Search In
• More options...
Find results that contain...
Find results in...

# Maximum numbers python file reading help

Go to solution Solved by 0x21,
2 hours ago, DerpDiamonds1 said:

So with this solution can I have multiple high scores from the same username?

No, if you want to have multiple scores from the same user then this will work:

```def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a list of tuples from the text file
scores = [(row[0], int(row[1])) for row in reader]

# Sort into a list of the top n scores.
scores = sorted(scores, key=lambda score: score[1], reverse=True)[:n]

# Print
if len(scores) > 0:
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1
else:
print("There are no scores")```

So I am trying to read from a file and display the top 5 scores, but I don't know how to do it. My formatting is like this:

`Name, Score`

My current code is:

```import random
import re

def storeWinners(winner, winningScore, user1Score, user2Score):
file = open("scores.txt", "a")
file.write("\n" + winner + ", " + winningScore)
file.close()

def finalDecide(user1Score, user2Score, user1, user2):
if user1Score > user2Score:
winner = user1
winningScore = str(user1Score)
print("The winner is", user1)
storeWinners(winner, winningScore, user1Score, user2Score)
elif user1Score < user2Score:
winner = user2
winningScore = str(user2Score)
print("The winner is", user2)
storeWinners(winner, winningScore, user1Score, user2Score)
elif user1Score == user2Score:
while user1Score == user2Score:
user1FinalRoll = random.randint(1,6)
user2FinalRoll = random.randint(1,6)
user1Score = user1Score + user1FinalRoll
user2Score = user2Score + user2FinalRoll
if user1Score > user2Score:
winner = user1
winningScore = str(user1Score)
print("The winner is", user1)
storeWinners(winner, winningScore, user1Score, user2Score)
elif user1Score < user2Score:
winner = user2
winningScore = str(user2Score)
print("The winner is", user1)
storeWinners(winner, winningScore, user1Score, user2Score)

def rollDieWithPoints(user1, user2):
user1Score = 0
user2Score = 0
for i in range(0, 5):
user1Roll1 = random.randint(1,6)
user1Roll2 = random.randint(1,6)
user2Roll1 = random.randint(1,6)
user2Roll2 = random.randint(1,6)
user1Score = user1Score + user1Roll1 + user1Roll2
user2Score = user2Score + user2Roll1 + user2Roll2
def user1Points(user1Score):
if (user1Score % 2 == 0):
user1Score = user1Score + 10
if user1Roll1 == user1Roll2:
user1Roll3 = random.randint(1,6)
user1Score = user1Score + user1Roll3
elif (user1Score % 2 != 0) and (user1Score - 5 >= 0):
user1Score = user1Score - 5
if user1Roll1 == user1Roll2:
user1Roll3 = random.randint(1,6)
user1Score = user1Score + user1Roll3
else:
print("I'm sorry there was an error, please try again later")
def user2Points(user2Score):
if (user2Score % 2 == 0):
user2Score = user2Score + 10
if user2Roll1 == user2Roll2:
user2Roll3 = random.randint(1,6)
user2Score = user2Score + user2Roll3
elif (user2Score % 2 != 0) and (user2Score - 5 >= 0):
user2Score = user2Score - 5
if user2Roll1 == user2Roll2:
user2Roll3 = random.randint(1,6)
user2Score = user2Score + user2Roll3
else:
print("I'm sorry there was an error, please try again later")
user1Points(user1Score)
user2Points(user2Score)
print("For this round, user 1 got", user1Score, "and user 2 got", user2Score)
print("Now for the end of the game")
finalDecide(user1Score, user2Score, user1, user2)

def authentication():
file = open("users.txt")
user1NameInput = input("What is your name user 1?: ")
re_res = re.search(r'^{}, (.*)\$'.format(user1NameInput), text, re.MULTILINE)
if re_res:
print("Welcome to the game user 1, now for user 2")
user2NameInput = input("What is your name user 2?: ")
re_res = re.search(r'^{}, (.*)\$'.format(user2NameInput), text, re.MULTILINE)
if re_res:
print("Welcome to the game, now you can both play")
user1 = user1NameInput
user2 = user2NameInput
rollDieWithPoints(user1, user2)
else:
else:
newUsernameInput = input("That username is not in the system, would you like to create a new user by that name? (Y/N): ")
file = open("users.txt", "a")
file.close()
else:
print("That is not an input, please try again")
else:
else:
newUsernameInput = input("That username is not in the system, would you like to create a new user by that name? (Y/N): ")
file = open("users.txt", "a")
file.close()
else:
print("That is not an input, please try again")
file.close()

def start():
startingChoice = input("Do you want to play the game (1) or check scores (2)?: ")
if startingChoice == "1":
authentication()
elif startingChoice == "2":
file = open("scores.txt")
else:
print("That is not an input, please try again")

start()
```

