Datentyp abgleichen und in Schleife einbinden

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.
Antworten
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Hey Leute mein Problem ist quasi das Urgestein der Probleme aber kurioserweise auf keiner Seite wirklich zufriedenstellend gelöst worden >>> soweit ich es finden konnte <<<.
Es geht darum das ich eine Eingabe durch den Benutzer haben möchte und dieser einen Zahlenwert eingeben soll.
Danach möchte ich erstmal prüfen ob der eingegebene Wert auch eine Zahl ist oder ein Zeichen.
Wenn es ein Zeichen ist dann soll der Benutzer erneut aufgefordert werden einen Wert einzugeben usw bis der eingegebene Wert auch ein zulässiges Format hat.

Mein Problem dabei ist der entstehende ValueError bei folgendem Befehl:

eingabe = float(input("Bitte Preis eingeben: "))

Ich habe bereits herausgefunden das ich hier mit try / except rangehen sollte also habe ich folgendes getestet:

try:
eingabe = float(input("Bitte Preis eingeben: "))
except ValueError:
print("Falchse Eingabe !)
eingabe = float(input("Bitte Preis eingeben: "))

Dadurch wird die Abfrage allerdings nur 1x durchgegangen nun weiß ich nicht wirklich wo und wie ich die while-Schleife einsetzen muss.
Ich habe zwar die Vermutung das ich diese vor der try/except Abfrage initialisieren muss, nur stelle ich mich wahrscheinlich einfach zu dumm an dafür oder bin damit generell auf dem Holzweg ^^

Oder gibt es für dieses Szenario eventuell noch eine wesentlich elegantere und vor allem effinzientere Lösung ?
Vielleicht in Form einer Liste oder eines Dictionarys ?

Wie gesagt ich bin aktuell ziemlich in der Bredouille deswegen....

Danke schonmal im voraus.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Bitte beim nächsten Mal die Code Tags im Forum benutzen, da sonst die Einrückung verloren geht. Die while Schleife ist über dem Try/Except zu starten.

Code: Alles auswählen

while True:
    try:
        eingabe = float(input("Bitte Preis eingeben: "))
        break
    except ValueError:
        print("Falchse Eingabe !")
        
        
print("korrekte Eingabe")
Zuletzt geändert von Jankie am Freitag 13. September 2019, 14:01, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da fehlt der entscheidende Abbruch wenn die Eingabe erfolgreich war. ZB mit break oder return wenn man das in eine Funktion packt.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Sorry, falsch verstanden. Habe es oben korrigiert.
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Wow ich danke dir vielmals =)

Ich habs mir offensichtlich einfach nur bedeutend schwerer gemacht als es war, hab wohl das Grundkonzept von try/except nicht ganz verstanden gehabt aber nun scheints ja doch recht überschaubar zu sein danke vielmals :D
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Das kann man auch ohne try/except coden.

Code: Alles auswählen

while True:
    eingabe = input("Bitte Preis eingeben: ")
    if all([char in '.0123456789' for char in eingabe]):
        zahl = float(eingabe)
        break
    print("Nur Ziffern und Punkt erlaubt!")

print(zahl)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Jagut ich geh jetzt schon davon aus das die try/except Lösung dann wohl die komfortablere Lösung ist aber ja genau in der Richtung hatte ich zu Beginn rumgedoktort ^^
Ich wusste nur nicht wie ich die Parameter festlegen kann jetzt weiß ich es danke auch dir :D
Benutzeravatar
__blackjack__
User
Beiträge: 13073
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ThomasL: Man kann, aber nicht so, denn der Benutzer könnte ja mal mehr als einen Punkt eingeben was dann wieder zu einer Ausnahme beim Umwandeln führt. Und bevor man sich da jetzt anfängt Code zu schreiben der das macht was `float()` sowieso schon macht – machen *muss* – kann man auch einfach die Ausnahme abfangen, die man aus Sicherheitsgründen *sowieso* abfangen sollte, auch wenn sie nie auftreten kann – theoretisch – mit einem ``assert False`` im ``except``-Zweig.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Leute nochmal etwas zum Thema, mir ist grade aufgefallen das ich meine Abfragen scheinbar stetig wiederholen muss um den Datentypabgleich vernünftig zu realisieren....
Ich habe jetzt die ganze Zeit versucht das Ganze etwas eleganter zu lösen indem ich versucht habe durch if-Anweisungen durch das try/except Konstrukt zu kommen aber egal was ich mache es geht nicht und ich muss scheinbar alles mehrfach schreiben...

Aber in der Programmierung soll man ja eben genau das vermeiden also suche ich eine Lösung für das Problem, um es mal zu verdeutlichen hier der Code:

Code: Alles auswählen

while True:
    try:
        literPreis = float(input("Bitte Preis eingeben: "))
        break
    except ValueError:
        print("Keine gültige Eingabe !")

while True:
    try:
        kilometer = float(input("Gefahrene Kilometer: "))
        break
    except ValueError:
        print("Keine gültige Eingabe !")

