Seite 1 von 1

Finde den Fehler in meinem Skript nicht

Verfasst: Montag 13. April 2009, 10:29
von Dango
Hallo liebe Python-Programmierer,
da ich schon in mehreren Fällen hier super Hilfe bekommen habe möchte ich noch mal um etwas Hilfe beten.
Ich bin eigentlich noch ein ziemlicher Anfänger und habe einen kleinen Code geschrieben, der eigentlich .txt Dateien nach dem Caeser-Verfahren einfach verschlüsseln und in einer .caes(wegen CAESar) Datei den Codierten text abspeichern soll. Der Coder sieht so aus :

Code: Alles auswählen

def caesercode(buchstabe):
    klar="abcdefghijklmnopqrstuvwxyz"
    i=klar.index(buchstabe)
    geheim=klar[i:] + klar[:i]
    code={}
    for j in range(len(klar)):
        code[klar[j]]=geheim[j]
    return code
def codiere(text, codedict):
    geheim=""
    for b in text:
        if b in text:
            neu = codedict[b]
        else:
            neu = b 
        geheim = geheim + neu
    return geheim
def codiere_datei(dateiname, char):
    f=open(dateiname+".txt")
    text=f.read()
    f.close()
    neu= codiere(text.lower(), caesercode(char))
    g=file(dateiname+".caes","w")
    g.write(neu)
    g.close
So natürlich passier erstma nichts weil ich ja nur Funktionen definiert habe . Aber wenn ich nun den Befehl: codiere_datei("C:\\py4kids\\kap12\\nocheintext","q") eingebe kommt folgende Meldung:
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
codiere_datei("C:\\py4kids\\kap12\\nocheintext","q")
File "C:\py4kids\kap12\coden.py", line 22, in codiere_datei
neu= codiere(text.lower(), caesercode(char))
File "C:\py4kids\kap12\coden.py", line 13, in codiere
neu = codedict
KeyError: ' '
Kann jemand den Fehler in meinem Skript finden??
Wenn ja bitte ich darum mir zu zeigen wo und mir zu erklären warum.
Ich bedanke mich schon im Voraus für die Hilfe
MfG
Dango

Verfasst: Montag 13. April 2009, 10:48
von EyDu
Zeile 12 sollte wahrscheinlich

Code: Alles auswählen

if b in codedict:
heißen.

Verfasst: Montag 13. April 2009, 10:49
von HWK
Sollte Zeile 12

Code: Alles auswählen

if b in codedict:
heißen? Dann schau Dir auch mal die get-Methode von dicts an.
MfG
HWK

Edit: Zu spät.

Verfasst: Montag 13. April 2009, 11:00
von EyDu
Noch ein paar Anmerkungen:

- schau dir mal im String-Modul "ascii_lowercase" an
- dann könnte für dich noch die translate-Methode auf Strings interessant sein, in dem Zusammenhang auch die Funktion "maketrans"
- bei Zuweisungen sollte auf beiden Seiten des Gleichheitszeichen ein Leerzeichen stehen
- wenn du beim Iterieren über eine Liste/String den Index benötigst, dann benutze enumerate

Code: Alles auswählen

for j, k in enumerate(klar):
        code[k] = geheim[j]
oder in diesem Fall:

Code: Alles auswählen

for k, g in zip(klar, geheim):
        code[k] = g
- die "codiere"-Funktion bekommst du gut in einer einzigen List-Comprehension unter, beachte dazu am besten den Tipp von HWK; dazu kannst du dir noch die "join"-Methode auf Strings anschauen
- beim Öffnen/Lesen/Bearbeiten der Dateien solltest du noch mögliche Fehler behandeln, indem du die entsprechenden Exceptions abfängst; je nachdem welche Python-Version du benutzt könnte auch das "with"-Statement für dich interessant sein
- und dann solltest du zum Öffnen von Dateien nur "open" benutzen

Verfasst: Montag 13. April 2009, 11:33
von Dango
Einen RIESEN Dank an euch Beide!
Der Skript läuft nun!
@EyDu Vielen Dank für die Anregungen ich werde versuchen sie zu verstehen ;-)
Noch einmal : Vielen Vielen Dank!!!
MfG
Dango

Verfasst: Montag 13. April 2009, 13:22
von Dango
Es hat sich leider doch noch ein Problem gefunden und ich hoffe mir kann da genau so gut geholfen werden wie beim ersten Problem.
Ich hatte mir gedacht man müsse den verschlüsselten Text ja auch wieder entschlüsseln können daher habe ich mein Skript damit ergänzt:

Code: Alles auswählen