But i am only focusing on:

```def start():
startingChoice = input("Do you want to play the game (1) or check scores (2)?: ")
if startingChoice == "1":
authentication()
elif startingChoice == "2":
file = open("scores.txt")
else:
print("That is not an input, please try again")

start()```

In the 'startingChoice == "2":' bit!

Thanks!

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

If you write to scores.txt as a dictionary, you will be able to load the array, sort it, and output the highest five values. By storing the data as raw text, it is very hard to manipulate it later.

##### Share on other sites

If you write to scores.txt as a dictionary, you will be able to load the array, sort it, and output the highest five values. By storing the data as raw text, it is very hard to manipulate it later.

How could you do that?

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

Readlines will generate a list, so you can iterate each entry in the high score file. From there on, split it by the comma, perform an lstrip and rstrip to remove leading and trailing white spaces on the score entry, then convert the entry into some numeric value instead of leaving it as a string, such as calling int().

From there on you can find a way to sort the data.

Edited by M.Yurizaki

##### Share on other sites

2 minutes ago, M.Yurizaki said:

Readlines will generate a list, so you can iterate each entry in the high score file. From there on, split it by the comma, perform an lstrip and rstrip to remove leading and trailing white spaces on the score entry, then convert the entry into some numeric value instead of leaving it as a string, such as calling int().

From there on you can find a way to sort the data.

Again, how can you do that in the code. I'm not that advanced.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

I don't know Python syntax, so you'll have to figure out the code on your own. However, you should understand that dictionaries are the proper way to store key-value pairs in Python.

Here is a primer on dictionaries:

And an example on how to sort by value:

##### Share on other sites

6 minutes ago, DerpDiamonds1 said:

Again, how can you do that in the code. I'm not that advanced.

Here's a code snippet.

```scores = []
for line in text:
score_entry = line.split(',')
scores.append(int(score_entry[1]))```

I found that int() doesn't care about the white space anyway.

##### Share on other sites

I don't know Python syntax, so you'll have to figure out the code on your own. However, you should understand that dictionaries are the proper way to store key-value pairs in Python.

Here is a primer on dictionaries:

And an example on how to sort by value:

Aren't they the same as arrays and I am using files to be able to store lots of users at a time and can expand without directly editing the file.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

1 minute ago, M.Yurizaki said:

Here's a code snippet.

```
scores = []
for line in text:
score_entry = line.split(',')
score_entry[1] = score_entry[1].lstrip()
score_entry[1] = score_entry[1].rstrip()
scores.append(int(score_entry[1]))﻿```

Sorry for being a burden, but how would I put that into my code.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

4 minutes ago, DerpDiamonds1 said:

Aren't they the same as arrays and I am using files to be able to store lots of users at a time and can expand without directly editing the file.

No, arrays are a list of values (i.e. scores = [5, 7, 3, 11]), while dictionaries are pairs of data (i.e. scores = {Alice: 3, Bob: 7, Charlie: 12}).

##### Share on other sites

