Global name is not defined? - python-3.x

G'day fellows. I face a problem regarding a global variable which python claims is not defiend even though it is. In essence, I just want to check if an integer contains a decimal place, or the input contains nothing integer related whatsoever. Here is my code:
def Strength1():
try:
global strength1
strength1 = int(input("%s, please enter your desired strength - between 1 and 20\n>"%name1))
strength1int = int(strength1)
def invLoop():
clearScreen()
Invalid()
Strength1()
if int(strength1) <= 0:
invLoop()
if int(strength1) >= 21:
invLoop()
except Exception as exception:
clearScreen()
print("'%s isn't an integer."%strength1)
Strength1()
def Skill1():
try:
global skill1
skill1 = int(input("%s, please enter your desired skill - between 1 and 20\n>"%name1))
skill1int = int(skill1)
def invLoop():
clearScreen()
Invalid()
Skill1()
if int(skill1) <= 0:
invLoop()
if int(skill1) >= 21:
invLoop()
except Exception as exception:
clearScreen()
print("'%s isn't an integer."%skill1)
Skill1()
def Strength2():
try:
global strength2
strength2 = int(input("%s, please enter your desired strength - between 1 and 20\n>"%name2))
def invLoop():
clearScreen()
Invalid()
Strength2()
if int(strength2) <= 0:
invLoop()
if int(strength2) >= 21:
invLoop()
except Exception as exception:
clearScreen()
print("'%s' isn't an integer."%strength2)
Strength2()
def Skill2():
try:
global skill2
skill2 = int(input("%s, please enter your desired skill - between 1 and 20\n>"%name2))
def invLoop():
clearScreen()
Invalid()
Skill2()
if int(skill2) <= 0:
invLoop()
if int(skill2) >= 21:
invLoop()
except Exception as exception:
clearScreen()
print("'%s' isn't an integer."%skill2)
Skill2()
and this is my error:
Traceback (most recent call last):
File "H:\Toby Reichelt\A453\Two Encounters - Developing Dice.py", line 29, in Skill1
skill1 = int(input("%s, please enter your desired skill - between 1 and 20\n>"%name1))
ValueError: invalid literal for int() with base 10: '0.5'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "H:\Toby Reichelt\A453\Two Encounters - Developing Dice.py", line 197, in <module>
mainloop()
File "H:\Toby Reichelt\A453\Two Encounters - Developing Dice.py", line 188, in mainloop
Skill1()
File "H:\Toby Reichelt\A453\Two Encounters - Developing Dice.py", line 41, in Skill1
print("'%s isn't an integer."%skill1)
NameError: global name 'skill1' is not defined

skill1 is not defined because if int(input()) fails and raises an exception, then nothing at all will be assigned to skill1.
First assign the string to a variable, and try to convert afterwards.
try:
global skill1
skill1 = input("%s, please enter your desired skill - between 1 and 20\n>"%name1)
#if the below line crashes, `skill1` will still have the old string value
skill1 = int(skill1)

If your int(input('...')) call fails, an Exception is raised before anything is assigned to skill1. Then you try to print the value of skill1 in your error handling, except that that name hasn't been defined yet.
Either remove skill1 (and strength1, and skill2, and strength2) from the exception handling, or else assign them some default value (None is customary, or sometimes -1) outside of the try block to be certain that they're defined, even if the user inputs a bad value.
This has nothing to do with global variables; in fact it's not clear that declaring skill1 and strength1 as global is being done for any reason at all in your code. Just to be clear, you should check the docs on the global keyword: it does not define a name; all it does is indicate to the parser that any assignments to that name in the local scope should be applied to that name in the module-level scope.

You seem to be expecting that if the user's input isn't a valid integer, skill1 will be defined to... something. Perhaps the raw text of the user's input? In any case, that's not what happens.
If int(input(...)) throws an exception, control goes to the except block without assigning skill1. If you want to have something to print even when the input is invalid, you need to save the result of input separately from converting it to an integer.

global keyword doesn't mean "define variable in global scope", but "when searching for variable to modify, look into global scope, not local scope".
Your code won't run anyway, you have no call to defined functions.
Define variables skill1, skill2, strength1, strength2 in module, not in function, it will solve the problem you've encountered.
PS. global variables are ugly. Don't do this.

