Python Forum
trying to change variable value with a def - 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: trying to change variable value with a def (/thread-24736.html)

Pages: 1 2


trying to change variable value with a def - pythonbegginer - Mar-02-2020

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


RE: trying to change variable value with a def - Larz60+ - Mar-02-2020

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.


RE: trying to change variable value with a def - micseydel - Mar-02-2020

(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.


RE: trying to change variable value with a def - jefsummers - Mar-03-2020

The first rule of Python is never use globals.
The second rule of Python is never use globals.
...


RE: trying to change variable value with a def - pythonbegginer - Mar-04-2020

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.


RE: trying to change variable value with a def - ndc85430 - Mar-04-2020

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.


RE: trying to change variable value with a def - ibreeden - Mar-04-2020

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.


RE: trying to change variable value with a def - jefsummers - Mar-04-2020

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()



RE: trying to change variable value with a def - jefsummers - Mar-04-2020

Add - lines 13 and 16 should be self.delay += .05 or self.delay -= .05. Missed that scope error without testing


RE: trying to change variable value with a def - pythonbegginer - Mar-04-2020

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.