0

I have managed to write the scores and names of anybody who wins a simple dice game I created to an external text document. How would I sort the top scores from this document and display them on the console alongside the name that achieved that score?

Code used to write score and name to the text document:

winners = open("winners.txt", "a")
winners.write(p1_username) #writes the name 
winners.write("\n")
winners.write(str(p1_total)) #writes the score

Tried entering the data into an array of tuples and sorting them according to the numerical value in each tuple when I found this, so tried

count = len(open("winners.txt").readlines(  ))
winners_lst = [(None, None)] * count
f = open("winners.txt", "r")
lines2 = f.readlines()
winners_lst[0][0] = lines2[0]
winners_lst[0][0] = lines2[1]

but that returns

TypeError: 'tuple' object does not support item assignment

Edit: I am not asking why my solution didn't work, I am asking what I could do to make it work or for an alternate soloution.

a121
  • 798
  • 4
  • 9
  • 20
baguettio
  • 179
  • 1
  • 1
  • 8
  • A tuple is [immutable](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences) – costaparas Jan 08 '21 at 14:48
  • The message is pretty clear: tuples are immutable. Don't create the list like that. Create an empty list and use `append`. – 001 Jan 08 '21 at 14:48
  • `Tuples` are ***immutable***. See https://www.afternerd.com/blog/difference-between-list-tuple/ (or similar) – PM 77-1 Jan 08 '21 at 14:50
  • @JohnnyMopp How do I create an empty list of the right size with the right kind of tuples in it? – baguettio Jan 08 '21 at 14:51
  • your write operation is flawed in several ways. There seems to be no newline after score. Also, use the `with open(...) as f:` context to close the file properly resources after usage. – Pierre D Jan 08 '21 at 14:51
  • Does this answer your question? [Why do we need tuples in Python (or any immutable data type)?](https://stackoverflow.com/questions/2174124/why-do-we-need-tuples-in-python-or-any-immutable-data-type) – PM 77-1 Jan 08 '21 at 14:51
  • `winners_lst = []; with open("winners.txt", "r") as f: lines = f.readlines(); for l in range(0, len(lines), 2): winners_lst.append((lines[l], lines[l+1]))` – 001 Jan 08 '21 at 14:53
  • @PM77-1 That tells me why my attempted solution didn’t work, but my question was what do I do that does work. – baguettio Jan 08 '21 at 14:54
  • @Thibault D.provided a [good answer](https://stackoverflow.com/a/65631309/2055998): – PM 77-1 Jan 08 '21 at 18:28

2 Answers2

1

Tuples are immutable, which means you cannot modify a tuple once it has been created. You have two options to achieve what you want:

  1. Use a list of size 2 instead of tuples, like this: winners_lst = [[None, None]] * count
  2. Replace the tuple by another one, like this: winners_lst[0] = (lines2[0], lines2[1])
Thibault D.
  • 201
  • 1
  • 4
1

First, the write operation should be cleaner:

with open('winners.txt', 'w') as f:
    for p1_username, p1_score in [('foo', 1), ('bar', 2), ('foobar', 0)]:
        print(f'{p1_username}\n{p1_score}', file=f)

Content of winners.txt:

foo
1
bar
2
foobar
0

Then, you can read this back into a list of tuples:

with open('winners.txt') as f:
    lines = f.read().splitlines()

winners_lst = [(a, b) for a, b in zip(lines[::2], lines[1::2])]

Content of winners_lst:

[('foo', '1'), ('bar', '2'), ('foobar', '0')]

After ingest, you may convert the scores into int:

winners_lst = [(a, int(b)) for a, b in winners_lst]

And sort by score descending (if such is your goal):

sorted(winners_lst, key=lambda ab: ab[1], reverse=True)
# out:
[('bar', 2), ('foo', 1), ('foobar', 0)]
Pierre D
  • 24,012
  • 7
  • 60
  • 96
  • I'm confused as to what `winners_lst = [(a, b) for a, b in zip(lines[::2], lines[1::2])]` means, is it just joining every two elements in the list into tuples? – baguettio Jan 08 '21 at 15:07
  • Yes indeed: in the list comprehension, each pair of consecutive elements is `a, b`; we make a list of those as tuples `(a, b)`. – Pierre D Jan 08 '21 at 15:09
  • @baguettio: see also the update with some follow up steps (convert to int, then sort) – Pierre D Jan 08 '21 at 15:13