Seite 1 von 1

eigener Fehler

Verfasst: Dienstag 10. März 2015, 00:12
von elchico
hallo zusammen,

ich habe eine definition geschrieben, welche eine eingabe auf verschiedene parameter überprüft. sollte bei der eingabe eine zahl eingegeben werden, wird ein fehler angezeigt ("das ist eine zahl") und das komplette python skript wird abgebrochen

meine frage: ich habe nun mehrere eingaben, wobei jede mit der def überprüft wird. ich möchte jetzt aber noch, dass die definition, falls ein fehler auftritt, auch die zeile ausgibt, in der der fehler stattfand:

Bsp.: 3 eingaben (zeile 1-3) => ich gebe in zeile 2 eine zahl ein => Ausgabe: "in zeile " + zeile + " wurde eine zahl eingegeben"

wie kann ich also in der definition auf die zeile zugreifen, in der die definition aufgerufen wurde? dabei möchte ich auch verschiedene python-skript-dateien miteinander verknüpfen (def in einer .py und mein eigentliches skript in einer anderen .py) und dann als ausgabe: "in zeile blabla von skript blubblub wurde eine zahl eingegeben"


Danke für eure hilfe
vg
elchico

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 01:09
von BlackJack
@elchico: Möchtest Du vielleicht einfach nur eine Ausnahme auslösen? Stichwort ``raise``-Schlüsselwort und die `Exception`-Klassen.

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 01:45
von pillmuncher
Das, was du eine def oder Definition nennst, nennt man eine Funktion. Das def zeigt an, dass eine Funktion definiert wird, nicht, dass eine Definition definiert wird.
Das, was du eine .py nennst, heißt Modul oder Python Skript oder Python Datei. Modul ist der beste Name dafür.
Das, was du miteinander verknüpfen nennst, nennt man importieren.

Angenommen, du hast eine Funktion foo() in einem Modul bar (mit dem Dateinamen bar.py) definiert. Und angenommen, du möchtest ein Programm (sagen wir program.py) schreiben, das diese Funktion verwendet, dann geht das so:

Code: Alles auswählen

def foo():
    return 123
bar.py

Code: Alles auswählen

from bar import foo

def main():
    value = foo()
    print(value)

if __name__ == '__main__':
    main()
program.py

Die Frage, in welcher Programmzeile eine Eingabe gemacht wurde, ist falsch gestellt. Tatsächlich wird ja nicht in der Programmzeile etwas eingegeben, denn diese ist Teil der statischen Beschreibung des Programms, und das Abfragen einer Benutzereingabe ist Teil des Laufzeitverhaltens des Programms. Der Programmtext ist so etwas wie ein Bauplan, das laufende Programm so etwas wie eine nach dem Bauplan hergestellte Maschine.

Vielleicht genügt dir aber auch schon das hier (um BlackJacks Beitrag etwas zu illustrieren):

Code: Alles auswählen

def get_data():
    data = []
    for i in range(3):
        data.append(input('bitte eine Zahl eingeben: '))
    for i in range(3):
        try:
            number = int(data[i])
        except ValueError:
            raise ValueError('Die {}. Eingabe konnte nicht als Zahl interpretiert werden: {}'.format(i, data[i]))
        print('Die {}. Eingabe war {}'.format(i, number))
(ungetestet)

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 07:32
von Sirius3
@pillmuncher: wobei Du in Dein Beispiel gleich wieder ein unschönes Anti-Pattern eingebaut hast. Gefragt war auch, *keine* Zahl einzugeben:

Code: Alles auswählen

def get_data():
    values = []
    for i in range(3):
        values.append(input('bitte keine Zahl eingeben: '))
    for i, value in enumerate(values):
        try:
            int(value)
        except ValueError:
            pass # keine Zahl
        else:
            raise ValueError('Die {}. Eingabe ist eine Zahl: {}'.format(i, value))
        print('Die {}. Eingabe war {}'.format(i, value))

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 07:39
von elchico
danke erstmal für eure beiden beiträge :)
die fachbegriffen muss ich wohl noch etwas lernen ;) des nächste mal wirds zumindest professioneller klingen :)

es geht mir eigentlich drum, eine meldung zzu bekommen, die ähnlich aufgebaut ist wie eine "echte Fehlermeldung", in der ja auch das modul und die zeile angegeben ist ... nur möchte ich eben nicht auf einen "echten Fehler" warten, sondern selbst welche deklarieren... wie zB die eingabe einer zahl

ich schau mir heute im laufe des tages mal "raise" an
vg und schönen tag euch

PS: ich habe eure beiträge nur überflogen, weil ich in die uni muss -.- aber: ich möchte in einem anderen modul die eingabe machen und in der funktion nur überprüfen, ob diese eingabe eine zahl war. und die funktion soll sich auch nur "melden", sprich eine ausgabe machen, falls es probleme gab (es war eine zahl).

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 09:17
von /me
elchico hat geschrieben:meine frage: ich habe nun mehrere eingaben, wobei jede mit der def überprüft wird. ich möchte jetzt aber noch, dass die definition, falls ein fehler auftritt, auch die zeile ausgibt, in der der fehler stattfand:
Ich verstehe nicht wozu das gut sein soll. Was soll ein Anwender damit anfangen?

