Variable will not update - python

Made my very first program for school using a basic calculator program but added a variable, not sure if it should be global or local. It calculates fine, but does not return 'tribble' as a new integer.
tribble = 1
def buy():
x=int(raw_input("How many?"))
return (tribble + x);
def sell():
x=int(raw_input("How many?"))
return (tribble - x);
def breed():
x=int(raw_input("Multiply them by 2"))
return (tribble * x);
def cull():
x=int(raw_input("Kill half your Tribbles"))
return (tribble / x);
print "1: Buy"
print "2: Sell"
print "3: Breed"
print "4: Cull"
print "0: QUIT"
while True:
CHOICE = int(raw_input("What will you do with your Tribbles?"))
if CHOICE == 1:
print "Buying Tribbles"
print buy()
print "You have" + str(tribble) + "Tribbles."
elif CHOICE == 2:
print sell()
print 'Selling Tribbles'
print "You have" + str(tribble) + "Tribbles."
elif CHOICE == 3:
print 'Breeding Tribbles, good luck.'
print breed()
print "You have" + str(tribble) + "Tribbles."
elif CHOICE == 4:
print "You're killing them!!"
print cull()
print "You have" + str(tribble) + "Tribbles."
elif CHOICE == 0:
exit()

Are you trying to update the value of tribble?
Then instead of print buy() you should update your variable by using: tribble = buy()
That way you know the value has been updated into the result from the function buy().
Do the same for other functions as well.
Hope it helps.

You don't update the value of tribbles in your functions and thus every time a function is called tribbles is being treated as 1, it's original value. Instead of returning tribbles * 2, for example, just do tribbles *= 2 and then return tribbles.

Yes 'tribble' does not get updated inside the while loop. Because everytime the function returns updated tribble, you're just printing it.
You may want to update tribble this way:
...
...
tribble= buy()
print tribble
...
....

You never reassign the result of your operation to the tribble. I also recommend that you avoid global variables where possible. For example, I would rewrite your cull function to the following:
def cull(number_of_tribbles):
x=int(raw_input("Kill half your Tribbles"))
return number_of_tribbles / x # No need for the parenthesis or the semicolon
# To use
tribble = cull(tribble)
# No need for explicit str conversion in print
print "You have", tribble, "Tribbles."
As a side note, it is odd that your message is "Kill half your Tribbles" yet you ask the user for input. You should either hard code to return tribbles / 2 or change the message to the user; same goes for breed.

You can also do it this way:
tribble = 1
def buy():
global tribble
x = int(raw_input("How many?"))
tribble = tribble + x;
...
print "1: Buy"
print "2: Sell"
print "3: Breed"
print "4: Cull"
print "0: QUIT"
while True:
CHOICE = int(raw_input("What will you do with your Tribbles?"))
if CHOICE == 1:
print "Buying Tribbles"
print buy()
print "You have " + str(tribble) + " Tribbles."
...
elif CHOICE == 0:
exit()
All other methods should be changed in a similar way.
However, it's recommended to avoid using global variables.

Related

Global name 'transact' not defined when trying to run my simple program

