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}