pythonpython-3.xterminalideturing-machines

python - 3 Turing Machine script, getting errors on an undefined variable, even though I assigned it


I'm working on a Turing machine in python and i'm getting an error for an undefined variable even though I have assigned it. Any help?

the exact error is

Traceback (most recent call last):
  File "main.py", line 71, in <module>
    read()
  File "main.py", line 20, in read
    if state == 0:
UnboundLocalError: local variable 'state' referenced before assignment

my code is:

#Turing Machine In Python
#by adrian wheeler

#the script

index = 5
state = 0
tape = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]




def MoveRight():
    index += 1

def MoveLeft():
    index -= 1

def read():
    if state == 0:
        if tape[index] == 0:
            tape.insert(index, "1")
            state = 2
            MoveRight()
            read()
    
    if state == 2:
        if tape[index] == 0:
            tape.insert(index, "1")
            state = 3
            MoveRight
            read()
    
    if state == 3:
        if tape[index] == 0:
            tape.insert(index, "1")
            state = 4
            MoveLeft()
            read()
            
    if state == 4:
        if tape[index] == 1:
            tape.insert(index, "0")
            state = 4
            MoveLeft
            read()
            
    if state == 4:
        if tape[index] == 0:
            tape.insert(index, "0")
            state = 5
            MoveRight()
            read()
            
    if state == 5:
        if tape[index] == 0:
            tape.insert(index, "0")
            state = 5
            MoveRight()
            read()
            
    if state == 5:
        if tape[index] == 1:
            tape.insert(index, "1")
            state = 0
            MoveRight()
            read()
    
#running the script

read()
            

I'm very sure I defined the variable before using it.

I've tried moving it around to different spots, and searched up a fix on google, I still can't seem to find the fix. I am using an IDE as i'm at school, maybe that's the problem, please help?


Solution

  • Declare state, index and tape as local variables at the top of your functions

    Every function is a new namespace. This means that even though the variable state was defined in the outer scope, it is not defined in the function. To fix this we can use python's global keyword, to ensure that your variables are defined within the function.

    Quick explanation of global keyword:

    Surprisingly, this code contains an error:

    foo = 1
    
    def do_something():
        foo = 2 # Uh, oh... foo is undefined
    

    Let's fix it:

    foo = 1
    
    def do_something():
        global foo # make sure foo is global
        foo = 2 # This works fine!
    

    So, back to your code: We need to put global key words at the top of all your functions as in:

    #Turing Machine In Python
    #by adrian wheeler
    
    #the script
    
    index = 5
    state = 0
    tape = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    
    
    
    
    def MoveRight():
        global index # Make sure our vars are global!
        index += 1
    
    def MoveLeft():
        global index # Make sure our vars are global!
        index -= 1
    
    def read():
        global state, index, tape # Make sure our vars are global!
        if state == 0:
            if tape[index] == 0:
                tape.insert(index, "1")
                state = 2
                MoveRight()
                read()
        
        if state == 2:
            if tape[index] == 0:
                tape.insert(index, "1")
                state = 3
                MoveRight
                read()
        
        if state == 3:
            if tape[index] == 0:
                tape.insert(index, "1")
                state = 4
                MoveLeft()
                read()
                
        if state == 4:
            if tape[index] == 1:
                tape.insert(index, "0")
                state = 4
                MoveLeft
                read()
                
        if state == 4:
            if tape[index] == 0:
                tape.insert(index, "0")
                state = 5
                MoveRight()
                read()
                
        if state == 5:
            if tape[index] == 0:
                tape.insert(index, "0")
                state = 5
                MoveRight()
                read()
                
        if state == 5:
            if tape[index] == 1:
                tape.insert(index, "1")
                state = 0
                MoveRight()
                read()
        
    #running the script
    
    read()