Save a variable from a function to reuse when it loops - python

I just started to learn python yesterday so complete noob. I have about 10 hours javascript experience to but had to switch since I'm learning Python in college. I decided to try make a program by myself since I learn a lot better doing that instead of countless videos.
The major problem I'm having is saving my variable of balance. When I win or lose the balance just restarts at 2000. I think that's probably because of the variable balance = 2000 but if I don't define it, it doesn't work. I know it's not anything important but I want to learn where I'm going wrong.
If anyone can help me that would be much appreciated. Also I know the codes a mess but will try make it better later.
global balance
name = input ("Please Enter Your Name: ")
password = input ("Please Make A Password: ")
def playgame():
balance = 2000
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
if yesOrNo == "y":
howBigABet = int(input("How Much Would You like to bet?: "))
if howBigABet <= balance:
pickNumber = int(input("Please PicK A Number: "))
from random import randint
value = randint(0, 1)
print(value)
if pickNumber == value:
print(value)
balance = balance + howBigABet * 2
print("you won " + str(howBigABet * 2))
print(balance)
playgame()
else:
print ("Sorry Wrong Number")
balance = balance - howBigABet
print("your new balance is: " + str(balance))
playgame()
if balance <= 200:
print("You Are Low on Cash Top up?")
elif balance <= 0:
print("You Are Out Of cash " + name + " Top Up ")
playgame()
else:
print("Sorry You Dont Have Enough Money")
print("Hello " + name)
passwordAttempted = input("Please Enter Your Password: ")
if passwordAttempted == password:
print("Welcome " + name)
playgame()
else:
print ("Wrong Password " + name + " !")

You can just pass balance as an argument, to your playgame function
like this
def playgame(balance=2000):
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
...
And than just pass, the new balance to all the playgame calls
But a much better way than using a recurent function would be a while loop
name = input ("Please Enter Your Name: ")
password = input ("Please Make A Password: ")
def playgame(balance=2000):
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
if yesOrNo == "y":
howBigABet = int(input("How Much Would You like to bet?: "))
if howBigABet <= balance:
pickNumber = int(input("Please PicK A Number: "))
from random import randint
value = randint(0, 1)
print(value)
if pickNumber == value:
print(value)
balance = balance + howBigABet * 2
print("you won " + str(howBigABet * 2))
print(balance)
return balance
else:
print ("Sorry Wrong Number")
balance = balance - howBigABet
print("your new balance is: " + str(balance))
return balance
if balance <= 200:
print("You Are Low on Cash Top up?")
elif balance <= 0:
print("You Are Out Of cash " + name + " Top Up ")
return balance
else:
print("Sorry You Dont Have Enough Money")
print("Hello " + name)
passwordAttempted = input("Please Enter Your Password: ")
if passwordAttempted == password:
print("Welcome " + name)
balance = playgame()
while input("You want to play again? Y/N").lower() == "y":
balance = playgame(balance)
else:
print ("Wrong Password " + name + " !")
Please note, that this code is not tested and may not work how you want.

Since balance is local to the function playgame() every time the function is called, the variable will be reset. You can fix this problem a couple of ways. You can make balance a global variable, or you can add a loop where the function doesn't return after one execution. The second example I gave would look something like this:
global balance
name = input ("Please Enter Your Name: ")
password = input ("Please Make A Password: ")
def playgame():
balance = 2000
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
while yesOrNo == "y":
howBigABet = int(input("How Much Would You like to bet?: "))
if howBigABet <= balance:
pickNumber = int(input("Please PicK A Number: "))
from random import randint
value = randint(0, 1)
print(value)
if pickNumber == value:
print(value)
balance = balance + howBigABet * 2
print("you won " + str(howBigABet * 2))
print(balance)
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
continue
else:
print ("Sorry Wrong Number")
balance = balance - howBigABet
print("your new balance is: " + str(balance))
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
continue
if balance <= 200:
print("You Are Low on Cash Top up?")
elif balance <= 0:
print("You Are Out Of cash " + name + " Top Up ")
yesOrNo = input("Would You Like To Put A Bet on Y/N?; ")
continue
else:
print("Sorry You Dont Have Enough Money")
print("Hello " + name)
passwordAttempted = input("Please Enter Your Password: ")
if passwordAttempted == password:
print("Welcome " + name)
playgame()
else:
print ("Wrong Password " + name + " !")

