0

Here is a puzzle I can't wrap my head around.

The code below works:

CONST_TIME_SPEED1S = 4000
CONST1_SPEED1S = 0.5
CONST2_SPEED1S = 0.12
CONST3_SPEED1S = 0.1
DS_FLAPS_SLOW = 0
DS_ERROR_F_NO_SPEED = 0

Timer_Speed_1s = 0
Direction = 'DIRECTION_LOWER'

Flag_Flaps_Primary_Fault = 0

def main_logic():
    if Direction == 'DIRECTION_LOWER':
        if Timer_Speed_1s > CONST_TIME_SPEED1S:
            if (Speed1S < CONST1_SPEED1S) and (Speed1S > CONST2_SPEED1S):
                DS_FLAPS_SLOW = 1
                DS_ERROR_F_NO_SPEED = 0
            else:
                DS_FLAPS_SLOW = 0
                if Speed1S < CONST3_SPEED1S:
                    DS_ERROR_F_NO_SPEED = 1
                    DS_FLAPS_PRIMARY_FAULT = 1
                else:
                    DS_ERROR_F_NO_SPEED = 0
                    if Flag_Flaps_Primary_Fault == 1:
                        pass
                    else:
                        DS_FLAPS_PRIMARY_FAULT = 0
        else:
            DS_FLAPS_SLOW = 0
            DS_ERROR_F_NO_SPEED = 0
    else:
        Timer_Speed_1S = 0
        DS_FLAPS_SLOW = 0
        DS_ERROR_F_NO_SPEED = 0
        
main_logic()

print ('DS_FLAPS_SLOW = ', DS_FLAPS_SLOW)
print ('DS_ERROR_F_NO_SPEED = ', DS_ERROR_F_NO_SPEED)

If I change name of the variable 'Timer_Speed_1s' into 'Timer_Speed_1S', I get a message "UnboundLocalError: local variable 'Timer_Speed_1S' referenced before assignment".

To puzzle me more, when I strip the code down to:

Timer_Speed_1S = 0

def main_logic():
    print (Timer_Speed_1S)
           
main_logic()

everything works just fine, no error messages. How can it be?

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 2
    You have *two* variables in your code, `Timer_Speed_1S` and `Timer_Speed_1s`. – juanpa.arrivillaga May 08 '22 at 11:18
  • 2
    The last one, `Timer_Speed_1S = 0` is presumably a typo (btw, you really should stick to PEP8 naming conventions, just use `lower_case`). This typo was preventing an error from being raised. It looks like you are also just not understanding how local variables work in Python, this is probably going to be a duplicate of: https://stackoverflow.com/questions/370357/unboundlocalerror-on-local-variable-when-reassigned-after-first-use – juanpa.arrivillaga May 08 '22 at 11:21
  • @juanpa.arrivillaga Thanks for the link, now I get it. Should have tell Python that I want to work with global variables. – Alexander T May 08 '22 at 11:38
  • All Python names - including names of variables, functions, classes, methods, etc. are **case-sensitive**. `hello = "one"`, `Hello = "two"`, & `HELLO = "three"` are 3 different variables. Which is a longer way of saying what @juanpa.arrivillaga said in their comment. And when you want to **access & assign** values to a global variable, you need to use `global` (or `nonlocal`), which is linked in their 2nd comment. – aneroid May 08 '22 at 11:39
  • 1
    @aneroid to be clear, you only need a `global`/`nonlocal` statement if you want to *assign* to a global or nonlocal variable, not merely to access – juanpa.arrivillaga May 08 '22 at 19:38
  • @juanpa.arrivillaga yes, that's what I meant by the emphasis. My phrasing could have been clearer. – aneroid May 08 '22 at 21:36

1 Answers1

1

In this code you have two variable Timer_Speed_1s(Outside main_logic function ) and Timer_Speed_1S(Inside main_logic function)

The error you get is

UnboundLocalError: local variable 'Timer_Speed_1S' referenced before assignment

This error means you want to access the variable before this is defined.

The variable is defined after you want to access it.

# Last Lines In main_logic Function
else:
        Timer_Speed_1S = 0
        DS_FLAPS_SLOW = 0
        DS_ERROR_F_NO_SPEED = 0
CONST_TIME_SPEED1S = 4000
CONST1_SPEED1S = 0.5
CONST2_SPEED1S = 0.12
CONST3_SPEED1S = 0.1
DS_FLAPS_SLOW = 0
DS_ERROR_F_NO_SPEED = 0

Timer_Speed_1s = 0
Direction = 'DIRECTION_LOWER'

Flag_Flaps_Primary_Fault = 0

def main_logic():
    if Direction == 'DIRECTION_LOWER':
        if Timer_Speed_1S > CONST_TIME_SPEED1S: # If you change the variable name then you get this error. 
            if (Speed1S < CONST1_SPEED1S) and (Speed1S > CONST2_SPEED1S):
                DS_FLAPS_SLOW = 1
                DS_ERROR_F_NO_SPEED = 0
            else:
                DS_FLAPS_SLOW = 0
                if Speed1S < CONST3_SPEED1S:
                    DS_ERROR_F_NO_SPEED = 1
                    DS_FLAPS_PRIMARY_FAULT = 1
                else:
                    DS_ERROR_F_NO_SPEED = 0
                    if Flag_Flaps_Primary_Fault == 1:
                        pass
                    else:
                        DS_FLAPS_PRIMARY_FAULT = 0
        else:
            DS_FLAPS_SLOW = 0
            DS_ERROR_F_NO_SPEED = 0
    else:
        Timer_Speed_1S = 0 # here
        DS_FLAPS_SLOW = 0
        DS_ERROR_F_NO_SPEED = 0
        
main_logic()

print ('DS_FLAPS_SLOW = ', DS_FLAPS_SLOW)
print ('DS_ERROR_F_NO_SPEED = ', DS_ERROR_F_NO_SPEED)

Here is some explanation

This code gives no error.

a = 12
def p():
    print(a)
p()

But this gives you the same error.

UnboundLocalError: local variable 'a' referenced before assignment

Here, This error is because you want to change the local variable.

a = 12

def p():
    a+=1
    print(a)

p()

If you don't want the error

a = 12
def p():
    global a
    a+=1
    print(a)
p() # → 13

codester_09
  • 5,622
  • 2
  • 5
  • 27