python: global name 'user_input' is not defined - python

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().

Related

Score function for a flashcard game in python

I am trying to add a very simple score function to an also very simple flashcard game and I can't make the game remember the value of the variable containing the score (it always resets it 0). The score is obviously relying on the honesty of the user (and that's fine) that has to press "Y" when guessing the word.
from random import *
def add_score():
pos_score = 0
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
pos_score += 1
print(pos_score)
def show_flashcard():
""" Show the user a random key and ask them
to define it. Show the definition
when the user presses return.
"""
random_key = choice(list(glossary))
print('Define: ', random_key)
input('Press return to see the definition')
print(glossary[random_key])
def add_flashcard():
""" This function allows the user to add a new
word and related value to the glossary. It will
be activated when pressing the "a" button.
"""
key = input("Enter the new word: ")
value = input("Enter the definition: ")
glossary[key] = value
print("New entry added to glossary.")
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
add_score()
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')
Some notes:
I am aware that right now only the positive score is implemented in the code, but I figured it would be better to proceed step by step and have that working first.
Problem
In your def add_score(), you initialise the variable to 0 every time. Also, it is a local variable, which means you can only reference it from within your function add_score(). This means that every time you exit that function, that variable is completely deleted.
Solution
You need to make that a global variable, that is, initialise it to 0 at the start of the game, and outside your function. Then inside your add_score you simply reference to the global variable and increase it without initialising it every time:
from random import *
def add_score():
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
global pos_score
pos_score += 1
print(pos_score)
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
pos_score = 0 #NOTE you initialise it here as a global variable
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
add_score()
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')
Note I skipped the irrelevant functions. However, usually changing the scope of variables like this is considered bad practice. What you should do is either have a class -- a bit overly complicated for this example -- or return a value to add from your add_score and add that value in the main loop. This would be the code:
from random import *
def add_score():
score = input("Press Y if you got the correct word or N if you got it wrong!" )
if score == 'Y':
#global pos_score
#pos_score += 1
#print(pos_score)
return 1
return 0
def show_flashcard():
""" Show the user a random key and ask them
to define it. Show the definition
when the user presses return.
"""
random_key = choice(list(glossary))
print('Define: ', random_key)
input('Press return to see the definition')
print(glossary[random_key])
def add_flashcard():
""" This function allows the user to add a new
word and related value to the glossary. It will
be activated when pressing the "a" button.
"""
key = input("Enter the new word: ")
value = input("Enter the definition: ")
glossary[key] = value
print("New entry added to glossary.")
# Set up the glossary
glossary = {'word1':'definition1',
'word2':'definition2',
'word3':'definition3'}
# The interactive loop
pos_score = 0 #NOTE you initialise it here as a global variable
exit = False
while not exit:
user_input = input('Enter s to show a flashcard, a to add a new card. or q to quit: ')
if user_input == 'q':
exit = True
elif user_input == 's':
show_flashcard()
pos_score += add_score()
print(pos_score)
elif user_input == 'a':
add_flashcard()
else:
print('You need to enter either q, a or s.')

How to pull a variable from one function to another