The first thing playgame does is set your balance to 2000, so it's always going to be 2000 at the beginning of a game. This is happening because you restart a new game by calling playgame() from within playgame. This is called recursion. It's a powerful tool that has a lot of uses, but this is probably not the best use of it. Among other things, when a game ends, it's going to return to where it was in the previous game, and pick up executing the next statement after playgame(). (You don't have anything like that in your current code, but the moment you do, you'll get confused. In short, playgame() is not a simple "go back to the beginning" command.)
So one way to address this is to change the main structure of your function to a loop. After balance = 2000 add:
while True:
and indent the rest of the function under that statement.
Wherever you have playgame() within the playgame function, change it to continue. This will cause the program to go back to the beginning of the while loop.
Since balance = 2000 is not within the loop, it will be executed once and will not be re-executed for subsequent games.
Another way to solve the problem (keeping the recursion) is to move the initialization of balance outside the loop, say to right after you ask for the user's name and password. In the playgame function, replace balance = 2000 with global balance. This way, the variable is not local to the function and will retain its value from call to call.
Finally, you could make the game a class rather than a standalone function. This way, balance can be an attribute of the object rather than a local variable to your function, but still not a global. (Global variables are generally a bad idea, especially as your code gets more complex, because they make it difficult to keep track of every piece of the data the function uses to do its job.) This is probably the best way to do it long-term, but you'll need to learn a bit more about programming before you tackle that.

Elaborating on loops since you said you are new to python, you can initiate the balance variable outside the function, and in a loop, you can ask for user input and call the function. Based on the input, you can rerun the function or exit and display balance.
One way would be, to modify you if-else loop for yesOrNo and add an elif (say elif yesOrNo=='end'), then break the loop and display balance.

Related

How to permanently change a variable in Python?

