-1

I am trying to print out high scores from a quiz, from a txt file, and align the correct username with the correct score. I am also trying to print the scores from highest to lowest. Currently the scores are highest to lowest, but I haven't been able to keep the scores with the names. I have a brief understanding of dictionaries but I haven't learned them yet as I am new to coding. I cannot find an answer to my question on here and am new to the website so I am posting the whole code as I do not know what you will need and what you don't need.

I am not opposed to massively re-writing this, but I would like tom change as little as possible.

P.S:

Sorry for any weird formatting, copy paste didn't work as intended

    #IMPORTS
import random
import time

#################TO DO##################
#Add 'Days since written' thing

################## TO ADD TO PLAN #################
#How I choose what questions to ask
#How I make sure I do not repeat questions
#Keeping track of score
#global highscore


def main(): #Main question asking function
global score
loop_text = 0 #Used for print formatting
while True:
    if loop_text == 0: #Used for print formatting
        go_ahead = input('\nAre you ready to continue? Y or N? ')
        print('---------------------------------------')
        if go_ahead in ["Y", "y", "Yes", "yes", "YES"]: #This checks for all logical ways they would answer yes
            break
        elif go_ahead in ["N", "n", "no", "No", "NO"]: #This checks for all logical ways they would answer no
            loop_text = 1 #Used for print formatting
            print('Oh... ok')
            time.sleep(1) #Delay running the next line for one second
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
        else:
            print('Yes or no only please!')
    else:
        go_ahead = input('\nNow are you ready to continue? Y or N? ') #Used for print formatting
        print('-----------------------------------------')
        if go_ahead in ["Y", "y", "Yes", "yes", "YES"]: #This checks for all logical ways they would answer yes
            break

        elif go_ahead in ["N", "n", "no", "No", "NO"]: #This checks for all logical ways they would answer no
            loop_text = 1
            print('Oh... ok')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
        else:
            print('Yes or no only please!')            



score = 0 #Setting score
error_count = 0 #GOTTA CHECK FOR THOSE ERRORS

#Questions
questions = ['\nWhat was the first video game ever made?\n',
             '\nWhat was the most expensive video game to ever be developed?\n',
             '\nWhat amount of time a day does the average gamer (In the US, age 13 or older) spend gaming?\n',
             '\nWho is the founder of Nintendo?\n',
             '\nWhat was the most purchased game of 2017?\n',
             '\nWhen was E3 [Electronic Entertainment Expo] 2017?\n', '\nWhat was the most popular console of 2010?\n',
             '\nWho was the most subscribed gaming youtuber of 2012?\n',
             '\nWho won the Game of The Year award 2016?\n',
             '\nWhen did DOOM release?\n']



#Options in the same pisitions as the questions so the program can print the right options easy
options = ['a)  God of War 9\nb)  Pacman \nc)  Pong \nd)  Tennis for Two', 
           'a)  Destiny\nb)  Call of Duty: Modern Warfare 2  \nc)  Grand Theft Auto: V  \nd)  Disney Infinity',
           'a)  54 minutes\nb)  25 hours\nc)  2 hours\nd)  30 minutes\n', 
           'a)  Fusajiro Yamauchi\nb)  Bob Dylan\nc)  Steve Bovaird\nd)  Nihonjin no Shimei',
           'a)  Jesus sim\nb)  Farming Simulator 2017\nc)  Call of Duty: WWII\nd)  Destiny 2',
           'a)  13 Jun 2017 - 15 Jun 2017\nb)  13 Jun 2017 - 14 Jun 2017\nc)  15 July 2017 - 13 July 2017\nd)  10 Jun 2017 - 18 Jun 2017)',
           'a)  Xbox 360\nb)  PlayStation 3\nc)  Xbox 1\nd)  PlayStation 4',
           'a)  PrettyL8r\nb)  Pewdiepie\nc)  Greg\nd)  NotGreg', 
           'a)  Overwatch\nb)  Treyarch\nc)  Blizzard\nd)  Rainbow Six Siege', 
           'a)  December 10, 1993\nb)  February 23, 1995\nc)  January 32, 20019\nd)  Yesterday']