I have to create this program for a class. I have been reading in various posts that lists in Python are already global and can be used in def statements.
Here are some of the resources I found that said this:
How to define a global list in python and append local list to it
How to declare python global list
Python global lists
None of these solutions have helped me and I am currently trying to figure this out. I might just have to rewrite it so that it doesn't use "options...". I also have a lot of "\n"s to make it look like it scrolls away from the old outputs because the teacher doesn't want to see them.
Here is the code I am having an issue with:
#!/usr/bin/python
import sys
def Switcher():
selec = 0
while (1):
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== WELCOME TO SPACECODE'S BANK ===="
print "==== Select an Option: ====\n"
print " 0. Check Current Balance\n"
print " 1. Deposit Money\n"
print " 2. Withdraw Money\n"
print " 3. Transaction History\n"
print " 4. Exit\n"
options = {0: zero,
1: one,
2: two,
3: three,
4: four
}
selection = input("\n")
if (selection < 0) or (selection > 4):
print '\n'
else:
selec = selection
options[selec]()
def zero():
global current
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== YOUR CURRENT BALANCE: ====\n"
print current
raw_input("\n Press enter to continue....")
Switcher()
def one():
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
global current, i
print "\n==== INPUT DEPOSIT AMOUNT: ====\n"
add = input()
current = add + current
i =+ 1
transact.append(i)
account.append(current)
raw_input("\n Press enter to continue....")
Switcher()
def two():
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n==== INPUT AMOUNT TO WITHDRAWL: ====\n"
global current, i
temp = current
wdrw = raw_input()
if (temp == 0):
print "==== YOU DONT HAVE ANY MONEY TO WITHDRAWL ====\n"
Switcher()
elif ((temp - wdrw) < 0):
print "==== YOU CANT WITHDRAWL MORE THAN YOU HAVE IN BALANCE ====\n"
two()
elif ((temp - wdrw) >= 0):
i =+ 1
transact.append(i)
current = temp - wdrw
account.append(current)
print "\n==== TRANSACTION SUCCESSFUL ====\n"
raw_input("\n Press enter to continue....")
Switcher()
def three():
global i
print "\n\n\n\n\n\n\n\n\n\n\n\n\n"
print "\n ==== TRANSACTION HISTORY (SAVES LAST 30) ====\n"
for w in range(len(trasac)):
print(transac[w]," : ",account[w])
print()
raw_input("\n Press enter to continue....")
Switcher(current)
def four():
sys.exit()
account = []
current = 0
transac = []
i = 0
Switcher()
Is it perhaps because you are declaring transac = [] instead of transact = [] at the bottom of your code?

Python switching the display based on input using If, Else

I want to display print text based on my Input value using IF/Else or Switch. And Also let me know how to use switch case for below code.
# OnButtonOK after clicking it, display the input value
def OnButtonOK(self):
Input = self.entrytext.get()
# self.text.insert(END, Input + '\n')
# self.scroll.config(Input = self.text.yview)
print Input
useroption = atoi(Input)
# self.OnButtonClick();
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
return;
def SubMenu1(self):
print 'SubMenu1'
return;
def SubMenu2(self):
print 'SubMenu2'
return;
def SubMenu3(self):
print 'SubMenu3'
return;
I am able to print only else part:
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
Let me know where exactly i am going wrong.
I think you have indentation problems in your code:
Python use 4 spaces(you can use 1 space but 4 is good practice) indentation language. Means if/else statement will be like this:
if a == 1:
print("A = 1") # 4 spaces w.r.t to above statement
elif a == 2:
print("A = 2")
elif a ==3:
print("A = 4")
else:
print("A = pta nahi")
you can use above if/else statements as a switch case and also your indentation problem will be solved
It's a simple beginner's mistake, you're indenting it worng:
if (useroption == 1):
print "input is output"
self.SubMenu1();
else:
print "Error:Invalid"
should be
if (useroption == 1):
print "input is output" # You had an indent too many here
self.SubMenu1();
else:
print "Error:Invalid"
Python is indentation sensitive; too many or too few indentations will break your code.

Python loop just keep going

I'm making a dart score keeper but it just keeps going round and round. I just need some help as to why this is.
The code:
import time
import sys
from sys import argv
script, name1, name2 = argv
def dartscore():
print "Play from 501 or 301?"
threeorfive = int(raw_input())
if (threeorfive == 501):
def playerone():
startnum1 = threeorfive
while (startnum1 > 0):
print "Ready ", name1,"?"
print "Please enter your score."
minusnum1 = int(raw_input())
startnum1 = startnum1 - minusnum1
playertwo()
if (startnum1 == 0):
print "Well done! You win!"
elif (startnum1 < 0):
print "Sorry but you have entered a wrong score"
playertwo()
def playertwo():
startnum2 = threeorfive
print "Ready ", name2,"?"
print "Please enter your score."
minusnum2 = int(raw_input())
startnum2 = startnum2 - minusnum2
if (startnum2 == 0):
print "Well done! You win!"
print "Unlucky ", name1,". Well played though."
sys.exit()
if (startnum2 < 0):
print "Sorry but you have entered an incorrect score. Please try again"
startnum2 += minusnum2
playerone()
playerone()
dartscore()
Now the two functions playerone() and playertwo() are different because I was trying something with the playerone() function to see if that solved my problem.
Well you have a while(startnum1 > 0):. It seems like startnum1is always bigger then 0. The only way to exit your loop is player 2 has a startnum2 on 0.
Your problem is:
threeorfive = 501
Throughout the entire game, and you begin each of your functions with
startnum = threeorfive
Which means the game 'resets' after both player takes a turn.
A possible fix would be to add global variables:
cumulative1 = 0
cumulative2 = 0
then update cumulative in each iteration:
cumulative1 += minusnum1
cumulative2 += minusnum2
and change your while loop to:
while(threeorfive - cumulative1 > 0)
while(threeorfive - cumulative2 > 0)

