Sharing Computer Science Project #1 - Coin Flip looking for feedback

Hello, i want to share my solution to the Project Coin Flip.

It’s on github https://github.com/Coroto17/coinflip

Since it was just me doing it, i didn’t use branching, just commits to master. I know i need to practice that more :stuck_out_tongue:

Please let me know on any suggestions, be it about the code, the way i putted it on github, some better or cleaner ways to do it, etc.

I will share it here too, for the ones that doesn’t want to go on github.

#PROJECT FOR CODECADEMY COMP-SCI PATH #1: COIN FLIP

#importing random to generate a random number to coin flip, and time to insert pause between print lines
import random
import time

#making the flip coin function
def coinflip():
    #local variables, counters
    game_count = 0
    success_count = 0
    print ("Loading Coin Flip...")
    time.sleep(2)
    #encapsulated everything inside a while loop, to make the game start again
    while True:
        #try except block to avoid unwanted inputs (strings), followed by a conditional for checking correct numbers
        try:
            guess = int(input("Please press 1 for Heads or 2 for Tails: "))
        except ValueError:
            print ("please enter a valid option")
            continue
        if guess < 1 or guess > 2:
            print ("please enter a valid number")
            continue
        #after checking inpput, starts the logic    
        if guess == 1:
            bet = "Heads"
        if guess == 2:
            bet = "Tails"
        #This is where the random flip happens
        num = random.randint(1, 6)
        #depending on the number generated, it will check whether its even or odd, making it a 50% chance.
        if num % 2 == 0:
            result = "Heads"
        else:
            result = "Tails"
        #console output, simulating the flip with time sleep
        print ("Your Guess is {bet}".format(bet = bet))
        time.sleep(2)
        print("Flipping Coin...")
        time.sleep(2)
        print("Coin dropped, facing on its {result} side".format(result = result))
        time.sleep(1)
        #checking result to count success and games played
        if bet == result:
            success_count += 1
            print ("You Won")
        else:
            print ("You Lost")
        game_count += 1
        time.sleep(1)
        #show game history, for the additional challenges section
        print ("Game history: correct: {correct} / total {total}".format(correct= success_count, total = game_count))
        time.sleep(2)
        #this will continue the game or exit in case of x is input
        play_again = input("enter any key to flip the coin again, or enter \"x\" to exit to the lobby: ")
        if play_again == "x":
            print("Thanks for playing Coin Flip, You Won {success} times out of {total}".format(success=success_count, total=game_count))
            time.sleep(2)
        #the line that exits the game    
            break
        else:
        #the magic line, this continue will redirect to the beginning of the while loop and start the game again    
            continue
    return

#This dice game is a copy paste of coinflip, with proper modifications, expect less comments 
def dice():
    #local variables, counters
    game_count = 0
    success_count = 0
    print ("Loading Dice...")
    time.sleep(2)
    while True:
        try:
            guess = int(input("Please input a number between 1 and 6: "))
        except ValueError:
            print ("please enter a valid option")
            continue
        if guess < 1 or guess > 6:
            print ("please enter a valid number")
            continue
        #using randint to generate the result of throwing
        num = random.randint(1, 6)
        #console output, simulating dice throwing with time sleep
        print ("Your Guess is {guess}".format(guess = guess))
        time.sleep(1)
        print("Throwing dice...")
        time.sleep(2)
        print("Dice finally stops, facing on its {num} side".format(num = num))
        time.sleep(1)
        #checking result to count success and games played
        if guess == num:
            success_count += 1
            print ("You Won")
        else:
            print ("You Lost")
        game_count += 1
        time.sleep(1)
        print ("Game history: correct: {correct} / total {total}".format(correct= success_count, total = game_count))
        time.sleep(2)
        play_again = input("enter any key to throw the dice again, or enter \"x\" to exit to the lobby: ")
        if play_again == "x":
            print("Thanks for playing Dice, You have won {success} times out of {total}".format(success=success_count, total=game_count))
            time.sleep(2)
            break
        else:
            continue
    return
    
