4

I recently started learning Python and have some code here.

...
workout = input("Work out if you won?")

if workout == "y":
    ballone()
elif workout == "n":
    print("Okay.")
    sys.exit("Not working out if you won")
else:
    sys.exit("Could not understand")

##Ball one
def ballone():
...

The issue is calling 'ballone'. You can see that it is defined and works perfectly when called from the command line (ballone())

Any ideas? I have scoured the net but cannot seem to find anything to help me. If any more code needs posting then please let me know :)

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Mattios550
  • 372
  • 1
  • 5
  • 18

1 Answers1

12

Move the function definition to before the lines that use it.

def ballone():
    # ...

if workout == "y":
    ballone()
elif workout == "n":
    print("Okay.")
    sys.exit("Not working out if you won")
else:
    sys.exit("Could not understand")

Functions are stored in identifiers (variables), just like your workout value. If you don't define it first, how is Python to know it'll be defined later?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Typically this is done by putting the main logic in a function and calling it at the bottom of the module, usually guarded by `if __name__ == '__main__':`. – Steven Rumbalski Feb 27 '13 at 18:28
  • @StevenRumbalski: the `__name__` test won't protect you from this error though. If you do that at the top of your module, you'll still have the same problem. – Martijn Pieters Feb 27 '13 at 18:28
  • True, but I did qualify it that way. – Steven Rumbalski Feb 27 '13 at 18:30
  • @StevenRumbalski: So you did. – Martijn Pieters Feb 27 '13 at 18:30
  • That seems really obvious now! :/ I have experience with PHP, HTML, CSS, jQuery etc... thanks for the other answers :D & for being so fast. I used to use Yahoo Answers for this type of question but this is my home now ;) :D – Mattios550 Feb 27 '13 at 18:43
  • @MartijnPieters Just came across this error and wanted to know why this happens. I'd have thought the cause would be that the function is available throughout the scope it was defined in. – cs95 Jul 04 '17 at 20:19
  • @cᴏʟᴅsᴘᴇᴇᴅ all lines in a given scope are executed line by line. If you tried to use `foo` before anything was assigned to that name, you'd *expect* an error, right? A function or class definition is no different here; the `def` statement creates a function object that is bound to the function name. It's as if you ran `ballone = function(...)` to produce the function, only with slightly different syntax. Until the `def ballone():` statement is reached the name doesn't exist, there is no function and you get an exception if you tried to use it. – Martijn Pieters Jul 04 '17 at 21:03
  • @MartijnPieters When I took a course in Python, the professor equated its scoping rules to javascript's hoisting in terms of the lifetime of variables (now I know better). In JS you can actually do this there and _not_ expect an error. I suppose that's why I always had that stuck in my mind. Thanks for the explanation. – cs95 Jul 04 '17 at 21:08
  • doesn't seem to work when flask is loading :-(( – eddie Apr 26 '20 at 13:07
  • @eddie Flask is it special here. Your actual code will have more going on than what this question and answer address. – Martijn Pieters Apr 26 '20 at 13:51