#Answers in the same pisitions as the questions so the program  easy
answers = ['d', 'b', 'a', 'a', 'c', 'a', 'a', 'b', 'c', 'a']


for i in range(len(questions)): #Repeating for how many questions there are
    q_ask = random.randint(0,len(questions)-1) #Asigning a variable to a random variable equal to the length of the list -1 because of how piition 1 is actually pisition 0
    while True:
        if error_count > 0:
            time.sleep(1) #Printing question with a delay because they tried to answer this question with an invalid response
            print (questions[q_ask])
            time.sleep(1)
        else:
            print (questions[q_ask]) #Printing question
        print (options[q_ask]) #Printing options
        user_answer = input('What is your answer?:   ') #What is your answer?
        user_answer = user_answer.lower() #This makes it easier to make decisions based on their input

        if user_answer in ['a', 'b', 'c', 'd']:
            if user_answer == answers[q_ask]: #This will run if they input a valid reponse
                print('Good job! You are correct.')
                questions.pop(q_ask) #Popping the question from the list of questions. Popping works without bugs whereas .remove didn't
                options.pop(q_ask) #Popping the options from the list of options.
                answers.pop(q_ask) #Popping the answer from the list of answers.
                score += 1 #+1 Score!
                error_count = 0 
                break #Next question 
            else:
                print ('Unfortunately that is not correct! Better luck next time.')  #They have not answered correctly
                questions.pop(q_ask)
                options.pop(q_ask)
                answers.pop(q_ask)                    
                error_count = 0
                break #Next question
        else:
            time.sleep(1)
            print ('ERROR, please input a, b, c or d only plesae!') #This is to tell them that they input and invalid option
            time.sleep(1)
            error_count += 1
print('\nYour score is >>>', score)

def high_scores(): #Highscores function
top_5_name = []
top_5_int = []
repeat_n = 0
repeat_i = 0
i = 0

print('\nScore : Name\n')
template = """{score} : {name}"""
display_good = template.format(score=score,name=user_name)  
highscore_a = open("highscoreFile.txt",'a') #The file that keeps the highest scores of all time
highscore_a.write(display_good)
highscore_a.write('\n')
highscore_a.close()
highscore_r = open("highscoreFile.txt", "r") 

file_open = open('highscoreFile.txt', 'r')  # op
score_list=[line.rstrip('\n') for line in file_open]
file_open.close()

for i in score_list:
    split_top_5 = score_list[repeat_i].split(":")
    if len(top_5_int) < 5:
        top_5_int.append(int(split_top_5[0]))
        top_5_name.append(split_top_5[1])
    elif int(split_top_5[0]) < int(top_5_int[0]):
        top_5_int.append(int(split_top_5[0]))
        top_5_name.append(split_top_5[1])
    elif int(split_top_5[0]) < int(top_5_int[1]):
        top_5_int.append(int(split_top_5[0]))
        top_5_name.append(split_top_5[1])
    elif int(split_top_5[0]) < int(top_5_int[2]):
        top_5_int.append(int(split_top_5[0]))
        top_5_name.append(split_top_5[1])
    elif int(split_top_5[0]) < int(top_5_int[3]):
        top_5_int.append(int(split_top_5[0]))
        top_5_name.append(split_top_5[1])

    elif int(split_top_5[0]) < int(top_5_int[4]):
        top_5_int.append(int(split_top_5[0]))
    else:
        pass

    if len(top_5_int) == 6:
        top_5_int.sort(reverse=True)
        top_5_int.pop(5)
    else:
        pass

    repeat_i += 1

for i in score_list:
    split_top_5 = score_list[repeat_n].split(":")
    top_5_name.append(split_top_5[1])
    repeat_n += 1  


repeat_i = (top_5_int[0:5])
repeat_n = (top_5_name[0:5])

i = 0
num = 0
while True:
    if num < 5:
        try:
            print(repeat_n[num], ':', repeat_i[num])
            i += 1  
            num += 1
        except IndexError:
            pass
    else:
        break