I decided to make a code in Python that is like an ATM Machine, and Everything works very well, you can check your balance, extract or add money,and change the PIN code. But when I change the PIN code i tried to assign the "changed_pin_code" variable to the "real_pin_code" variable,and it doesen't work, the PIN code remains the same. If you could give me some ideas on how I could solve the problem, or improve my code, that would be fantastic.
I am at the beggining with coding, and I am doing this so I can test my knowledge.
I left the code below.
def atm_machine():
code = input("Enter yout PIN code:")
pin_code = int(code)
real_pin_code = 4137
balance = 10000
if pin_code == real_pin_code:
print("""
ATM
1)Check Balance
2)Add money
3)Extract money
4)Change PIN code\n""")
number_select = int(input("Select a number:"))
if number_select > 4 and number_select == 0:
print("You must select a number between 1 and 4!")
atm_recall()
if number_select == 1:
print("Your current balance is:", balance, "$")
atm_recall()
if number_select == 2:
money_add = int(input("Enter amount of money you want to add:"))
new_money = balance + money_add
print("Your current balance is:", new_money, "$")
atm_recall()
if number_select == 3:
money_extract = int(input("Enter the amount of money you want to extract:"))
if money_extract > balance:
print("Insufficent fund")
atm_recall()
if money_extract <= balance:
remained_money = balance - money_extract
balance = remained_money
print("Your current balance is:", remained_money, "$")
atm_recall()
if number_select == 4:
measure_pin = 9999
changed_pin_code = int(input("Enter new PIN code:"))
if changed_pin_code == real_pin_code:
print("You can't enter the same PIN code:")
print("Wait for yout card!")
atm_recall()
if changed_pin_code > measure_pin:
print("PIN code must be formed of 4 digits!")
print("Wait for your card")
atm_recall()
else:
real_pin_code = changed_pin_code
print("PIN code succesfully changed!")
print("Your new PIN code is:", changed_pin_code)
atm_recall()
else:
print("PIN code inccorect!")
print("Wait for your card!")
def atm_recall():
question = str(input("To make another action, type \"Y\",else, type\"N\" "))
if question == "Y":
result = atm_machine()
return result
if question == "N":
print("Good Bye!")
print("Wait for your card!")
atm_machine()
The problem you are currently facing is because at end of each option you call atm_recall function, in which if the user selects the 'Y' option, it calls the atm_machine function which whenever called starts with real_pin_code set to 4137.
Solution:
As already mentioned by others, in comments what you should rather do is get rid of the recursion as it uses up a lot of memory and fills up the call stack on each function call. So a refactored approach would be something like this:
real_pin_code = 4137
balance = 10000
while True:
code = input("Enter yout PIN code:")
pin_code = int(code)
if pin_code == real_pin_code:
print("""
ATM
1)Check Balance
2)Add money
3)Extract money
4)Change PIN code\n""")
number_select = int(input("Select a number:"))
if number_select == 1:
print("Your current balance is:", balance, "$")
elif number_select == 2:
money_add = int(input("Enter amount of money you want to add:"))
balance = balance + money_add
print("Your current balance is:", balance, "$")
elif number_select == 3:
money_extract = int(input("Enter the amount of money you want to extract:"))
if money_extract > balance:
print("Insufficent fund")
else:
remained_money = balance - money_extract
balance = remained_money
print("Your current balance is:", remained_money, "$")
elif number_select == 4:
measure_pin = 9999
changed_pin_code = int(input("Enter new PIN code:"))
if changed_pin_code == real_pin_code:
print("You can't enter the same PIN code:")
print("Wait for yout card!")
elif changed_pin_code > measure_pin:
print("PIN code must be formed of 4 digits!")
print("Wait for your card")
else:
real_pin_code = changed_pin_code
print("PIN code succesfully changed!")
print("Your new PIN code is:", changed_pin_code)
else:
print("You must select a number between 1 and 4!")
else:
print("PIN code inccorect!")
print("Wait for your card!")
question = str(input("To make another action, type \"Y\",else, type\"N\" "))
if question == "N":
print("Good Bye!")
print("Wait for your card!")
break
Changes:
I took real_pin_code out of the loop, so its value doesn't reset at each iteration.
Also, for the same reason I took balance out of the loop and made the changes to balance itself rather than declaring a new variable new_money.
Also, as a good programming practice I changed a lot of if statements to elif and else where the conditions were exclusive of each other.
Better Approach:
A better approach, as already highlighted by others would be to use class where you would initialize an ATMMachine object with all the required details. However the approach you choose, mostly all the logic would remain the same except some refactoring and specific methods for each task.
I'm not sure if it's a best way to do it, but I would create a txt file with atm pin which You could read in the beggining to take pin code and write it when You want to change it. Something like this:
def atm_machine():
code = input("Enter yout PIN code:")
pin_code = int(code)
real_pin = open("code.txt", "r")
real_pin_code = int(real_pin.read())
Here I already have a txt file with some code created in program folder so python could read it, and here I'm saving new pin to same txt file:
else:
real_pin = open("code.txt", "w")
real_pin.write(str(changed_pin_code))
print("PIN code succesfully changed!")
print("Your new PIN code is:", changed_pin_code)
atm_recall()
Hope this helps anyhow.

Using a variable in a try function in another function without global (python)