While-Loop Use in Python

When you come to the 2nd while loop while x == 2: it's still repeating the whole script even though x /= 1 (not if "n"is entered). Let say we enter "y" on the prompt "Is this correct?" shouldn't x become 3 which stops both the first and the 2nd loop?
This is probably obvious but I'm pretty new.
# -*- coding: utf-8 -*-
import time
x = 1
while x == 1:
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
while x == 2:
if correct == "y":
x = 3 # x = 3 skips all whiles, not working
time.sleep(1)
elif correct == "n":
time.sleep(1)
x = 1 # x = 1 --> 1st while still in action
else:
print "Invalid input \n\t Loading..."
x = 2 # x = 2 --> 2nd while takes over
print "Where do you live?"
time.sleep(0.5)
country = raw_input("Country: ")
time.sleep(0.5)
city = raw_input("City: ")
time.sleep(1)
print " \n Data: \n\t Name: %r \n \t Age: %r \n \t Country: %r \n \t
City: %r " % (name, age, country, city )
In the code you never change the value of your x to 2 so your inner loop while x==2: never runs and you loop infinitely. You need to change the value of x just inside the while x==1: loop for you to even enter the second loop.
The while structure is totally unnecessary, use functions instead and chain them
def ask():
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
return decide(name,age) #<-- Goes to decide
def decide(name,age):
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
if correct == "y":
return name,age #<-- process finishes
elif correct == "n":
return ask() #<-- goes back to asking
else:
print "Invalid input"
return decide(name,age) #<--Goes back to wait for a valid input
name, age = ask() #<--Starts the whole process
While I like my other answer better, if you want this code to work with just a slight modification, just bring the definition of correct to the inner loop and as Abdul Fatir say, kick in an x = 2. Anyhow using creating a state machine this way is not recommended.
x = 1
while x == 1:
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
x = 2 #<--Necessary
while x == 2:
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
if correct == "y":
x = 3 # x = 3 skips all whiles, not working
time.sleep(1)
elif correct == "n":
time.sleep(1)
x = 1 # x = 1 --> 1st while still in action
else:
print "Invalid input \n\t Loading..."
x = 2 # x = 2 --> 2nd while takes over
I like the solution involving chaining functions, but I also think that you could use some help with your input validation. I really nice tool for this is not in to validate it ahead of time. For instance
def ask():
print "What's your name?"
name = raw_input("Name: ")
print "How old are you?"
age = raw_input("Age: ")
return decide(name,age) #<-- Goes to decide
def decide(name,age):
print "So you are %r years old and your name is %r. Is this correct?" % (age, name)
correct = raw_input("(y/n): ")
while correct not in ["y", "n"]:
correct = raw_input("(y/n): ")
if correct == "y":
return (name,age) #<--process finishes
else
return ask() #<-- goes back to asking
Just to be clear, I ripped a large portion of that code from another answer, but I think that doing it that way is more efficient, and puts all acceptable answers in once place for easy viewing. It would even allow for more complex input validation, and potentially let you use a constant or config file to define available options.

Referenced before assignment Python

