Seite 1 von 1

Bei Eingabe ungewollter/ungeklärter Sprung zu except

Verfasst: Dienstag 29. April 2008, 16:45
von Evil4President
Hi all,

habe mal wieder ein kleines Problem. Wir sollen ein Programm schreiben, dass mit Hilfe von Caesar verschlüsselt. Da ich in Python noch nicht so fit bin, habe ich mir jetzt erstmal etwas Umständliches ausdenken müssen, um zu testen, ob in dem bisher nur einzigen Wort, das verschlüsselt werden soll, ein Leerzeichen/Sonderzeichen steckt. Das Problem ist nun jedoch, dass der Ablauf bei der Prüfung des Wortes ständig im except endet, wobei ich keinen Eingabefehler mache. Könnte höchstens sein, dass bei der Abfrage in der for-Schleife etwas falsch gesetzt ist. Wäre froh wenn mir jemand einen Rat geben könnte.

Code: Alles auswählen

beenden=0
while beenden==0:
    try:
        schluessel=input('Geben Sie hier an um wieviele Stellen ihr Alphabet verrückt werden soll: ')
    except:
        print 'Bitte geben Sie eine positive, ganze Zahl ein!'
    try:
        wort=raw_input('Geben Sie hier Ihr zu verschlüsselndes Wort an: ')
        laenge=len(wort)
        for i in range(0,laenge+1):
            if ord(wort[i]) not in range(int(chr(65)),int(chr(90))) or ord(wort[i]) not in range(int(chr(97)),int(chr(122))):
                raise
    except:
        print 'Sie dürfen nur ein einziges Wort ohne Sonderzeichen angeben'
Habe mir die Abfrage so vorgestellt:
in der for-Schleife soll das Skript jeden Buchstaben des Wortes auslesen und diesen mit ord() in einen Integer umwandeln. Mit der if-Anweisung soll dann sichergestellt werden, dass jeder der Buchstaben auch ein Buchstabe ist; diese liegen meines Wissens in den chr-Werten 65-90 (Großbuchstaben) bzw. 97-122 (Kleinbuchstaben)...
Meiner Meinung nach kann der Fehler nur in der if-Anweisung liegen.
Wäre wirklich dankbar für jede Hilfe,

MFG evil4president

Re: Bei Eingabe ungewollter/ungeklärter Sprung zu except

Verfasst: Dienstag 29. April 2008, 16:53
von numerix
Evil4President hat geschrieben:Meiner Meinung nach kann der Fehler nur in der if-Anweisung liegen.
Aus meiner Sicht ist so ziemlich das ganze Programm ein Fehler ...

Ein konkreter Fehler ist auf jeden Fall dieser:

Code: Alles auswählen

>>> chr(65)
'A'
>>> int(chr(65))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'A'

Verfasst: Dienstag 29. April 2008, 16:58
von EyDu
Nächstes mal wäre es gut, wenn du auch die Exception online stellst. Dein Fehler liegt in Zeile 10: an Position "laenge+1" liegt kein Buchstabe mehr, die letzte gültige Position ist "laenge-1". Du kannst aber auch direkt über die Buchstaben iterieren:

Code: Alles auswählen

for buchstabe in wort:
    if ord(buchstabe) not ...
.

Wie ich aber sehe, geht es schon vorher schief: "int(chr(65))" kann eigentlich gar nicht gutgehen. Du meinst bestimmt einfach nur "range(65, 90)". Aber warum testest du nicht einfach gegen die Buchstaben, die vorkommen dürfen?

Vielleicht noch ein paar Tips:

Anstelle von "beenden = 0" schreibe doch "beenden = False".

"input" ist ziehmlich gewfährlich, die Forensuche liefert da einiges. mache lieber ein "int(raw_input("...."))" und fange gegebenfalls die Excpetion ab.

Eine "except" ohne Einschränkung ist auch nicht gerade gesund, dann werden wirklich ALLE Fehler abgefangen und unter umständen findest du dann bestimme Fehler nicht mehr. Mache lieber ein "except ValueError".

Diesen ganzen Range-Kram, denn du dort