The Global Variable Wont Work
it Wont Work Cuz if U'r "try : except :" Fails There Wont Be any Skill1
Why Dont u Define u'r Variables Outside of The Function ? Unless u Got Other ones with The Same Name .
And I dont Recommend Using a Global Variable

Related

how to throw an error if certain condition evaluates to true

I have below code block:
try:
if str(symbol.args[0]) != str(expr.args[0]):
print('true')
raise SyntaxError('====error')
except:
pass
Here I am trying to raise Syntax error if certain condition is true.I am testing this code block, I can see 'true' is getting printed which means condition is met but even after that also the code is not throwing syntax error.
I am trying to understand what is wrong in the above code.
You're putting pass in the except: block which is swallowing the exception. Either remove the code from the try-except block or change pass to raise
Above answer is pointing the issue, I just want to give some examples to help you better understand how try/except works:
# Just raise an exception (no try/except is needed)
if 1 != 2:
raise ValueError("Values do not match")
# Catch an exception and handle it
a = "1"
b = 2
try:
a += b
except TypeError:
print("Cannot add an int to a str")
# Catch an exception, do something about it and re-raise it
a = "1"
b = 2
try:
a += b
except TypeError:
print("Got to add an int to a str. I'm re-raising the exception")
raise
try/except can also be followed by else and finally, you can check more about these here: try-except-else-finally

Why ValueError: invalid literal for int() with base 10: ''

I've found it difficult to understand this problem:
Traceback (most recent call last):
opc = int(self.qtjog_entry.get())
ValueError: invalid literal for int() with base 10: ''
I'm confused because in another program without self., this is possible. Look at this:
qjogos = (int(qtjog_entry.get())) # here, python casts str to int normally.
Can someone help me? Sorry, for my English, and I'm learning programming languages now. Thanks.
I hope this simple example helps you udnerstand on your errors more.
If I say qjogos = (int(qtjog_entry.get())) at the main block, like:
from tkinter import *
root = Tk()
def click():
pass
qtjog_entry = Entry(root)
qtjog_entry.pack()
qjogos = (int(qtjog_entry.get()))
b = Button(root,text='Click me',command=click)
b.pack()
root.mainloop()
I get youre same error,
Traceback (most recent call last):
File "c:/PyProjects/Patient Data Entry/test2.py", line 11, in <module>
qjogos = (int(qtjog_entry.get()))
ValueError: invalid literal for int() with base 10: ''
But now if i say it inside of a function, like:
from tkinter import *
root = Tk()
def click():
qjogos = (int(qtjog_entry.get()))
print(qjogos)
qtjog_entry = Entry(root)
qtjog_entry.pack()
b = Button(root,text='Click me',command=click)
b.pack()
root.mainloop()
I dont get any error and the number is printed in the terminal.
What happens in the first code is that, initially when the program runs, the value of whats inside the entry box is '' (empty sting) which is not an int and hence cannot be converted to an integer using int(). So you have to enter the value then click on a button which calls the function and then gets the value which is inside the entrybox at the time you clicked the button.
I hope this is what you meant in your Q and that it clears your doubt, let me know if any more doubts. Explained it more cause you mentioned you're new to programming, cheers :D
It looks like self.qtjog_entry.get() returns an empty string; you can't use int() on an empty string. Without having more context, it's hard to tell exactly what's wrong here.

Why do the code shows tons of error whenever i type in alphabet input

