0

[enter image description here][1]I defined my label widget correctly at the top unsure why it's throwing the error that the lbl is defined in an enclosing scope. Can someone explain where is this enclosing scope and where I've gone wrong?

global lbl
lbl = tk.Label(tab1)

def display_each(value):
  ID = value
  # TO CHECK IF IT WORKS
  print(ID)
  if ID == 0:
    add = 0
  if ID == 1:
    add = 5
  if ID == 2:
    add = 6
  if ID == 3:
    add = 9
  c.execute(f'''
  SELECT * FROM Workout
  WHERE Program_Routine_ID = {ID}
  ''')
  x = c.fetchall()
  for i in range(len(x)):
    c.execute(f'''
    SELECT ID,Name,Equipment,Difficulty,Muscle FROM Exercise
    WHERE Workout_ID = {i+(ID+add)}
    ''')
    y = c.fetchall()
    print(f'{x[i][2].upper()} workout.{len(y)} exercises:')
    print()
    for j in range(len(y)):
      if y[j][2] == "None" or y[j][2] == "none":
        lbl.config(text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires no equipment. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}')
      else:
        lbl = tk.Label(tab1, text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires {y[j][2]}. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}')
    lbl.pack()
  #print(time.time()-time.time())
#display_each()
  • 1
    First of all, `if y[j][2] == "None" or "none":` should be `if y[j][2] == "None" or y[j][2] == "none":`, or `if y[j][2] in ("None", "none"):`. – Paul M. May 09 '23 at 16:09
  • Think about it this way: How is Python supposed to know if `lbl = ...` means "create a new variable named lbl and bind it to ..." or "take the existing variable lbl and rebind it to ..."? It doesn't know, because the syntax looks exactly identical, which is why you have to tell Python what your intention is. Since you want to rebind the already existing `lbl`, which is in global scope, your `display_each` function needs `global lbl`. – Paul M. May 09 '23 at 16:11
  • Sorry I forgot to include this from my code. So sorry. I had already made lbl a global variable, right at the top of my code, which accidentally got cut off while copy and pasting – Armaan Khaitan May 09 '23 at 21:49
  • @ArmaanKhaitan no, **no you did not**. `global some_var` *in the global scope* does **absolutely nothing**. It is just ignored (although, it should probably raise a SyntaxError, frankly) – juanpa.arrivillaga May 09 '23 at 22:13
  • @ArmaanKhaitan That's not the same thing. Notice, I said `global lbl` needs to be inside the `display_each` function. – Paul M. May 09 '23 at 22:51
  • I finally understood and it was fixed. Thanx guys – Armaan Khaitan May 19 '23 at 15:06

1 Answers1

0

Consider the first step in your for loop:

for j in range(len(y)):
      if y[j][2] == "None" or "none":
        lbl.config(text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires no equipment. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}')
      else:
        lbl = tk.Label(tab1, text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires {y[j][2]}. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}')
    lbl.pack()

If your first condition is satisfied at j = 0, lbl is never defined, hence the error. The trick is that it will be satisfied because of this bit:

if y... == "None" or "none"

This will always be true because it should be if y[j][2] == "None" or y[j][2] == "none".

To demonstrate:

x = False

if x == True or "true":
    print("Bad Result")

Bad Result


if "true":
    print("caught it")

caught it


## to fix
if x == True or x == "True":
    print("Shouldn't print")
else:
    print("Does print")

Does print
C.Nivs
  • 12,353
  • 2
  • 19
  • 44