def inputKilos():
while True:
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
convert_kilos(numKilos)
return
def convert_kilos(numKilos):
numMiles = numKilos * 0.6214
print_output()
return
def print_output():
print numKilos, "kilometers eqauls", numMiles, "miles."
def main():
inputKilos()
main()
When I try to run the program it says "NameError: global name 'numKilos' is not defined" I don't know why it says numKilos isn't defined. numKilos is equal to the number that the user enters.
numKilos is a local variable in both inputKilos and convert_kilos, but not print_output. Local variables can only be accessed from within that function.
To pass variables around, use return <value> to return a value from the function, then collect it by using result = function(), or do the reverse by passing values into functions (like you did with convert_kilos.
Those are local variables not global.
You can try this:
#!/usr/bin/python
def inputKilos():
while True:
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
miles = convert_kilos(numKilos)
print_output(numKilos,miles)
return
def convert_kilos(numKilos):
numMiles = numKilos * 0.6214
return numMiles
def print_output(numKilos,numMiles):
print numKilos, "kilometers eqauls", numMiles, "miles."
inputKilos()
Or using global keyword:
#!/usr/bin/python
numKilos=0
numMiles=0
def inputKilos():
while True:
global numKilos
numKilos = float(raw_input("Enter a number of Kilometers. Enter 0 to end program. "))
if numKilos == 0:
break
else:
convert_kilos(numKilos)
print_output
def convert_kilos(numKilos):
global numKilos
global numMiles
numMiles = numKilos * 0.6214
def print_output:
global numKilos
global numMiles
print numKilos, "kilometers eqauls", numMiles, "miles."
inputKilos()
Here's a refactored version:
MILES_PER_KM = 0.621371
def get_float(prompt=''):
while True:
try:
return float(raw_input(prompt))
except ValueError:
pass
def main():
while True:
kms = get_float('Enter a distance in kms (or 0 to exit): ')
if kms:
miles = MILES_PER_KM * kms
print ' {} kilometers is {} miles.'.format(kms, miles)
else:
break
if __name__=='__main__':
main()
Related
from better_blackjack.preset_folder import build_deck
"""
This file is used to load all the things we need to run game.py (player_chips, deck, number of hands, bet amount)
"""
with open(r"C:\Hacks\python\programs\better_blackjack\Save_settings/chips.txt", "r") as file:
file_data = file.read()
if len(file_data) == 0:
player_chips = 1000000 # This will get altered (live amount of chips)
else:
try:
player_chips = int(file_data)
except ValueError:
print('File corrupted... restarting player chips ')
player_chips = 1000000
print(player_chips)
def get_num_hands():
try:
num_hands = (int(input('How many hands would you like ? ')))
get_bet_amount(num_hands)
except ValueError:
print('Use a valid number.')
get_num_hands()
def get_bet_amount(num_hands):
list_of_bets = []
for i in range(1, num_hands+1):
try:
print('How much would you like to bet on hand', i, ' Balance', player_chips)
bet_amount = int(input())
list_of_bets.append(bet_amount)
player_chips = player_chips - bet_amount
if player_chips < 0:
print('Bets exceed player balance... Restarting betting process')
player_chips = int(file_data)
get_bet_amount(num_hands)
return None # ends func
except ValueError:
print('Please use numbers only !... Restarting betting process')
player_chips = int(file_data)
get_bet_amount(num_hands)
return None # ends func
deck = build_deck.deck
get_num_hands()
I am getting the error 'player_chips' referenced before assignment on the following line - print('How much would you like to bet on hand', i, ' Balance', player_chips)
However it is defined before we call any of our functions how could this be ?
If a variable is modified inside a function, it is a local variable, and has nothing to do with the global variable of the same name. Hence player_chips inside get_bet_amount has nothing to do with the variable of the same name used at top level.
Add global player_chips inside your function to override this behavior.
I'm creating a simple program to take in time and distance to then state the speed, but I want to do this with classes to learn about oop in python. I'm not figuring out how to set the loop to keep going until the user decides to not go again.
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
You need following code:
y=True
while y:
class Timer:
def __init__(self,speed):
self.speed=speed
def log(self):
print(mph)
global y
again=input('Go again? y or n: ')
if again=='y':
y=True
else:
print('Thank you')
y=False
if y:
m=float(input('Enter the minutes: '))
s=float(input('Enter the seconds: '))
d=float(input('Enter distance: '))
x=(m*60)+s
x_tot=(x/3600)
mph=d/x_tot
t=Timer(mph)
t.log()
else:
break
The y variabel inside log function should be global else it won't change global y referred inside if-else. We need if-else with y so that we can break out of loop if user chooses n. The t=Timer(mph) has to be inside while loop because class is not known outside the loop. Same applies for t.log function call.
Honestly to make your code easier to debug and track where changes are occuring, you should pull the class out of the loop and then reference it inside the loop when you need to use it.
In the init, I would pull out the assignment of the speed variable and just initialize it as none.
def __init__(self):
self.speed = None
Then you can add a separate private setter function to set the speed with user input and do error checking around it. Note, I have set the program to exit with a 0 code if the user inputs something wrong, but you can easily make another loop here that will wait until the user finally does input valid values for all the inputs. The __ double underscore in front of the function name makes it private to the class.
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
Now you can update the log function to not even worry about the y variable by changing it to this:
def log(self):
self.__set_mph()
print(mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
Now we just initialize the class before the loop and clean it up to be make it more manageable.
t = Timer()
while True:
if not t.log():
break
Final Code:
class Timer:
def __init__(self):
self.speed = None
self.mph = None
def __set_mph(self):
try:
m = float(input('Enter the minutes: '))
s = float(input('Enter the seconds: '))
d = float(input('Enter distance: '))
x = (m * 60) + s
x_tot = (x / 3600)
self.mph = d / x_tot
except (ValueError, ArithmeticError) as e:
print(f'Invalid user input: {e}')
exit(0)
except Exception as e:
print(f'Unexpected error: {e}')
exit(0)
def log(self):
self.__set_mph()
print(self.mph)
again = input('Go again? y or n: ')
if again == 'y':
return True
else:
print('Thank you')
return False
t = Timer()
while True:
if not t.log():
break
OOP is all about modeling your real world objects into programmatic objects that maintain the features and functionality of the real world object to its programatic counterpart's attributes and features, respectively.
Also, those objects should be separated on its own. Creating and calling a class from within a while loop is pretty bad practice. I would encourage you to separate the code based on its purpose. for example, I would have a file called timer.py to handle the Object that matches the timer like so:
# The timer class
class Timer:
def calculate_speed(self, minutes, seconds, distance):
hours = (minutes * 60) + seconds
tot_time = (hours / 3600)
return distance / tot_time
def get_speed(self):
minutes = float(input('Enter the minutes: '))
seconds = float(input('Enter the seconds: '))
distance = float(input('Enter distance: '))
return self.calculate_speed(minutes, seconds, distance)
Then in your main file:
from timer import Timer
timer = Timer()
while True:
user_response = input('Go again? y or n: ').lower()
if user_response == 'n':
break
elif user_response == 'y':
speed = timer.get_speed()
print(f'Your speed is {speed}')
else:
print('Not a valid response')
This makes it easier on the backend too. In other words, if you have an error that relates to the calculations, you know where to start looking.
in order to fix the NameError (name not defined problem) I used the global keyword like this, but I don't think it's a good solution. And I want to put the last part of the code into a function (main()), but then again the not defined error occurs with purchase_item function, Can someone help me improve this code?
from RetailItem import RetailItem
class CashRegister:
global Item_List
global Cashier_List
global total
Item_List = [ RetailItem("Item 1","Jacket", 12, 59.95),
RetailItem("Item 2", "Designer Jeans", 40, 34.95),
RetailItem("Item 3", "Shirt", 20, 24.95) ]
Cashier_List = []
total = 0
def purchase_item(RetailItem):
global Cashier_List
Cashier_List.append(RetailItem)
def get_total():
global Cashier_List
global total
for o in Cashier_List:
total += o.getPrice()
return total
def show_items():
global Cashier_List
for o in Cashier_List:
print(o)
def clear():
global Cashier_List
del Cashier_List[:]
print("Here are available items:")
for o in Item_List:
print(o)
while True:
x = input("Select items by number to buy or enter \"n\" to finish shopping: ")
if x != "n":
try:
purchase_item(Item_List[int(x)-1])
print("ADDED!")
except ValueError:
print("Invalid number, try again!")
except IndexError:
print("Invalid number, try again!")
else:
break
print("......The total price is ${:0.2f}\n......This is your checkout items:".format(get_total()))
show_items()
I am working on some Python code where I create a basic ATM. The issue I am having is I am not able to get the result that I want its printing "<'function Account.balance at 0x012CBC90>" Instead of the actual balance number. So far I have only tested using jsmith. Feel free to call out any other issues that may cause a problem later.
class Account:
def __init__(self,user,pin,balance):
self.user = user
self.pin = pin
self.balance = int(balance)
def get_user(self):
return self.user
def get_pin(self):
return self.pin
def balance(self):
return int(self.balance)
def setBalance(self,newBalance):
self.balance = newBalance
def __repr__(self):
return str(self.user) + " " + str(self.pin) + " " + str(self.balance)
class ATM:
def withdraw(self,Person,amount):
result = Person - amount
return result
def check(self,Person):
Person = Account.balance
return str(Person)
def transfer(self,id1,id2):
pass
def __str__(self):
return self
def main():
Chase = ATM()
Database = []
Teron_Russell = Account("trussell",1738,0)
Joe_Smith = Account("jsmith",1010,1350)
print(Teron_Russell)
Database.append(Teron_Russell)
Database.append(Joe_Smith)
print("Welcome to the ATM")
id = input("Please enter your user ID: ")
pin = input("Enter your pin: ")
chosen = ""
for i in Database:
print("Test1")
name = Account.get_user(i)
print(name)
checkPin = Account.get_pin(i)
print(checkPin)
if id == name and pin == checkPin:
chosen = i
choice = input("What would you like to do. (Type 'Check','Withdraw','Transfer': ")
if(choice == "Check" or "check"):
print(Chase.check(chosen))
# if(choice == "Withdraw" or "withdraw"):
# wAmount = eval(input("How much would you like to Withdraw: "))
# # Chase.withdraw(Account.balance,)
# elif(choice == "Check" or "check"):
# Chase.check()
# else:
# print("Invalid Choice!")
if __name__ == "__main__":
main()
You named a variable and a method the same name, so the interpreter is confused on which one to use. Change the name of either the method or variable balance and you won't have this problem. Additionally, this isn't java, and you shouldn't use classes for no reason. Since you aren't using any instance variables, it is pointless to have all of those methods inside that class.
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