Seite 1 von 1
try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 01:25
von Hugin
Hallo zusammen,
bin hier schon 2 Tage am grübeln über folgendes:
#Es handelt sich um eine Übung in einem Buch. Die verlangt ein Script zu schreiben das Einträge in eine Liste vornimmt.
#Das Programm schaute am Schluss ein bischen anders aus aber es hat gemacht was es sollte. Es hat halt alles eingetragen was man ihm vorgeschrieben hat.
Ich wollte nun noch ein paar Abfragen einbauen (Übungen aus den vorherigen Kapiteln)
hier mal der Code:
Code: Alles auswählen
f = open("Bestellliste.txt", "a")
while True:
artikelnummer = eval(input("Geben Sie bitte die 5 Stellige Artikelnummer ein, zum abbrechen bitte 'quit' eingeben : "))
artikelnummer = (str(artikelnummer))
a = (len(artikelnummer))
if artikelnummer == "quit":
break
try:
if a < 5:
print ("Artikelnummer zu kurz")
elif a > 5:
print ("Artikelnummer zu lang!")
except ValueError:
print ("Bitte nur 5 Stellige Zahlen eingeben!")
except NameError:
print ("nur Zahlen!")
finally:
if a == 5:
print("erledigt!")
f.write (artikelnummer+"\n")
f.close
print ("Auf wiedersehen!")
Es funktioniert soweit.. ausser 2 Ausnahmen:
problem1 = Das erste ist das wenn ich Buchstaben eingebe, eigentlich die except Schleife laufen sollte mit ValueError oder NameError
diese springt jedoch nicht an und das Programm wird mit dem "Error-Wert" abegebrochen. Obwohl die finally Schleife wirkt!
Warum zum T***** schaltet das except nicht ???
problem2 = Die zweite wäre das wenn eine 0 oder 5x 0 eingegeben wird alles auseinanderfällt.
z.B. wird die Artikelnummer, die ja 5 Stellen haben muss, 01234 nicht erkannt.
oder 0000000000 wird als zu kurz ausgegeben.
Kann mir schon vorstellen das es daran liegt das ich die "int" eingabe in einen "str"ing umwandle um die len() abzufragen.
Wie kann ich trotzdem eine 0er Artikelnummer in die Liste bringen und trotzdem durch die Schleife laufen lassen?
Mir raucht schon der Schädel....
Grüße
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 06:22
von Sirius3
Das Problem ist das eval, dass man eh nicht benutzen sollte. Du musst die ganze Zeit mit Strings arbeiten. isdigit ist hilfreich. a ist ein sehr schlechter Name für eine Variable. Innerhalb des try-Blocks kann weder ein ValueError noch ein NameError auftreten, weil nur Zahlen mit Zahlen verglichen werden. Ein NameError ist auch immer ein Programmierfehler und sollte nicht abgegangen werden (müssen). Das close ist an der falschen Stelle und wird auch nicht aufgerufen. Um solche Fehler zu vermeiden, benutze das with-Statement.
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 06:33
von sparrow
Zu Problem 1:
Damit der except-Block ausgeführt wird, muss im try-Block ja irgendwo eine Ausnahme auftreten.
Bei dir stehen im try-Block 2 if-Bedingungen und 2 print-Anweisungen. Wie genau soll es denn da zu einer Exception kommen, wegen der der Except-Block ausgeführt wird?
Gewöhn dir besser sofort an Variablen vernünftige Namen zu geben. Sprechende Namen, die dem Leser (also dir) sagen, was sie sind.
Was in finally steht, sollte mit in den try-Block. Und zwar als letzter else-Zweig. Finally verwendet man um "aufzuräumen". Zum Beispiel offene Verbindungen oder Dateien kontrolliert zu schließen.
Apropos schließen: Du schließt deine geöffnete Datei nicht wieder. Close wird nicht aufgerufen, dafür fehlen die Klammern dahinter.
Besser: benutze open mit dem with-Statement. Dann kannst du dir das Schließen sparen.
"f" ist wieder ein schlechter Name.
Und zuletzt: Hinter den Methodennamen und die öffnende Klammer gehört kein Leerzeichen. Also print( nicht print ( etc.
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 09:09
von kbr
@Hugin: ich habe dir den Code in ein sauberes Gerüst umgeschrieben, so dass du nun die Prüfung auf Ziffern hinzufügen kannst:
Code: Alles auswählen
with open('bestell_liste.txt', 'a') as fobj:
while True:
value = input('Bitte 5 stellige Artikelnummer eingeben (quit zum beenden): ')
if value.lower() == 'quit':
break
if len(value) != 5:
print('Nur 5 stellige Artikelnummern erlaubt.')
else:
# prüfe ob value nur Ziffern enthält
# falls ja: speichere value
pass
print('exit')
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 10:39
von Jankie
Ich würde das komplett ohne Try/Except lösen und mir eine Funktion schreiben, die prüft ob die eingegebene Zahl dem gewünschten Format entspricht. (Hier: 5 Zeichen, nur Zahlen)
Beispiel:
Code: Alles auswählen
def is_valid_item_number(item_number):
return len(item_number) == 5 and not any(number.isalpha() for number in item_number)
while True:
eingabe = input("> ")
if is_valid_item_number(eingabe):
with open("Bestellliste.txt", "a", encoding="UTF-8") as f:
f.write(f"{eingabe}\n")
print("Erledigt!")
else:
print("Die Artikelnummer darf nur 5 Zeichen lang sein und darf nur Zahlen enthalten!")
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 11:03
von sparrow
@Jankie: So beraubt man sich der Möglichkeit auf den tatsächlichen Fehler hinzuweisen. Stimmt die Länge oder der Inhalt nicht?
Der Einsatz von .isalpha() ist hier falsch, denn du schließt so nur Buchstaben aus.
Die Zeichen-für-Zeichen-Überprüfung könntest du dir auch sparen, denn isalpha() prüft auf eine ganze Zeichenkette, ob sie nur aus Buchstaben besteht. Das Ergebnis ist also identisch.
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 11:11
von Jankie
Wenn ein genaures Format gewünscht ist stimme ich dir zu, aber wenn es - wie hier in dem Beispiel - nur zwei Bedinungen gibt würde ich das dem Benutzer noch zutrauen den Fehler den er gemacht hat zu finden.
Habe gemerkt das man mit .isdigit() auch ganze Strings testen kann, also hier noch mal der überarbeitete Code, bei dem auch keine Sonderzeichen mehr gehen.
Code: Alles auswählen
def is_valid_item_number(item_number):
return len(item_number) == 5 and item_number.isdigit()
while True:
eingabe = input("> ")
if is_valid_item_number(eingabe):
with open("Bestellliste.txt", "a", encoding="UTF-8") as f:
f.write(f"{eingabe}\n")
print("Erledigt!")
else:
print("Die Artikelnummer darf nur 5 Zeichen lang sein und darf nur Zahlen enthalten!")
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 12:34
von __blackjack__
@Jankie: `isdigit()` ist auch falsch vermute ich mal, denn
genau wie `int()` kennt auch `isdigit()` deutlich mehr Zeichen als nur 0 bis 9 als Ziffern.
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 12:58
von Jankie
Wie prüft man das denn richtig? Ich hab jetzt einfach noch eine Bedingung hinzugefügt, also .isascii(). Wenn jemand eine Antwort weiß kann er mir die gerne auch per PN schicken, damit ich den Thread hier nicht vollspamme mit Sachen die nur peripher zu Thema gehören.
Code: Alles auswählen
def is_valid_item_number(number):
return len(number) == 5 and number.isascii() and number.isdigit()
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:29
von kbr
Du könntest z.B. mit einem regulären Ausdruck auf fünf aufeinander folgende Ziffern testen. Oder versuchen, jedes Zeichen im input in einen Integer zu konvertieren. Oder prüfen, ob jedes Zeichen in string.digits ist. Geht vielleicht auch noch anders, aber die drei Möglichkeiten fallen mir gerade ein. Die zweite Möglichkeit gefällt mir am wenigsten. Die letzte ist vermutlich die einfachste. Mit der ersten holt man direkt den Knüppel aus dem Sack

Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:33
von sparrow
Die zweite Möglichkeit fällt aus, wie __blackjack__ bereits gesagt hat:
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:35
von kbr
Ah, hatte ich überlesen. Gut, dass sie mir am wenigsten gefiel ...

Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:37
von Jankie
RegEx erkennt "୨୩" auch als Zahl.
> ['୨୩', '30']
So würde es auch noch gehen, aber dann fängt es an unübersichtlich zu werden.
Code: Alles auswählen
def is_valid_item_number(item_number):
return len(item_number) == 5 and all(number in map(str, range(0, 10)) for number in item_number)
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:56
von kbr
Es kommt darauf an, dass reguläre Ausdrücke korrekt verwendet werden:
Code: Alles auswählen
>>> import re
>>> print(re.match(r'[0-9]{5}', "56a89"))
None
>>> print(re.match(r'[0-9]{5}', "56୨୩89"))
None
>>> print(re.match(r'[0-9]{5}', "56789"))
<_sre.SRE_Match object at 0x10561b7e8>
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 15:59
von Sirius3
Die Frage ist doch, ob Ziffern aus anderen Kulturkreisen denn nun wirklich keine Ziffern sind. Ich würde isdigit als richtig ansehen.
Ansonsten der reguläre Ausdruck "[0-9]{5}".
Re: try schleife erkennt except nicht
Verfasst: Montag 20. Januar 2020, 17:45
von Hugin
Woow.. erstmal, danke für eure mühen!
Werd das mal versuchen mit den Tipps die Ihr mir gegeben habt.
Habs im vorfeld mit den typen direkt probiert sprich int(), float(), eval war nur ne notlösung als Versuch.
Inzwischen bin ich bei einfach nur wieder bei input(). Jeder type bringt hier seine eigenen probleme mit.
Aber ich werd es wohl von Grund auf neu anpacken und mich mit den funktionen und den ideen hier versuchen.
Hab hier ja genug inspiration bekommen.
Die re.match variante ist sehr interessant !
Und gern "hier" weiter diskutieren!