Seite 1 von 1
Programm Wiederholen
Verfasst: Dienstag 15. August 2023, 18:20
von Baronheart
Guten Abend,
ich entschuldige mich jetzt schonmal für diese dumme Frage, jedoch bin ich noch ein blutiger Anfänger und ich habe auf meine Frage keine plausible Antwort gefunden.
Ich habe ein einfaches Taschenrechner Programm geschrieben (Bei Verbesserungsvorschlägen meldet euch gerne). Nun das Problem, ich würde gerne am ende der Rechnung jedesmal fragen ob noch eine Aufgabe ausgerechnet werden soll, dies wird auch einmal gemacht, jedoch nur einmal. Danach geht der Taschenrechner in eine endlos schleife und es wird nicht mehr nachgefragt.
Code: Alles auswählen
print("Taschenrechner")
zahl1 = eval(input("Bitte geben Sie die erste Zahl ein :"))
zahl2 = eval(input("Bitte geben Sie die zweite Zahl ein :"))
Zeichen = input("Bitte geben Sie die den Operator ein :")
if Zeichen == "+":
print("Das Ergebnis ist:" ,zahl1+zahl2)
elif Zeichen == "-":
print("Das ergebnis ist:" ,zahl1-zahl2)
elif Zeichen == "*":
print("Das Ergebnis ist:" ,zahl1*zahl2)
elif Zeichen == "/":
print("Das Ergebnis ist: " ,zahl1/zahl2)
else:
print("falsches Zeichen")
wiederholung = input("Moechten Sie noch eine Rechnung? Ja/Nein: ")
while wiederholung == "Ja" or wiederholung == "ja":
zahl1 = eval(input("Bitte geben Sie die erste Zahl ein :"))
zahl2 = eval(input("Bitte geben Sie die zweite Zahl ein :"))
Zeichen = input("Bitte geben Sie die den Operator ein :")
if Zeichen == "+":
print("Das Ergebnis ist:" ,zahl1+zahl2)
elif Zeichen == "-":
print("Das ergebnis ist:" ,zahl1-zahl2)
elif Zeichen == "*":
print("Das Ergebnis ist:" ,zahl1*zahl2)
elif Zeichen == "/":
print("Das Ergebnis ist: " ,zahl1/zahl2)
else:
print("falsches Zeichen")
LG und einen schönen Abend

