Reputation: 29
This is python and I am using idle version 3.4.2. So at the moment my code works but I would like to adapt it to be able to: Save the most recent three scores for the name (as they re-run the code and the scores are saving in the text file). However there is an issue that whatever "name" is entered, it re saves on its own line with the score, rather than "appending" (I know this is because it's not saved in the form of a list/dictionary, but how would I do that? - or I read that you can "split" the line?)
That is my first question and if anyone can help I would be so hugely appreciative, I am new to python so this is ab ig challenge for me! Any comments or suggestions are very welcome!!
import random #import module
print("What is your name?") #prints writing in brackets
name = input().title() #Capitalizes the first letter of the word inputted
print("What class are you in? (Enter 1, 2 or 3)") #asks the user to input a number
while True:
try:
class_number = int(input()) #asks for an integer input from user
except ValueError:
print("Sorry, I didn't understand that, please try again") #print statement
continue
if class_number > 3: #if input is more than 3
print("SORRY but that class isn't recognised, try again") #print statement
continue
else:
print ("Hello,", name, "from class", class_number, "welcome to my quiz") #prints writing in brackets and anything saved in the variable "name" and "class_number"
break #break out of loop
score = 0 #sets the variable "score" to zero
question = 0 # sets the variable "question" to zero
while question < 3:#If questions (intitally set to 0) is smaller than 10, carry out this function
question +=1 # add one to the value of "question"
maths = random.randint(1,3) #randomly generate a number from 1-3 and store as "maths"
num1 = random.randint(1,10)#randomly generate an integer from 1-10 and store as "num1"
num2 = random.randint(1,10)#randomly generate a second integer from 1-10 and store as "num2"
if maths == 1: #if the number generated is 1
print(num1, "+", num2) #prints num1 + num2
ans = num1 + num2 #sets "ans" to equal the value of num1 added to num2
elif maths == 2: #if the number generated is 1
print(num1, "*", num2) #print num1 multiplied by num2
ans = num1 * num2 #sets "ans" to equal the value of num1 multiplied by num2
else: #else run this part of code
print(num1, "-", num2) #print num1 subtracted by num2
ans = num1 - num2 #sets "ans" to equal the value of num1 subtracted by num2
while True:
try:
user_ans = int(input()) #user inputs answer to question
except ValueError: #runs when the user input is no an integer
print ("SORRY but that answer isn't recognised, try again")
else:
break
if user_ans == ans:
score+=1
print("Well done, you are CORRECT")
else:
print("SORRY, you are INCORRECT") #print writing in brackets
print("The correct answer was", ans)
if score == 10: #run this part of code if "score" equals 10
print("fantastic", name, "you got full marks!") #print statement and name
elif score >= 6: #run this part of code if "score" is larger than or equal to 6
print("well done, there's some improvement to be done here though", name, "you got", score, "/10")# then print statement and score
elif score <=5: #run this part of code if "score" is smaller than or equal to 5
print("hmm, maybe some more practise would be beneficial", name, "you got", score, "/10") #then print statement and score
class_number = str(class_number) + ".txt" #this adds '.txt' to the end of the file (therefore creating a text file) so it can be used to create a file under the name of the class
file = open(class_number, 'a') #opens the file in 'append' mode so you don't delete all the information
file.write(str(name + " : ")) #writes the name and ":" to file
file.write(str(score)) #writes the score to file
file.write('\n')#writes the score to the file
file.close()#safely closes the file to save the information
view = int(input("would you like to view the scores? If yes, press 1 or not press 2"))
if view == 1:
exit
elif view == 2:
exit #to be completed
Upvotes: 0
Views: 541
Reputation: 253
Some answers suggest storing the scores as JSON (good idea) or pickling them (bad idea! it's dangerous). This answer assumes you want to keep the flat-file, oldest-first format.
You're opening the file in append mode, so you won't be able to change any of the content. To make changes, you'll first need to read from the file:
try:
fileh = open(class_number, 'r')
oldlines = fileh.readlines()
fileh.close()
except IOError: # If we didn't find the file, there were no old scores
oldlines = []
Note that this reads all the lines; if your file grows very large, it won't all fit into memory and you should read line-by-line and write as you go.
For each line:
It's slightly easier to keep track of the most-recent scores if we start with the most recent line, so let's do that:
updatedlines = []
recentscores = 0
for line in oldlines[::-1]: # go backwards, most recent line first
(lname, lscore) = line.split(" : ") # read the name and the score from the line; this will break if the name contains " : "
if lname == name:
recentscores += 1 # keep track of how many scores we have for this person
if recentscores <3:
updatedlines.append(line)
else:
updatedlines.append(line)
updatedlines = updatedlines[::-1] # put the lines back in the right order
Finally, add the new score.
updatedlines.append("%s : %d\n" % (name, score))
Now we can write the lines back to the file:
fileh = open(class_number, 'w')
fileh.writelines(updatedlines)
fileh.close()
Upvotes: 0
Reputation: 511
If you're ok with changing the look of your file, try saving the file as json.
At the top of your code, load in the scores from the file:
import json
with open('{}.txt'.format(class_number)) as f:
scores = json.load(f)
Then you can modify scores in your dictionary and write back to the file:
scores[name] = score
with open('{}.txt'.format(class_number)) as f:
json.dump(scores, f)
This code doesn't store more than the latest score, but you can explore options for saving more than one score per name. I suggest taking a look at defaultdict.
Upvotes: 0
Reputation: 91
If you want to save the user's score to a list...
my_list = []
my_list.append(score)
You may want to read in the file before the game starts as well. Then, you will need to populate the list with scores that are in the text file.
with open(class_number) as scorefile:
for line in scorefile:
my_list.append(line)
Finally, when the game ends you'll want to add the user's score to the file. In this case, I'll keep it simple and not include the person's name for an example, you can still add the line to the list though.
f = open(class_number 'w')
f.write("\n" + score)
f.close()
And then if they view the scores, just print off the value of my_list, separating each element in the list by a new line.
Upvotes: 1
Reputation: 3773
If you want to keep it human readable write it in a json file:
import json
your_dictonary = {"my_key":"one_value"}
str_to_save = json.dumps(your_dictonary)
# Then write it to a file as you did before
Loading is almost as easy:
json.loads(file_content) # after you read the file as usual
Upvotes: 1
Reputation: 1932
Use the pickle
module to store your data. Organise your user => score
relation into an dictionary, then call pickle.dump(filename, theDict)
to save it to a file.
When you need it back, call theDict = pickle.load(filename)
and it will load the data from the pickle file. This approach is better than you having to devise your own parsing algorithm.
Upvotes: 0