Seite 1 von 1

1xAlle Fehler

Verfasst: Dienstag 31. Oktober 2017, 18:11
von paradiesvogel24
Hallo brauche Hilfe :roll: :roll: :roll:
lerne gerade Python zu programmieren und komme nicht weiter.

Versuche gerade einen Vokabeltrainer nach zu programmieren und verstehe den Fehler nicht da in dem Tutorial der gleiche Befehl "1xAlle" ist und funktioniert.

Kann mir da jemand weiterhelfen. Suche mir den Wolf aber versteh nicht woran es liegt.

Code: Alles auswählen

# Externe Module
import os, sqlite3, tkinter, random

# Falls keine Datenbankdatei vorhanden: Erstellen, mit Startdaten
if not os.path.exists("vokabel.db"):
    con = sqlite3.connect("vokabel.db")
    cursor = con.cursor()
    sql = "CREATE TABLE daten(id INTEGER PRIMARY KEY, deu TEXT, eng TEXT, fra TEXT)"
    cursor.execute(sql)
    startdaten = [["suchen", "to look for", "chercher"],
                  ["abkürzen", "to abbreviate", "raccourcir"],
                  ["nützlich", "useful", "utile"],
                  ["beraten", "to advise", "conseiller"],
                  ["einfach", "easy", "simple"],
                  ["ankündigen", "to announce", "annoncer"]]
    for gruppe in startdaten:
        sql = "INSERT INTO daten(deu, eng, fra) VALUES('" + gruppe[0] \
              + "', '" + gruppe[1] + "', '" + gruppe[2] + "')"
        print(sql)
        cursor.execute(sql)
        con.commit()
    con.close()

# Vokabel speichern
def vokabelSpeichern():
    if enDeu.get() == "" or enEng.get() == "" or enFra.get() == "":
        tkinter.messagebox.showwarning("Warnung", "Alle drei Eingabefelder füllen")
        return

    # Prüfen, ob Vokabel bereits vorhanden ist
    con = sqlite3.connect("vokabel.db")
    cursor = con.cursor()
    sql = "SELECT * FROM daten WHERE deu = '" + enDeu.get() + "'"
    cursor.execute(sql)
    ergebnis = cursor.fetchall()

    # Falls Vokabel bereits vorhanden ist, ggf. überschreiben
    if ergebnis:
        antwort = tkinter.messagebox.askyesno("Vokabel bereits vorhanden",
            "Wollen Sie Folgendes ersetzen?\n" + ergebnis[0][1] +
            "; " + ergebnis[0][2] + "; " + ergebnis[0][3])
        if antwort == 1:
            sql = "UPDATE daten SET eng = '" + enEng.get() + "', fra = '" + \
                  enFra.get() + "' WHERE deu = '" + enDeu.get() + "'"
            print(sql)
            cursor.execute(sql)
            con.commit()

    else:
        sql = "INSERT INTO daten (deu, eng, fra) VALUES('" + enDeu.get() \
              + "', '" + enEng.get() + "', '" + enFra.get() + "')"
        print(sql)
        cursor.execute(sql)
        con.commit()

    con.close()

# Vokabel löschen
def vokabelLoeschen():
    if enDeu.get() == "" or enEng.get() == "" or enFra.get() == "":
        tkinter.messagebox.showwarning("Warnung", "Alle drei Eingabefelder füllen")
        return

    # Löschen, falls alle drei Einträge übereinstimmen
    con = sqlite3.connect("vokabel.db")
    cursor = con.cursor()
    sql = "DELETE FROM daten WHERE deu = '" + enDeu.get() + "' AND eng = '" + \
          enEng.get() + "' AND fra = '" + enFra.get() + "'"
    print(sql)
    cursor.execute(sql)
    con.commit()
    con.close()

