Problem mit Überprüfung auf Umlaute

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

Achso. Vielen Dank schonmal an alle. Habe jetzt die valid-Liste als Unicode String erstellt, jetzt kommt auch kein Fehler mehr wenn ich Umlaute eingebe. Allerdings kommt jetzt ein Fehler wenn ich Sonderzeichen eingebe...
Hier mal meine Liste:

Code: Alles auswählen

valid = u'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz' + u'ÜüÄäÖö' + u',;.:?"&/()§'

Allerdings habe ich auch noch ein Problem innerhalb eines if's.
So sieht mein if-Teil aus:

Code: Alles auswählen

for a in range(0,length_w):
        if 90<(ord(WORT[a])+zahl)<97:
            number=(ord(WORT[a])+zahl)-90
            geheim +=chr(64+number)
        elif (ord(WORT[a])+zahl)>122 and WORT[a] not in Umlaute:
            number=(ord(WORT[a])+zahl)-122
            geheim += chr((96+number))
        elif WORT[a]==' ':
            geheim += ' '
        elif WORT[a] in Zeichen:
            geheim += WORT[a]
        elif WORT[a] in Umlaute:
            geheim += WORT[a]
        else:
            geheim += chr(ord(WORT[a])+zahl)
Entschuldigt schonmal, dass es ein wenig umständlich gemachht ist, aber die Verbesserung mit slices füge ich bald noch ein... Würde das ganze aber gerne so mal lauffähig haben. Wenn ich jetzt einen Umlaut eingebe, dann müsste doch der teil "elif WORT[a] in Umlaute" eintreten, d.h. er sollte den Umlaut einfach stehen lassen, da ansonsten abstruse Zeichen herauskommen. Wieso verschiebt er trotzdem das Zeichen innerhalb der ASCII Tabelle... Die Sache, dass der Wert größer als 122 ist, wird doch ausgeschlossen, wenn das Zeichen ein Umlaut wäre... Die Bedingung mit größer 122 sollte nur eintreten, wenn man beispielsweise das "Z" verschiebt...
Wäre schön, wenn mir hierbei auch jemand helfen könnte...
Und entschuldigt, wenn ich mich etwas dumm anstelle bei solchen Sachen ;-)
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Ok, das Problem mit den Sonderzeichen habe ich gerade selbst gelöst. Hatte oben in der valid-Liste übersehen, dass mir noch ein Leerzeichen und das Ausrufezeichen fehlten.... :-)

Aber das Problem mit dem Vershcieben der Umlaute besteht weiterhin...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Evil4President hat geschrieben:Aber das Problem mit dem Vershcieben der Umlaute besteht weiterhin...
Ich verstehe allmählich nicht, wo dein Problem noch ist. Es wurde doch eigentlich alles mehrmals und von verschiedenen Seiten durchgekaut.

Ist es nicht das, was du willst:

Code: Alles auswählen

import string

zeichenvorrat = string.ascii_letters+"ÄÖÜäöü"
delta = 5

def kodiere(ch):
    try:
        return zeichenvorrat[(zeichenvorrat.index(ch)+delta) % len(zeichenvorrat)]
    except ValueError:
        return ch

textalt = "Bist du 17? Nö, älter!"
textneu = ""
for ch in textalt:
    textneu += kodiere(ch)
print textneu
Ausgabe:

Code: Alles auswählen

Gnxy iz 17? Sd, cqyjw!
Der ganze Weg über die elifs und die ASCII-Codenummern ist doch überflüssig.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Im Prinzip is das schon so wie ich es will, nur so habe ich es ja auch, nur in abgewandelter Form... Es wird ja auch alles korrekt verschlüsselt, nur die Umlaute werden zu sehr seltsamen Zeichen, da sie in einem sehr unregelmäßig verteiltren Zahlenbereich der ASCII Tabelle liegen. Ich wollte oben in meiner for-Schleife testen, ob der i-te Buchstabe des Wortes in meiner Liste Umlaute drin ist. Falls er das ist, soll der Umlaut beim verschlüsselten Text einfach stehen bleiben; rundherum wird alles verschlüsselt. Allerdings scheint das "elif" in dem geprüft wird, ob der Buchstabe in Umlaute enthalten ist, nicht korrekt abzulaufen... Ich wollte fragen wieso.

Ich persönlich habe nur zwei Erklärungen, allerdings keine Ahnung wie ich darüber auf eine Lösung komme. Zur Erläuterung:

Die Zahlenwerte der Umlaute liegen alle über 122, d.h. er springt im Programmablauf in das elif in dem gefragt wird, ob der Zahlenwert des Buchstaben + die Zahl um die verschoben wird größer ist als 122. Diese Bedingung habe ich jedoch mit der Bedingung verknüpft, dass der Buchstabe nicht in meiner Liste Umlaute ist. Also sollte er doch folglich, wenn ich einen Umlaut eingebe nichtmehr in diesem elif weiterarbeiten, sondern zu dem springe, in dem abgefangen wird, wenn der Buchstabe ein Umlaut ist.
Das Problem, dass ich Umlaute garnicht erst weiterverarbeien kann, ist ja bereits dank eurer Hilfe gelöst ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Ich verstehe nicht, was du willst.
Was ist denn an meinem Beispielcode so, dass du es nicht willst?
Warum hängst du so an den ASCII-Codes und willst die Verschiebung unbedingt auf die ASCII-Code (also die Codenummern) beziehen?
Klar, die Umlaute hängen da irgendwo >127 quer drin. Also bekommst du natürlich irgendwelche Sonderzeichen, wenn du zum ASCII-Code einen Zahlenwert addierst und das entsprechende Zeichen nimmst.

