Deleting text from file using python - python

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]

Related

How to delete a line of text in python (minimal reproducable example)

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

How can I work out average of One person in same class when calling from Csv

I have saved a score with a name in a csv. I would like to create an average score out of people names who are the same and display this.
score2 = str(score)#Converts the integer into the string so can be saved
fsav = (fulnam + " : " + score2)#Sets the variable as Full name of the user and the score
filsav = clsnam + ".csv" #Creates the file that the scores will be saved in
file = open(filsav , "a") #Opens the file so it can be appended
file.write(fulnam + " , ") #Writes the persons name to the
file.write(score2) #Writes the persons score to the file
file.write("\n")#Moves the file onto a new line
file.close() #Closes and saves the file
Obviously, you have to read the entire file in to do it:
import csv
def compute_average(clsnam, fulnam):
""" Determine average score in class for named person.
"""
scores = []
with open(clsnam + ".csv", 'r') as file:
for name, score in csv.reader(file):
if name.strip() == fulnam:
scores.append(int(score))
return None if not scores else float(sum(scores)) / len(scores)

How do you limit the inclusion of a specific input in a text file

Im trying to save student's scores in a text file however I have been asked to save the student's last three scores. This sounded fairly straight forward however after attempting various different things I still can't do it. I have been trying to use their names as the variable that changes i.e. if their name is entered more than once.
here is my pitiful best attempt
please help
class_number = prompt_int_big("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number")
filename = (str(class_number) + "txt")
if any(name in s for s in filename):
for score in range (0,3):
with open(filename, 'a') as f:
f.write("\n" + str(name) + " also scored " + str(score) + " on difficulty level " + str(level_of_difficulty) + "\n")
with open(filename) as f:
lines = [line for line in f if line.strip()]
lines.sort()
name[-3]
else:
with open(filename, 'a') as f:
f.write("\n" + str(name) + " scored " + str(score) + " on difficulty level " + str(level_of_difficulty) + "\n")
with open(filename) as f:
lines = [line for line in f if line.strip()]
lines.sort()
filename = (str(class_number) + "txt")
class_number is already a string--because anything a user inputs is a string. So, let's say the user inputs "1", then you get:
filename = "1txt"
Then you do:
any(name in s for s in filename):
When you loop over the string "1txt":
for s in filename
you get letters back, so you are asking:
any(name in "1" ....)
...which appears to be nonsensical.
I have been asked to save the student's last three scores.
Based on your code, I have no inkling what that even remotely means. How about you post:
I have this....
I want this....
In the meantime, here's some stuff you can try. The shelve module will make your life much easier:
import shelve
fname = "scores"
name = "John"
current_scores = [75, 98]
#shelve will add a .db extension to the filename,
#but you use the name without the .db extension.
with shelve.open(fname) as db:
old_scores = db.get(name, []) #db is dictionary-like. Get previously stored scores--if any,
# or return an empty list
old_scores.extend(current_scores) #Add the current scores to the old scores.
db[name] = old_scores[-3:] #Save the last three scores in the file.
#Time passes....
nane = "John"
current_scores = [67, 80, 41]
with shelve.open(fname) as db:
old_scores = db.get(name, [])
old_scores.extend(current_scores)
old_scores.sort()
print(old_scores)
db[name] = old_scores[-3:]
with shelve.open(fname) as db:
print(db["John"])
--output:--
[41, 67, 75, 80, 98, 98]
[80, 98, 98]

Python: Using an input to determine what line to save on

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)

Keeping high scores in a text file

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

Categories