# Test starten, Frage stellen, Eingabe prüfen
testAktiv = False
def startenStellenPruefen():
    global testAktiv, listeEins, listeZwei, nummerAuswahl
    
    # Falls Test noch nicht gestartet wurde
    if not testAktiv:
        # Wurde eine Auswahl getroffen?
        if liKombi.curselection():
            kombi = int(liKombi.curselection()[0])
        else:
            tkinter.messagebox.showwarning("Warnung", "Treffen Sie zunächst eine Auswahl")
            return

        # Test starten
        buTestStarten["text"] = "Prüfen / Nächste Vokabel"
        testAktiv = True
        nummerAuswahl = -1

        # Datensätze laden
        con = sqlite3.connect("vokabel.db")
        cursor = con.cursor()
        sql = "SELECT * FROm daten"
        cursor.execute(sql)

        # Listen füllen
        listeEins = []
        listeZwei = []
        for dsatz in cursor:
            if kombi == 0:
                listeEins.append(dsatz[1])
                listeZwei.append(dsatz[2])
            elif kombi == 1:
                listeEins.append(dsatz[2])
                listeZwei.append(dsatz[1])
            elif kombi == 2:
                listeEins.append(dsatz[1])
                listeZwei.append(dsatz[3])
            elif kombi == 3:
                listeEins.append(dsatz[3])
                listeZwei.append(dsatz[1])
            elif kombi == 4:
                listeEins.append(dsatz[2])
                listeZwei.append(dsatz[3])
            else:
                listeEins.append(dsatz[3])
                listeZwei.append(dsatz[2])
        con.close()

    # Antwort prüfen, falls nicht allererste Frage
    if nummerAuswahl != -1:
        if enAntwort.get() == listeZwei[nummerAuswahl]:
            lbBew["text"] = "Richtig: " + listeEins[nummerAuswahl] + " = " + listeZwei[nummerAuswahl]
            del listeEins[nummerAuswahl]
            del listeZwei[nummerAuswahl]
        else:
            lbBew["text"] = "Falsch: " + listeEins[nummerAuswahl] + " = " + listeZwei[nummerAuswahl]

    # Test ist zu Ende?
    if not listeEins:
        tkinter.messagebox.showinfo("Info", "Alles gelöst, gratuliere")

        # Startzustand herstellen
        buTestStarten["text"] = "Test starten"
        lbFrage["text"] = "(Frage)"
        enAntwort.delete(0, "end")
        lbBew["text"] = "(Bewertung)"
        testAktiv = False
        nummerAuswahl = -1
        return

    # Nächste Frage stellen
    nummerAuswahl = random.randint(0, len(listeEins) - 1)
    lbFrage["text"] = listeEins[nummerAuswahl] + " ="
    enAntwort.delete(0, "end")

# Alle Vokabeln anzeigen
def alleAnzeigen():
    con = sqlite3.connect("vokabel.db")
    cursor = con.cursor()
    sql = "SELECT * FROM daten order by deu"
    cursor.execute(sql)
    lxAlle.delete(0, "end")
    for dsatz in cursor:
        lxAlle.insert("end", dsatz[1] + "; " + dsatz[2] + "; " + dsatz[3])
    con.close()

# Anzeige löschen
def anzeigeLoeschen():
    lxAlle.delete(0, "end")

# Auf Auswahl eines Eintrags reagieren
def lxAlleClick(e):
    nr = int(lxAlle.curselection()[0])
    inhalt = lxAlle.get(nr)
    teile = inhalt.split(";")
    enDeu.delete(0, "end")
    enEng.delete(0, "end")
    enFra.delete(0, "end")
    enDeu.insert("end", teile[0])
    enEng.insert("end", teile[1][1:])
    enFra.insert("end", teile[2][1:]) 

# Programm beenden
def ende():
    main.destroy()

# Hauptfenster
main = tkinter.Tk()
main["height"] = 480
main["width"] = 600

# Drei Label zum Ändern der Vokabeln
lbDeu = tkinter.Label(main, text="deutsch:")
lbDeu.place(x=10, y=10)
lbEng = tkinter.Label(main, text="englisch:")
lbEng.place(x=140, y=10)
lbFra = tkinter.Label(main, text="französisch:")
lbFra.place(x=270, y=10)

# Drei Entries zum Ändern der Vokabeln
enDeu = tkinter.Entry(main, width=13)
enDeu.place(x=10, y=40)
enEng = tkinter.Entry(main, width=13)
enEng.place(x=140, y=40)
enFra = tkinter.Entry(main, width=13)
enFra.place(x=270, y=40)

# Zwei Buttons zum Speichern bzw. Löschen einer Vokabel
buSpeichern = tkinter.Button(main, text="Speichern", command=vokabelSpeichern)
buSpeichern.place(x=410, y=30)
buLoeschen = tkinter.Button(main, text="Löschen", command=vokabelLoeschen)
buLoeschen.place(x=510, y=30)

# Label und Listbox zur Auswahl der Sprachkombination
lbKombi = tkinter.Label(main, text="Sprachkombination für Test:")
lbKombi.place(x=10, y=80)

