Python Forum
Global variable does not seem to be global. - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Global variable does not seem to be global. (/thread-19804.html)



Global variable does not seem to be global. - Columbo - Jul-15-2019

I am trying to use a global variable which is then incremented in a function but I am getting this error:

File "E:\Python 3\Prehistoric Life\prehistoricLife.py", line 169, in fetchRecord recNo += 1
UnboundLocalError: local variable 'recNo' referenced before assignment.

It is saying that recNo is a local variable.

Here is an excerpt of the code where I set recNo as a global and then the function where I am using it.

from tkinter import *
from tkinter import ttk
import sqlite3

root = Tk()


#---------------------------[ Global Variables ]--------------------------------
dinoPath = 'dino_images\\'
sizePath = 'dinosize\\'
maxRec = 0
recNo = 0
rowCount = 0

#---------------------------- Clear all entry boxes ---------------------------------
def fetchRecord():
    recBox.delete(0,END)      #entry boxes
    eName.delete(0,END)      
    eMeaning.delete(0,END)
    ePronounce.delete(0,END)
    ePeriod.delete(0,END)
    eGroup.delete(0,END)
    eSize.delete(0,END)
    eLived.delete(0,END)
    eDiet.delete(0,END)
    eFossils.delete(0,END)
    factFile.delete(1.0,END)    #Textbox
    
#---------------------------- Get Record From Database ---------------------------------   
   recNo += 1     #increment recNo
    
    conn=sqlite3.connect('dinobase.db')
    c=conn.cursor()
    c.execute('SELECT * FROM dino WHERE record = recNo')
    rows=c.fetchall()
    
    for row in rows:
        recBox.insert(0,row[0])
        eName.insert(0,row[1])
        eMeaning.insert(0,row[2])
        ePronounce.insert(0,row[3])
        ePeriod.insert(0,row[4])
        eGroup.insert(0,row[5])
        eSize.insert(0,row[6])
        eLived.insert(0,row[7])
        eDiet.insert(0,row[8])
        eFossils.insert(0,row[9])
        factFile.insert(1.0,row[10])
    
    c.close()
    conn.close()
Any suggestions appreciated.


RE: Global variable does not seem to be global. - ichabod801 - Jul-15-2019

You don't want to try to modify global variables within a function, it just leads to a mess that is hard to maintain. It is much better to use functions with parameters and return values:

a = 5
def foo(x)
    return x + 2
a = foo(a)



RE: Global variable does not seem to be global. - Columbo - Jul-15-2019

Thanks. I need to increment the value of recNo and use it in that function to get the record. That is why I tried incrementing recNo within that function. I tried passing recNo as a parameter and then using local variable x=recNo, incrementing x and then recNo=x but have this error:

TypeError: fetchRecord() missing 1 required positional argument: 'recNo'

ef fetchRecord(recNo):
    recBox.delete(0,END)
    eName.delete(0,END)      #entry boxes
    eMeaning.delete(0,END)
    ePronounce.delete(0,END)
    ePeriod.delete(0,END)
    eGroup.delete(0,END)
    eSize.delete(0,END)
    eLived.delete(0,END)
    eDiet.delete(0,END)
    eFossils.delete(0,END)
    factFile.delete(1.0,END)    #Textbox
    
    x=recNo
    x += 1
    recNo = x
    
    conn=sqlite3.connect('dinobase.db')
    c=conn.cursor()
    c.execute('SELECT * FROM dino WHERE record = recNo')
    rows=c.fetchall()
    
    for row in rows:
        recBox.insert(0,row[0])
        eName.insert(0,row[1])
        eMeaning.insert(0,row[2])
        ePronounce.insert(0,row[3])
        ePeriod.insert(0,row[4])
        eGroup.insert(0,row[5])
        eSize.insert(0,row[6])
        eLived.insert(0,row[7])
        eDiet.insert(0,row[8])
        eFossils.insert(0,row[9])
        factFile.insert(1.0,row[10])
    
    c.close()
    conn.close()
Not the best way I guess.


RE: Global variable does not seem to be global. - ichabod801 - Jul-15-2019

You don't need all that complication. Pass it as a parameter, update it in the function, return the updated value, assign the function call back to the original variable.

def fetchRecord(recNo):
    ...
    recNo += 1
    ...
    return recNo

recNo = fetchRecord(recNo)



RE: Global variable does not seem to be global. - Columbo - Jul-15-2019

Thank you very much. Since my last post I was playing with it and I now have it working within the function as I needed it for my Next Record button.

What I did was to get the current record number that was in the record number entry box and save that into the variable x. Because it is a string I converted the string to an int y. Then used recNo = y + 1 and it seems to work ok. I just repeated the same thing but changed the recNo = y + 1 to recNo = y - 1 for the Previous Button.

def fetchRecord():
    x=recBox.get()
    y=int(x)
    recNo = y + 1

    ....
Thanks again for you help. Very much appreciated.


RE: Global variable does not seem to be global. - ichabod801 - Jul-15-2019

I don't think that works. That's creating a local variable named recNo with the value y + 1, but that doesn't update the global variable.


RE: Global variable does not seem to be global. - Columbo - Jul-15-2019

I didn't quite understand your example in that I saw that you incremented recNo and then returned it. At first look I was under the impression that it was returned right after it was incremented and that the rest of the function was not being executed. Having looked at it again, I think I now see what is actually happening. The recNo is incremented and after executing the rest of the function using the new value of recNo, then it is reutrned to update the global. I went back and changed my code to yours and it is working fine.

Thank you. I really do appreciate you help and your patience.