@Brevista: Warum das mit ``buchstabe in satz`` nicht geht, wird Dir die Fehlermeldung ja verraten haben.
Und bei der ``range(len(satz)):``-Lösung ist der Name `buchstabe` falsch, denn die Schleifenvariable wird in dem Fall ja gar nicht an Buchstaben gebunden sondern an Zahlen die als Indexwerte verwendet werden.
Warum heisst das eigentlich `verschlüsselung()`, und `satz`, dann aber `key` und nicht `schlüssel`?
`re` ist kein guter Name für das Ergebnis, denn das ist eine Abkürzung. Zudem noch eine die üblicherweise für „regular expression“ steht, wie beim `re`-Modul in der Standardbibliothek.
Wiederholtes zusammensetzen von Zeichenketten mit ``+`` in einer Schleife ist nicht gut, da potentiell sehr ineffizient, da Zeichenketten nicht veränderbar sind und man deshalb damit rechnen muss das für jede neue Teilzeichenkette das bisherige und das neue in eine neu erstellte Zeichenkette kopiert werden müssen und die beiden Teile wieder freigegeben werden. Darum sammelt man die Teile besser in einer Liste und setzt die am Ende mit `join()` zusammen:
Code: Alles auswählen
def verschlüsselung(satz, schlüssel):
ergebnis = list()
for i in range(len(satz)):
ergebnis.append(chr(ord(satz[i]) + ord(schlüssel[i % len(schlüssel)])))
return ''.join(ergebnis)
Den Index braucht man ja eigentlich nur für den Schlüssel, deshalb kann man auch über die Buchstaben des Satzes *und* den Index iterieren (und die Umwandlung von Zahlen in Zeichen habe ich in die letzte Zeile verschoben):
Code: Alles auswählen
def verschlüsselung(satz, schlüssel):
ergebnis = list()
for i, buchstabe in enumerate(satz):
ergebnis.append(ord(buchstabe) + ord(schlüssel[i % len(schlüssel)]))
return ''.join(map(chr, ergebnis))
In Python gibt es oft einen Weg ohne Indexvariablen. Hier Beispielsweise über `itertools.cycle()` und `zip()` (+ Umwandlung der Zeichen von Satz und Schlüssel aus der Schleife heraus gezogen):
Code: Alles auswählen
def verschlüsselung(satz, schlüssel):
ergebnis = list()
for wert, schlüssel_wert in zip(map(ord, satz), cycle(map(ord, schlüssel))):
ergebnis.append(wert + schlüssel_wert)
return ''.join(map(chr, ergebnis))
Hier bräuchte man die Ergebnisliste nicht mehr sondern käme auch mit einem Generatorausdruck hin:
Code: Alles auswählen
def verschlüsselung(satz, schlüssel):
ergebnis = (
wert + schlüssel_wert
for wert, schlüssel_wert
in zip(map(ord, satz), cycle(map(ord, schlüssel)))
)
return ''.join(map(chr, ergebnis))
Wenn das ``wert + schlüssel_wert`` nicht etwas zu kurz gedacht wäre, dann könnte man auch `operator.add()` und `itertools.starmap()` verwenden:
Code: Alles auswählen
def verschlüsselung(satz, schlüssel):
ergebnis = starmap(add, zip(map(ord, satz), cycle(map(ord, schlüssel))))
return ''.join(map(chr, ergebnis))
Man könnte `add()` dann durch eine eigene `wert_verschlüsseln()`-Funktion ersetzen die das Problem vom einfachen Addieren/Subtrahieren nicht mehr hat. Ich würde so eine Ver-/Entschlüsselung auch auf Bytes definieren und nicht auf Zeichen. Dann kann man *alles* ver-und entschlüsseln, weil sich alles als Bytes ausdrücken lässt.
Ein nacktes ``except:`` ohne konkrete Ausnahme(n) anzugeben ist fast nie eine sinnvolle Fehlerbehandlung. Damit erschwert man sich die Fehlersuche, denn das behandelt *alle* Ausnahmen. Auch solche mit denen man gar nicht rechnet.
Hier ”verschluckst” Du die Fehlerursache auch noch, das heisst man bekommt nicht heraus *was* der Fehler war. Und der Aufrufer kann einen Fehler noch nicht einmal erkennen und darauf reagieren. Wenn beim Aufruf von `entschlüsselung()` der Wert 'ERROR' zurückgegeben wird, hat dann jemand das Wort 'ERROR' verschlüsselt, oder ist beim entschlüsseln ein Fehler aufgetreten?
Ansonsten Unterscheiden sich die beiden Funktionen nur durch einen einzigen Operator. Das würde man dann besser in eine Funktion herausziehen die diesen Operator als Argument bekommt, und von den anderen Beiden Funktionen aufgerufen wird. Die Operatoren gibt es im `operator`-Modul alle auch als Funktionen.
Die Zeilen 21 und 22 machen keinen Sinn.
Das das Hauptprogramm auf Modulebene steht und auch noch von Funktionsdefinitionen unterbrochen wird, ist unübersichtlich. Üblicherweise steht das Hauptprogramm in einer Funktion die `main()` heisst.