Python: replace specific character in string (problem with duplicates)

Viewed 383

I have this code for a program that replaces characters in a string for superscript characters, jumping 1 character every time.

Characters that are not in my dictionary should be skipped but also affect if the next character will be replaced (so, if the "not-in-dict-character" should be replaced, it is skipped and the next character is not replaced and vice-versa)

Blank spaces should be skipped without altering the next character.

letters = { # My dictionary for all the letters and superscript versions
   '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' : 'ᶻ',
   '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' : 'ᶻ'
}

x = 0

while True:
   text = input('Insert text: ')

   while True:

   # This will ask if the user wants something like 'aᵃaᵃaᵃaᵃ' or 'ᵃaᵃaᵃaᵃa'

       fos = input('Do you want the first or the second letter to be small?(f/s): ')

       if fos != 'f':
           if fos != 's':
               print('Please insert \'f\' or \'s\' (for first and second letters).\n')
           else:
               break
       else:
           break

   if fos == 'f':
       x = 1
   elif fos == 's':
       x = 2

   for e in text:
       if x % 2 == 0: # If x value is even, it skips this character
           x = x + 1 # Makes the x value odd, so the next character isn't skipped
           continue

       elif e == ' ': # Ignoring blank spaces
           continue

       elif e not in letters: # Ignoring characters that are not in my dict
           x = x + 1
           continue

       elif e in letters:
           text = text.replace(e, letters[e], 1) # The third parameter is
           x = x + 1

   print(text)

The problem is, if the character the replace function is trying to replace has a duplicate in the string, it doesn't care which one of the characters is 'e' and just replaces the first one in the string.

So, if the user inputs 'abaaba' and 'f', the result will be 'ᵃᵇᵃaba' when it should be 'ᵃbᵃaᵇa'. Is there any way to make the replace sensitive to which character in the string is e?

4 Answers

str.replace, with or without the third parameter, is not the right choice here, as it will always start replacing at the start of the word. Instead, you could just iterate the characters one by one and replace them with their counterpart from the dictionary if all the conditions apply (is in the dict, is even/odd position, etc.).

text = "Some Text"
k = 1
res = ""
for i, c in enumerate(text):
    if c in letters and i % 2 == k:
        res += letters[c]
    else:
        res += c

I did not quite understand how you want to handle spaces and other characters that are not in letters; you might have to count the number of skipped characters and consider those, too, when checking i % 2 == k.

Without any such "skip"-condition, you might even turn this into a one-liner:

res = ''.join(letters.get(c, c) if i % 2 == k else c for i, c in enumerate(text))

I made a few tweeks on your code, and it works like this:

while True:
    text = input('Insert text: ')
    while True:
        fos = input('Do you want the first or the second letter to be small?(f/s): ')
        if fos in ['f','s']:
            break
        print('Please insert \'f\' or \'s\' (for first and second letters).\n')
    txt = ''
    if fos == 's':
        c = 'low'
    else:
        c = 'up'
    for l in text:
        if c == 'up' and l:
            txt += letters[l]
            c = 'low'
        else:
            txt += l
            c = 'up'
    print(txt)

Test:

Insert text: abaaba
Do you want the first or the second letter to be small?(f/s): f
ᵃbᵃaᵇa
Insert text: ababab
Do you want the first or the second letter to be small?(f/s): s
aᵇaᵇaᵇ
Insert text: 

it is better to use another string and append the characters to it.

letters = { # My dictionary for all the letters and superscript versions
   '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' : 'ᶻ',
   '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' : 'ᶻ'
}

x = 0

while True:
   text = input('Insert text: ')

   while True:

   # This will ask if the user wants something like 'aᵃaᵃaᵃaᵃ' or 'ᵃaᵃaᵃaᵃa'

       fos = input('Do you want the first or the second letter to be small?(f/s): ')

       if fos != 'f':
           if fos != 's':
               print('Please insert \'f\' or \'s\' (for first and second letters).\n')
           else:
               break
       else:
           break

   if fos == 'f':
       x = 1
   elif fos == 's':
       x = 2
   text2 = ''
   for e in text:
       if x % 2 == 0: # If x value is even, it skips this character
           x = x + 1 # Makes the x value odd, so the next character isn't skipped
           text2+=e
           continue

       elif e == ' ': # Ignoring blank spaces
           text2+=e
           continue

       elif e not in letters: # Ignoring characters that are not in my dict
           text2+=e
           x = x + 1
           continue

       elif e in letters:
           text2 += letters[e]
           x = x + 1

   print(text2)

just simply convert every other character in string ...

for i in string(0, len(string), 2): #number 2 is equal to i

Related