Feedback on Coin Flip project

Hello there,

I think I finally finished the coin flip project that is included in Code Academy Pro. However, i’m pretty confident this is far from the optimal solution and would really appreciate any feedback on how this could be improved. Since i’m studying by myself using Head First and Code Academy any feedback would be very very helpful!

The goals of the challenge are:

  • As a user I want to be able to guess the outcome of a random coin flip(heads/tails).
  • As a user I want to clearly see the result of the coin flip.
  • As a user I want to clearly see whether or not I guessed correctly.
  • As a user I want to clearly see the updated guess history (correct count/total count).
  • As a user I want to be able to quit the game or go again after each cycle.

This is my first time really using Git Hub, but I included the .py file which hopefully you can access here: (https://github.com/adarmec/coin_flip_challenge)

I’ve also included the code in the post if thats easier:

import random


def random_flip(): #function to generate random Heads or Tails output
    
    random_choice = random.choice(["Heads","Tails"])
    return random_choice

def user_choice(): #function to ensure a valid input from the user, and returns that input.

    user_input = ""
    valid_guesses = ["Heads", "Tails"]

    while user_input not in valid_guesses:
        user_input = input("Heads or Tails?")
        
    return user_input
 

def coin_flip_game(): #function that plays the coin flip game.

    guess_count = 1  #guesses set to 1 so that program considers 1st guess.
    guesses = []     #list of guesses made by user
    winner = False
    first_try = True      #Variable to determine whether first try of user or not
    cancel_game = False   #Variable to determine whether game was cancelled
    
    print("Lets start! Begin by choosing:")

    while winner == False:
        if first_try == True:
            user_input = user_choice()
        
            if user_input != random_flip():
                guess_count += 1
                guesses.append(user_input)
                first_try = False
            else:
                winner = True
        else:
            decision = input("You guessed wrong, do you want to continue? Yes or No ")

            if decision == "Yes":
                user_input = user_choice()
        
                if user_input != random_flip():
                    guess_count += 1
                    guesses.append(user_input)
                    first_try = False
                else:
                    winner = True
            else:
                winner = True
                cancel_game = True
                break
                
    if cancel_game == True:
        print("Game over")
    elif guess_count == 1:
        print("Congratulations, you guessed correctly on your first try!")
    else:
        print("Congratulations! After ", guess_count, "you guessed correctly!")
        print("Your previous guesses were: ", guesses)

coin_flip_game()

Good job :slight_smile: How happy are you with the result yourself?

Just a few minor issues:

i would do this:

input("Heads or Tails?").lower()

simply make the user input lowercase, this prevents case sensitive wrong input.

i would change this:

while winner == False:

into:

while True:

This way, you have a deliberate infinity loop, which you can break out of when the user wants to exit. Otherwise, this will keep the game going

1 Like

One thing you might want to evaluate is does your code meet the requirements (goals in this case)?

As a user I want to clearly see the updated guess history (correct count/total count). - This is poorly worded but I take the key part to be the clarification at the end of what they mean by guess history.

As a user I want to be able to quit the game or go again after each cycle. - You do not give the option to play again if they guess correctly.

They aren’t comments on the code directly and they aren’t meant to be negative, but a key part of programming is solving the issue you are asked to. Now when you code for yourself, this often means keeping your head level and not allowing feature creep.

If doing it for someone else or taking part in an open source project, for example, meeting to requirement will be key and is just as important as the programming (when good is code to someone if it doesn’t do what they need it to?)

With regards to the code, you have written:

if user_input != random_flip():
                    guess_count += 1
                    guesses.append(user_input)
                    first_try = False
                else:
                    winner = True

Twice, once for each logic path. If you needed to change the code you now have to remember to change it in both places the same otherwise you’ll have a bug. So it could be put into another function and called in both places.

Beyond that, it depends how far you want to go down the rabbit hole of making it resilient, like where you compare the response to continue, it has to have a capital Y in Yes.

1 Like

Thanks! Felt pretty good after a few hours of trying and finally getting a result I wanted! One thing that wasnt clear was the use you just gave of While True.

If I understand correctly, if I have a return command (or break) anywhere in a loop, or a function… if that command is activated that will automatically end the code, right? Id also have to include a break command in the first Else.

In the code I shared, the command that will end the coin_flip_game function is the break command (which the user can activate if he wants to end the game), right?

You have a point…so I should have a count of correct guesses AND of total guesses made…which I dont address in the code. This will only be relevant if I also address your second point…and allow the user to continue playing after he guessed correctly.

I havent been studying programming for very long, around 1.5 months so far but its quite amazing how far you can go in a very simple task.

Good to hear :slight_smile:

having an infinite loop, should enable to simplify your program a bit.

here:

            decision = input("You guessed wrong, do you want to continue? Yes or No ")

            if decision == "Yes":
                user_input = user_choice()
        
                if user_input != random_flip():
                    guess_count += 1
                    guesses.append(user_input)
                    first_try = False
                else:
                    winner = True
            else:
                winner = True
                cancel_game = True
                break

if the now makes a typo (they type: yed), the program exit. By having an infinite loop, you can even handle incorrect input without your program

and this duplicate code:

            user_input = user_choice()

            if user_input != random_flip():
                guess_count += 1
                guesses.append(user_input)
                first_try = False
            else:
                winner = True
# duplicate fragment:
                user_input = user_choice()
        
                if user_input != random_flip():
                    guess_count += 1
                    guesses.append(user_input)
                    first_try = False
                else:
                    winner = True

could then be eliminated.