Re: Programm Wiederholen
Verfasst: Dienstag 15. August 2023, 18:58
von noisefloor
Hallo,
du musst nur die Schleife anders setzen.
Beispiel:
Code: Alles auswählen
>>> while True:
... print('Hallo Schleife!')
... answer = input('Nochmal (ja für nochmal, alles andere für Ende)? ')
... if not answer.lower()=='ja':
... break
...
Zum Code gibt's einiges zu sagen, leider fehlt mir gerade die Zeit. Jedenfalls _nie_ eval benutzen, wenn man nicht ganz ganz genau weiß, was man tut. Das kann ein massives Sicherheitsrisiko sein.
Gruß, noisefloor
Re: Programm Wiederholen
Verfasst: Dienstag 15. August 2023, 21:43
von __blackjack__
Und hier ist `eval()` auch überhaupt nicht sinnvoll, denn für das umwandeln einer Zeichenkette in eine Zahl gibt es die `float()`-Funktion.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 08:13
von Sirius3
`eval` darf in einem sauberen Programm nicht vorkommen, zum Umwandeln von Zahlen benutzt man `float`. Variablennamen werden generell klein geschrieben, Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 1, mal 4 und mal 5.
Kopierten Code sollte man beim Programmieren vermeiden. Du hast den eigentlichen Taschenrechner zweimal im Programm. Das läßt sich vermeiden, indem man die Schleife umstellt.
Du fragst einmal für der while-Schleife das `wiederholung` ab, und änderst es innerhalb der Schleife nie. Das bedeutet, die Schleife läuft entweder nie oder unendlich oft durch. Die Voraussetzungen für Schleifenbedingung muß sich innerhalb der Schleife ändern, sonst macht man etwas falsch (außer bei gewollten Endlosschleifen;-)
Ein typischer Schleifentyp ist der, bei dem die Bedingung am Ende abgefragt wird; dafür gibt es in Python kein extra Konstrukt, sondern man muß sich mit einer Endloschleife und break behelfen:
Code: Alles auswählen
print("Taschenrechner")
while True:
zahl1 = float(input("Bitte geben Sie die erste Zahl ein :"))
zahl2 = float(input("Bitte geben Sie die zweite Zahl ein :"))
rechenoperation = input("Bitte geben Sie die den Operator ein :")
if rechenoperation == "+":
print("Das Ergebnis ist:", zahl1 + zahl2)
elif rechenoperation == "-":
print("Das ergebnis ist:", zahl1 - zahl2)
elif rechenoperation == "*":
print("Das Ergebnis ist:", zahl1 * zahl2)
elif rechenoperation == "/":
print("Das Ergebnis ist: ", zahl1 / zahl2)
else:
print("falsches Zeichen")
wiederholung = input("Möchten Sie noch eine Rechnung? Ja/Nein: ")
if wiederholung.lower() != "ja":
break
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 10:00
von snafu
Sirius3 hat geschrieben: Mittwoch 16. August 2023, 08:13
`eval` darf in einem sauberen Programm nicht vorkommen, zum Umwandeln von Zahlen benutzt man `float`.
Schon verständlich bezüglich float(). Aber bei solchen pauschalen Aussagen muss man sich fragen, warum eval() dann existiert. Ich denke schon, dass es seinen Zweck hat. Nur wird dieser insbesondere von Anfängern oft nicht sinnvoll genutzt.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 10:28
von __deets__
Dafuer muss es keine gute Begruendung geben, weil Python ein Interpreter ist, hat man's halt mal eingebaut - und die Konsequenzen nicht ueberissen. Aber wenn es einmal drin ist, bekommt man es auch nicht mehr raus. Und mir faellt auch wirklich kein echter Zweck ein.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 10:37
von __blackjack__
@snafu: Echt jetzt?
Das muss man sich nicht fragen. Nur weil etwas existiert, muss man das nicht benutzen, und Sachen die existieren, können Sachen sein die man nicht benutzen sollte. So ganz pauschal. Globale Variablen existieren. ``global`` existiert. `os.system()` existiert. Man kann SQL als Zeichenkette mit Werten zusammenbasteln und das an Datenbanken verfüttern. Man kann alles in Klassen stecken und jede Klasse einzeln in ein Modul. Hat alles ganz pauschal nichts in sauberen Programmen verloren.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 13:08
von DeaD_EyE
eval wird sogar sinnvoll eingesetzt und es ist sogar schneller.
Wenn man weiß, was man macht, dann darf man auch
eval nutzen.
Code: Alles auswählen
[andre@andre-Fujitsu-i5 jinja]$ grep -R "eval("
tests/test_nativetypes.py:def test_no_intermediate_eval(env):
src/jinja2/nativetypes.py: return literal_eval(
src/jinja2/nodes.py: representation (objects where ``eval(repr(x)) == x`` is true).
src/jinja2/lexer.py: value = literal_eval(value_str.replace("_", ""))
Es gibt sicherlich noch andere, sehr prominente Beispiele. Ich finde das immer so witzig, dass einerseits immer herum theoretisiert wird, aber anderseits Bibliotheken genutzt werden, die komplett gegensätzlich sind und diese Tricks anwenden.
Wusstet ihr, dass jinja2 die Templates mit eval befüllt?
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 13:26
von __deets__
Ich finde es ironisch, das du zum vermeintlichen Beleg, dass eval ja durchaus benutzt wird, einen test-case case mit literal_eval anführst, das >90% aller Nutzungen von eval ablöst. Weil es Python literale übersetzt, ohne weitere Seiteneffekte. Was die Nutzung von eval auch hier und anderswo unnötig macht.
Das jinja das macht, ist kein Beleg dafür, das es gut ist. Sondern eher dafür, dass es ähnlich zu log4j ein Problem darstellt, das nur darauf wartet, ausgenutzt zu werden.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 13:29
von __blackjack__
@DeaD_EyE: Dir ist schon klar das Deine Shell-Session da kein einziges `eval()` zeigt das da ausgeführt wird‽
Jinja benutzt kein `eval()` sondern `exec()` und Jinja ist als Template-Bibliothek auch ein besonderer Fall.
Und natürlich gibt es auch Gründe ``global`` zu verwenden. Trotzdem darf man NIEMALS ``global`` verwenden, in einem sauberen Programm.
Das Bibliotheken die komplett grundsätzlich sind, solche Tricks anwenden ist ja auch okay. Solche Bibliotheken schreibt man ja auch nicht selbst.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 19:06
von Baronheart
Vielen Dank für eure Hilfe, genauso sollte das Programm laufen. Jetzt kann ich die Methode lernen
Eine wichtige Sache für meinen Lerneffekt. Was ist am 'eval' Befehl ein Sicherheitdrisiko?
Ich hatte es so gelernt das der eval Befehl die Eingabe automatisch richtig einsortiert in Zahl Buchstabe oder Zeichen. Für mich wirkte es wie eine sinnvolle Methode.
Lg
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 19:23
von Sirius3
Wenn Du das so gelernt hast, dann hast Du noch nie Buchstaben bei eval eingegeben. Laß Dich überraschen.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 19:42
von __deets__
eval erlaubt prinzipiell das ausführen beliebigen Codes. Wen du also einen Benutzer Eingaben mache lässt, kann der damit im Zweifel so nette Dinge wie deine ganze Platte löschen anstellen. Etc pp.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 20:00
von __blackjack__
Davon mal abgesehen kann man auch Fehleingaben nicht wirklich sinnvoll behandeln. Bei `float()` kann es einen `ValueError` geben auf den man reagieren kann. Bei `eval()` kann so gut wie alles passieren. Angefangen mit Syntaxfehlern, die man sonst eigentlich *nie* behandeln muss, weil das eigentlich immer ein Problem ist das man im eigenen Code lösen sollte.
Re: Programm Wiederholen
Verfasst: Mittwoch 16. August 2023, 20:14
von noisefloor
Hallo,
zum Thema löschen via eval:
https://realpython.com/python-eval-func ... es-of-eval zeigt, wie an zumindest des aktuelle Homeverzeichnis ohne weitere Rückfragen via eval löscht.
Unter
https://nedbatchelder.com/blog/201206/e ... erous.html gibt es weitere Beispiele.
Wie schon gesagt wurde: einfach nicht benutzen. Was nicht heißt, dass es nutzlos ist.
Gruß, noisefloor
Re: Programm Wiederholen
Verfasst: Donnerstag 17. August 2023, 18:29
von Baronheart
Vielen Dank. Dann werde ich demnächst float für Zahlen benutzen.
Ich hätte noch eine Frage (off-Topic), mein Programm zeigt sobald ich ein ä, ü, ö verwende eine Fehlermeldung an. Ist dies eine Einstellungssache oder kann man das irgendwie umgehen?
Re: Programm Wiederholen
Verfasst: Donnerstag 17. August 2023, 19:10
von Sirius3
Das liegt wahrscheinlich daran, dass Dein Editor falsch eingestellt ist. Du mußt die Datei UTF8-kodiert speichern.