How to update a variable within multiple functions: Powerball game - python

New to Python, but learning through struggling and trying to make good practices. Hoping someone can point me in the right direction for my python program: the powerball. It's between the computer and user, where each pick 3 unique (non duplicated) numbers between 1-9, and a powerball number between 1-3. I wanted to add a money variable that would be shared between the main() function, (which tells you 'welcome' and 'your current money is: (money)), and also shared between the compare_winnings() function, which compares my two lists, and adds the total to the (money) variable.
I've done some research through google and SO, and found that placing my money variable outside of every function turns it into a 'global variable', which seems useful since it'll be used in 2 functions. I've also learned that using the syntax 'global' is bad practice. However, the code runs fine and within the compare_winnings() function, the money is updated. When the game prompts you if you would like to play again (another function), it then starts over, and the money is back to its original value. (which starts at 20).
def main():
print("Each ticket costs $1. Your winnings will be totaled. Current money is",money, "dollars." )
start = input("\n Are you ready? [y/n]: ")
if start == "y" or start == "yes":
#erased variables for legibility; gathers numbers from computer and user
compare_winnings(actual, chosen,cpb, comp_cpb,money)
else:
play_again()
def compare_winnings(actual, chosen, cpb, comp_cpb,money):
counter = 0
print("You chose: ", chosen) #user-inputted
print("Ticket was actually: ", actual) #random (actual)
same_values = set(actual) & set(chosen)
#print ("These are the values that are the same",same_values)
if len(same_values) > 0:
counter += len(same_values)
print("Numbers correct was : ",counter)
if counter == 1 and cpb != comp_cpb :
print("You won $1")
money += 1
print("total money is:", money)
play_again()
def play_again():
play = input("Do you want to play again? ")
if play == "y" or play == "yes":
main()
else:
print("Program will exit. Thanks for playing.")
I expect for the money variable to be updated (and kept) until they decide to stop playing the game. However, it seems to be restarted when they decide to play again and or at main().

Related

Force Python code to restart itself properly

I have tried to figure out a way on how to restart my code in Python, but I can't get it to work properly.
if keepLooping == True:
if userInput == randomNumber:
if attempt == 1:
print()
print("Correct, First try!")
stop = time.time()
print("It took", int(stop - start), "seconds.")
replay = input("Do you want to play again?: ")
if replay.lower() in ("yes"):
print()
os.execl(sys.executable, '"{}"'.format(sys.executable), *sys.argv) # Restart code. You are here
elif replay.lower() in ("no"):
break
else:
print("Invalid input, Yes or No?")
continue # Restart segment. You are here
replayAttempt += 1
print()
As you can see, I have tried using os.execl(sys.executable, '"{}"'.format(sys.executable), *sys.argv). Sure, it works, but then one of my inputs turn red, as you can see here. I have been trying to solve this but I can't find a solution.
I found a solution for the text being red, I added '\033[37m' before my inputs. The only problem I have now is that it can only restart once. When I try it again I get this error code here.
One way to this is to encapsulate thing into function
going from this
#start of scrip
#... game logic
#end of script
to
def game():
#...game logic
game()
encapsulated like this allow for easier reuse of stuff, and allow you to reduce repetition, if you do same thing in your code two or more times that is when you should factor that out into its own function, that is the DRY principle, Don't Repeat Yourself.
You can do something like this for example
def game():
#...game logic
return game_result
def main():
done=False
result=[]
while not done:
result.append( game() )
reply = input("Do you want to play again?: ")
if reply=="no":
done=True
#display the result in a nice way
main()
Here the main function do a couple of simple thing, play one round of the game, save the result, ask if you want to play again and display the result, and the game function do all the heavy work of playing the game.
Here is a simple working example of guess the number between 0 and 10
import random
def game(lower,upper):
answer = str(random.randint(lower, upper))
user_answer = input(f"Guess a number between {lower} and {upper}: ")
game_result = user_answer == answer
if game_result:
print("you win")
else:
print("you lose, the answer was:",answer)
return game_result
def main(lower=0,upper=10):
done=False
result=[]
while not done:
result.append( game(lower,upper) )
reply = input("Do you want to play again?: ")
if reply=="no":
done=True
print("Your result were",sum(result),"/",len(result) )
main()
Notice that the game function take 2 arguments, so you can play this game not just with 0 and 10, but any two number you desire, in turn the main function also take those same arguments but assign them default value so if you don't call this function with any of them it will use those default value and use them to call the game function, doing so allow for flexibility that you wouldn't have if you lock it to just 0 and 10 in this case.
(the sum(result) is because boolean are a subclass of int(numbers) so in math operation they are True==1 and False==0)