def dcaesercode(buchstabe):
    klar="abcdefghijklmnopqrstuvwxyz"
    dc={}
    cc=caesercode(buchstabe)
    for l in klar:
        dc[cc[l]]=l
        
    return dc  
So nun habe ich zur Probe mal mir durch die ganz oben im ersten Beitrag geposteten Funktion caesercode(buchstabe) den Code mit dem Buchstaben "r" generieren lassen. Python spuckt daraufhin diese Dictionary aus :
caesercode("r")
{'a': 'r', 'c': 't', 'b': 's', 'e': 'v', 'd': 'u', 'g': 'x', 'f': 'w', 'i': 'z', 'h': 'y', 'k': 'b', 'j': 'a', 'm': 'd', 'l': 'c', 'o': 'f', 'n': 'e', 'q': 'h', 'p': 'g', 's': 'j', 'r': 'i', 'u': 'l', 't': 'k', 'w': 'n', 'v': 'm', 'y': 'p', 'x': 'o', 'z': 'q'}
Nun nehm ich meine Funktion dcaesercode(buchstabe) und will für diesen Code den decodierungs Code generieren . Dann kommt aber das :
dcaesercode("r")
{'a': 'j', 'c': 'l', 'b': 'k', 'e': 'n', 'd': 'm', 'g': 'p', 'f': 'o', 'i': 'r', 'h': 'q', 'k': 't', 'j': 's', 'm': 'v', 'l': 'u', 'o': 'x', 'n': 'w', 'q': 'z', 'p': 'y', 's': 'b', 'r': 'a', 'u': 'd', 't': 'c', 'w': 'f', 'v': 'e', 'y': 'h', 'x': 'g', 'z': 'i'}
Warum werden die Buchstaben nun GANZ anderen Buchstaben zugeordnet??
Ich hoffe das man mir genau so schnell wie eben helfen kann.
Vielen vielen Dank schon mal im Voraus
MfG
Dango

Verfasst: Montag 13. April 2009, 13:50
von Spezmanu
soweit ich das gesehen hab, ist das die richtige Decodierung. Dictionaries haben nur die Eigenschaften, dass die Schlüssel keine sortierte Reihenfolge aufweisen.
d.h. wenn du jetzt die Schlüssel sortierst, siehst du auch die Reihenfolge. oder du testest es ganz einfach

