-1

So I am trying to solve a problem on the PyBites Platform where it asks you to do the following:

  • Take any string
  • Format it to lowercase
  • Replace any vowel with the * symbol
  • Track how many vowels were changed

The example string text = 'Hello World' should return the following tuple: ('h*ll* w*rld', 3) with 3 representing the total vowels changed.

The code below includes a function that should take care of all the steps listed. I even used assignment so that I could use .replace() and output the changed characters:

from typing import Tuple

text = 'Hello World'

def strip_vowels(text: str) -> Tuple[str, int]:
    vowels = 'aeiou'
    count = 0
    text = text.lower().splitlines()
    for words in text:
        for char in words:
            for vowel in vowels:
                if char == vowel:
                    count += 1
                    result = words.replace(char, '*'), count                     
        return result
        

answer = strip_vowels(text)
print(answer)

The problem I am having is that although I am successfully checking whether a character in a string is a vowel or not, the return value is off: ('hell* w*rld', 3) I know that replace() is checking for a vowel at each iteration but it's not storing all the results.

Any guidance on what steps I should take? Thanks in advance.

  • Does this answer your question? [String replace doesn't appear to be working](https://stackoverflow.com/questions/26943256/string-replace-doesnt-appear-to-be-working) – Ken Y-N Jul 07 '20 at 04:12

3 Answers3

1

The problem is the use of words variable when doing a replace. Every use of the word variable refers to its original loop variable form. You need to use the result string created by the replace. A fix could be assigning a None value to result before entry into the topmost loop the checking if work has been use:

result = None
for words in text:
.....

if result is None:
    result = words.replace(char, '*'), count   
else:
    result = result[0].replace(char, '*'), count

The use of splitlines is ambiguous to me, I didn't see the need for it. I think the creation of a transtable will be more effective than the nested loops used

def strip_vowels(text: str) -> Tuple[str, int]:
    text = 'Hello World'
    inner, outer = "aeiou", "*"*5
    transtab = str.maketrans(inner, outer)

    text = text.translate(transtab)
    count = 0
    for letter in text:
        if letter == '*':
            count += 1
    return (text, count)
zizu
  • 33
  • 4
0

Try this solution

text = 'Hello World'

def strip_vowels(text):
    newString = ''
    count = 0
    text = text.lower()
    for char in text:
        if(char in 'aeiou'):
            count += 1
            newString += '*'
        else:
            newString += char
        
    return newString, count

answer = strip_vowels(text)
print(answer)
TechWithVP
  • 44
  • 3
0

The problem is here

if char == vowel:
    count += 1
    result = words.replace(char, '*'), count  

You replace the vowel of the original text without saving it for the loop.

Take the word hello world as an example,

|------|-------------|-------------|-------|
| char | words       | result      | count |
|------|-------------|-------------|-------|
| h    | hello world | hello world |     0 |
| e    | hello world | h*llo world |     1 | Replaced 'e', count + 1
| l    | hello world | hello world |     1 |
| l    | hello world | hello world |     1 |
| o    | hello world | hell* w*rld |     2 | Replaced 'o', count + 1
|      | hello world | hello world |     2 | 
| w    | hello world | hello world |     2 |
| o    | hello world | hell* w*rld |     3 | Replaced 'o', count + 1
| r    | hello world | hello world |     3 |
| l    | hello world | hello world |     3 |
| d    | hello world | hello world |     3 |
|------|-------------|-------------|-------|

Below is a modified version of your code

def strip_vowels(text: str) -> Tuple[str, int]:
    vowels = 'aeiou'
    count = 0
    text = text.lower().splitlines()
    for words in text:
        for char in words:
            for vowel in vowels:
                if char == vowel:
                    count += 1
                    words = words.replace(char, '*')  # Modified
        return words, count                           # Modified

print(strip_vowels('Hello World'))
# Output:
# ('H*ll* W*rld', 3)

A neater version would be like this

def strip_vowels(text: str) -> Tuple[str, int]:
    vowels = 'aeiou'
    for vowel in vowels:
        text = text.replace(vowel.upper(), '*')
        text = text.replace(vowel.lower(), '*')
    return text, text.count('*')

print(strip_vowels('Hello World'))
# Output:
# ('H*ll* W*rld', 3)
pe-perry
  • 2,591
  • 2
  • 22
  • 33
  • This was an awesome answer! The table visualizing how my implementation iterated through the string was crucial to my understanding. Thank you!! – Ian Vidaurre Jul 07 '20 at 17:19