How do I stop a while loop if something happens inside a function that should stop the itterations?

Hello fellow programmers! I am a beginner to python and a couple months ago, I decided to start my own little project to help my understanding of the whole development process in Python. I briefly know all the basic syntax but I was wondering how I could make something inside a function call the end of the while loop.
I am creating a simple terminal number guessing game, and it works by the player having several tries of guessing a number between 1 and 10 (I currently made it to be just 1 to test some things in the code).
If a player gets the number correct, the level should end and the player will then progress to the next level of the game. I tried to make a variable and make a true false statement but I can't manipulate variables in function inside of a while loop.
I am wondering how I can make it so that the game just ends when the player gets the correct number, I will include my code down here so you guys will have more context:
import random
import numpy
import time
def get_name(time):
name = input("Before we start, what is your name? ")
time.sleep(2)
print("You said your name was: " + name)
# The Variable 'tries' is the indication of how many tries you have left
tries = 1
while tries < 6:
def try_again(get_number, random, time):
# This is to ask the player to try again
answer = (input(" Do you want to try again?"))
time.sleep(2)
if answer == "yes":
print("Alright!, well I am going to guess that you want to play again")
time.sleep(1)
print("You have used up: " + str(tries) + " Of your tries. Remember, when you use 5 tries without getting the correct number, the game ends")
else:
print("Thank you for playing the game, I hope you have better luck next time")
def find_rand_num(get_number, random, time):
num_list = [1,1]
number = random.choice(num_list)
# Asks the player for the number
ques = (input("guess your number, since this is the first level you need to choose a number between 1 and 10 "))
print(ques)
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
try_again(get_number, random, time)
elif input != number:
time.sleep(2)
print("Oops, you got the number wrong")
try_again(get_number, random, time)
def get_number(random, try_again, find_rand_num, time):
# This chooses the number that the player will have to guess
time.sleep(3)
print("The computer is choosing a random number between 1 and 10... beep beep boop")
time.sleep(2)
find_rand_num(get_number, random, time)
if tries < 2:
get_name(time)
tries += 1
get_number(random, try_again, find_rand_num, time)
else:
tries += 1
get_number(random, try_again, find_rand_num, time)
if tries > 5:
break
I apologize for some of the formatting in the code, I tried my best to look as accurate as it is in my IDE. My dad would usually help me with those types of questions but it appears I know more python than my dad at this point since he works with front end web development. So, back to my original question, how do I make so that if this statement:
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
try_again(get_number, random, time)
is true, the while loop ends? Also, how does my code look? I put some time into making it look neat and I am interested from an expert's point of view. I once read that in programming, less is more, so I am trying to accomplish more with less with my code.
Thank you for taking the time to read this, and I would be very grateful if some of you have any solutions to my problem. Have a great day!
There were too many bugs in your code. First of all, you never used the parameters you passed in your functions, so I don't see a reason for them to stay there. Then you need to return something out of your functions to use them for breaking conditions (for example True/False). Lastly, I guess calling functions separately is much more convenient in your case since you need to do some checking before proceeding (Not inside each other). So, this is the code I ended up with:
import random
import time
def get_name():
name = input("Before we start, what is your name? ")
time.sleep(2)
print("You said your name was: " + name)
def try_again():
answer = (input("Do you want to try again? "))
time.sleep(2)
# Added return True/False to check whether user wants to play again or not
if answer == "yes":
print("Alright!, well I am going to guess that you want to play again")
time.sleep(1)
print("You have used up: " + str(tries) + " Of your tries. Remember, when you use 5 tries without getting the correct number, the game ends")
return True
else:
print("Thank you for playing the game, I hope you have better luck next time")
return False
# Joined get_number and find_random_number since get_number was doing nothing than calling find_rand_num
def find_rand_num():
time.sleep(3)
print("The computer is choosing a random number between 1 and 10... beep beep boop")
time.sleep(2)
num_list = [1,1]
number = random.choice(num_list)
ques = (input("guess your number, since this is the first level you need to choose a number between 1 and 10 "))
print(ques)
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
# Added return to check if correct answer is found or not
return "Found"
elif input != number:
time.sleep(2)
print("Oops, you got the number wrong")
tries = 1
while tries < 6:
if tries < 2:
get_name()
res = find_rand_num()
if res == "Found":
break
checker = try_again()
if checker is False:
break
# Removed redundant if/break since while will do it itself
tries += 1

How Can I Give the User 5 Lives for my script?

Title.
I'm currently writing a choose your own adventure python script for my computer science class and need to give the player 5 lives and when they run out have a line of text appear. Any ideas?
(I'm not sure if I need to post the script or not but I can later today if needed.)
script:
# Name: Drew Dilley
**# Date: 12/7/20
# 1 REMOVED IMPORT MATH BECAUSE IT IS NOT NEEDED FOR THIS SCRIPT.
# 2
import random
answer: str = input("Do you want to go on an adventure? (Yes/No)")
# hint: the program should convert player's input to lowercase and get rid of any space player enters
# hint: check out what .upper(), .lower(), .strip() do on a string, reference: https://www.w3schools.com/python/python_ref_string.asp
# 3
if answer.upper().strip() == "yes":
# hint: pay attention to the variable name
# 4
ANSWER= input("You are lost in the forest and the path splits. Do you go left or right? (Left/Right) ").lower().strip()
if answer == "left":
# 5 UNNECESSARY INDENT
answer = input("An evil witch tries to cast a spell on you, do you run or attack? (Run/Attack) ").lower().strip()
if answer == "attack": #(HAD TO FIX UNEXPECTED INDENT)
print("She turned you into a green one-legged chicken, you lost!")
# 6 HAD TO ADD PARENTHESES AND FIX THE SEMICOLON AFTER "ANSWER"
elif answer := "run":
print("Wise choice, you made it away safely.")
answer = input("You see a car and a plane. Which would you like to take? (Car/Plane) ").lower().strip()
if answer == "plane":
print("Unfortunately, there is no pilot. You are stuck!")
elif answer == "car":
print("You found your way home. Congrats, you won!")
# 7 SEMICOLON NEEDED AFTER "ELSE" PLANE/ANSWER + CAR/ANSWER NEEDED TO BE FLIPPED. NO INDENTATION NEEDED FOR "ELSE". == INSTEAD OF !=
elif answer != "plane" or answer != "car":
print("You spent too much time deciding...")
elif "right" != answer:
else:
print("You are frozen and can't talk for 100 years...")
# hint: the program should randomly generate a number in between 1 and 3 (including 1 and 3)
# hint: remember random module? reference: https://www.w3schools.com/python/module_random.asp
# 8 HAD TO IMPORT "RANDOM"
num: int = random.randint(0,3)
# 9
answer = input("Pick a number from 1 to 3: ")
# hint: will the following if statement ever be executed even when the values of answer and num are the same? If not, can you fix the problem?
# hint: the error is not necessarily in the line below.
if answer == num:
print("I'm also thinking about {}".format(num))
print("You woke up from this dream.")
else:
print("You fall into deep sand and get swallowed up. You lost!")
else:
print('You can\'t run away...')
# 10 NEEDED A SEMICOLON FOLLOWING THE ELSE STATEMENT, SO THAT IT KNOWS WHAT TO READ AND PERFORM NEXT IN THE SCRIPT.
else:
print ("That's too bad!")** ```
you can use a for loop with a counter variable which you can decriment at every time player looses and when it goes from 5 to zero you can use break to exit the loop or a print before break to display a message.

How do I make this dice game run in a simulation 10,000 times using python?

I'm doing a homework assignment. I can't seem to find a solution on how to make the dice roll 10,000 times plus create a variable that updates everytime you win some money when you roll the dice correctly. I have some instructions on the homework below can anyone shed some light on me?
The game is played as follows: roll a six sided die.
If you roll a 1, 2 or a 3, the game is over.
If you roll a 4, 5, or 6, you win that many dollars ($4, $5, or $6), and then roll again.
With each additional roll, you have the chance to win more money, or you might roll a game-ending 1, 2, or 3, at which time the game is over and you keep whatever winnings you have accumulated.
Use the randint function from Python's Random module to get a die roll result
(see functions for integers).
Run 10,000 simulations of the game (Monte Carlo method).
Print the average amount won and the largest amount won.
Just as a thought experiment, would you pay $3 for a chance to play this game?
Example Output:
Average amount won = x.xx
Max amount won = xx
import random
class diceGame:
def __init__(self,dice):
self.dice = dice
def gameOutCome(self):
askUser = str(input("Roll to play the game? Y/N: "))
while True:
if askUser == 'y':
print(self.dice)
if self.dice == 1:
print("Sorry, Try Again!")
elif self.dice == 2:
print("Sorry, Try Again!")
elif self.dice == 3:
print("Sorry, Try Again!")
elif self.dice == 4:
print("You win $4")
elif self.dice == 5:
print("You win $5")
elif self.dice == 6:
print("You win $6")
askUser = str(input("Roll to play the game? Y/N: "))
x = random.randint(1,6)
dd = diceGame(x)
dd.gameOutCome()
Welcome to stackoverflow. Since this is your homework, I don't think it is appropriate to post an entire solution here.
However I do think some pointers in the right direction might be helpful:
1) You are running the simulation 10000 times. Each roll requires 2 user inputs. So in order to finish the simulation you need at least 20000 user inputs... Yeah that will be tiresome ;) .... So lets cut the user input - just write a function that executes the game until the game is finished. Once you have a function that executes one game, how can you execute it multiple times?
2) Think of each roll having two possible outcomes - continue the game or not. What des it mean to continue? What condition has to be fullfilled for the game to end?
3) Once the game has ended, what do you need to do with the money?
4) You can use the sum and max functions to calculate the average and the maximum win.
import random
def play_game():
#The function that executes the game - you have to write that on your own
pass
wins = [play_game() for i in range(0,10000)]
win_average = sum(wins)/10000.0
max_win = max(wins)

elif statement returning the "lost" result each time incorrectly. (homework)

I have updated my code with the changes made. I am still getting incorrect results...
# Import statements
import random
# Define main function that will ask for input, generate computer choice,
# determine winner and show output when finished.
def main():
# Initialize Accumulators
tie = 0
win = 0
lose = 0
score = 0
# initialize variables
user = 0
computer = 0
# Initialize loop control variable
again = 'y'
while again == 'y':
userInput()
computerInput()
if score == win:
print('You won this round, good job!')
win += 1
elif score == tie:
print('You tied this round, please try again!')
tie += 1
else:
print('You lost this round, please try again!')
lose += 1
again = input('Would you like to play another round (y/n)? ')
#determine winning average
average = (win / (win + lose + tie))
print('You won ', win, 'games against the computer!')
print('You lost ', lose, 'games against the computer.')
print('You tied with the computer for', tie)
print('Your winning average is', average)
print('Thanks for playing!!')
# get user input for calculation
def userInput():
print('Welcome to Rock, Paper, Scissor!')
print('Please make your selection and and Good Luck!')
print('1) Rock')
print('2) Paper')
print('3) Scissor')
user = int(input('Please enter your selection here: '))
print('You selected', user)
# get compter input for calculation
def computerInput():
computer = random.randint(1, 3)
print('The computer chose', computer)
def getScore():
if user == 1 and computer == 3:
score = win
return score
elif user == 2 and computer == 1:
score = win
return score
elif user == 3 and computer == 2:
score = win
return score
elif user == computer:
score = tie
return score
else:
score = lose
return score
# Call Main
main()
In Python:
>>> print("3" == 3)
False
Strings and integers are values of different data types, and will not compare equal. Try changing your input to:
userInput = int(input('Please enter your selection here: '))
This will convert the string typed by the user to a number for later comparison. (Note that I have assumed you are using Python 3.x, because input() behaves slightly differently in Python 2.x.)
Note that this will throw an error if you type anything other than a number.
Update: As pointed out by #FelipeFG in the comments below, you are also overwriting the function userInput with the value typed by the user. You'll need to change the name of one or the other, for example:
def getUserInput():
...
Also don't forget to change the place where you call the function. Do the same for computerInput (change to getComputerInput).
Later on, you can change those to actual functions that return values.
userInput() calls the function "userInput", but you discard the result. The same remark applies to computerInput().
userInput == 1 asks whether the function userInput itself is equal to 1. It isn't. The same remark applies to computerInput == 3 and the others.
In the function "userInput", userInput = ... binds the name "userInput" to the result of the expression. This makes "userInput" a local variable of the function. The function doesn't explcitly return anything, therefore it returns None.
If you're using Python 3, input returns a string, and you should convert its result to an int. If you're using Python 2, input evaluates whatever is entered, which isn't safe; you should use raw_input instead and convert its result to an int.
You need to compare against the return value of your function, not the function itself.
Also:
again = input('Would you like to play another round (y/n)? ')
This will throw an exception if you enter y or n, because there is no defined identifier of that name! What you want to use instead is raw_input()
Edit: As pointed out by Greg, this only applies to Python 2.x. You seem to be using Python3 though.

Categories