Bei Eingabe ungewollter/ungeklärter Sprung zu except

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
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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

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
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

`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).
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

``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).
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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
>>>
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

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.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab mal eine alte Wiki Seite ausgekramt: [wiki]Wunschliste#InputRawInput[/wiki]

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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)
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.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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...
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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

Wenn du im interaktiven Modus bist, dann rufst du die Funktion einfach auf. Andernfalls benutzt du, wie sonst auch, "print".
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

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.
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.
Antworten