Verfasst: Montag 13. April 2009, 14:07
von Dango
Ich habe es einfach mal ausprobiert ob es einfach richtig decodiert wird. Doch der Text, der eigentlich "laber laber test test" heißen sollte heißt nun "rghkx rghkx zkyz zkyz".
Das heißt i-was ist immer noch falsch :-(

Verfasst: Montag 13. April 2009, 14:31
von HWK
Zeig mal den gesamten Code, auch den Deines Tests.
MfG
HWK

Verfasst: Montag 13. April 2009, 19:17
von busfahrer
@Dango

da ich mit Python auch mit dem Buch "Python für Kids" angefangen
habe :wink: ,habe ich hier noch das ein oder andere Übungs-Skript
herum liegen.Vielleicht hilft es dir ja dein Problem zu erkennen
und zu lösen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf8 -*-

# caesarcode.py : Verschluesselt und entschluesselt nach dem Caesarcode.


testtext = "bla bla test test"


def caesarcode(buchstabe):
    klar = "abcdefghijklmnopqrstuvwxyz"
    i = klar.index(buchstabe)
    geheim = klar[i:] + klar[:i]
    code = {}
    for j in range(len(klar)):
        code[klar[j]] = geheim[j]
    return code

def decodedict(codedict):
    dc = {}
    for schluessel, wert in codedict.items():
        dc[wert] = schluessel
    return dc
                   
    

def codiere(text, codedict):
    geheim = ""
    for b in text:
        if b in codedict:
            neu = codedict[b]
        else:
            neu = b
        geheim = geheim + neu
    return geheim


if __name__ == "__main__":
    print "Testtext:"
    print testtext
    print

    cc = caesarcode("r")
    geheimtext = codiere(testtext, cc)

    print "Geheimtext:"
    print geheimtext
    print

    dc = decodedict(cc)
    klartext = codiere(geheimtext, dc)

    print "Klartext:"
    print klartext
Gruß...busfahrer

Verfasst: Montag 13. April 2009, 20:48
von CM
Was EyDu mit string.ascii_lowercase meinte verdeutlicht dies:

Code: Alles auswählen

import string
klar = string.ascii_lowercase
def foo():
    print klar
foo()
HTH,
Christian

Verfasst: Dienstag 14. April 2009, 08:55
von Dango
Ich bitte um Verzeihung, dass ich nicht früher antworten konnte, aber mein Internet hatte gestern gestreikt :-(
@HWK Mein gesamter coder sieht jetzt so aus :

Code: Alles auswählen

def caesercode(buchstabe):
    klar="abcdefghijklmnopqrstuvwxyz"
    i=klar.index(buchstabe)
    geheim=klar[i:] + klar[:i]
    code={}
    for j in range(len(klar)):
        code[klar[j]]=geheim[j]
    return code
def codiere(text, codedict):
    geheim=""
    for b in text:
        if b in codedict:
            neu = codedict[b]
        else:
            neu = b 
        geheim = geheim + neu
    return geheim
def codiere_datei(dateiname, char):
    f=open(dateiname+".txt")
    text=f.read()
    f.close()
    neu= codiere(text.lower(), caesercode(char))
    g=file(dateiname+".caes","w")
    g.write(neu)
    g.close

def dcaesercode(buchstabe):
    klar="abcdefghijklmnopqrstuvwxyz"
    dc={}
    cc=caesercode(buchstabe)
    for l in klar:
        dc[cc[l]]=l
        
    return dc  
                
def dcodiere_datei(dateiname,char):
    f=open(dateiname+".caes")
    text=f.read()
    f.close()
    neu= codiere(text.lower(), caesercode(char))
    g=file(dateiname+".txt","w")
    g.write(neu)
    g.close
Nun dann habe ich den Text "laber laber test test" in der Datei nocheintext.txt mit der Funktion codiere_datei mit dem buchstaben "r" codiert. Dann kam in der .caes datei folgender Text heraus "crsvi crsvi kvjk kvjk". diesen Text habe ich nun mit der Funktion dcodiere_datei Versucht zu decodieren. Der Skript lief doch das ergebnis war eine .txt _ Datei mit dem Inhalt rghkx rghkx zkyz zkyz anstatt dem erwünschtem "laber laber test test".
@busfahrer
Vielen Dank für den Code, doch könntest du mir bitte die 21ste zeile erklären? Ich war lange nicht mehr am Buch ( bzw. an Python) und verstehe nicht ganz wie es möglich ist und was für welche Folgen es hat ,wenn man 2 Sachen mit einem Komma zwischen for und in schriebt.
@CM Vielen Dank!
Vielen Dank noch mal an Alle!!!
MfG
Dango

Verfasst: Dienstag 14. April 2009, 10:55
von Spezmanu
Muss es in zeile 40 nicht heißen:
neu= codiere(text.lower(), dcaesercode(char))

und in zeile 43 fehlt soweit ich weiß ()

Verfasst: Dienstag 14. April 2009, 11:23
von Dango
@Spezmanu
Vielen vielen Dank!!!! Das waren die Fehler! Mein Skript läuft nun wie er laufen soll !! Danke!!!
Ich denke in anderen Foren hätten sie sich noch nicht mal die Mühe gemacht den Skript so genau nach Fehlern zu durchforsten. Deswegen ein riesiges Danke an ALLE die mir in diesem Thread geholfen haben!
MfG
Dango

Verfasst: Dienstag 14. April 2009, 12:15
von cofi
Jetzt könntest du dich erkenntlich zeigen indem du die ganzen Verbesserungsvorschläge im Thread auch umsetzt ;)

Passend dazu gibts auch noch: [wiki]PEP 8 (Übersetzung)[/wiki] und das Orginal

Verfasst: Dienstag 14. April 2009, 13:42
von yipyip
Hab' auch noch eine Version:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import with_statement
import string
import codecs

def encdecode(alpha):
  
  def code(text, char, mode):

    index = alpha.find(char)
    alpha_i = alpha[index:] + alpha[:index]
    pair = alpha, alpha_i
    dct = dict(zip(pair[0^mode], pair[1^mode]))
    return ''.join(dct.get(c, c) for c in text)

  codefunc = lambda mode : lambda text, char: code(text, char, mode)
  return codefunc(0), codefunc(1)


def file_encdecode(encdecode, alpha=string.printable):

  def file_code(src, dest, char, encdec, mode):

    with codecs.open(src, 'r', 'utf-8') as infile:
      text = infile.read()

    #print text.encode('utf-8')
    with codecs.open(dest, 'w', 'utf-8') as outfile:
      outfile.write(encdec[mode](text, char))

  codefunc = lambda mode:\
    lambda src, dest, char: file_code(src, dest, char, encdecode(alpha), mode)
    
  return codefunc(0), codefunc(1)

 
if __name__ == '__main__':

  enc, dec = file_encdecode(encdecode)
  enc('test', 'test.caes', 'x')
  dec('test.caes', 'test.clear', 'x')
...duck und weg...
:wink:
yipyip

Verfasst: Donnerstag 16. April 2009, 12:04
von Dango
Ich werde mich bemühen. :wink: