Search code examples
pythonpython-3.xfunctionglobal-variablesglobal

Python unable to access global variable in simple grade program


I am trying to create a python program which I am facing an issue to access the global variable in function. Please check the code below and suggest to me what is wrong with the program.

All the global variable I am using is not been accessed by the last function showGrades()

I am getting the error below: NameError: name 'marks' is not defined

def main():
  getInput()
  getGrades()
  showGrades()
def getInput():
    global Quiz,Ass,Test1,Test2,marks,Grade,GradePoint
    Quiz = float(input("Enter quiz overall marks out of 100 :"))
    Ass =  float(input("Enter assignment overall mark out of 100 :"))
    Test1 = float(input("Enter test1 overall mark out of 100 :"))
    Test2 = float(input("Enter test2 overall mark out of 100 :"))
def getGrades():
    marks = float((Quiz * 0.2) + (Ass * 0.2) + (Test1 * 0.3) + (Test2 * 0.3))
    if marks<=100 and marks>=94:
     Grade = "A+"
     GradePoint = 4.0
    elif marks<=93 and marks>=87:
      Grade = "A"
      GradePoint =3.7
    elif marks <= 86 and marks >= 80:
      Grade = "A-"
      GradePoint = 3.5
    elif marks <= 79 and marks >= 77:
     Grade = "B+"
     GradePoint = 3.2
    elif marks <= 76 and marks >= 73:
     Grade = "B"
     GradePoint = 3.0
    elif marks <= 72 and marks >= 70:
     Grade = "B-"
     GradePoint = 2.7
    elif marks <= 69 and marks >= 67:
     Grade = "C+"
     GradePoint = 2.3
    elif marks <= 66 and marks >= 63:
     Grade = "C"
     GradePoint =2.0
    elif marks <= 62 and marks >= 60:
     Grade = "C-"
     GradePoint = 1.7
    elif marks <= 59 and marks >= 50:
     Grade = "D"
     GradePoint =1.0
    else:
     Grade = "F"
     GradePoint = 0.0
def showGrades():
     print(f"your overall marks are:" , float(marks))
     print("Grade:" + str(Grade))
     print(f"GradePoint:" ,float(GradePoint))
main()

Solution

  • In the getInput function, you declare that marks will be a global variable, but never actually assign it. Since the scope of the global keyword is only within that function, you actually never created a global variable marks.

    Then in getGrades, you create another variable marks, which is local to getGrades, because you didn't declare marks as global in getGrades. This is why showGrades cannot find the variable marks; it is local to getGrades.

    Try making declaring marks as a global inside of getGrades, and I'm pretty sure the problem will be fixed.

    For more see: What are the rules for local and global variables in Python?


    Edit: To confirm my thinking I decided to do an experiment: I created a function where I declared, but never assigned a global variable. We then run the function, and use the built in globals function to check if myglobalvariable actually exists in the global scope

    >>> def globaltest():
           global myglobalvariable
    
    >>> globaltest()
    >>> globals()
    
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'globaltest': <function globaltest at 0x0000027E24B11EA0>}
    

    We see from the output above that, as expected, myglobalvariable is not in the global scope.