While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:
Related
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))
When I enter data in to my function directly I get the right output but when I use input from the user to fill the list nothing happens. I don't get any errors or output what so ever.
The data from input should enter the list and the index from input should be deleted from the list.
#!/usr/bin/env python3
#class definitions
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
def __str__(self):
return f"Last name: {self.lastname}, First Name: {self.firstname}, Telephone: {self.telephone}"
class PhoneBook:
def __init__(self):
self.phonebook = []
def addrecord(self, record):
self.phonebook.append(record)
return self.phonebook.index(record)
def deleterecord(self, i):
self.phonebook.pop(i-1)
def printphonebook(self):
x = 1
for entry in self.phonebook:
print(x,'. ',entry,sep='')
x = x + 1
#Main
select = None
while select != 'exit':
ph = PhoneBook()
ph.addrecord(record(515,'fin','matt'))
ph.addrecord(record(657,'fisher','bill'))
select = input('Main Menu \n1. show phonebook \n2. add record \n3. remove record\nor "exit" to exit program\n')
test = False
while test == False:
if select == '1':
ph.printphonebook()
test = True
elif select == '2':
x = int(input('Enter telephone number.\n'))
y = str(input('Enter last name.\n'))
z = str(input('Enter first name.\n'))
ph.addrecord(record(x,y,z))
test = True
elif select == '3':
i = int(input('Enter the record number youd like to delete.\n'))
ph.deleterecord(i)
test = True
elif select == 'exit':
break
else:
print('Invalid selection. Please try again.')
test = True
The desired output would be getting the data to correctly enter and exit the list based on my x, y and z inputs and take out the specified index of the list based on the i input.
You clear and create a new Phonebook() object every time your first while loop runs.
I'm new and not skilled enough to fix every problem in a short amount of time.
You don't see your new entries, because they get wiped out every time.
Try using one while loop and a switch statement.
I'm working on a school project and I have a problem. I have to write code for apothecary where clients can buy medicine. So, I need to make restrictions, which one doesn't go with others and etc. Here is the code:
def prodajLek():
lekovi = Fajl1.UcitavanjeLekova()
lekoviRed = []
brojacZaForPetlju = 1
n = 0
cena = 0
kolicina = []
korpa = []
rednibrojevilekova = []
ukupnacena = 0
print(" Fabricki naziv Genericki naziv Serijski broj Kolicina Cena \n")
for i in lekovi:
x = i.strip().split("|")
lekoviRed.append(x)
if lekoviRed[n][5] == "False":
print(brojacZaForPetlju,"\t {:10} \t {:10} \t\t\t {:3} \t\t\t {:4} \t\t {:5}".format(x[0],x[1],x[2],x[3],x[4]))
brojacZaForPetlju = brojacZaForPetlju + 1
n = n + 1
print("\n\n\n\n")
rednibrleka = input("Izaberite redni broj leka koji zelite da prodate:\n>>\t")
rednibrleka = int(rednibrleka)
rednibrleka = rednibrleka - 1
rednibrojevilekova.append(rednibrleka)
kolicinaZahteva = input("Koju kolicinu zelite da prodate?\n>>\t")
kolicinaZahteva = int(kolicinaZahteva)
if kolicinaZahteva > int(lekoviRed[rednibrleka][3]):
print("Nema toliko na lageru!\n")
Fajl1.LekarMenu()
kolicina.append(kolicinaZahteva)
cena = int(lekoviRed[rednibrleka][4])
korpa.append(cena)
print("Da li zelite da kupite jos lekova?\n1.Da\n2.Ne\n")
nastavakKupovine = input(">>")
if nastavakKupovine == "1":
prodajLek()
elif nastavakKupovine == "2":
Fajl1.LekarMenu()
So, when I get to the nastavakKupovine input, when I press 1, I need to continue shopping and store my row numbers, my price and quantity in arrays rednibrojlekova = [] , korpa = [] and kolicina = []. But I have a problem, because I dont know how to continue this without reseting these arrays to empty.
The standard idiom for what you want to do is a while True loop. Rather than show how to change your (rather long) function, here's a very simple one which hopefully shows the principle in a straightforward way:
def ask():
answers = []
while True:
response = input("What do you have to say? ")
answers.append(response)
check = input("Type 'q' to quit, anything else to repeat: ")
if check == "q":
break
else:
continue
return answers
For this simple function, the else: continue part isn't necessary, because the loop will continue anyway, but I've included it so you can see how to use it.
Here's an example of the function in action:
>>> ask()
What do you have to say? Something
Type 'q' to quit, anything else to repeat:
What do you have to say? Another thing
Type 'q' to quit, anything else to repeat:
What do you have to say? Ok, done
Type 'q' to quit, anything else to repeat: q
['Something', 'Another thing', 'Ok, done']
>>>
You can find out more about while, break and continue by reading the More Control Flow Tools chapter of the official Python tutorial.
My task is to create a quiz for primary school children. The quiz bit works fine. But I must time how long the child takes and store their 'username' 'correctAnswers' and 'timeTaken' into a .txt file for the specific class the child is in. To do that I ask the child their class number and store their information into the file that was specifically made for that class.
The problems I in counter are:
The time isnt being rounded even though I have timeTaken = round(etime)in my code
raw_input not being defined (I have no idea how else to define it)
The message "Sorry, we can not save your data as the class you entered is not valid." comes up even when a valid class number has been entered.
Ive searched everywhere but with no luck. Any help at all would be greatly appreciated.
import time
import random
import math
def test():
num1=random.randint(1, 10)
num2=random.randint(1, num1)
ops = ['+','-','*']
operation = random.choice(ops)
num3=int(eval(str(num1) + operation + str(num2)))
print ("What is {} {} {}?".format(num1, operation, num2))
userAnswer= int(input("Your answer:"))
if userAnswer != num3:
print ("Incorrect. The right answer is {}".format(num3))
return False
else:
print("correct")
return True
username=input("What is your name?")
print ("Welcome {} to the Arithmetic quiz".format(username))
usersClass = input("Which class are you in? (1,2 or 3)")
raw_input("Press Enter to Start...")
start = time.time()
correctAnswers=0
for question_number in range(10):
if test():
correctAnswers +=1
print("{}: You got {} answers correct".format(username, correctAnswers))
end = time.time()
etime = end - start
timeTaken = round(etime)
print ("You completed the quiz in {} seconds".format(timeTaken))
if usersClass == 1:
with open("class1.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
elif usersClass == 2:
with open("class2.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
elif usersClass == 3:
with open("class3.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
else:
print("Sorry, we can not save your data as the class you entered is not valid.")
The return value of input is a str object:
>>> usersClass = input("Which class are you in? (1,2 or 3)")
Which class are you in? (1,2 or 3)3
>>> type(usersClass)
<class 'str'>
As a result, your subsequent checks against int objects will evaluate to False (ie, '3' != 3) resulting in what you are seeing.
The conditions of comparing which usersClass the user has selected would need to compare the same type to ensure equality. This means you could convert your return value of input to an int and continue to compare usersClass to an int which would satisfy your comparison as your code is written now,
usersClass = int(input("Which class are you in? (1,2 or 3)"))
or change the conditionals to compare usersClass to the str representation of 1, 2 and 3.
if usersClass == '1':
with open("class1.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
...
As to the problem you are experiencing with raw_input using Python 3, it has been renamed to input: (taken from What's New in Python 3.0)
PEP 3111: raw_input() was renamed to input(). That is, the new input()
function reads a line from sys.stdin and returns it with the trailing
newline stripped. It raises EOFError if the input is terminated
prematurely. To get the old behavior of input(), use eval(input()).
I keep getting the error message "global name 'user_input' not defined. new to python and to SO, hope you can help. Here's my code. Sorry if it's a mess. just starting out and teaching myself...
def menu():
'''list of options of unit types to have converted for the user
ex:
>>> _1)Length
_2)Tempurature
_3)Volume
'''
print('_1)Length\n' '_2)Temperature\n' '_3)Volume\n' '_4)Mass\n' '_5)Area\n'
'_6)Time\n' '_7)Speed\n' '_8)Digital Storage\n')
ask_user()
sub_menu(user_input)
def ask_user():
''' asks the user what units they would like converted
ex:
>>> what units do you need to convert? meter, feet
>>> 3.281
'''
user_input = input("Make a selection: ")
print ("you entered", user_input)
#conversion(user_input)
return user_input
def convert_meters_to_feet(num):
'''converts a user determined ammount of meters into feet
ex:
>>> convert_meters_to_feet(50)
>>> 164.042
'''
num_feet = num * 3.28084
print(num_feet)
def convert_fahrenheit_to_celsius(num):
'''converts a user determined temperature in fahrenheit to celsius
ex:
>>> convert_fahrenheit_to_celsius(60)
>>> 15.6
>>> convert_fahrenheit_to_celsius(32)
>>> 0
'''
degree_celsius = (num - 32) * (5/9)
print(round(degree_celsius, 2))
def sub_menu(num):
'''routes the user from the main menu to a sub menu based on
their first selection'''
if user_input == '1':
print('_1)Kilometers\n' '_2)Meters\n' '_3)Centimeters\n' '_4)Millimeters\n'
'_5)Mile\n' '_6)Yard\n' '_7)Foot\n' '_8)Inch\n' '_9)Nautical Mile\n')
ask = input('Make a selection (starting unit)')
return
if user_input == '2':
print('_1)Fahrenheit\n' '_2)Celsius\n' '_3)Kelvin\n')
ask = input('Make a selection (starting unit)')
return
When you do:
user_input = input("Make a selection: ")
Inside the ask_user() function, you can only access user_input inside that function. It is a local variable, contained only in that scope.
If you want to access it elsewhere, you can globalise it:
global user_input
user_input = input("Make a selection: ")
I think what you were trying was to return the output and then use it. You kind of got it, but instead of ask_user(), you have to put the returned data into a variable. So:
user_input = ask_user()
THere's no need to globalise the variable (as I showed above) if you use this method.
In your menu function, change the line that says ask_user() to user_input = ask_user().