I will answer this question:
This is basically a one line argument, that:
- Adds +1 to the pointer for the keyword (the pointer is for the index)
- checks if the new index is higher than the highest index of the keyword (length -1 because we start with 0)
- calculates the new index, if it is higher (with the modulo operator)
You could do all steps one by one like this:
letter_pointer += 1 if letter_pointer == len(keyword): letter_pointer= 0
This is basically the same, as an index, that reaches he length of the keyword, the modulo (%) function will set it to 0.
keyword = "bob" letter_pointer = 0 print (keyword[letter_pointer])
the result here would be “b”
keyword = "bob" letter_pointer = 3 print (keyword[letter_pointer])
this would throw an error, because len(keyword) is = 3 and therefor the highest index is 2 (, ,  = 3 indexes)
to avoid this, the modulo function is added, that the index can never be at 3 or more.
keyword = "bob" letter_pointer = 3 letter_pointer = letter_pointer % len(keyword) print (keyword[letter_pointer])
this repairs the error, because now in this case we set letter_pointer to 3 % 3 (which is 0, because there is no rest if we calculate 3/3)
why are we increasing the letter pointer (with the +1)?
This is because we circle through the keyword (like in the example at the top with “dog”) to add the value to the message values.
When we reach the last letter at len(keyword) - 1 (because of indexing), we need to start at the beginning again with the next circle.
The modulo function is doing all this in one go.
btw. a nice tweak to the solution given is, to make it more flexible.
The solution can still throw a lot of errors, e.g. if you use capital letters or puntuation that is not captured (e.g. ‘:’, ‘;’ etc.)
You can counter that by defining two alphabets:
alphabet = "abcdefghijklmnopqrstuvwxyz" alphabet_capital = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
you do not even need the punctuations variable, because we just make sure that every letter that is not known will just not be decrypted:
for letter in message_coded: if letter in alphabet: decode_num = (alphabet.index(letter) - keyword[letter_pointer] + 26) % 26 decoded_message += alphabet[decode_num] letter_pointer = (letter_pointer + 1) % len(keyword) elif letter in alphabet_capital: decode_num = (alphabet_capital.index(letter) - keyword[letter_pointer] + 26) % 26 decoded_message += alphabet_capital[decode_num] letter_pointer = (letter_pointer + 1) % len(keyword) else: decoded += letter
this way you will also ensure, that special characters will not cause errors in the code and are translated back correctly.
Even if you would send a message like this:
""" There is a big flaw with the coder, that you sent us. It created an error (we tried several times with different people!). Please check if there are bugs in the program you gave us. People who tested the program: Charly, Marianne, Elsa, Peter We just wanted to send this poem: 'The birds are beautiful; are they not? they fly like artists; they fly a lot! Is there more freedom; than a bird in the sky? Fly little bird; fly!' """
The official solution would try to use
letter_value = alphabet.find(letter) on special characters like ‘(’ and ‘;’ which results in an error, because it is not in alphabet (and also not in punctuation).
If capital letters should not be regarded, you can also just put the whole message in .lower() instead, which will then save one line but still encodes capital letters.
You can test this with the following sentence, I put as the final message into the decoder (keyword is the same as in the solution):
Mvtpb Yaxyip! Uro fswyg zw yig Sgwwsuwvs hfhigtglfl embg? (Wznj eshov gv mzrq etim wrfmwv!) Ei jldq jmi rdum fblru ktfv. Frvl Wvoeegk Dfcv Suajel
I hope this helped you.