Seite 1 von 1
Eingabenprüffunktion
Verfasst: Mittwoch 22. Juni 2011, 21:28
von derrick
Abend Leute,
es kommt ja ab und an mal vor, dass man prüfen muss ob der input eines Benutzers z.B. eine Zahl ist , damit ein Programm richtig funktioniert. Ich habe mir überlegt ob es z.B. sinnvoll wäre eine derartige Funktion zu schreiben:
Code: Alles auswählen
def int_input():
try:
digit = int(input("Enter a number: "))
return digit
except:
print("Only numbers are allowed")
int_input()
Dann kann man es sich sparen bei jeder Benutzereingabe in einem beliebigen Modul eine Überprüfung durchzuführen.
Natürlich ist obiges auch für so ziemlich jede andere Eingabe wie z.B. Buchstaben (.isalpha()) denkbar.
Was haltet ihr von einem solchen Vorgehen und gibt es soetwas möglicherweise schon vorgefertigt.
Grüße
derrick
Re: Eingabenprüffunktion
Verfasst: Mittwoch 22. Juni 2011, 21:36
von cofi
So eine Funktion ist generell eher weniger sinnvoll. Man will beispielsweise nicht immer eine Schleife, solange kein gültiger Wert übergeben wird. Wenn man die Funktion, um eine Option dafür erweitert, hat man am Ende mehr Ärger als Nutzen.
Konkret an der Implementierung: Man will eigentlich ein Prompt übergeben, der Nutzer wird sich freun, wenn man ihm sagt, dass er eine Zahl übergeben soll, aber nicht was sie repräsentiert.
Desweiteren ist die Rekursion unnötig und da Python nur eine bestimmte Rekursionstiefe zulässt, stösst man schnell an die Grenzen.
Re: Eingabenprüffunktion
Verfasst: Mittwoch 22. Juni 2011, 21:47
von deets
@cofi
Bei der Rekursionstiefe von Python ist wohl eher davon auszugehen, dass die Grenzen der Belastbarkeit des Dateneingebers eher erreicht ist

Aber elegant ist anders, ja.
@derrick
Sowas gibt es in gewisser Weise schon, zb formencode. Das ist zwar eigenlich dazu gedacht, HTTP-Requests zu validieren & konvertieren. Aber fuer diesen Zweck ginge es auch. Dann ist die (nicht-rekursive..) Implementation trivial.
Code: Alles auswählen
from formencode import Invalid
from formencode.validators import Int
def safe_input(validator, message="", error_msg="falsche eingabe"):
while True:
raw = raw_input(message)
try:
return validator.to_python(raw)
except Invalid:
print error_msg
print safe_input(Int())
Aber mir ehrlich gesagt nicht weiter wert, weil so simpel, dass sie sich bei Bedarf eben schnell schreibt, wie man sie gerade en detail braucht.
Re: Eingabenprüffunktion
Verfasst: Mittwoch 22. Juni 2011, 22:26
von mutetella
cofi hat geschrieben:So eine Funktion ist generell eher weniger sinnvoll.
Warum? Wenn man desöfteren eine Zahl als Eingabe verlangt, macht eine Funktion zur Validierung doch Sinn. Ok, die von derrick gezeigte Funktion ist nicht ganz glücklich, aber grundsätzlich...
Ich würde das halt ohne try: ... except: machen:
Code: Alles auswählen
def valid(spec, prompt, end='xX'):
spec = spec.upper()
test = {'DI': 'isdigit', 'AL': 'isalpha', 'AN': 'isalnum'}
value = input(prompt)
while not value in end and not getattr(value, test[spec])():
print('Bitte wiederholen Sie Ihre Eingabe!')
value = input(prompt)
return value
Die Funktion überprüft, ob die Eingabe mit einer vorgegebenen 'spec' übereinstimmt und gibt diese Eingabe dann unverändert als string zurück.
Abbrechen lässt sich die Schleife durch ein in 'end' enthaltenes Zeichen.
mutetella
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 07:42
von EyDu
@mutella: EAFP verlangt von dir geradezu, dass du das Problem mit Exceptions löst

Ich würde deine Lösung in etwa so anpassen:
Code: Alles auswählen
import functools
def ask(question, type_, stop="", default=None):
for value in iter(functools.partial(raw_input, question), stop):
try:
return type_(value)
except ValueError:
pass
return default
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 08:10
von cofi
mutetella hat geschrieben:cofi hat geschrieben:So eine Funktion ist generell eher weniger sinnvoll.
Warum? Wenn man desöfteren eine Zahl als Eingabe verlangt, macht eine Funktion zur Validierung doch Sinn.
Das steht im Satz danach. Und das ist auch nur ein Beispiel. Wenn man das natuerlich im eigenen Code desoefteren genauso braucht, kann man das durchaus machen, aber eine allgemein brauchbare Funktion ist nicht sonderlich hilfreich.
@deets: Wir reden hier von Eingaben der boesen User

Und so ein boeser User kann das auch problemlos automatisieren.
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 08:46
von mutetella
@EyDu:
Was für ein Unterschied! Mein zusammengeschusterter Code und Deine schöne, kompakte Lösung! Cool!
Für den OP, der mit Python 3 arbeitet, sei noch gesagt, dass 'raw_input' durch 'input' zu ersetzen ist.
mutetella
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 12:02
von problembär
mutetella hat geschrieben:@EyDu:
Was für ein Unterschied! Mein zusammengeschusterter Code und Deine schöne, kompakte Lösung! Cool!
Die Schönheit liegt (mal wieder) im Auge des Betrachters. Ich habe bei solchen "kompakten Lösungen" Verständnisprobleme.
Ich würde mich daher nahe an dem Vorschlag des OP halten, allerdings die Rekursion vermeiden:
Code: Alles auswählen
#!/usr/bin/env python
# coding: iso-8859-1
def int_input(question):
digit = None
while digit == None:
try:
digit = int(raw_input(question))
return digit
except ValueError:
print("Only numbers are allowed.")
print int_input("Enter a number: ")
Gruß
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 12:45
von EyDu
Was ist denn an meinem gezeigten Ansatz nicht sofort verständlich? Mich stören zum Beispiel eher die überflüssige Bedingung und ein unnötiger Name welcher eine vollkommen triviale Zeile erzeugt
Code: Alles auswählen
def int_input(question):
while True
try:
return int(raw_input(question))
except ValueError:
print "Only numbers are allowed."
Re: Eingabenprüffunktion
Verfasst: Donnerstag 23. Juni 2011, 15:23
von mutetella
problembär hat geschrieben:Die Schönheit liegt (mal wieder) im Auge des Betrachters.
Du hast sicher Recht, über Schönheit lässt sich streiten. Die Kompaktheit von EyDu's Beispiel hat aber neben seiner Schönheit einen unbestreitbaren Vorteil. Der Einsatz von 'iter' an dieser Stelle spart eine zusätzliche Abfrage, um die Eingabeschleife auch abbrechen zu können.
Dein Beispiel ist auf den ersten Blick natürlich leichter lesbar. Um allerdings ein Abbrechen zu ermöglichen, müsste ein Aufwand betrieben werden, der durch 'iter' erspart bleibt.
mutetella