Python Forum

Full Version: trying to change variable value with a def
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hi, i am a newbie in python and am trying to make a gui to control how fast an LED blinks with a variable named "delay". i am using this code

from tkinter import *
from tkinter import ttk
import RPi.GPIO as GPIO
import time

root = Tk()

redLED = 26
GPIO.setmode(GPIO.BCM)
GPIO.setup(redLED, GPIO.OUT)


global delay
delay = .40
while True:
   GPIO.output(redLED, GPIO.HIGH)
   time.sleep(delay)
   GPIO.output(redLED, GPIO.LOW)
   time.sleep(delay)
   def Decrease_Time():
      delay -= .05

   def Increase_Time():
      delay += .05

   button_increse = ttk.Button(root, text = 'Increase', command = Increase_Time).pack()
   button_decrease = ttk.Button(root, text = 'Decrease', command = Decrease_Time).pack()

   root.mainloop()
but i get this error when i press the Increase or decrease buttons

Error:
UnboundLocalError: local variable 'delay' referenced before assignment
any help appreciated
remove line 13, it has no purpose and is the cause for error (delay is defined after declaring as global)
In general, globals are considered bad programming practice, and are rarely if ever needed.
(Mar-02-2020, 04:43 AM)Larz60+ Wrote: [ -> ]rarely if ever needed
I've been using Python since 2005. I've never needed a global. Same for the last six years, in which I've been programming professionally - I've never used one, and never seen one in code review. Occasionally I hear about Java-style globals (mutable state in a class) and those are always trouble.
The first rule of Python is never use globals.
The second rule of Python is never use globals.
...
but how am i going to be able to change the variable. i tried removing line 13, but when i press either one of the buttons, it gives me another error which is
Error:
[error]UnboundLocalError: local variable 'delay' referenced before assignment
[/error]

Is there any other way to do it.
Why are you declaring functions inside the loop (lines 20-24)? They only need to be declared once. They should also not be mutating some global state: have them take the value as a parameter and return the new value.
Nice that everyone agrees about not using globals, but this does not help "pythonbeginner". For the ttk.Button() uses a parameter "command", and the documentation states:
Quote:Python callable. Will be called with no arguments whenever either of the increment or decrement buttons are pressed.
.
So nothing with parameters or return values.
Apologies.

While I stand by my statement that globals should be avoided and the comments of others that there is usually (?always) a better way, I do not own a Raspberry Pi and therefore cannot test the code.

Therefore must work from observations of the code. Your functions Increase_Time and Decrease_time both access the value of delay. I do get accused of overusing classes, but here is an idea that avoids globals by creating a class, instantiating that class, and the class holds delay and the two functions, isolating delay from the global arena.

No raspberry pi yet, so no testing, but see if this works for you.
from tkinter import *
from tkinter import ttk
import RPi.GPIO as GPIO
import time
 
root = Tk()
class blinker :
    self.delay
    
    def __init__(self, dtime):
        self.delay = dtime
    def Decrease_Time():
        delay -= .05
 
    def Increase_Time():
        delay += .05

bc = blinker(0.4)
redLED = 26
GPIO.setmode(GPIO.BCM)
GPIO.setup(redLED, GPIO.OUT)

while True:
   GPIO.output(redLED, GPIO.HIGH)
   time.sleep(bc.delay)
   GPIO.output(redLED, GPIO.LOW)
   time.sleep(bc.delay)
 
   button_increse = ttk.Button(root, text = 'Increase', command = bc.Increase_Time).pack()
   button_decrease = ttk.Button(root, text = 'Decrease', command = bc.Decrease_Time).pack()
 
   root.mainloop()
Add - lines 13 and 16 should be self.delay += .05 or self.delay -= .05. Missed that scope error without testing
i am a very begginer in python so if you might know somewhere i might might be better bale to understand what a class is and what the def __init__(self, dtime): is that would be helpful.
Pages: 1 2