1

I would like to count the number of attempts the user took to guess the correct color sequence. I have been stuck for quite a while as I tried to add a count function but it kept being stuck at 0. I'm new at python so any help is much appreciated (I had to remove some unrelated part of the code because I cant fit it in the box (at compare_list section)

import random

colours = ['PINK', 'BLUE', 'YELLOW', 'RED']
random_colours = []
colours_input = []

#handles the users input and stores in a list (colours_input)
def user_input():
    i = 1
    while i < 5:
        a = input('Please enter your selected colours in sequence, colour ' + str(i) + ': ').upper()
        while a not in colours:
            print('Please only type the colours in the range (PINK, BLUE, YELLOW, RED) ')
            a = input('Please enter a valid colour ' + str(i) + ': ').upper()
                     
        colours_input.append(a)
        i+=1
    print('Your selected colour sequence is: ' + str(colours_input))

#Automatically generate four random colours for the user to guess    
def randomize():
    for i in range (0,4):
        random_colours.append(random.choice(colours))

#To check 2 variables: Correct colour in the correct place and correct colour but in the wrong place
def compare_list():
    correct_place = 0
    if random_colours[0] == colours_input[0]:
        colour_1 = True
        correct_place = correct_place + 1
    else:
        colour_1 = False
    if random_colours[1] == colours_input[1]:
        colour_2 = True
        correct_place = correct_place + 1
    else:
        colour_2 = False
    if random_colours[2] == colours_input[2]:
        colour_3 = True
        correct_place = correct_place + 1
    else:
        colour_3 = False
    if random_colours[3] == colours_input[3]:
        colour_4 = True
        correct_place = correct_place + 1
    else:
        colour_4 = False

    print('Correct colour in the correct place: ' + str(correct_place))

    while correct_place == 4:
        print('Congratulations! You are a master mind')
        break
    else:
        colours_input.clear()
        user_input()
        compare_list()

1 Answers1

0

You're going to want to have some driver code, that acts as the entry point to your program and orchestrates how functions will be called. Currently you are doing this in your compare_list() function, simply move this code (and change it a bit, there were some mistakes with the while loop structure) to a new function.

Typically this code is placed in a main function. In your case, it could look something like:

def main():
    random_colours = []
    colours_input = []

    randomize() # you forgot to call this in your code
    while True:
        user_input()
        if compare_list():
            print('Congratulations! You are a master mind')
            break # exit the program

        colours_input.clear()

Then, we just need to refactor our compare_list() function so that it only compares the lists, and returns the result of the comparison (I just return a boolean representing whether the comparison was successful, but you could also return the correct_place value for example).

def compare_list():
    correct_place = 0
    if random_colours[0] == colours_input[0]:
        colour_1 = True
        correct_place = correct_place + 1
    else:
        colour_1 = False
    if random_colours[1] == colours_input[1]:
        ...

    print('Correct colour in the correct place: ' + str(correct_place))

    return correct_place == 4 # returns True, if correct_place equals 4, False otherwise

Now, in our main function, we can count how many times we have run this main loop for each user attempt:

def main():
    random_colours = []
    colours_input = []
    
    attempts = 0
    while True:
        attempts += 1
        user_input()
        randomize()
        if compare_list():
            print('Congratulations! You are a master mind')
            print('It only took you {} attempt{}!'.format(attempts, 's' if attempts > 1 else "")
            break # exit

        colours_input.clear()
        random_colours.clear()

Now we simply call the main() function in our file to run the driver code. Typically this is done in an if block that runs only if your script is being run directly as opposed to being imported by something else:

...

def compare_list():
    ...

def main():
    ...

if __name__ == "__main__":
    main()

(You can read up about this practice here: What does if __name__ == “__main__”: do?)

A final refactor would be to reduce the use of global variables. You should aim to make your functions units of code that operate on input(s) and return output(s). Designing your functions so that they mutate global variables to produce a result is an anti-pattern.

Here's one way to refactor it:

import random

colours = ('PINK', 'BLUE', 'YELLOW', 'RED') # this is okay since it is a constant. We can make it an immutable tuple to clearly indicate that this is read-only.
# remove the following global variables
# random_colours = []
# colours_input = []

#handles the users input and stores in a list (colours_input)
def user_input():
    colours_input = [] # define the variable here. We create a new list that this function will populate, then return it

    for i in range(5):
        ...

    print('Your selected colour sequence is: ' + str(colours_input))
    return colours_input # return the populated list

def randomize():
    random_colours = [] # define the variable here. Similar to above.

    for i in range (0,4):
        random_colours.append(random.choice(colours))
     
    return random_colours # return it to the caller

# we take in the lists to compare as parameters to the function, rather then getting them from the global scope
def compare_list(colours_input, random_colours):
     ... # (everything else is the same)

def main():
    random_colours = randomize()

    # colours_input = []

    attempts = 0
    while True:
        attempts += 1
        colours_input = user_input()
        if compare_list(colours_input, random_colours): # pass the returned lists in as arguments to this function call
            print('Congratulations! You are a master mind')
            print('It only took you {} attempt{}!'.format(attempts, 's' if attempts > 1 else "")
            break # exit the program

        # no need to clear this anymore. We get a new list from each call to user_input()
        # colours_input.clear()

zr0gravity7
  • 2,917
  • 1
  • 12
  • 33