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])
Related
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)
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
Working through exercises on the CodeWars website and I need help being pointed in the right direction for a simple function:
Write a function toWeirdCase (weirdcase in Ruby) that accepts a
string, and returns the same string with all even indexed characters
in each word upper cased, and all odd indexed characters in each word
lower cased. The indexing just explained is zero based, so the
zero-ith index is even, therefore that character should be upper
cased.
The passed in string will only consist of alphabetical characters and
spaces(' '). Spaces will only be present if there are multiple words.
Words will be separated by a single space(' ').
The code I have so far is this:
def to_weird_case(string):
#TODO
new_string = ''
add = 0
for letter in range(len(string)):
if string[letter] == ' ':
add += 1
new_string += string[letter]
continue
if (letter+add)%2 == 0:
new_string += string[letter].upper()
else:
new_string += string[letter].lower()
print("Returning: " + new_string)
return new_string
I am trying to iterate over each letter while taking in to account the spaces but I am unsure how to 'skip over' the spaces and that is what is messing up my function? If someone could point me in the right direction that would be helpful, thanks.
def to_weird_case(string):
#TODO
counter = 0
new_string = ''
add = 0
for letter in range(len(string)):
if string[letter] == ' ':
new_string += string[letter]
continue
if (counter)%2 == 0:
new_string += string[letter].upper()
else:
new_string += string[letter].lower()
# Increment counter after one place as 0th position is even
counter = counter + 1
print("Returning: " + new_string)
return new_string
to_weird_case("HELLO MY NAME IS abcdefghijk")
Output : Returning: HeLlO mY nAmE iS aBcDeFgHiJk
Just create a counter (an integer variable) that will keep track of whether you are in an even or odd index. The counter will not increment if you encounter a space, thereby ignoring it.
def to_weird_case(string):
#TODO
counter = 0
new_string = ''
add = 0
for letter in range(len(string)):
if string[letter] == ' ':
new_string += string[letter]
continue
# Increment counter only if not space
counter = counter + 1
if (counter)%2 == 0:
new_string += string[letter].upper()
else:
new_string += string[letter].lower()
print("Returning: " + new_string)
return new_string
You can disregard the spaces by first splitting the string using str.split, transform each word using enumerate to select even and odd characters, and then rejoin the string using str.join on spaces:
def transform_word(s):
return ''.join(x.upper() if i%2==0 else x.lower() for i, x in enumerate(s))
# ^------------^-> ternary operator for alternating
def to_weird_case(string):
return ' '.join(transform_word(s) for s in string.split())
print(to_weird_case('This is a lovely day'))
# ThIs Is A LoVeLy DaY
And if you eventually want to consider the spaces, use the transform_word function directly:
print(transform_word('This is a lovely day'))
# ThIs iS A LoVeLy dAy
Try list comprehension:
def my_func(your_string):
x = [ x.upper() if i%2==0 else x.lower() for i,x in enumerate(your_string)]
return ''.join(x)
your_string = 'hello my name is lmurdock12'
print(my_func(your_string))
Output:
HeLlO My nAmE Is lMuRdOcK12
So basically what happens in this list comprehension is that we use enumerate()
x = [ x.upper() if i%2==0 else x.lower() for i,x in enumerate(your_string)]
enumerate takes a iterable (string,list..etc) and gives out items one by one (i) where i would be 0,1,2,3...and so on
So in the list comprehension we check if i corresponding to that item x returned from iterable string your_list. So in hello my name is lmurdock12 i would be 0 for h and 1 for e and so on. If i%2==0 which means it's even we keep x.upper() else we keep x.lower() in the list.
Finally use ''.join(x) to join the list and return it if you want.
NOTE: This could be done without enumerate by using index() but that would make our algorithm a little inefficient because that we way we have search for the value and return index everytime. It's better to use enumerate.
Here is a working solution. Hope that helps!
def to_weird_case(string)
words = string.split(" ")
words.map do |word|
word.chars.map.with_index {|letter, idx| idx.even? ? letter.upcase : letter.downcase }.join("")
end.join(" ")
end
You can avoid the counter if you user the enumerate function
def to_weird_case(string):
#TODO
new_string = ''
for i,letter in enumerate(string):
if string[i] == ' ':
new_string += string[i]
continue
if i%2 == 0:
new_string += string[i].upper()
else:
new_string += string[i].lower()
print("Returning: " + new_string)
return new_string
Your code is not really pythonesque. Your function can actually have only 1 line of code. This is why Python is so cool.
def ToWeirdCase(word):
return ''.join([char.upper() if pos%2==0 else char.lower() for pos, char in enumerate(word)])
Hi I had this same problem early this morning, this is my answer:
def to_weird_case(sentence):
counter = 0 # Counter set to zero, because of the even number fact at zero-ith.
weird_sentence = "" # This is the string we are going to return at the end.
for character in sentence:
if character == " " and counter % 2 == 0:
weird_sentence += character
counter += 1 # Incrementation that will now make each characters before a space to be uppercased.
elif character != " " and counter % 2 == 0:
weird_sentence += character.upper()
else:
weird_sentence += character.lower()
counter += 1
return weird_sentence
I hope it helps you out.
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')
# '()()()'
This question already has answers here:
How can I invert (swap) the case of each letter in a string?
(8 answers)
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 6 months ago.
I would like to change the chars of a string from lowercase to uppercase.
My code is below, the output I get with my code is a; could you please tell me where I am wrong and explain why?
Thanks in advance
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
for word in words:
if word.isupper() == True:
return word.lower()
else:
return word.upper()
print to_alternating_case(test)
If you want to invert the case of that string, try this:
>>> 'AltERNating'.swapcase()
'aLTernATING'
There are two answers to this: an easy one and a hard one.
The easy one
Python has a built in function to do that, i dont exactly remember what it is, but something along the lines of
string.swapcase()
The hard one
You define your own function. The way you made your function is wrong, because
iterating over a string will return it letter by letter, and you just return the first letter instead of continuing the iteration.
def to_alternating_case(string):
temp = ""
for character in string:
if character.isupper() == True:
temp += character.lower()
else:
temp += word.upper()
return temp
Your loop iterates over the characters in the input string. It then returns from the very first iteration. Thus, you always get a 1-char return value.
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
rval = ''
for c in words:
if word.isupper():
rval += c.lower()
else:
rval += c.upper()
return rval
print to_alternating_case(test)
That's because your function returns the first character only. I mean return keyword breaks your for loop.
Also, note that is unnecessary to convert the string into a list by running words = list(string) because you can iterate over a string just as you did with the list.
If you're looking for an algorithmic solution instead of the swapcase() then modify your method this way instead:
test = "AltERNating"
def to_alternating_case(string):
res = ""
for word in string:
if word.isupper() == True:
res = res + word.lower()
else:
res = res + word.upper()
return res
print to_alternating_case(test)
You are returning the first alphabet after looping over the word alternating which is not what you are expecting. There are some suggestions to directly loop over the string rather than converting it to a list, and expression if <variable-name> == True can be directly simplified to if <variable-name>. Answer with modifications as follows:
test = "AltERNating"
def to_alternating_case(string):
result = ''
for word in string:
if word.isupper():
result += word.lower()
else:
result += word.upper()
return result
print to_alternating_case(test)
OR using list comprehension :
def to_alternating_case(string):
result =[word.lower() if word.isupper() else word.upper() for word in string]
return ''.join(result)
OR using map, lambda:
def to_alternating_case(string):
result = map(lambda word:word.lower() if word.isupper() else word.upper(), string)
return ''.join(result)
You should do that like this:
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
newstring = ""
if word.isupper():
newstring += word.lower()
else:
newstring += word.upper()
return alternative
print to_alternating_case(test)
def myfunc(string):
i=0
newstring=''
for x in string:
if i%2==0:
newstring=newstring+x.lower()
else:
newstring=newstring+x.upper()
i+=1
return newstring
contents='abcdefgasdfadfasdf'
temp=''
ss=list(contents)
for item in range(len(ss)):
if item%2==0:
temp+=ss[item].lower()
else:
temp+=ss[item].upper()
print(temp)
you can add this code inside a function also and in place of print use the return key
string=input("enter string:")
temp=''
ss=list(string)
for item in range(len(ss)):
if item%2==0:
temp+=ss[item].lower()
else:
temp+=ss[item].upper()
print(temp)
Here is a short form of the hard way:
alt_case = lambda s : ''.join([c.upper() if c.islower() else c.lower() for c in s])
print(alt_case('AltERNating'))
As I was looking for a solution making a all upper or all lower string alternating case, here is a solution to this problem:
alt_case = lambda s : ''.join([c.upper() if i%2 == 0 else c.lower() for i, c in enumerate(s)])
print(alt_case('alternating'))
You could use swapcase() method
string_name.swapcase()
or you could be a little bit fancy and use list comprehension
string = "thE big BROWN FoX JuMPeD oVEr thE LAZY Dog"
y = "".join([val.upper() if val.islower() else val.lower() for val in string])
print(y)
>>> 'THe BIG brown fOx jUmpEd OveR THe lazy dOG'
This doesn't use any 'pythonic' methods and gives the answer in a basic logical format using ASCII :
sentence = 'aWESOME is cODING'
words = sentence.split(' ')
sentence = ' '.join(reversed(words))
ans =''
for s in sentence:
if ord(s) >= 97 and ord(s) <= 122:
ans = ans + chr(ord(s) - 32)
elif ord(s) >= 65 and ord(s) <= 90 :
ans = ans + chr(ord(s) + 32)
else :
ans += ' '
print(ans)
So, the output will be : Coding IS Awesome