I am new to python and I have an upcoming assignment that creates a menu that creates a function whenever the users enter the input. Here is the problem, whenever I enter a number the code shows a normal invalid option. For alphabetic input, however, it started to appear tons of errors. Does anyone know how to solve this issue
import turtle
wn = turtle.Screen()
poly = turtle.Turtle()
wn.setup(1000, 600)
poly.pensize(2)
poly.fillcolor('lightblue')
poly.penup()
poly.goto(-400, 15)
poly.pendown()
def menu():
print(' *********************************')
print('1. Draw polygons')
print('2. Draw a flower')
print('3. Exit')
task = int(input('Enter an option (1/2/3): '))
return task
def draw_shape(t, sides):
for i in range(0, sides):
t.forward(50)
t.stamp()
t.left(360 / sides)
t.forward(50)
def draw_flower(t, sides):
for i in range(0, sides):
t.left(90)
t.forward(100)
t.left(137.5)
t.forward(60)
t.left(80)
t.forward(70)
das = menu()
if das == 1:
for angle in [10, 9, 8, 7, 6, 5, 4, 3]:
poly.penup()
poly.forward(100)
poly.pendown()
poly.begin_fill()
draw_shape(poly, angle)
poly.end_fill()
elif das == 2:
poly.pencolor('cyan')
wn.bgcolor('light yellow')
poly.speed(4)
poly.penup()
poly.goto(0, 0)
poly.pendown()
draw_flower(poly, 52)
poly.forward(-100)
elif das == 3:
print('Program exists. Have a nice day')
exit()
else:
print('Invalid option')
. Draw polygons
2. Draw a flower
3. Exit
Enter an option (1/2/3): sa
Traceback (most recent call last):
File "C:/Users/jonny/PycharmProjects/untitled2/Polygon and flowers.py", line 40, in <module>
das = menu()
File "C:/Users/jonny/PycharmProjects/untitled2/Polygon and flowers.py", line 18, in menu
task = int(input('Enter an option (1/2/3): '))
ValueError: invalid literal for int() with base 10: 'sa'
Your Python interpreter is basically telling you that it cannot parse 'sa' into an int, which is to be expected right?
When prompted to enter an option, if you enter sa, input(...) returns exactly that: sa, as a string.
At that point in your script, task = int(input(...)) essentially becomes task = int('sa').
Exceptions
Now put yourself in the shoes of function int(): you receive a string, and you must return an integer.
What do you do when the input string, 'sa' for that matter, does not correctly represent an integer?
You cannot return an integer, because that would imply that you parsed the string successfully.
Returning something else than an integer would make no sense (and would be a pain to work with).
So you throw an exception: the execution flow is interrupted, and a specific kind of object, an exception, is thrown.
Exception handling
When a function throws an exception, it is interrupted: it does not finish running, it does not return anything, and the thrown exception is forwarded to the calling function. If that function decides to catch that exception (i.e. to handle it), then good, the normal execution flow can resume at that point.
If it decides not to handle the exception, then that function is interrupted too and the exception is forwarded yet again to the calling function. It continues in a similar fashion until the exception is caught, or until "no calling function is left", at which point the Python interpreter takes over, halts the execution of your script, and displays info about that exception (which is what happened in your case).
A first solution
If you're new to Python, maybe you shouldn't worry too much about handling exceptions right now. More generally, if you try to handle every possible case when it comes to user input, you're in for a wild ride.
For the sake of completeness though:
In order for your code to do what you expect, replace the das = menu() line with this:
try: # Enter a section of code where exceptions may be thrown
das = menu() # menu() may throw an exception because of the int(...) inside
except: # 'Catch' any exception that was thrown using an `except` block
das = -1 # Set a dummy, invalid value
With this code, if menu() throws an exception (when you enter sa for example), it will be caught: the try block will be interrupted, and the except block will be executed. das will receive value -1, which by the rest of your code is invalid, and thus Invalid option will be displayed. This is much better than having your whole script halted!
On the other hand, if no exception is thrown by menu(), the try block will reach its end normally, and the except block will not be executed.
A better solution
However, this is not ideal. The exception should not be handled around menu(), it should be handled around int(...) inside your menu function.
You could do this as an exercise: first handle the exception inside menu, and then try to loop over the int(input(...)) statement until a valid value is entered by the user.
There again, exception handling is not necessarily trivial and can be hard to get right, especially for beginners. So don't get frustrated if it seems like a not-so-useful overcomplication to you, there will come a point where you realize you can't go without them.
You can read more about exceptions here: https://www.w3schools.com/python/python_try_except.asp or here if you want a more comprehensive tutorial: https://docs.python.org/3/tutorial/errors.html
Hope this helps. :)

Defining function difficulties ["NameError: name 'number' is not defined"]

