UnboundLocalError


#1

I have managed to generate and error I don’t know how to correct. I have been trying to work out how import works and how I can use it to modularise my program. It doesn’t seem to be working as I expected, and I’m not sure why. I’ve been experimenting with different approaches to doing stuff, so please ignore the actual functionality. I started with the example blink program and just went from there.
The final project is an encoder for a R/C model plane, if you’re wondering what the heck I’m trying to do. :slight_smile:

This is a copy of the output.

Loading settings...
Switched to auto mode
Ready!
Checking for updates...
[info] Searching for /home/ian/zerynthProjects/Blink/__builtins__.py
[info] Searching for /home/ian/.zerynth2/dist/r2.1.1/stdlib/__builtins__.py
[info] ########## STEP 0 - first pass
[info] Compiling module: __main__ @ /home/ian/zerynthProjects/Blink/main.py
[info] Searching for /home/ian/zerynthProjects/Blink/__builtins__.py
[info] Searching for /home/ian/.zerynth2/dist/r2.1.1/stdlib/__builtins__.py
[info] Compiling module: __builtins__ @ /home/ian/.zerynth2/dist/r2.1.1/stdlib/__builtins__.py
[info] Searching for /home/ian/zerynthProjects/Blink/myDict.py
[info] Compiling module: myDict @ /home/ian/zerynthProjects/Blink/myDict.py
[info] ########## STEP 0 - second pass
[info] Compiling module: __main__ @ /home/ian/zerynthProjects/Blink/main.py
[info] Searching for /home/ian/zerynthProjects/Blink/__builtins__.py
[info] Searching for /home/ian/.zerynth2/dist/r2.1.1/stdlib/__builtins__.py
[info] Compiling module: __builtins__ @ /home/ian/.zerynth2/dist/r2.1.1/stdlib/__builtins__.py
[info] Searching for /home/ian/zerynthProjects/Blink/myDict.py
[info] Compiling module: myDict @ /home/ian/zerynthProjects/Blink/myDict.py
[fatal] Unexpected exception
Traceback (most recent call last):
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 120, in visit_Import
mod = self.hooks.getModuleCode(alias.name)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compiler.py", line 149, in getModuleCode
return self.modules[name]
KeyError: 'myDict'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compilercmd.py", line 71, in compile
binary, reprs = compiler.compile()
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compiler.py", line 350, in compile
self.compileModule(self.mainfile)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compiler.py", line 319, in compileModule
mc.visit(tree)
  File "/home/ian/.zerynth2/sys/python/lib/python3.5/ast.py", line 245, in visit
return visitor(node)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 103, in visit_Module
self.code.addCode(self.visit(stmt))
  File "/home/ian/.zerynth2/sys/python/lib/python3.5/ast.py", line 245, in visit
return visitor(node)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 122, in visit_Import
self.hooks.importHook(alias.name,node.lineno,self.filename)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compiler.py", line 165, in importHook
self.compileModule(name,line,filename)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/compiler.py", line 319, in compileModule
mc.visit(tree)
  File "/home/ian/.zerynth2/sys/python/lib/python3.5/ast.py", line 245, in visit
return visitor(node)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 107, in visit_Module
self.generateCodeObjs()
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 853, in generateCodeObjs
fcode.addCode(self.genCodeList(node.body))
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 92, in genCodeList
listcode.append(self.visit(cc))
  File "/home/ian/.zerynth2/sys/python/lib/python3.5/ast.py", line 245, in visit
return visitor(node)
  File "/home/ian/.zerynth2/dist/r2.1.1/ztc/compiler/astwalker.py", line 810, in visit_FunctionDef
code.addCode(OpCode.BUILD_TUPLE(len(cellvars)))
UnboundLocalError: local variable 'cellvars' referenced before assignment

This is the main.py

###############################################################################
#
# import experiments...
#
###############################################################################

import myDict
dummy = myDict.anotherFunction()
sw = {
    "ailTrim": 0,
    "eleTrim": 0,
    "rudTrim": 0,
    "thrTrim": 0,
    "ailDualRate": 100,
    "eleDualRate": 100,
    "rudDualRate": 100,
    "flapSwitch": 0,
    "gearSwitch": 0,
    "momButton": 0
}

newdict = myDict.pollSwitches(sw)
btn1 = D3
flashRate = 1000
# configure the pin behaviour to drive the LED and to read from the button
pinMode(btn1, INPUT_PULLUP)
pinMode(LED0, OUTPUT)
pinMode(LED1, OUTPUT)
pinMode(LED2, OUTPUT)

digitalWrite(LED0, LOW)
digitalWrite(LED1, HIGH)
digitalWrite(LED2, HIGH)


def pressed():
    print("button pressed!")
    flashRate = 100

def released():
    if flashRate == 100:
        print("button released!!")
        flashRate = 1000

onPinFall(btn1, pressed)
onPinRise(btn1, released)

# loop forever
while True:
    digitalWrite(LED0, HIGH)
    digitalWrite(LED1, HIGH)
    digitalWrite(LED2, HIGH)
    sleep(flashRate)
      digitalWrite(LED0, LOW)
    digitalWrite(LED1, LOW)
    digitalWrite(LED2, LOW)
    sleep(flashRate)

This is the module I’m trying to import (apologies for the poor naming…)