No, arrays are a list of values (i.e. scores = [5, 7, 3, 11]), while dictionaries are pairs of data (i.e. scores = {Alice: 3, Bob: 7, Charlie: 12}.

I did this in a file so I can future proof the code and add unlimited amounts of users.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

1 minute ago, DerpDiamonds1 said:

Sorry for being a burden, but how would I put that into my code.

I edited my post, but you don't actually need the lstrip and rstrip steps.

Otherwise, you copy and paste it where you want it to run. However, I'd advise actually playing around with the code and figuring out where to best put it on your own.

##### Share on other sites

1 minute ago, M.Yurizaki said:

I edited my post, but you don't actually need the lstrip and rstrip steps.

Otherwise, you copy and paste it where you want it to run. However, I'd advise actually playing around with the code and figuring out where to best put it on your own.

How can i print the result, so it ends up like:

```The top 5 scores are:

1. Jack with 5.
2. Oliver with 4.
3. Emily with 3
4. Jean with 2
5. Mike with 1```

So does this code pick out the higher scores then as well.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

```import csv

def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a dictionary from the text file
scores = {row[0]: int(row[1]) for row in reader}

# Sort into a list of the top n scores.
scores = [(k, scores[k]) for k in sorted(scores, key=scores.__getitem__, reverse=True)][:n]

# Print
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1

def start():
# ...
elif startingChoice == "2":
# Print the top 5 scores
printScores(5)
# ...```

If you have any questions, feel free to ask.

##### Share on other sites

18 minutes ago, mshaugh said:
```
import csv﻿

def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a dictionary from the text file
scores = {row[0]: int(row[1]) for row in reader}

# Sort into a list of the top n scores.
scores = [(k, scores[k]) for k in sorted(scores, key=scores.__getitem__, reverse=True)][:n]

# Print
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1﻿

def start():
# ...
elif startingChoice == "2":
# Print the top 5 scores
printScores(5)﻿
# ...```

If you have any questions, feel free to ask.

Thanks, just put it in and now trying to learn how each of it works.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

40 minutes ago, mshaugh said:
```
import csv

def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a dictionary from the text file
scores = {row[0]: int(row[1]) for row in reader}

# Sort into a list of the top n scores.
scores = [(k, scores[k]) for k in sorted(scores, key=scores.__getitem__, reverse=True)][:n]

# Print
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1

def start():
# ...
elif startingChoice == "2":
# Print the top 5 scores
printScores(5)
# ...```

If you have any questions, feel free to ask.

Sorry to bother you, but two quick questions:

1. Can this be made any simpler?

2. What statement can you add to print out if there are no scores inside the file (I am kinda new to CSV so I don't know that much about it)?

Thanks!

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

4 minutes ago, DerpDiamonds1 said:

Can this be made any simpler?

What do you mean by "simpler"?

11 minutes ago, DerpDiamonds1 said:

I am kinda new to CSV so I don't know that much about it

CSV simply stands for comma-separated values, and the eponymous module just implements classes to read/write data in this format.

11 minutes ago, DerpDiamonds1 said:

What statement can you add to print out if there are no scores inside the file?

All we need for this is a slight modification to the `printScores` function.

```def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a dictionary from the text file
scores = {row[0]: int(row[1]) for row in reader}

# Sort into a list of the top n scores.
scores = [(k, scores[k]) for k in sorted(scores, key=scores.__getitem__, reverse=True)][:n]

# Print
if len(scores) > 0:
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1
else:
print("There are no scores")```

##### Share on other sites

3 minutes ago, DerpDiamonds1 said:

1. Can this be made any simpler?

The simplest (and slowest) way to find the maximum score is shown below. If you choose to go this route instead of the preferable route already shown, I will leave it to you to figure out how to modify it to track the highest 5 scores (this is homework, after all). I will also leave it to you to figure out how to determine if the file contains no scores.

1. Initialize two variables, max_score_name and max_score, to an empty string and the lowest possible score, respectively.
2. Check if you've reached the end of the file. If not, go to step 3, otherwise go to step 6
3. Read a (name, score) pair from the file. Set the variables current_name to the name, and current_score to score, after converting it to a number.
4. If current_score is greater than max_score go to step 5, otherwise go to step 2.
5. Replace max_score_name with current_name, and max_score with current_score. Go to step 2.
6. Display the max_score_name and max_score.

I should also warn you that you shouldn't copy and paste anything from this thread into your homework. If your teacher googles "maximum numbers python file" (or any combination thereof), this thread is one of the first results returned.

ENCRYPTION IS NOT A CRIME

##### Share on other sites

Here's another solution, with an example of how to use it.

```# itemgetter allows sorted() to sort by entries in a list
from operator import itemgetter

text = ["Alice, 83", "Bob, 29", "Charlie, 20", "Dave, 48", "Eve, 9", "Fred, 10", "George, 58", "Hellen, 69", "Isabelle, 2", "Jordan, 81", "Alice, 100", "Dave, 99"]

def print_high_scores(scores, last_place=5):
entries = []

# You can replace this for-iterator with a CSV reader if you want
for score in scores:
score = score.split(',')
score[1] = int(score[1])
entries.append(score)

if len(entries) == 0:
print("No scores available")
else:
entries = sorted(entries, key=itemgetter(1), reverse=True)
place = 0

print("Top", last_place, "scores")
for entry in entries:
if place == last_place:
break
print(str.format("{0}. {1}: {2}", place+1, entry[0], entry[1]))
place +=1
return

print_high_scores(text, last_place=3)
print()
print_high_scores(text, last_place=10)
print()
print_high_scores(text, last_place=5)```

The problem with putting the scores into a dictionary is that it doesn't allow the same name to have multiple scores.

But as usual, I highly advise you look through and see how this code works rather than copy, pasting, testing that it works, and calling it a day if it does.

Edited by M.Yurizaki

##### Share on other sites

And because I'm bored, alternatives solutions that don't involve itemgetter

This method does use a dictionary, but instead of using the name as the key, it uses the score as the key and a list of names as the value. This gets around the issue of not allowing the same person to have multiple scores .

This approach is a bare-bones that implements a bubble sort routine if one didn't know anything about Python's built-in sort function:

```text = ["Alice, 83", "Bob, 29", "Charlie, 20", "Dave, 48", "Eve, 9", "Fred, 10", "George, 100", "Hellen, 69", "Isabelle, 2", "Jordan, 81", "Alice, 100", "Dave, 99"]

def swap(in_list, first, second):
temp = in_list[first]
in_list[first] = in_list[second]
in_list[second] = temp
return

def sort_scores(scores_list):
end = len(scores_list)
x = 0
swapped = False

while x < end:
swapped = False
first_num = scores_list[x]
for y in range(x, end):
second_num = scores_list[y]
if second_num > first_num:
swapped = True
swap(scores_list, x, y)
if swapped == False:
x += 1
return

def print_scores(scores, last_place=5):
entries = {}
score_numbers = []

for score_entry in scores:
score_entry = score_entry.split(',')
score_name = score_entry[0]
score_number = int(score_entry[1])

if score_number not in score_numbers:
score_numbers.append(score_number)
if score_number not in entries:
entries[score_number] = []
entries[score_number].append(score_name)

if len(score_numbers) == 0:
print("No scores available")
else:
sort_scores(score_numbers)
place = 0
print("Top", last_place, "scores")
for entry in entries:
if place == last_place:
break
print(str.format("{0}. {1}: {2}", place+1, entry[0], entry[1]))
place +=1

print_scores(text)```

This approach uses Python's built-in sort function

```text = ["Alice, 83", "Bob, 29", "Charlie, 20", "Dave, 48", "Eve, 9", "Fred, 10", "George, 100", "Hellen, 69", "Isabelle, 2", "Jordan, 81", "Alice, 100", "Dave, 99"]

def print_scores(scores, last_place=5):
entries = {}
score_numbers = []

for score_entry in scores:
score_entry = score_entry.split(',')
score_name = score_entry[0]
score_number = int(score_entry[1])

if score_number not in score_numbers:
score_numbers.append(score_number)
if score_number not in entries:
entries[score_number] = []
entries[score_number].append(score_name)

if len(score_numbers) == 0:
print("No scores available")
else:
score_numbers = sorted(score_numbers, reverse=True)
place = 0
print("Top", last_place, "scores")
for entry in entries:
if place == last_place:
break
print(str.format("{0}. {1}: {2}", place+1, entry[0], entry[1]))
place +=1

print_scores(text)```

Also while I can see merit in doing a with file approach in the print function itself, I don't like it because I consider that functionality an interface. While it sort of conflicts with the "You ain't gonna need it" principle, I like the function to accept the actual data its interested in rather than an indirect reference to that data.

##### Share on other sites

2 hours ago, mshaugh said:

```
def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a dictionary from the text file
scores = {row[0]: int(row[1]) for row in reader}

# Sort into a list of the top n scores.
scores = [(k, scores[k]) for k in sorted(scores, key=scores.__getitem__, reverse=True)][:n]

# Print
if len(scores) > 0:
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1
else:
print("There are no scores")```

So with this solution can I have multiple high scores from the same username?

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB

##### Share on other sites

2 hours ago, DerpDiamonds1 said:

So with this solution can I have multiple high scores from the same username?

No, if you want to have multiple scores from the same user then this will work:

```def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a list of tuples from the text file
scores = [(row[0], int(row[1])) for row in reader]

# Sort into a list of the top n scores.
scores = sorted(scores, key=lambda score: score[1], reverse=True)[:n]

# Print
if len(scores) > 0:
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1
else:
print("There are no scores")```

##### Share on other sites

9 hours ago, mshaugh said:

No, if you want to have multiple scores from the same user then this will work:

```
def printScores(n):
with open('scores.txt', mode='r') as file:
# Create a list of tuples from the text file
scores = [(row[0], int(row[1])) for row in reader]

# Sort into a list of the top n scores.
scores = sorted(scores, key=lambda score: score[1], reverse=True)[:n]

# Print
if len(scores) > 0:
print("The top {} scores are:\n".format(n))
pos = 1
for name, score in scores:
print("\t{}. {} with {}".format(pos, name, score))
pos += 1
else:
print("There are no scores")﻿```

Thanks, just going to understand now how the new version works.

Specs:

Motherboard: Gigabyte Z97X Gaming 3

CPU: Intel Core I7 4790K

GPU: Gigabyte G1 Gaming GTX 970

RAM: HyperX Fury 16GB

HDD: Seagate ST3000DM001 3TB

SSD: KINGSTON SV300S37A480G 450GB

Cooler: Corsair H100i GTX

Case: NZXT H440 Red

Monitor: DELL U2412M

Keyboard: Gigabyte Force K7

Mouse: Corsair Sabre RGB