When to break up a function - python

Currently I am very new to python programming, been working on it for a while, I came across a little project task which was to make a program that takes all of the vowels out of a statement so I decided to try it out. I came up with a program but it seems that it only takes out the vowels sometimes, I find this very weird and I would like to ask for some assistance in solving it.
def anti_vowel(text):
list = ['a', 'e', 'i', 'o', 'u']
big_list = ['A', 'E', 'I', 'O', 'U']
list_word = []
for f in text:
list_word.append(f)
for vowel in list:
for letter in list_word:
if vowel == letter:
list_word.remove(vowel)
for vowel in big_list:
for letter in list_word:
if vowel == letter:
list_word.remove(vowel)
new_word = ''.join(list_word)
return new_word
print anti_vowel("uuuUUUUUIIIIiiiIiIoOuuooouuUOUUuooouU")
This statement as it sits prints out 'IiIuUUuoouU', but if I add more iterations over the lists using more for statements it decreases the amount of shown letters. Can someone tell me why this might be?

A little improvement:
list = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
def anti_vowel(text):
return ''.join([x for x in text if x not in list])
print anti_vowel("uuuUUUUUIIIIiiiIiIoOuuooouuUOUUuooouU")

Abend's solution with little edits that make it correct
vowels = ['a','e','i','o','u','A','E','I','O','U']
def no_vowels(str1):
return ''.join([char for char in list(str1) if char not in vowels])
print no_vowels('finished')
Gives
fnshd
Process finished with exit code 0

This code is the correct implementation
def anti_vowel(c):
newstr = c
vowels = ('a', 'e', 'i', 'o', 'u')
for x in c.lower():
if x in vowels:
newstr = newstr.replace(x,"")
return newstr

Related

How do I return a value within a loop within a function?

I have this almost figured it out but there is one thing. Basically I want to return a string without a vowel (a common challenge I guess). This is similar to other challenges on CodeWars I have done, still uncompleted due to this. I have a for loop within a function. I call the function to return value.
For some reason, I'm returning empty or rather "None", yet I get the result I wanted by printing. On the same line and indenting.
This is for a Codewar challenge, so I need to return values instead of , printing, logging (I know). I asked for a friend, hours of researching but nothing could help me.
def disemvowel(string):
#aeiou
vowel = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
aList = list(string) #'' to [...]
for x in aList:
for y in vowel:
if x == y:
#print(x)
aList.remove(x)
print(''.join(aList)) # "Ths wbst s fr lsrs LL!"
return(''.join(aList)) # Nothing shows up here...
I expect the output of "Ths wbst s fr lsrs LL!" by returning but I get None.
https://www.codewars.com/kata/52fba66badcd10859f00097e/train/python
Source ^
To remove vowels from strings, the quickest way would be to use str.replace.
def remove_vowels(msg):
vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
for vowel in vowels:
msg = msg.replace(vowel, '')
return msg
Use a list comprehension:
def remove_vowels(msg):
return ''.join(c for c in msg if c.lower() not in {'a', 'e', 'i', 'o', 'u'})
Examples:
>>> remove_vowels("Lorem ipsum dolor sit amet.")
'Lrm psm dlr st mt.'
>> remove_vowels("This is it")
'Ths s t'
>>> remove_vowels("This website is for losers LOL!")
'Ths wbst s fr lsrs LL!'

Append dot before each letters

