0

so I've been trying to learn Python and I have this little app to conduct an English test. But I want to take the 'score' and put it into a file but not as a string but as an integer. Then I also want to take it out as one.

Also along the way I sometimes will create files if the 'name' is new so I want to check if the file is empty and if so to put a 0 in there. Any tips?

And of course if you have any other criticism I would be happy to hear it :)

questions = ["1. You won't find Jerry at home right now. He ______________ (study) in the library."
        "2. Samantha ______________   (do) her homework at the moment."
        "3. We______________  (play) Monopoly a lot."
        "4. Ouch! I ______________ (cut, just) my finger!"
        "5. Sam (arrive) ______________in San Diego a week ago."]
keys = ["is studying"
    "is doing"
    "play"
    "have just cut"
    "arrived"]

print("Hello. This is an English test.")
name = input("What is your name?")

#creates a file with the person's name
file = open("%sScore.txt" % name, "w+")

#reads that person's score
score = file.read()

#if there is nothing in the file it puts in 0
if (len(score) == 0):
file.write(bytes('0'), "UTF-8")

print("Type in the verb given in brackets in the correct form.\n")

#this loop asks questions and determines whether the answer is right
for i in range (0, 4):
print("Your current score is: %d" % score)
answer = input("%s" % questions[i])
if(answer == "keys[i]"):
    print("You are right! You get one point")
    score = score + 1
else :
    print("Wrong! You lose one point!")
    score = score - 1

#end of the test and writing the score to the file
print("Congratulations! You finished the test. Your score is %d" % score)
file.write(bytes("%d" % score, "UTF-8"))

file.close()

2 Answers2

0

It's likely easiest to just write it as a string and then read it back as a string:

file = open(filename, 'w')
file.write(str(score))

Later:

score = int(file.read())

However, if there's a reason you want to write it in binary (say to obfuscate the score a bit) there are many options. While it's definitely possible to say, write it using standard integer encoding, I typically just go with the pickle module if I want to serialize data:

import pickle

file = open(filename, "w")
pickle.dump(score, file)
file.close()

Later:

file = open(filename)
score = pickle.load(file)

I like this approach because it works for serializing any kind of data, not just integers. See this post for some leads on writing or reading in full binary, if that's what you truly seek:

Reading a binary file with python

Finally, since you asked for other feedback: if I were implementing this and I wasn't expecting a huge data set, I would just store all of the scores in a dictionary, then pickle and unpickle that dictionary to a single file as necessary.

Community
  • 1
  • 1
Christian
  • 709
  • 3
  • 8
0

If you want to persist the data, using a dict and pickling would be a good approach, you can use a single file and use the name to lookup the user, like your own approach though you will have problems if two users have the same name so you might want to think of how you would make each user choose a uniqe identifier:

questions = ["1. You won't find Jerry at home right now. He ______________ (study) in the library.",
             "2. Samantha ______________   (do) her homework at the moment.",
             "3. We______________  (play) Monopoly a lot.",
             "4. Ouch! I ______________ (cut, just) my finger!",
             "5. Sam (arrive) ______________in San Diego a week ago."]
keys = ["is studying",
        "is doing",
        "play",
        "have just cut",
        "arrived"]

import pickle


def ask(scores):
    print("Type in the verb given in brackets in the correct form.\n")
    # this loop asks questions and determines whether the answer is right
    # if new user default score to 0
    score = scores.get(name, 0)

    # zip the questions and answer together
    for q, a in zip(questions, keys):
        print("Your current score is: %d" % score)
        answer = input(q)
        if answer == a:
            print("You are right! You get one point")
            score += 1
        else:
            print("Wrong! You lose one point!")
            # don't want minus scores.
            if score > 0:
                score -= 1
    # update or create user name/score pairing and dump to file
    scores[name] = score
    with open("score.pkl", "wb") as f:
        pickle.dump(scores, f)


# creates a file with the person's name
print("Hello. This is an English test.")
name = input("What is your name?")


try:
   # first run file won't exist 
    with open("score.pkl", "rb") as f:
        scores = pickle.load(f)
except IOError as e:
    print(e)
    scores = {}

ask(scores)
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • Thanks for putting so much work into this! I'll now go and try and understand what each part does :D there are so many new things here :O – JakeTheSnake Apr 03 '16 at 11:56
  • By the way what is up with this line: – JakeTheSnake Apr 03 '16 at 12:25
  • scores[name] = score Because the score increases or decreases with each answer so shouldn't this be the other way round? The new score updated to the dictionary next to the name? – JakeTheSnake Apr 03 '16 at 12:27
  • Plus why is it a square brace and not a curly one? its a dictionary we are searching for the 'name' right? – JakeTheSnake Apr 03 '16 at 12:28
  • @OmenOfTheCode, because we are accessing a dictionary by key, if the user does not already exist the score defaults to 0, `score = scores.get(name, 0)` if it scores exist we add/update the new score then `scores[name] = score` to the new score before we dump the dict to disk – Padraic Cunningham Apr 03 '16 at 15:48