Okay, trying to make a simple game of Guessing Numbers but I can't find the mistake in this code. Still pretty new to python so probably the reason why but I can't figure out what is wrong with it.
import random
from time import sleep
def start():
print("Welcome To The Guessing Game \n Try to guess the number I'm thinking of \n Good luck!")
selectRandomNumber()
guessCheck(number, numberInput=1)
def restart():
print("Creating new number ...")
sleep(1)
print("OK")
selectRandomNumber()
guessCheck(number,numberInput=1)
def selectRandomNumber():
number = random.randint(0,1000)
tries = 0
return
def tryAgain():
while True:
try:
again = int(input("Do you want to play again? y/n:"))
except ValueError:
print("Couldn't understand what you tried to say")
continue
if again == "y" or "yes":
print("Awesome! Lets go")
restart()
elif again == 'n' or "no":
print("Goodbye!")
break
else:
print("Not a valid option")
continue
def guessCheck(number,numberInput=1):
while True:
try:
numberInput = int(input("What number do you think it is?: "))
except ValueError:
print("Couldn't understand that. Try again")
continue
if numberInput > number:
print("Too high")
tries += 1
continue
elif numberInput < number:
print("Too low")
tries += 1
continue
elif numberInput == number:
print("Congrats! You got my number")
tryAgain()
number = selectRandomNumber()
print(number)
start()
Every time I try to run the program I keep getting the same mistake.
It tells me:
Traceback (most recent call last):
File "python", line 60, in <module>
start()
File "python", line 8, in start
guessCheck(number, numberInput)
NameError: name 'number' is not defined
Don't quite understand what that means.
Some help would be appreciated. Thanks!
* UPDATE *
Was able to fix the part about defining the variable but now new problem happened where when I try to run
Same code as before but added
guessCheck(number,numberInput=1)
and also added the variable number at the end
number = selectRandomNumber()
print(number)
start()
when I run it I get this
None # this is from `print(number)` so instead of getting a number here I'm getting `None`
Welcome To The Guessing Game
Try to guess the number I'm thinking of
Good luck!
What number do you think it is?:
The Traceback is telling you this:
We got to start().
start() called guessCheck().
We tried to pass two pieces of information to guessCheck(): the variable names number and numberInput.
We don't have those variables defined yet! numberInput doesn't get defined until once we've already started guessCheck(), and number isn't actually defined anywhere.
As Manoj pointed out in the comments, you probably want number to hold the output of selectRandomNumber(). So, instead of just calling selectRandomNumber() in start(), try number = selectRandomNumber() instead.
You can add a print(number) on the line right after that to make sure number has a value assigned to it.
Now number has a value, going into your call to guessCheck(). That still leaves numberInput undefined though. You can set a default value for function arguments like this:
guessCheck(number, numberInput=1)
That way, when guessCheck is called but numberInput hasn't been defined yet, it will automatically give it the value 1 until you set it explicitly.
You may encounter other issues with your code the way it is. My advice would be to start really simply - build up your game from each individual piece, and only put the pieces together when you're sure you have each one working. That may seem slower, but trying to go too fast will cause misunderstandings like this one.

NameError and ValueError in Python

Why is python shell throwing a NameError where as windows console a ValueError?
def PrintArgs(*arg):
list = ['1','2']
for i in arg:
try:
print(list[int(i)])
except ValueError:
print('Please enter integer value')
except NameError:
print('Name Error')
if __name__ == '__main__':
PrintArgs(*sys.argv[1:])
Providing the following arguments to Windows Console gives this output:
Here is how I call the code in windows console:
C:\>C:\Python34\python C:\Users\User\Documents\PYTest\Test.py 0 a
1
Please enter integer value
Providing the following arguments to Python Shell does not display the cusom error for NameError as mentioned in the code above, but mentions the following error:
PrintArgs(0,a)
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
PrintArgs(0,a)
NameError: name 'a' is not defined
In the code example you've provided you define a list i, then you iterate over a collection called list you never initiated, and assign the values in this list to i, thus dropping the original value. I guess you only provided a part of your code, please provide a minimum working example.
If I try to reproduce your problem, I only get a type error, for iterating over a list which is not initialized.

Resources