while True:
    try:
        verbrauch = float(input("Verbrauchter Sprit in Liter: "))
        break
    except ValueError:
        print("Keine gültige Eingabe !")
        
hundertKm = verbrauch / kilometer * 100
print(f"Der Verbrauch liegt bei {hundertKm:.2f} Liter auf 100 km.")
pphk = hundertKm * literPreis
print(f"Der Preis bedingt durch den Verbrauch auf 100km beträgt {pphk:.2f}€.")
gesamtPreis = verbrauch * literPreis
print(f"Der Gesamtpreis beläuft sich auf {gesamtPreis:.2f}€ bei {kilometer:.2f}km gefahrener Strecke.")
Ich schwofe bereits nebenbei durch gefühlt halb Google um euch nicht permanent auf den Schnuller zu gehen aber es lernt sich leider nicht so einfach wie ein Computerspiel .... ^^
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Schreibe ich das Ganze nun zusammen in ein try/except Konstrukt dann fängt er bei einer falschen Eingabe immer wieder beim ersten Parameter an, was ich aber nicht möchte....

Also das meine ich dann damit:

Code: Alles auswählen

while True:
    try:
        literPreis = float(input("Bitte Preis eingeben: "))
        kilometer = float(input("Gefahrene Kilometer: "))
        verbrauch = float(input("Verbrauchter Sprit in Liter: "))
        break
    except ValueError:
        print("Keine gültige Eingabe !")
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@Stievus: don't repeat yourself. Lagere die Abfrage in eine Funktion aus.
When we say computer, we mean the electronic computer.
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

sls hat geschrieben: Freitag 13. September 2019, 15:59 @Stievus: don't repeat yourself. Lagere die Abfrage in eine Funktion aus.
Jo exakt daran arbeite ich grade ich geb Laut von mir wenn ich eine Lösung habe ^^
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

So liebe Leute hier nun noch mein kleiner Nachtrag bzw meine Lösung für das Problem des mehrfach auftretendem try/except Konstrukts:

Code: Alles auswählen

def typabfrage():
    while True:
        try:
            wert = float(input("Wert angeben: "))
            break
        except ValueError:
            print("Falsche Eingabe !")
    return wert

print("Bitte Vebrauch angeben !")
verbrauch = typabfrage()
print("Bitte gefahrene Kilometer angeben !")
kilometer = typabfrage()
print("Bitte Preis pro Liter angeben !")
literPreis = typabfrage()

        
hundertKm = verbrauch / kilometer * 100
print(f"Der Verbrauch liegt bei {hundertKm:.2f} Liter auf 100 km.")
pphk = hundertKm * literPreis
print(f"Der Preis bedingt durch den Verbrauch auf 100km beträgt {pphk:.2f}€.")
gesamtPreis = verbrauch * literPreis
print(f"Der Gesamtpreis beläuft sich auf {gesamtPreis:.2f}€ bei {kilometer:.2f}km gefahrener Strecke.")
Ich hatte eigentlich gehofft eine Lösung zu finden bei der sich der ausgegebene Text innerhalb der Funktion abändern lässt aber so ist es aktuell für mich am besten zu lösen ^^
Nur damit man sieht ich gebe mir Mühe :P :)
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum übergibst du den gewünschten Text dann nicht einfach als Argument an deine Funktion?
Stievus
User
Beiträge: 8
Registriert: Freitag 13. September 2019, 12:54

Wie soll das bitte aussehen ? Ich kann mir darunter grade ehrlich gesagt nur schwer was vorstellen (Anfänger- Facepalm incoming....)
Meinst du sowas wie def typabfrage(x.....) oder wie gemeint ?
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Wenn du einen String an Print übergeben kannst, kannst du das auch an deine eigene Funktion. Die muss den Parameter natürlich deklarieren, und dann benutzen.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

eventuell so

Code: Alles auswählen

def typabfrage(inp_msg, error_msg):
    while True:
        try:
            wert = float(input(inp_msg))
            break
        except ValueError:
            print(error_msg)
    return wert

typabfrage("Wert angeben: ", "Falsche Eingabe !")
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Dabei fragst Du gar keinen Typ ab, sondern eine Zahl.

Code: Alles auswählen

def zahl_abfragen(text):
    while True:
        try:
            return float(input(text))
        except ValueError:
            print("Falsche Eingabe !")

verbrauch = zahl_abfragen("Bitte Vebrauch angeben !")
Benutzeravatar
__blackjack__
User
Beiträge: 13073
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Man könnte das dann auch noch in `positive_zahl_abfragen()` umbenennen und entsprechenden Code zum Testen hinzufügen. Denn bei keiner der abgefragten Grössen ist es sinnvoll negative Werte einzugeben. Benutzer machen so etwas aber.

Eine gültige Eingabe für die Kilometeranzahl wäre auch 0 — damit sollte dann die Berechnung aber auch klar kommen!
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten