Variablennamen aus einer Loop aufrufen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Hallo Leute,
ich bin recht neu in der python-Programmierung. Da ich zu meinem Problem nicht in die richtigen Stichworte finde, hilft mir die Suche nicht weiter.

Ich habe mit tkinter mir eine Benutzeroberfläche geschaffen. Darauf habe ich etliche Label und Schaltflächen plaziert. Das funktioniert alles. Mein Problem ist folgendes: Ich möchte z.B. an 20 Label die Hintergrundfarbe bei einem Ereignis ändern. Jetzt könnte ich natürlich im Code 20 mal die Abfrage programmieren, ob dieses Ereignis vorliegt, und dann entsprechend die Farbe zu zuweisen.

Bei der Namensgebung habe ich die Position im Raster verwendet.
Ein Beispiel für zwei Label:
self.label_2B['bg'] = 'green'
self.label_3B['bg'] = 'green'

Meine Idee, an der ich scheitere: Ich habe ein Array erstellt, welches den variablen Bestandteil der Namen enthällt.
Pos = [_2B,_3B,_4B, , , u.s.w]

Jetzt möchte ich in einer Loop einfach den Namen "self.label" mit dem entsprechenden Wert aus dem Array "_2B" und der Farbzuordnung ['bg'] = 'green' zusammensetzen. Also im Prinzip so:

'self.label'+(loop)+'['bg'] = 'green''

Ich würde hier nicht schreiben, wenn's gehen würde :lol:

Ich hoffe, ich konnte mein Problem ausreichend schildern, und mir jemand einen guten Rat geben kann.
Vielen Dank an alle, die bis hierher gelesen haben,
Der RaPi_Fan
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt lange und breit Deinen Code zu umschreiben, poste ihn doch einfach am Stück.
Statt Informationen im Variablennamen zu kodieren, benutzt man Listen oder Wörterbücher. Hier würde ich Listen vorschlagen, weil 2B oder 3B nicht wirklich mehr Informationen als einen Index enthält.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Danke für die Antwort Sirius3.
Mein Code hat 650 Zeilen und ist ein Zusammengebastel aus vielen Schnipseln, die ich gefunden habe. Da ist sicherlich noch viel Potenzial zur Verbesserung. Den kompletten Code zu posten hätte es auch nicht übersichtlicher gemacht. Desshalb habe ich versucht mein Problem zu beschreiben. Mein Code funktioniert und macht genau das, was ich erreichen wollte. Ich möchte durch meine Frage lernen, wie ich Definitionen erstellen, und Änderungen in Gruppen von Variablen einfacher gestallten kann. Kannst du mir ein Beispiel posten, wie du mit Listen mein Problem lösen würdest?
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

650 Zeilen Code, werden das Forum nicht sprengen. Und sie sind ein Anzeichen dafür, dass wahrscheinlich etwas nicht stimmt.

Wenn du anfängst Dinge durchzunummerieren, dann willst du sie eigentlich in eine Liste stecken. Denn ob du nun name1, name2, ... schreibst oder namen[1], namen[2] macht keinen Unterschied, ABER(!!!!) du kannst Dinge in einer Liste einfach in einr Schleife abarbeiten. Wenn du, wie du schreibst, 20 Laben definierst und die anhand des Namens identifizierst, gehören die in eine Liste - was deinen Code schon alleine bei der Definition um ~18 Zeilen verkürzt. Ebenso bei dem Zugriff darauf.

Wenn du wirkich lernen willst, poste deinen Code und hör dir die Verbesserungen an. Funktionieren wird dein Code auch nach den Verbesserungen noch.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Ich gebe dir Recht, dass der Fehler schon bei der Erstellung der Namen passiert ist. Wahrscheinlich hätte ich auch es auch wie du es beschreibst gemacht, wenn ich die Dinge nicht zusammenkopiert hätte. Da ich mit Python erst beginne, kann ich auch nicht einschätzen, ob gewisse Namensbestandteile vorgegeben sind, bzw. zu Klassen/Definitionen etc. passen müssen. Ich bin in VBA und Fortran zuhause, da habe ich diese Probleme nicht. Wenn ich den kompletten Code poste, fürchte ich, dass (zurecht) so viel Kritik auf mich einprasselt, dass ich mit den sicherlich richtigen Ratschlägen überfordert bin.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und ihn nicht zu posten, und keine Ratschläge zu bekommen, ist irgendwie hilfreicher? Man kann dir nun mal nicht helfen bei Umschreibungen.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Ich hatte ja gehofft, dass es eine Möglichkeit gibt, die Variablen aus zusammengebauten Strings aufzurufen.
Da ich in den nächsten 14 Tagen am Projekt nicht weiter arbeiten kann, mache ich hier eine Pause und melde mich später wieder.

Danke für eure Beiträge.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Wie gesagt: Das ist das falsche Vorgehen. Dafür benutzt man in Python Datenstrukturen und wie Listen oder dicts.
Aber da du deinen Code ja geheim hälst, kann man dir auch nicht helfen.
Es ist wie so oft: dein eigentliches Problem ist, dass du etwas für die Lösung für ein Problem hälst, das aber gar nicht die Lösung ist. Und solange du damit hinterm Berg hälst, wirst du dein grundlegendes Problem nicht lösen können. 💁‍♂️
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Ich melde mich in 14 Tagen mit dem Code wieder, versprochen.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Wie versprochen bin ich wieder da und habe Zeit um mich um mein Projekt zu kümmern.
Ich möchte erläutern, wie es zu meinem Progamm kam und was ich erreichen will. Ich möchte eine Steuerung bauen, bei der viele Temperaturen erfasst und einige In- und Outputs benötigt werden. Da ich in Python absoluter Neuling bin, habe ich mir Codeschnipsel zusammenkopiert und zum Laufen bekommen. Ziel war es eine GUI zu schaffen, wo ich einigermaßen aufgeräumt Dinge platzieren kann, viele Temp-Sensoren abgefragt werden, analoge und digitale Inputs eingehen, und über Relais Geräte gesteuert werden können. Um die Hardware zu testen (die zur Zeit nur auf dem Steckboard existiert) ist dieses Programm entstanden. Es kann also nichts, außer das Interface abzufragen und zu steuern. Der einzig aktive Teil (wo ich später das laufende Programm plazieren würde) ist die blinkende Anzeige, die auf das laufende Programm hinweist.

Code: Alles auswählen


import tkinter as GUI
from queue import Queue
from threading import Thread, Event
from time import sleep
import time#, sys


import gpiozero 
from gpiozero import MCP3008
#from gpiozero import LED
#from gpiozero import Button
Poti_1 = MCP3008(0)
Poti_2 = MCP3008(1)
Poti_3 = MCP3008(2)
Poti_4 = MCP3008(3)
Poti_5 = MCP3008(4)
Poti_6 = MCP3008(5)
Poti_7 = MCP3008(6)
Poti_8 = MCP3008(7)

