Bei tkinter Eingabe in Float

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.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Hallo zusammen,
Ich will gleich mein Problem erklären: Hier der Code

Code: Alles auswählen

import tkinter

root=tkinter.Tk()

root.minsize(600,600)

def eingab():
    lb=tkinter.Label()
    filename='Butterbrot.txt'
    file=open('Butterbrot.txt')
    lb["text"] = file.read()
    lb.pack()
    


b2=tkinter.Button(root, text="abrufen", command=eingab)
b2.pack()

def hinzu():
    e = tkinter.Entry(root)
    e.pack()
    button = tkinter.Button(root, text="abgeben", command=get())
    button.pack()
    lb=tkinter.Label()
    lb["text"] = "Betrag eingeben"
    lb.pack()
def get():
    e=tkinter.Entry(root)
    neu=e.get()

    filename = "Butterbrot.txt"
    myfile = open('Butterbrot.txt', 'r')
    while myfile.readline():
        f=myfile.readline()
    
        
    f=f.split("/")[-1]
    letztes=float(f)

    jetzt=letztes+neu

    lb=tkinter.Label()
    lb["text"] = myfile.read()
    lb.pack()
    
b1=tkinter.Button(root, text="hinzufügen", command=hinzu)
b1.pack()

root.mainloop()
jetzt möchte ich aber das hier in einem Float haben:

Code: Alles auswählen

def get():
    e=tkinter.Entry(root)
    neu=e.get()
Aber wenn ich jetzt z.B. neu=float(neu) eingebe, kommt da die normale Fehlermeldung, dass man einen str nicht in einen Float umrechnen kann. Wie kann ich jetzt aber trotzdem mit der Eingabe eine Rechnung durchführen?

Mfg
Christian
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rennmaus: `float()` ist schon richtig, die Eingabe muss halt etwas sein, das man in eine Zahl umwandeln kann. Da man nicht weiss ob der Benutzer sich da immer dran hält, muss man den Fall das es nicht umwandelbar ist, halt entsprechend behandeln. Hat letztlich nicht wirklich etwas mit Tk zu tun, denn bei Konsolenprogrammen hat man ja genau das gleiche Problem.

Was natürlich völliger Quatsch ist, ist das erstellen eines `Entry`-Objekts und dann *sofort* den Inhalt davon abzufragen. Das ist *immer* die leere Zeichenkette, denn da konnte ja zu dem Zeitpunkt noch gar nichts eingegeben werden.

Du bist anscheinend noch nicht bereit für GUI-Anwendungen. Gewöhn Dir diese Abkürzungen ab und vergibt ordentliche Namen und beschäftige Dich mit objektorientierter Programmierung. Also eigene Klassen schreiben. Denn das ist Voraussetzung für jede nicht-triviale GUI.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

@rennmaus: da ist so vieles falsch.
Benutze keine globalen Variablen, und damit keinen ausführbaren Code auf oberster Ebene. Benutze keine Abkürzungen, was soll denn `eingab` sein? Vergangenheitsform?
command erwartet eine Funktion, und nicht den Rückgabewert eines Funktionsaufrufs.
Die Variable `filename` wird nie benutzt. Die `while`-Schleife tut nicht das, was Du denkst. Das sollte wohl eine for-Schleife sein, um bis zur letzten Zeile zu iterieren. `myfile.read()` liefert dann zum Schluß garantiert einen leeren String.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Code: Alles auswählen

import tkinter

root=tkinter.Tk()

root.minsize(600,600)


lb=tkinter.Label()
filename='Butterbrot.txt'
file=open('Butterbrot.txt')
lb["text"] = file.read()
lb.pack()
    



def get():
    neu = e.get()

    filename = "Butterbrot.txt"
    myfile = open('Butterbrot.txt', 'r')
    while myfile.readline():
        f=myfile.readline()
            
    f=f.split("/")[-1]
    letztes=float(f)

    jetzt=letztes+neu

    lb=tkinter.Label()
    lb["text"] = jetzt
    lb.pack()

e = tkinter.Entry(root)
e.pack()
lb=tkinter.Label()
lb["text"] = "Betrag eingeben"
lb.pack()
button = tkinter.Button(root, text="abgeben", command=get())
button.pack()



root.mainloop()
Ich habe ihn nochmal überarbeitet, wahrscheinlich ist er nicht besser geworden, aber das hat ja Zeit. Die while-Schleife funktioniert bei mir aber in einem anderem Programm ganz super aber hier nicht, obwohl ich sie genau gleich abgeschrieben habe...

EDIT: for schleife funktioniert super, danke an @Sirius3
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rennmaus: Die ``while``-Schleife funktioniert nicht ganz super. Die könnte zufällig funktionieren wenn die Datei immer eine gerade Anzahl von Zeilen hat. Aber selbst dann wäre das falsch das so auszudrücken.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Bei mir ist es gerade so, dass noch bevor ich den Knopf gedrückt habe, versucht das Programm das umzuformen, deshalb wird bei mir der Knopf auch garnicht mehr erzeugt...
@__Blackjack__ danke für die Tipps :)
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rennmaus: *Du* rufst ja auch *vor* dem Erstellen des `Button`-Objekts die `get()`-Funktion auf. `command` muss man die Funktion übergeben und nicht deren Rückgabewert.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Inwiefern 'command' muss man die Funktion übergeben? Bei mir steht doch beim Button nach Text, command=get()
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rennmaus: Ja und das bedeutet „rufe die Funktion `get()` auf und verwende deren Rückgabewert als `command`-Argument“. Du *rufst die Funktion auf*.

