Posts by steffenr2001

    Das mit dem "global" habe ich jetzt mal umgecodet... aber daran lag das Problem nicht.

    Code zeigen. Ich kann nicht hellsehen, das dürfte auch auf alle anderen hier zutreffen.


    Dann solltest du vielleicht nochmal einen Schritt zurück gehen und nicht gleich ein GUI mit OOP schreiben, sondern kleine, "sinnlose" Programme, an denen du verschiedene Konzepte üben kannst und die du zu 100% verstehst und erklären kannst. Programmieren ist nämlich weder raten noch copy & paste.

    Entschuldigung... das war natürlich blöd von mir gedacht. Ich erstelle nun beim "Init" ein Instanzattribut:

    Python
    def __init__(self, sensor):
            global letzter_tag
            self.pn532 = sensor
            letzter_tag = "hauptmenue"
            self.changewindow(part="hauptmenue")

    Und greife dann Inn der Sensorabfrage mit self. darauf zu:


    LG

    Ja - weil du sensor nicht als Instanzattribut (self.pn532 = sensor, Zugriff in einer anderen Methode dann mit self.pn532.foo()) von der MainWindow-Instanz speicherst, sondern als lokale Variable im Konstruktor.

    Moin!


    Ich habe das jetzt genau so gemacht wie von dir beschrieben... dann lädt das Fenster "Hauptmenü" vom Init und danach geht gar nichts mehr... das Fenster kann. nicht geschlossen werden und der Sensor liest nichts...


    Was kann da denn noch das Problem sein? Langsam verzweifle ich echt.


    Mit freundlichen Grüßen

    Nein. Das wäre Vererbung - du musst einen Parameter zu __init__ hinzufügen. Hier ist es von Anfang an erklärt: https://realpython.com/python3-object-oriented-programming/


    Deutsche Lektüre gibt es sicherlich auch, aber erfahrungsgemäß mit einigen „schwarzen Schafen“.

    Habe es jetzt folgendermaßen gemacht.


    Code: Main Funktion
    def main():
        pn532 = PN532.PN532(cs=CS, sclk=SCLK, mosi=MOSI, miso=MISO)
        pn532.begin()
        pn532.SAM_configuration()
    
        win = MainWindow(sensor=pn532)
        win.startsensortimer()
        Gtk.main()


    und dann bei Init:

    Python: Init
    def __init__(self, sensor):
            global letzter_tag
            pn532 = sensor
            letzter_tag = "hauptmenue"
            self.changewindow(part="hauptmenue")



    Leider bekomme ich immer noch den gleichen Fehler...

    :conf:

    Nö. Das ist falsch, bei einem handelt es sich um die Klasse (PN532), beim anderen um die Instanz (pn532) - das kann man nicht einfach austauschen. Die korrekte Lösung ist, die Instanz von PN532 entweder in der MainWindow-Klasse zu erstellen oder als Argument zu übergeben.

    Wie kann ich die denn als Argument übergeben? Einfach in der Klasse ein Parameter wie zum Beispiel "sensor" hinzufügen?


    Also wäre das so korrekt?:

    class MainWindow(Gtk.Window, sensor):


    und dann


    Gtk.main(sensor= pn532):denker::denker:


    LG

    Das sollte eigentlich kein Problem sein, denn ich denke das kleingeschriebene pn532 bezieht sich auf das zuvor definierte

    pn532 = PN532.PN532(cs=CS, sclk=SCLK, mosi=MOSI, miso=MISO) in der Main Funktion. Hier wiederum wird sich auf das PN532 aus Zeile 8 bezogen.


    LG

    Moin Moin!


    Der Code ist nun überarbeitet, aber ich konnte jedoch manche Probleme noch nicht ganz lösen und es gibt auch einen neuen Fehler den ich versucht habe zu lösen... leider hat der Versuch das Problem nur noch verschlimmert.:conf::no_sad:


    Das Ist die neue Fehlermeldung:

    Quote from Fehlermeldung

    Traceback (most recent call last):

    File "SensorUI.py", line 49, in sensorabfrage

    uid = pn532.read_passive_target()

    NameError: global name 'pn532' is not defined

    Mein Ansatz war die Teile von der "main" Funktion , die den NFC Sensor inkludieren mit in die "Sensorabfrage" Funktion zu verschieben. Das hat nicht geklappt.:helpnew:


    Außerdem konnte ich bisher das Problem mit den globalen Variablen lösen, daher bestehen diese weiterhin... ich finde bei Tutorials eigentlich immer nur die Möglichkeit mit global. :daumendreh2:

    Außerdem bestehen auch weiterhin kleine Teile wo Sprachen durchmisst sind, um dieses Finetuning mit Variablenumbennenung werde ich mich kümmern, wenn ich die erste Version des funktionierenden Codes habe.

    Bei der Erstellung des Strings bin ich auf die bessere Art zur Verknüpfung mehrerer Springs/Variablen umgestiegen, die Änderung auf Integer sehe ich noch skeptisch, weil ich ja auch den String "Hauptmenü" benutze.

    Bei der "sensorabfrage()" Funktion habe ich das return true beibehalten, weil dies dort laut einiger Beispielprojekte sein sollte.


    Hier der aktuelle Code:



    Mit freundlichen Grüßen

    Steffen

    :danke_ATDE:

    Noch mehr Kritik hilfreiche Tipps:

    • Konsistente Einrückungen sind wichtig. Nicht nur das, konsistenter Code allgemein ist wichtig. So solltest du IMMER 4 Leerzeichen pro Ebene einrücken - nicht mehr, nicht weniger, keine Tabs, nichts mischen.
      Verwende am besten einen Code-Formatter (Black erfreut sich wachsender Beliebtheit und wurde sogar in die GitHub-Organisation der PSF übertragen: https://github.com/psf/black). So spart man sich mühsame Handarbeit und muss sich nicht über Formatierung Gedanken machen.
    • Alle Variablennamen von Konstanten GROSS_MIT_UNTERSTRICH schreiben
    • Das Hauptprogramm in einer Funktion kapseln und mit if __name__ == "__main__": main() ausführen. Dieses weit verbreitete Konstrukt ist hier sehr ausführlich erklärt: https://code.visualstudio.com/docs/python/linting
      Im globalen Namensraum sollten sich nur Funktionen/Klassendefinitionen, Konstanten und Imports befinden
    • Imports sortieren - ist nicht zwingend notwendig, aber übersichtlicher. Viele (inkl. mir) verwenden folgendes:

      Also zuerst die Module aus der Standardbibliothek, dann externe (i.d.R. mit pip installierte) Module, dann die eigenen zum Projekt gehörenden.

    • Warum enthalten einige deiner Methoden ein return True? Das hat keinen Mehrwert, erst Recht wenn du mit dem Rückgabewert nichts tust. Selbst für sensorabfrage solltest du es nicht brauchen, siehe Doku: https://developer.gnome.org/py…unction-glib--timeout-add
    • teil = part bringt... nichts. Nenne den Parameter gleich teil oder verwende part im Code.
    • Strings werden nicht mit + zusammengesetzt, niemalsnie. Nimm str.format (https://docs.python.org/3/library/stdtypes.html#str.format) oder noch viel besser f-Strings (https://docs.python.org/3/refe…l_analysis.html#f-strings, ab Python 3.6, auf dem neuen Raspbian Buster ist 3.7). Beides ist deutlich mächtiger (siehe Doku) und erhöht die Lesbarkeit des Codes.
    • Andererseits ist ein sowas eher schlecht: '{0}'.format(int(data[2:8].decode("utf-8"), 16)). Das ist besser und kürzer als str(int(data[2:8].decode("utf-8"), 16)) geschrieben - du willst ja keinen String formatieren, sondern eine Nummer in einen String konvertieren. Wobei das hier auch nicht optimal ist, verwende einfach Integer als Keys im Dictionary karten. Und if action is not None: kannst du dir sparen, da das Ergebnis von str.format immer ein String sein wird.
    • Bleibe mit der Sprache konsistent. Entweder allen eigenen Code Deutsch, oder viel besser, alles auf Englisch. Alles andere wird einfach nur unlesbar.
    • Folge dem "Don't repeat yourself"-Prinzip (DRY). Der Code im Konstruktor und changewindow gehört in eine gemeinsam verwendbare Funktion/Methode ausgelagert um Wiederholungen zu vermeiden.
    • Vermeide global, das ist in 99.9% falsch. Du hast doch eine Klasse und kannst Instanz-Attribute verwenden!
    • Denk' dir was besseres aus, als None und "none" zu mischen. Es ist spät und ich hab' schon den ganzen Tag auf Code gestarrt, ich werde jetzt nicht versuchen, das zu entziffern :lol:
    • Verwende sinnvolle Kommentare. Keine Sorge, ich habe auch ewig gebraucht, bis ich das halbwegs drauf hatte - aber #Auswertung der Daten oder # Timer starten haben wirklich keinen Mehrwert - das ist doch mehr als offensichtlich. Lieber sollten kompliziertere Codestellen erklärende Kommentare haben, und da muss man dann auch nicht sparsam sein. Dazu gibt's jede Menge Lesestoff im Internet, z.B. https://www.freecodecamp.org/n…nd-the-ugly-be9cc65fbf83/

    Vieles davon ist Teil von PEP 8, dem in der Python-Community anerkannten Styleguide: https://www.python.org/dev/peps/pep-0008/. Das solltest du beachten, dabei kann dir teilweise ein Formatter, teilweise ein Linter helfen. (z.B. https://code.visualstudio.com/docs/python/linting)


    Zu guter Letzt - laut deinem Profil bist du 17 Jahre alt - aus Erfahrung weiß ich, dass sich nicht viele leider immer weniger Schüler*innen/junge Menschen für "Computerzeugs" interessieren, bei der derzeitigen Situation bezüglich Informatik-Unterricht in den deutschen Schulen ja auch kein Wunder. Weiter so! :bravo2:

    :danke_ATDE::danke_ATDE::danke_ATDE::danke_ATDE::danke_ATDE::danke_ATDE::danke_ATDE:


    Vielen Dank für diese detaillierte konstruktive Kritik zu meinem Code, genau das ist das, was einem so unglaublich weiterhilft, wenn man noch in der Lernphase ist. Denn wie du auch schon erwähnt hast ist es mit dem erlernen einer Programmiersprache in der Schule aktuell alles andere als einfach... ich habe selber drei Jahre Informatik belegt und über RobotKarol; Scratch und dem MIT-AppInventor sind wir nicht hinaus gekommen...


    Ich habe die Antwort grade erst gesehen als ich eigentlich schon wegen einem weiteren Error fragen wollte, doch nun werde ich ersteinmal versuchen meinen Code durch deine ganzen Tipps zu verschlanken und die Syntax zu verbessern.


    Vielen Dank!


    LG

    Steffen

    Das ist mir auch klar! :angel:

    Dafür vielen Dank! Wenn ich das Gefühl habe helfen zu können, werde ich das natürlich auch tun, denn so funktioniert ein Forum ja... da ich die Möglichkeit habe wollte ich jedoch trotzdem so etwas Projektbezogenes anbieten.


    LG :baeh2:

    Linus


    Ich habe das Programm jetzt komplett neu geschrieben und dabei etwas abgespeckt. Dabei sind auch alle bestehenden Fehler verschwunden...


    Leider bekomme ich jetzt aber diesen Fehler:


    Quote

    File "SensorUI.py", line 58, in sensorabfrage

    self.changewindow(part=obj)

    TypeError: changewindow() got multiple values for keyword argument 'part'

    Kannst du (oder auch jemand anderes) mir erklären wo hier das Problem liegt?:wallbash::helpnew:


    Der neue Code:


    Um mich für diese bisher schon gigantische Hilfe von euch zu revongieren, habe ich mir etwas überlegt. Allen Leuten, die mir in diesem Thread aktiv geholfen haben ( Linus , Hofei , noisefloor ) möchte ich anbieten (falls ihr keinen eigenen 3D-Drucker habt) Teile für euer nächstes Projekt auszudrucken, falls ihr das gebrauchen könnt. Dafür könnt ihr mir einfach eine DM schicken.:angel:


    Vielen Dank für die ganze nette Hilfe bisher!:bravo2::danke_ATDE:


    LG

    Steffen

    Du hast ja auch keine globale Funktion changeinterface - aber eine Medthode in der selben Klasse. Python kann aber nicht hellsehen, also musst du auf die Methode über self zugreifen (Instanz der Klasse).


    Siehe Python OOP-Grundlagen hier: https://docs.python.org/3/tutorial/classes.html

    Ich habe jetzt alle Variablen auch in die Klasse verlegt da es bei einer möglichen späteren Erweiterung um eine LED-Lichtsteuerungsklasse so übersichtlicher bleibt. Nach den Ausgaben zu urteilen läuft das Script auch ganz gut bis es zur Auswertung der Daten kommt... nun erhalte ich folgenden Fehler:


    Ich weiß echt nicht woran es liegen kann weil genau die Befehle in einem anderen Script (hier Script 2) nicht diesen Fehler auslösen:



    Hallo!


    Ich habe mich nun mit dieser klassenorientieren Entwicklung beschäftigt und da mal mal Anfänge geschaffen. Nun bekomme ich folgende Error nicht weg:

    Das ist der Quellcode dazu:


    LG und vielen Dank für die Hilfe

    Steffen

    Vielen Dank!


    Kennt da jemand vielleicht noch ein Beispiel script? Im Internet finde ich ohne konkretes Suchwort leider auch nichts.


    Mit freundlichen Grüßen

    Moin Moin!


    Dank eurer großartigen Unterstützung bin ich schon sehr weit gekommen, harke nun jedoch aber erneut und meine versuche mit asyncio sind auch sehr daneben gewesen...


    Mittlerweile sieht das Script wie folgt aus:


    Gegen Ende des Programms rufe ich die Funktion "loadui" auf. Mithilfe von dieser selbstgeschriebenen Funktion lade ich das userinterface...

    Leider bleibt dann mein code in der Gtk.main() Funktion hängen... das funktioniert aber nicht weil der Hauptcode weiter laufen muss um bei Änderung der eingäbe das bestehende UI zu schließen und ein anderes zu öffnen bzw zwischen zwei unterschiedlichen UIs muss ein Wechsel möglich sein.


    Hat da jemand eine Idee ?


    LG

    Steffen

    Linus

    Eine Frage hätte ich aber dennoch...


    aktuell hatte ich ja geplant den wert der Abfrage so auszuwerten:

    Code
    if Wert == "Auto":
        # öffne Auto
    elif Wert == "Spoiler":
        # öffne Spoiler
    Elif Wert == "Heckspoiler":
        # öffne Heckspoiler

    Welchen weg gibt es um das durch weniger if Statements zu realisieren? Habt ihr da ein Stichwort für mich?

    Linus  Hofei


    Hallo!


    Ich habe mich nun näher mit dem Thema beschäftigt und mich dafür entschieden den PN532 zu verwenden. Ich bin auch auf ein sehr gutes und verständliches Beispielscript gefunden:



    Ich erhalte entweder die Ausgabe "Keine Karte!" oder "User Id: xxx".


    Code
    User Id: 112

    Nun würde ich gerne die Zahl, die in dem String , der wiefolgt ausgegeben wird, durch ein if Statement vergleichen:

    Code
    print('User Id: {0}'.format(int(data[2:8].decode("utf-8"), 16)))


    Wie kann ich nur die Zahl bekommen und diese dann wie folgt vergleichen?:


    Code
    if zahl == 100:
        # Aktion 1
    else if zahl == 200:
        # Aktion 2
    else:
        #keine Aktion