In this code I tried to make that when you type "work", you get any number from 1 to 50 and it adds itself to the total balance (5 times). But when I do this, the previous amount of the variable resets to the new amount.
import random
balance = 0
def work(balance):
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work(balance)
Even though the global keyword solves your problem, depending on who you ask, global variables are considered bad practice in Python. I try to avoid them unless there's absolutely no other way, and in this case, it's quite easy to come up with a solution that doesn't need globals:
import random
balance = 0
def work(balance):
earned_money = random.randint(1, 50)
return balance + earned_money
for x in range(5):
user_input = input()
if user_input == "work":
balance = work(balance)
print(balance)
I recommend learning more about variable scope.
Here is working code. You need to declare it as global.
import random
balance = 0
def work():
global balance
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work()
The outer balance variable is in global scoping whereas the balance variable inside function is in local scoping.
If you want to make local scope variable global then you need to use global keyword inside your function.
import random
balance = 0
def work():
global balance # This makes balance variable global.
earned_money = random.randint(1, 50)
balance += earned_money
print(balance)
for x in range(5):
user_input = input()
if user_input == "work":
work()
Related
For example, let's say I'm trying to create a wallet system in python where money can be add to and taken out of. I try this code here:
balance = 0
def addmoney(x):
x += balance
addmoney(10000)
print(balance)
but it just gave me 0.
so then I tried this:
def addmoney(x):
balance = 0
balance += x
And I realized that this would set the money back to 0 every time the user adds money, which I didn't want. Is there a solution to this?
You could declare the balance variable as global inside the function.
balance = 0
def addmoney(x):
global balance
balance += x
addmoney(10000)
print(balance)
This is usually do with OOP:
class BankAccount:
def __init__(self, owner, balance, currency):
self.owner = owner
self.balance = balance
self.currency = currency
def print_balance(self):
print("Your current balance is:")
print(self.balance)
def make_deposit(self, amount):
if amount > 0:
self.balance += amount
else:
print("Please enter a valid amount.")
def make_withdrawal(self, amount):
if self.balance - amount >= 0:
self.balance -= amount
else:
print("You don't have enough funds to make this withdrawal.")
To call the function:
my_savings_account = BankAccount("Pepita Perez", 45600, "USD")
my_savings_account.print_balance()
my_savings_account.make_deposit(5000)
my_savings_account.make_withdrawal(200)
my_savings_account.print_balance()
In Python, you must use the global keyword when accessing global variables from within a function. See here.
One way to keep track of the changes is to store the previous values in a list outside the function. Again, using the global keyword
Also your logic for the balance is backwards. You should be adding x to the balance.
balance = 0
historyLst = []
def addmoney(x):
global balance
global historyLst
historyLst.append(balance)
balance += x
addmoney(10000)
print(balance)
So what I mean by this is if you have this code for example:
def test():
money = 0
x = input('')
if x == "givemoney":
money = money + 100
print(money)
test()
else:
print("something")
test()
It'll reset money to 0 every time the function goes which makes sense but how could I stop that?
You should use a loop. Here money is defined and initialized in a scope local to the function when the function is called; this is why it reset for every call to test().
def test():
money = 0
x = input('')
while x != 'stop':
if x == "givemoney":
money = money + 100
print(money)
x = input('')
else:
print("something")
test()
In the first version you can make money an optional parameter to the function. When you call it from the top-level you allow it to default. When you make the recursive call, you pass the current value in place of the default.
def test(money = 0):
x = input('')
if x == "givemoney":
money = money + 100
print(money)
test(money)
else:
print("something")
test()
I am trying to build a small game in python. The idea is that there will be a random generated number and before you start you can choose your difficulty (the max number the random number will be) and I ran into a problem.
I have defined difficulty_input where it asks you what the difficulty should be and saves it to a string called difficulty. After this, I defined difficulty_check where it checks in what category the answear fits in (easy, medium or hard) and after it found what difficulty it is, it generetes the random number according to the difficulty but I get an error syaing:
NameError: name 'x' is not defined
Here is the code:
from random import randrange
global x
def difficulty_input():
global difficulty
difficulty = input('Choose the difficulty;Easy(1-20 ), Medium(1-50 ), Hard(1-100): ')
def difficulty_check():
difficulty_input()
if difficulty == "Easy":
x = randrange(20)
elif difficulty == "Normal":
x = randrange(50)
elif difficulty == "Hard":
x = randrange(100)
else:
difficulty_check
difficulty_check()
print (x)
You need to refer to global x inside the function. Everything outside - in the main program body - is by definition global:
#import random
from random import randrange
x=0
def difficulty_input():
global difficulty
difficulty=input('Choose the difficulty;Easy(1-20 ),Medium(1-50 ),Hard(1-100): ')
def difficulty_check():
difficulty_input()
global x
if difficulty=="Easy":
x = randrange(20)
elif difficulty=="Normal":
x = randrange(50)
elif difficulty=="Hard":
x = randrange(100)
else:
difficulty_check
difficulty_check()
print (x)
In this code
money = .3
Things = ["Nothing"]
def main():
print "go to buy things"
print "Current Money %s" % (money)
print "Things you have:"
for item in Things:
print item
wait = raw_input()
buythings(money)
def buythings(money):
print "Type Buy to buy things"
buy = raw_input()
if buy == "buy":
money = money - .3
Things.append("Things")
main()
else:
print "you bought nothing"
print ""
main()
Why after buying the things does the money not go down? This has been a problem to me for a while now and I cant seem to understand how the scope works in this situation.
The global variable money is shadowed by the function parameter money in buythings(money) function. You should remove the parameter for it to work:
def main():
global money
global Things
...
def buythings():
global money
global Things
...
However, A better approach, as alfasin pointed out, would be passing money and Things as parameters to both functions and not using global keyword at all:
def main(money, things):
...
for item in things:
print item
wait = raw_input()
buythings(money, things)
def buythings(money, things):
...
if buy == "buy":
money = money - .3
Things.append("Things")
main(money, things)
else:
...
main(money, things)
>>> money = .3
>>> Things = ["Nothing"]
>>> main(money, Things)
Hope this helps.
You can use a global variable in other functions by declaring it as global in each function that assigns to it:
money = 0
def set_money_to_one():
global money # Needed to modify global copy of money
money = 1
def print_money():
print money # No need for global declaration to read value of money
set_money_to_one()
print_money() # Prints 1
In your case :
def buythings():
global money
Python wants to make sure that you really know what you're
playing with by explicitly requiring the global keyword.
I'm coding a small program to time and show, in a ordered fashion, my Rubik's cube solvings. But Python (3) keeps bothering me about times being used prior to global declaration. But what's strange is that IT IS declared, right on the beggining, as times = [] (yes, it's a list) and then again, on the function (that's where he complains) as times = [some, weird, list] and "globaling" it with global times. Here is my code, so you may analyse it as you want:
import time
times = []
def timeit():
input("Press ENTER to start: ")
start_time = time.time()
input("Press ENTER to stop: ")
end_time = time.time()
the_time = round(end_time - start_time, 2)
print(str(the_time))
times.append(the_time)
global times
main()
def main():
print ("Do you want to...")
print ("1. Time your solving")
print ("2. See your solvings")
dothis = input(":: ")
if dothis == "1":
timeit()
elif dothis == "2":
sorte_times = times.sort()
sorted_times = sorte_times.reverse()
for curr_time in sorted_times:
print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
else:
print ("WTF? Please enter a valid number...")
main()
main()
Any help would be very appreciated as I'm new in the world of Python.
The global declaration is when you declare that times is global
def timeit():
global times # <- global declaration
# ...
If a variable is declared global, it can't be used before the declaration.
In this case, I don't think you need the declaration at all, because you're not assigning to times, just modifying it.
From the Python documentation:
Names listed in a global statement must not be used in the same code block
textually preceding that global statement.
https://docs.python.org/reference/simple_stmts.html#global
So moving global times to the top of the function should fix it.
But, you should try not to use global in this situation. Consider using a class.
From the Python Docs
Names listed in a global statement must not be used in the same code block textually preceding that global statement.
This program should work but may not work exactly as you intended. Please take note of the changes.
import time
times = []
def timeit():
input("Press ENTER to start: ")
start_time = time.time()
input("Press ENTER to stop: ")
end_time = time.time()
the_time = round(end_time - start_time, 2)
print(str(the_time))
times.append(the_time)
def main():
while True:
print ("Do you want to...")
print ("1. Time your solving")
print ("2. See your solvings")
dothis = input(":: ")
if dothis == "1":
timeit()
elif dothis == "2":
sorted_times = sorted(times)
sorted_times.reverse()
for curr_time in sorted_times:
print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
break
else:
print ("WTF? Please enter a valid number...")
main()
import time
times = []
def timeit():
global times
input("Press ENTER to start: ")
start_time = time.time()
input("Press ENTER to stop: ")
end_time = time.time()
the_time = round(end_time - start_time, 2)
print(str(the_time))
times.append(the_time)
main()
def main():
print ("Do you want to...")
print ("1. Time your solving")
print ("2. See your solvings")
dothis = input(":: ")
if dothis == "1":
timeit()
elif dothis == "2":
sorte_times = times.sort()
sorted_times = sorte_times.reverse()
for curr_time in sorted_times:
print("%d - %f" % ((sorted_times.index(curr_time)+1), curr_time))
else:
print ("WTF? Please enter a valid number...")
main()
main()
that should work. The "global[varname]" have to be at start from definition ;)
For the main program, you can declare it on the top. Ther will be no warning. But, as said, the global mention is not useful here. Each variable put in the main program is in the global space. In functions, you must declare that you want use the global space for it with this keyword.
I got the same error below:
SyntaxError: name 'x' is used prior to global declaration
When trying to use the local and global variables x in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
x = 10 # Local variable
x += 1
print(x)
global x # Global variable
x += 1
print(x)
inner()
outer()
And, when trying to use the non-local and global variables x in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
nonlocal x # Non-local variable
x += 1
print(x)
global x # Global variable
x += 1
print(x)
inner()
outer()
So, I renamed x to y for the local variable as shown below:
x = 0
def outer():
x = 5
def inner():
y = 10 # Here
y += 1 # Here
print(y) # Here
global x
x += 1
print(x)
inner()
outer()
Then, the error was solved as shown below:
11
1
And, I renamedx to y for the non-local variable as shown below:
x = 0
def outer():
y = 5 # Here
def inner():
nonlocal y # Here
y += 1 # Here
print(y) # Here
global x
x += 1
print(x)
inner()
outer()
Then, the error was solved as shown below:
6
1