I have two functions, the first one is related to the second, and it codes for whether or not a letter is a vowel (True) or a consonant (False).
def vowel(c):
"""(str) -> bool
Return whether the string c is a vowel.
>>> vowel('e')
True
>>> vowel('t')
False
"""
for char in c:
if char.lower() in 'aeiou':
return True
else:
return False
def repeated(s, k):
"""(str) -> str
Return a string where consonants in the string s is repeated k times.
>>> repeated('', 24)
''
>>> repeated('eoa', 2)
'eoa'
>>> repeated('m', 5)
'mmmmm'
>>> repeated('choice', 4)
'cccchhhhoicccce'
"""
result = ''
for c in s:
if c is not vowel(c):
result = result + (c * k)
return result
This is what I have for the function, but the examples fail and doesn't skip the vowels.
repeat('eoa', 2)
Expected:
'eoa'
Got:
'eeooaa'
Thanks in advance!
Two things. In the vowel function, there's no need for a loop. You're sending a single character so you simply need to check it:
def vowel(c):
if c.lower() in 'aeiou':
return True
else:
return False
Or:
def vowel(c):
return True if c.lower() in 'aeiou' else False
Then, in repeated, don't use c is not vowel(c). That compares if the identity of c, the character, is or isn't equal to True/False. Just use the value returned from vowel directly and conditionally add to result:
def repeated(s, k):
result = ''
for c in s:
if not vowel(c):
result += (c * k)
else:
result += c
return result
Related
I want to write a function that takes 2 inputs: a string and a substring, then the function will remove that part of the substring from the string.
def remove_substring(s, substr):
"""(str, str) -> NoneType
Returns string without string substr
remove_substring_from_string("Im in cs", "cs")
Im in
"""
other_s = ''
for substr in s:
if substr in s:
continue
How do I continue on from here? Assuming my logic is sound.
Avoiding the use of Python functions.
Method 1
def remove_substring_from_string(s, substr):
'''
find start index in s of substring
remove it by skipping over it
'''
i = 0
while i < len(s) - len(substr) + 1:
# Check if substring starts at i
if s[i:i+len(substr)] == substr:
break
i += 1
else:
# break not hit, so substr not found
return s
# break hit
return s[:i] + s[i+len(substr):]
Method 2
If the range function can be used, the above can be written more compactly as follows.
def remove_substring_from_string(s, substr):
'''
find start index in s of substring
remove it by skipping over it
'''
for i in range(len(s) - len(substr) + 1):
if s[i:i+len(substr)] == substr:
break
else:
# break not hit, so substr not found
return s
return s[:i] + s[i+len(substr):]
Test
print(remove_substring_from_string("I have nothing to declare except my genuis", " except my genuis"))
# Output: I have nothing to declare'
This approach is based on the KMP algorithm:
def KMP(s):
n = len(s)
pi = [0 for _ in range(n)]
for i in range(1, n):
j = pi[i - 1]
while j > 0 and s[i] != s[j]:
j = pi[j - 1]
if s[i] == s[j]:
j += 1
pi[i] = j
return pi
# Removes all occurences of t in s
def remove_substring_from_string(s, t):
n = len(s)
m = len(t)
# Calculate the prefix function using KMP
pi = KMP(t + '\x00' + s)[m + 1:]
r = ""
i = 0
while i + m - 1 < n: # Before the remaining string is smaller than the substring
if pi[i + m - 1] == m: # If the substring is here, skip it
i += m
else: # Otherwise, add the current character and move to the next
r += s[i]
i += 1
# Add the remaining string
r += s[i:]
return r
It runs in O(|s| + |t|), but it has a few downsides:
The code is long and unintuitive.
It requires that there is no null (\x00) in the input strings.
Its constant factors are pretty bad for short s and t.
It doesn't handle overlapping strings how you might want it: remove_substring_from_string("aaa", "aa") will return "a". The only guarantee made is that t in remove_substring_from_string(s, t) is False for any two strings s and t.
A C++ example and further explanation for the KMP algorithm can be found here. The remove_substring_from_string function then only checks if the entire substring is matched at each position and if so, skips over the substring.
I would do this using re.
import re
def remove_substring(s, substr):
# type: (str, str) -> str
return re.subn(substr, '', s)[0]
remove_substring('I am in cs', 'cs')
# 'I am in '
remove_substring('This also removes multiple substr that are found. Even if that substr is repeated like substrsubstrsubstr', 'substr')
# 'This also removes multiple that are found. Even if that is repeated like '
def remove_substring(s, substr):
while s != "":
if substr in s:
s = s.replace(substr, "")
else:
return s
if s == "":
return "Empty String"
The idea here is that we replace all occurrences of substr within s, by replacing the first instance of substr and then looping until we are done.
The question given is : How to implement a function so that it returns True if the input strings are the same length and differ at exactly one character position, and returns False otherwise.
I'm looking to return true or false depending on if the input strings are the same length and differ at exactly one character position. What I have now tells me if they're the same length but fails when given the same set of letters in a different order.
def sameordiffernt(string1,string2):
str1 = string1.lower()
str2 = string2.lower()
count = 0
if len(str1) == len(str2):
print ('true1')
else:
print('false1')
count = count +1
while str1 == str2:
print('true2')
else:
print('false2')
count = count + 1
if count == 2:
print('false3')
else:
print('true')
return
Try the following to see if this works:
def sameOrDifferent(param1, param2):
str1 = param1.lower()
str2 = param2.lower()
count = 0
numDiff = 0
if len(str1) == len(str2):
for index in range(len(str1)):
if str1[index] != str2[index]:
numDiff = numDiff + 1
return numDiff == 1
else:
return False
You can use in-built zip() function for a pythonic solution:
def sameOrDifferent(s1, s2):
for (c1, c2) in zip(s1, s2):
if c1 != c2:
print('False')
return False;
print('True')
return True
sameOrDifferent('car', 'car') # True
sameOrDifferent('car', 'caw') # False
I'm trying to create a function to evaluate if contains at least three vowels consecutively.
I've tried so far:
( I don't know how to evaluate if they are consecutive)
any ideas?
def isConsecutive(word):
# initialize vowel count
vCounter = 0
for letter in word:
if letter == isVowel(word):
vCounter += 1
else:
vCounter = 0
if vCounter < 3:
return False
return True
Helper function
def isVowel(char):
return len(char) == 1 and char.lower() in 'aeiou'
The check, whether you have reached the third vovel in sequence, should be right after the vCounter += 1. If there are three vovels: return true.
Also, the isVowel check should be applied to the letter, not the whole word.
def isVowel(char):
return char.lower() in 'aeiou'
def isConsecutive(word):
# initialize vowel count
vCounter = 0
for letter in word:
if isVowel(letter): # <= check if the letter is a vowel
vCounter += 1
if vCounter >= 3: # <= do the check right here
return True
else:
vCounter = 0
return False # <= if we did not find three vovels in the loop, then there is none
print "hello: " + str(isConsecutive("hello"))
print "heeello: " + str(isConsecutive("heeello"))
print "hellooo: " + str(isConsecutive("hellooo"))
Give it a try online: DEMO
You can do this also with two list comprehensions:
a list of booleans, if the characters in a word are vowels
a list of booleans, if there are three consecutive True values in the first list
.
def three_consecutive_vowels(s):
is_vow = [c.lower() in 'aeiou' for c in s]
three_cons = [all(is_vow[i:i+2]) for i in range(len(is_vow) - 2)]
return any(three_cons)
Test:
words = ['hellO', 'heIah', 'aAarrgh']
for w in words:
print(three_consecutive_vowels(w))
False
True
True
def myfunc(word):
result = ""
index = 0
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
index +=1
I am trying to return a matching string where every even letter is uppercase and every odd letter is lowercase. But the code doesn't show this exact result, any solution?
The problem is that you're only incrementing index after the loop, rather than each time through it. So, inside the loop, it's always 0. The smallest fix is:
def myfunc(word):
result = ""
index = 0
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
index += 1
return result
But this kind of mistake is very easy to make (and sometimes not as easy as this to debug)—which is exactly why Python has nice tools like enumerate, that make it impossible to get wrong:
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
People, including myself, have already pointed out your programming error. Here is an alternative one-liner solution to your problem using a generator expression and a ternary conditional operator:
def myfunc(word):
return "".join(w.upper() if i%2 else w.lower() for i,w in enumerate(word))
enumerate will return a tuple of the form (index, value) for each item in the iterable. In this case, the iterable is the string word.
At each step in the iteration, we check to see if the index i is odd.
i%2 will return 0 for even numbers and the if statement will evaluate to False.
Likewise, it will evaluate to True for odd numbers.
Respectively, we call lower() and upper() on the current character w.
Finally we use str.join to concatenate all the individual letters back together. Here we join the characters using an "" with is the empty string.
The problem was with how you were incrementing. You only set up your index to increment inside the "Else" block of your code. It was missing from the "If" block. As such as soon as you entered the "If" block you would be stuck there.
def myfunc(string):
result = ""
index = 0
for letter in string:
if index % 2 == 0:
result += letter.upper()
index += 1
else:
result += letter.lower()
index += 1
return result
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
return result
this worked for me.
Also it is much easier to understand the above block of code if you understand the enumerate function well
def myfunc(word):
index = 0
result = ''
for letter in word:
if index % 2 == 0:
result += letter.lower()
else:
result += letter.upper()
index += 1
print result
You weren't increment your index in the correct spot ;)
If you execute myfunc(word) it will print hElLo
def gonna(st) :
a = []
Index = 0
for index, c in enumerate(st) :
if index ℅ 2 == 0:
a.append(c.upper())
Index = Index + 1
else:
a.append(c.lower())
Index = Index + 1
return a
def myfunc(a):
result=""
for x in range(0,len(a)):
if x%2==0:
result=result+a[x].upper()
else:
result=result+a[x].lower()
return result
def myfunc(word):
z=list(word)
x=[]
y=[]
new_list=[]
str=""
for a in z:
x+=[a]
if len(x)==2:
y+=[x]
x=[]
for i in y:
odd=i[0].lower()
even=i[1].upper()
new_list.append(odd)
new_list.append(even)
for el in new_list:
str+=el
return str
def myfunc(str):
# Create an empty string to append the values to
result = ''
# Iterate through the loop using the enumerate function on the string so that you can use the index and the letter at the same time.
for index,letter in enumerate(str):
if index %2 == 0:
result += letter.lower()
else:
result += letter.upper()
# Return the string after all the letters have been appended to the string
return result
More Simpler , which is made using all the basic conecpts of Python
def myfunc(string):
new_string=""
for items in range(len(string)): # help us to to know about the index
if items % 2 == 0:
new_string = new_string + string[items].upper()
else:
new_string = new_string + string[items].lower()
return new_string
result=myfunc("Draco")
print(result)
def myfunc(word):
index=0
result = ''
for letter in word:
if index%2==0:
result=result+letter.upper()
else:
result=result+letter.lower()
index+=1
return result
**
Heading
**
def myfunc(word):
result = ""
for index, letter in enumerate(word):
if index % 2 == 0:
result += letter.upper()
else:
result += letter.lower()
return result
I'd like to try and do this without using indexing.
def SSet(s, i, c):
#A copy of the string 's' with the character in position 'i'
#set to character 'c'
count = -1
for item in s:
if count >= i:
count += 1
if count == i:
item += c
print(s)
print(SSet("Late", 3, "o"))
in this example, Late should be changed to Lato.
Thank you.
You didn't have an accumulator to hold the output and the logic on the counter was off. The following loops over the string and concatenates the character to the output unless the characters index is the index given at which point it uses the given character.
def SSet(s, i, c):
"""A copy of the string 's' with the character in position 'i' set to character 'c'"""
res = ""
count = -1
for item in s:
count += 1
if count == i:
res += c
else:
res += item
return res
print(SSet("Late", 3, "o"))
prints
Lato
This can be written better with enumerate which removes the counter:
def SSet(s, i, c):
"""A copy of the string 's' with the character in position 'i' set to character 'c'"""
res = ""
for index, item in enumerate(s):
if index == i:
res += c
else:
res += item
return res
It could also be made faster by appending the characters to a list and then joining them at the end:
def SSet(s, i, c):
"""A copy of the string 's' with the character in position 'i' set to character 'c'"""
res = []
for index, item in enumerate(s):
if index == i:
res.append(c)
else:
res.append(item)
return ''.join(res)
It is also unasked for but here is how to do it with slices:
def SSet(s, i, c):
"""A copy of the string 's' with the character in position 'i' set to character 'c'"""
return s[:i]+c+s[i+1:]
def SSet(s, i, c):
#A copy of the string 's' with the character in position 'i'
#set to character 'c'
count = 0
strNew=""
for item in s:
if count == i:
strNew=strNew+c
else:
strNew=strNew+item
count=count+1
return strNew
print(SSet("Late", 3, "o"))