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

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?

Related

Cannot pass returned values from function to another function in python

My goal is to have a small program which checks if a customer is approved for a bank loan. It requires the customer to earn > 30k per year and to have atleast 2 years of experience on his/her current job. The values are get via user input. I implemented regexs to validate the input to be only digits without any strigns or negatives, nor 0.
But the 3rd function asses_customer is always executing the else part. I think everytime the parameters are either None, either 0
here's the source code:
import sys
import re
import logging
import self as self
class loan_qualifier():
# This program determines whether a bank customer
# qualifies for a loan.
def __init__(self): #creates object
pass
def main():
salary_check()
work_exp_check()
asses_customer(salary = 0, years_on_job = 0)
def salary_check():
input_counter = 0 # local variable
# Get the customer's annual salary.
salary = raw_input('Enter your annual salary: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary)
while not salary:
salary = raw_input('Wrong value. Enter again: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary)
input_counter += 1
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
else:
return salary
def work_exp_check():
input_counter = 0 #local variable to this function
# Get the number of years on the current job.
years_on_job = raw_input('Enter the number of ' +
'years on your current job: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job)
while not years_on_job:
years_on_job = raw_input('Wrong work experience. Enter again: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job)
input_counter += 1
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
else:
return years_on_job
def asses_customer(salary, years_on_job):
# Determine whether the customer qualifies.
if salary >= 30000.0 or years_on_job >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
# Call main()
main()
You have stated:
It requires the customer to earn > 30k per year and to have at least 2 years of experience on his/her current job.
We can write some simple statements that request a number and if a number is not given then ask for that number again.
The following code is a very simple approach to achieving that goal.
class Loan_Checker():
def __init__(self):
self.salary = 0
self.years_on_job = 0
self.request_salary()
self.request_years()
self.check_if_qualified()
def request_salary(self):
x = raw_input('Enter your annual salary: ')
try:
self.salary = int(x)
except:
print("Please enter a valid number")
self.request_salary()
def request_years(self):
x = raw_input('Enter the number of years on your current job: ')
try:
self.years_on_job = int(x)
except:
print("Please enter a valid number")
self.request_years()
def check_if_qualified(self):
if self.salary >= 30000 and self.years_on_job >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
Loan_Checker()
You have a few errors in your code, and I've refactored it to use the class structure you seemed to want to imply.
import sys
import re
import logging
class loan_qualifier():
# This program determines whether a bank customer
# qualifies for a loan.
def __init__(self): #creates object
self.salary = self.salary_check()
self.years_on_job = self.work_exp_check()
def salary_check(self):
input_counter = 0 # local variable
# Get the customer's annual salary.
salary = None
while salary is None:
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
elif input_counter >= 1:
print ("Invalid salary.")
salary = raw_input('Enter your salary: ')
salary = re.match(r"(?<![-.])\b[1-9][0-9]*\b", salary).group(0)
input_counter += 1
# broke out of loop, so valid salary
return salary
def work_exp_check(self):
input_counter = 0 #local variable to this function
# Get the number of years on the current job.
years_on_job = None
while years_on_job is None:
if input_counter >= 6:
print ("No more tries! No loan!")
sys.exit(0)
elif input_counter >= 1:
print ("Invalid year amount")
years_on_job = raw_input('Enter the number of years at your current job: ')
years_on_job = re.match(r"(?<![-.])\b[1-9][0-9]*\b", years_on_job).group(0)
input_counter += 1
# broke out of loop, so valid years_on_job
return years_on_job
def assess_customer(self):
# Determine whether the customer qualifies.
if int(self.salary) >= 30000.0 and int(self.years_on_job) >= 2:
print 'You qualify for the loan. '
else:
print 'You do not qualify for this loan. '
if __name__ == "__main__":
lq = loan_qualifier()
lq.assess_customer()
Some of the errors fixed include the way you were calling assess_customer initially (you were assigning 0's to both values in the function call), as well as the spelling of assess :p. Your condition in assess_customer should also have been an and instead of an or (you wanted both conditions to be true for them to qualify, not for either condition to be true).
You actually don't even really need to do the:
self.salary = self.salary_check()
self.years_on_job = self.work_exp_check()
lines. You could just directly assign the class variables in the functions (i.e. instead of returning, just set self.salary = blah in salary_check). That's kind of a personal choice thing though. I think this makes it clear.
Hopefully this is all clear to you. Let me know if you have any questions. The code can be called by simply typing python NAME_OF_YOUR_FILE.py.
Edit: I didn't realize how broken the salary and years checks were, the new code should fix them.
Edit: Fixed the regex results in this version. My bad.
In this fragment you pass third function always salary = 0 and years_on_job = 0
Try this way:
salary = salary_check()
years_on_job = work_exp_check()
asses_customer(salary, years_on_job)

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)

Variable will not update

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.

How do you change a variable in a function to then be used in the main code?

I am quite new to Python and I am having some trouble figuring out the following:
import random
import sys
print("Welcome to this Maths quiz.")
playerName = str(input("Please enter your name: "))
playerAge = int(input("Please enter your age: "))
if playerAge < 11:
print("This quiz is not for your age.")
sys.exit(0)
else :
print("Great! Let's begin.\n")
quizQuestions = ["9(3+8)", "7+9*8", "(9+13)(9-5)", "50*25%", "104-4+5*20"]
quizAnswers = ["99", "79", "88", "12.5", "0"]
quizSync = list(zip(quizQuestions, quizAnswers))
random.shuffle(quizSync)
quizQuestions, quizAnswers = zip( * quizSync)
questionNumber = 1
quizScore = 0
def displayQuestion(quizQuestions, quizAnswers, questionNumber, quizScore):
print("Question " + str(questionNumber) + ": " + quizQuestions[questionNumber - 1] + "\n")
questionAnswer = str(input())
if questionAnswer == quizAnswers[questionNumber - 1]:
print("\nCorrect!\n")
quizScore += 1
else :
print("\nIncorrect! The answer is: " + quizAnswers[questionNumber - 1] + "\n")
while questionNumber < 6:
displayQuestion(quizQuestions, quizAnswers, questionNumber, quizScore)
questionNumber += 1
print("You have a total score of: "+str(quizScore))
I would like the variable "quizScore" in the function "displayQuestion" to increase by one if the player gets a question right. However, after the quiz is finished, the print function at the end always prints the score is 0 even if the player gets questions right.
You have to declare it as a global variable inside the function so that it can modify the variable in the global scope
def displayQuestion(quizQuestions, quizAnswers, questionNumber):
global quizScore
...
quizScore += 1
That being said, you should generally avoid global variables if you can and try to redesign your program to either pass the variables along as arguments and return values, or use a class to encapsulate the data.
Although this won't be the shortest answer, which is to use another global variable. It instead will show you how to avoid using global variables (which are considered harmful) by using Object Oriented Programming (OOP). To accomplish this, most of the code in your question can be encapsulated into a single class named MathQuiz below.
Besides getting rid of almost all global variables, it also provides a usable template for you to create any number of independent math quizzes.
import random
import sys
class MathQuiz:
def __init__(self, questions, answers):
quizSync = list(zip(questions, answers))
random.shuffle(quizSync)
self.quizQuestions, self.quizAnswers = zip(*quizSync)
self.quizScore = 0
print("Welcome to this Maths quiz.")
self.playerName = str(input("Please enter your name: "))
self.playerAge = int(input("Please enter your age: "))
if self.playerAge > 10:
print("Great! Let's begin.\n")
else :
print("This quiz is not for your age.")
sys.exit(0)
def run(self):
for questionNumber in range(len(self.quizQuestions)):
self._displayQuestion(questionNumber)
print("You have a total score of: " + str(self.quizScore))
def _displayQuestion(self, questionNumber):
print("Question " + str(questionNumber) + ": "
+ self.quizQuestions[questionNumber-1]
+ "\n")
questionAnswer = str(input())
if questionAnswer == self.quizAnswers[questionNumber-1]:
print("\nCorrect!\n")
self.quizScore += 1
else :
print("\nIncorrect! The answer is: "
+ self.quizAnswers[questionNumber-1]
+ "\n")
quiz = MathQuiz(["9(3+8)", "7+9*8", "(9+13)(9-5)", "50*25%", "104-4+5*20"],
["99", "79", "88", "12.5", "0"])
quiz.run()

Issues with global variables and their values

I'm having some issues with this code. There is a lot of other code to go with it but none that will interfere or have any affect on the issue I'm having. So basically, when I run the code and we get to the for loop at the bottom, it prints nothing because apparently the variable 'walls' = 0, even though I've already given it a valid input. If anyone could help it would be much appreciated.
global walls
global wallLengths
walls = 0
wall = 0
wallLengths = 0
def clientDetails():
#global walls
print("Welcome to the InHouse Solutions Room Painting Price Calculator")
print("STEP 1 - CLIENT DETAILS")
print("Please enter your full name")
userName = input(">>>")
print("Please enter your post code")
postCode = input(">>>")
print("Please enter you first address line here:")
addressLineOne = input(">>>")
print("Please enter your second address line here (OPTIONAL)")
addressLineTwo = input(">>>")
print("Thank you for your information")
print (userName)
print (addressLineOne + ", " + addressLineTwo + ", " + postCode)
print (" ")
def ValidationOne():
print ("Is this information correct? Pleast enter Yes or No")
clientDetailsCorrect = input(">>>")
if clientDetailsCorrect == "no" or clientDetailsCorrect == "No":
clientDetails()
elif clientDetailsCorrect == "Yes" or clientDetailsCorrect == "yes":
roomDimensions()
else:
("Invalid response, please try again")
ValidationOne()
ValidationOne()
def roomDimensions():
global walls
print ("STEP 2 - ROOM DIMENSIONS")
def ValidationTwo():
global walls
print ("How many walls does your room have?")
walls = int(input(">>>"))
if walls > 10 or walls < 3:
print("Invalid, please enter a number between 3 and 10")
ValidationTwo()
elif walls == " " or walls == "":
print("Invalid")
ValidationTwo()
def ValidationThree():
global walls
print ("How tall is the room in meters?")
roomHeight = float(input(">>>"))
if roomHeight < 2.4 or roomHeight > 6:
print ("Invalid, please enter a value between 2.4 and 6")
ValidationThree()
def IndividualWalls():
global wallLengths
global walls
for i in range(1,walls):
print("Please enter the width of wall" , i)
wallLengths[i] = float(input(">>>"))
ValidationTwo()
ValidationThree()
IndividualWalls()
clientDetails()
there is no need to use 'global' keyword when declaring a global at the top of the script:
>>> walls = 0
>>> def increase_walls():
... global walls
... walls += 1
... print walls
...
>>> increase_walls()
1
I can't comment to your question because I don't have over 50 reputation so I will ask here
Can you tell me what the function roomDimensions does?
I tried to run it and you have some deep recursion problem (you can't call recursion function without any if - it will run forever) BUT the first thing that I notice is that you don’t initialize the walls variable so it will not be global variable it will be non-local variable. and you don't call any inner function ( ValidationTwo, ValidationThree,IndividualWalls)
so you main problems are: (handle them in this order)
walls initialize
you didn't call any inner function
deep recursion
here is my example for the use of the three of above:
global_var = 12
def outer():
global global_var
print("*"*10)
print('hello im outer function')
print("*"*10)
def inner1():
global global_var
print('hello im inner1 function')
if global_var < 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var -= 1
return inner1()
def inner2():
global global_var
print('hello im inner2 function')
if global_var >= 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var += 1
return inner2()
if global_var >= 10:
return inner1()
else:
return inner2()
if __name__ == '__main__':
print outer()

Categories

Resources