DI_1 = gpiozero.Button(25)
DI_2 = gpiozero.Button(12)
DI_3 = gpiozero.Button(16)
DI_4 = gpiozero.Button(26)
DI_5 = gpiozero.Button(20)
DI_6 = gpiozero.Button(21)

Relay_1 = gpiozero.LED(17)
Relay_2 = gpiozero.LED(18)
Relay_3 = gpiozero.LED(27)
Relay_4 = gpiozero.LED(22)
Relay_5 = gpiozero.LED(5)
Relay_6 = gpiozero.LED(6)
Relay_7 = gpiozero.LED(13)
Relay_8 = gpiozero.LED(19)

# default Werte setzen
Relay_1.on()
sleep(0.1)
Relay_2.on()
sleep(0.1)
Relay_3.on()
sleep(0.1)
Relay_4.on()
sleep(0.1)
Relay_5.on()
sleep(0.1)
Relay_6.on()
sleep(0.1)
Relay_7.on()
sleep(0.1)
Relay_8.on()
sleep(0.1)

Restzeit= 0
ConsoleAnzeige = 0
BlinkAnzeige = 0
tempMax = 50.0
maxPosition = 0
FirstPath = 1

# Sensor Seriennummern zuweisen
Tempsensor = [22,# Anzahl der Sensoren
                '/sys/bus/w1/devices/28-01143b9758aa/w1_slave', #sensor1 1m
                '/sys/bus/w1/devices/28-01143bd16eaa/w1_slave', #sensor2 1m
                '/sys/bus/w1/devices/28-01143e1a7baa/w1_slave', #sensor3
                '/sys/bus/w1/devices/28-01143e2e31aa/w1_slave', #sensor4
                '/sys/bus/w1/devices/28-01143d695baa/w1_slave', #sensor5
                '/sys/bus/w1/devices/28-01143e2445aa/w1_slave', #sensor6
                '/sys/bus/w1/devices/28-01143e2e63aa/w1_slave', #sensor7
                '/sys/bus/w1/devices/28-01143c5be8aa/w1_slave', #sensor8
                '/sys/bus/w1/devices/28-01143c6cc7aa/w1_slave', #sensor9
                '/sys/bus/w1/devices/28-01143c5988aa/w1_slave', #sensor10
                '/sys/bus/w1/devices/28-01143c6784aa/w1_slave', #sensor11
                '/sys/bus/w1/devices/28-01143fa67daa/w1_slave', #sensor12
                '/sys/bus/w1/devices/28-012112587e4f/w1_slave', #sensor13
                '/sys/bus/w1/devices/28-01211265ff52/w1_slave', #sensor14
                '/sys/bus/w1/devices/28-0121125ff38a/w1_slave', #sensor15
                '/sys/bus/w1/devices/28-0121126b3fd2/w1_slave', #sensor16
                '/sys/bus/w1/devices/28-0121122f9105/w1_slave', #sensor17
                '/sys/bus/w1/devices/28-012112616893/w1_slave', #sensor18
                '/sys/bus/w1/devices/28-0121126f7458/w1_slave', #sensor19
                '/sys/bus/w1/devices/28-0121124dcddb/w1_slave', #sensor20
                '/sys/bus/w1/devices/28-012112650020/w1_slave', #sensor21
                '/sys/bus/w1/devices/28-012112722655/w1_slave', #sensor22
                ]

# Array Temp deklarieren
Temp = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
#LabelPos= [_0,_2B,_3B,_4B,_5B,_6B,_7B,_8B,_9B,_10B,_11B,_12B,_2C,_3C,_4C,_5C,_6C,_7C,_8C,_9C,_10C,_11C,_12C]
#tempalle = 0.0
#tempdurch = 0.0

# Temperatur der DS18B20 aus dem Systembus lesen
def readTempSensor(sensorName) :
    f = open(sensorName, 'r')
    lines = f.readlines()
    f.close()
    return lines
# Endlosschleife bis alle Daten gelesen werden konnten
def readTempLines(sensorName) :
    lines = readTempSensor(sensorName)
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = readTempSensor(sensorName[1])
    temperaturStr = lines[1].find('t=')
    # Ich überprüfe ob die Temperatur gefunden wurde.
    if temperaturStr != -1 :
        tempData = lines[1][temperaturStr+2:]
        tempCelsius = float(tempData) / 1000.0
        # Rückgabe als Array - [0] tempCelsius
        return [tempCelsius]

# Programm ausserhalb der Temperaturmessung
def blinken(): 
    global BlinkAnzeige    
    if BlinkAnzeige == 1:
        BlinkAnzeige = 0
    else:
        BlinkAnzeige = 1                         
# 
#
def einlesen():
    tempalle=0.0
    for loop in range(1,Tempsensor[0]+1):                                     #Werte in Temp[] einlesen
        Temp[loop] = (readTempLines(Tempsensor [loop])[0])
        tempalle = tempalle+ Temp[loop]
#
    tempdurch = tempalle / Tempsensor[0]
    Temp[0]= tempdurch
#   
def ausgabeConsole():
    global tempMax
    global maxPosition
    global timeold    
    tempdurch = Temp[0]
    timeold = timeold - 30
    tempMax = 0.0
#
    print("Durchschnitt: " + "%7.3f"% (tempdurch))
    print("Zeit: " + time.strftime('%H:%M:%S'))
    print("Sensor    Wert           Abweichung")
#
    for loop in range(1,Tempsensor[0]+1):
        print("Sensor " + str(loop) + ": " + "%7.3f"% (Temp[loop]) + "   -   " + "%7.3f"% (Temp[loop]-tempdurch))
        if (Temp[loop]) > tempMax:
            tempMax = (Temp[loop])
            maxPosition = loop
    time.sleep(1)
    print("-------------------------------------------")
    
#
def generate_data(my_queue, event):
    global timeold
    timeold = 0.0
    global Restzeit
    while not event.is_set():
        data ={}
        data['value_sensor_3'] = Poti_1.value
        data['value_sensor_4'] = Poti_2.value
        my_queue.put(data)        
        sleep(0.7)
            
        if time.time() > timeold +180:         # nur alle 180 sec Sensoren abfragen
            timeold = time.time()                    
            einlesen()
 
        Restzeit= (timeold - time.time() +180)            
        p1 = Poti_1.value * 100
        p2 = Poti_2.value * 100
        
        blinken()  
        
        if ConsoleAnzeige == 1:
            print("Zeit bis Aktualisierung: " + "%4.0f"% ((timeold - time.time()) +180) + " Sekunden")
            print ("Anzahl der Sensoren: " + "%4.0f"% Tempsensor[0])
            print("Analog Input = Ch1:" +"%4.0f"% p1 + " %  --  Ch2:" + "%4.0f"% p2 + " %") 
            ausgabeConsole()             

