Off-Platform Project: Coded Correspondence

I’m stuck on Step 5 of the Python Off-Platform Project “Coded Correspondence.”
Here is the link to the project: link

The instructions for Step 5 in particular are:

           Now we use the repeat the keyword over and over to generate a _keyword phrase_ that is the same length as the message we want to code. So if we want to code the message "barry is the spy" our _keyword phrase_ is "dogdo gd ogd ogd". Now we are ready to start coding our message. We shift the each letter of our message by the place value of the corresponding letter in the keyword phrase, assuming that "a" has a place value of 0, "b" has a place value of 1, and so forth. Remember, we zero-index because this is Python we're talking about!

                        message:       b  a  r  r  y    i  s   t  h  e   s  p  y
                 keyword phrase:       d  o  g  d  o    g  d   o  g  d   o  g  d
          resulting place value:       4  14 15 12 16   24 11  21 25 22  22 17 5

            So we shift "b", which has an index of 1, by the index of "d", which is 3. This gives us an place value of 4, which is "e". Then continue the trend: we shift "a" by the place value of "o", 14, and get "o" again, we shift "r" by the place value of "g", 15, and get "x", shift the next "r" by 12 places and "u", and so forth. Once we complete all the shifts we end up with our coded message:
                eoxum ov hnh gvb

Here is my code:

def vigenere(coded,keyword):
    #basic definitions
    alphabet = "abcdefghijklmnopqrstuvwxyz"
    punctuation = "!? "
    #Step 1: repeat keyword
    keyword_phrase = ""
    index = 0
    for i in range(0, len(coded)):
        if coded[i] in punctuation:
            keyword_phrase += coded[i]
            keyword_phrase += keyword[index]
            index = (index + 1) % len(keyword)
    decoded = ''
    for i in range(0,len(keyword_phrase)):
        if keyword_phrase[i] in punctuation:
            location = alphabet.find(keyword_phrase[i]) - alphabet.find(coded[i])
            decoded += alphabet[location]
vigenere("dfc aruw fsti gr vjtwhr wznj? vmph otis! cbx swv jipreneo uhllj kpi rahjib eg fjdkwkedhmp!","friends")

And this is what it outputs:

fri ends frie nd sfrien dsfr? iend sfri! end sfr iendsfri endsf rie ndsfri en dsfriendsfr!

As you can see, the first line (which is the one that matters in this case), doesn’t produce a “decoded” output. I’m not sure how to fix this. Any help would be appreciated.

You first step should be to repeat through the letters in the keyword until it has the same length or longer of letters in the coded message. This can be done without a for loop. Here is a compact code that should accomplish this:

keyword_phrase = keyword * len([letter for letter in coded.lower() if letter in alphabet])

Then you just cycle through the coded message, character by character. This can be done with a for loop. In the code you posted, you’re cycling through keyword_phrase, which contains no punctuation and won’t hit every letter in your coded message besides.