liKombi = tkinter.Listbox(main, width=25, height=0)
liKombi.insert("end", "deutsch / englisch")
liKombi.insert("end", "englisch / deutsch")
liKombi.insert("end", "deutsch / französisch")
liKombi.insert("end", "französisch / deutsch")
liKombi.insert("end", "englisch / französisch")
liKombi.insert("end", "französisch / englisch")
liKombi.place(x=10, y=110)

# Button zum Starten des Tests
buTestStarten = tkinter.Button(main, text="Test starten", command=startenStellenPruefen)
buTestStarten.place(x=250, y=110)

# Zwei Label und ein Entry für den Test
lbFrage = tkinter.Label(main, text="(Frage)")
lbFrage.place(x=250, y=165)
enAntwort = tkinter.Entry(main, width=13)
enAntwort.place(x=410, y=165)
lbBew = tkinter.Label(main, text="(Bewertung)")
lbBew.place(x=250, y=210)

# Liste mit Scrollbalken, um alle Vokabeln anzuzeigen
lbListe = tkinter.Label(main, text="Alle Vokabeln:")
lbListe.place(x=10, y=260)
frListe = tkinter.Frame(main)
frListe.place(x=10, y=290)

scbAlle = tkinter.Scrollbar(frListe, orient="vertical")
lxAlle = tkinter.Listbox(frListe, width=40, height=7, yscrollcommand=scbAlle.set)
scbAlle["command"] = lxAlle.yview
lxAlle.pack(side="left")
scbAlle.pack(side="left", fill="y")
lxAlle.bind("<<ListboxSelect>>", lxAlleClick)

# Zwei Buttons zum Anzeigen aller Vokabeln und zum Löschen der Anzeige
buAlleAnzeigen = tkinter.Button(main, text="Alle Vokabeln anzeigen", command=alleAnzeigen)
buAlleAnzeigen.place(x=380, y=290)
buAnzeigeLoeschen = tkinter.Button(main, text="Anzeige löschen", command=anzeigeLoeschen)
buAnzeigeLoeschen.place(x=380, y=340)

# Ende
buEnde = tkinter.Button(main, text="Ende", command=ende)
buEnde.place(x=530, y=400)

# Hauptprogrammschleife starten
main.mainloop()


             

Re: 1xAlle Fehler

Verfasst: Dienstag 31. Oktober 2017, 18:42
von eckhard
@paradiesvogel24. Welchen Fehler bekommst Du?

Wie hast Du das Skript gestartet? Ich habe (in Linux) das Skript in die Datei datei,pl kopiert, #!/usr/bin/python3 an den Anfang gesetzt,
chmod u+x datei.pl gemacht und dann mit ./datei.pl aufgerufen. Es wird ein Fenster ausgegeben. Buttons funktionieren.

Eckhard

Re: 1xAlle Fehler

Verfasst: Dienstag 31. Oktober 2017, 18:47
von heiner88
Zeile 167 nr = int(lxAlle.curselection()[0])

lxAlle.cuselection liefert manchmal ein leeres Tupel zurück.
Darauf muss du reagieren, sonst IndexError: tuple index out of range

Der Rest scheint zu funktionieren.

Re: 1xAlle Fehler

Verfasst: Dienstag 31. Oktober 2017, 19:35
von Sirius3
@paradiesvogel24: bei Deinem Programm mußt Du noch einiges aufräumen. Auf oberster Ebene sollten nur Definitionen und KONSTANTEN stehen, Du mischst ausführbaren Code und Funktionsdefinitionen wild durcheinander. In Zeile 17 stückelst Du SQL-Kommandos per + zusammen. Das solltest Du nie! machen. Das ist nicht nur unleserlich und fehleranfällig, dadurch können undurchsichtige Fehler entstehen, versuch mal o'clock als Vokabel einzufügen. `execute` kennt ein zweites Argument als Parameter:

Code: Alles auswählen

    for gruppe in startdaten:
        sql = "INSERT INTO daten(deu, eng, fra) VALUES(?, ?, ?)"
        cursor.execute(sql, gruppe)
Gleicher Fehler in Zeile 33, 43, 50, 67, etc.

Funktionen sollten alles was sie brauchen per Parameter erhalten. Globale Variablen machen ein Programm untestbar und Fehler sind schwer zu lokalisieren. Für GUI-Programme braucht man eigentlich zwangsläufig Objektorientierung.

Du solltest auch die Datenbankabfrage stärker von der Anzeigelogik trennen, also Funktionen schreiben, die nichts anderes machen, als die verschiedenen Datenbankabfragen. Dass an vielen Stellen jeweils eine eigene Datenbankverbindung aufgebaut ist, ist auch nicht gut.