Verfasst: Dienstag 29. April 2008, 17:08
von Evil4President
Ah stimmt. Habe da tatsächlich den kleinen Denkfehler gehabt mit dem int(chr(65). Kann ja schlecht einen Integer von einem Buchstaben bilden. Werde das Programm dann mal verbessern, in Bezug auf except und inputs.
Vielen Dank schonmal.

@ pütone: Wieso meinst du, dass das ganze Programm ein Fehler ist? Ich bin halt noch nicht so erfahren in dem Gebiet, von daher finde ich das nicht so schlimm. Man fängt eben nicht als vollkommen an... Jedoch war ich mir selbst im Klaren, dass das Programm so niemals gut geschrieben ist. Kann es nur mit derzeitigen Kenntnissen nicht kürzer/besser schreiben

Verfasst: Dienstag 29. April 2008, 17:14
von Leonidas
Evil4President hat geschrieben:Wieso meinst du, dass das ganze Programm ein Fehler ist?
Naja, zumindest wenn ich sehe, dass irgendwo ``input()`` verwendet wird, kann ich es mir meist sparen, den Rest anzuschauen, weil es nur noch grausam sein kann. Zeile 11 ist noch so ein Kandidat, wo ich mir nicht einmal mehr die Mühe machen würde, nachzusehen, was das eigentlich prüfen soll. Wird vermutlich die ASCII-Codes checken, aber wenn ich ``)))`` in einem Python-Code sehe, leuchtet bei mir die "Refactoring"-Lampe auf.

Verfasst: Dienstag 29. April 2008, 17:21
von Evil4President
Wie oben schon erwähnt, ist mir der Denkfehler bereits aufgefallen, werde das ja auch verbessern. Zu den inputs: Was gibt es denn für andere Methoden, um reim in der IDLE Eingaben abzufragen außer der input-Variante, bzw. raw_input. In unserem Informatikunterricht haben wir bisher nur diese gelernt... Würde dann in Zukunft gerne vermeiden mit diesen 2 Varianten zu arbeiten, wenn sie soviele Probleme verursachen.

MFG evil4president

Verfasst: Dienstag 29. April 2008, 17:32
von Trundle
`input` ist pöhse, weil `input` die Eingabe `eval`t, und `eval` ist einfach nur pöhse. Außerdem wäre z.B. ``'Spam'`` eine gültige Eingabe bei `input`, bei weitem jedoch keine Zahl und das Programm scheitert hoffnungslos. `raw_input` ist ok, man muss dann eben nur selbst die Eingabe in den gewünschten Datentyp umwandeln (und eben überprüfen/Ausnahmen abfangen).

Verfasst: Dienstag 29. April 2008, 17:35
von Evil4President
Achso...^^ Aber nur interessehalber: Wieso wäre der String "Spam" eine gültige Eingabe bei input? Leuchtet mir nicht ein. Aber vielleicht ist es genau das, was ihr mit pöhsem ( ;-) ) input meint.

Verfasst: Dienstag 29. April 2008, 17:40
von Trundle
``Spam`` wäre keine gültige Eingabe, ``'Spam'`` bzw. ``"Spam"`` schon (man beachte die einfachen bzw. doppelten Hochkommata). So wie man eben Strings im Quelltext auch notieren würde. Grundsätzlich kann man bei `eval` alles eingeben, was eine ``Expression`` und kein ``Statement`` ist (und somit z.B. auch Dateien löschen).

Verfasst: Dienstag 29. April 2008, 21:08
von birkenfeld
Trundle hat geschrieben:``Spam`` wäre keine gültige Eingabe, ``'Spam'`` bzw. ``"Spam"`` schon (man beachte die einfachen bzw. doppelten Hochkommata).
Vorsicht:

Code: Alles auswählen

>>> Spam = 1
>>> input()
Spam
1
>>>

Verfasst: Dienstag 29. April 2008, 21:53
von Trundle
birkenfeld hat geschrieben:
Trundle hat geschrieben:``Spam`` wäre keine gültige Eingabe, ``'Spam'`` bzw. ``"Spam"`` schon (man beachte die einfachen bzw. doppelten Hochkommata).
Vorsicht:

Code: Alles auswählen

>>> Spam = 1
>>> input()
Spam
1
>>>
Oh. Stimmt, daran habe ich in der Tat nicht gedacht. Das mit den Expressions ist wohl die bessere Erklärung.

Verfasst: Mittwoch 30. April 2008, 07:40
von jens
Hab mal eine alte Wiki Seite ausgekramt: [wiki]Wunschliste#InputRawInput[/wiki]

