1

I'm trying to create a simple Caesar Cipher function in Python that shifts letters based on input from the user and creates a final, new string at the end. Problem is that the final cipher text shows only the last shifted character, not an entire string with all the shifted characters and when the letter z for example the program doesn't restart at the beginning of the alphabet PS i am french educated so some lines might be in french Here's my code:

list=list()
r=0
choix=int(input("Veuillez entrer 1 pour coder ou 2 pour decoder"))
if choix==1 :
    cle=int(input("Quelle est votre clé?"))
    phrase=input("Quelle est votre phrase? ")
    for i in phrase :
        r=ord(i)
        r=(r+cle)%26
        lettre=chr(r)
        list.append(lettre)
    print(list)
elif choix==2 :
    cle=int(input("Quelle est votre clé?"))
    phrase=input("Quelle est votre phrase? ")
    for i in phrase :
       r=ord(i)
       r=(r-cle)%26
       lettre=chr(r)
       list.append(lettre)
    print(list)
shifoc
  • 13
  • 4
  • Tu ne devrais pas utiliser `list` comme nom de variable. En effet, il s'agit d'un nom déjà utilisé comme nom de fonction et de type de données. – D. LaRocque Jan 29 '18 at 21:58
  • You are `print(lettre)` instead of `list` for encoding. You're overriding the builtin `list` with your own list. `list=list.append(lettre)` sets `list` to `None`. It should just be `list.append(lettre)`. See the dupe target. – TemporalWolf Jan 29 '18 at 22:11
  • Your code is riddled with issues. You need to break down the problem and ensure you can do one part at a time. – TemporalWolf Jan 29 '18 at 22:17
  • 1
    Although your code is partly written in French the comments should be in English. If you want to communicate in french find a site where that is aloud. choice 1: you're not appending the output to the 'lettre' thus you get only the last one in the list_lettre. – ZF007 Jan 29 '18 at 22:17

3 Answers3

1

Ok bear with me here, I only have the first part (the encoding), but I think it is enough for you to be able to do the rest:

code=list()
choix=int(input("Veuillez entrer 1 pour coder ou 2 pour decoder"))
if choix==1 :
    cle=int(input("Quelle est votre clé?"))
    phrase=input("Quelle est votre phrase? ")
    for el in phrase:
        if el.islower():
            r = ((ord(el) - ord('a')) + cle) % 26 + ord('a')
            code.append(chr(r))
        elif el.isupper():
            r = ((ord(el) - ord('A')) + cle) % 26 + ord('A')
            code.append(chr(r))
        else:
            code.append(el)

    print(code)

The tricky part here is this: ((ord(el) - ord('a')) + cle) % 26 + ord('a'), since you want to loop through the smaller case letters, you have to constrain your computation between ord('a') which is 97 and ord('z') which is 122. As @Malvolio suggested using the modulus, does the "restarting".

domochevski
  • 553
  • 5
  • 13
1

Here is a shift cipher function that might get you started.

def shift_cipher(phrase, shift):
    '''Ceaser Ciphers/Unciphers a string'''
    alphabet = list(string.ascii_lowercase)

    phrase = str(phrase)
    phrase = phrase.lower()
    new_phrase = ''
    for letter in phrase:
        shift_letter_index = alphabet.index(letter) + shift
        new_phrase += alphabet[shift_letter_index % 26]

    return new_phrase
Ethan Henderson
  • 428
  • 4
  • 11
  • Why not use the `ascii_lowercase` attribute from the `string` module to populate your alphabet rather than writing it by hand? Something like, `alphabet = list(string.ascii_lowercase)`? – domochevski Jan 30 '18 at 12:15
  • Because I was copying from an old file and didn't think. That is a good suggestion. – Ethan Henderson Jan 30 '18 at 21:35
0

Some points:

  • You didn't actually ask your question. What's the problem?
  • You make the liste_lettre but you never do anything with it.
  • The way to "restart" (usually called "wrap" in English) is to use the modulus. The modulus symbol in Python (and most programming languages) is %.
Michael Lorton
  • 43,060
  • 26
  • 103
  • 144