Code: Alles auswählen

In [78]: def f(): print("Test")                                                 

In [79]: f()  # Aufruf der Funktion `f`                                                             
Test

In [80]: f  # Die Funktion `f`.
Out[80]: <function __main__.f()>
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

OK, neue Antwort neues Problem. Ich habe es jetzt geändert, so wie du es geschrieben hast, aber er übernimmt nicht 'neu' als Variable, deshalb kommt bei mir immer die Fehlermeldung : Name 'neu' is not defined
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

@rennmaus: bitte Code und komplette Fehlermeldung posten.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Code: Alles auswählen

import tkinter

root=tkinter.Tk()

root.minsize(600,600)


lb=tkinter.Label()
filename='Butterbrot.txt'
file=open('Butterbrot.txt')
lb["text"] = file.read()
lb.pack()
    
def get():
    neu = e.get()
    neu=float(neu)

e = tkinter.Entry(root)
e.pack()
lb=tkinter.Label()
lb["text"] = "Betrag eingeben"
lb.pack()
button = tkinter.Button(root, text="abgeben", command=get)
button.pack()


filename = "Butterbrot.txt"
myfile = open('Butterbrot.txt', 'r')
for i in myfile.readline():
        f=myfile.readline()
            
f=f.split("/")[-1]
letztes=float(f)

jetzt=letztes+neu

lb=tkinter.Label()
lb["text"] = jetzt
lb.pack()





root.mainloop()
Fehlermeldung:

Code: Alles auswählen

jetzt=letztes+neu
NameError: name 'neu' is not defined
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Update: Ich habe es jetzt mit global geschafft, jetzt folgendes Problem :| :
Ich möchte ja die beiden addieren, aber jetzt taucht bei mir immer auf:
jetzt=letztes+neu
TypeError: unsupported operand type(s) for +: 'float' and 'str'
Dabei konvertiere ich doch die beiden in einen Float um...
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

GUIs sind anscheinend noch zu komplex für Dich. Schreibe erst einmal die Programmlogik ohne GUI. Ordentlich. Mit sinnvollen Variablennamen, und Funktionen und ohne globale Variablen.

Ich sehe jetzt erst, dass Du die for-Schleife komplett falsch hast, aber das fällt Dir nicht auf, weil Du nicht sauber testest. Jeder Teil eines Programms (am besten als Funktion geschrieben) muß getestet werden, bevor man weitermacht. Ja, das ist nervend, weil das wenig Spaß bringt, aber so stückelst Du nur nicht funktionierende Teile zusammen und fragst Dich dann, warum etwas nicht funktioniert. Die Antwort: von vorne bis hinten funktioniert es nicht.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Oke, dann bleibe ich bei meiner Version ohne gui. Danke an euch alle
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Nur kurz, wie ist denn die for Schleife richtig?
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Das gab es doch schon im letzten Thread.
Also hier Dein Code:

Code: Alles auswählen

myfile = open('Butterbrot.txt', 'r')
for i in myfile.readline():
        f=myfile.readline()
            
f=f.split("/")[-1]
letztes=float(f)
Das my in myfile bietet keinen Mehrwert. `i` ist ein irreführender Name, weil man bei `i` an ein ganze Zahl denkt. Die for-Schleife geht aber über die einzelnen Zeichen der ersten Zeile der Datei, die Du mit `myfile.readline()` liest. Also wäre character der richtige Name. Schon da sollte klar sein, dass die Schleife nicht das macht, was Du denkst. So lange die for-Schleife läuft, liest Du Zeilen. Die werden an `f` gebunden, auch kein sehr guter Name. Die Datei mycode wird nicht wieder geschlossen.

Dateien öffnet man innerhalb eines with-Statements. Du willst tatsächlich die letzte Zeile, also mußt Du über alle Zeilen iterieren.

Code: Alles auswählen

with open("Butterbrot.txt") as lines:
    for line in lines:
        pass
last_number = float(line.rsplit("/",1)[-1])
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und auch hier noch mal die Anmerkungen die im anderen Thema auch schon gemacht habe: Falls die Datei leer sein kann oder die letzte Zeile keinen "/" enthalten kann, muss man überlegen wie der Code da robust und sinnvoll drauf reagieren kann.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

@__Blackjack__ die Datei wird nie leer sein, und ein / ist in jeder Zeile vorhanden (3x) ;)

Der Code Funktionen bei mir leider nicht, bekomme wieder einen leeren String zurück...
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

@rennmaus: Bei dem Code von Sirius3 ist last_number hinterher ein leerer String? Dann steht in der letzten Zeile rechts vom letzten / nichts.
Antworten