Just serialize your data using pickle or json. Here is an example using json to serialize the scores (storing scores in a dict - a mapping between a name and a score):
# import the serializing library
import json as serializer
Now we'll make a function to write a score to a given file:
def write_score(score_file_name, name, score):
scores = read_scores(score_file_name)
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
What it does is:
- Load the serialized results object from the score file (
dict)
- update the score
dict (add key / update value of key)
- write the updated
dict to the file (using json.dump)
When writing the write_score function, we were missing a read_scores function, that enables us to see what the current scores are. So let's write this read_scores:
def read_scores(score_file_name):
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
What read_scores does is:
- Read the serialized
dict (using json.load)
Now we can test if it actually works. Here is a small example:
# set the score file name
SCORES_FILE_NAME = 'scores.txt'
write_score(SCORES_FILE_NAME, 'john', 10)
print(read_scores(SCORES_FILE_NAME))
write_score(SCORES_FILE_NAME, 'jim', 11)
print(read_scores(SCORES_FILE_NAME))
# overwrite john's score
write_score(SCORES_FILE_NAME, 'john', 12)
print(read_scores(SCORES_FILE_NAME))
Tip 1: You may want to use name.lower() when writing a score so that john and John are considered the same user.
Tip 2: Because we referenced the json library as serializer, and it has the same API as pickle, you can choose between the two simply by replacing import json as serializer to import pickle as serializer. Just make sure you delete the scores file since they don't serialize data the same way.
The whole code together:
# import the serializing library
import json as serializer
def write_score(score_file_name, name, score):
scores = read_scores(score_file_name)
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
def read_scores(score_file_name):
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
# TESTS
# set the score file name
SCORES_FILE_NAME = 'scores.txt'
write_score(SCORES_FILE_NAME, 'john', 10)
print(read_scores(SCORES_FILE_NAME))
write_score(SCORES_FILE_NAME, 'jim', 11)
print(read_scores(SCORES_FILE_NAME))
# overwrite john's score
write_score(SCORES_FILE_NAME, 'john', 12)
print(read_scores(SCORES_FILE_NAME))
Output:
{u'john': 10}
{u'john': 10, u'jim': 11}
{u'jim': 11, u'john': 12}
To read a specific score you can use the existing method read_scores:
def read_score(score_file_name, name):
return read_scores(score_file_name)[name]
You can make the functions specific to a file if you understand closures, the following way:
def write_score(score_file_name):
# create closure specific to 'score_file_name'
def write_score_specific(name, score):
scores = read_scores(score_file_name)
# we're going to make a 'read_scores' with closures as well!
# so use that one...
scores_reader = read_scores(score_file_name)
scores = scores_reader()
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
# return file-specific function
return write_score_specific
Now, we only have to call the function with the file name argument once, and from that moment we can use the result ot write scores:
# create specific 'write_score' for our file
score_txt_writer = write_score('scores.txt')
# update john's score to 10 without specifying the file
score_txt_writer('john', 10)
The same done with read_score:
def read_scores(score_file_name):
# create closure function
def read_scores_specific():
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
return read_scores_specific
The whole code with closures together:
# import the library
import serializer
# CLOSURES
SCORES_FILE = 'scores.txt'
def read_scores(score_file_name):
# create closure function
def read_scores_specific():
try:
with open(score_file_name, 'r') as f:
scores = serializer.load(f)
return scores
except IOError:
# if file does not exist - we have no scores
return {}
return read_scores_specific
def write_score(score_file_name):
# create closure specific to 'score_file_name'
def write_score_specific(name, score):
scores_reader = read_scores(score_file_name)
scores = scores_reader()
# add score
scores[name] = score
with open(score_file_name, 'w') as f:
serializer.dump(scores, f)
# return file-specific function
return write_score_specific
# create specific 'write_score' for our file
score_txt_writer = write_score(SCORES_FILE)
# update john's score to 10 without specifying the file
score_txt_writer('john', 10)
score_txt_reader = read_scores(SCORES_FILE)
print score_txt_reader()
Output:
{u'john': 10}