0

I have a problem with concerning my code:

with open('Premier_League.txt', 'r+') as f:
    data = [int(line.strip()) for line in f.readlines()] # [1, 2, 3]
    f.seek(0)

    i = int(input("Add your result! \n"))

    data[i] += 1  # e.g. if i = 1, data now [1, 3, 3]

    for line in data:
        f.write(str(line) + "\n")

    f.truncate()
    print(data)

The code works that the file "Premier_League.txt" that contains for example:

1
2
3

where i=1 gets converted to and saved to already existing file (the previous info gets deleted)

1
3
3

My problem is that I want to chose a specific value in a matris (not only a vertical line) for example:

0 0 0 0
0 0 0 0
0 0 0 0

where i would like to change it to for example:

0 1 0 0
0 0 0 0
0 0 0 0

When I run this trough my program this appears:

ValueError: invalid literal for int() with base 10: '1 1 1 1'

So my question is: how do I change a specific value in a file that contains more than a vertical line of values?

5
  • Question: why 0 1 0 0 and not say 0 0 1 0 or any other combination? Commented Jul 19, 2017 at 11:50
  • No you should be able to change it to both, its just going in and changing a specific value in the file , therefore it can be both 0 1 0 0 or 0 0 1 0 or why not 0 1 1 0 Commented Jul 19, 2017 at 11:52
  • This is the very definition of an XY problem. You are approaching the whole thing wrong. Commented Jul 19, 2017 at 11:57
  • Maybe consider providing column names and handle it like a csv instead? It might make things much easier to handle as well when wanting to change data. Commented Jul 19, 2017 at 11:59
  • Also you prompt the user to add his result but instead you simply use the input to jump to the corresponding line and increment the content by 1.. Commented Jul 19, 2017 at 12:02

2 Answers 2

3

The problem is you are not handling the increased number of dimensions properly. Try something like this;

with open('Premier_League.txt', 'r+') as f:
    # Note this is now a 2D matrix (nested list)
    data = [[int(value) for value in line.strip().split()] for line in f ]
    f.seek(0)

    # We must specify both a column and row
    i = int(input("Add your result to column! \n"))
    j = int(input("Add your result to row! \n"))

    data[i][j] += 1 # Assign to the index of the column and row

    # Parse out the data and write back to file
    for line in data:
        f.write(' '.join(map(str, line)) + "\n")

    f.truncate()
    print(data)

You could also use a generator expression to write to the file, for example;

# Parse out the data and write back to file
f.write('\n'.join((' '.join(map(str, line)) for line in data)))

instead of;

# Parse out the data and write back to file
for line in data:
    f.write(' '.join(map(str, line)) + "\n")
Sign up to request clarification or add additional context in comments.

4 Comments

And just a question, the two examples; do they basically act the same?
Is it just that the first one is simpler written? ^^
The first one is one line less code, but they basically do the same thing.
If you want to get technical I suppose the second one uses more write operations but less memory, I prefer it just because I think it's more elegant, but it's harder to understand to I included both.
1

First up, you are trying to parse the string '0 0 0 0' as an int, that's the error you are getting. To fix this, do:

data = [[int(ch) for ch in line.strip().split()] for line in f.readlines()]

This will create a 2D array, where the first index corresponds to the row, and the second index corresponds to the column. Then, you would probably want the user to give you two values, instead of a singular i since you are trying to edit in a 2D array.

Edit:
So your following code will look like this:

i = int(input("Add your result row: \n"))
j = int(input("Add your result column: \n"))

data[i][j] += 1  
# For data = [[1,2,1], [2,3,2]], and user enters i = 1
# and j = 0, the new data will be [[1,2,1], [3,3,2]]

2 Comments

I am not compleatly sure I understand you. Do you mean I should change my data = [int(line.strip()) for line in f.readlines()] # [1, 2, 3] into data = [[int(ch) for ch in line.strip().split(' ')] for line in f.readlines()], but the program tells me that: TypeError: 'int' object is not iterable
Sorry there was a slight bug, it should be split() not split(' '). But the user Tom Wyllie has already addressed it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.