I want to add a point before each letter.
Unfortunately, the point is after each letter. How to insert the point before each letter?
myText = str(input())
vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
result = ''
for letter in myText:
if letter not in vowels:
result = result + letter
for i in result:
result = result + '.'
break
print(result.lower())
A shorter and faster solution relying on the power of regular expressions:
import re
my_text = "sample"
re.sub(r"[aeiou]*([^aeiou])[aeiou]*", r".\1", my_text.lower())
This reads: “delete vowels, and prefix each remaining letter with a dot”.
Removing all vowels and append "." before each letter.
myText = "sample"
vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
result = ''
for letter in myText:
if letter not in vowels:
result = result + '.' + letter
print(result.lower())
# .s.m.p.l
Fian's answer is probably the best one. Here's my attempt:
text = 'audfijsdfmsomlasn'
vowels = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}
result = ''
for letter in text:
if letter in vowels:
result += '.'
result += letter
print(result)
Yet another way:
import re
myText = "sample"
result = '.' + '.'.join(list(re.sub('[aeiou]', "", myText, flags=re.I)))
print(result)
Explanation:
re.sub removes the not required letters (case insensitive = re.I)
list makes the string an array of characters
join places a dot in between
'.' + adds the missing dot in front of the first character
string = input()
vowels = ['a', 'A', 'i', 'I', 'o', 'O', 'u', 'U', 'e', 'E']
translation = string.maketrans({i: '' for i in vowels})
string = string.translate(translation)
result = ''
for letter in string:
result = result + '.' + letter
print(result.lower())

Iterating through list, ignoring duplicates

I've written a program that attempts to find a series of letters (toBeFound - these letters represent a word) in a list of letters (letterList), however it refuses to acknowledge the current series of 3 letters as it counts the 'I' in the first list twice, adding it to the duplicate list.
Currently this code returns "incorrect", when it should return "correct".
letterList= ['F','I', 'I', 'X', 'O', 'R', 'E']
toBeFound = ['F', 'I', 'X']
List = []
for i in toBeFound[:]:
for l in letterList[:]:
if l== i:
letterList.remove(l)
List.append(i)
if List == toBeFound:
print("Correct.")
else:
print("Incorrect.")
letterList and toBeFound are sample values, the letters in each can be anything. I can't manage to iterate through the code and successfully ensure that duplicates are ignored. Any help would be greatly appreciated!
Basically, you're looking to see if toBeFound is a subset of letterList, right?
That is a hint to use sets:
In [1]: letters = set(['F','I', 'I', 'X', 'O', 'R', 'E'])
In [2]: find = set(['F', 'I', 'X'])
In [3]: find.issubset(letters)
Out[3]: True
In [4]: find <= letters
Out[4]: True
(BTW, [3] and [4] are different notations for the same operator.)
I think this would solve your problem. Please try it and let me know
letterList= ['F','I', 'I', 'X', 'O', 'R', 'E']
toBeFound = ['F', 'I', 'X']
found_list = [i for i in toBeFound if i in letterList]
print("Correct" if toBeFound == found_list else "Incorrect")
You could make the initial list a set, but if you want to look up a word like 'hello' it wont work because you'll need both l's.
One way to solve this is to use a dictionary to check and see how we are doing so far.
letterList = ['H', 'E', 'L', 'X', 'L', 'I', 'O']
toBeFound = ['H', 'E', 'L', 'L', 'O']
# build dictionary to hold our desired letters and their counts
toBeFoundDict = {}
for i in toBeFound:
if i in toBeFoundDict:
toBeFoundDict[i] += 1
else:
toBeFoundDict[i] = 1
letterListDict = {} # dictionary that holds values from input
output_list = [] # dont use list its a reserved word
for letter in letterList:
if letter in letterListDict: # already in dictionary
# if we dont have too many of the letter add it
if letterListDict[letter] < toBeFoundDict[letter]:
output_list.append(letter)
# update the dictionary
letterListDict[letter] += 1
else: # not in dictionary so lets add it
letterListDict[letter] = 1
if letter in toBeFoundDict:
output_list.append(letter)
if output_list == toBeFound:
print('Success')
else:
print('fail')
How about this: (I tested in python3.6)
import collections
letterList= ['F','I', 'I', 'X', 'O', 'R', 'E']
toBeFound = ['F', 'I', 'X']
collections.Counter(letterList)
a=collections.Counter(letterList) # print(a) does not show order
# but a.keys() has order preserved
final = [i for i in a.keys() if i in toBeFound]
if final == toBeFound:
print("Correct")
else:
print("Incorrect")
If you're looking to check if letterList has the letters of toBeFound in the specified order and ignoring repeating letters, this would be a simple variation on the old "file match" algorithm. You could implement it in a non-destructive function like this:
def letterMatch(letterList,toBeFound):
i= 0
for letter in letterList:
if letter == toBeFound[i] : i += 1
elif i > 0 and letter != toBeFound[i-1] : break
if i == len(toBeFound) : return True
return False
letterMatch(['F','I', 'I', 'X', 'O', 'R', 'E'],['F', 'I', 'X'])
# returns True
On the other hand, if what you're looking for is testing if letterList has all the letters needed to form toBeFound (in any order), then the logic is much simpler as you only need to "check out" the letters of toBeFound using the ones in letterList:
def lettermatch(letterList,toBeFound):
missing = toBeFound.copy()
for letter in letterList:
if letter in missing : missing.remove(letter)
return not missing
As requested.
letterList= ['F','I', 'I', 'X', 'O', 'R', 'E']
toBeFound = ['F', 'I', 'X']
List = []
for i in toBeFound[:]:
for l in set(letterList):
if l== i:
List.append(i)
if List == toBeFound:
print("Correct.")
else:
print("Incorrect.")
This prints correct. I made the letterList a set! Hope it helps.
One simple way is to just iterate through toBeFound, and look for each element in letterList.
letterList= ['F','I', 'I', 'X', 'O', 'R', 'E']
toBeFound = ['F', 'I', 'X']
found = False
for x in letterList:
if x not in toBeFound:
found = False
break
if found:
print("Correct.")
else:
print("Incorrect.")