class Application(GUI.Frame):
    
    def __init__(self, my_queue, thread_kill_event, master=None):
        super().__init__(master)
        self.my_queue = my_queue        
        self.thread_kill_event = thread_kill_event
        self.grid()
        if FirstPath == 1:
            self.create_widgets()
            
        self.update_labels()

    def create_widgets(self):
        global FirstPath
        # Rahmen definieren
        self._1A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._1B = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1C = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1D = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1E = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1F = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1G = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1H = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1I = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._1J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        
        self._10A = GUI.Label(self, bg='red', height=2, width=2, text='')
        self._10B = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10C = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10D = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10E = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10F = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10G = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10H = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10I = GUI.Label(self, bg='grey', height=2, width=20, text='')
        self._10J = GUI.Label(self, bg='red', height=2, width=2, text='')  
           
        self._2A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._3A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._4A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._5A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._6A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._7A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._8A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._9A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._10A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._11A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._12A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._13A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._14A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._15A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._16A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._17A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._18A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._19A = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._20A = GUI.Label(self, bg='grey', height=3, width=2, text='')
        self._21A = GUI.Label(self, bg='grey', height=3, width=2, text='')
        self._22A = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._23A = GUI.Label(self, bg='grey', height=2, width=2, text='')

        self._2J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._3J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._4J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._5J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._6J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._7J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._8J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._9J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._10J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._11J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._12J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._13J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._14J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._15J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._16J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._17J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._18J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._19J = GUI.Label(self, bg='grey', height=2, width=2, text='')        
        self._20J = GUI.Label(self, bg='grey', height=3, width=2, text='')
        self._21J = GUI.Label(self, bg='grey', height=3, width=2, text='')
        self._22J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        self._23J = GUI.Label(self, bg='grey', height=2, width=2, text='')
        
        self._1A.grid(row=0,column=0)        
        self._1B.grid(row=0,column=1)
        self._1C.grid(row=0,column=2)       
        self._1D.grid(row=0,column=3)        
        self._1E.grid(row=0,column=4)
        self._1F.grid(row=0,column=5)
        self._1G.grid(row=0,column=6)       
        self._1H.grid(row=0,column=7)        
        self._1I.grid(row=0,column=8)
        self._1J.grid(row=0,column=9)       
                
        self._10A.grid(row=22,column=0)        
        self._10B.grid(row=22,column=1)
        self._10C.grid(row=22,column=2)       
        self._10D.grid(row=22,column=3)        
        self._10E.grid(row=22,column=4)
        self._10F.grid(row=22,column=5)
        self._10G.grid(row=22,column=6)       
        self._10H.grid(row=22,column=7)        
        self._10I.grid(row=22,column=8)
        self._10J.grid(row=22,column=9)
        
        self._2A.grid(row=1,column=0)        
        self._3A.grid(row=2,column=0)        
        self._4A.grid(row=3,column=0)
        self._5A.grid(row=4,column=0)
        self._6A.grid(row=5,column=0)        
        self._7A.grid(row=6,column=0)        
        self._8A.grid(row=7,column=0)
        self._9A.grid(row=8,column=0)        
        self._10A.grid(row=9,column=0)        
        self._11A.grid(row=10,column=0)        
        self._12A.grid(row=11,column=0)
        self._13A.grid(row=12,column=0)
        self._14A.grid(row=13,column=0)        
        self._15A.grid(row=14,column=0)        
        self._16A.grid(row=15,column=0)
        self._17A.grid(row=16,column=0)                
        self._18A.grid(row=17,column=0)        
        self._19A.grid(row=18,column=0)        
        self._20A.grid(row=19,column=0)
        self._21A.grid(row=20,column=0)
        self._22A.grid(row=21,column=0)
        self._23A.grid(row=22,column=0)

        self._2J.grid(row=1,column=9)        
        self._3J.grid(row=2,column=9)        
        self._4J.grid(row=3,column=9)
        self._5J.grid(row=4,column=9)
        self._6J.grid(row=5,column=9)        
        self._7J.grid(row=6,column=9)        
        self._8J.grid(row=7,column=9)
        self._9J.grid(row=8,column=9)        
        self._10J.grid(row=9,column=9)        
        self._11J.grid(row=10,column=9)        
        self._12J.grid(row=11,column=9)
        self._13J.grid(row=12,column=9)
        self._14J.grid(row=13,column=9)        
        self._15J.grid(row=14,column=9)        
        self._16J.grid(row=15,column=9)
        self._17J.grid(row=16,column=9)                
        self._18J.grid(row=17,column=9)        
        self._19J.grid(row=18,column=9)        
        self._20J.grid(row=19,column=9)
        self._21J.grid(row=20,column=9)
        self._22J.grid(row=21,column=9)
        self._23J.grid(row=22,column=9)
        
        #Temp Sensoren
        self.label_1B = GUI.Label(self, bg='yellow', height=1, width=16, text='TempSensoren')
        self.label_1B.grid(row=0,column=1)
        self.label_2B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_2B.grid(row=1,column=1)       
        self.label_3B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_3B.grid(row=2,column=1)
        self.label_4B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_4B.grid(row=3,column=1)       
        self.label_5B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_5B.grid(row=4,column=1)
        self.label_6B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_6B.grid(row=5,column=1)       
        self.label_7B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_7B.grid(row=6,column=1)
        self.label_8B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_8B.grid(row=7,column=1)       
        self.label_9B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_9B.grid(row=8,column=1)        
        self.label_10B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_10B.grid(row=9,column=1)       
        self.label_11B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_11B.grid(row=10,column=1)
        self.label_12B = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_12B.grid(row=11,column=1)
        
        self.label_1C = GUI.Label(self, bg='yellow', height=1, width=16, text='TempSensoren')
        self.label_1C.grid(row=0,column=2)
        self.label_2C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_2C.grid(row=1,column=2)
        self.label_3C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_3C.grid(row=2,column=2)       
        self.label_4C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_4C.grid(row=3,column=2)
        self.label_5C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_5C.grid(row=4,column=2)       
        self.label_6C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_6C.grid(row=5,column=2)         
        self.label_7C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_7C.grid(row=6,column=2)
        self.label_8C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_8C.grid(row=7,column=2)       
        self.label_9C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_9C.grid(row=8,column=2)
        self.label_10C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_10C.grid(row=9,column=2)       
        self.label_11C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_11C.grid(row=10,column=2)
        self.label_12C = GUI.Label(self, bg='grey', height=2, width=16, text='Sensor')
        self.label_12C.grid(row=11,column=2)        
        
        #Analog in
        self.label_1D = GUI.Label(self, bg='yellow', height=1, width=16, text='Analog Input')
        self.label_1D.grid(row=0,column=3)
        self.label_2D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_2D.grid(row=1,column=3)
        self.label_3D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_3D.grid(row=2,column=3)
        self.label_4D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_4D.grid(row=3,column=3)
        self.label_5D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_5D.grid(row=4,column=3)
        self.label_6D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_6D.grid(row=5,column=3)
        self.label_7D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_7D.grid(row=6,column=3)
        self.label_8D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_8D.grid(row=7,column=3)
        self.label_9D = GUI.Label(self, bg='grey', height=2, width=16, text='Poti')
        self.label_9D.grid(row=8,column=3)       
        
        #Digital in
        self.label_1E = GUI.Label(self, bg='yellow', height=1, width=16, text='Digital Input')
        self.label_1E.grid(row=0,column=4)
        self.label_2E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_2E.grid(row=1,column=4)        
        self.label_3E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_3E.grid(row=2,column=4)
        self.label_4E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_4E.grid(row=3,column=4)
        self.label_5E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_5E.grid(row=4,column=4)
        self.label_6E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_6E.grid(row=5,column=4)
        self.label_7E = GUI.Label(self, bg='grey', height=2, width=16, text='DI')
        self.label_7E.grid(row=6,column=4) 
  
        #Relays
        self.label_1F = GUI.Label(self, bg='yellow', height=1, width=16, text='Relay Outputs')
        self.label_1F.grid(row=0,column=5)
        self.out_1 = GUI.Button(self, text='       Relay 1       ', fg='black',  command=self.Relays1)
        self.out_1.grid(row =1,column=5)
        self.out_2 = GUI.Button(self, text='       Relay 2       ', fg='black',  command=self.Relays2)
        self.out_2.grid(row =2,column=5)
        self.out_3 = GUI.Button(self, text='       Relay 3       ', fg='black',  command=self.Relays3)
        self.out_3.grid(row =3,column=5)
        self.out_4 = GUI.Button(self, text='       Relay 4       ', fg='black',  command=self.Relays4)
        self.out_4.grid(row =4,column=5)
        self.out_5 = GUI.Button(self, text='       Relay 5       ', fg='black',  command=self.Relays5)
        self.out_5.grid(row =5,column=5)
        self.out_6 = GUI.Button(self, text='       Relay 6       ', fg='black',  command=self.Relays6)
        self.out_6.grid(row =6,column=5)
        self.out_7 = GUI.Button(self, text='       Relay 7       ', fg='black',  command=self.Relays7)
        self.out_7.grid(row =7,column=5)
        self.out_8 = GUI.Button(self, text='       Relay 8       ', fg='black',  command=self.Relays8)
        self.out_8.grid(row =8,column=5)

        #Misc
        self.label_1H = GUI.Label(self, bg='yellow', height=1, width=16, text='Status')
        self.label_1H.grid(row=0,column=8)
        
        self.quit = GUI.Button(self, text='         QUIT         ', fg='white', bg='red', command=self.exit_cleanup) 
        self.quit.grid(row=20,column=8, sticky='s')
        
        self.knopf2 = GUI.Button(self, text=' Max Temp Wert ' + "\n" + ' + Console ', fg='red', command=self.console)
        self.knopf2.grid(row=20,column=1, sticky='n')
        
        self.knopf3 = GUI.Button(self, text='   aktualisieren   ', fg='blue',  command=self.aktualisieren)        
        self.knopf3.grid(row=20,column=2,sticky='n')
         
        self.label_14B = GUI.Label(self, bg='grey', height=2, width=16, text='Durchschnitt')
        self.label_14B.grid(row=13,column=1)        
        
        FirstPath = 0
        
    def update_labels(self):
        global tempMax
        self.master.after(500, self.update_labels)
        if not self.my_queue.empty():
            data = self.my_queue.get()
  
            self.label_2B['text'] = "No 01 = " + "%7.3f"% (Temp[1])
            self.label_3B['text'] = "No 02 = " + "%7.3f"% (Temp[2])
            self.label_4B['text'] = "No 03 = " + "%7.3f"% (Temp[3])
            self.label_5B['text'] = "No 04 = " + "%7.3f"% (Temp[4])
            self.label_6B['text'] = "No 05 = " + "%7.3f"% (Temp[5])
            self.label_7B['text'] = "No 06 = " + "%7.3f"% (Temp[6])
            self.label_8B['text'] = "No 07 = " + "%7.3f"% (Temp[7])
            self.label_9B['text'] = "No 08 = " + "%7.3f"% (Temp[8])           
            self.label_10B['text'] = "No 09 = " + "%7.3f"% (Temp[9])
            self.label_11B['text'] = "No 10 = " + "%7.3f"% (Temp[10])
            self.label_12B['text'] = "No 11 = " + "%7.3f"% (Temp[11])
            self.label_2C['text'] = "No 12 = " + "%7.3f"% (Temp[12])
            self.label_3C['text'] = "No 13 = " + "%7.3f"% (Temp[13])
            self.label_4C['text'] = "No 14 = " + "%7.3f"% (Temp[14])
            self.label_5C['text'] = "No 15 = " + "%7.3f"% (Temp[15])
            self.label_6C['text'] = "No 16 = " + "%7.3f"% (Temp[16])            
            self.label_7C['text'] = "No 17 = " + "%7.3f"% (Temp[17])
            self.label_8C['text'] = "No 18 = " + "%7.3f"% (Temp[18])
            self.label_9C['text'] = "No 19 = " + "%7.3f"% (Temp[19])
            self.label_10C['text'] = "No 20 = " + "%7.3f"% (Temp[20])
            self.label_11C['text'] = "No 21 = " + "%7.3f"% (Temp[21])
            self.label_12C['text'] = "No 22 = " + "%7.3f"% (Temp[22])
            self.label_14B['text'] = "Mittelwert = " + "%7.3f"% (Temp[0])
                        
            self.label_2B['bg'] = 'red' if tempMax == Temp[1] else 'grey'
            self.label_3B['bg'] = 'red' if tempMax == Temp[2] else 'grey'
            self.label_4B['bg'] = 'red' if tempMax == Temp[3] else 'grey'
            self.label_5B['bg'] = 'red' if tempMax == Temp[4] else 'grey'        
            self.label_6B['bg'] = 'red' if tempMax == Temp[5] else 'grey'
            self.label_7B['bg'] = 'red' if tempMax == Temp[6] else 'grey'
            self.label_8B['bg'] = 'red' if tempMax == Temp[7] else 'grey'
            self.label_9B['bg'] = 'red' if tempMax == Temp[8] else 'grey'           
            self.label_10B['bg'] = 'red' if tempMax == Temp[9] else 'grey'
            self.label_11B['bg'] = 'red' if tempMax == Temp[10] else 'grey'
            self.label_12B['bg'] = 'red' if tempMax == Temp[11] else 'grey'
            self.label_2C['bg'] = 'red' if tempMax == Temp[12] else 'grey'        
            self.label_3C['bg'] = 'red' if tempMax == Temp[13] else 'grey'
            self.label_4C['bg'] = 'red' if tempMax == Temp[14] else 'grey'
            self.label_5C['bg'] = 'red' if tempMax == Temp[15] else 'grey'
            self.label_6C['bg'] = 'red' if tempMax == Temp[16] else 'grey'
            self.label_7C['bg'] = 'red' if tempMax == Temp[17] else 'grey'
            self.label_8C['bg'] = 'red' if tempMax == Temp[18] else 'grey'
            self.label_9C['bg'] = 'red' if tempMax == Temp[19] else 'grey'
            self.label_10C['bg'] = 'red' if tempMax == Temp[20] else 'grey'        
            self.label_11C['bg'] = 'red' if tempMax == Temp[21] else 'grey'
            self.label_12C['bg'] = 'red' if tempMax == Temp[22] else 'grey'
            
            
            self.label_2D['text'] = "Poti 1 = ""%3.0f"%(Poti_1.value *100)
            self.label_3D['text'] = "Poti 2 = ""%3.0f"%(Poti_2.value *100)
            self.label_4D['text'] = "Poti 3 = ""%3.0f"%(Poti_3.value *100)
            self.label_5D['text'] = "Poti 4 = ""%3.0f"%(Poti_4.value *100)
            self.label_6D['text'] = "Poti 5 = ""%3.0f"%(Poti_5.value *100)
            self.label_7D['text'] = "Poti 6 = ""%3.0f"%(Poti_6.value *100)
            self.label_8D['text'] = "Poti 7 = ""%3.0f"%(Poti_7.value *100)
            self.label_9D['text'] = "Poti 8 = ""%3.0f"%(Poti_8.value *100)
            
            self.knopf3['text'] = "Restzeit: " + "%4.0f"%(Restzeit) + " sec" + "\n" + "> aktualisieren <" 
                       
           
            if DI_1.is_held:
                self.label_2E['text'] = ' TRUE '
                self.label_2E['bg'] = 'green'
            else:
                self.label_2E['text'] = 'Input 1'
                self.label_2E['bg'] = 'grey'
                
            if DI_2.is_held:
                self.label_3E['text'] = ' TRUE '
                self.label_3E['bg'] = 'green'
            else:
                self.label_3E['text'] = 'Input 2'
                self.label_3E['bg'] = 'grey'
                
            if DI_3.is_held:
                self.label_4E['text'] = ' TRUE '
                self.label_4E['bg'] = 'green'
            else:
                self.label_4E['text'] = 'Input 3'
                self.label_4E['bg'] = 'grey'
                
            if DI_4.is_held:
                self.label_5E['text'] = ' TRUE '
                self.label_5E['bg'] = 'green'
            else:
                self.label_5E['text'] = 'Input 4'
                self.label_5E['bg'] = 'grey'
                
            if DI_5.is_held:
                self.label_6E['text'] = ' TRUE '
                self.label_6E['bg'] = 'green'
            else:
                self.label_6E['text'] = 'Input 5'
                self.label_6E['bg'] = 'grey'
                
            if DI_6.is_held:
                self.label_7E['text'] = ' TRUE '
                self.label_7E['bg'] = 'green'
            else:
                self.label_7E['text'] = 'Input 6'
                self.label_7E['bg'] = 'grey'
                
            self.out_1['text'] =' Relay 1  on       ' if Relay_1.value ==0 else ' Relay 1        off '
            self.out_2['text'] =' Relay 2  on       ' if Relay_2.value ==0 else ' Relay 2        off '                
            self.out_3['text'] =' Relay 3  on       ' if Relay_3.value ==0 else ' Relay 3        off '
            self.out_4['text'] =' Relay 4  on       ' if Relay_4.value ==0 else ' Relay 4        off '
            self.out_5['text'] =' Relay 5  on       ' if Relay_5.value ==0 else ' Relay 5        off '
            self.out_6['text'] =' Relay 6  on       ' if Relay_6.value ==0 else ' Relay 6        off '
            self.out_7['text'] =' Relay 7  on       ' if Relay_7.value ==0 else ' Relay 7        off '
            self.out_8['text'] =' Relay 8  on       ' if Relay_8.value ==0 else ' Relay 8        off '            
            
           
            if BlinkAnzeige ==1:        
                self.label_1H['text'] = ' working '
                self.label_1H['fg'] = 'green' 
            else:
                self.label_1H['text'] = ' dreaming '
                self.label_1H['fg'] = 'orange' 
        

    def exit_cleanup(self):
        self.thread_kill_event.set()
        self.master.destroy()
        
    def mach_was(self):
        if  led11.value ==0:
            led11.on()
        else:
            led11.off()
            
    def console(self):
        global ConsoleAnzeige
        global tempMax
        if ConsoleAnzeige == 0:
            ConsoleAnzeige = 1
            self.knopf2['fg'] ='green'
        else:
            ConsoleAnzeige = 0
            self.knopf2['fg'] ='red'
            tempMax = 50.0
            
    def aktualisieren(self):
        global Restzeit
        global timeold
        timeold = 0.0
        timeold = time.time()
        einlesen()
        Restzeit= (timeold - time.time() +180)
        
    def Relays1(self):    
        Relay_1.on() if Relay_1.value ==0 else Relay_1.off()

    def Relays2(self):
        Relay_2.on() if Relay_2.value ==0 else Relay_2.off()
          
    def Relays3(self):    
        Relay_3.on() if Relay_3.value ==0 else Relay_3.off()

    def Relays4(self):
        Relay_4.on() if Relay_4.value ==0 else Relay_4.off()
           
    def Relays5(self):    
        Relay_5.on() if Relay_5.value ==0 else Relay_5.off()
        
    def Relays6(self):
        Relay_6.on() if Relay_6.value ==0 else Relay_6.off()
           
    def Relays7(self):    
        Relay_7.on() if Relay_7.value ==0 else Relay_7.off()

    def Relays8(self):
        Relay_8.on() if Relay_8.value ==0 else Relay_8.off()
           
