0

So I'm trying to make an encoding/decoding program, that lets the user to type a sentence and turn it into an encoding message by replacing letters with other letters.

It works fine with one words, but when I put more words with spaces and special characters it seems to be not working.

So here is my code:

 phrase = input("Write a sentence:")
decalage = int(input("By how many letters (1 to replace a with b...): "))

maping = {}
for i in range(26):
    i_cesar = (i + decalage) % 26
    c_cesar = chr(i_cesar + ord('a'))
    c = chr(i + ord('a'))
    maping[c] = c_cesar

result = ""
for c in phrase:
   result = result + maping[c]
print(result)
JNevill
  • 46,980
  • 4
  • 38
  • 63
Mehdi
  • 13
  • 3
  • Define "seems to be not working". See [Ask] and the [question checklist](//meta.stackoverflow.com/q/260648/843953). – Pranav Hosangadi Mar 24 '22 at 15:19
  • It would be very useful to see the output of your program in both cases you are describing. – Atalajaka Mar 24 '22 at 15:20
  • You are trying to find what a space (or special character) will map to, but there is no entry for those character in your `maping` dictionary because you _never put it there_. Notice how you only loop over `0` through `25` and use that to create a mapping for each _lowercase letter!_ What would happen if I entered an uppercase letter in `phrase`? Is there even a need to pre-calculate this mapping? Can you not simply do it on the fly for each `c in phrase`? Read [this](//ericlippert.com/2014/03/05/how-to-debug-small-programs/) and [this](/q/25385173) – Pranav Hosangadi Mar 24 '22 at 15:22

2 Answers2

0

If I understand your requirements correctly, I think this whole thing can be simplified to just add to the numeric representation of the character, but only in the case if the character is a letter.

Something like the following would be a little easier:

phrase = input("Write a sentence:")
decalage = int(input("By how many letters (1 to replace a with b...): "))

result = ""
for c in list(phrase): 
    if ord(c) >= 65 and ord(c) <= 122:
        result = result + chr(ord(c)+decalage) 
    else: 
        result + c

print(result)
JNevill
  • 46,980
  • 4
  • 38
  • 63
0

You're only building a mapping for the lowercase letters. One thing you can do is make a string of all the characters you intend to change, then rotate a copy of that string to form your dictionary.

from string import ascii_lowercase, digits, punctuation

characters = ascii_lowercase + digits + punctuation

def rotate(s: str, degree: int) -> str:
    return s[degree:] + s[:degree]

def cesar_encode(plaintext: str, cipher: int) -> str:
    mapping = dict(zip(characters, rotate(characters, cipher)))
    return "".join([mapping.get(c, c) for c in plaintext])

cesar_encode("abcde12345$%^&", 1)
# "bcdef23456%&_'"
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96