Yep, its a tough project to think through.
In your case, you need what’s happening with the keyword to overlap with what’s happening with the letters in message
so you shouldn’t put
for c in message:
and
for l in keyword:
as separate loops.
Instead of having a loop to go through the message, it may be more useful to have a counter variable [that starts at 0 and increases by 1 each time the letter changes] to then use to find the appropriate thing in the keyword.
And then use something like
l = keyword[counter_variable % len(keyword)]
to get the appropriate letter from the keyword
.
Also, you don’t need clue
in your function: the clue
string is just an aid to check that what your doing with the keyword is correct, but it wouldn’t be part of the decoding function. (You don’t need to loop through clue
at all.)
You’re concerned with the position of the keyword letter l
in the alphabet, so instead of
l_value = clue.find(l)
you should have
l_value = alphabet.find(l)
You have:
vigenere_decoded_message += [(c_value % 26) + (l_value % len(keyword))]
but you’re adding a letter from alphabet
, so instead of
vigenere_decoded_message += [stuff]
it should be
vigenere_decoded_message += alphabet[stuff]
where stuff
is a placeholder for the calculation to get the index of the appropriate character.
also, the % 26
should be the last thing done in the calculation (to ensure that you have a valid index of the alphabet
string).
So you might end up with something like:
vigenere_decoded_message += [(c_value + l_value) % 26]
The else
you have should happen if that letter in the message
is not in alphabet
so
the indentation for
if c in alphabet:
and
else:
should be the same.
possible solution (try not to look at it until you're done)
Here’s one possible way to do it using much of your code.
The commented out code would print the stuff identical to hint
.
alphabet = "abcdefghijklmnopqrstuvwxyz"
v_message = "txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!"
clue = "fri ends frie nd sfrien dsfri ends frie nds fri endsfrie ndsfr ien dsfrie nd sfriendsfri "
def vigenere_decode(message, keyword):
vigenere_decoded_message = ""
i = 0 #counter (counts iterations)
for c in message:
if c in alphabet:
c_value = alphabet.find(c)
l = keyword[i % len(keyword)]
#print(l, end="");
l_value = alphabet.find(l)
vigenere_decoded_message += alphabet[(c_value + l_value) % 26]
i += 1
else:
#print(" ", end="")
vigenere_decoded_message += c
#print()
return vigenere_decoded_message
print(vigenere_decode("txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!", "friends"))
Think about the order of the steps for the letters from keyword
for each letter in the message
- setup (like a counter variable) may be needed
- get the appropriate letter from
keyword
- find the position of that letter in the
alphabet
- use that result to get the position of the shifted letter (multiple steps)