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