I have the following code:
#AON = Amount of Numbers to average
def general():
print "Enter how many numbers you will enter."
print "Maximum amount is 10: "
aon = raw_input()
try:
aon = int(aon)
if aon >= 10:
print "I cannot average more than 10 numbers."
general()
else:
start_average()
except ValueError:
print "You entered an invalid input, try again."
general()
def start_average():
if aon == 1:
print "You cannot average one number."
general()
elif aon == 2:
def first_number():
print "First number: "
first_ni = raw_input()
second_number()
first_number()
def second_number():
print "Second number: "
second_ni = raw_input()
ans_two = first_ni / second_ni
second_number()
final_two()
elif aon == 3:
def third_number():
first_number()
second_number()
print "Third number: "
third_ni = raw_input()
ans_three = ans_two / third_ni
third_number()
final_three()
elif aon == 4:
def fourth_number():
first_number()
second_number()
third_number()
print "Fourth number: "
fourth_ni = raw_input()
ans_four = ans_three / fourth_ni
fourth_number()
final_four()
elif aon == 5:
def fifth_number():
first_number()
second_number()
third_number()
fourth_number()
print "Fifth number: "
fifth_ni = raw_input()
ans_five = ans_four / fifth_ni
fifth_number()
final_five
def final_two():
final_input = ans_two
final_answer()
def final_three():
final_input = ans_three
final_answer()
def final_four():
final_input = ans_four
final_answer
def final_five():
final_input = ans_five
final_answer()
def final_six():
final_input = ans_six
final_answer()
def final_seven():
final_input = ans_seven
final_answer()
def final_eight():
final_input = ans_eight
final_answer()
def final_nine():
final_input = ans_nine
final_answer()
def final_answer():
listofnumbers = [first_ni, second_ni, third_ni, fourth_ni, fifth_ni, sixth_ni, seventh_ni, eight_ni, ninth_ni]
print "The average of your numbers:"
print listofnumbers
print "Is = %d." % final_input
general()
It's purpose is to find the average of a number, but when I run it through PowerShell, I get the following error:
Traceback (most recent call last):
File "average.py", line 97, in <module>
general()
File "average.py", line 10, in general
general()
File "average.py", line 10, in general
general()
File "average.py", line 12, in general
start_average()
UnboundLocalError: local variable 'start_average' referenced before assignment
I've probably done this more throughout my code, and I just made this, but I just don't know how to fix it or what is the error showing! I don't understand.
It's hard to tell from what you've pasted, because you've clearly broken the indentation.
But it looks like this code:
print "Enter how many numbers you will enter."
print "Maximum amount is 10: "
… is meant to be inside general, while this code:
aon = raw_input()
try:
aon = int(aon)
if aon >= 10:
print "I cannot average more than 10 numbers."
general()
else:
start_average()
except ValueError:
print "You entered an invalid input, try again."
general()
… is meant to be at module level.
Code is executed in the order it appears. Function definitions are just code, like anything else. So, you can't call a function before you define it, because the function doesn't exist yet.
You're probably about to object, with an example like this:
def foo():
bar()
def bar():
print('Hi!')
foo()
It looks like we're calling bar before it exists, and yet it works. How?
Well, the definition of foo is being executed before bar exists, but that's fine. That just defines a function that will, when run, call whatever bar means. As long as we've defined bar before we call it—and we have—everything is fine.
However, you have a number of similar problems in your code. For example, let's look at this part:
elif aon == 2:
def first_number():
print "First number: "
first_ni = raw_input()
second_number()
first_number()
def second_number():
print "Second number: "
second_ni = raw_input()
ans_two = first_ni / second_ni
second_number()
final_two()
That first_ni is a local variable within the first_number function. Every time you call first_number, a new first_ni gets defined, but only visible within that function. You can't use it in second_number, because second_number can only see its own local variables, and global variables, and first_ni is neither.
The concept you need to understand is called scope. Python has some nice tools to help you understand scope. You can print out locals() and globals() and dir() at any part of your program to see what's in scope there. But you'll need to read the tutorial first.
Indentation and a few other things are questionable. I'm not sure why you're defining all of these functions inside of other functions... I think this will do what you want. You're going to need a lot more error checking though (making sure the inputs are integers, divide by 0, etc.)
>>> def getMean(maxNumsToDivide):
... listNums = []
... for i in range(maxNumsToDivide):
... num = raw_input("Please enter a number: ")
... if not num:
... break
... listNums.append(int(num))
... return float(sum(listNums))/len(listNums)
...
>>> getMean(100)
Please enter a number: 2
Please enter a number: 3
Please enter a number: 4
Please enter a number: 5
Please enter a number: 3
Please enter a number:
3.4

Categories

Resources