-1

I have a function which works with integers. I have added code for exception handling if strings or floats are entered, however, Python keeps returning either nonsense or NameError. At this point I have tried a loop which keeps asking until an integer is entered and a try and except. Nothing works.

Here's the code:

def threes(num):

    """isNotCorrect = True

    while isNotCorrect:
        print(type(num))
        if type(num) is not int:
            print("Sorry, you need to enter a whole number to play Threes.")
        else:
            print('X')
            isNotCorrect = False"""

    try:
        while num > 1:
            if num % 3 == 0:
                num = num/3
            else:
                if ((num + 1) % 3 == 0):
                    num = (num + 1)/3
                else:
                    num = (num - 1)/3
            print(num)
    except NameError:
        print("Invalid number. Please enter a valid number.")

Entering a whole number(the intended input) executes the code fine, but everything else leads to a name error like this, where the input is threes(bob). The top part is my attempt at a loop, which also failed and returned the same error;

Traceback (most recent call last):
   File "<input>", line 1, in <module>
NameError: name 'bob' is not defined
Tomalak
  • 332,285
  • 67
  • 532
  • 628
Spirits
  • 9
  • 3
  • 2
    It seems that you haven't defined bob variable... Could you please post the entiere code ? – Darkaird Jul 27 '17 at 11:17
  • 1
    What did you expect when you call `threes(bob)` and `bob` is not defined anywhere? – Tomalak Jul 27 '17 at 11:17
  • 1
    The exception is raised before the method is executed (`bob` doesn't exist). By not entering the method, the `try` `except` is not being executed. Also, if you want to check the input is a number, the `Except` should check for `TypeError`, not `NameError`. – AArias Jul 27 '17 at 11:20
  • As Ruud de Jong says, `NameError` is irrelevant to the code you posted. BTW, if you actually _do_ want to catch a non-number being passed to code that needs numbers, you'd normally catch it with `except ValueError`. But it's better to handle that in the code that gets the input data _before_ you pass it to the code which processes that data. – PM 2Ring Jul 27 '17 at 11:24
  • 1
    You may find the info here useful: [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response). – PM 2Ring Jul 27 '17 at 11:25

4 Answers4

0

Your bob variable is not defined at all, so you don't reach the try/catch.

Try decalring bob with not a number, bob = 'test_string' and retry.

Chen A.
  • 10,140
  • 3
  • 42
  • 61
0

The problem is that NameError is being raised from outside the function call. When you say:

threes(bob)

What Python does is:

  1. Get the value of bob.
  2. Call threes passing that value as parameter.

NameError is raised in step 1., so you don't even get into the function. If you still want to catch it, you should have the try/except block outside:

try:
    threes(bob)
except NameError:
    print("NameError raised.")
jdehesa
  • 58,456
  • 7
  • 77
  • 121
0

The code you posted simply cannot raise a NameError. The error probably comes from the part where you call you threes function. If you just wrote threes(bob), then the NameError will be raised if you did not previously define a variable named bob. If you wanted to pass a string, you should call your function like: threes("bob")

Ruud de Jong
  • 744
  • 3
  • 11
0

NameError: name 'bob' is not defined means that you try to use a variable named bob but you didn't create it.
You have to define what is bob like that for exemple :
bob = 'a simple man' # bob is a string
or
bob = 4 # bob is an integer

Furthermore, I just want you to know that even if it works, try to avoid using try/except because this is quite slow when you have to enter in the except block.

If you want to check if your variable is an integer I recommend you using :

if isinstance(bob, int):
    # do something
else:
    # do something else

Where isinstance() is a built-in function.

Darkaird
  • 2,700
  • 4
  • 15
  • 29
  • Good advice. Exceptions are faster than the equivalent `if...else` code when the exception doesn't actually get raised, but if you expect the exception to be raised more than 5-10% of the time, then the code will run faster if it uses `if...else` code. However, using `isinstance` is better than using `type` for this sort of thing. – PM 2Ring Jul 27 '17 at 12:33
  • @PM 2Ring Yes, I forgot `isinstance`, I edited. And about `try...except`, I would add that even if it's less than 5-10% (but not to much neither), I'll prefer `if...else` because it's more constant and predictable which can be useful for multiprocessing purpose (for exemple). – Darkaird Jul 27 '17 at 12:43