Funktion vereinfachen (statt t1,t2,t3,...) mit Index-Zählvariable (ti) arbeiten

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Hallo liebe Forenmitglieder,


    Sorry für den Titel, ich weiß nicht genau wie ich mein Problem in einem Satz sonst zusammenfassen soll.


    Kurz zum Projekt: Ich habe 16 Schalter mit denen ich über 2 Schieberegister 16 LED bei Tastendruck individuell ein und ausschalten möchte.

    Bisher hab ich zum Ausprobieren nur 3 Schalter angeschlossen.


    Ich habe eine Menge Funktionen und Schleifen, die jeweils auf eine bestimmte Variable angewandt werden.

    Z.B. muss ich folgende Funktion (Taster1) für alle anderen Taster umkopieren und die Indizes auf 2,3,4,5 usw. ändern, was insgesamt bei 16 Tastern sehr lang und unübersichtlich wird.


    Ein anderes gutes Beispiel ist dieses hier:

    Die if - Bedingung wird hier durch die ganzen "or"'s sehr sehr lang. Auch alle alle ti und tasterix werden eine lange Liste abgeben.


    Nachfolgend der gesamte bisherige Code. Dort lässt sich an einigen Stellen mein Problem finden.

    Der Teil mit den Schieberegistern usw. ist jetzt nicht weiter für meine Fragestellung wichtig und darf ignoriert werden.

    Mich interessiert nur, ob es einen Weg gibt, mit einer Art Schleife alle (obiges Beispiel) 16 t-Variablen mithilfe eines arrays oder so in einer einzelnen Schleife durchzählen zu lassen und auszuwerten.


    Wenn die Aufgabenstellung und das Problem unklar ist, gerne fragen, womöglich hab ichs ein bisschen verkorkst formuliert...:conf:

    Ich hoffe jemand hat eine Idee.:danke_ATDE:

  • Da gibt es ganz verschiedene Loesungsansaetze, je nachdem was genau resultieren soll...


    Fuer das erste Codestueck koennte man mit einem Array arbeiten:


    Code
    status = [0,0,0,0,0,0,...]
    
    # Was steht in channel?
    def Tasterfunktion1(channel, status, index ):
        status[index] = (status[index] + 1) % 2
        print( f"TASTER{index+1] {status[index]" )
  • Z.B. muss ich folgende Funktion (Taster1) für alle anderen Taster umkopieren und die Indizes auf 2,3,4,5 usw. ändern, was insgesamt bei 16 Tastern sehr lang und unübersichtlich wird.

    Das geile an Funktionen ist, dass sie sich prima für wiederholende und leicht unterschiedliche Variablen eignen. Anstatt deine Funktion für t1, t2, ... zu schreiben, kannst du einfach tx übergeben und so abstrahieren. In dem Schritt kannst du auch gleich auf das global verzichten und mit return arbeiten:


    Deine Tasterfunktion heißt im englischen übrigens "Toggle". Wenn 1, dann mache 0 und wenn 0, dann mache 1 -> also immer genau das Gegenteil. Hier ist eine elegantere Lösung (https://stackoverflow.com/a/8381955/2153629):

    Python
    def TasterfunktionX(channel, tx, name):
      tx ^= 1  # setze tx auf das Gegenteil
      print("TASTER " + name + str(tx))
      return tx

    Kelvin

  • Alles was das machen soll ist Ausgang = Eingang??


    Dann ist dieses Programm aber viel zu kompliziert.


    * status = 0

    * Schalter 1 setzt Bit 1 von status

    * Schalter 2 setzt Bit 2 von status

    .

    .

    .


    Die Ausgabefunktion wird angepasst so dass sie die Bits von status auf das Schieberegister ausgibt

  • Jonny98731 Du solltest als erstes mal kein Python 2 mehr verwenden.


    Eingerückt wird mit vier Leerzeichen pro Ebene.


    ``as`` beim Import ist zum umbenennen, `GPIO` wird aber gar nicht umbenannt. `os` wird importiert, aber nirgends verwendet.


    Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht. So etwas wie ``# importieren von Bibliotheken`` bei einem ``import`` oder ``# Keine Warnungen anzeigen`` bei einem ``GPIO.setwarnings(False)`` ist einfach nur überflüssig.


    Wirklich schlecht sind Kommentare die offensichtlich dem Code widersprechen, denn dann weiss der Leser nicht wer Recht hat, der Kommentar oder der Code. Und damit erreicht der Kommentar dann das Gegenteil von seiner Funktion: Statt fragen zu klären, wirft er neue auf. Ein Grund Redundanz in Kommentaren zu vermeiden, wie im Beispiel die Pinnummern die nicht mit denen im Code übereinstimmen. Und auch die Konstantennamen in den Kommentaren weichen von den Konstantennamen im Code ab. Warum?


    Auch ein falscher Kommentar ist das ``# 100ms warten`` was noch nicht mal leicht als falsch zu erkennen ist, weil `t` ganz woanders, ausserhalb der Funktion definiert ist. Dort ist das nicht 0.1, was 100ms wären, sondern 0.0001, was 0.1ms oder 100µs wären. Was ist da jetzt falsch? Die Zahl im Code oder die Einheit im Kommentar?


    Man sollte weder die Warnungen unterdrücken, noch am Anfang vom Code `cleanup()` aufrufen. Dieser Aufruf gehört an das Ende vom Programmablauf, mit einem ``try``/``finally`` abgesichert, so dass es auch aufgerufen wird, falls eine unerwartete Ausnahme auftritt.


    Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Was man gar nicht machen sollte ist auf Modulebene Konstanten, Variablen, Funktionen, und Hauptprogramm fröhlich abwechselnd mischen. Da muss man am Ende das gesamte Programm an einem Stück kennen und nachvollziehen können, statt das man sich einzelne Funktionen getrennt anschauen kann.


    Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Wenn man einen Kommentar braucht, der das in Langform erklärt, dann sollte der Name diesen Kommentar überflüssig machen.


    Man nummeriert keine Namen. Man will dann entweder sinnvolle Einzelnamen, oder gar keine einzelnen Werte sondern eine Datenstruktur. Oft eine Liste. Wie auch in diesem Fall.


    Du hast da 17 Werte für 16 LEDs und ein Wert davon wird auch noch zweimal in der Schleife in `ausgabe()` verarbeitet — also insgesamt 18 Schleifendurchläufe. Soll das so‽


    Man sollte Zahlen nicht als Wahrheitswerte missbrauchen. Python hat einen eigenen Datentyp (`bool`) mit den Werten `True` und `False` dafür.


    Gehört das mit dem BLANK-Pin nicht auch in die `ausgabe()`?


    Zwischenstand (ungetestet):


    Das ist vom Prinzip her das was Du machen wolltest, aber es hat zwei Probleme:


    1. Es besteht eine kleine zeitliche Lücke in der Tastendrücke nicht sofort berücksichtigt werden, sondern erst wenn der nächste Tastendruck erkannt wird.

    2. Die ``while``-Schleife beschäftigt die CPU zu 100% mit „busy waiting“.


    Beides würde man mit einer `Queue` lösen in die die Rückruffunktion das Ereignis schreibt und die man in der Hauptschleife blockierend abfragt.


    Wieder ungetestet:

    „Eat the rich — the poor are full of preservatives.“ — Rebecca ”Becky” Connor, The Connors