eigener Fehler

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
elchico
User
Beiträge: 29
Registriert: Dienstag 10. März 2015, 00:06

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
BlackJack

@elchico: Möchtest Du vielleicht einfach nur eine Ausnahme auslösen? Stichwort ``raise``-Schlüsselwort und die `Exception`-Klassen.
Benutzeravatar
pillmuncher
User
Beiträge: 1490
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

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)
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

@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))
elchico
User
Beiträge: 29
Registriert: Dienstag 10. März 2015, 00:06

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).
Benutzeravatar
/me
User
Beiträge: 3558
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

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?
elchico
User
Beiträge: 29
Registriert: Dienstag 10. März 2015, 00:06

/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 ...
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.
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

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

Zeig' doch mal den Code hier im Forum!

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6754
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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).
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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?
Das Leben ist wie ein Tennisball.
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
Benutzeravatar
snafu
User
Beiträge: 6754
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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...
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack: mit Ziffern in anderen Schriften kann int schon umgehen:

Code: Alles auswählen

>>> int(u'६')
6
BlackJack

@Sirius3: Ui, das war mir jetzt neu. :-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
Antworten