2

I'm new to python and I'm trying to create a code for a course where I have to replace the second occurrence of each letter with something else such as:

print(vowel_swapper("aAa eEe iIi oOo uUu")) Should print "a/\a e3e i!i o000o u/u" to the console

The code works for this string but when I do the second:

print(vowel_swapper("Hello World")) Should print "Hello Wooorld" to the console

it outputs "Hell000 W000rld". I'm sure that the way I'm doing it won't be very efficient, since I'm new to it I'm not expecting it to be efficient I'm just trying to learn how to make it do what I want it to do.

def vowel_swapper(string):

    replace1 = ["a", "A"]
    replace2 = ["e", "E"]
    replace3 = ["i", "I"]
    replace4 = ["o", "O"]
    replace5 = ["u", "U"]
    new_string = string

    count = 0
    for i in range(0, len(string)):
        if (string[i] == replace1[0]) or (string[i] == replace1[1]):
            count = count + 1
            if count == 2:
                new_string = new_string.replace(string[i], '/\\')

    count = 0
    for i in range(0, len(string)):
        if (string[i] == replace2[0]) or (string[i] == replace2[1]):
            count = count + 1
            if count == 2:
                new_string = new_string.replace(string[i], "3")

    count = 0
    for i in range(0, len(string)):
        if (string[i] == replace3[0]) or (string[i] == replace3[1]):
            count = count + 1
            if count == 2:
                new_string = new_string.replace(string[i], "!")

    count = 0
    for i in range(0, len(string)):
        if (string[i] == replace4[0]) or (string[i] == replace4[1]):
            count = count + 1
            if count == 2:
                new_string = new_string.replace(string[i], "000")

    count = 0
    for i in range(0, len(string)):
        if (string[i] == replace5[0]) or (string[i] == replace5[1]):
            count = count + 1
            if count == 2:
                new_string = new_string.replace(string[i], "\\/")

    return new_string