Auf welche Zeichen möchtest du die Umlaute denn abbilden?


:?:
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

An deinem Code ist nichts auzusetzen ;-)
Nur da ich das Programm einreichen muss bei unserem Lehrer, möchte ich es so schreiben, dass er mir auch wirklich glaubt, dass ich es selbts geschrieben habe. Eventuell werde ich es mit den slices auch noch einmal schreiben, also etwa so wie du es oben hast.
Ich will die Umlaute garnicht verändern, die sollen im verschlüsselten Text einfach stehen bleiben... So wie es mit den Sonderzecihen in meinem Code geschieht. Wenn der x-te Stringteil ein Sonderzeichen ist, bleibt es einfach stehen, das wird ja in meinen if-Teilen abgefragt. Genauso sollte es ja auch mit den Umlauten sein, deshalb:

Code: Alles auswählen

if WORT[i] in Umlaute:
        geheim += WORT[i]
Kurz gesagt, sollen die Umlaute einfach nicht verändert werden, während der Verschlüsselung... Ich hoffe, du verstehst wie ich das meine... Mir gehen die Erklärungen aus :-) Ich will eben rein aus Lerneffekt bedingten Gründen noch herausfinden, wieso momentan die Umlaute verschoben werden, obwohl sie es eigentlich nicht sollten. Dient quasi nur mir selbst, werde wenn ich das gelöst habe sowieso über den gesamten Algorithmus drüber schauen und besser strukturieren und vereinfachen. ;-)

Aber noch eine kleine Frage zu deinem Algorithmus. Wenn du den verschobenen Index durch die Länge der valid-List teilst... Was genau bringt das? Reicht es nicht, wenn man einfach nur verschiebt?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Evil4President hat geschrieben:Nur da ich das Programm einreichen muss bei unserem Lehrer, möchte ich es so schreiben, dass er mir auch wirklich glaubt, dass ich es selbts geschrieben habe.
Verstehe.
Evil4President hat geschrieben:Ich will die Umlaute garnicht verändern, die sollen im verschlüsselten Text einfach stehen bleiben...
Aha. Also so:

Code: Alles auswählen

import string

zeichenvorrat = string.ascii_letters
delta = 5

def kodiere(ch):
    if ch in zeichenvorrat:
        return chr(ord(ch)+delta) # noch unvollständig -> selber machen!
    else:
        return ch

textalt = "Bist du 17? Nö, älter. Wow, sonst nix!"
textneu = ""
for ch in textalt:
    textneu += kodiere(ch)
print textneu
Ausgabe:

Code: Alles auswählen

Gnxy iz 17? Sö, äqyjw. \t|, xtsxy sn}!
Wie du am Ergebnis siehst, funktioniert das soweit ganz gut.
Aber nicht perfekt. Das zu lösen, überlasse ich dir (damit der Lehrer keinen falschen Eindruck von dir bekommt ... :wink:
Evil4President hat geschrieben:Aber noch eine kleine Frage zu deinem Algorithmus. Wenn du den verschobenen Index durch die Länge der valid-List teilst... Was genau bringt das? Reicht es nicht, wenn man einfach nur verschiebt?


Es reicht immer dann, wenn an der Stelle, an die man verschiebt noch ein (gültiges/gewolltes) Zeichen steht. Wenn du z.B. "z" um drei Stellen verschiebst, was dann?
Die erwähnte Division ist ja nur eine modulo-Operation, also nur der Rest, der bleibt, wenn ich durch die Länge dividiere. Das verhindert, dass auf einen Index zugegriffen wird, der hinter dem letzten Zeichen liegt.

In dieser Richtung liegt auch das Problem bei obigem Code ...
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Ja das Problem im obigen Code habe ich schon gefunden, wüsste auch schon wie ich es beheben könnte. Das wird ja eigentlich genauso in meinen ganzen if's abgefangen, da ein "z" zu irgend einem Sonderzeichen werden würde. Werde das Programm mal weiterhin bearbeiten und hoffe, dass es jetzt funktioniert.
Vielen Dank nochmal für die ganzen hilfreichen Tipps ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Evil4President hat geschrieben:Ja das Problem im obigen Code habe ich schon gefunden, wüsste auch schon wie ich es beheben könnte. Das wird ja eigentlich genauso in meinen ganzen if's abgefangen, da ein "z" zu irgend einem Sonderzeichen werden würde.
Dazu brauchst du aber gar nicht "die ganzen if's", sondern (maximal) eine Bedingung. Überleg doch mal genau, in welchen Fällen das Programm (ich meine meine letzte Fassung) versagt und was dann getan werden könnte.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Ah, ich hab mich grad selbst korrigiert. Hatte vergessen, dass der zeichenvorrat als String importiert wird. War immernoch auf den Codewerten festgefahren. Das läuft nur schief wenn man soweit verschiebt, dass der neu zugewiesene Index außerhalb des Strings liegen würde. Deshalb benutzt du ja auch den Rest. Hat mir anfangs nicht ganz eingeleuchtet, da ich immernoch zu sehr auf den Werten festgefahren war.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Hallo mal wieder ;-)
Ich muss sagen, ich bin gerade etwas ratlos.
Habe jetzt meinen Code mit Hilfe dessen, was pütone gepostet hat, verbessert... Allerdings bekomme ich, wenn ich einen Umlaut im eingegebenen Text habe als Ausgabe immer denselben Text zurück, wie den den ich eingegeben habe... Sobald kein Umlaut enthalten ist, funktioniert das ganze einwandfrei...