################################################################################
# Set switch interrupts (22 of them)
#
# Should this thing run in a thread that fires every (say) 100ms ???
# i.e. switches are polled 10 times per second. 
#
################################################################################
def pollSwitches(switches):
## pins 22 to 39 are the switches
    global sw
    """
    sw = {
        "ailTrim" : 0,
        "eleTrim" : 0,
        "rudTrim" : 0,
        "thrTrim" : 0,
        "ailDualRate" : 100,
        "eleDualRate" : 100,
        "rudDualRate" : 100,
        "flapSwitch" : 0,
        "gearSwitch" : 0,
        "momButton" : 0
        }
    """
    ailRates = [50, 75, 100]
    eleRates = [70, 85, 100]
    rudRates = [90, 95, 100]
    flapPos = [0, 35, 85]
    
        # configure pins as input  
    for swPin in range(22, 39):
        pinMode(swPin,INPUT_PULLUP)
        
    def pressed(swPin):
    ## Trim switches are three position momentary, centre off
        if   swPin == 22: sw["ailTrim"] += 1
        elif swPin == 23: sw["ailTrim"] -= 1
        elif swPin == 24: sw["eleTrim"] += 1
        elif swPin == 25: sw["eleTrim"] -= 1
        elif swPin == 26: sw["rudTrim"] += 1
        elif swPin == 27: sw["rudTrim"] -= 1
        elif swPin == 28: sw["thrTrim"] += 1
        elif swPin == 29: sw["thrTrim"] -= 1
    
    ## Dual rate switches are three posistion centre off[" 
        if   swPin == 30: sw["ailDualRate"] = ailRates[2]
        elif swPin == 31: sw["ailDualRate"] = ailRates[0]
        else:             sw["ailDualRate"] = ailRates[1]
        
        if   swPin == 32: sw["eleDualRate"] = eleRates[2]
        elif swPin == 33: sw["eleDualRate"] = eleRates[0]
        else:             sw["eleDualRate"] = eleRates[1]
        
        if   swPin == 34: sw["rudDualRate"] = rudRates[2]
        elif swPin == 35: sw["rudDualRate"] = rudRates[0]
        else:             sw["rudDualRate"] = rudRates[1]
        
    ##Flap switch (3 position switch)
        if   swPin == 36: sw["flapSwitch"] = flapPos[2]
        elif swPin == 37: sw["flapSwitch"] = flapPos[0]
        else:             sw["flapSwitch"] = flapPos[1]
        
    ## landing gear (2 position switch)
        if   swPin == 38: sw["gearSwitch"] = 0
        else:             sw["gearSwitch"] = 100
    
    ## momentary button (2 position momentary switch)
        if   swPin == 39: sw["momButton"] = 100
        else:             sw["momButton"] = 0
        
    for swPin in range (22, 39):
        onPinFall(swPin,pressed,swPin,1,MILLIS)
        onPinRise(swPin,pressed,swPin,1,MILLIS)
    ### end of for swPin
    return(sw)
def anotherFunction(x):
    return x

Any ideas greatly appreciated.
Ian


#2

I think I may have fixed it. At least the error has gone away (no idea if the logic is correct, still on steep learning curve). I had to change the imported module quite a bit. It now looks like this.

################################################################################
# Set switch interrupts (22 of them)
#
################################################################################
sw = {
    "ailTrim" : 0,
    "eleTrim" : 0,
    "rudTrim" : 0,
    "thrTrim" : 0,
    "ailDualRate" : 100,
    "eleDualRate" : 100,
    "rudDualRate" : 100,
    "flapSwitch" : 0,
    "gearSwitch" : 0,
    "momButton" : 0
    }

ailRates = [50, 75, 100]
eleRates = [70, 85, 100]
rudRates = [90, 95, 100]
flapPos = [0, 35, 85]

def pressed(swPin):
## Trim switches are three position momentary, centre off
    if   swPin == 22: sw["ailTrim"] += 1
    elif swPin == 23: sw["ailTrim"] -= 1
    elif swPin == 24: sw["eleTrim"] += 1
    elif swPin == 25: sw["eleTrim"] -= 1
    elif swPin == 26: sw["rudTrim"] += 1
    elif swPin == 27: sw["rudTrim"] -= 1
    elif swPin == 28: sw["thrTrim"] += 1
    elif swPin == 29: sw["thrTrim"] -= 1

## Dual rate switches are three posistion centre off[" 
    if   swPin == 30: sw["ailDualRate"] = ailRates[2]
    elif swPin == 31: sw["ailDualRate"] = ailRates[0]
    else:             sw["ailDualRate"] = ailRates[1]
    
    if   swPin == 32: sw["eleDualRate"] = eleRates[2]
    elif swPin == 33: sw["eleDualRate"] = eleRates[0]
    else:             sw["eleDualRate"] = eleRates[1]
    
    if   swPin == 34: sw["rudDualRate"] = rudRates[2]
    elif swPin == 35: sw["rudDualRate"] = rudRates[0]
    else:             sw["rudDualRate"] = rudRates[1]
    
##Flap switch (3 position switch)
    if   swPin == 36: sw["flapSwitch"] = flapPos[2]
    elif swPin == 37: sw["flapSwitch"] = flapPos[0]
    else:             sw["flapSwitch"] = flapPos[1]
    
## landing gear (2 position switch)
    if   swPin == 38: sw["gearSwitch"] = 0
    else:             sw["gearSwitch"] = 100

## momentary button (2 position momentary switch)
    if   swPin == 39: sw["momButton"] = 100
    else:             sw["momButton"] = 0

" I think this stuff might be run automatically the first time the module is loaded"
## pins 22 to 39 are the switches
# configure pins as input and set interrupts
for swPin in range(22, 39):
    pinMode(swPin,INPUT_PULLUP)
    onPinFall(swPin,pressed,swPin,10,MILLIS)
    onPinRise(swPin,pressed,swPin,10,MILLIS)