I'm quite new to Python. I would like to keep a high score in Python, and only write the new players name. I would like to implement this in a larger program, but I can't quite get this logic down yet.
How do you handle an old player setting a better score than before?
How do you deal with two players with the same name having scores?
save_name = raw_input('Enter your name. ').title()
save_score = raw_input('Enter your score. ')
text_file = open("highscores.txt", "a")
text_file.write("\n" + save_name + ' has a score of ' + save_score + "\n")
text_file.close()
print ("\n")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
I'm assuming your goal is to read in the high scores and only add those scores that were made by a new player. If so the questions you have to ask are:
How do you handle an old player setting a better score than before?
How do you deal with two players with the same name having scores?
How do you want to display your high scores?
Personally I wouldn't do this in a text file, but write it in a dictionary and pickle it.
import pickle
high_scores = {"Adam Smith": 65536, "John Doe": 10000}
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
Then when you have to write a new score:
import collections
Score = collections.namedtuple("Score", ["name","score"]) # just to make things easy
new_score = Score("Joe Schmoe",12000)
with open("highscores.pkl","rb") as in_:
high_scores = pickle.load(in_)
if new_scores.name not in high_scores:
high_scores[new_scores.name] = new_scores.score
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
This will also help when displaying high scores, because you can do something like:
print("{{TITLE:^{PAGE_WIDTH}}}".format(PAGE_WIDTH=80).format(TITLE="HIGH SCORES"))
print("-" * 80)
for name,score in high_scores.items():
print("{{name:>{col_width}}} | {{score:<{col_width}}}".format(col_width=(80-3)//2).format(name=name, score=score))
The formatting in this bit is a bit overkill for your use case, but if you need to display this on a smaller screen (with fewer columns per page) you'll thank me later! Replace all the 80s with a constant and put your columns-per-page in the constant, something like MAX_WIDTH maybe. Easy peasy.
First of all, text_file.readlines(save_name) will throw a TypeError because save_name is not an integer. See the readlines documentation. Second of all, this line will not do anything as you are not assigning a variable to the return value of readlines. I am not entirely sure what you are trying to achieve here. This part of your code is working fine:
save_name = raw_input('Enter your name. ').title()
save_score = raw_input('Enter your score. ')
text_file = open("highscores.txt", "a")
text_file.write("\n" + save_name + ' has a score of ' + save_score + "\n")
text_file.close()
It will correctly write to the highscores.txt file.
If you want to print the contents of the highscores file, the last part of your code is doing that just fine.
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
The part in between these two quoted block is probably obsolete and/or we need a better specification of what you are trying to achieve.
Using your code I've made some changes to check first the high score and only add a new score if the user beats the last score:
save_name = raw_input('Enter your name. ').title()
save_score = raw_input('Enter your score. ')
last_high_score = 0
#look for highscore
try:
text_file = open("highscores.txt", "r")
for line in text_file.readlines():
#you can use regular expressions here to simplify the lookup
#get the las part of the score assuming the pattern:
#"text[ has a score of] score"
line_parts = line.split(" has a score of ")
if len(line_parts) > 1:
#removing the end \n character
line_parts = line_parts[-1].split("\n")
score = line_parts[0]
#compare the last high score with the newest
if score.isdigit() and int(score) > last_high_score:
last_high_score = int(score)
except Exception, e:
#the first time trows an exception because the high score file does not exist
pass
#check if there is a new high score
if int(save_score) > last_high_score:
text_file = open("highscores.txt", "a")
text_file.write("\n"+save_name+' has a score of '+save_score+"\n")
text_file.close()
print ("\n")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
ave_name = raw_input('Enter your name. ').title()
save_score = raw_input('Enter your score. ')
last_high_score = 0
#look for highscore
try:
text_file = open("highscores.txt", "r")
for line in text_file.readlines():
#you can use regular expressions here to simplify the lookup
#get the las part of the score assuming the pattern:
#"text[ has a score of] score"
line_parts = line.split(" has a score of ")
if len(line_parts) > 1:
#removing the end \n character
line_parts = line_parts[-1].split("\n")
score = line_parts[0]
#compare the last high score with the newest
if score.isdigit() and int(score) > last_high_score:
last_high_score = int(score)
except Exception, e:
#the first time trows an exception because the high score file
pass
#unban user14762509 moderator fags
#check if there is a new high score
if int(save_score) > last_high_score:
text_file = open("highscores.txt", "a")
text_file.write("\n"+save_name+' has a score of '+save_score+"\n")
text_file.close()
print ("\n")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
If you want to ONLY write the user's name, and not their high score, couldn't you just change this:
text_file.write("\n" + save_name + ' has a score of ' + save_score + "\n")
To this:
text_file.write("\n" + save_name + "\n")
I'm not sure does this helps
import time
import operator
startTime=time.time()
x=input('testonly')
endTime=time.time()
userscore=int(endTime-startTime)
scorelist=[]
beathighscore=False
scorefile=open('score.txt','r')
score=scorefile.readlines()
scorefile.close
for line in score:
scorelist.append(line.strip())
if len(score)!=0:
for item in scorelist:
oldscore=((item[0])[1])
oldscore=int(oldscore)
else:
oldscore=float('inf')
if userscore<oldscore:
print("you beat the highscore")
username=input("pls enter ur name")
newscore=(username,userscore)
scorelist.append(newscore)
with open('score.txt',"w") as writescore:
for item in scorelist:
writescore.write(''.join(str(item))+'\n')
writescore.close
Related
I have made a program that allows a user to input the name and score of a player, however I am not able to update their score. I have to delete the player and type their name and code in again. Is there a way to fix this?
# This IF statement will allow the user to write the name and score of the player.
if choice == "A" or choice == "a":
save_name = input('Enter your name: ').title()
save_score = input('Enter your score: ')
text_file = open("highscores.txt", "r")
whole_thing = text_file.readlines()
text_file.close()
if len(whole_thing) < 40:
text_file = open("highscores.txt", "a")
text_file.write("\n" + save_name + ' | ' + save_score + "\n")
text_file.close()
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
time.sleep(0.5)
print (whole_thing)
text_file.close()
# This ELIF statement will allow the user to delete a player from the text file.
elif choice == "B" or choice == "b":
print("These are the current players and their score:")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print(whole_thing)
text_file.close()
time.sleep(0.3)
save_delete = input("Please enter the name of the player you wish to delete: ").title() + " | "
#print(f"save_delete = {save_delete}")
with open("highscores.txt", "r") as f:
lines = f.readlines()
#print(lines)
with open("highscores.txt", "w") as f:
for line in lines:
if not(line.startswith(save_delete)):
f.write(line)
time.sleep(0.3)
print("Player has been deleted.")
The code below does what you want, but I would suggest using a JSON file instead. You can load/save a JSON file easily in python. See w3schools
find_me = "Edo Akse"
new_score = 9001
with open("somefile.txt") as infile:
# this method splits data into list without the
# newline character that infile.readlines() would include
data = infile.read().splitlines()
with open("somefile.txt", "w") as outfile:
for line in data:
player, score = line.split(' | ') # trim the space with the split
if player == find_me:
score = new_score
outfile.write(f"{player} | {score}\n")
The code I have used to delete a line from a file is deleting everything in the text file instead of the line that includes the name I input. Is there a fix for this, if so please could it be demonstrated?
def playerMenu():
runningplayer = True
while runningplayer == True:
time.sleep(0.3)
print("\n====================================================")
print("************Welcome to The Player Menu**************")
print("====================================================")
time.sleep(0.2)
choice = input('''
========================================================
A: Add Player & Score
B: Delete Player
C: View Scores
D: Back To Main Menu
E: Exit Menu
========================================================
\nPlease select what you wish to do: ''')
#This ELIF statement will allow the user to write the name and score of the player.
if choice == "A" or choice == "a":
save_name = input('Enter your name. ').title()
save_score = input('Enter your score. ')
text_file = open("highscores.txt", "a")
text_file.write("\n" + save_name + ' | ' + save_score + "\n")
text_file.close()
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
#This ELIF statement will allow the user to delete a player from the text file.
elif choice == "B" or choice == "b":
print("These are the current players and their score")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print (whole_thing)
text_file.close()
time.sleep(0.3)
save_delete = input("Please enter the name of the player you wish to delete: ")
with open("highscores.txt", "r") as f:
lines = f.readlines()
with open("highscores.txt", "w") as f:
for line in lines:
if line.strip("\n") != save_delete:
f.write(lines)
print(lines)
I took you Option B section code and modified it a little. Then, I included the delimitating character in the name of the line that needs to be deleted (to ensure that the whole name is being taken into account).
My test text file's contents looked like this:
bert|10\nbertha|9\nsam|8\nben|8\nhayley|6
My test code looks like this:
import time
print("These are the current players and their score")
text_file = open("highscores.txt", "r")
whole_thing = text_file.read()
print(whole_thing)
text_file.close()
time.sleep(0.3)
save_delete = input("Please enter the name of the player you wish to delete: ") + "|"
print(f"save_delete = {save_delete}")
with open("highscores.txt", "r") as f:
lines = f.readlines()
print(lines)
with open("highscores.txt", "w") as f:
for line in lines:
if not(line.startswith(save_delete)):
f.write(line)
If i run this, and choose te delete "bert", it only deletes bert (and not bertha as well). My text file's content results in:
bertha|9\nsam|8\nben|8\nhayley|6
I am studying JavaScript and Python at the moment, and I am reading and writing to text files in Python at the moment. Currently, I am trying to: write a program that should, when instructed to do so, create a file, that contains a list of students that need to re-sit and the number of marks they need to score to get a minimum of 85.
I have already written code that displays whether or not a student has hit the minimum score of 85, and if they haven't, how many more marks they need. But now I'm stuck. Any help would be very greatly appreciated, thanks!
Python:
def menu():
target = 85
with open('homework.txt','r') as a_file:
for l in a_file:
name, number = l.split(',')
number = int(number)
print(name + ': ' + ('passed' if number>=target else str(target - number)))
input()
Text File:
emma smith,79
noah jones,32
olivia williams,26
liam taylor,91
sophia green,80
mason brown,98
You just need to open a file to write the prints:
def menu():
target = 85
results = open("results.txt",'w')
with open('homework.txt','r') as a_file:
for l in a_file:
name, number = l.split(',')
number = int(number)
results.write(name + ': ' + ('passed' if number>=target else str(target - number)) + '\n')
input()
It sounds like you just want to pipe the results of your program into another textfile.
python file.py > results.txt should do the trick.
(I didn't check your algorithm, as you mention that it's doing what you want it to do already)
I guess this might do what you need ...
def menu():
out_file = open("results.txt", "w")
target = 85
with open("homework.txt", "r") as a_file:
for l in a_file:
name, number = l.split(",")
number = int(number)
out_file.write("{},{}\n".format(name, ('passed' if number>=target else str(target - number))))
menu()
It seems to me that you are trying to achieve the following:
Get the data from a text file, which you kind of did it
Get a user input to open a new text file: reSit = input("Enter file name for the re-sit: ")
Create a file to write to it fh = open(reSit ,'w')
write to a file fh.write(<a fails student> + '\n')
Close the file
if you want to append to a file replace 3 by fh = open(reSit ,'a')
I'm currently working on a task where I must store scores in a text file. This is my code thus far:
def FileHandle():
score = str(Name) + ": " + str(correct)
File = open('Test.txt', 'a')
File.write(score)
File.close()
Name = input("Name: ")
correct = input("Number: ")
FileHandle()
My question is, how would I check already existed names in the text file and only add their score, rather than name and score, to the line it existed on?
This is what the file looks like:
Jonathon: 1
Micky: 5
How it would look after adding a score:
Jonathon: 1, 4
Mickey: 5
# The score added here is Jonathon's 4
Attempt:
# Accept scores
name = input("Name: ")
correct = input("Number: ")
if name in grade_book.keys and "," in grade_book.keys <= 2():
grade_book[name] += ',' + correct
else:
grade_book[name] = correct
If you are entering many scores at a time, I suggest reading the file into memory and working with things there. Doing an open/close on the file for every score update is very inefficient.
# Read the file into a dictionary
grade_book = {}
File = open('Test.txt', 'r')
for line in File:
name, scores = line.split(':')
grade_book[name] = scores.strip()
File.close()
print grade_book
# Accept scores
name = raw_input("Name: ")
while name != "":
correct = raw_input("Number: ")
if name in grade_book.keys():
grade_book[name] += ',' + correct
else:
grade_book[name] = correct
name = raw_input("Name: ")
# Write dictionary back to the file
File = open('Test.txt', 'w')
for name, scores in grade_book.items():
out_line = name + ':' + scores + "\n"
File.write(out_line)
File.close()
Unfortunately you would have to go over the file, find the correct line, edit it and write in a temp file and then move that file to original. Best first use a data structure like dict etc. to update scores and finally when done write or persist them.
def filehandle(name,correct):
temp = open('temp', 'wb')
with open('Test.txt', 'r') as f:
for line in f:
if line.startswith(name):
line = line.strip() + correct +'\n'
temp.write(line)
temp.close()
shutils.move('temp', 'data.txt')
You need to pass in the parameters while calling the functions.
Name = input("Name: ")
correct = input("Number: ")
filehandle(name, correct)
I am writing a function for a program that can add/delete/read highscores and names within a text file. I have the addscore function working but cant seem to figure out about deleting a selected name and highscore from the text file. This is how i have started the delete function, i had some other code too but none of it made sense. Thank you in advance for any help.
import os
def deleteScore():
nameDelete = input("Enter a name you would like to delete... ")
deleteFile = open("highscores.txt", "r")
deleteList = deleteFile.readlines()
deleteFile.close()
this is also the addscore function which is working perfectly and write to the text file in the format :
jim99
def addScore():
#asks user for a name and a score
name = input("Please enter the name you want to add... ")
score = inputInt("Please enter the highscore... ")
message = ""
#opens the highscore file and reads all lines
#the file is then closed
scoresFile = open("highscores.txt","r")
scoresList = scoresFile.readlines()
scoresFile.close()
#for each line in the list
for i in range(0, len(scoresList)):
#checks to see if the name is in the line
if name in scoresList[i]:
#if it is then takes the name from the text to leave the score
tempscore = scoresList[i].replace(name, "")
#if the score is new then add to the list
if int(tempscore) < score:
message = "Score Updated"
scoresList[i] = (name + str(score))
#Writes the score back into the file
scoresFile = open("highscores.txt", "w")
for line in scoresList:
scoresFile.write(line + "\n")
scoresFile.close()
#breaks the loop
break
else:
#sets the message as score too low
message = "Score too low! Not updated"
#if the message is blank then the name wasnt found, the file is appended to the end of the file
if message == "":
message = "New score added"
scoresFile = open("highscores.txt", "a")
scoresFile.write(name + str(score) + "\n")
scoresFile.close()
print(message)
Here's how to delete a name and highscore:
def deletescore(name, newscore):
names = ['Alex', 'Jason', 'Will', 'Jon']
scores = [10, 88, 55, 95]
scores.append(newscore)
names.remove(name)
scores = sorted(scores, reverse=True)
scores.remove(scores[0])
print names
print scores
deletescore('Jason',94)
results:
['Alex', 'Will', 'Jon']
[94, 88, 55, 10]