UnboundLocalError: local variable 'endProgram' referenced before assignment - python

I've seen multiple posts about this same issue but no answers that satisfy my issue. I wrote this code from a pseudo code provided as part of my class assignment, this generally seems to be a common error in my programs and normally I circumvent the issue by taking another route. for this program though i'm required to follow the exact pseudo and its left me boggled. so here goes
def main():
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount)
while endProgram == 'no' or endProgram == 'No':
resetVariables(totalBurger, totalFry, totalSoda, total, tax, subtotal)
while endOrder == 'no' or endOrder == 'No':
print("Enter 1 for Yum Yum Burger")
print("Enter 2 for Grease Yum Fries")
print("Enter 3 for Soda Yum")
option = input("Please make your selection: ")
if option == 1:
getBurger(totalBurger, burgerCount)
return option
elif option == 2:
getFry(totalFry, fryCount)
return option
elif option == 3:
getSoda(totalSoda, sodaCount)
return option
endOrder = input("Do you want to end your order?(Enter no to add more items: ")
return endOrder
calcTotal(burgerTotal, fryTotal, sodaTotal, total, subtotal, tax)
printReceipt(total)
endProgram = input("Do you want to end the program?(Enter no to process a new order)")
return endProgram
def declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount):
endProgram = 'no'
endOrder = 'no'
totalBurger = 0
totalFry = 0
totalSoda = 0
total = 0
tax = 0
subtotal = 0
option = 0
burgerCount = 0
fryCount = 0
sodaCount = 0
obviously the rest of the program is much longer but I feel this is the only relevant information
the full error displays as follows:
Traceback (most recent call last):
File "C:/Users/edigi/Desktop/FSW/COP 1000/YumYumBurger.py", line 96, in
main()
File "C:/Users/edigi/Desktop/FSW/COP 1000/YumYumBurger.py", line 15, in main
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
UnboundLocalError: local variable 'endProgram' referenced before assignment
I cant seem to avoid this issue, just an explanation of what i'm doing wrong will be fine for me.

The very first line in main() is this:
declareVariables(endProgram, endOrder, totalBurger, totalFry, totalSoda, total, tax,
subtotal, option, burgerCount, fryCount, sodaCount)
This means you are calling the declareVariables() function with the given argument values.
But at that point in main(), none of those variables exist. So, you got the error.

Related

why does this python while loop not work in the program?

