Jordhi Obdam
Jordhi Obdam

Reputation: 43

why don't the characters of my word shift one place in the alphabet?

I'm trying to make a program which takes a word or sentence, and then shifts each character one place in the alphabet. This is my minimal reproducible example:

alphabet = []
alphabet = [chr(x) for x in range(ord('a'), ord('z') +1)]

word = 'hello' 
new_word = [ ] 

for char in word:
    if char in alphabet:
        new_pos = alphabet.index(char) + 1
        if new_pos > len(alphabet):
            new_pos %= len(alphabet)
        new_word.append(alphabet[new_pos])
    else:
        continue

my question is: why doesn't this shift the characters of the word one place in the alphabet?

Upvotes: 2

Views: 144

Answers (5)

cdlane
cdlane

Reputation: 41872

The str methods maketrans and translate are perfect for this type of problem:

from string import ascii_lowercase as alphabet

# One time initialization:

translation = str.maketrans(alphabet, alphabet[1:] + alphabet[:1])

# Can be reused multiple times:

words = ('hello', 'add', 'inks ohm', 'end')

for word in words:
    new_word = word.translate(translation)

    print(word, '->', new_word)

OUTPUT

% python3 test.py
hello -> ifmmp
add -> bee
inks ohm -> jolt pin
end -> foe
% 

a program which takes a word or sentence

Your original code, nor the currently accepted code, handle a sentence as they squeeze out the spaces. The code above will handle sentences correctly, passing through things that aren't letters.

Here's a rework of your code to handle sentences correctly:

from string import ascii_lowercase as alphabet

phrase = 'inks ohm'
new_phrase = ''

for character in phrase:
    if character in alphabet:
        new_position = (alphabet.index(character) + 1) % len(alphabet)
        character = alphabet[new_position]

    new_phrase += character

print(new_phrase)

Of course, these all only handle lower case and to handle sentences properly, you need to extend them to handle upper case as well. An exercise left to the reader.

Upvotes: 1

Red
Red

Reputation: 27557

You can instead use this list comprehension:

word = 'hello'
new_word = ''.join([chr(ord(w)+1) if w.lower()!='z' else chr(ord(w)-25) for w in word])
print(new_word)

Output:

ifmmp


You can also:

new_word = ''.join([chr(ord(w)+1) if w not in ['z','Z'] else chr(ord(w)-25) for w in word])

Upvotes: 3

Rusty Widebottom
Rusty Widebottom

Reputation: 984

I got it to work by making new_word a string, and doing string concatenation (instead of array appending).

alphabet = []
alphabet = [chr(x) for x in range(ord('a'), ord('z') +1)]

word = 'hello'
new_word = ''

for char in word:
    if char in alphabet:
        new_pos = alphabet.index(char) + 1
        if new_pos >= len(alphabet):
            new_pos %= len(alphabet)
        new_word = new_word + alphabet[new_pos]
    else:
        continue

print(word, new_word)

Prints:

hello ifmmp

Upvotes: 2

Chris Johnson
Chris Johnson

Reputation: 21956

In Python, it’s often best to strive for compact solutions that use the expressive power of the language instead of extra loops and temporary data structures. Fewer lines of code = fewer places for things to go wrong.

The answer from Ann Zen is a good example of a pythonic approach. I’ll generalize that solution a little to deal with (1) possible future changes to your alphabet and (2) handling input characters not in your alphabet.

alpha_min, alpha_max = sorted(['a', 'z'])
alpha_count = ord(alpha_max) - ord(alpha_min) + 1 
phrase = 'hello there 123'
new_phrase = ''.join([chr(((ord(w)+1-alpha_min) % alpha_count) + alpha_min) for w in phrase])
print(new_phrase)

Outputs ifmmp uifsf 123.

Upvotes: 0

Anna Kallivayalil
Anna Kallivayalil

Reputation: 122

Good question Jordhi!
Letters can not be incremented by 1 but their ASCII code can be. ASCII codes are numerical representations of characters, each character on the keyboard has a unique ASCII code.

So first the character is converted into it's ASCII code by using the inbuilt python function ord() and stored into the integer variable num. Num is then incremented by 1 to get the ASCII code of the next letter. Then the ASCII code is converted back into a character using the function chr()

So the code:

word = 'hello'
new_word = ''

for char in word:
    if char.isalpha():
       num=ord(char)
       num=num+1
       x=chr(num)
       new_word+=x
print(word, new_word)


Will give you the output you're looking for:
hello ifmmp

Upvotes: 0

Related Questions