def main():
    my_queue = Queue()
    my_event = Event()
    my_thread = Thread(target=generate_data, args=(my_queue, my_event, ))
    my_thread.start()

    root = GUI.Tk()
    app = Application(my_queue, my_event, master=root)
    app.master.title('GUI')
    app.mainloop()
    #root.grid_rowconfigure(0, weight=1)
if __name__ == '__main__':
    main()
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

@Rapi_Fan: Du wirst nicht drum herum kommen, dich intensiver mit Klassen und Objektorientier Programmierung zu beschäftigen. Jedes nicht triviales Programm mit einer GUI wird da nicht drum herum kommen. Solange du globale Variablen verwendest, ist dein Programm faktisch hoch fehleranfällig und kaum zu debuggen. Da musst du dran.
Insbesondere weil du Threads und globale Variablen verwendest. Das ist ein absolutes no-go.

Du solltest dich an die Namenskonvetionen haltet. namen werden klein_mit_unterstrich geschrieben. Konstanten KOMPLETT_GROSS, die Namen von Klassen (nicht die Namen der Instanzen!) PascalCase. Dann ist jedem Leser (auch dir) klar, worum es sich handelt.

Auf die Modulebene (also ohne Einrückung) gehört gar kein Code. In der Regel sieht das Grundgerüst eines Python-Programms so aus:

