Denkfehler? - Anfänger braucht Hilfe

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
Cyberx ix
User
Beiträge: 8
Registriert: Donnerstag 5. März 2009, 15:26

Ich will zu üben ein kleines Pythonprogramm schreiben, das einen text ohne umlaute durch Buchstabenvertauschen verschlüsseln kann. Bedient wird es im Moment von Python Card aus. Nur habe ich jetzt ein Probem. die Buchstaben a, b und c werden nicht verschlüsselt. Ich glaube, dass mein Problem in den Listen liegt, in denen die Buchstaben abgespeichert sind. Ich glaube auch das es irgendwie damit zusammenhängt, wie ich die Zahl angebe, um die die Buchstaben versetzt werden sollen. Ach schaut euch das einfach mal an, und habt bitte Nachsicht mit einem Anfänger. Die vielen print's sind nur wegen der Fehlersuche da. Danke schonmal für eure Hilfe!

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: cp1252 -*-

"""
__version__ = "$Revision: 1.3 $"
__date__ = "$Date: 2004/04/14 02:38:47 $"
"""

from PythonCard import model

def schluesseln(eingabe, faktor):
    x = list(eingabe)
    woerter = eingabe.split()
    y = list(u'xyzabcdefghijklmnopqrstuvwxyzabc')
    z = list(u'XYZABCDEFGHIJKLMNOPQRSTUVWXYZABC')
    k = list(u'89012345678901234567890123456789')
    print x
    print y
    wortnummer = 1
    for wort in woerter:
               
        stelle = 0
        for buchstabe in x:
            print buchstabe
            wo = 0
            #print 'for   x   gest'
            for buchstver in y:
                #print 'for y gest'
                print 'xstelle: '+str(stelle)+' '+'xst: '+x[stelle]+' '+y[wo]

                if 5 < wo < 31:
                    if x[stelle] == y[wo]:                    
                        #print 'if stelle = wo erfolgr'
                        x[stelle] = y[wo+wortnummer*faktor]
                        #print 'xstelle: '+str(stelle)+' '+'xst: '+x[stelle]+' '+'buchst: '+buchstabe+' '+y[wo]
                        print 'out: ' + x[stelle]+ ' Vers: '+str(wortnummer*faktor)
                        break
            
                if 5 < wo < 32:
                    if x[stelle] == z[wo]:                    
                        #print 'if stelle = wo erfolgr'
                        x[stelle] = z[wo+wortnummer*faktor]
                        print 'out: ' + x[stelle]+ ' Vers: '+str(wortnummer*faktor)
                        break

                if 5 < wo < 32:
                    if x[stelle] == k[wo]:                    
                        #print 'if stelle = wo erfolgr'
                        x[stelle] = k[wo+wortnummer*faktor]
                        print 'out: ' + x[stelle]+ ' Vers: '+str(wortnummer*faktor)
                        break
                if wo <= 25:
                    wo = wo+1
                else:
                    wo = 0
            stelle = stelle +1
    if wortnummer == 1:
        wortnummer = 2
    elif wortnummer == 2:
        wortnummer = 3
    elif wortnummer == 3:
        wortnummer = 1
        
            
    xb = str(''.join(x))
    return xb
    #self.components.txtdisp.text = xb
    

class MyBackground(model.Background):

    def on_initialize(self, event):
        # if you have any initialization
        # including sizer setup, do it here
        pass
    
    def on_btnverschluesseln_mouseClick(self, event):
        self.components.txtdisp.text = schluesseln(self.components.txtdisp.text, -1)    
                
            
    def on_btnentschluesseln_mouseClick(self, event):
        self.components.txtdisp.text = schluesseln(self.components.txtdisp.text, 1)
        

if __name__ == '__main__':
    app = model.Application(MyBackground)
    app.MainLoop()
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

es wäre schön wenn du auch eine ausgabe des programms zeigen und die variablen sinnvoll benennen würdest. was soll der teil mit dem "wo"? kommentar wäre hier hilfreich...

soll das programm sowas machen?

Code: Alles auswählen

>>> alphabet="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
>>> def crypt(c, i):
...   return alphabet[alphabet.index(c)+i]
...
>>> crypt("a", 3)
'd'
>>> crypt("z", 3)
'c'
>>> [crypt(c, 3) for c in "hallo"]
['k', 'd', 'o', 'o', 'r']
>>> "".join([crypt(c) for c in "hallo"])
'kdoor'
http://www.kinderpornos.info
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@Dill: wenn schon das Alphabet, dann aus dem "string"-Modul.
Die Verdoppelung kann man mit "string.ascii_lowercase*2" erreichen. Ist aber vollkommen überflüssig, wenn man den Modulo-Operator benutzt.
Die eckigen Klammern im "join"-Aufruf sind ebenfalls überflüssig

Und vielleicht noch der Hinweis darauf, dass Strings eine "translate"-Methode besitzen und "maketrans" im "string"-Modul.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

und man kann es sicher auch noch komplizierter machen, dass der herr cyba-x überhauptnixmehr versteht.

