Codieren in zwei Richtungen #
Buchstaben als Zahlen codieren #
Habe ich dir schon von meinem großen Vorbild erzählt? Dieser Mensch hat sich ein wirklich großes Projekt vorgenommen, und dieses sein Leben lang verfolgt – es lohnt sich, dies bei Gelegenheit einmal anzusehen.
Sein Name ist hier in Zahlen codiert:
4 15 14 1 12 4 5 11 14 21 20 8
Wenn du neugierig warst, und den Namen decodiert hast, weißt du im Prinzip schon genau, mit welchem Vorgehen sich das hier beschriebene Problem lösen lässt. Vielleicht hast du auch schon eine Idee, wie sich das Vorgehen in einer Programmiersprache aufschreiben lässt?
Wir lassen den Computer die langweilige Arbeit übernehmen #
Um einen Text nach und nach in Zahlen zu codieren, bestimmen wir nach und nach die Position jedes Buchstabens im Alphabet. Diese Bestimmung kann eine Funktion für uns erledigen!
Im folgenden Codegerüst siehst du eine entsprechende Funktion angelegt. (Neu ist dir vielleicht die Erweiterung : str
und -> int
im Kopf der Funktion – das bedeutet, dass die Funktion eine Zeichenkette (str
) erwarten, und eine ganze Zahl (int
) zurückgeben soll.)
Lies dir die Beschreibung der Funktion position_im_alphabet
im Docstring genau durch, sieh’ dir die Testfälle an, übernimm den Code in Thonny, und implementiere die Funktion entsprechend. Führe dein Programm regelmäßig aus, um zu sehen, ob du die Testfälle erfüllen kannst. Hilfreiche Tipps findest du weiter unten.
import doctest
def position_im_alphabet(zeichen: str) -> int:
"""
Die Funktion positionImAlphabet gibt für einzelne
Buchstaben deren Position (1..26) im Alphabet zurück.
Für Umlaute, andere Zeichen und längere Zeichenketten
wird -1 zurückgegeben.
>>> position_im_alphabet('c')
3
>>> position_im_alphabet('Z')
26
>>> position_im_alphabet(' ')
-1
>>> position_im_alphabet('abc')
-1
"""
pass
if __name__ == '__main__':
doctest.testmod()
Tipp 1
Nutze eine Fallunterscheidung, um sicherzustellen, dass die übergebene Zeichenkette genau ein Zeichen umfasst und aus dem Alphabet stammt.
if <Zeichenkette genau ein Zeichen lang> and <das Zeichen kommt im Alphabet vor>:
pass # dann kann’s weitergehen! (Wie sehen wir später…)
else:
return -1 # Andernfalls wird der Fehlercode zurückgegeben
Tipp 2
<Zeichenkette genau ein Zeichen lang>
lässt sich mit Hilfe der eingebauten len
-Funktion ermitteln:
len(zeichen) == 1
Tipp 3
<das Zeichen kommt im Alphabet vor>
lässt sich mit einem Alphabetstring und dem Schlüsselwort in
feststellen:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
… zeichen in alphabet …
Übrigens können wir Großbuchstaben, die ja eventuell vorkommen können, mit zeichen.lower()
in Kleinbuchstaben verwandeln – so müssen wir nicht verschiedene Alphabete überprüfen!
Tipp 4
So setzt sich nun diese Fallunterscheidung insgesamt zusammen:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
if len(zeichen) == 1 and zeichen.lower() in alphabet:
pass # dann kann’s weitergehen! (Wie sehen wir später…)
else:
return -1 # Andernfalls wird der Fehlercode zurückgegeben
Tipp 5
Wo wir nun die praktische Alphabet-Zeichenkette schon haben, lässt sich hier auch die Position ablesen. Teste einmal die index
-Funktion, die sich an Zeichenketten aufrufen lässt:
>>> 'hallo'.index('h')
0
>>> 'hallo'.index('a')
1
>>> 'hallo'.index('l')
2
>>> 'hallo'.index('ll')
2
>>> 'hallo'.index('i')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
Alternativ ließe sich auch eine Wiederholung nutzen, die einmal durch die Alphabet-Zeichenkette hindurchgeht und jedes Zeichen mit dem eingegebenen Zeichen vergleicht. Mit der index
-Funktion kommt man allerdings schneller zum Ziel.
Tipp 6
Der Index startet natürlich bei der Zahl 0 – wir wollen aber die Position im Alphabet herausbekommen, und fangen daher bei 1 an. Damit kommen wir zu der Zeile (an der richtigen Stelle eingesetzt):
return alphabet.index(zeichen.lower()) + 1
Lösungsvorschlag
Wo wir nun die praktische Alphabet-Zeichenkette schon haben, lässt sich hier auch die Position ablesen. Teste einmal die index
-Funktion, die sich an Zeichenketten aufrufen lässt:
def position_im_alphabet(zeichen: str) -> int:
"""
Die Funktion positionImAlphabet gibt für einzelne
Buchstaben deren Position (1..26) im Alphabet zurück.
Für Umlaute, andere Zeichen und längere Zeichenketten
wird -1 zurückgegeben.
>>> position_im_alphabet('c')
3
>>> position_im_alphabet('Z')
26
>>> position_im_alphabet(' ')
-1
>>> position_im_alphabet('abc')
-1
"""
alphabet = 'abcdefghijklmnopqrstuvwxyz'
if len(zeichen) == 1 and zeichen.lower() in alphabet:
return alphabet.index(zeichen.lower()) + 1
else:
return -1
Um die Funktion in Aktion zu sehen, solltest du sie nun einmal ausprobieren. Etwa so:
if __name__ == '__main__':
doctest.testmod()
for buchstabe in 'Hallo':
print(position_im_alphabet(buchstabe))
Klappt alles?
Zahlen zu Buchstaben decodieren #
Nun fehlt noch der umgekehrte Weg: wie lässt sich herausbekommen, welcher Buchstabe zu einer gegebenen Zahl gehört?
Übernimm’ den folgenden Code in die gleiche Datei, die du bereits angelegt hast. Nun muss die andere Richtung implementiert werden! Tipps findest du wieder untern.
def buchstabe_an_position(position: int) -> str:
"""
Die Funktion buchstabe_an_position gibt für Zahlen zwischen
1 und 26 Buchstaben zurück, die an der entsprechenden
Position im Alphabet stehen. Für alle anderen Zahlen
wird eine leere Zeichenkette zurückgegeben.
>>> buchstabe_an_position(2)
'b'
>>> buchstabe_an_position(25)
'y'
>>> buchstabe_an_position(27)
''
>>> buchstabe_an_position(-1)
''
"""
pass
Tipp 1
Liegt die übergebene Position nicht zwischen (einschließlich) 1 und 26 soll eine leere Zeichenkette zurückgegeben werden – das lässt sich mit einer Fallunterscheidung erledigen:
if 1 <= position <= 26:
pass # hier muss noch weiter programmiert werden…
else:
return ''
Python erlaubt es wie oben gezeigt, gleich zwei Bedingungen zu überprüfen (1 ist kleiner/gleich als die Position, die Position ist kleiner/gleich als 26).
Tipp 2
Um zu bestimmen, welcher Buchstabe nun an einer bestimmten Position im Alphabet steht, hilft uns wieder der Alphabetstring weiter:
alphabet = 'abcdefghijklmnopqrstuvwxyz'
return alphabet[position]
Schon fertig?
Tipp 3
- 1
an der richtigen Stelle. (Immer das gleiche: der Index beginnt bei 0, die Position bei 1…)
Lösungsvorschlag
Um zu bestimmen, welcher Buchstabe nun an einer bestimmten Position im Alphabet steht, hilft uns wieder der Alphabetstring weiter:
def buchstabe_an_position(position: int) -> str:
"""
Die Funktion buchstabe_an_position gibt für Zahlen zwischen
1 und 26 Buchstaben zurück, die an der entsprechenden
Position im Alphabet stehen. Für alle anderen Zahlen
wird eine leere Zeichenkette zurückgegeben.
>>> buchstabe_an_position(2)
'b'
>>> buchstabe_an_position(25)
'y'
>>> buchstabe_an_position(27)
''
>>> buchstabe_an_position(-1)
''
"""
alphabet = 'abcdefghijklmnopqrstuvwxyz'
if 1 <= position <= 26:
return alphabet[position - 1]
else:
return ''
Nun lässt sich auch der Name decodieren:
codierter_name = [4, 15, 14, 1, 12, 4, 5, 11, 14, 21, 20, 8]
for pos in codierter_name:
print(buchstabe_an_position(pos))