I'm trying to run the program in the following article:
https://blockgeeks.com/guides/python-blockchain-2/
I've copied all of the code into my Spyder IDE. When i run it there's a while loop which starts up asking the user to choose a number from the list of options it prints.
After selecting a number the program should perform the requested action. When i select it though it just loops back to the start of the while loop.
It appears to be ignoring the rest of the code in the while loop (the if statement part).
Confusingly if i take the parts of the code from the program which are used in the while loop and run them separately they work i.e if i run the below code and select the number 1 for my choice it will run the code in the if statement.
Why would the if statement run here but not in the main program?
#function 1:
def get_user_choice():
user_input = input("enter a number: ")
return user_input
#function 2:
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == '1':
tx_data = get_transaction_value()
print(tx_data)
Update:
Sorry i realise i may not have been very clear what the problem is.
The above code is part of the code from the entire program and runs as expected in isolation from the main program.
The below code is the entire program from the article in the link. It includes all of the code in the program. If i run this main program the while loop doesn't use the if statement. It appears to just be breaking straight out of the loop after i select 1, 2 or 3 (any other number should break out of the loop anyway).
Here's a link for a screen shot showing what the console looks like after i have selected the number 1 for the option.
https://ibb.co/RNy2r0m
# Section 1
import hashlib
import json
reward = 10.0
genesis_block = {
'previous_hash': '',
'index': 0,
'transaction': [],
'nonce': 23
}
blockchain = [genesis_block]
open_transactions = []
owner = 'Blockgeeks'
def hash_block(block):
return hashlib.sha256(json.dumps(block).encode()).hexdigest()
# Section 2
def valid_proof(transactions, last_hash, nonce):
guess = (str(transactions) + str(last_hash) + str(nonce)).encode()
guess_hash = hashlib.sha256(guess).hexdigest()
print(guess_hash)
return guess_hash[0:2] == '00'
def pow():
last_block = blockchain[-1]
last_hash = hash_block(last_block)
nonce = 0
while not valid_proof(open_transactions, last_hash, nonce):
nonce += 1
return nonce
# Section 3
def get_last_value():
""" extracting the last element of the blockchain list """
return(blockchain[-1])
def add_value(recipient, sender=owner, amount=1.0):
transaction = {'sender': sender,
'recipient': recipient,
'amount': amount}
open_transactions.append(transaction)
# Section 4
def mine_block():
last_block = blockchain[-1]
hashed_block = hash_block(last_block)
nonce = pow()
reward_transaction = {
'sender': 'MINING',
'recipient': owner,
'amount': reward
}
open_transactions.append(reward_transaction)
block = {
'previous_hash': hashed_block,
'index': len(blockchain),
'transaction': open_transactions,
'nonce': nonce
}
blockchain.append(block)
# Section 5
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
def get_user_choice():
user_input = input("Please give your choice here: ")
return user_input
# Section 6
def print_block():
for block in blockchain:
print("Here is your block")
print(block)
# Section 7
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == 1:
tx_data = get_transaction_value()
recipient, amount = tx_data
add_value(recipient, amount=amount)
print(open_transactions)
elif user_choice == 2:
mine_block()
elif user_choice == 3:
print_block()
else:
break
[1]: https://i.stack.imgur.com/FIrn7.png
When comparing values, Python takes a stronger route regarding data types than some other languages. That means no string in Python will equal a number.
Or in other terms "1" == 1 will be False.
That means you have to consider that in Python 3 you will receive a string from input() (not necessarily so in Python 2).
You can either compare this directly to another string:
user_choice = input()
if user_choice == "1":
print("You chose item 1")
Or you can convert it into a number first and compare it to a number:
user_choice = int(input())
if user_choice == 1:
print("You chose item 1")
Note that in the former case it might not be robust if the user enters extra spaces and in the latter case it will fail very loudly with an exception if the user doesn't enter an integer (or even nothing at all).
Both ways can be handled with extra code if necessary. In the former case, you can strip whitespace with user_input = input().strip() and in the latter case you can catch the exception with a try ... except ... block.
You have only handled the case for user_choice == '1'. If you enter anything other than 1, the program will return control to the beginning of the while loop.
I'll suggest you use a debugger to see what user_choice is before the if condition. If not, just use prints.
print("user_choice: {}, type: {}".format(user_choice, type(user_choice))

Python code error in program should calculate the monthly average price for Google and tell us the best and worst six-month period for Google

I need help to figure out how to fix errors in my Python code Assignment.
Basically I need create a program that should calculate the monthly average price for Google and tell us the best and worst six-month period for Google.
The average price is defined as ((v1*c1)+(v2*c2)+(v3*c3)+(v4*c4)...+(vn*cn)) / (v1+v2+v3+v4...+vn) where vi is the volume for day i and ci is the adjusted close price for day i.
For this assignment we'll look at Google from 2004 to 2012. The data-set we'll need is a table in CSV format and can be downloaded from https://www.dropbox.com/s/qr7cu2kui654kgz/googlePrices.csv.
So far I've created the Python code below but it's show some errors message and I couldn't figure out.
Thank you in advance.
Regards,
Roberto Leal
============================================================
Code:
__author__ = 'Roberto'
def get_values():
import operator
data_file = open("googlePrices.csv")
def get_data_list(file_name):
data_list = [] # always start with an open list
for line_str in data_file:
data_list.append(line_str.strip().split(',')) # removes all commas from the csv file
return data_list
def monthlyAverage(list_of_tuples=[]):
averageList = []
currentYear_int = 2012
month_int = 11
sum_float = float()
count = 0
for a_tuple in list_of_tuples:
dateStr = a_tuple[0]
Floatdata = a_tuple[1]
listdate = dateStr.split(',')
Year_int = int(listdate[0])
month_int = int(listdate[1])
date_year_str = "Date: " + str(month_int) + "-" + str(currentYear_int)
if month_int != currentYear_int:
float_average = sum_float / count
list_average = [date_year_str , float_average]
average_tuple = tuple(list_average)
averageList.append(average_tuple)
current_month_int = month_int
sum_float = 0.0
count = 0
sum_float += Floatdata
count += 1
return averageList
def best_6_month(averageList):
averageList.sort()
print("The 6 best months fo google are: ")
print()
print(averageList)
def worst_6_month(averageList):
averageList.reverse()
print("The 6 worst months for google are: ")
print()
print(averageList)
optionStr = ""
if optionStr != "0":
print("------------------------------")
print("\n Google Stock Prices. 2004 - 2012")
print("------------------------------")
print("Please choose an option")
print()
print("1. Calculate Average")
print("2. View best six months")
print("3. View worst six months")
print("0. Exit program")
print()
optionStr = input("Enter you choice now: ")
if (len(optionStr) != 1) or (optionStr not in "0123"):
print("You have entered an invalid number!")
print("Please try again")
elif optionStr == "1":
monthlyAverage()
elif optionStr == "2":
best_6_month()
elif optionStr == "3":
worst_6_month()
elif optionStr == "0":
print("\n Exiting program... Goodbye.")
else:
print("\n Bad option")
===============================================================
Error:
Traceback (most recent call last):
File "C:/Users/Kate/Desktop/College DIT/projecttest1/Project_3.py", line 97, in <module>
best_6_month()
TypeError: best_6_month() missing 1 required positional argument: 'averageList'
Process finished with exit code 1
Traceback (most recent call last):
File "C:/Users/Kate/Desktop/College DIT/projecttest1/Project_3.py", line 94, in <module>
monthlyAverage()
File "C:/Users/Kate/Desktop/College DIT/projecttest1/Project_3.py", line 48, in monthlyAverage
list_average = [date_year_str , float_average]`enter code here`
UnboundLocalError: local variable 'date_year_str' referenced before assignment
Process finished with exit code 1

Python: Using defs in a program about ordering stuff

This program is about ordering stuff from a "mail order" house thing.
They sell five products. P1 = 2.98, P2 = 4.5, P3 = 9.98, P4 = 4.49, P5 = 6.87
So this is my code so far.
#Imports: None
#Defs:
def userInput1():
x = int(input("Product Number?"))
return x
def userInput2():
q = int(input("Quantity?"))
return q
def calculations(x,q):
p1 = 2.98
p2 = 4.5
p3 = 9.98
p4 = 4.49
p5 = 6.87
subtotal = q * x
return subtotal
def final(subtotal):
print ("Total:", subtotal)
def loop():
cont = input("Do you want to continue? (yes/no)")
if cont == 'yes':
main()
return
else:
final()
def main():
x = userInput1()
subtotal = calculations(x,q)
final(subtotal)
#Driver:
main()
I have to use a sentinel controlled loop.
Here's my traceback.
Traceback (most recent call last):
File "C:\Documents and Settings\user1\My Documents\Downloads\az_mailorder3.py", line 49, in <module>
main()
File "C:\Documents and Settings\user1\My Documents\Downloads\az_mailorder3.py", line 46, in main
subtotal = calculations(x,q)
NameError: name 'q' is not defined
Here's how it should work.
Product number?: 1
Quantity?: 2
Continue?(yes/no): yes
Product number?: 2
Quantity?: 5
Continue?(yes/no): yes
Product number?: 3
Quantity?: 3
Continue?(yes/no): yes
Product number?: 4
Quantity?: 1
Continue?(yes/no): no
Total: $62.89
There's probably deeper problems.
Assuming you are a newbie to programming (I can feel that from your code) and also this problem seems a school homework which is quite easy and also you don't want to try hard debugging it (You need to debug a lot to be a good programmer)
Here I am presenting your code to you with proper comments why your code is going wrong.
Start reading from the main function (not from the first line)
def userInput1():
x = int(input("Product Number?"))
return x
def userInput2():
q = int(input("Quantity?"))
return q
def calculations(x,q):
p1 = 2.98
p2 = 4.5
p3 = 9.98
p4 = 4.49
p5 = 6.87
subtotal = q * x
#here you are multiplying the item number by quantity
#not the price by quantity (use proper if else to check price for item number
# return to main function again for more comments
return subtotal
def final(subtotal):
print ("Total:", subtotal)
#nothing wrong here but since we have declared subtotal as global (remember that?)
#so no need to pass subtotal by argument.
def loop():
cont = input("Do you want to continue? (yes/no)")
if cont == 'yes':
main()
return
else:
final()
#you are calling final() but you declared with argument (are you mad?)
#now check final function
def main():
x = userInput1()
#Where you are taking input from user for quantity??
#first take quantity as input q = userInput2()
subtotal = calculations(x,q)
#now every time you call main function your subtotal will be revised
#remember teacher talking about global and local variables?
#subtotal needs to be global (declare it somewhere outside the functions
#now even if subtotal is global you need to increment it (not reassign)
# use subtotal += calculations(x,q)
#now check your calculations function
final(subtotal)
#you are calling final subtotal but where the hell you calling your loop?
#call it before calling final and now check your loop function
main()
hopefully by now you are able to write correct code
but even if you are not able to write correct code by now here is something for your help. But try to write code by yourself first. Happy Debugging :)

making a piggy bank program in python

I'm a beginner to Python and programming, and I'm trying to make a simple piggy bank that will be able to deposit or withdraw pennies, nickels, dimes, and quarters. I don't know how to loop the code or how to store the data if I enter a coin to be able to keep adding to the total number of coins in the bank. I can only do it so it runs and tells me if I add, for example, 100 pennies, that my bank has 100 pennies. but then it resets. How do I do this? my code is probably awful but here's what I have so far based off my current knowledge of python (added empty parts like the "return" and pennies_previous so anyone reading can understand my thought process, and the withdrawstep() function has not been added yet):
print "Welcome to the Piggy Bank!"
def depositstep():
deposit = raw_input("What would you like to deposit? (P for pennies, N for nickels, D for dimes, Q for quarters): ").upper()
if deposit == 'P':
pennies_previous =
pennies_instance = raw_input("How many pennies would you like to deposit?: ")
pennies_total = int(pennies_instance) + pennies_previous
print "There are %s pennies in your bank"% (pennies_total)
return execute()
elif deposit == 'N':
N = raw_input("How many nickels would you like to deposit?: ")
return
elif deposit == 'D':
D = raw_input("How many dimes would you like to deposit?: ")
return
elif deposit == 'Q':
Q = raw_input("How many quarters would you like to deposit?: ")
return
else:
return "Sorry. Please Type P for pennies, N for nickels, D for dimes, or Q for quarters."
def execute():
exc = raw_input("Would you like to deposit or withdraw money? (D for deposit, W for withdraw): ").upper()
if exc == 'D' or exc == 'DEPOSIT':
return depositstep()
elif exc == 'W' or exc == 'WITHDRAW':
return withdrawstep()
else:
return "Sorry. Please type D for deposit or W for withdrawal."
print execute()
You should store your total amount of pennies in the original variable.
pennies_previous= int(pennies_instance) + pennies_previous then the amount of pennies will be stored there.
If you are looking to make the bank continue to store the value of the bank for each session, then you are going to want to save the bank's value to a file. You could do it like this:
1. First, make a file with a name like bankvalue.txt.
2. Then, add these lines before every return:
value = open(bankvalue.txt, 'w') # that opens your bankvalue.txt file in write mode
value.write('\n'pennies_previous) #You should use the answer above for the pennies_previous
value.close() #saves the file
3.Then, in order to tell a person their balance you would use the readline() function
I hope that was what you were looking for
I would use a python dictionary instead of variables:
do so as:
bank = {'pennies':0, 'nickles':1, 'dimes':0, 'quarter':0}
to increase either of those you do
bank['pennies'] += int(pennies_instance) # not need the pennies_previous
Then you need to write that to a file which you could do:
f = open('filename','w')
f.write(bank.items())
f.close
But that don't preserve the python structure. But you can use json module, which is simple as:
import json
f = open('filename','wb')
json.dump(bank,f)
f.close()
And at the start of the script you need to fetch the data from the file, you do this with
f = open('bank.dat','rb')
bank = json.load(f)
It would look like this:
import json
f = open('bank.dat','rb')
bank = json.load(f)
f.close()
## you code goes here.
f = open('bank.dat','wb')
json.dump(bank,f)
f.close()
There are some other problems in your code that should be addressed too.
1) In the 'else' part of your code, if the user inputs the wrong letter it terminates, instead it should call the function again.
2) You don't need to return a string and print it in the 'print execute()', you could just print it in place and don't return anything.

