Search code examples
pythonfunctionscope

NameError when accessing variable returned from function (out of order?)


Per the code below, I'm getting this error:

NameError: name 'leap_status' is not defined

The def days_in_month() is looking for the status of leap_status which should be defined already but, for some reason, it seems to be calling it before it's defined by the is_leap() function?

I feel like I missed something about how the return value is stored or something..

def is_leap(year):
  if year % 4 == 0:
    if year % 100 == 0:
      if year % 400 == 0:
        leap_status = True
      else:
        leap_status = False
    else:
      leap_status = True
  else:
    leap_status = False
  return leap_status

def days_in_month(year, month):
    if leap_status == True:
        month_days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    else:
      month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 
    num_days_in_month = month_days[month -1]
    return num_days_in_month


#Year Input from user
year = int(input()) # Enter a year
#Function to calculate if Leap Year
is_leap(year)
#Month Input from User
month = int(input())
#Function to determine how many days in month
#depending on if Leap Year is True
days_in_month(year, month)
days = days_in_month(year, month)

Solution

  • The reason of the error is because you use the variable out of scope. the leap_status variable is locally in is_leap function and out of the function python doesn't know this variable.

    You can solve it in two ways: First, and recommended, is to call the function and not the variable:

    def days_in_month(year, month):
        if is_leap(year):
            # rest of code
    

    In here, you call the first function that is above the function you are in, so the is_leap function is called and known by python. be aware the if the is_leap function was down the days_in_month function you can't do it.

    The second and less recommended way is to use global variable, so python know to use the variable in other places, out of the declared function:

    def is_leap(year):
        global leap_status
            # rest of code
    

    This way when you can use or change the variable where ever you want in your program.