How can I use the variable 'guess' in my guessfunction() in the main function (for i in range (1,6)? I get the error that guess is not defined. Initially everything worked fine without the guessfunction, but I wanted to add the possiblity of wrong input from the user and that got me stuck.
I saw on stackexchange that it is bad practice to use global inside a function, but even with global I don't know how to solve my issue.
Is there also a way to change the int(guess) if it is possible to get the variable from the function?
Thank you!
import random, sys
print("Hello. What is your name?")
name = str(input())
print("Well, " + name + ", I am thinking of a number between 1 and 20.")
number = random.randint(1, 20)
def guessfunction():
print("Take a guess.")
guess = input()
for number_attempts in range(0,3):
try:
return guess
except ValueError:
print("Please enter a number in figures not as a word")
print("You didn't enter a number in figures after 3 tries, program ended")
sys.exit()
for i in range(1,6):
guessfunction()
if int(guess) != number:
if int(guess) < number:
print("Your guess is too low")
else:
print("Your guess is too high")
elif int(guess) == number:
print("Good job, " + name + "! You guessed my number in " + str(i) + " guesses")
sys.exit()
print("Nope. The number I was thinking of was " +str(number))
you need to initialise it in your for loop:
guess = guessfunction()

Restarting a function once condition returns True

Trying my hand at writing a very simple Game of Chance game on Codecademy while working through their Python course. I was doing ok (I think) for a while and the code returned what I expected it to, but now it feels I'm stuck and googling things frantically hasn't really helped me and I don't just want to look at the actual solution because where's the fun in that so here goes.
My thought process was the game should initially ask the player to input their guess and their bid, then run the code in game() and print the outcome. This was then to be locked in a while loop to check if the user wanted to continue playing or not and if the answer was "Yes" to restart the game() function again. This is where I am stuck as I just can't figure out what to put in line 26 after the "Yes" check returns True.
I guess the TL/DR version of my actual question is how do you (without giving the actual code away) call a function from within a while loop? Wondering if perhaps I'm simply headed in the wrong direction here and need to review while loops once more.
Thanks!
# Import stuff
import random
# Generate random number from 1 - 9
num = random.randint(1, 10)
# The actual game, asking user for input and returning the outcome
def game():
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
money = 100
if guess == num:
money = (money + bid)
print("You Won")
print("You now have: " + str(money) +" money")
return money
else:
money = (money - bid)
print("You lost, you will die poor")
print("You now have: " + str(money) +" money")
return money
# Run game() while there's still money left in the pot
def structure():
while money > 0:
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
game() # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
game()
Ok so a few things to go through here.
First off, the concept of a local variable is coming into play here and is why your money variable is not communicating properly between your two functions. Each of your functions uses it's own money variable, which is completely independent of the other.
So this is the root of your current problem, where your money > 0 loop never actually runs. Secondly, although this might have just been done for troubleshooting, you don't actually call structure which is supposed to control game().
Lets try something like this where we keep money in the structure function and pass an update version to the game function as a parameter. Then, because you have game() returning money, you can just update the money value in your structure() call.
# Import stuff
import random
# Generate random number from 1 - 9
num = random.randint(1, 10)
# The actual game, asking user for input and returning the outcome
def game(money):
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
if guess == num:
money = (money + bid)
print("You Won")
print("You now have: " + str(money) +" money")
return money
else:
money = (money - bid)
print("You lost, you will die poor")
print("You now have: " + str(money) +" money")
return money
# Run game() while there's still money left in the pot
def structure():
money = 100
money = game(money)
while money > 0:
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
money = game(money) # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
structure()
Notice because of how your while loop is written, in order to get game() to run the first time I had to call it before the while loop. Maybe as a challenge, see if you can be rewrite the structure of your loop so that you don't have to do this!
Welcome to SO. Your code is overall fine. Here's one way to slightly change your code to make it work:
... Most of the code ...
money = 10
def structure():
another_go = "Yes" # initialize to 'Yes', so we'll
# always have a first game.
while money > 0:
if another_go == "Yes":
game() # This is where I'm stuck
elif another_go == "No":
print("Oh well, suit yourself")
break
else:
print("Pick Yes or No")
print(another_go)
# move 'another go' to the end of the loop
another_go = input("Would you like to play again? Yes or No: ")
structure() # call this function to start
# make money a global parameter with a -ve value
money = -1
def game():
global money
guess = int(input("Guess the number: "))
bid = int(input("Bet on the game: "))
# Then, if money has default(game started for first time), update it
if(money < 0):
money = 100
.
.
.
.
while money > 0:
global money
another_go = input("Would you like to play again? Yes or No: ")
if another_go == "Yes":
game(money) # Pass remaining money to game()
.
.
.

Self teaching python. Having trouble with score incrementing after each round

TL:DR Trying to set up a scoring system, it doesn't seem to go up when you get than answer right
As the title says I'm teaching myself python, thus this is only the second code I have written (hints in why I'm learning python). I'm more than happy to take criticism on everything from syntax to how to better comment. With that being said, let's get to my issue.
This is a small guessing game. The book I'm reading taught the "for guessTaken" and subsequent code. My problem is in one small aspect of my code. The scoring system won't increment.
I set up the code in the for loop called games then try to have it display at that start of each round and go up with each correct guess. However, it will display 0 for the first few rounds then it will show 2 ( or whatever your current score is I think...). I think the problem is I'm calling the score +1 int in an if statement but I've moved the code around and can't figure it out.
I am aware that it's not beautiful! There are also a few bugs (number of games played isn't what you enter.)Right now I'm only working on the scoring system.
#this is a guess the number game.
import random
#Get's user's name
print("Hello. Welcome to Print's guessing game. Please enter your name: ")
userName = input()
#askes if they are ready
print("Are you ready to play " + userName + "?")
ready = input().lower()
if ready == 'yes' :
print("Let's get started")
else:
while ready != 'yes':
print("Let me know when you are ready")
ready = input().lower()
#Game start
#number of games
games = int(input("How many games would you like to play?"))
if games >= 1:
print("Let's get started")
for games in range (int(games), 1, -1):
while games != 1:
print("I am thinking of a number between 1 and 20 ")
secretNumber = random.randint(1, 20)
score = 0
print("Current score: " + str(score))
print("Debug: " + str(secretNumber))
for guessTaken in range (7, 1, -1):
print("you have " + str(guessTaken - 1 ) + " guesses left")
guess = int(input())
if guess < secretNumber:
print("Your guess is to low. Please guess again")
elif guess > secretNumber:
print("Your guess is too high. Maybe something a little lower?")
else:
break # This conditon is for the right guess.
if guess == secretNumber:
print("good Job " + userName + "! you guessed the number right!")
score = int(score + 1)
print("your score is " + str(score))
games = int(games - 1)
else:
print("Nope, the number I was thinking of was " + str(secretNumber))
print("you have " + str(games) + " games left")
elif games == 0:
while games == 0:
print("Would you like to exit? Yes or No ")
exit = input().lower()
if exit == 'yes':
quit()
else:
games = int(input("How many games would you like to play?"))
else:
print("wtf")
Your score variable is being initialized to zero every time your code goes through the while loop. If you want it to track the total score for all of the games, initialize it right after your print("Let's get started"). This will reset their score whenever they tell you how many games they want to play.
If you don't want their score to reset until they quit your program, you will have to initialize it at the beginning of your program. Up by your import random would work well.

How to make a Pin pritection thing for an ATM in python 2.7

Okay so I have done most of the work but my pin code isn't working properly. You can enter a code but I want it to be you can only enter e.g 1234 to get in as so far you can but any number and get it, I tried using an else statement but I cant get it to work, any help? Also does anyone know how I could write this stuff to a file, for example, your write your name e.g joe, it finds your balance etc maybe I could do this with the pin too? not sure need some help, thanks
balance = float(0)
userInput = None
pin = int(input('Please enter the 4 digit pin on your card:'))
if pin == (1234):
print('Correct pin!')
print "Hello, welcome to the ATM"
while userInput != "4":
userInput = raw_input("\n what would you like to do?\n\n (1)Check balance\n (2)Insert funds\n" +
" (3)Withdraw funds\n (4)Exit the ATM\n" )
if userInput == "1":
print "your balance is", "£" , balance
elif userInput == "2":
funds = float(raw_input("Enter how much money you want to add"))
balance = balance + funds
elif userInput == "3":
withdraw = float(raw_input("Enter how much money you want to withdraw..."))
balance = balance - withdraw
elif userInput == "4":
print "Thanks for using the ATM!"

Categories