How to fix when Python says: UnboundLocalError: local variable 'money' referenced before assignment - variables

I am having troubles with my money variable. Each time I save and run, a ERROR pops up and I try to fix the problem but can't figure out how? I really need a reply so please soon. This is my project:
money = 0.0
Chop = 0
spike = 0
name = input("What is your name?")
greeting = 'Hello ' + name + ','
def Command():
Command = input('Press \"C\" to continue or Press \"E\" to exit -->')
if name == 'SpikeTheKing':
print('Welcome Spike,')
spike = 1
elif name == 'Spike':
spike = 1
print ('Welcome Spike,')
else:
print(greeting)
def draw_line():
print ('----------------')
def Work1():
Chop = input('Type anything to earn $1 -->')
while Chop == ('C') or ('c'):
print ('$1 earned')
money = money+1
displayMoney()
Chop = 0
Command()
def displayMoney():
draw_line()
print(('Money = '),('$'),(money))
draw_line()
displayMoney()
Work1()
if Command == ('C'):
Work1()
if Command == ('E'):
quit()
Each time I save and run this happens:
Traceback (most recent call last):
File "C:\Users\Leora\Desktop\Python Files\Python.py", line 35, in <module>
Work1()
File "C:\Users\Leora\Desktop\Python Files\Python.py", line 26, in Work1
money = money+1
UnboundLocalError: local variable 'money' referenced before assignment
What should I change?

In the def Work code, before you do money = money+1, you will need to initialize money. So in the first statement after def Work, do: money = 0...
Alternatively, money is global , so you could do global money, in the first line after def Work instead of money=0....
The global keyword tells the interpreter, that money is defined outside the scope of Work function and to look for it there

Related

cx_oracle ORA-01036: illegal variable name/number

I have this group of python scripts where I do an API call, merge the resulting df together, then output to a table in an Oracle db. This exact script is working perfectly in three other scripts configured same, except a different API, but in this particular script, this error is getting thrown. I read up on binds, but I can't see how I'm doing it incorrectly for a tuple. Thanks in advance for your time.
sf_joined = pd.merge(sf_opp, sf_account,on=["CustID","CustID"])
# sf_joined.to_csv('sf_joined.csv', index=False)
# sf_types = sf_joined.dtypes
# print(sf_types)
char_columns = sf_joined.select_dtypes(include=['object']).columns
for col in char_columns:
if col not in ['rundate','Amount','Estimated_GC','Probability','MDC','DaysOpen']:
sf_joined[col] = sf_joined[col].fillna('')
# sf_joined[col] = sf_joined[col].map(lambda x: x.encode('utf-8'))
sf_joined[col] = sf_joined[col].map(lambda x: x[:1000])
pw = '****'
db_con = cx_Oracle.connect('mktg', pw, "prd-bia-db-***.o******.com:1521/BIPRD", encoding = "UTF-8", nencoding = "UTF-8")
cur = db_con.cursor()
print(db_con.version)
cur.execute('drop table cs_salesforce')
create_opps = """create table cs_salesforce(
rundate date,
sfoppid varchar(500)
)
"""
cur.execute(create_opps)
all_opps = []
for x in sf_joined.itertuples():
all_opps.append(x[1:])
insert_statement = """insert into cs_salesforce(rundate,sfoppid)values(:1, :2)"""
cur.executemany(insert_statement, all_opps)
db_con.commit()
Error:
runfile('C:/python_scripts_prod/cs_salesforce.py', wdir='C:/python_scripts_prod')
18.3.0.0.0
Traceback (most recent call last):
File "C:\python_scripts_prod\cs_salesforce.py", line 163, in <module>
cur.executemany(insert_statement, all_opps)
DatabaseError: ORA-01036: illegal variable name/number

ValueError: invalid literal for int() with base 10: 'O'