#For the final challenge, selecting between 2 games, and letting the user to switch games
while True:
    try:
        game = int(input("Welcome to the game lobby, Press 1 to play Coin Flip, Press 2 to Play Dice, or press 3 to exit: "))
    except ValueError:
        print ("Please enter a valid option")
        continue
    if game == 3:
        print("Thanks for Playing")
        break
    if game < 1 or game > 3:
        print ("Please enter a valid number")
        continue
    else:
        if game == 1:
            coinflip()
            continue
        if game == 2:
            dice()
            continue

I had a hard time figuring how to manage incorrect inputs on the play_again part, it keeps going on continue whenever i input a number or a letter other than x, so i tricked it with the message: “press any key” lol. Some feedback on the matter would be appreciated.

In the github there are various commits where you can check the evolution of the code, from the basic requests to the final ones.

2 Likes

@corotox, great work!! It works fine, and doesn’t necessarily require any changes.

There are so many ways to code this sort of thing. A few ideas:

Staying more or less with your structure, but with fewer if chains or try-except:

play_again = "y"
while play_again != "n":
    if not play_again in 'yn':
            play_again = input("Play another? (y/n)")
            continue
    guess = input("Please press h for Heads or t for Tails: ")
    if not guess in "ht":
        print ("please enter a valid option")
        continue
    guess = 1 if guess == 'h' else 2

    print(guess)
    # play game   here

    play_again = input("Play another? (y/n)")
        
print("Good-bye!")

But my favorite structure is to maintain all of the bookkeeping and as much of the interaction as possible in a play() function, possibly like this:

def play(coin_flip_success = 0, coin_flip_total = 0, dice_success = 0, dice_total = 0):
    
    while True:        
        game = input("Welcome to the game lobby, Press 1 to play Coin Flip, Press 2 to Play Dice, or press 3 to exit: ")
        if not game in '123':
            print ("Please enter a valid option")
            continue
        game = int(game)
        if game == 1:
            augment = coinflip()
            coin_flip_success += augment[0]
            coin_flip_total += augment[1]
            continue
        if game == 2:
            augment = dice()
            dice_success += augment[0]
            dice_total += augment[1]
            continue
    print("Thanks for Playing.\n Your coin_flip record was {} wins out of {} tries.\nYour dice record was {} wins out of {} tries.".
          format(coin_flip_success, coin_flip_total, dice_success, dice_total))

play()

For this to work, you need to modify the two other functions to return success_count, game_count

This takes care of wins and losses. It would take some more extensive modification to incorporate all of the interaction and dialog in this function, but I think thatit gives good encapsulation.

1 Like

First of all, @patrickd314 Thank you very much for taking the time to review and analyze the code.

Ok, this statement blew my mind lol. This is the kind of feedback i was hoping for, a better or more sophisticated approach opposed to my “naive approach”. While i was thinking like i write, you brought a more programming-oriented solution. Thanks for that.

I think i got the idea here, and again, it blew my mind lol. The first time we enter this whole section, there won’t be a “play another” prompt (like its supposed to happen because we are playing for the first time), so the code will run 1 time and go to the bottom part where we will get the prompt, save the variable value and go to the beginning of the while loop. Again, i think i got it.

Now, about your favorite structure, i was thinking about how to keep the counters updated, and i can say honestly that i didn’t think of declaring some play_counters with 0 value inside the args of the function. At some point i had at the end, instead of return a return w/e counters i wanted but i discarded that idea, or didn’t think of making a play function then games inside that.

This is about the same as i explained before, thanks for claryfing how to make the prompt fool proof lol.

Pretty clear here, first, game is saved as string, compared (or parsed) in the string “123” then passed to the rest of the code as int so we can select the game.

Putting the counters outside the game functions is another clear improvement; so we return from the game with game counters and add them to the play() function counters. This play() then games() tree structure of functions is a lot better than having separate functions interacting each other.

Thank you very much for the feedback. I hope to retrieve this in form of feedback to another fellow learner.

Kind regards…

1 Like