Code: Alles auswählen

def main():
    pass

if __name__ == "__main__":
    main()
Wobei in der Funktion "main" dann der quasi der Startpunkt des Programms ist.
Auf Modulebene (also ohne Einrückung) stehen dann nur Importe, Konstanten (die heißen Konstanten, weil sie sich nie ändern) und die Definition von Funktionen und Klassen. Der Rest des Codes gehört in Funktionen. Auf diese Weise wirst du gleich die globalen Variablen los.

Ansonsten ist es genau wie hier in dem Thread bereits erklärt: Wenn du anfängst Variablen zu nummerieren, willst du eigentlich eine Datenstruktur verwenden. Damit schmilzt dein Code automatisch auf einene Bruchteil seiner Länge zusammen. Dafür hat man in der Programmierung Schleifen erfunden.

Ich weiß nicht was ein Poti ist (meine Nichte sagt das zum Klo), aber das würde am Anfang so aussehen:

Code: Alles auswählen

# Falsch
Poti_1 = MCP3008(0)
Poti_2 = MCP3008(1)
Poti_3 = MCP3008(2)
Poti_4 = MCP3008(3)
Poti_5 = MCP3008(4)
Poti_6 = MCP3008(5)
Poti_7 = MCP3008(6)
Poti_8 = MCP3008(7)

