How can I make the saving to the dictionaries more efficient as well as making my overall code more efficient?
import random import sys import shelve def get_input_or_quit(prompt, quit="Q"): prompt += " (Press '{}' to exit) : ".format(quit) val = input(prompt).strip() if val.upper() == quit: sys.exit("Goodbye") return val def prompt_bool(prompt): while True: val = get_input_or_quit(prompt).lower() if val == 'yes': return True elif val == 'no': return False else: print ("Invalid input '{}', please try again".format(val)) def prompt_int_small(prompt='', choices=(1,2)): while True: val = get_input_or_quit(prompt) try: val = int(val) if choices and val not in choices: raise ValueError("{} is not in {}".format(val, choices)) return val except (TypeError, ValueError) as e: print( "Not a valid number ({}), please try again".format(e) ) def prompt_int_big(prompt='', choices=(1,2,3)): while True: val = get_input_or_quit(prompt) try: val = int(val) if choices and val not in choices: raise ValueError("{} is not in {}".format(val, choices)) return val except (TypeError, ValueError) as e: print( "Not a valid number ({}), please try again".format(e) ) role = prompt_int_small("Are you a teacher or student? Press 1 if you are a student or 2 if you are a teacher") if role == 1: score=0 name=input("What is your name?") print ("Alright",name,"welcome to your maths quiz." " Remember to round all answers to 5 decimal places.") level_of_difficulty = prompt_int_big("What level of difficulty are you working at?\n" "Press 1 for low, 2 for intermediate " "or 3 for high\n") if level_of_difficulty == 3: ops = ['+', '-', '*', '/'] else: ops = ['+', '-', '*'] for question_num in range(1, 11): if level_of_difficulty == 1: max_number = 10 else: max_number = 20 number_1 = random.randrange(1, max_number) number_2 = random.randrange(1, max_number) operation = random.choice(ops) maths = round(eval(str(number_1) + operation + str(number_2)),5) print('\nQuestion number: {}'.format(question_num)) print ("The question is",number_1,operation,number_2) answer = float(input("What is your answer: ")) if answer == maths: print("Correct") score = score + 1 else: print ("Incorrect. The actual answer is",maths) if score >5: print("Well done you scored",score,"out of 10") else: print("Unfortunately you only scored",score,"out of 10. Better luck next time") filename1 = [] filename2 = [] filename3 = [] class_number = prompt_int_big("Before your score is saved ,are you in class 1, 2 or 3? Press the matching number") if class_number == 1: with shelve.open(filename1) as db: old_scores = db.get(name, []) old_scores.extend(str(score)) db[name] =score[-3:] if class_number == 2: with shelve.open(filename2) as db: old_scores = db.get(name, []) old_scores.extend(str(score)) db[name] =score[-3:] if class_number == 3: with shelve.open(filename3) as db: old_scores = db.get(name, []) old_scores.extend(str(score)) db[name] =score[-3:] if prompt_bool("Do you wish to view previous results for your class"): for line in lines: print (line) else: sys.exit("Thanks for taking part in the quiz, your teacher should discuss your score with you later") if role == 2: class_number = prompt_int_big("Which class' scores would you like to see? Press 1 for class 1, 2 for class 2 or 3 for class 3") filename = (str(class_number) + "txt") sort_or_not = int(input("Would youlike to sort these scores in any way? Press 1 if the answer is no or 2 if the answer is yes")) if sort_or_not == 1: f = open(filename, "r") lines = [line for line in f if line.strip()] lines.sort() for line in lines: print (line) if sort_or_not == 2: type_of_sort = int(input("How would you like to sort these scores? Press 1 for scores in alphabetical order with each student's highest score for the tests, 2 if you would like to see the students' highest scores sorted from highest to lowest and 3 if you like to see these student's average scores sorted from highest to lowest")) if type_of_sort == 1: with open(filename , 'r') as r: for line in sorted(r): print(line, end='') if type_of_sort == 2: file = open(filename, 'r') lines = file.read().splitlines() s = {lines[i]:[int(k) for k in lines[i+1:i+4]] for i in range(0,len(lines),4)} for i in sorted(s.keys()): print (i,max(s[i])) avg_mark = lambda name:sum(s[name])/len(s[name]) for i in sorted(s.keys(),key=avg_mark,reverse=True): print (i,avg_mark(i)) if type_of_sort == 3: file = open(filename, 'r') lines = file.read().splitlines() s = {lines[i]:[int(k) for k in lines[i+1:i+4]] for i in range(0,len(lines),4)} for i in sorted(s.keys()): print (i,max(s[i])) high_mark = lambda name:max(s[name]) for i in sorted(s.keys(),key=high_mark,reverse=True): print (i,high_mark(i))