Hier mal der Code:

Code: Alles auswählen

def chiffre(text,zahl):
    import string
    valid=string.ascii_letters+'ÄÖÜäöü'
    def kodiere(ch):
        try:
            return valid[(valid.index(ch)+zahl) % len(valid)]
        except ValueError:
            return ch
    geheim=''
    for buchstabe in text:
        geheim += kodiere(buchstabe)
    return geheim
Hoffe mir kann auch jetzt wieder geholfen werden.
MFG evil4president
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

jens hat geschrieben:Warum hast du set benutzt? Es würde reichen, wenn es ein tuple ist oder sogar nur ein string...
Weil `in` mit Sets schneller ist. Da ich das heute auch gebraucht habe, habe ich extra nochmal die Geschwindigkeit mittels `timeit` überprüft. Dabei kommt ein `frozenset` übrigens nicht schneller weg als ein `set` (was nicht unbedingt unverständlich ist).
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Mit der Info zu "set()" wolltest du mir aber doch jetzt keinen Tipp geben, oder? Weil unter set() die .index Methode nicht verfügbar ist...
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Es ging mir nur darum, Zeichen schnell in einer Menge von Zeichen zu finden - da ist ein Set eben schneller als ein String (und wohl auch eine Liste - die wiederum mit einem String die feste Reihenfolge gemein hat).

Wenn du bestimmte Methoden brauchst, mag ein Set nicht mehr in Frage kommen, klar.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Evil4President hat geschrieben:Hallo mal wieder ;-)
Ich muss sagen, ich bin gerade etwas ratlos.
Habe jetzt meinen Code mit Hilfe dessen, was pütone gepostet hat, verbessert... Allerdings bekomme ich, wenn ich einen Umlaut im eingegebenen Text habe als Ausgabe immer denselben Text zurück, wie den den ich eingegeben habe... Sobald kein Umlaut enthalten ist, funktioniert das ganze einwandfrei...

Hier mal der Code:

Code: Alles auswählen

def chiffre(text,zahl):
    import string
    valid=string.ascii_letters+'ÄÖÜäöü'
    def kodiere(ch):
        try:
            return valid[(valid.index(ch)+zahl) % len(valid)]
        except ValueError:
            return ch
    geheim=''
    for buchstabe in text:
        geheim += kodiere(buchstabe)
    return geheim
Ich kann hier kein Problem entdecken, jedenfalls keins, das sich so äußert, wie du es beschrieben hast.
BlackJack

Aber da gibt's doch wieder Unicode-Probleme wenn etwas ausserhalb von ASCII eingegeben wird:

Code: Alles auswählen

In [53]: valid = 'abcäöü'

In [54]: valid.index(u'\xe4')  # Ist ein ä.
---------------------------------------------------------------------------
<type 'exceptions.UnicodeDecodeError'>    Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.UnicodeDecodeError'>: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128)
Sowie man mit Zeichen bzw. Buchstaben arbeiten möchte, die nicht im ASCII-Zeichensatz vor kommen, gibt einfach keinen sauberen Weg um Unicode herum.

Weiteres Problem falls die Kodierung des Quelltextes nicht ein Byte pro Zeichen ist, also zum Beispiel UTF-8:

Code: Alles auswählen

In [68]: valid = string.ascii_letters + 'ÄÖÜäöü'

In [69]: zahl = 5

In [70]: [valid[(valid.index(ch) + zahl) % len(valid)] for ch in 'VXZ']
Out[70]: ['\xc3', '\xc3', '\xc3']
Ups, da werden verschiedene Buchstaben auf den gleichen Bytewert abgebildet und lassen sich damit nicht mehr eindeutig dekodieren.
Evil4President
User
Beiträge: 83
Registriert: Dienstag 15. Januar 2008, 15:39
Kontaktdaten:

Vielen Dank BlackJack!
Hatte mal wieder vergessen, vor den Valid-String ein "u" für Unicode zu setzen. Habe das jetzt ergänzt und siehe da, es funktioniert einwandfrei ;-)

Nochmals vielen Dank für eure Hilfe!
Antworten