sinback
  • 926
  • 5
  • 17
  • replace: new_string = new_string.replace(string[i], "000") with new_string = new_string[:i] + "000" + new_string[i+1:] see https://stackoverflow.com/questions/1228299/changing-one-character-in-a-string – pippo1980 Apr 11 '21 at 17:12
  • Does this answer your question? [Changing one character in a string](https://stackoverflow.com/questions/1228299/changing-one-character-in-a-string) – pippo1980 Apr 11 '21 at 17:13
  • print('/\\') is trickier cant get it right – pippo1980 Apr 11 '21 at 17:48
  • Correction new_string_1= new_string[:i] + "000" + new_string[i+1:] and return new_string_1 – pippo1980 Apr 15 '21 at 18:36

2 Answers2

0

You should enumerate the string to easily get the index of the second occurrence of the vowel you are looking for, then you can replace it using the join function to join the substring before the replaced character and the substring after it.

The following code has two key advantages:

  1. By accepting as a parameter a dictionary (swaps) with all the char : replacement pairs you can replace all the characters you want, not just the vowels.
  2. Since it is index based, you can easily change the occurrence index (idx) and replace the third, the forth occurrence ... and so on... I set its default value to 1 to directly replace the 2nd occurrence if you do not provide a value.

Code:

def chars_swapper(s, swaps, idx=1):
    
    for k, v in swaps.items():
        l = [i for i, char in enumerate(s) if char.upper() == k]
        if len(l) > idx:  s = v.join((s[:l[idx]], s[l[idx]+1:]))
            
    return s

Output:

SWAPS = {'A':'/\\', 'E':'3', 'I':'!', 'O':'000', 'U': '/'}

chars_swapper("aAa eEe iIi oOo uUu", SWAPS)
'a/\\a e3e i!i o000o u/u'

chars_swapper("Hello World", SWAPS)
'Hello W000rld'

One Backslash:

In Python strings, the backslash "\" is a special character, also called the "escape" character. It is used in representing certain whitespace characters: "\\" is a backslash, "\t" is a tab, "\n" is a newline, and "\r" is a carriage return. Conversely, prefixing a special character with "\" turns it into an ordinary character.

print(chars_swapper("aAa eEe iIi oOo uUu", SWAPS))
a/\a e3e i!i o000o u/u

You can read more about it here (2.4.1. String and Bytes literals): Python docs

nico9T
  • 2,496
  • 2
  • 26
  • 44
  • expected result is : a/\a e3e i!i o000o u/u – pippo1980 Apr 16 '21 at 15:53
  • Sure. If you print what the function returns you get what you are expecting. ‘\’ has to be escaped, must be preceded by another ‘\’ but Python sees it as a single character. Because of this what the function returns is perfect. I edited my answer to provide you more info about this. – nico9T Apr 17 '21 at 06:50
0

Here's my solution:

>>> SWAPS = {
        "A": "/\\", "E": "3", "I": "!", "O": "000", "U": "/"
    }
>>> def vowel_swapper(string, swaps=SWAPS):
        searching = {
            "A": False, "E": False, "I": False, "O": False, "U": False
        }
        str_list = list(string)
        for i, char in enumerate(str_list):
            char = char.upper()
            if searching.get(char) is False:
                searching[char] = True
            elif searching.get(char):
                str_list[i] = SWAPS.get(char)
                del searching[char]
        return "".join(str_list)

>>> vowel_swapper("aAa eEe iIi oOo uUu")
'a/\\a e3e i!i o000o u/u'
>>> vowel_swapper("Hello World")
'Hello W000rld'
>>> 

The dictionary searching determines whether the function is actively searching for a letter to replace. Once the first instance of a vowel is found, the value which corresponds to the vowel is set from False to True. If another instance of the same vowel is found (when the corresponding value in searching is True), the vowel is replaced, according to swaps, and the key is deleted from searching (to avoid repeats).

By iterating over string as a list, we can use index assignment (strings are not mutable; lists are). Then, at the end, the str.join() method is called to return the list of strings as a single string.


Edit

From the comments, I understand that OP wants to view the string with only one backslash, as opposed to the escaped backslash used in Python. To do so, you can write the resultant string to a file, then view the file:

>>> with open("file.txt", "w") as file:
        file.write(vowel_swapper("aAa eEe iIi oOo uUu"))

If you then open up the file, you'll see the backslash without the escape character:

a/\a e3e i!i o000o u/u

file.txt

Jacob Lee
  • 4,405
  • 2
  • 16
  • 37
  • expected result is : a/\a e3e i!i o000o u/u – pippo1980 Apr 16 '21 at 15:54
  • @pippo1980 The only reason there is a `/\\` between the a's is because when printing, Python will escape all backslashes. You won't be able to print only one backslash. – Jacob Lee Apr 16 '21 at 16:46
  • though your output was the actual print, is there any way to get rid of the double slash \\ inside a string ? I tried x = x[:2] + '/\' + x[5:] but got error and I am not printing it – pippo1980 Apr 16 '21 at 17:11
  • `"\\"` is actually one character. If you try to index the string `"\\"` with index 1, you'll get an error. Your error, I'm guessing, is a `SyntaxError` because you're trying to use a backslash without escaping it. I'll re-iterate that it's not possible to isolate a single backslash; the backslash character in python is composed of the escape character (a backslash) and a backslash. – Jacob Lee Apr 16 '21 at 17:14
  • OK thanks a lot ... I am kind of slow on the uptake ... but your < "\\" is actually one character. If you try to index the string "\\" with index 1, you'll get an error > explanation it's easy to understand. thank again – pippo1980 Apr 16 '21 at 17:22
  • but why : def return_string1(string): string = string[:1] + "/\\" + string[1+1:] return string, 'pippo' print('\n\n\n\n') print(return_string1("aAa eEe iIi oOo uUu")) gives me : ('a/\\a eEe iIi oOo uUu', 'pippo') – pippo1980 Apr 16 '21 at 17:24
  • You string slicing expression is equivalent to `string[:1] + "/\\" + string[2:]`. This will add the following characters: (1) The characters of `string` up to, but not including, the character at index 1; (2) The `"/\\"` characters; (3) The characters of `string` starting at the character at index 2 and including the following characters. So, it would be `"a" + "/\\" + "a eEe iIi oOo uUu"`. – Jacob Lee Apr 16 '21 at 17:28
  • my question was about the fact that print(returned tuple of strings) printed the tuple with the /\\ instead of just /\ : ('a/\\a eEe iIi oOo uUu', 'pippo') – pippo1980 Apr 16 '21 at 17:31
  • def return_string2(string): string = string[:1] + "/\\" + string[1+1:] return string print('\n\n\n\n') print(return_string2("aAa eEe iIi oOo uUu")) def return_string1(string): string = string[:1] + "/\\" + string[1+1:] return string, 'pippo' print('\n\n\n\n') print(return_string1("aAa eEe iIi oOo uUu")) def return_string3(string): string = string[:1] + "/\\" + string[1+1:] return string, 'pippo' print('\n\n\n\n') print(return_string3("aAa eEe iIi oOo uUu")[0]) – pippo1980 Apr 16 '21 at 17:33
  • sorry to bother but can't overvcame my : You have reached your question limit ban – pippo1980 Apr 16 '21 at 17:34
  • Again, `"\\"` is a **single character**. In Python, there **is not** a way to print _only_ `"\"`. – Jacob Lee Apr 16 '21 at 17:35
  • I guess not all the 'print' are the same print: a = '\\' print(a) b = list(a) print(b) – pippo1980 Apr 16 '21 at 17:42