I am relatively new to python, and as such I don't always understand why I get errors. I keep getting this error:
Traceback (most recent call last):
File "python", line 43, in <module>
ValueError: invalid literal for int() with base 10: 'O'
This is the line it's referring to:
np.insert(arr, [i,num], "O")
I'm trying to change a value in a numpy array.
Some code around this line for context:
hOne = [one,two,three]
hTwo = [four,five,six]
hThree = [seven, eight, nine]
arr = np.array([hOne, hTwo, hThree])
test = "O"
while a != Answer :
Answer = input("Please Enter Ready to Start")
if a == Answer:
while win == 0:
for lists in arr:
print(lists)
place = int(input("Choose a number(Use arabic numerals 1,5 etc.)"))
for i in range(0,len(arr)):
for num in range(0, len(arr[i])):
print(arr[i,num], "test")
print(arr)
if place == arr[i,num]:
if arr[i,num]:
np.delete(arr, [i,num])
np.insert(arr, [i,num], "O")
aiTurn = 1
else:
print(space_taken)
The number variables in the lists just hold the int version of themselves, so one = 1, two = 2 three = 3, etc
I've also tried holding "O" as a variable and changing it that way as well.
Can anyone tell me why I'm getting this error?

PyOmo/Ipopt fails with "can't evaluate pow"

I am using PyOmo to generate a nonlinear model which will ultimately be solved with Ipopt. The model is as follows:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.t = ContinuousSet(bounds=(0,100))
m.T = Param(default=100,mutable=True)
m.a = Param(default=0.1)
m.kP = Param(default=20)
m.P = Var(m.t, bounds=(0,None))
m.S = Var(m.t, bounds=(0,None))
m.u = Var(m.t, bounds=(0,1), initialize=0.5)
m.Pdot = DerivativeVar(m.P)
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[100],sense=maximize)
def _Pdot(M,i):
if i == 0:
return Constraint.Skip
return M.Pdot[i] == (1-M.u[i])*(M.P[i]**0.75)
def _Sdot(M,i):
if i == 0:
return Constraint.Skip
return M.Sdot[i] == M.u[i]*0.2*(M.P[i]**0.75)
def _init(M):
yield M.P[0] == 2
yield M.S[0] == 0
yield ConstraintList.End
m.Pdotcon = Constraint(m.t, rule=_Pdot)
m.Sdotcon = Constraint(m.t, rule=_Sdot)
m.init_conditions = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,nfe=100,ncp=3,scheme='LAGRANGE-RADAU')
discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t)
solver = SolverFactory('ipopt')
results = solver.solve(m,tee=False)
Running the model results in the following error:
Error evaluating constraint 1: can't evaluate pow'(0,0.75).
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/pyomo/opt/base/solvers.py", line 577, in solve
"Solver (%s) did not exit normally" % self.name)
pyutilib.common._exceptions.ApplicationError: Solver (asl) did not exit normally
The first part of the error comes from Ipopt whereas the second part comes from PyOmo. Evidently the issue has something ot do with the term M.P[i]**0.75 in the constraints, but changing the power does not resolve the issue (though 2.0 did work).
How can I resolve this?
The error message states that pow'(0,0.75) cannot be evaluated. The ' character in this function indicates the first derivative ('' would indiate the second derivative). The message is effectively saying that the first derivative does not exist or results in an infinity at zero.
Resolving the issue is easy: bound your variables to a non-zero value as follows:
m.P = Var(m.t, bounds=(1e-20,None))
m.S = Var(m.t, bounds=(1e-20,None))
I would add to Richard's answer:
you might also need to update the initial value of your variable as ipopt assumes 0 if not specified, so it will evaluate the variable at 0 for the first iteration.
hence:
m.P = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
m.S = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
instead of 1e-20 as initialize you might use a value more relevant to your problem

Guess number, no such attribute, python 3