Verfasst: Samstag 3. Mai 2008, 16:53
von Evil4President
habe jetzt das programm auf tkinter umgeschrieben. das mit der IDLE hat mir nichtmehr so gut gefallen und durch die while-schleifen sind auch ein paar probleme entstanden. allerdings funktioniert die überprüfung hier immernoch nicht. kann mir nicht jemand sagen, woran das liegt bzw mir ne andere möglichkeit sagen, wie ich testen kann ob sonderzeichen bzw leerzeichen in einem eingegebenen string enthalten sind? so komme ich nichtmehr weiter. :(

Code: Alles auswählen

try:
      word=wort_eingabe.get()
      for i in range(0,(length_w)+1):
            if ord(str(word[i])) not in range(65,91) or ord(str(word[i])) not in range(97,123):
                wort_eingabe.delete(0,END)
                raise
            else:
                WORT=word
except ValueError:
      showerror('Fehler!!!','Sie dürfen nur ein einziges Wort ohne Sonder-(Leer-)zeichen angeben.')
das mit dem ord(str()) habe ich jetzt mal nur zu testzwecken eingebaut. ich denke aber das ist unsinnig, da durch den wort_eingabe.get() ja ein string übernommen wird...

mfg evil4president

Verfasst: Samstag 3. Mai 2008, 17:08
von Evil4President
habe jetzt gerade mal weitergedacht...
ich habe jetzt mal in der if-anweisung das raise rausgenommen. kann das irgendwie mit der eingabe durch das entry zu tun haben?

hier mal die entsprechende stelle:

Code: Alles auswählen

wort_eingabe=Entry(root,width=30)

Verfasst: Samstag 3. Mai 2008, 18:41
von BlackJack
Magst Du nicht vielleicht nochmal das Tutorial durcharbeiten und versuchen zu verstehen was Du da tust. Das sieht alles sehr nach try'n'error und wenig nach durchdachtem Programmieren aus.

Verfasst: Samstag 3. Mai 2008, 20:58
von Evil4President
Ich mach das mit Tutorials und Referenzen alles nach und nach. Informatik habe ich etwa seit einem 3/4 jahr in der Schule. Das was ich mache, kann ich anhand der Tatsachen, die uns unser Lehrer beigebracht hat, erklären. So wie er das mit dem try'n'except erklärt hat, kommt in den try-die normale Aktion hinen, die falls ein Fehler intritt dann nicht zu einem Ablaufabbruch führt, der in der IDLE protokolliert wird, sondern durch das except abgefangen wird und dann korrigiert werden kann.
Habe jetzt aber mal eine andere Idee bekommen und werde das jetzt mal testen. Falls es dann noch Probleme gibt, werde ich mich drum kümmern...

Verfasst: Samstag 3. Mai 2008, 22:43
von Evil4President
Hallo nochmal, habe jetzt eine andere Frage, um eine Lösung zu versuchen.
Ich zerlege jetzt jeden Teil in eine einzelne Funktion um zu testen, wos hängt. Will dann bei einem Fehler TRUE bzw FALSE returnen.
Wie kann ich denn in der IDLE dann den Wert des returns für die Funktion ausgeben lassen bzw anzeigen?

Verfasst: Samstag 3. Mai 2008, 22:53
von EyDu
Wenn du im interaktiven Modus bist, dann rufst du die Funktion einfach auf. Andernfalls benutzt du, wie sonst auch, "print".

Verfasst: Samstag 3. Mai 2008, 23:50
von Evil4President
So, habe jetzt mein Problem gelöst...
Das mit dem print bzw Funktionaufrufen ging so nicht, da ich TRUE oder FALSE nicht an eine Variable gebunden habe. Habe an entsprechende Stelle jetzt einfach mal ein print mit entsprechendem Wert gesetzt m zu schauen, wo ich rauskomme. Mein Vergleichsproblem habe ich gelöst, indem ich mehrere if's ineinander verschachtelt habe.
Aber trotzdem gings noch nicht mit den Zahlen. Ein Bekannter hat mich eben darauf aufmerksam gemacht, dass man auch Strings miteinander vergleichen kann.
Also z.B. so: word<'a'

so ging das jetzt. :)

kann das eigtl sein, dass durch den Vergleich von ord(word) ein "falscher" ASCI werd ausgegeben wird? wenn ich einfach so prints setze um anzeigen zu lassen, sind die Werte korrekt. Sobald ich sie dann im Vergleich benutze, kommt der Fehler. Dafür finde ich keine logische Erklärung... Wäre ganz gut, wenn dafür vielleicht jemand eine Antwort hätte, damit ich da nicht einem syntax-Fehler unterlaufe oder so. Aber mit dem Vergleich von Strings geht mein Vorhaben wie gewollt.

Verfasst: Sonntag 4. Mai 2008, 06:31
von BlackJack
"try'n'error" hat nichts mit den Schlüsselworten ``try`` und ``except`` zu tun. Das heisst zu Deutsch "Versuch und Irrtum" und ich meinte damit, dass Deine Quelltextschnippsel nicht danach aussehen, dass Du weisst was Du da tust, sondern durch herumprobieren entstanden sind.

``ord(word)`` liefert zum Beispiel immer den gleichen Wert zurück (für gleiches `word` und `i`), egal ob's nach einer ``print``-Anweisung oder mit einem Vergleichsoperator verwendet wird. Wenn da etwas nicht funktioniert wie erwartet, ist der Quelltext falsch, oder es ist ein Denkfehler. Und das solltest Du *klären*. Aus Fehlern sollte man lernen, damit sie nicht wiederholt.