def letterChoice():
playerLetter = input('Please choose X or O.').upper()
if playerLetter in ['X','O']:
print('The game will now begin.')
while playerLetter not in ['X','O']:
playerLetter = input('Choose X or O.').upper()
if playerLetter == 'X':
computerLetter = 'O'
else:
computerLetter = 'X'
turnChooser()
def turnChooser():
choice = input("Would you like to go first, second or decide by coin toss?(enter 1, 2 or c) ")
while choice not in ["1","2","c"]:
choice = input("Please enter 1, 2 or c. ")
if choice == 1:
print("G")
cur_turn = letterChoice.playerLetter()
elif choice == 2:
print("H")
else:
print("P")
moveTaker()
I can't figure out how I'm supposed to inherit playerLetter into turnChooser(), I've tried putting playerLetter into the brackets of each function but they don't pass and create an argument error and the print("G") and so on are simply there to see if the code works but whenever I enter 1 or 2 "P" is outputted.
You need to define function Attributes for playerLatter
For EX:
def foo():
foo.playerletter=input('Please choose X or O.').upper()
>>> foo()
Please choose X or O.x
>>> foo.playerLetter
'X'
Accessing from another function
def bar():
variable=foo.playerLetter
print(variable)
>>> bar()
X
>>>
You can always check what Attributes are available for a given function
>>> [i for i in dir(foo) if not i.startswith('_')]
['playerLetter']
>>>
Edit turnchooser() to turnchooser(var), then when calling the function pass the letter to the function like this:
def LetterChoice():
Code...
turnchooser(playerletter)
And,
def turnchooser(var):
Code...
The letter will be placed in a variable called var, which means your code will use the letter as var not playerletter.
Of Course you can change the names to whatever you like.
You could add as many variables to the function however they all should have something assigned to them, aka you can't call the previous function like so:
turnchooser()
Unless you assign it a default value:
def turnchooser(var = 'x')
This way whenever the function is called the value of "var" is x unless stated otherwise.
Note that if you want to pass it from one function to another, u either have to assign the letter to a variable then call the function outside the "LetterChoice" or call it in the definition of "LetterChoice"
Within the function that has the variable in it type:
global variableName
Obviously change variableName to whatever the variable is actually called. Hope this helps!
Tommy
You should try using classes: Python documentation
This should be the code:
class Game:
def __init__(self):
self.cur_turn = ''
self.choise = ''
self.playerLetter = ''
self.computerLetter = ''
def letterChoice(self):
while True:
self.playerLetter = input('Please choose X or O.').upper()
if self.playerLetter in ['X','O']:
print('The game will now begin.')
if playerLetter == 'X':
self.computerLetter = 'O'
else:
self.computerLetter = 'X'
break
else:
print ('Please enter only X or O')
def turnChooser(self):
while True:
self.choice = input("Would you like to go first, second or decide by coin toss? (enter 1, 2 or c) ")
if self.choice in ["1","2","c"]:
if self.choice == 1:
print("G")
self.cur_turn = self.playerLetter()
elif self.choice == 2:
print("H")
else:
print("P")
break
else:
print ('Please enter 1, 2 or c')
game = Game()
game.letterChoice()
game.turnChooser()
# If you want to read any of the variables in Game just write 'self.VARIABLE_NAME'

Error str' object is not callable

I don't understand how I am getting this error, can someone help:
import time
import os
import xlwt
from datetime import datetime
num = 0
def default():
global num
global model
global partnum
global serialnum
global countryorigin
time.sleep(1)
print ("Model: ")
model = input()
print ()
print ("Part number: ")
partnum = input()
print()
print ("Serial Number: ")
serialnum = input()
print ()
print ("Country of origin: ")
countryorigin = input()
print ("Thanks")
num = num+1
xlwt()
def xlwt():
print ("Do you want to write to excel?")
excel = input()
if excel == "y" or "yes":
excel()
else:
print ("Bye")
sys.exit()
def excel():
print ("Enter a spreadsheet name")
name = input()
wb = xlwt.Workbook()
ws = wb.add_sheet(name)
ws.write(0,0,"Model")
ws.write(0,1,"Part Number")
ws.write(0,2,"Serial Number")
ws.write(0,3,"Country Of Origin")
ws.write(num,0,model)
ws.write(num,1,partnum)
ws.write(num,2,serialnum)
ws.write(num,3,countryorigin)
ws.save(name)
def custom():
print()
def main():
print ("Welcome")
print ()
print ("The deafult catagories are: Model, Part Number, Serial Number,"
"country of origin")
time.sleep(1)
print()
dorc()
def dorc():
print ("Would you like to use the default or custom?")
dorc = input ()
if dorc == "default":
default()
elif dorc == "custom":
custom()
else:
print ("Invalid input")
dorc()
main()
When I execute this, I get an error str object is not callable.
You have both a function named excel() and a local variable named excel that you assigned a string to.
You can't do that and expect the function to still be available. The local name excel masks the global, so excel() tries to call the string result that input() returned.
Rename your variable:
print ("Do you want to write to excel?")
choice = input()
if choice in ("y", "yes"):
excel()
Note that I also corrected your variable test; excel == "y" or "yes" does not do what you think it does, programming language logic is not quite the same as English grammar rules. See Why does `a == b or c or d` always evaluate to True?
Next, you make the same mistake by using the name xlwt for both a module you import and a function:
import xlwt
# ...
def xlwt():
# ...
Both the module and the function are global names, and the name can only point to either the module you imported or the function you created, not both at the same time. Rename your function to something else, otherwise the following line will fail too:
wb = xlwt.Workbook()
because xlwt is bound to your function as that was defined later than the module import.

python: Maths quiz- data not being stored

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()).

Problems transferring information from one part of a function to another

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"]:

Categories