Coded Correspondence code review

Hello!
Just finished the most difficult off-platform project in Data Scientist career path. It took a lot of time and effort, but the emotional reward is outstanding.
I would love to get your feedback and constructive critics :slight_smile:

alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
def decypher_caesar(message, offset):
    dec_message = []
    for i in range(len(message)):
        if message[i] not in alphabet:
                dec_message.append(message[i])
        else:
            for j in range(len(alphabet)):
                if alphabet[j] == message[i]:
                    if (offset + j) < len(alphabet):
                        dec_message.append(alphabet[j+offset])
                    elif (offset + j) >= len(alphabet):
                        dec_message.append(alphabet[j+offset-len(alphabet)])
    return ''.join(dec_message)
message_1 = "xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!"
print(decypher_caesar(message_1, 10))

def cypher_message(message, offset):
    c_message = []
    for i in range(len(message)):
        if message[i] not in alphabet:
                c_message.append(message[i])
        else:
            for j in range(len(alphabet)):
                if alphabet[j] == message[i]:
                    if (offset - j) < len(alphabet):
                        c_message.append(alphabet[j-offset])
                    elif (offset - j) >= len(alphabet):
                        c_message.append(alphabet[j-offset+len(alphabet)])
    return ''.join(c_message)
my_message = "hey there! this is an example of a caesar cipher. were you able to decode it? i hope so! send me a message back with the same offset!"
print(cypher_message(my_message, 10))

message_2 = "jxu evviuj veh jxu iusedt cuiiqwu yi vekhjuud."
print(decypher_caesar(message_2, 10))
message_3 = "bqdradyuzs ygxfubxq omqemd oubtqde fa oapq kagd yqeemsqe ue qhqz yadq eqogdq!"
print(decypher_caesar(message_3, 14))
message_4 = "vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl tl hulhexmx. px'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx."
print(decypher_caesar(message_4, 7))

