1

The problem is a known one: Given a sentence, return the sentence with all its letters transposed by 1 in the alphabet, but only if the letter is a-y.

I understand similar questions have been asked here bunch of times, but the solution I applied in my case actually came from one of these stackoverflow answers and the function still keeps jumping 2-3 letters ahead:

from string import ascii_letters

def inverter(sentence):
    for x in sentence:
        if x in ascii_letters and x!= 'z' and x != ' ':
            sentence = sentence.replace(x,ascii_letters[ascii_letters.index(x)+1])
        else:
            sentence = sentence
    return sentence

sent3 = 'a quick brown fox jumps over the lazy dog'

inverter(sent3)

Output:

'c uwkem cuqzq hqz kwnqu qwfu uif mczz eqh'

What could be going wrong in the loop of mutation?

Anish
  • 31
  • 4
  • 3
    You find an a and replace **all of them** by b. Later in the sentence you find b and replace **all of them** by c. – Michael Butscher Nov 28 '20 at 22:35
  • Thank you @Michael. Makes sense. What could be the solution for this? Relatively new to coding. – Anish Nov 28 '20 at 22:37
  • 1
    Build a new string character by character (there is a more efficient way but this is easier). You look already at each character of the input sequence. Just calculate the replacement character (may be same character sometimes) and append it to the new result string. – Michael Butscher Nov 28 '20 at 22:40

1 Answers1

2

Use ord to convert each of the certain characters into its number form, add 1, and use chr to convert the integer back to a character:

from string import ascii_letters

def inverter(sentence):
    a_to_y = ascii_letters[:25]
    s = ''
    for i in sentence:
        if i in a_to_y:
            i = chr(ord(i) + 1)
        s += i
    return s

sent3 = 'a quick brown fox jumps over the lazy dog'

print(inverter(sent3))

Output:

b rvjdl cspxo gpy kvnqt pwfs uif mbzz eph

Here's a one-liner:

def inverter(sentence):
    return ''.join([chr(ord(i) + 1) if i in 'abcdefghijklmnopqrstuvwxy' else i for i in sentence])

sent3 = 'a quick brown fox jumps over the lazy dog'

print(inverter(sent3))

Here is why your for loop didn't work:

The str.replace method replaces all occurrences of the specified string with the other specified string, not just one.

Let's say your sentence is "apple anna".

With for x in sentence:, the first letter will be "a".

Since "a" meets the condition if x in ascii_letters and x!= 'z' and x != ' ':, the "a" will be replaced with "b", but not just that "a", also all the other "a"s in that string

By the time the iteration reaches the next "a", the "a" will already be a "b", so the former "a" will be replaced with a "c", and then the next former will be "c" to "d"!

The same applies for your string, with most of the letters in it.

Red
  • 26,798
  • 7
  • 36
  • 58
  • this is helpful! Is there any way I can research such for loop traps, like the one I fell into? Thank you!! – Anish Nov 29 '20 at 02:15
  • 1
    @Anish I've added the explanation. – Red Nov 29 '20 at 03:58
  • Oh perfect! Thank you so much! I was assuming it's the for loop that replaces all instances, as opposed to the string.replace() – Anish Nov 29 '20 at 20:23