Die Variablenschreibweise hält sich nicht an die übliche Konvention: klein_mit_unterstrich. Viele Namen sind zu generisch, listeEins und listeZwei sagen nicht, was denn nun in den Listen steht. die Präfixe lb, bu, lx sind nichtssagend. Ob etwas ein Knopf ist, oder nicht, braucht nicht im Variablennamen stehen, weil es durch seine Funktion sowieso klar wird.

Elemente sollte man nicht mit `place` positionieren, sondern entweder mit `grid` oder mit `pack`. Bei `place` funktioniert deine GUI nur unter Deinem Betriebssystem mit Deiner Auflösung. Bei anderen könnte das Programm unbenutzbar sein, weil Textfelder übereinander liegen oder aus dem Fenster herausgerutscht sind.

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 06:29
von paradiesvogel24
@ eckhard
Ich habe das Programm ganz normal mit Python mit der F5 taste dem Befehl:"Progtamm starten gestartet.

Leider kommt bei mir der Fehler: "invalid Syntax " und so komme ich erst gar nicht bis zum Button

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 07:06
von paradiesvogel24
@Sirius3
ich verstehe nur Bahnhof.

Seltsam das da so viele Fehler sein sollen wo ich doch das Programm eigentlich von dem Videokurs von Videobrain2 nachrprogrammiert habe
Die Jungs sollten doch wissen wie das richtig geht oder?

Seltsam ist nur wenn ich in den gleichen Zeilen den Code einsetze (in dem Fall von 240-243)

Code: Alles auswählen

scbAlle = tkinter.Scrollbar(frListe, orient="vertical")
lxAlle = tkinter.Listbox(frListe, width=40, height=7, yscrollcommand=scbAlle.set)
scbAlle["command"] = lxAlle.yview
lxAlle.pack(side="left")
...funktioniert es und das Programm startet obwohl es derselbe Text ist, kann doch nicht sein oder?

Kann ich in Python irgendwo die Zeilennummern einblenden?

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 07:12
von paradiesvogel24
@heiner88
wo siehst Du denn das ein leeres Feld zurück geliefert wurde?

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 09:01
von kbr
paradiesvogel24 hat geschrieben:Seltsam das da so viele Fehler sein sollen wo ich doch das Programm eigentlich von dem Videokurs von Videobrain2 nachrprogrammiert habe
Die Jungs sollten doch wissen wie das richtig geht oder?
Das Programm ist vom Entwurf her wirklich schlecht und ein Beispiel, wie es nicht gemacht werden sollte. Das ist generell ein Problem bei solchen Online-Kursen, die sich an Teilnehmer wenden, die Python bzw. Programmieren lernen möchten und daher die Qualität des vorgesetzten noch gar nicht beurteilen können.

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 09:12
von nezzcarth
paradiesvogel24 hat geschrieben: Seltsam das da so viele Fehler sein sollen wo ich doch das Programm eigentlich von dem Videokurs von Videobrain2 nachrprogrammiert habe
Die Jungs sollten doch wissen wie das richtig geht oder?
Ich kenne das Video nicht, aber wenn der Stil, den du gezeigt hast, so auch in dem Video vermittelt wird, spricht das nicht für das Video. Python zeichnet sich dadurch aus, dass es in der Community recht viele Konventionen/Best Practices gibt, die z.B. nahelegen, wie Code formatiert und strukturiert sein sollte, wie man Dinge benennt, wie man bestimmte, wiederkehrende Probleme idiomatisch löst und was man nicht tun sollte.

Hier im Forum tauchen immer wieder Schnipsel aus Lehrwerken oder Kursen auf, die nicht nach "echtem" Python aussehen. Die Lehrperson hat in diesen Fällen zwar scheinbar generelle Programmiererfahrung, aber sich vielleicht nicht besonders tiefgreifend mit den Besonderheiten von Python beschäftigt, sondern auf die Syntax geschaut und dann einfach so losgelegt, wie sie/er es von anderen Sprachen gewohnt ist. Andere Dinge sind auch in anderen Sprachen schlechte Angewohnheiten, auf deren Vermeidung bei Python besonders viel Wert gelegt wird, um sauberen, gut lesbaren Code zu erhalten. Ich weiß wie gesagt nicht, ob das bei dem Video auch so ist. Aber es wäre nicht ungewöhnlich. Insofern würde ich nicht unbedingt darauf setzen, dass das Video in allen Punkten richtig liegt und die Vorschläge von Sirius3 annehmen/umsetzen.

