Seite 1 von 1
Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 15:55
von Sdlogni
Hallo zusammen
Ich beschäftige mich ganz neu mit Python und Programmieren ganz allgemein.
bei meiner ersten Übung stosse ich an Grenzen:
hier der code:
Code: Alles auswählen
print("Benzinrechner")
eingabeKm = input("Anzahl gefahrene km: ")
km = eval(eingabeKm)
if km < 50:
print("fahre noch ein paar KM weiter, bis du den Verbrauch ausrechnen lassen willst")
eingabeWeitereFrage = input("Haben Sie noch weitere Fragen? (Y/N:) ")
WeitereFrage = eval(eingabeWeitereFrage)
if WeitereFrage == N:
print("dann machen wir hier Schluss")
else:
eingabeLiter = input("getankte Menge Benzin in Liter: ")
Liter = eval(eingabeLiter)
print("der durchschnittliche Verbrauch liegt bei", Liter * 100 / km , "Liter pro 100km")
wie muss ich es anstellen, dass ich nach der Engabe bei weitere Frage mit Y oder N weiter komme?
Irgendwie muss ich N ode Y als Variable deklarieren, aber wie und wo?
Danke für euren Tip.
Gruss
Nik
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 16:27
von Sirius3
@Sdlogni: was willst Du denn, was passiert, wenn jemand »Y« oder »N« eintippt?
Vergiß, daß es »eval« gibt. Wenn Du einen String in eine Zahl umwandeln willst, nimm »float« oder »int«. Bei der Frage nach "Y/N" hast Du schon einen String, den Du direkt vergleichen kannst »WeitereFrage == "N"«.
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 16:29
von BlackJack
@Sdlogni: Als erstes solltest Du `eval()` nicht verwenden. Um eine Eingabe in eine ganze Zahl umzuwandeln gibt es die `int()`-Funktion und für Gleitkommazahlen die `float()`-Funktion. Und wenn man die Eingabe als Zeichenkette haben möchte dann macht man gar nichts damit, denn `input()` liefert ja bereits eine Zeichenkette.
`eval()` führt jeden beliebigen Python-Ausdruck aus. Der Benutzer kann da sonst was eingeben. Auch Eingaben die alle Deine Dateien löschen. Selbst wenn der Benutzer nichts bösartiges plant, ist es schwer *sicher* mit `eval()` zu operieren, weil bei beliebigen Ausdrücken auch beliebige Fehler/Ausnahmen auftreten können. Das abzusichern und sinnvoll zu behandeln ist nicht leicht und zudem halt auch völlig überflüssig wenn man einfach nur eine Zahl haben möchte.
Du könntest `N` natürlich vorher definieren, aber warum? An der Stelle kannst Du den Wert den Du an `N` binden würdest auch einfach direkt angeben.
Lesetipp:
Style Guide for Python Code.
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 16:40
von Axel-Erfurt
python 2
Code: Alles auswählen
print("Benzinrechner")
eingabeKm = raw_input("Anzahl gefahrene km: ")
km = str(eingabeKm)
if int(km) < 50:
print("fahre noch ein paar KM weiter, bis du den Verbrauch ausrechnen lassen willst")
WeitereFrage = raw_input("Haben Sie noch weitere Fragen? (y/n:)")
if str(WeitereFrage) == "n":
print("dann machen wir hier Schluss")
else:
print("dann machen wir hier weiter") # was auch immer du dann noch fragen willst
else:
eingabeLiter = raw_input("getankte Menge Benzin in Liter: ")
Liter = float(eingabeLiter)
print("der durchschnittliche Verbrauch liegt bei " + str(Liter * 100 / int(km)) + " Liter pro 100 km")
python3
Code: Alles auswählen
print("Benzinrechner")
eingabeKm = input("Anzahl gefahrene km: ")
km = str(eingabeKm)
if int(km) < 50:
print("fahre noch ein paar KM weiter, bis du den Verbrauch ausrechnen lassen willst")
WeitereFrage = input("Haben Sie noch weitere Fragen? (y/n:)")
if str(WeitereFrage) == "n":
print("dann machen wir hier Schluss")
else:
print("dann machen wir hier weiter") # was auch immer du dann noch fragen willst
else:
eingabeLiter = input("getankte Menge Benzin in Liter: ")
Liter = float(eingabeLiter)
print("der durchschnittliche Verbrauch liegt bei " + str(Liter * 100 / int(km)) + " Liter pro 100 km")
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 16:51
von Sirius3
@Axel-Erfurt: `raw_input` bzw. `input` liefern bereits Strings, der Aufruf von `str` ist also überflüssig. Es macht auch keinen Sinn, jedesmal, wenn man eine Zahl braucht, `km` wieder umzuwandeln. Kilometer sind von Natur aus Zahlen, dann sollte man sie auch gleich so speichern. Statt Strings mit + zusammenzustückeln, kann man wie Sdlogni mehrere Parameter an `print` übergeben, oder man benutzt `.format`.
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 18:27
von Sdlogni
Danke für die raschen Feedbacks.
@Sirius3: es wäre schon toll, wenn bei ja oder auch bei nein ein weiterer Text angezeigt würde.
Das Eval habe ich heute Nachmittag irgendo aufgeschnapt.
Werde demnach versuchen, das ganze Konstrukt ohne diese Funktion aufzubauen.
@Axel Erfurt: ich werde Deine Vorschläge anschauen und versuchen, diese zu verstehen.
Werde mich bestimmt wieder melden, sei es bei Erfolg oder auch Misserfolg
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 21:44
von /me
Sdlogni hat geschrieben:Das Eval habe ich heute Nachmittag irgendo aufgeschnapt.
Das klingt für einen erfahrenen Python-Entwickler jetzt so ähnlich wie: "Heute habe ich was von
Ebola gehört und es mir sofort zugelegt."
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 22:10
von Axel-Erfurt
hier mal als GUI Version
Code: Alles auswählen
#!/usr/bin/python
# -- coding: utf-8 --
import Tkinter as tk
import tkSimpleDialog, tkMessageBox
def ergebnis(self):
label_4.config(text="")
var_1 = len(entry_1.get())
var_2 = len(entry_2.get())
if var_1 > 0 and var_2 > 0:
km = float(entry_1.get().replace(",", "."))
liter = float(entry_2.get().replace(",", "."))
if km > 50:
ausrechnen(km, liter)
else:
result = tkMessageBox.askyesno("Frage", "Fahren Sie noch ein paar km weiter, bis Sie den Verbrauch ausrechnen lassen!\n\nHaben Sie noch weitere Fragen?")
if result == True:
tkMessageBox.showinfo("Info", "Dann machen wir hier weiter")
weiter()
else:
tkMessageBox.showinfo("Info", "Dann machen wir hier Schluss")
quit()
else:
label_4.config(text="Eintrag fehlt!")
label_4.configure(fg="red")
def nextfield(self):
entry_2.focus()
entry_2.select_range(0, tk.END)
def ausrechnen(km, liter):
verbrauch = round(liter * 100 / km, 2)
result = ('{0} {1}'.format(verbrauch , "Liter pro 100 km"))
label_4.config(text=result)
if verbrauch > 6:
label_4.configure(fg="red")
else:
label_4.configure(fg="green")
def weiter():
tkMessageBox.showinfo("Info", "funktioniert!") # kann dann weg wenn code
# code für weiter hier
root = tk.Tk()
root.title("Benzinverbrauch")
root.resizable(width=False, height=False)
root.geometry("260x130")
label_1 = tk.Label(root, text="gefahrene km").pack()
entry_1 = tk.Entry(root, width=10, justify="center")
entry_1.pack()
entry_1.bind("<Return>", nextfield)
label_2 = tk.Label(root, text="getankte Liter").pack()
entry_2 = tk.Entry(root, width=10, justify="center")
entry_2.pack()
entry_2.bind("<Return>", ergebnis)
label_3 = tk.Label(root, text="Verbrauch:").pack()
label_4 = tk.Label(root, text="", font=('', 13, "bold"))
label_4.pack()
entry_1.insert(0, "112,7")
entry_2.insert(0, "6,5")
entry_1.focus()
entry_1.select_range(0, tk.END)
root.mainloop()
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 23:05
von Sirius3
@Axel-Erfurt: Variablennamen sollten aussagekräftig sein. Was hast Du Dir dabei gedacht die Länge eines Strings `var_1` zu nennen? `result` oder meintewegen `result_label` ist doch viel lesbarer als `label_4`. Weißt Du welchen Wert die ganzen anderen `label_x`-Variablen haben? Explizit auf »True« zu prüfen ist unnötig. Statt mit `round` zu runden, gibt man im Formatstring die Nachkommastellen an; literale Strings schreibt man direkt in den Formatstring. Eine feste Fenstergröße vorzugeben ist eine schlechte Idee; bei mir ist z.B. die Ergebniszeile halb abgeschnitten.
Um den Überblick in größeren Projekten zu behalten, darf man keine globalen Variablen benutzen. Das heißt auch, dass alles ab Zeile 44 in eine Funktion gehört und um die ganzen Entry-Variablen in die Funktionen zu bekommen, müßte man eigentlich auch eine Klasse mit Methoden schreiben. Scheinbar hattest Du auch diesen Gedanken, da alle Deine Funktionen ein nicht benutztes self-Argument haben (was eigentlich event heißen müßte, so wie sie benutzt werden).
Code: Alles auswählen
#!/usr/bin/python
# -- coding: utf-8 --
import Tkinter as tk
import tkSimpleDialog, tkMessageBox
class Verbrauchsrechner(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
tk.Label(self, text="gefahrene km").pack()
self.km = tk.Entry(self, width=10, justify="center")
self.km.pack()
self.km.bind("<Return>", self.nextfield)
tk.Label(self, text="getankte Liter").pack()
self.liter = tk.Entry(self, width=10, justify="center")
self.liter.pack()
self.liter.bind("<Return>", self.ergebnis)
tk.Label(self, text="Verbrauch:").pack()
self.result = tk.Label(self, text="", font=('', 13, "bold"))
self.result.pack()
self.km.insert(0, "112,7")
self.liter.insert(0, "6,5")
self.km.focus()
self.km.select_range(0, tk.END)
def ergebnis(self, _event):
try:
km = float(self.km.get().replace(",", "."))
liter = float(self.liter.get().replace(",", "."))
except ValueError:
self.result['text'] = "Zahl erwartet"
self.result['fg'] = "red"
else:
if km > 50:
verbrauch = liter * 100 / km
self.result['text'] = '{:.2f} Liter pro 100 km'.format(verbrauch)
self.result['fg'] = "red" if verbrauch > 6 else "green"
else:
result = tkMessageBox.askyesno("Frage", "Fahren Sie noch ein paar km weiter, bis Sie den Verbrauch ausrechnen lassen!\n\nHaben Sie noch weitere Fragen?")
if result:
tkMessageBox.showinfo("Info", "Dann machen wir hier weiter")
self.weiter()
else:
tkMessageBox.showinfo("Info", "Dann machen wir hier Schluss")
self.parent.quit()
def nextfield(self, _event):
self.liter.focus()
self.liter.select_range(0, tk.END)
def weiter(self):
# code für weiter hier
tkMessageBox.showinfo("Info", "funktioniert!")
def main():
root = tk.Tk()
root.title("Benzinverbrauch")
verbrauch = Verbrauchsrechner(root)
verbrauch.pack()
root.mainloop()
if __name__ == '__main__':
main()
Re: Ja oder nein Abfrage
Verfasst: Sonntag 29. Januar 2017, 23:28
von Axel-Erfurt
Wieso hat man beim Kopieren aus einer Python Codebox immer Leerzeichen am Anfang jeder Zeile?