-2

My code is a little complicated so firstly I will explain. Basically I am trying to create a simple arithmetic game that asks a user/student 10 questions with random numbers from one to ten. This data (their name and score out of 10) is then written to a file named class_a.txt in the following format:

Student_Name,7
Another_Person,5

I then want to read class_a.txt back. However, When I read it back I need to store all the information that is read back in a dictionary. I'm currently doing that like this:

def updateScores():
for line in fhandle:
    finder = line.find(",")
    newKey = line[0:finder]
    newValue = line[finder+1:len(line)-1]
    scores_content[newKey] = newValue

Where the function is getting called after the class_a.txt file is already opened for a read operation. And scores_content is already defined. But, if a student does two quizzes so the file may look like this:

Student_A,6
Student_A,5

Then when I read back and print out the dictionary it just returns:

['Student_A':'5']

I wan't it to return the key in this case Student_A but with both 5 and 6 as it's values.

Basically I need to know how to read back from a file and when duplicate names appear add both scores as values to a key in a dictionary. This is what I have attempted so far...

import random

username = input("Enter students name: ")

while username.isalpha() == False:
    print ("Invalid name for student entered")
    username = input("Enter students name: ")

score = 0
answer = 0

for i in range(10):
    numOne = random.randint(1,10)
    numTwo = random.randint(1,10)

    operators = (" + "," - "," * ")
    operator = random.choice(operators)

    if operator == " + ":
        answer = numOne + numTwo
    elif operator == " - ":
        answer = numOne - numTwo
    elif operator == " * ":
        answer = numOne * numTwo

    question = "What is " + str(numOne) + operator + str(numTwo) + "? "

    user_answer = int(input(question))

    if user_answer == answer:
        score = score + 1
        print ("That is correct!")
    else:
        print ("That is incorrect!")

print (username + " you got " + str(score) + " out of 10")


user_class = input("What class is the student in (a/b/c)? ")
user_class = user_class.lower()

classes = ('a','b','c')

while user_class not in classes:
    print ("Invalid class entered")
    user_class = input("What class is the student in (a/b/c)? ")

if user_class == "a":
    fhandle = open("class_a.txt","a")
    fhandle.write(username.capitalize() + "," + str(score) + "\n")
elif user_class == "b":
    fhandle = open("class_b.txt","a")
    fhandle.write(username.capitalize() + "," + str(score) + "\n")
else:
    fhandle = open("class_c.txt","a")
    fhandle.write(username.capitalize() + "," + str(score) + "\n")

fhandle.close()


def updateScores():
    for line in fhandle:
        finder = line.find(",")
        newKey = line[0:finder]
        newValue = line[finder+1:len(line)-1]
        scores_content[newKey] = newValue
        for line in fhandle:
            newValues = []
            finderTwo = line.find(",")
            newKeyTwo = line[0:finderTwo]
            newValueTwo = line[finderTwo+1:len(line)-1]
            if newKeyTwo == newKey:
                newValues.append(newValue)
                newValues.append(newValueTwo)
                scores_content[newKey] = newValues
            else:
                print("No duplicate found for current line",line)
                scores_content[newKey] = newValue
    print(scores_content)

user_class = input("What classes results would you like to view (a/b/c)? ")
while user_class not in classes:
    user_class = input("Invalid class entered\n" + "What classes results would you like to view (a/b/c)? ")

print("What sorting method would you like to use?" + "\nA = Alphabetically" + "\nB = Average score maximum to minimum" + "\nC = Maximum to minimum")

method = input("Enter a sorting method: ").lower()
while method not in classes:
    method = input("Invalid method entered\n" + "Enter a sorting method: ")

scores_content = {}
if user_class == "a":
    fhandle = open("class_a.txt","r")
    updateScores()
elif user_class == "b":
    fhandle = open("class_b.txt","r")
    updateScores()
else:
    fhandle = open("class_c.txt","r")
    updateScores()
fhandle.close()
Kara
  • 6,115
  • 16
  • 50
  • 57
  • FWIW, there have been _many_ questions asked on SO in relation to this [GCSE Computing programming task](https://www.reddit.com/r/Python/comments/2gawvg/gcse_computing_programming_tasks_14_16_year_olds), so you might get a few useful ideas by looking at those questions. – PM 2Ring Nov 11 '15 at 10:22
  • Burhan Khalid has answered the question you asked, but I notice another problem with your code. The inner `for line in fhandle:` loop will read all the lines of the file, leaving the file cursor at the end of the file, so when the outer `for line in fhandle:` loop next tries to read from the file it will get nothing. You can reset the file position using the `.seek()` method, but it's probably simpler to just read the file once and store the file data in a list of lines. – PM 2Ring Nov 11 '15 at 10:22

1 Answers1

1

You need to store the values in a list, as a dictionary cannot have duplicate keys.

In other words, you need {'Student_A': [7,6], 'Student_B': [5]}, try this instead:

results = {} # this is an empty dictionary
with open('results.txt') as f:
   for line in f:
     if line.strip(): # this skips empty lines
        student,score = line.split(',')
        results.setdefault(student.strip(), []).append(int(score.strip()))

print(results) # or you can do this:
for student,scores in results.iteritems():
    print('Scores for: {}'.format(student))
    for score in scores:
        print('\t{}'.format(score))
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284