test = "dfc aruw fsti gr vjtwhr wznj? vmph otis! cbx swv jipreneo uhllj kpi rahjib eg fjdkwkedhmp!"
def decrypt_vigеnere(message, keyword):
    result = []
    #Step 1: Filling keyword list
    keyword_string = []
    kw_counter = 0
    for i in range(len(message)):
        if message[i] not in alphabet:
            keyword_string.append(message[i])
            kw_counter += 1
        else:
            keyword_string.append(keyword[(i-kw_counter) - ((i-kw_counter)//len(keyword)*len(keyword))])
    #Step 2: Filling result list
    for i in range(len(message)):
        if message[i] not in alphabet:
                result.append(message[i])
        else:
            for j in range(len(alphabet)):
                #finding keyword_string element's index in alphabet
                for k in range(len(alphabet)):
                    if alphabet[k] == keyword_string[i]:
                        offset = k
                if alphabet[j] == message[i]:
                    if (offset - j) < len(alphabet):
                        result.append(alphabet[j-offset])
                    elif (offset - j) >= len(alphabet):
                        result.append(alphabet[j-offset+len(alphabet)])
    #Step 3: Joining result list into string
    return ''.join(result)
        
print(decrypt_vigеnere(test, "friends"))

test_vigenere_crypt = "hello, friend, i've spent a bunch of time and nerves to solve this puzzle, but, thanks to you, i've reached my goal and improved my python skills!"
def crypt_vigеnere(message, keyword):
    result = []
    #Step 1: Filling keyword list
    keyword_string = []
    kw_counter = 0
    for i in range(len(message)):
        if message[i] not in alphabet:
            keyword_string.append(message[i])
            kw_counter += 1
        else:
            keyword_string.append(keyword[(i-kw_counter) - ((i-kw_counter)//len(keyword)*len(keyword))])
    #Step 2: Filling result list
    for i in range(len(message)):
        if message[i] not in alphabet:
                result.append(message[i])
        else:
            for j in range(len(alphabet)):
                #finding keyword_string element's index in alphabet
                for k in range(len(alphabet)):
                    if alphabet[k] == keyword_string[i]:
                        offset = k
                if alphabet[j] == message[i]:
                    if (offset + j) < len(alphabet):
                        result.append(alphabet[j+offset])
                    elif (offset + j) >= len(alphabet):
                        result.append(alphabet[j+offset-len(alphabet)])
    #Step 3: Joining result list into string
    return ''.join(result)
        
crypted = crypt_vigеnere(test_vigenere_crypt, "friends")
print(crypted)
print(decrypt_vigеnere(crypted, "friends"))
2 Likes

Hi @happygoose

I just finished the project myself and looking through different solutions on forums. Thus I’m not qualified to review your code, I’d like to show you mine,

import string
alphabet = list(string.ascii_lowercase)
# I looked this on the web to avoid typing all the letters manually
encoded_message = "xubbe co vyudt! fhekt je tusyfxuh oekh cuiiqwu myjx co vyhij iubv-mhyjjud fojxed fhewhqc"
decoded_message = []
for symbol in encoded_message:
    if symbol in alphabet:
        decoded_message.append(alphabet[(alphabet.index(symbol)+10) % len(alphabet)])   
    else:
      decoded_message.append(symbol)
print("".join(decoded_message))

I’m skipping the encoding part since it’s almost the same
Same with the function:

def decoder(message, offset):
 decrypted_message = []
 for symbol in message:
   if symbol in alphabet:
       decrypted_message.append(alphabet[(alphabet.index(symbol) + offset) % len(alphabet)])
   else:
     decrypted_message.append(symbol)
 return "".join(decrypted_message)

Vigenère was a really hard one, I’ve spend almost a day on this part to make it work. Couple of times I was tempted to look into solutions but proud that did not :wink:

def vigenere_decode(message, key):
  decrypted_message = []
  counter = 0
  for symbol in message:
    if symbol in alphabet:
      x = alphabet.index(key[(counter+len(key))%len(key)])
      y = alphabet.index(symbol) - x
      decrypted_message.append(alphabet[y % len(alphabet)])
            counter += 1
    else: 
      decrypted_message.append(symbol)
       return "".join(decrypted_message)
1 Like

I just spent legit like 2 hours on the first question literally going insane because I assumed it had to be -10 … Woozy Face on Facebook 14.0 I can’t belive that even just happened lol This is legit the only time in my entire life I have actually been so stuck on something I needed to go find the answer :face_with_spiral_eyes: :dizzy_face:

1 Like

lol youre not the only… i think i had rewritten my code like 4 or 5 different ways when i realized what i was doing lol

but heres my vigenere coder for review if anyone would like to comment

def coder_two(message, key): # holds the message in key form (message ---> keykeyk) key_message = '' index = 0 coded_message = '' # Alphabet reapeated because i didnt know about % alpha = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' for char in message: #adds all non letters to key_message if char not in alpha: key_message += char else: #adds key[index] to key_message and resets index at end of str if index == len(key): index = 0 key_message += key[index] index += 1 for i in range(len(key_message)): #adds all non letters to coded_message if key_message[i] not in alpha : coded_message += key_message[i] #adds index of message[i] with key_message[i] else: coded_message += alpha[alpha.index(message[i]) + alpha.index(key_message[i])] return coded_message
2 Likes

i tried so hard to get my vigenere decode/coder with 1 for loop but gave up, too much ()()()( for my small brain
nice job on yours though still cant read it tho :frowning:

Did that code work properly? Would you mind showing me the output? (Cant see it without the input message) By the way from my experience it seems people mostly use the “preformatted text” option rather than codebites. I don’t think ive actually seen anyone use codebites besides me my first post lol. Im going to go get my code now and ill post it but im not going to explain it because I think itl give you a lot of value going through. After you do if you need an explanation tho would be happy to. 1 min… (Its in a jupyter notebook)

alphabet = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
vishal_encrypted_message4 = 'dfc aruw fsti gr vjtwhr wznj? vmph otis! cbx swv jipreneo uhllj kpi rahjib eg fjdkwkedhmp!'
key = 'friends'

def vigenere_positive(message, keyword):
    decrypted_message = ''
    count = 0
    for letter in message:
        if letter not in alphabet:
            decrypted_message += letter
        elif letter in alphabet:
            a = alphabet.index(key[(count + len(key)) % len(key)])
            b = alphabet.index(letter) + a
            decrypted_message += alphabet[b % len(alphabet)]
            count += 1
    return decrypted_message
                
def vigenere_negative(message, keyword):
    decrypted_message = ''
    count = 0
    for letter in message:
        if letter not in alphabet:
            decrypted_message += letter
        elif letter in alphabet:
                a = alphabet.index(key[(count + len(key)) % len(key)])
                b = alphabet.index(letter) - a
                decrypted_message += alphabet[b % len(alphabet)]
                count += 1
    return decrypted_message

print(vigenere_positive(vishal_encrypted_message4, key))
print(vigenere_negative(vishal_encrypted_message4, key))

So there is two functions because I wasn’t sure if it was going to be negative and positive, and the alternate function can be used as a decrypter as well. See if you can dissect it yourself first if you want and then when your done and understand it (can play with it, just think it through, compare it to yours, wtv you want). Than when you’re done msg me if you want and I can explain it if need be and also we can review each others code if you’d like. Since it seems like we are going the same path I would be up to keeping contact and reviewing each others code and working together possibly if you are up for it. (I am at this literally 12 hours+ a day so in just a short bit of time I will probably be able to explain a lot and going over it myself would be a lot of help for me too :p, teaching is the best way to learn 100%)

Okay so hope that’s helpful. Can msg me here on codeacademy (u can direct message on my profile) or catch me on discord at Carpen-Them-Diemz#3114 , if you haven’t joined to codeacademy discod yet you should, if need be I can send u an invite but you can also access it on here somewhere. Good work on the code btw, I actually tried using that method first but couldn’t get it working in one function either so I ended up scraping it all (and an hour of my life :cry: lol).

Yes it works perfect, I’m wondering why everyone else is putting their strings into lists tho,

I’ll add the output when I get home on mobile at the moment

def coder_two(message, key):
    # holds the message in key form (message ---> keykeyk)
    key_message = ''
    index = 0
    coded_message = ''
    # Alphabet reapeated because i didnt know about %
    alpha = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'
    
    for char in message:
        #adds all non letters to key_message
        if char not in alpha: key_message += char
        else:
            #adds key[index] to key_message and resets index at end of str
            if index == len(key): index = 0
            key_message += key[index]
            index += 1
        
    for i in range(len(key_message)):
        #adds all non letters to coded_message
        if key_message[i] not in alpha : coded_message += key_message[i]
        #adds index of message[i] with key_message[i] 
        else: coded_message += alpha[alpha.index(message[i]) + alpha.index(key_message[i])]
    
    return coded_message



coder_two('testing testing testing testing', 'buzzkill')

#outputs: uyrssvr efmshxo eptnhmq bpducmf

figuring out how to get the code to show up here may have been harder than any lesson

Oh, I didn’t even think about defining the alphabet. I was still thinking about how to use ascii at this point; mostly because it was used in the previous exercises in the AI/ML skill path.

if you’re on same track as me wait till you get to the hurricanes one lol I did it without any help took me 3 days x.x.
Strings into lists? Oh for the list comprehensions? I think it was because that’s what this project is supposed to be training (least on my path a.i/ml engineering foundations ). I’m not positive though cuz I’m like 4 projects ahead of that by now.
When I get to my next one ill throw you code into a cell on jupyter notebook and see what’s up. Can review each others code then if you want too. Or even better the hurricane project if you finish that by later tonight when i have the time.

Yeah well the cool thing with projects like this is there’s no specific way to do it, so you’ll get to compare your code to a lot of different ones and refine your methods. Btw sadrho if your on discord I started a server for A.I/ML, data science and so on. Can send me a message @ carpen-them-diemz#3114 @playabeavs you too, makes it a little easier to collaborate with people specifically in your path and I added a playlist of A.I/ML. Data science and python, etc vids I have saved up and used (A lot are for future use though def above our pay grades, many beginner lvl and intermediate tho) It also has midjourney AI image generator connected to it and a gpt-3 chabot (not chatGPT) you can place with. I made a channel just for down that, Anyways yeah lol I gotta get to workin

I’m having trouble messaging you. maybe you could message me instead? My username is: Gollsodia#0794

yeah wow im new to platform didn’t realize you cant just search people up ■■■■ lol wonder how much time I wasted doing this xD Singularity Surfers (AI/ML/DL-DataScience) you can join the server with this invite url then find me there.

Hi, i just finished the challenge and it surprised me on how challenging it was. But very well thought, im open to criticism, please.

Caeser Cipher

Ps: created some functions to help the process and break down more easily.

def position(letter, alphabet): pos = 0 for i in range(len(alphabet)): if letter == alphabet[i]: pos =i return pos return letter def position_list(message, alphabet, offset): p_list = [] for i in message: if isinstance(position(i,alphabet), str) == True: p_list.append(i) else: if offset >= 0: if position(i,alphabet)+offset >= 26: p_list.append((position(i,alphabet)+offset)-26) else: p_list.append(position(i,alphabet)+offset) else: if position(i,alphabet)+offset <0: p_list.append((position(i,alphabet)+offset)+26) else: p_list.append(position(i,alphabet)+offset) return p_list def decoded_msg(message, alphabet, offset): p_list = position_list(message, alphabet, offset) msg = "" for i in p_list: if isinstance(i, int) == True : msg = msg + alphabet[i] else: msg = msg + i continue return msg def encode_msg(message, alphabet, offset): p_list = position_list(message, alphabet, offset) msg = "" for i in p_list: if isinstance(i, int) == True : msg = msg + alphabet[i] else: msg = msg + i continue return msg alpha = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] message = "xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!" d_msg = decoded_msg(message, alpha,10) print(d_msg) encoded_msg = encode_msg(d_msg,alpha,-10) print(encoded_msg)

And if you want to force some search looping the offset, here we are:

my_message = "vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl hulhexmx. px'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx."


result = []

for i in range(20):
    
    result.append(decoded_msg(my_message,alpha, i))

Vigenere Cipher

alpha = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] new_message = "txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztylktoikqq!" keyword = 'friends' def position(letter, alphabet): pos = 0 for i in range(len(alphabet)): if letter == alphabet[i]: pos =i return pos return letter def position_list(message, alphabet, offset): p_list = [] for i in message: if isinstance(position(i,alphabet), str) == True: p_list.append(i) else: if offset >= 0: if position(i,alphabet)+offset >= 26: p_list.append((position(i,alphabet)+offset)-26) else: p_list.append(position(i,alphabet)+offset) else: if position(i,alphabet)+offset <0: p_list.append((position(i,alphabet)+offset)+26) else: p_list.append(position(i,alphabet)+offset) return p_list def decode_vigenere(message,keyword, alphabet): lst = position_list(message,alphabet, 0) position_list_keyword = [] aux = 0 for i in lst: if isinstance(i, int) == True : key = aux%len(keyword) aux+=1 ind = i + position(keyword[key], alphabet) if ind >=26: position_list_keyword.append(i + position(keyword[key], alphabet) -26) else: position_list_keyword.append(i + position(keyword[key], alphabet)) else: position_list_keyword.append(i) msg = "" for i in position_list_keyword: if isinstance(i, int) == True : msg = msg + alphabet[i] else: msg = msg + i continue return msg def encode_vigenere(message,keyword, alphabet): lst = position_list(message,alphabet, 0) position_list_keyword = [] aux = 0 for i in lst: if isinstance(i, int) == True : key = aux%len(keyword) aux+=1 ind = i - position(keyword[key], alphabet) if ind <0: position_list_keyword.append(i - position(keyword[key], alphabet) + 26) else: position_list_keyword.append(i - position(keyword[key], alphabet)) else: position_list_keyword.append(i) msg = "" for i in position_list_keyword: if isinstance(i, int) == True : msg = msg + alphabet[i] else: msg = msg + i continue return msg msg=decode_vigenere(new_message, keyword, alpha) print(msg) encoded = encode_vigenere(msg,keyword,alpha) print(encoded)

Tks!

Glad to see I wasn’t the only one to struggle with the Vigenère decoder function… I’m pretty sure this isn’t the nicest solution (my initial approach would stop parsing at the first whitespace haha, so I had to fiddle around with the code until I finally though to use a counter to keep track of where I was in the decoder key string)


#Defining the Vigenère decoder function

def V_decoder(message,keyword):
    key_string=''
    decoded_string_V=''
    index=0
    for character in message:
        key_string+=character
        for i in range(0,len(alphabet)):
            if character==alphabet[i] or character==alphabet[i].upper():
                key_string=key_string[:-1]
                key_string+=keyword[0]
                keyword+=keyword[0]
                keyword=keyword[1:]
                break
    for character in message:
        decoded_string_V+=character
        for i in range(0,len(alphabet)):
            if character==alphabet[i]:
                decoded_string_V=decoded_string_V[:-1]
                decoded_string_V+=caesar_decode(character,alphabet.find(key_string[index]))
                break
            elif character==alphabet[i].upper():
                decoded_string_V=decoded_string_V[:-1]
                decoded_string_V+=caesar_decode(character,alphabet.find(key_string[index])).upper()
                break
        index+=1
    return decoded_string_V

#Decoder in action!
keyword='friends'
message='Txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!'
print(V_decoder(message,keyword))

Hello, everyone! I’m glad that my message started a discussion :slight_smile:
I reworked this project from the beginning and happy to share my new approach with you:

This one works both ways with Caesar, depending on offset being positive/negative

#Defining alphabet as list
alphabet_str = 'abcdefghijklmnopqrstuvwxyz'
alphabet = []
for letter in alphabet_str:
    alphabet.append(letter)

#Decrypting function
def decrypting_caesar(message, offset):
    #resulting message
    message = message.lower()
    decrypted_message = ''
    for i in range(len(message)):
        #check for non-letters
        if not message[i] in alphabet:
            decrypted_message += message[i]
        #convert letters back to normal 
        else:
            alphabet_place = alphabet.index(message[i]) + offset
            #we subtract the lenght of an alphabet if letter index in higher than that
            if alphabet_place >= len(alphabet):
                alphabet_place -= len(alphabet)
            decrypted_message += alphabet[alphabet_place]
    return decrypted_message
print(decrypting_caesar("o", 3))
decrypted_caesar = decrypting_caesar("xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!", 10)
print(decrypted_caesar)

This one is for Vigenere:

def vigenere_cypher(message, keyword):
    #resulting message
    message = message.lower()
    result_message = ''
    counter = 0
    for i in range(len(message)):
        #check for non-letters
        if not message[i] in alphabet:
            result_message += message[i]
        #convert letters back to normal 
        else:
            #we check if counter is in keyword length and subtract it from counter if not
            if counter >= len(keyword):
                counter -= len(keyword)
            alphabet_place = alphabet.index(message[i]) - alphabet.index(keyword[counter])
            #we subtract the length of an alphabet if letter index in higher than that
            if alphabet_place >= len(alphabet):
                alphabet_place -= len(alphabet)
            result_message += alphabet[alphabet_place]
            counter += 1
    return result_message
vigenere_cypher_1 = vigenere_cypher("barry is the spy", "dog")
print(vigenere_cypher_1)

def vigenere_decypher(message, keyword):
    #resulting message
    message = message.lower()
    result_message = ''
    counter = 0
    for i in range(len(message)):
        #check for non-letters
        if not message[i] in alphabet:
            result_message += message[i]
        #convert letters back to normal 
        else:
            #we check if counter is in keyword length and subtract it from counter if not
            if counter >= len(keyword):
                counter -= len(keyword)
            alphabet_place = alphabet.index(message[i]) + alphabet.index(keyword[counter])
            #we subtract the length of an alphabet if letter index in higher than that
            if alphabet_place >= len(alphabet):
                alphabet_place -= len(alphabet)
            result_message += alphabet[alphabet_place]
            counter += 1
    return result_message
vigenere_decypher_1 = vigenere_decypher("txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!", "friends")
print(vigenere_decypher_1)

Hope that helps! Have a nice day)

3 Likes

Hi there!

I have somehow hit a wall and can’t seem to work out the issue. I think I’m close but there’s some sort of faulty logic in my code

def vigenere_decode(message, keyword): alphabet_letter_key = {"a":0,"b":1, "c":2, "d":3,"e":4,"f":5,"g":6,"h":7,"i":8,"j":9,"k":10,"l":11,"m":12,"n":13, "o":14, "p":15,"q":16,"r":17, "s":18,"t":19,"u":20,"v":21,"w":22,"x":23,"y":24,"z":25} alphabet_num_key = {v: k for k, v in alphabet_letter_key.items()} # print(alphabet_num_key) message_decoded = "" keyword_len = len(keyword) for i,character in enumerate(message): if character in alphabet_letter_key: alphabet_space = alphabet_letter_key[character] offset = alphabet_letter_key[keyword[i % keyword_len]] alphabet_space_cipher = (alphabet_space + offset ) % 26 message_decoded += alphabet_num_key[alphabet_space_cipher] else: message_decoded += character return message_decoded message= "txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!" print(vigenere_decode(message, "friends"))

The output for this code is:
you fugr doqd lc pmoyei ucgt? nice jaig! mgi mzq yrxphgod ulser the umcqip zy qhxpjujofgu!

Hey, Bit!
Tbh, you follow completely different approach and it’s hard to understand it (just different, not better or worse).
I noticed that 1-st word is decoded right, that’s why I think that problem is with correctly skipping whitespaces while picking a letter from keyword (offset).
Try to fix it and I hope that works.
Good luck!

1 Like

Hey happygoose,

This work perfectly! As soon as you said it, I could see what I had done. Iterating through the keyword for whitespace when I shouldn’t have was the issue.

Thank you!!

1 Like

This is the only solution I found that has comments that I can clearly understand! You’ve literally saved my brain from exploding! :exploding_head:

1 Like