EDIT: kbr war schneller; aber wo ich das schon mal getippt hatte... :)

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 09:53
von heiner88
>>>wo siehst Du denn das ein leeres Feld zurück geliefert wurde?

Ich starte dein Programm mit IDLE.
Nach einer Weile bekommt man diesen Fehler angezeigt im IDLE-Fenster:
Exception in Tkinter callback
Traceback (most recent call last):
...
File "test.py", line 168, in lxAlleClick
nr = int(lxAlle.curselection()[0])
IndexError: tuple index out of range
Wegen [0] gibt es einen "Index out of range"-Fehler,
weil curselection() ein leeres Tupel zurückgibt.

Re: 1xAlle Fehler

Verfasst: Mittwoch 1. November 2017, 10:27
von heiner88
Falls du das Programm überhaupt nicht zum Laufen bekommst,
kannst du mal den Code in deinem ersten Beitrag in einen File zurückkopieren.
Und dann mit diesem File IDLE starten. Vielleicht hast du tabs-Probleme.
Bedenke auch, dass dein Programm Python 3.x braucht (nicht Python 2.7).
Ich habe Windows 7 mit Python 3.6.2 benützt.

Re: 1xAlle Fehler

Verfasst: Freitag 3. November 2017, 09:27
von paradiesvogel24
@kbr
Das ist generell ein Problem bei solchen Online-Kursen, die sich an Teilnehmer wenden, die Python bzw. Programmieren lernen möchten und daher die Qualität des vorgesetzten noch gar nicht beurteilen können.
Na das hört sich ja nicht so toll an.
Hatte gedacht das Video2brain weiss was sie da tun und wissen welche Dozenten sie mit welchem Wissen dort einsetzen.

Wollte mir das lernen durch die Videos etwas vereinfachen. Mal gut das ich mir den Kurs geliehen und nicht verkauft hatte.

Wie kann ich denn wissen welche Lehrwerke das Programmieren mit Python gut sind.

Re: 1xAlle Fehler

Verfasst: Freitag 3. November 2017, 09:40
von paradiesvogel24
@nezzcarth
nezzcarth hat geschrieben:
paradiesvogel24 hat geschrieben: Andere Dinge sind auch in anderen Sprachen schlechte Angewohnheiten, auf deren Vermeidung bei Python besonders viel Wert gelegt wird, um sauberen, gut lesbaren Code zu erhalten. Ich weiß wie gesagt nicht, ob das bei dem Video auch so ist. Aber es wäre nicht ungewöhnlich.
Ja das ist natürlich alles Käse.
Wie schon geschrieben der Code ist genau so im Video wie eingefügt.

Wenn da soviel Schrott auf dem Markt ist und jeder alles anbieten kann macht es für die Programmieranfänger nicht unbedingt einfacher das Programmieren zu erlernen.

Wo finde ich denn die wertvollen Tipps wie ich am besten den Code: formatieren, strukturieren und analysieren sollte. habe das nicht gefunden.

Arbeite gerade das Buch: "Programmieren von Kopf bis Fuss an" und hoffe das es besser ist obwohl es dort erst einmal ums Gehirn gerechte lernen geht und nicht um die Sortierung des Codes. Das soll wohl in einem anderem Buch erklärt werden. Da empfiehlt der Autor: dieses https://www.amazon.de/Einf%C3%BChrung-P ... +in+python

Kennt jemand die Bücher"Von Kopf bis Fuss?
Hat jemand damit gute Erfahrungen gemacht?
Habe den Tipp vom Freund bekommen der programmiert.
Habe bei Amazon darüber viele Lobeshymnen gesehen.

Re: 1xAlle Fehler

Verfasst: Freitag 3. November 2017, 10:40
von kbr
@paradiesvogel24: Die Kopf bis Fuß Reihe verfolgt einen didaktischen Ansatz, der insbesondere für Leser, die bei einem neuen Thema den Wald vor lauter Bäumen nicht mehr sehen und von allem erschlagen sind, hilfreich sein kann. Das ist schonmal positiv; als Nachschlagewerke sind sie ungeeignet. Ob der Inhalt dagegen gut ist, hängt wieder von den einzelnen Autoren ab. Da mag die Qualität variieren.

Das Buch von Mark Lutz ist zu empfehlen, aber auch ziemlich weitschweifig. Je nach Vorwissen muß das kein Nachteil sein. Trotz komischen Cover ist auch das folgende Buch gut für Einsteiger: Python Crashkurs.