I'm learning OOP in python and was trying to run this small game in OOP style, but for some reason system doesn't find object's attributes.
Here's the problem:
Traceback (most recent call last):
File "HelloUsername.py", line 47, in <module>
newGameGTN = GuessTheNumber()
File "HelloUsername.py", line 6, in __init__
self.start_game()
File "HelloUsername.py", line 32, in start_game
player = player_choice()
NameError: name 'player_choice' is not defined
On this code in python 3:
from random import randint
class GuessTheNumber(object):
"""docstring for GuessTheNumber"""
def __init__(self):
self.start_game()
self.player_choice()
self.compare_numbers()
def player_choice(self):
choice = int(input("Choose your number: "))
if choice in range(101):
return(choice)
else:
print("Please enter a number 0-100")
player_choice()
def compare_numbers(self, computer, player):
if player == computer:
return(0)
elif player > computer:
return(1)
elif player < computer:
return(-1)
def start_game(self):
computer = randint(0, 100)
turn = 0
for turn in range(3):
player = player_choice()
x = compare_numbers(computer, player)
print(computer)
if x == -1:
print("too small")
elif x == 1:
print("too big")
elif x == 0:
print("you win")
break
turn += 1
print("game over")
newGameGTN = GuessTheNumber()
newGameGTN.start_game()
NameError is not the same as AttributeError (which you mention in the question's summary). A NameError exception means that the name referenced in your code does not exist. A name can be a local variable, or a variable in an enclosing scope.
All methods in a class need to be called on an instance of that class. (staticmethods and classmethods not withstanding) Instead of name = player_choice() you need to write name = self.player_choice(). Likewise for all other occurrences where you call a method defined in the class.

Learning Python 3.3 - TypeError: 'int' object is not callable

I was trying to solve Challenge 2 at the end of the classes chapter (Chapter 8) in "Python Programming for the Absolute Beginner" which is stated as:
Write a program that simulates a television by creating it as an object. The user should be able to enter a channel number and raise or lower the volume. Make sure that the channel number and the volume level stay within valid ranges.
I keep getting: TypeError: 'int' object is not callable, which at this stage just isn't very helpful.
I'm a beginner but I've seen something really similar working (see at the bottom right below my code) and nearly went as far as nearly copying that code. Could somebody maybe explain what's wrong with this and how I can get it to work?
Here's the complete error:
Traceback (most recent call last):
File "Untitled 3.py", line 59, in <module>
main()
File "Untitled 3.py", line 50, in main
tv.channel(newchannel = int(input("What channel would you like to set the TV to?")))
TypeError: 'int' object is not callable
My code is below,
Thanks
class Television(object):
"""a TV"""
def __init__(self, channel = 0, volume = 0):
self.channel = channel
self.volume = volume
def channel(self, newchannel = 0):
if newchannel <= 0 or newchannel >9:
print("No negative numbers or numbers higher than 9. Start again from the menu")
else:
self.channel = newchannel
print("You set the TV on channel", self.channel)
def volume(self, newvolume = 0):
if newvolume <= 0 or newvolume >9:
print("No negative numbers or numbers higher than 9. Start again from the menu")
else:
self.volume = newvolume
print("You set the TV on volume", self.volume)
def watch(self):
print("You are watching channel", self.channel, "at volume", self.volume)
def main():
tv = Television()
choice = None
while choice != "0":
print \
("""
TV
0 - Quit
1 - Watch the TV
2 - Change channel
3 - Set the volume
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
elif choice == "1":
tv.watching()
elif choice == "2":
tv.channel(newchannel = int(input("What channel would you like to set the TV to?")))
elif choice == "3":
tv.volume(newvolume = int(input("What channel would you like to set the TV to?")))
# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")
main()
("\n\nPress the enter key to exit.")
Why does the following work instead? To me, it looks pretty similar to what I've done.
class Critter(object):
"""A virtual pet"""
def __init__(self, hunger = 0, boredom = 0):
self.hunger = hunger
self.boredom = boredom
def eat(self, food = 4):
print("Brruppp. Thank you.")
self.hunger += food
if self.hunger < 0:
self.hunger = 0
crit = Critter()
print(crit.hunger)
crit.eat(food = int(input("how much do you want to feed him?")))
print(crit.hunger)
The problem is you are defining a method with the same name as a property. That is, you're saying Television.channel is an int, but later you are binding a method to that name.