-3

Why does it say "name 'max_range' is not defined" when I have already assigned it. this is an attempt at a question on https://www.algoexpert.io/questions/Largest%20Range example array:

array = [1, 11, 3, 0, 15, 5, 2, 4, 10, 7, 12, 6]

def largestRange(array):
    # Write your code here.
    sub_array = array # substitute array as it will be modified later3
    Range = [0,0]
    max_range = [0,0]
    
    def run() :
        global max_range
        num = min(sub_array)
        Range = [num]
        running = True
        while running :
            num += 1
            if num not in sub_array :
                Range.append(num - 1)
                running = False
                pass
            else :
                sub_array.remove(num)
                pass
            pass
        print(Range)
        print(max_range)
        if (max_range[1] - max_range[0]) <= (Range[1] - Range[0]) :
            max_range = Range
        if len(sub_array) != 0:
            run()
        pass
    
    run()
    print(max_range)
    return max_range
    pass
largestRange(array)

The complete error:

name 'max_range' is not defined
Traceback (most recent call last):
  File "/tester/json_wrapper.py", line 9, in run
    actual = program.largestRange(array[:])
  File "/tester/program.py", line 30, in largestRange
    run()
  File "/tester/program.py", line 23, in run
    print(max_range)
NameError: name 'max_range' is not defined

stack overflow says that my question is mostly code so I am just writing this line so that it lets me post the question

example reproducible code :

def largestRange(array):
    # Write your code here.
    sub_array = array  # substitute array as it will be modified later3
    Range = [0, 0]
    max_range = [0, 0]

    def run():
        global max_range
        num = min(sub_array)
        Range = [num]
        running = True
        while running:
            num += 1
            if num not in sub_array:
                Range.append(num - 1)
                running = False
                pass
            else:
                sub_array.remove(num)
                pass
            pass
        print(Range)
        print(max_range)
        if (max_range[1] - max_range[0]) <= (Range[1] - Range[0]):
            max_range = Range
        if len(sub_array) != 0:
            run()
        pass

    run()
    print(max_range)
    return max_range


pass
largestRange([1, 11, 3, 0, 15, 5, 2, 4, 10, 7, 12, 6])
Mehul
  • 115
  • 6

2 Answers2

1

max_range is defined in global scope. So "by defualt" it is also visible in function's local scope.

max_range = whatever
def run():
    ....
    print(max_range) # OK

However, making max_range = Range inside the function, max_range is then considered as local variable to the function, i.e. in the all function it has nothing to do with the global max_range

max_range = whatever
def run():
    ....
    print(max_range) # error, because local max_range has not been declared yet
    max_range = Range # this makes max_range local

EDIT (to edited question)

The global keyword works, well, for global variables. In your code, you have max_range defined inside a function (not in global scope) and you want to change it inside inner function. You can achieve this e.g. by taking it as a parameter and return the modified value:

def largestRange(array):
    ...
    max_range = [0,0]
    def run(max_range):
        ... # the code you have
        return max_range
    max_range = run(max_range)
    ...
Jan Stránský
  • 1,671
  • 1
  • 11
  • 15
1

In Python a variable that is assigned to is by default considered to be a local variable... i.e. in

x = 3

def foo():
    print(x)   # <--- error: x is considered a local
               # because of next statement, but at this
               # point it has not yet received any value
    x = 5

If you want to mutate a global you need to inform the compiler:

x = 3

def foo():
    global x # <--- this informs x is global even if there are assignments
    print(x) # <--- prints the global
    x = 5 # <--- ok, this changes the global

If a variable is never written to then the compiler assumes it's captured from an outer scope or a global.

6502
  • 112,025
  • 15
  • 165
  • 265
  • but when it gives File "/tester/program.py", line 23, in run print(max_range) NameError: name 'max_range' is not defined – Mehul Sep 02 '20 at 11:50
  • @Mehul: no... the error is `UnboundLocalError: local variable 'max_range' referenced before assignment`. With the first example you would get the same error about `x`. Python decided it's a local but if you use it before the assignment it gives the error you got. – 6502 Sep 02 '20 at 11:52
  • i am super confused, What should i do now?? pl tell, I am very new to python – Mehul Sep 02 '20 at 11:57
  • oh wait i will do that – Mehul Sep 02 '20 at 11:57