python adding a negative sign to calculation result

First, I will warn you, I am new at this so please bear with me. I created the following program (for a class, of course) and everything works except that the withdrawal calculation spits out a negative number when the value shouldn't be negative. Can you guys see what I'm doing wrong?
Thanks in advance
#define the main
def main():
name=input('Enter the customer\'s name: ')
account_id=input('Enter the account ID: ')
code=input('Enter the transaction code:')
previous_balance=float(input('Enter the previous balance: '))
transaction_amount=float(input('Enter the transaction amount: '))
if code == "w" or code == "W":
process_withdrawal (transaction_amount, previous_balance)
else:
if code == "d" or code == "D":
process_deposit (transaction_amount, previous_balance)
else:
process_invalid_transaction_code (previous_balance)
#define process withdrawal
def process_withdrawal (previous_balance, transaction_amount):
if previous_balance >= transaction_amount:
print('You have entered an invalid transaction amount')
balance=previous_balance
print_balance (balance)
else:
balance=previous_balance-transaction_amount
print_balance (balance)
#define process deposit
def process_deposit (previous_balance, transaction_amount):
balance=previous_balance+transaction_amount
print_balance (balance)
#define invalid transaction code
def process_invalid_transaction_code (previous_balance):
print('You have entered an invalid transaction code.')
balance=previous_balance
print_balance (balance)
#define print balance
def print_balance(balance):
print('Your current balance is :', format(balance, '.2f'))
main()
Your call to process_withdrawal has the first argument as transaction_amount and the second as previous_balance, but the function declaration has previous_balance as the first argument and transaction_amount as the second.
Try this:
if code == "w" or code == "W":
process_withdrawal(previous_balance, transaction_amount)
You are passing the arguments backwards.
process_withdrawal (transaction_amount, previous_balance)
and
def process_withdrawal (previous_balance, transaction_amount):
I think your if statement within process withdrawl should be
if previous_balance < transaction_amount:

Categories