>Die eckigen Klammern im "join"-Aufruf sind ebenfalls überflüssig

an die generator-ausdrücke gewöhn ich mich nicht...
seit wann ist das eigentlich möglich?
http://www.kinderpornos.info
Cyberx ix
User
Beiträge: 8
Registriert: Donnerstag 5. März 2009, 15:26

Erst mal danke! Und ich mach so einen Aufwand obwohl das in so wenigen Zeilen geht. Naja so ist es halt als Anfänger. Danke. Und das mit den Variablen, ich versuche mich zu bessern!
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

wenn du jetzt meine lösung abschreibst bringt das ja nix.
die ist sicher auch nicht ideal. schau doch mal was eydu dazu angemerkt hat, evtl kannst du damit ja meine lösung verbessern...?
oder wir suchen den fehler in deinem code? dazu brauchts aber kommentare sonst ist mir der zu schwer verdaulich.
http://www.kinderpornos.info
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dill hat geschrieben:an die generator-ausdrücke gewöhn ich mich nicht...
seit wann ist das eigentlich möglich?
Seit 2.4.
Das Leben ist wie ein Tennisball.
Cyberx ix
User
Beiträge: 8
Registriert: Donnerstag 5. März 2009, 15:26

Also ich hab jetzt dein Verschlüsselungsverfahren in meinen Code eingebaut. Jetzt sieht er so aus:

Code: Alles auswählen

def crypt(eingabe, i)           #Eingabe ist der zu Verschüssende Text, i ist der Verschiebungsfaktor
    woerter = eingabe.split()   
    wortnummer = 1
    ausgabe = ""
    for wort in woerter:        #Wird gebraucht, da jedes Wort einen anderen Verschiebungsfaktor besiten soll
        wortverschluesselt = ""
        print wort
        for buchstabe in wort:
            try:
                alphabet="lpsbh8Okz9Nm0wPtXMYoaQi2ZG3LR1WcTfqSvDHxVK4neIE5Cgy6JF7rBUujdAlpsbh8Okz9Nm0wPtXMYoaQi2ZG3LR1WcTfqSvDHxVK4neIE5Cgy6JF7rBUujdA" 
                wortverschluesselt += alphabet[alphabet.index(buchstabe)+i*wortnummer]
                print wortverschluesselt
            except ValueError:                      #Wenn Buchstabe oder Zeichen nicht in alphabet, dann nicht ersetzen
                wortverschluesselt += buchstabe
                
        
        if wortnummer == 1:
            wortnummer = 2
        elif wortnummer == 2:
            wortnummer = 3
        elif wortnummer == 3:
            wortnummer = 1
        
        ausgabe += " "+wortverschluesselt
    return ausgabe
Hoffe der ist jetzt nen bisschen besser. Zumindest funktioniert's so. Mein Problem bei der Lösung mit den Listen war, das die irgendwie nur eine bestimmte länge haben durften. Ich habe jetzt deine Lösung so umgeschrieben, dass man ganze Texte verschlüsseln kann.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Der Algorithmus funktioniert so aber nicht. Versuch mal i=2000.

Alle meine Hinweise kannst du auch auf deinen jetzigen Code anwenden.

Schau dir mal die "enumerate"-Funktion an, damit kannst du dir die "wortnummer"-Berechnung zum größten teil sparen.

"wortverschluesselt" sollte auch besser eine Liste von Buchstaben sein, welche du am Ende mit "".join zusammenfügst.

Die Kommentare sollten auch nicht in der Zeile hinter dem Code stehen, sondern in einer einzelnen Zeile davor. Dann kann man es viel besser lesen. Zur Beschreibung von Funkionen gibt es übrigens Docstrings.
Hoffe der ist jetzt nen bisschen besser. Zumindest funktioniert's so. Mein Problem bei der Lösung mit den Listen war, das die irgendwie nur eine bestimmte länge haben durften. Ich habe jetzt deine Lösung so umgeschrieben, dass man ganze Texte verschlüsseln kann.
Dann hast du irgendwo einen Fehler gemacht (wahrscheinlich Zurgriff auf enien zu großen Index), Listen können beliebig lang werden.
Das Leben ist wie ein Tennisball.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Cyberx ix hat geschrieben:Zumindest funktioniert's so.
Der Satz ist verdächtig, weil er häufig impliziert, dass derjenige, der sich in dieser Weise äußert, im Grunde nicht versteht, WARUM sein Programm das macht, was es macht, aber aufgrund einiger Durchläufe mit ausgewählten Testdaten anhand des anscheinend erwünschten Ergebnisses zu dem Schluss kommt, es mache - auch mit anderen Eingabewerten und unter anderen Bedingungen - immer das, was es soll ... :)
Cyberx ix
User
Beiträge: 8
Registriert: Donnerstag 5. März 2009, 15:26

Der Satz ist verdächtig, weil er häufig impliziert, dass derjenige, der sich in dieser Weise äußert, im Grunde nicht versteht, WARUM sein Programm das macht, was es macht, aber aufgrund einiger Durchläufe mit ausgewählten Testdaten anhand des anscheinend erwünschten Ergebnisses zu dem Schluss kommt, es mache - auch mit anderen Eingabewerten und unter anderen Bedingungen - immer das, was es soll ... Smile
So war das eigentlich nicht gemeint. Es war eher darauf bezogen, dass ich weiß, dass mein Code der eines Anfängers ist und dass man das ganze auch besser schreiben könnte, wenn man das Wissen dazu hätte.
Der Algorithmus funktioniert so aber nicht. Versuch mal i=2000.

Alle meine Hinweise kannst du auch auf deinen jetzigen Code anwenden.

Schau dir mal die "enumerate"-Funktion an, damit kannst du dir die "wortnummer"-Berechnung zum größten teil sparen.

"wortverschluesselt" sollte auch besser eine Liste von Buchstaben sein, welche du am Ende mit "".join zusammenfügst.

Die Kommentare sollten auch nicht in der Zeile hinter dem Code stehen, sondern in einer einzelnen Zeile davor. Dann kann man es viel besser lesen. Zur Beschreibung von Funkionen gibt es übrigens Docstrings.
Das mit dem i = 2000 ist ja klar, das funktioniet im Moment nur bis 32, weil der string "alphabet" ja nur so lang ist. Damit werde ich mich heute Abend dann mal beschäftigen, ich muss jetzt leider noch was anderes machen.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

du hast ja hier das problem, dass i nicht zu groß werden darf. (sonst hast du einen ungültigen listenindex)
du kannst das in deinem code ganz deutlich machen, indem du etwa schreibst:

assert(i < MAXIMALES_I), "i ist zu gross"


in diesem speziellen fall stört ein zu grosses i aber garnicht, da du einfach wieder am anfang der liste anfängst wenn i zu groß wird.
dabei hilft dir der modulo-operator (%)


genreller hinweis: einer der hauptvorteile von python ist der interpreter.
probier darin erstmal die einzelteile aus, nehme sie genau unter die lupe, dann verstehst du viel schneller was passiert.
http://www.kinderpornos.info
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier mal mit exzessiver Nutzung des [mod]string[/mod]-Moduls, wobei ich `translate()` der Einfachheit halber außen vor lasse:

Code: Alles auswählen

import string

def very_simple_crypt(string_to_crypt, pos_to_jump):
    alphanums = string.ascii_letters + string.digits
    crypted = ''
    for char in string_to_crypt:
        if char in string.whitespace or char in string.punctuation:
            crypted += char
        else:
            pos = (pos_to_jump + alphanums.index(char)) % (len(alphanums) - 1)
            crypted += alphanums[pos]
    return crypted

Code: Alles auswählen

In [3]: very_simple_crypt('hallo', 3)
Out[3]: 'kdoor'

In [4]: very_simple_crypt('Hallo, du Mensch!', 3)
Out[4]: 'Kdoor, gx Phqvfk!'

In [5]: very_simple_crypt('Hallo, du Mensch!', 347647)
Out[5]: 'UnyyB, qH ZrAFpu!'

In [6]: very_simple_crypt('2 girls, 1 cup', 3)
Out[6]: '5 jluov, 4 fxs'
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Entschlüsseln könnte ein wenig schwierig werden ;-)

Code: Alles auswählen

>>> very_simple_crypt("a", 1)
'b'
>>> very_simple_crypt("9", 1)
'b'
Es muss

Code: Alles auswählen

pos = (pos_to_jump + alphanums.index(char)) % len(alphanums)
heißen.

Man sollte auch besser fragen, ob ein Zeichen umwandelbar ist, dann deckt man auch alles ab:

Code: Alles auswählen

>>> very_simple_crypt("§", 1)
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    very_simple_crypt("§", 1)
  File "C:\Programme\Python30\test.py", line 9, in very_simple_crypt
    pos = (pos_to_jump + alphanums.index(char)) % (len(alphanums)-1)
ValueError: substring not found
Edit:

Code: Alles auswählen

import string

def very_simple_crypt(string_to_crypt, pos_to_jump):
    alphanums = string.ascii_letters + string.digits
    crypted = []
    for char in string_to_crypt:
        try:
            pos = (pos_to_jump + alphanums.index(char)) % len(alphanums)
            crypted.append(alphanums[pos])
        except ValueError:
            crypted.append(char)
    
    return "".join(crypted)
Das Leben ist wie ein Tennisball.
Cyberx ix
User
Beiträge: 8
Registriert: Donnerstag 5. März 2009, 15:26

Ich glaube ich werde mich jetzt erstmal mit dem modulo-operator (%) und danach mit dem string-Modul beschäftigen. Also heute bringe ich das aber nicht mehr hin. Mein Gehirn fängt bald an "IndexError: Index our of range" zu senden, wenn ich nicht mehr durchblicke. :D Danke für eure Tipps und eure Hilfe! Ich werde euch demnächst wieder Belästigen. Nur als Vorwarnung.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@EyDu:

Ich muss zugeben, dass ich meine Version nicht mehr so ausführlich durchgetestet habe, besonders nicht auf's Entschlüsseln.
Antworten