dave
dave

Reputation: 53

Global name is not defined?

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

Upvotes: 1

Views: 1449

Answers (5)

user3460574
user3460574

Reputation:

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

Upvotes: 0

Henry Keiter
Henry Keiter

Reputation: 17168

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.

Upvotes: 1

Filip Malczak
Filip Malczak

Reputation: 3194

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.

Upvotes: 0

user2357112
user2357112

Reputation: 280271

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.

Upvotes: 0

Kevin
Kevin

Reputation: 76194

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)

Upvotes: 1

Related Questions