my code to remove vowels from a string is acting weird

So I wrote this code to remove the vowels from any string given.
it should work fine. And it actually does. Just not for all strings
which is weird why it would work for some strings and not for others
here's the code:
vowels = ["a", "e", "i", "o", "u"]
def anti_vowel(text):
text1 = list(text)
print text1
for i in text1:
if i.lower() in vowels:
text1.remove(i)
text2 = "".join(text1)
return text2
and here are the tests that I placed:
print anti_vowel("my name is Omar")
print anti_vowel("Hey look Words!")
print anti_vowel("Hey look more Words to look for!")
I tried placing print statements in the middle of the code to test it and I found something weird.
the for loop iterates about 3 or 4 times to remove one vowel.
I can't seem to know why
This weird case happens when 2 vowels are right next to each other. Basically, you are looping for each letter in the word, but when you remove the letter (if it is a vowel), then you shorten the length of the word, and therefore the next letter will have skipped over the real next letter. This is a problem when the letter being skipped is a vowel, but not when it is a consonant.
So how do we solve this? Well, instead of modifying the thing we're looping over, we will make a new string and modify it. So:
text2 = ""
for letter in text1:
if letter not in vowels:
text2 += letter
return text2
This can also be achieved with list comprehension:
return "".join ([letter for letter in text1 if letter not in vowels])
You don't have to convert the string to a list. Refer to this answer here:
Correct code to remove the vowels from a string in Python
Because the for statement checks through every letter within the list, even when it removes that vowel. Here's a quick example where it doesn't iterates 3-4 times to remove one vowel:
vowels = ["a", "e", "i", "o", "u"]
def anti_vowel(text):
text1 = list(text.lower())
text1 = [x for x in text1 if x not in vowels]
text2 = "".join(text1)
return (text2)
print anti_vowel("my name is Omar")
print anti_vowel("Hey look Words!")
print anti_vowel("Hey look more Words to look for!")
I am using Python 2.7. I modified your code slightly as follows,
vowels = 'aeiou'
def anti_vowel(text):
text1 = list(text)
print text1
for i in text:
if i.lower() in vowels:
text1.remove(i)
text2 = "".join(text1)
return text2
print anti_vowel("my name is Omar")
#['m', 'y', ' ', 'n', 'a', 'm', 'e', ' ', 'i', 's', ' ', 'O', 'm', 'a', 'r']
#my nm s mr
print anti_vowel("Hey look Words!")
#['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
#Hy lk Wrds!
print anti_vowel("Hey look more Words to look for!")
#['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'm', 'o', 'r', 'e', ' ', 'W', 'o', 'r', 'd', 's', ' ', 't', 'o', ' ', 'l', 'o', 'o', 'k', ' ', 'f', 'o', 'r', '!']
#Hy lk mr Wrds t lk fr!
I cannot duplicate your problem. The for loop sweeps through the input string once (one character by one character) and removes any vowel encountered. Perhaps you can post your output so we can debug.
This can be done without remove()
#!python2
def anti_vowel(text):
vowels = ["a", "e", "i", "o", "u"]
s1 = ''
for i in text:
if i.lower() in vowels:
pass
else:
s1 += i
return s1
print anti_vowel("my name is Omar")
print anti_vowel("Hey look Words!")
print anti_vowel("Hey look more Words to look for!")

