I'm trying to add the letter 'X' before each vowel in a string or sentence, however, when there is a repeated vowel, the letter 'X' should only be written once. For example, the word 'speeding' should look like this 'spXeedXing' but i'm getting 'spXeXedXing'.
I know why I'm getting this problem but don't know where to go from here to make it work.
Code below
def vowels(string):
newString = ""
for letter in string:
if letter in "aeiou":
newString += "X" + letter
else:
newString += letter
print(newString)
if __name__ == "__main__":
vowels("speeding")
>>> import re
>>> re.sub('([aeiou]+)','X\g<1>','speeding')
'spXeedXing'
>>>
You should create a new variable to track the previous letter in string. Check if the letters are continuous and only add X if the previous char is not the same as the current char.
def vowels(string):
newString = ""
i = 0 # Create a counter variable
for letter in string:
if (letter in "aeiou" and letter != string[i-1]) or (letter in "aeiou" and i == 0 and letter == string[i-1]): # Change this condition.
i += 1
newString += "X" + letter
else:
newString += letter
i += 1 # Increment counter variable
print(newString)
if __name__ == "__main__":
vowels("speeding")
Output:
spXeedXing
Other test cases:
vowels("oompaloompas")
XoompXalXoompXas
vowels("eerie")
XeerXiXe
You can let a regex do all the state-machine hard work...
To prepend 'X' to any number of consecutive vowels:
import re
s = 'speeding'
>>> re.sub(r'([aeiou]+)', r'X\1', s)
'spXeedXing'
To prepend 'X' only to the same repeating vowel:
s = 'speeding'
>>> re.sub(r'(([aeiou])\2*)', r'X\1', s)
'spXeedXing'
s = 'toaster'
>>> re.sub(r'(([aeiou])\2*)', r'X\1', s)
'tXoXastXer'
Here is a simple non-regex version:
def vowels(word):
new_word = ""
prev = "" # no previous letter at first
for letter in word:
if letter in "aeiou" and letter != prev:
new_word += "X" + letter
else:
new_word += letter
prev = letter # keep to avoid insertion for repeats
return new_word
if __name__ == "__main__":
print(vowels("speeding"))
print(vowels("eerie"))
print(vowels("aaaaaaaaaaaaaargh"))
producing
spXeedXing
XeerXiXe
Xaaaaaaaaaaaaaargh
you should try checking the previous letter in the string to see if it is the same letter as the current index
def vowels(string):
newString = ""
for i in range(len(string)):
if string[i] in "aeiou":
if string[i - 1] == string[i]:
newString += string[i]
else:
newString += "X" + string[i]
else:
newString += string[i]
print(newString)
Related
I am trying to solve an exercise regarding strings in Python. The exercise says: Write a function that takes a string word and returns a list of strings containing the sound elements of the given word.
A sound element is a maximal sequence of 1 or more consonants followed by 1 or more vowels. In other words, i am supposed to iterate over a string of characters and split it everytime a vowel is followed by a consonant.
Example:
the following string given in input:
S = 'unconditionally'
should return the following list
L = ['u','nco','ndi','tio','na','lly']
In order to solve the exercise, i have written the following function:
def split_words(S):
string = ''
syllables = []
vowels = ['a','e','i','o','u','j','y']
for i in range(len(S)):
if S[i] not in vowels:
string += S[i]
elif S[i] in vowels and S[i+1] not in vowels:
string += S[i]
syllables.append(string)
string = ''
return syllables
Which should be able to solve it. The problem is that i get an index-out-of-range error everytime i run the program. I know the issue is in the elif statement which i don't know how to get rid of.
Is there any way to solve this exercise without importing any external libraries?
Any help will be appreciated
You iterate till the index of the last character :
for i in range(len(S)):
and you have this line:
elif S[i] in vowels and S[i+1] not in vowels:
if i is the last index of S, then it will throw error on S[i+1]
Edit: You can use this:
def split_words(S):
string = ''
syllables = []
vowels = ['a','e','i','o','u','j','y']
for i in range(len(S)):
if S[i] not in vowels:
if len(string) == 0 or not string[-1] in vowels: #here I check if length of string is 0
#in this case I can append letter to it. And also if last letter (`string[-1]`) isn't a vowel,
#then also I can add this letter to string
string += S[i]
else: # if last letter was vowel then we reset string.
syllables.append(string)
string = ''
string += S[i]
else:
string += S[i]
syllables.append(string)
return syllables
We can further simplify code, because we have string += S[i] in every block of if-else:
def split_words(S):
string = ''
syllables = []
vowels = ['a','e','i','o','u','j','y']
for i in range(len(S)):
if S[i] not in vowels and len(string) > 0 and string[-1] in vowels:
syllables.append(string)
string = ''
string += S[i]
syllables.append(string)
return syllables
vowel = "aeiou"
for i in range(0:len(s)):
if s[i] in vowel == True
count += 1
print("Number of vowels: "+str(count))
The above code doesn't throw any errors in Spyder. I am taking an online course, s is a predefined variable which contains a string. Here I defined s as "big black car"
I have to count the vowels in the string.
When I press enter after typing the code in, I am moved to the next line, nothing happens, I am prompted for more input.
What am I doing wrong?
Working code for you:
s="big black car"
vowel = "aeiou"
count = 0
for i in range(len(s)):
if s[i] in vowel:
count += 1
print("Number of vowels: "+str(count))
Note: First of all, you should use range (len(s)). Second thing is that s[i] in vowel == True will return False. You can easy check it in python console.
>>> 'a' in 'a'
True
>>> 'a' in 'a' == True
False
>>> ('a' in 'a') == True
True
According to my best knowledge Python firstly execute 'a' == True that gives False, then execute 'a' in False. That's why condition is False. Extra parentheses fix that problem.
EDIT: tripleee point that you can use range(len(s)) :).
You need to fix the following:
Get rid of the 0:
Replace the == True with a :
Indent the count += 1 4 spaces to the right
So your code should look as follows:
vowel = "aeiou"
for i in range(len(s)):
if s[i] in vowel:
count += 1
print("Number of vowels: "+str(count))
You can further reduce it to:
vowel = "aeiou"
for i in range(len(s)):
count += s[i] in vowel
print("Number of vowels: "+str(count))
And then further reduce it to:
vowel = "aeiou"
count = sum([s[i] in vowel for i in range(len(s))])
print("Number of vowels: "+str(count))
And then further reduce it to:
vowel = "aeiou"
print("Number of vowels: "+str(sum([s[i] in vowel for i in range(len(s))])))
And then further reduce it to:
vowel = "aeiou"
print("Number of vowels: ", sum([s[i] in vowel for i in range(len(s))]))
And then further reduce it to:
print("Number of vowels: ", sum([s[i] in "aeiou" for i in range(len(s))]))
I need to convert a string word where each character that appears only once should be appear as '(' in the new string. Any duplicate characters in the original string should be replaced with ')'.
My code below...
def duplicate_encode(word):
new_word = ''
for char in word:
if len(char) > 1:
new_word += ')'
else:
new_word += '('
return new_word
The test I'm not passing is as follows:
'((((((' should equal '()()()'
This would suggest that, if for example, the input is "recede," the output should read ()()().
Your Code is Good just need some alteration it will be great.
def duplicate_encode(word):
"""
To replace the duplicate letter with ")" in a string.
if given letter is unique it replaced with "("
"""
word_dict = {} # initialize a dictionary
new_word = ""
for i in set(word): # this loop is used to count duplicate words
word_count = word.count(i)
word_dict[i] = word_count # add letter and count of the letter to dictionary
for i in word:
if word_dict[i] > 1:
new_word += ")"
else:
new_word += "("
print new_word
duplicate_encode("recede")
I think you got the answer :)
Just because (it's late and) it's possible:
def duplicate_encode(word):
return (lambda w: ''.join(('(', ')')[c in w[:i] + w[i+1:]] for i, c in enumerate(w)))(word.lower())
print(duplicate_encode("rEcede"))
OUTPUT
> python3 test.py
()()()
>
Seems like your result is based on the number of occurrences of a character in the word, you can use Counter to keep track of that:
def duplicate_encode(word):
from collections import Counter
word = word.lower() # to disregard case
counter = Counter(word)
new_word = ''
for char in word:
if counter[char] > 1: # if the character appears more than once in the word
# translate it to )
new_word += ')'
else:
new_word += '('
return new_word
duplicate_encode('recede')
# '()()()'
Input : UserID/ContactNumber
Output: user-id/contact-number
I have tried the following code:
s ="UserID/ContactNumber"
list = [x for x in s]
for char in list:
if char != list[0] and char.isupper():
list[list.index(char)] = '-' + char
fin_list=''.join((list))
print(fin_list.lower())
but the output i got is:
user-i-d/-contact-number
You could use a regular expression with a positive lookbehind assertion:
>>> import re
>>> s ="UserID/ContactNumber"
>>> re.sub('(?<=[a-z])([A-Z])', r'-\1', s).lower()
'user-id/contact-number'
What about something like that:
s ="UserID/ContactNumber"
so = ''
for counter, char in enumerate(s):
if counter == 0:
so = char
elif char.isupper() and not (s[counter - 1].isupper() or s[counter - 1] == "/"):
so += '-' + char
else:
so += char
print(so.lower())
What did I change from your snippet?
You were checking if this is the first char and if it is a upper char.
I have add a check on the previous char, to not consider when the previous is upper (for the D of ID) or when the previous is \ for the C of Contact.
You are also editing the list list while iterating on it's element, that is dangerous.
I have instead create an output string to store the new values
I did something like this
s ="UserID/ContactNumber"
new = []
words = s.split("/")
for word in words:
new_word = ""
prev = None
for i in range(0, len(word)):
if prev is not None and word[i].isupper() and word[i-1].islower():
new_word = new_word + "-" + word[i]
prev = word[i]
continue
new_word = new_word + word[i]
prev = word[i]
new.append(new_word.lower())
print "/".join(new)
user-id/contact-number
This is a homework question. I'm defining a function that takes a word and replaces a given char by another char. For example replace("cake","a","o") should return "coke" I have tried
def replace(word,char1,char2):
newString = ""
for char1 in word:
char1 = char2
newString+=char1
return newString #returns 'oooo'
and
def replace(word,char1,char2):
newString = ""
if word[char1]:
char1 = char2
newString+=char1
return newString #TypeError: string indices must be integers, not str
I'm assuming my first attempt is closer to what I want. What is going wrong in my functions?
Try this:
def replace(word,char1,char2):
newString = ""
for next_char in word: # for each character in the word
if next_char == char1: # if it is the character you want to replace
newString += char2 # add the new character to the new string
else: # otherwise
newString += next_char # add the original character to the new string
return newString
Although strings in python already have a method that does this:
print "cake".replace("a", "o")
def replace(word, ch1, ch2) :
return ''.join([ch2 if i == ch1 else i for i in word])