BubbleMonster
BubbleMonster

Reputation: 1416

Python - why does this for loop only print 1 letter?

def caesar(plaintext,shift):  
    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"]  

    #Create our substitution dictionary  
    dic={}  
    for i in range(0,len(alphabet)):  
        dic[alphabet[i]]=alphabet[(i+shift)%len(alphabet)]  

    #Convert each letter of plaintext to the corrsponding  
    #encrypted letter in our dictionary creating the cryptext  
    ciphertext=("")  
    for l in plaintext.lower():  
            if l in dic:  
                l=dic[l]  
                ciphertext+=l
            return ciphertext  

#Example useage  
plaintext="the cat sat on the mat"  
print "Plaintext:", plaintext  
print "Cipertext:", (caesar(plaintext,29)) 

The cipertext prints just one letter, instead of printing the 'plaintext' variable in caesar shift. I want it to print the whole sentence.

Thanks

Upvotes: 1

Views: 298

Answers (3)

Joran Beasley
Joran Beasley

Reputation: 114098

do it better with string.translate :)

import string
def caesar(plaintext,shift):  
    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"]
    alphabet_shifted = alphabet[shift:]+alphabet[:shift]
    tab =    string.maketrans("".join(alphabet),"".join(alphabet_shifted))
    return plaintext.translate(tab)

Upvotes: 3

Sukrit Kalra
Sukrit Kalra

Reputation: 34531

This is because your return ciphertext is indented wrong. You return from the first iteration of the for loop. (Indentation matters a lot in Python!)

    for l in plaintext.lower():  
            if l in dic:  
                l=dic[l]  
                ciphertext+=l
            return ciphertext  # Indented to match level of `if`.

Fix it to.

    for l in plaintext.lower():  
        if l in dic:  
            l=dic[l]  
            ciphertext+=l
    return ciphertext

Couple of Pointers

  1. Instead of listing out all alphabets in your code, you can just set alphabets = string.ascii_lowercase.
  2. You don't need a variable to store dic[l], just do ciphertext += dic[l].

Upvotes: 8

jh314
jh314

Reputation: 27812

You need to fix the indents for the return statement:

for l in plaintext.lower():  
    if l in dic:  
       l=dic[l]  
       ciphertext+=l
    # <-- if you return here, then you will loop only once.      
return ciphertext  

Upvotes: 2

Related Questions