#for i in score_list:
    #split_top_5 = score_list[repeat].split(":")
    #top_5_name.append(split_top_5[1])
    #repeat += 1

#top_5_name.sort(reverse=True)
#repeat = (top_5_name[0:5])
#for i in repeat:
    #print(i)        

while True:
user_name = input('\nHello! What is your name?: ') #The users inputs their name 

if len(user_name) == 0:
    print('\nError, nothing was entered.') #This will run if the user enters nothing
else:
    break

print('\nHello ', user_name.capitalize(), ', welcome to The Videogame Quiz!', sep='') #Welcome message

print('\nIn this quiz, you will be asked 10 questions about videogames.\nTry your best to answer all 10 correctly. Enter a, b, c or d,\ndepending on which answer you decide is right.') #Telling them how to do the quiz


while True: 
main() #Main program
while True: #Loop to here when the program uses continue
    go_again = input('\nDo you want to take the quiz again? Y or N: ') #Ask the user whether the user wants to take the quiz again or not
    if go_again in ["Y", "y", "Yes", "yes", "YES", "N", "n", "no", "No", "NO", "nO", "YeS", "yES", "yEs", "YEs", "yeS", 'CLEAR']: #This checks for all logical ways they would answer no
        break #break out of while True Loop
    else:
        print ('ERROR, please input Y or N') #Incorrect input

if go_again in ["Y", "y", "Yes", "yes", "YES", "YeS", "yES", "yEs", "YEs", "yeS"]: #Do they want to go again
    #They want to go
    continue #Loop to the while True
elif go_again == 'CLEAR':
    wipe_file = open("highscoreFile.txt",'w')
    wipe_file.close
    break   