Warum schreibst du nicht einfach eine Eingaberoutine die bei einer fehlerhaften Eingabe erneut zu einer Eingabe auffordert?

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 11:58
von elchico
/me hat geschrieben:
elchico hat geschrieben:meine frage: ich habe nun mehrere eingaben, wobei jede mit der def überprüft wird. ich möchte jetzt aber noch, dass die definition, falls ein fehler auftritt, auch die zeile ausgibt, in der der fehler stattfand:
Ich verstehe nicht wozu das gut sein soll. Was soll ein Anwender damit anfangen?

Warum schreibst du nicht einfach eine Eingaberoutine die bei einer fehlerhaften Eingabe erneut zu einer Eingabe auffordert?
okay also ich steuere von meinem raspberry pi aus die gpio's und habe eine funktion geschrieben, sodass ich nicht jedes mal alles einzeln eintippen muss, sondern es reicht, wenn ich der funktion sage: welcher pin + IN oder OUT ...
jetzt initiiere ich 10 verschiedene pins, wobei ich einmal statt "OUT" "oUT" schreibe... damit funktioniert es natürlich nicht => ich möchte in meinem modul, wo ich die pins initiiere, nicht einzeln jede zeile abklappern, wo ich pins aktiviere, sondern anhand der ausgabe feststellen, wo der fehler liegt ...

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 12:15
von BlackJack
@elchico: Welche Bibliothek verwendest Du denn um die Pins zu konfigurieren die nicht bereits eine Funktion dafür bietet, beziehungsweise wie machst Du das? Und warum überhaupt Zeichenketten für 'IN' und 'OUT' statt Konstanten dafür zu definieren wie die üblichen Bibliotheken das machen. Dann gibt's schon von Haus aus einen `NameError` wenn sich jemand beim Namen der Konstanten vertippt und man braucht da nicht mehr selber etwas zu prüfen.

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 12:47
von noisefloor
Hallo,

und das "oUt" Problem kannst du mit der `.upper()` Methode von Strings eleminieren.

Zeig' doch mal den Code hier im Forum!

Gruß, noisefloor

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 13:34
von snafu
Sirius3 hat geschrieben:Gefragt war auch, *keine* Zahl einzugeben
Warum gehst du eigentlich über "try ... except"? Wäre es nicht einfacher, die Eingabe mittels `.isdigit()` zu testen? Zumindest wenn man nicht an dem Ergebnis der Umwandlung interessiert ist, sondern nur wissen möchte, ob eine Konvertierung überhaupt möglich ist, finde ich den Weg über die entsprechende Methode weniger umständlich.

Sähe dann so aus:

Code: Alles auswählen

def get_data():
    values = []
    for i in range(3):
        values.append(input('bitte keine Zahl eingeben: '))
    for i, value in enumerate(values):
        if value.isdigit():
            raise ValueError('Die {}. Eingabe ist eine Zahl: {}'.format(i, value))
        print('Die {}. Eingabe war {}'.format(i, value))
EDIT: Ich sehe gerade, dass `.isdigit()` nicht mit negativen Zahlen umgehen kann. `int()` hingegen kann das (also auch bei Umwandlungen von Strings).

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 13:43
von EyDu
snafu hat geschrieben:
Sirius3 hat geschrieben:Gefragt war auch, *keine* Zahl einzugeben
Warum gehst du eigentlich über "try ... except"? Wäre es nicht einfacher, die Eingabe mittels `.isdigit()` zu testen?
EAFP, das ist der Standardweg in Python. Man geht einfach davon aus, dass es sich um einen Integer handelt. Wenn nicht, dann gibt es schon eine Exception und man kann sich um den Randfall kümmern.

Man könnte jetzt natürlich mit Sonderfällen kommen, die von isdigit nicht abgedeckt werden. Negative Zahlen, Leerzeichen an den Rändern, man möchte irgendwann Floats statt Ints, ...

int macht ja genau das was man möchte, warum sollte man also selbst etwas entwickeln, bei dem man nur Fehler einbauen, aber nichts besser machen kann?

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 13:47
von BlackJack
@snafu: Umgekehrt gibt es Zeichenketten die nur aus Ziffern im Sinne von `isdigit()` bestehen, mit denen `int()` aber nicht klar kommt:

Code: Alles auswählen

In [5]: u'①'.isdigit()
Out[5]: True

In [6]: u'६'.isdigit()
Out[6]: True

In [7]: u'2¹⁶'.isdigit()
Out[7]: True

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 13:55
von snafu
EyDu hat geschrieben:int macht ja genau das was man möchte, warum sollte man also selbst etwas entwickeln, bei dem man nur Fehler einbauen, aber nichts besser machen kann?
Ich dachte im ersten Moment, dass `.isdigit()` deutlich mehr Fähigkeiten hätte. Aber es beschränkt sich wohl einfach auf die Erkennung einer Folge von Ziffern. Da wäre natürlich ein Blick in die Doku nicht schlecht gewesen...

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 14:07
von Sirius3
@BlackJack: mit Ziffern in anderen Schriften kann int schon umgehen:

Code: Alles auswählen

>>> int(u'६')
6

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 14:08
von BlackJack
@Sirius3: Ui, das war mir jetzt neu. :-)

Re: eigener Fehler

Verfasst: Dienstag 10. März 2015, 14:10
von EyDu
Das eröffnet auch ganz neue Möglichkeiten:

Code: Alles auswählen

>>> int(u'६7')
67
Ob das Verhalten wirklich so sinnvoll ist? Jetzt mal abgesehen vom Ärgern der Kollegen.