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
Related
When a user enters an input and if it is not available, the print executes twice
How do I fix it???
if ask.lower() == 'open':
with open(filename, 'r') as f:
contents = f.read().splitlines()
search_name = input("What is your name? ")
for line in contents:
if line.find(search_name) != -1:
print(line)
else:
print("Unable to find your name")
output:
Unable to find your name
Unable to find your name
Here is a more robust construct:
if ask.lower() == 'open':
with open(filename) as f:
name = input('What is your name? ')
for line in f:
if name in line:
print(line)
break
else:
print('Unable to find your name')
You are invoking the print command for every entry in your file!
Let me clarify, for the name that you get as input into search_name, you are looping over EVERY LINE that you have read from a file (in your case it seems that the file had 2 lines).
Your if cluase is not what you want. What you need is something like this:
if ask.lower() == 'open':
with open(filename, 'r') as f:
contents = f.read().splitlines()
search_name = input("What is your name? ")
is_found = false
for line in contents:
if line.find(search_name) != -1:
is_found = true
print(line)
if not is_found:
print("Unable to find your name")
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")
Trying to do a contact list where you can add and remove people from a .txt, i can add people but i get this line of error when i try to write out all the lines in the txt but the one i want to remove. I've seen other threads but don't understand what i should change.
Error: AttributeError: 'list' object has no attribute 'write'
from model_contact import Contact
toDo = input("Add or remove contact: ")
if toDo == "add":
name = input("Name: ")
contactlist = open("contactlist.txt", "a")
contactlist.write("\n" + name)
contactlist.close()
print(name + " is now added to the contactlist!")
elif toDo == "remove":
name = input("Name of removal: ")
contactlist = open("contactlist.txt", "r")
lines = contactlist.readlines()
contactlist.close()
open("contactlist.txt", "w")
for line in lines:
if line.strip("\n") != name:
lines.write(line)
Just to sum up all the comments from above in a code snippet :
from model_contact import Contact
toDo = input("Add or remove contact: ")
name = input("Name: ")
if toDo == "add":
with open("contactlist.txt", "a") as contactlist:
contactlist.write("\n" + name)
print(name + " is now added to the contactlist!")
elif toDo == "remove":
with open("contactlist.txt", "r") as contactlist:
lines = contactlist.readlines()
with open("contactlist.txt", "w") as ncl: #cnl == new contact list
for line in lines: # lines here are the read lines from above
if line.strip("\n") != name:
ncl.write(line)
This code is very direct and has a serious flaw, which is the the second opening of the file, which if it is a big one, could be a problem.
To reduce the impact if the file is big, i would try this:
with open("contactlist.txt", "r+") as contactlist:
lines = contactlist.readlines()
tmp = []
for num, line in enumerate(lines):
if line.strip("\n") == name:
tmp.append(num)
for num in tmp:
lines.pop(num)
contactlist.writelines(lines)
def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
for line in lines:
username, lel, type = line.split("/")
while name == username:
name = input("input name again: ")
tip = True
with open("users.txt", "w") as users:
users.write(str(red))
#
#I do not know how to perform a given modification and enrollment into place in #the text.
#
#I wont to change word False to True for username i input.
#I have this text in file users:
#Marko123/male/False
#Mimi007/female/False
#John33/male/False
#Lisa12/female/False
#Inna23/female/False
#Alisa27/female/False
I won't to change word False to True for username I input.
I have this text in file users:
Marko123/male/False
Mimi007/female/False
John33/male/False
Lisa12/female/False
Inna23/female/False
Alisa27/female/False
You can just use the csv library and forget about string manipulation:
import csv
def false_to_true():
#read from user.txt file into list(data)
with open('users.txt', 'r') as userfile:
data = [row for row in csv.reader(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)]
while True:
#waiting for input until you enter nothing and hit return
username = input("input name: ")
if len(username) == 0:
break
#look for match in the data list
for row in data:
if username in row:
#change false to true
row[2] = True
#assuming each username is uniqe break out this for loop
break
#write all the changes back to user.txt
with open('users.txt', 'w', newline='\n') as userfile:
dataWriter = csv.writer(userfile,
delimiter="/",
quoting=csv.QUOTE_NONE)
for row in data:
dataWriter.writerow(row)
if __name__ == '__main__':
false_to_true()
Open the input and output files, make a set out of the user-input names (terminated by a blank line), then create a generator for strings of the proper format that check for membership in the user-input names, then write these lines to the output file:
with open('names.txt') as f, open('result.txt', 'w') as out:
names = {name for name in iter(input, '')}
f = ('{}/{}/{}'.format(a,b,'True\n' if a in names else c) for a,b,c in (line.split('/') for line in f))
output.writelines(f)
To modify a text file inplace, you could use fileinput module:
#!/usr/bin/env python3
import fileinput
username = input('Enter username: ').strip()
with fileinput.FileInput("users.txt", inplace=True, backup='.bak') as file:
for line in file:
if line.startswith(username + "/"):
line = line.replace("/False", "/True")
print(line, end='')
See How to search and replace text in a file using Python?
Ask for name and iterate throw your lines to check for username, like this:
def false_to_true():
name = input("Input name: ")
file=open("users.txt","r")
lines = file.readlines()
file.close()
users = open("users.txt", "w")
for line in lines:
username, lel, type = line.split("/")
if name == username:
type = 'True\n'# \n for new line type ends with '\n'
users.write("/".join([username, lel, type]))
users.close()
false_to_true()
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