else:
    #They do not want to go again
    high_scores() #Running the highscores function
    print ('\nGoodbye!') #Goodbye!
    break #Break out of while True Loop**strong text**
  • Please read [this](https://stackoverflow.com/help/mcve) and consider *editing* your question to (a) contain far, far less of the code. Only post what is directly relevant to your problem, we don't need the entire program! (b) include a sample of the text file you are reading in the *exact* format it is in in the text file. (c) An example (based on your sample text file data) of exactly what you want the output to look like. Note that the code you leave in from section (a) should only be the code needed to transform the text in (b) to the desired output in (c). – Dan Jul 15 '18 at 01:51
  • [Please include the minimum amount of code in your question needed to illustrate your problem.](http://idownvotedbecau.se/toomuchcode/) –  Jul 16 '18 at 10:27

2 Answers2

1

Ok! This took me a lot of time. Hope it is useful. PS: you will need to adjust some loops which i broke in the middle PSS: Ifa score, example: 5, appears twice in the highscore the last person with it will have his/her name twice. Sorry for not fixing this issue, it's already midnight here in Brazil. PSSS: Try not to use too many while True loops, it was really hard to understand your code PSSSS: Just another tip: try to use more calling and returning variables instead of global ones. Here is the code: :)

    #IMPORTS
import random
import time

#################TO DO##################
#Add 'Days since written' thing

################## TO ADD TO PLAN #################
#How I choose what questions to ask
#How I make sure I do not repeat questions
#Keeping track of score
#global highscore


def main(): #Main question asking function
    global score
    loop_text = 0 #Used for print formatting
    b = True 
    while b:
        if loop_text == 0: #Used for print formatting
        go_ahead = raw_input('\nAre you ready to continue? Y or N? ')
        print('---------------------------------------')
        if go_ahead in ["Y", "y", "Yes", "yes", "YES"]: #This checks for all logical ways they would answer yes
            break
        elif go_ahead in ["N", "n", "no", "No", "NO"]: #This checks for all logical ways they would answer no
            loop_text = 1 #Used for print formatting
            print('Oh... ok')
            time.sleep(1) #Delay running the next line for one second
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            b = not b
        else:
            print('Yes or no only please!')
        else:
        go_ahead = raw_input('\nNow are you ready to continue? Y or N? ') #Used for print formatting
        print('-----------------------------------------')
        if go_ahead in ["Y", "y", "Yes", "yes", "YES"]: #This checks for all logical ways they would answer yes
            break

        elif go_ahead in ["N", "n", "no", "No", "NO"]: #This checks for all logical ways they would answer no
            loop_text = 1
            print('Oh... ok')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            print('...')
            time.sleep(1)
            b = not b
        else:
            print('Yes or no only please!')




    score = 0 #Setting score
    error_count = 0 #GOTTA CHECK FOR THOSE ERRORS

    #Questions
    questions = ['\nWhat was the first video game ever made?\n',
             '\nWhat was the most expensive video game to ever be developed?\n',
             '\nWhat amount of time a day does the average gamer (In the US, age 13 or older) spend gaming?\n',
             '\nWho is the founder of Nintendo?\n',
             '\nWhat was the most purchased game of 2017?\n',
             '\nWhen was E3 [Electronic Entertainment Expo] 2017?\n', '\nWhat was the most popular console of 2010?\n',
             '\nWho was the most subscribed gaming youtuber of 2012?\n',
             '\nWho won the Game of The Year award 2016?\n',
             '\nWhen did DOOM release?\n']



    #Options in the same pisitions as the questions so the program can print the right options easy
    options = ['a)  God of War 9\nb)  Pacman \nc)  Pong \nd)  Tennis for Two', 
           'a)  Destiny\nb)  Call of Duty: Modern Warfare 2  \nc)  Grand Theft Auto: V  \nd)  Disney Infinity',
           'a)  54 minutes\nb)  25 hours\nc)  2 hours\nd)  30 minutes\n', 
           'a)  Fusajiro Yamauchi\nb)  Bob Dylan\nc)  Steve Bovaird\nd)  Nihonjin no Shimei',
           'a)  Jesus sim\nb)  Farming Simulator 2017\nc)  Call of Duty: WWII\nd)  Destiny 2',
           'a)  13 Jun 2017 - 15 Jun 2017\nb)  13 Jun 2017 - 14 Jun 2017\nc)  15 July 2017 - 13 July 2017\nd)  10 Jun 2017 - 18 Jun 2017)',
           'a)  Xbox 360\nb)  PlayStation 3\nc)  Xbox 1\nd)  PlayStation 4',
           'a)  PrettyL8r\nb)  Pewdiepie\nc)  Greg\nd)  NotGreg', 
           'a)  Overwatch\nb)  Treyarch\nc)  Blizzard\nd)  Rainbow Six Siege', 
           'a)  December 10, 1993\nb)  February 23, 1995\nc)  January 32, 20019\nd)  Yesterday']

    #Answers in the same pisitions as the questions so the program  easy
    answers = ['d', 'b', 'a', 'a', 'c', 'a', 'a', 'b', 'c', 'a']


    for i in range(len(questions)): #Repeating for how many questions there are
        q_ask = random.randint(0,len(questions)-1) #Asigning a variable to a random variable equal to the length of the list -1 because of how piition 1 is actually pisition 0
        b = True
        while b:
        if error_count > 0:
            time.sleep(1) #Printing question with a delay because they tried to answer this question with an invalid response
            print (questions[q_ask])
            time.sleep(1)
        else:
            print (questions[q_ask]) #Printing question
        print (options[q_ask]) #Printing options
        user_answer = raw_input('What is your answer?:   ') #What is your answer?
        user_answer = user_answer.lower() #This makes it easier to make decisions based on their input

        if user_answer in ['a', 'b', 'c', 'd']:
            if user_answer == answers[q_ask]: #This will run if they input a valid reponse
                print('Good job! You are correct.')
                questions.pop(q_ask) #Popping the question from the list of questions. Popping works without bugs whereas .remove didn't
                options.pop(q_ask) #Popping the options from the list of options.
                answers.pop(q_ask) #Popping the answer from the list of answers.
                score += 1 #+1 Score!
                error_count = 0 
                break #Next question 
            else:
                print ('Unfortunately that is not correct! Better luck next time.')  #They have not answered correctly
                questions.pop(q_ask)
                options.pop(q_ask)
                answers.pop(q_ask)                    
                error_count = 0
                break #Next question
        else:
            time.sleep(1)
            print ('ERROR, please input a, b, c or d only plesae!') #This is to tell them that they input and invalid option
            time.sleep(1)
            error_count += 1
    print('\nYour score is >>>', score)
    return score
def high_scores(user_name,score):
    sorted_dict = {}
    wipe_file = open("highscoreFile.txt",'a')
    wipe_file.write(user_name + ":" + str(score) + "\n")
        wipe_file.close()
    all_scores = []
    top_five = []
    sortNum = 0
    file_open = open('highscoreFile.txt', 'r')  # op
    lines = file_open.readlines()

    for line in lines:
        str_sortNum = str(sortNum)
        get_score = line.split(":")
        get_score = get_score[1]
        get_score = get_score.replace("\n","")
        get_score = int(get_score)
        all_scores.append(get_score)
        sorted_dict[str(get_score)] = str_sortNum
        sortNum = sortNum + 1

    all_scores.sort()

    top_five_list = all_scores[-5:]
    for i in top_five_list:
        x = sorted_dict.get(str(i))
        top_five.append(x)
    for i in top_five:
        try:
            j = int(i)
            print(lines[j])
        except:
            pass


b = True 
while b:
    user_name = raw_input('\nHello! What is your name?: ') #The users inputs their name 

    if len(user_name) == 0:
        print('\nError, nothing was entered.') #This will run if the user enters nothing
    else:
        break

    print('\nHello ' + user_name.capitalize() + ', welcome to The Videogame Quiz!') #Welcome message

    print('\nIn this quiz, you will be asked 10 questions about videogames.\nTry your best to answer all 10 correctly. Enter a, b, c or d,\ndepending on which answer you decide is right.') #Telling them how to do the quiz


b = True 
while b: 
    score = main() #Main program
    b = not b
b = True 
while b: #Loop to here when the program uses continue
    go_again = raw_input('\nDo you want to take the quiz again? Y or N: ') #Ask the user whether the user wants to take the quiz again or not
    if go_again in ["Y", "y", "Yes", "yes", "YES", "YeS", "yES", "yEs", "YEs", "yeS"]: #Do they want to go again
        None
    else:
        #They do not want to go again
        high_scores(user_name,score) #Running the highscores function
        print ('\nGoodbye!') #Goodbye!
        break #Break out of while True Loop**strong text**
1

I do not understand the logic in the very first while loop "Are you ready to continue? as I see no clear action if the answer is No.

Some suggestions to improve the code:

  • break it up in functions for example: input_username, play_quiz, handle_scores, exit_quiz, main
  • Use def main() for overall structure of the program to include calling the functions I mentioned above and use if __name__ == "__main__": main() and rename your main into something like play_quiz
  • for file input/ output use with open(filename.,.) as scorefile:
  • avoid repetitive code
  • control while loops with Boolean switches, for example while continueplay: and set continueplay to False somewhere in the loop ...

Perhaps when you have a working version submit to Stack Codereview for many more useful tips to bring more structure to the program.

Below is a refactored version of the program where above principles have been implemented. One further suggestion would be to hustle the multiple choice questions, so they not always occur in same order for the question. I leave that to you!

import random
import time

YES = ['y', 'Y', 'yes', 'Yes', 'YES']
NO = ['n', 'N', 'no', 'No', 'NO']
CLEAR = ['c', 'C', 'clear', 'Clear', 'CLEAR']
QUIT = ['q', 'Q', 'quit', 'Quit', 'QUIT']
MULTIPLECHOICE = ['a', 'b', 'c', 'd']


class QuizGame:
    '''  repository of methods to do with QuizGame
         -  get_username
         -  play_loop
         -  ask_play_again
         -  escape_quiz
         -  play_quiz
         -  read_highscores
         -  write_highscores
         -  clear_highscores
         -  display_highscores
    '''
    questions = \
        {1: ('What was the first video game ever made?',
             'a)  God of War 9\nb)  Pacman \nc)  Pong \nd)  Tennis for Two',
             'd'),

         2: ('What was the most expensive video game to ever be developed?',
             'a)  Destiny\nb)  Call of Duty: Modern Warfare 2  \n'
             'c)  Grand Theft Auto: V  \nd)  Disney Infinity',
             'b'),

         3: ('What amount of time a day does the average gamer (In the US, '
             'age 13 or older) spend gaming?',
             'a)  54 minutes\nb)  25 hours\nc)  2 hours\nd)  30 minutes',
             'a'),

         4: ('Who is the founder of Nintendo?',
             'a)  Fusajiro Yamauchi\nb)  Bob Dylan\nc)  Steve Bovaird\n'
             'd)  Nihonjin no Shimei',
             'a'),

         5: ('What was the most purchased game of 2017?',
             'a)  Jesus sim\nb)  Farming Simulator 2017\n'
             'c)  Call of Duty: WWII\nd)  Destiny 2',
             'c'),

         6: ('When was E3 [Electronic Entertainment Expo] 2017?',
             'a)  13 Jun 2017 - 15 Jun 2017\nb)  13 Jun 2017 - 14 Jun 2017\n'
             'c)  15 July 2017 - 13 July 2017\nd)  10 Jun 2017 - 18 Jun 2017',
             'a'),

         7: ('What was the most popular console of 2010?',
             'a)  Xbox 360\nb)  PlayStation 3\nc)  Xbox 1\nd)  PlayStation 4',
             'a'),

         8: ('Who was the most subscribed gaming youtuber of 2012?',
             'a)  PrettyL8r\nb)  Pewdiepie\nc)  Greg\nd)  NotGreg',
             'b'),

         9: ('Who won the Game of The Year award 2016?',
             'a)  Overwatch\nb)  Treyarch\nc)  Blizzard\n'
             'd)  Rainbow Six Siege',
             'c'),

         10: ('When did DOOM release?',
              'a)  December 10, 1993\nb)  February 23, 1995\n'
              'c)  January 32, 20019\nd)  Yesterday',
              'a'), }

    welcometext =\
        '\nHello {}, welcome to The Videogame Quiz'\
        '\nIn this quiz, you will be asked 10 questions about videogames.'\
        '\nTry your best to answer all 10 correctly. Enter a, b, c or d '\
        '\ndepending on which answer you think is right\n'

    users = {}
    score = 0
    highscore_file = 'highscore.log'

    @classmethod
    def get_username(cls):
        '''  method to ask user for user_name, if user name is Quit then leave.
             Dictionary of cls.users is checked on existing users. If user
             does not exist he/ she is added.
        '''
        user_name = ''
        quit = False
        while len(user_name) < 4 and not quit:
            user_name = input('Hello! What is your name [enter Q(uit) '
                              'to leave]?: ').strip().capitalize()

            if user_name in QUIT:
                quit = True

        if not quit:
            if user_name not in cls.users:
                cls.users.update({user_name: 0})
                cls.highscore = 0

            print(cls.welcometext.format(user_name))

        return user_name, quit

    @classmethod
    def play_loop(cls, user_name):
        '''  method to control loop of the quiz, update highscore, and ask
             to play again or not
        '''
        playagain = True
        while playagain:
            print(f'\n{user_name}, your current highscore is '
                  f'{cls.users[user_name]}.\n')

            if cls.escape_quiz():
                break

            score = cls.play_quiz()

            if score > cls.users[user_name]:
                cls.users.update({user_name: score})

            playagain = cls.play_again()

    @staticmethod
    def play_again():
        '''   ask player if he/ she wants to play quiz again
        '''
        answered = False
        while not answered:
            answer = input('Do you want to take the quiz again? Y or N: ')
            answered = True

            if answer in YES:
                playagain = True

            elif answer in NO:
                playagain = False

            else:
                answered = False

        return playagain

    @staticmethod
    def escape_quiz():
        '''  ask player twice if he/ she is ready to continue
        '''
        answered = 0
        question = '\nAre you ready to continue? Y or N? '
        while answered < 2:
            answer = input(question)
            print('---------------------------------------')
            answered += 1

            if answer in YES:
                escape_the_quiz = False
                break

            elif answer in NO:
                escape_the_quiz = True
                for i in range(3):
                    print('Oh... ok')
                    time.sleep(0.5)
                question = '\nNow are you ready to continue? Y or N '

            else:
                print('Yes or no only please!')

        return escape_the_quiz

    @classmethod
    def play_quiz(cls):
        '''  core of quiz asking multiple choice questions. Player can leave
             by entering quit
        '''
        questions = cls.questions.copy()
        question_choice = {i for i in range(1, len(questions)+1)}
        score = 0
        question_nr = 1

        while questions:
            question = random.sample(question_choice, 1)[0]
            answered = False

            print(f'Question: {question_nr} of {len(cls.questions)}')
            print(questions[question][0])
            print(questions[question][1])
            question_nr += 1

            answered = False
            while not answered:
                answer = input('What is your answer?: ').lower()

                if answer in (MULTIPLECHOICE + QUIT):
                    answered = True

                else:
                    print('ERROR, please input a, b, c or d only please!')

            if answer in QUIT:
                break

            elif answer == questions[question][2]:
                print('Good job! You are correct.\n')
                score += 1

            else:
                print('Unfortunately that is not correct! '
                      'Better luck next time.\n')

            questions.pop(question)
            question_choice.remove(question)

        print(f'Your score is >>> {score}\n')

        return score

    @classmethod
    def read_highscores(cls):
        '''  read highscores from cls.highscore_file
        '''
        try:
            with open(cls.highscore_file, 'r') as highscores:
                for line in highscores:
                    user_name, score = line.split(':')
                    cls.users[user_name.strip()] = int(score)

        except Exception as e:
            print('Error in log file, must be format <name: score>')

    @classmethod
    def write_highscores(cls):
        '''  write highscores to cls.highscore_file
        '''
        try:
            with open(cls.highscore_file, 'w') as highscores:
                for name in cls.users:
                    highscores.write('{}: {}\n'.
                                     format(name, str(cls.users[name])))

        except Exception as e:
            print('Error in log file, must be format <name: score>')

    @classmethod
    def clear_highscores(cls):
        '''  clears the highscore file if confirmed by typing 'CLEAR'
        '''
        answer = input('\nDo you want to clear the scores log, '
                       'type \'CLEAR\' ')

        if answer == 'CLEAR':
            with open(cls.highscore_file, 'w') as highscores:
                highscores.write('')

    @classmethod
    def display_highscores(cls):
        '''  displays highscores in order from high to low
        '''
        print('\nHighscores')
        print('-'*40)
        print('{:20}{}'.format('Name', 'Score'))
        print('-'*40)

        sorted_output = sorted(QuizGame.users.items(), key=lambda v: v[1],
                               reverse=True)
        for line in sorted_output:
            print(f'{line[0]:20}{line[1]}')


def main():
    '''  starts the program
    '''
    QuizGame.read_highscores()
    QuizGame.display_highscores()
    quit = False

    while not quit:
        user_name, quit = QuizGame.get_username()
        if not quit:
            QuizGame.play_loop(user_name)

    QuizGame.display_highscores()
    QuizGame.write_highscores()
    QuizGame.clear_highscores()


if __name__ == '__main__':
    main()
Bruno Vermeulen
  • 2,970
  • 2
  • 15
  • 29
  • What is this "__name__ == "__main__" ive seen a few times – Callum Clow Jul 16 '18 at 08:37
  • The construction is to safeguard execution of the program when you import it as a module. Many answers are given in https://stackoverflow.com/q/419163/9874393 – Bruno Vermeulen Jul 16 '18 at 09:25
  • Holy crap this code is amazing compared to my poor attempt. Unfortunately there is a lot I do not understand... also a couple things i'd change but its amazing compared to mine which doesn't work. I have a lot to learn – Callum Clow Jul 18 '18 at 06:17