Splitting the letters of a word based on conditions, and returning in a list (Python)

vowels = "aeiou"
consonants = "bcdfghjklmnpqrstvwxyz"
I'm trying to make a function that would only return constants followed by vowels in a list.
So for example:
f("therapist")
>>>["he", "ra", "pi"]
f("apple")
>>>["le"]
So it's only when a vowel follows a consonant and it returns both the consonant and the vowel in a list.
I was thinking it would be something along the lines of:
def f(word):
for consonant in word:
for vowel in word:
But I don't know how to work with the order and test whether the vowel is after the consonant. Thanks in advance
You can use enumerate with a starting index of 1, checking if the current ele is a consonant and the next chaarcter word[i] is a vowel.
def f(word):
vowels = {"a", "e", "i", "o", "u"}
consonants = {'t', 'b', 'm', 'h', 'y', 'w', 'z', 'p', 'v', 'd', 'g', 'k', 'j', 'n', 'r', 'q', 'x', 'c', 's','f', 'l'}
return [ele + word[i] for i, ele in enumerate(word[:-1], 1)
if word[i] in vowels and ele in consonants ]
Or using loops keep track of the last character and compare:
def f(word):
vowels = {"a", "e", "i", "o", "u"}
consonants = {'t', 'b', 'm', 'h', 'y', 'w', 'z', 'p', 'v', 'd', 'g', 'k', 'j', 'n', 'r', 'q', 'x', 'c', 's','f', 'l'}
pairs = []
it = iter(word)
# get first char
prev = next(it,"")
# iterate over the rest starting at the second char
for ch in it:
# compare prev and current
if prev in consonants and ch in vowels:
pairs.append(prev + ch)
# update prev
prev = ch
return pairs
You can use regex :
>>> import re
>>> def f(s):
... return re.findall(r'[bcdfghjklmnpqrstvwxyz][aeiou]',s)
...
>>> f('therapist')
['he', 'ra', 'pi']
Also you can use zip within a list comprehension :
>>> def f(s):
... return [''.join((i,j)) for i,j in zip(s,s[1:]) if i in 'bcdfghjklmnpqrstvwxyz' and j in 'aeiou']
...
>>> s='therapist'
>>> f(s)
['he', 'ra', 'pi']
Well, you could use a regular expression for this.
I think the real question is: "Does 'y' constitute as a vowel?"
import re
def f(word):
return re.findall('[bcdfghjklmnpqrstvwxyz][aeiou]', word)
print(f("therapist")) # Prints ['he', 'ra', 'pi']
Try this using re
import re
def f(word):
return re.findall(r"(?![aeiou$])\w[aeiou]",word)
>>>f('therapist')
['he', 'ra', 'pi']

Categories

Resources