# Besser
potis = [MSCP3008(i) for i in range(8)]
Wobei ich nicht sehe, dass Potis global sein muss. Das muss in die Klasse (d

Ich überspringe die DIs, weil ich nicht weiß, was DIs sind. Bisschen schwierig dide Namensgebung.

Code: Alles auswählen

# Falsch
Relay_1 = gpiozero.LED(17)
Relay_2 = gpiozero.LED(18)
Relay_3 = gpiozero.LED(27)
Relay_4 = gpiozero.LED(22)
Relay_5 = gpiozero.LED(5)
Relay_6 = gpiozero.LED(6)
Relay_7 = gpiozero.LED(13)
Relay_8 = gpiozero.LED(19)

Besser:
RELAY_PINS = (17, 18, 27, 22, 5, 6, 13 ,19) 
relays = [gpiozero.LED(pin) for pin in RELAY_PINS]
Ich werde aus deiner Namensgebung nicht schlau und habe mit dem Raspi noch nichts in dem Bereich gemacht, deshalb bin ich mir unsicher, was davon wirklich Kosntanten sind. Ich glaube, vieles Davon gehört in die Klasse.

Bevor mal 8 Funktionen schreibt, die alle gleich aussehen und sich nur in einer Zahl im Namen unterscheiden, schreibt man eine Funktion und übergibt den Unterschied als Parameter:

Code: Alles auswählen

# Falsch:
    def Relays1(self):    
        Relay_1.on() if Relay_1.value ==0 else Relay_1.off()

    def Relays2(self):
        Relay_2.on() if Relay_2.value ==0 else Relay_2.off()


# Mögliche bessere  Lösung:
    def set_relays_status(self, relays, relay_id, status):
        self.relais[relay_id].on() if status == 0 else self.relais[relay_id].off()
Warum werden deine Widgets in einer extra Funktion erstellt? Alles was man an self bindet, bindet man in __init__ daran, damit man eine Übersicht hat, was da eigentlich definiert hat. __init__ wird bei der Instanzierung der Klasse ausfgerufen. Warum sollte man da unterscheiden, ob sie bereits einmal ausgeführt wurde?

Deine Datenstruktur "Tempsensor" ist etwas krude. Zum einen ist das eine Liste, sollte also ein "s" an Ende haben. Und warum steckt denn da die Anzahl der Sensoren als erstes Element drin?!

Funktionen bekommen alles, was sie zum Arbeiten brauchen, als Parameter und geben ihr Ergebnis als return zurück. Kein! globalen! Variablen! Das was einlesen() da macht, erschließt sich mir durch das ansehen gar nicht und sieht falsch aus, weil es nur den ersten Wert updated. Oder ist das ein magischer Wert wie die Anzahl die "22" in der Datenstruktur, die eigentlich die Pfade zu den Sensoren hält?! Magie ist schlecht.

Code: Alles auswählen

# Falsch
Tempsensor = [22,# Anzahl der Sensoren
                '/sys/bus/w1/devices/28-01143b9758aa/w1_slave', #sensor1 1m
                '/sys/bus/w1/devices/28-01143bd16eaa/w1_slave', #sensor2 1m
                '/sys/bus/w1/devices/28-01143e1a7baa/w1_slave', #sensor3
                '/sys/bus/w1/devices/28-01143e2e31aa/w1_slave', #sensor4
                '/sys/bus/w1/devices/28-01143d695baa/w1_slave', #sensor5
                '/sys/bus/w1/devices/28-01143e2445aa/w1_slave', #sensor6
                '/sys/bus/w1/devices/28-01143e2e63aa/w1_slave', #sensor7
                '/sys/bus/w1/devices/28-01143c5be8aa/w1_slave', #sensor8
                '/sys/bus/w1/devices/28-01143c6cc7aa/w1_slave', #sensor9
                '/sys/bus/w1/devices/28-01143c5988aa/w1_slave', #sensor10
                '/sys/bus/w1/devices/28-01143c6784aa/w1_slave', #sensor11
                '/sys/bus/w1/devices/28-01143fa67daa/w1_slave', #sensor12
                '/sys/bus/w1/devices/28-012112587e4f/w1_slave', #sensor13
                '/sys/bus/w1/devices/28-01211265ff52/w1_slave', #sensor14
                '/sys/bus/w1/devices/28-0121125ff38a/w1_slave', #sensor15
                '/sys/bus/w1/devices/28-0121126b3fd2/w1_slave', #sensor16
                '/sys/bus/w1/devices/28-0121122f9105/w1_slave', #sensor17
                '/sys/bus/w1/devices/28-012112616893/w1_slave', #sensor18
                '/sys/bus/w1/devices/28-0121126f7458/w1_slave', #sensor19
                '/sys/bus/w1/devices/28-0121124dcddb/w1_slave', #sensor20
                '/sys/bus/w1/devices/28-012112650020/w1_slave', #sensor21
                '/sys/bus/w1/devices/28-012112722655/w1_slave', #sensor22
                ]
                
 # Besser
SENSOR_SERIAL_NUMBERS = [
    "28-01143b9758aa", "28-01143bd16eaa", "28-01143e1a7baa",
    "28-01143e2e31aa", "28-01143d695baa", "28-01143e2445aa",
    "28-01143e2e63aa", "28-01143c5be8aa", "28-01143c6cc7aa",
    "28-01143c5988aa", "28-01143c6784aa", "28-01143fa67daa",
    "28-012112587e4f", "28-01211265ff52", "28-0121125ff38a",
    "28-0121126b3fd2", "28-0121122f9105", "28-012112616893",
    "28-0121126f7458", "28-0121124dcddb", "28-012112650020",
    "28-012112722655"
]
SENSOR_PATHES = [f"/sys/bus/w1/devices/{snr}/w1_slave" for snr in SENSOR_SERIAL_NUMBERS]
Die Anzahl der SENSOR_PATHES muss man nicht separat speichern. Die Anzahl der Elemente in einer Datenstruktur is ja schon bekannt.

Wenn du das Programm entsprechend auf Datentrukturen und den Zugriff darauf per Loops umgstellt hast, bleibt eine übersichtliche Anzahl an Zeilen übrig. Dann kann man am Rest aufräumen.
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@sparrow: Potis sind Potentiometer — so Drehregler die einen analogen Spannungswert beeinflussen und wo man dann über einen Analog/Digitalwandler eine Zahl lesen kann, die mit der Spannung korrespondiert.

@RaPi_Fan: Ich habe über Deinen Code nur schnell drüber geschaut und habe bei der Liste mit der Anzahl als erstes Element mal was gesehen was ich vorher noch nie gesehen habe (kommt auch nicht so oft vor) und was ein klares Zeichen ist, dass Du dringend mal ein Grundlagentutorial durcharbeiten solltest. Dann ``global``, Threads, und GUI → das solltest Du bis einschliesslich objektorientierter Programmierung machen. Du hast Dir da ein Projekt gesucht bei dem man wirklich den kompletten Sprachumfang + den ereignisbasierten Programmablauf von GUIs + nebenläufige Programmierung drauf haben muss.

Zur Namensgebung hat sparrow ja schon etwas gesagt. Ergänzend: Funktionen und Methoden werden üblicherweise nach der Tätigkeit benannt, die sie durchführen, damit der Leser weiss was er zu erwarten hat, und um sie von eher passiven Werten unterscheiden zu können. `Relays` ist beispielsweise keine Tätigkeit.

Die Vorsilbe `my_*` bringt dem Leser keinerlei Mehrwert wenn es nicht auch ein `their_*` oder `our_*` gibt, gegen das sich das abgrenzen würde. Das kann man also in 99,9% der Fälle einfach sein lassen.

Warum sind die Relays `LED`-Objekte? Das ist verwirrend. Das sind allgemeiner `DigitalOutputDevice`-Objekte.

Aufsetzend auf die Vereinfachung von sparrow muss man auch nicht Code schreiben der aufgrund einer Zahl entweder `on()` oder `off()` aufruft, sondern man kann die Zahl ganz einfach als `value`-Attribut zuweisen. Also:

Code: Alles auswählen

    def set_relay_status(self, relay_index, status):
        self.relays[relay_index].on() if status == 0 else self.relays[relay_index].off()

    # <=>

    def set_relay_status(self, relay_index, status):
        self.relays[relay_index].value = status
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Vielen Dank für eure intensive Begutachtung meines Codes.
Wie ihr schon erkannt habt, habe ich (noch) keine Ahnung wie man Python richtig programmiert.
Eure Tipps werde ich mir alle einzelnd genau betrachten und versuchen zu kapieren, wie ich es umsetzten muß. Einiges leuchtet mir sofort ein, bei anderem muß ich weiter recherchieren, um dahinter zu kommen.

@sparrow
"Poti" wurde schon von __blackjack__User richtig erklärt, ergänzend kann man es auch als "veränderbaren Widerstand" bezeichnen.
"DI" steht bei mir für Digital Input. Das ist, glaube ich, auch nicht unüblich.
Das was einlesen() da macht, erschließt sich mir durch das ansehen gar nicht und sieht falsch aus, weil es nur den ersten Wert updated.
Oder ist das ein magischer Wert wie die Anzahl die "22" in der Datenstruktur, die eigentlich die Pfade zu den Sensoren hält?! Magie ist schlecht.
einlesen() ist auch nur irgendwoher kopiert, somit von mir nur angepasst worden. Funktionieren tut es, es werden alle Werte upgedatet.
In der ersten Position steht ja die Anzahl der Sensoren! Witzigerweise verstehe ich sogar die Funktionsweise. Magie finde ich da keine.


@__blackjack__User
@RaPi_Fan: Ich habe über Deinen Code nur schnell drüber geschaut und habe bei der Liste mit der Anzahl als erstes Element mal was gesehen was ich vorher noch nie gesehen habe (kommt auch nicht so oft vor) und was ein klares Zeichen ist, dass Du dringend mal ein Grundlagentutorial durcharbeiten solltest. Dann ``global``, Threads, und GUI → das solltest Du bis einschliesslich objektorientierter Programmierung machen. Du hast Dir da ein Projekt gesucht bei dem man wirklich den kompletten Sprachumfang + den ereignisbasierten Programmablauf von GUIs + nebenläufige Programmierung drauf haben muss.
Die Anzahl der zu erwartenden Listeneiträge setze ich häufig gerne voran. Da habe ich gleich eine definierte Größe der Arrays.
Das ich mit meinem Projekt so ziemlich alle Bereiche abdecke, ist mir durchaus bewußt. Umsomehr freut es mich, dass es mir gelungen ist, es voll funktionsfähig zum Laufen zu bekommen.

die Vorsilbe "my" verwende ich in der Regel um mich von default-Namen abzugrenzen. In diesem Fall wollte ich sehen, ob die verwendeten Bezeichnungen verändert werden dürfen.
Warum sind die Relays `LED`-Objekte? Das ist verwirrend. Das sind allgemeiner `DigitalOutputDevice`-Objekte.
Einfach zu erklären. In dem ersten Versuchsaufbau hatte ich LEDs, die wurden durch Relais ersetzt.

Wenn ich mein "richtiges" Programm zusammenschreibe, werde ich auch die entsprechenden Beschreibungen nehmen.


Noch einmal vielen Dank für eure Beiträge.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@RaPi_Fan: Vielleicht noch als Ergänzung: du könntest die Sensor-IDs (oder serial numbers) auch in einer einfachen Textdatei anlegen (es gibt auch noch andere mögliche Formate, aber fangen wir leicht verständlich an), die pro Zeile - ohne Leerzeilen – die Id eines jeden Sensors enthält, den du ansprechen möchtest:

sensorids.txt:

Code: Alles auswählen

28-01143b9758aa
28-01143bd16eaa
28-01143e1a7baa
Das hat den Vorteil, dass du Zahl der Sensoren ändern kannst, ohne in den Programmcode einzugreifen.
Hier ein Beispiel, wie du die IDs einlesen könntest (da die Zeichen alle im unteren ascii-Bereich liegen, kannst du den Sinn des encodings erst einmal ignorieren):

Code: Alles auswählen

def get_sensor_ids(filename, encoding="utf-8"):
    with open(filename) as fobj:
        return fobj.readlines()

# hier erhältst du eine Liste aller ids:        
sensor_ids = get_sensor_ids("sensorids.txt")
# und hier eine Liste mit den Pfaden (siehe auch sparrows Beispielcode):
sensor_pathes = [
    f"/sys/bus/w1/devices/{sensor_id}/w1_slave" 
    for sensor_id in sensor_ids
]
# und hier die Zahl der Pfade in der Liste:
sensor_nums = len(sensor_pathes)
Die letzte Anweisung gibt die die Zahl der Einträge zurück. Du brauchst diese Anzahl also nicht als eigenen Eintrag in der Liste zu speichern (sowas führt in der Praxis auch eher zu Ärger).
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@RaPi_Fan: `di` ist unüblich und auch deutlich zu verkürzt. ”Poti” kann man noch suchen, bei ”di” ist das eher Zufall wenn man da etwas passendes findet.

Du hast da keine „definierte Grösse des Arrays“ wenn Du in eine *Liste* als erstes Element eine Wunsch- oder Hoffnungsgrösse einträgst. Selbst wenn Wunsch/Hoffnung mit der Realität übereinstimmt, wofür Du ja immer selbst sorgen musst, womit das eine Fehlerquelle ist, hast Du dann in einer Liste Elemente mit unterschiedlichen Bedeutungen und kannst die nicht mehr normal, also so wie vorgesehen verwenden, weil Dein Code immer diesen einen komischen, besonderen, aus der Reihe tanzenden Wert, besonders behandeln muss. Das macht überhaupt gar keinen Sinn. Wenn Du wissen willst wie viele Elemente in einer Liste sind, dann fragst Du einfach die tatsächliche Länge ab. Keine komischen Sonderwerte, keine redundante Information wo man aufpassen muss, das die auch tatsächlich mit der Realität übereinstimmt, eine Fehlerquelle weniger, und man kann dann auch normal über die Elemente der Liste iterieren. Wofür man die Länge überhaupt gar nicht wissen muss.

Welche Defaultnamen? Es gibt weder `queue` noch `event`. Es gibt `Queue` und `Event` — das sind Datentypen, erkennbar an der Schreibweise mit grossem Anfangsbuchstaben, beziehungsweise allgemeiner ”PascalCase” falls es sich um zusammengesetzte Worte handelt. Aber selbst wenn Du zusätzlich einen eigenen Datentyp für eine Queue oder ein Ereignis definieren würdest, will doch kein Mensch wissen, dass das ”Deins” ist. Du weisst das offensichtlich, und andere sehen ja, dass es in dem Modul definiert ist und nicht aus `queue` oder `threading` kommt. Man würde dann entweder die entsprechenden vorhandenen Typen nicht direkt importieren sondern über `queue.Queue`/`threading.Event` ansprechen, oder in den neuen Typ etwas aufnehmen was den Sinn/die Bedeutung näher spezifiziert. Von `My*` hat keiner was.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

@__blackjack__User
Von `My*` hat keiner was.
In diesem Fall wollte ich sehen, ob die verwendeten Bezeichnungen verändert werden dürfen.
Habe doch geschrieben, wie es dazu kam. Natürlich hätte ich die Namen wieder zurück ändern können (müssen).
Du hast da keine „definierte Grösse des Arrays“ wenn Du in eine *Liste* als erstes Element eine Wunsch- oder Hoffnungsgrösse einträgst. Selbst wenn Wunsch/Hoffnung mit der Realität übereinstimmt, wofür Du ja immer selbst sorgen musst, womit das eine Fehlerquelle ist, hast Du dann in einer Liste Elemente mit unterschiedlichen Bedeutungen und kannst die nicht mehr normal, also so wie vorgesehen verwenden, weil Dein Code immer diesen einen komischen, besonderen, aus der Reihe tanzenden Wert, besonders behandeln muss. Das macht überhaupt gar keinen Sinn
Sehe ich nicht ganz so. Die richtige Anzahl einzuschreiben sollte fehlerfrei möglich sein. In diesem Fall ist es sogar so, dass hierdurch der SensorName auch mit der Position in der Reihe übereinstimmt, da es Sensor "0" nicht gibt. Andernfall muss immer ein Offset beachtet werden.

@kbr
interessanter Ansatz. Da sich die Seriennummern nicht (oder nur sehr selten) ändern, werde ich es wahrscheinlich nicht umsetzen. Die Möglichkeit, dass die entsprechende Textdatei nicht gefunden wird, ist eine Fehlerquelle, die ich gerne vermeiden möchte.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

@RaPi_Fan

Code: Alles auswählen

falsche_liste = [20, "hallo"]
ist moeglich, aber nicht fehlerfrei. Denn es suggeriert, die Liste haette 20 Eintraege. Hat sie aber nicht. Und Computer zaehlen halt von 0. Wenn das zur Darstellung anders sein soll, muss man das an der Stelle aendern. Und nicht sinnlos in allen moeglichen Datenstrukturen Dummy-Werte mit Fehlerpotential mitfuehren.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Ergänzend zu __deets__: Elemente einer Liste sollten von der selben Art sein. Sonst schlägst du dir selber einen Nagel in den Fuß. Denn nur wenn alle Elemente das enthalten, kannst du sauber über sie hinweg iterieren und man muss nicht einen Kofpstand und zwei Seitensprünge machen, um die Daten zu bekommen.

Das Beispiel lieferst du selbst:

Code: Alles auswählen

# Nicht so schön
    for loop in range(1,Tempsensor[0]+1):                                     #Werte in Temp[] einlesen
        Temp[loop] = (readTempLines(Tempsensor [loop])[0])
        tempalle = tempalle+ Temp[loop]

# besser:
    for sensor_path in sensor_pathes:
        ...
Ich sehe gar keinen Sinn darin, dort die Anzahl der Elemente einzutragen - außer die Komplexität und Fehleranfälligkeit unnötig zu erhöhen.

Bei der Gelgenheit ist mir noch aufgefallen, dass das sehr unglücklich ist, was du da tust.
Denn du rufst jedes Mal readTempLines auf. Und dan loopt über etwas - und wartet dann auch noch absichtlich. Das heißt, der Aufruf hier blockiert. Das soltest du anders lösen. Kommt aber wahrscheinlich von alleine, wenn du ein Gefühl für Datenstrukturen bekommen hast.
RaPi_Fan
User
Beiträge: 26
Registriert: Mittwoch 10. November 2021, 17:37

Ich versuche gerade eure Vorschläge umzusetzen.

Code: Alles auswählen

RELAY_PINS = (17, 18, 27, 22, 5, 6, 13 ,19)
relays = [gpiozero.LED(pin) for pin in RELAY_PINS]

# default Werte setzen
relays(0).on()
sleep(0.1)
relays(1).on()
sleep(0.1)
relays(2).on()
sleep(0.1)
... endet leider mit dieser Fehlermeldung:
relays(0).on()
TypeError: 'list' object is not callable
Ein entprechendes Ergebnis hatte ich auch mit den potis(8).
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@RaPi_Fan: Was irgendwie erwartbar ist wenn man versucht eine Liste wie eine Funktion aufzurufen. Wie kommst Du denn auf die Idee das zu machen? Syntax raten funktioniert nicht.

Zudem ist das aber auch gar nicht notwendig hier mit magischen oder wahlweise sehr langweiligen/monotonen Indexwerten zu arbeiten und achtmal mal den gleichen Code hin zu schreiben der sich nur durch den laufenden Index unterscheidet. Dafür gibt es Schleifen:

Code: Alles auswählen

for relay in relays:
    relay.on()
    sleep(0.1)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten