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:

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