If a string ends in a vowel of the following characters? - python

If a string doesn't end in s, x, ch, sh or if it doesn't ends in a vowel, then I need to add a 's'. This works for tell and eat but doesn't work for show. I am not able to figure out why.
This is the code I wrote:
if not re.match(".*(s|x|ch|sh)",s):
if re.match(".*(a|e|i|o|u)",s):
s = s+'s'
return s
else:
return s

Use endswith instead. It takes a single string, or a tuple of strings, and returns True if the string has any of the given arguments as a suffix.
cons = ('s', 'x', 'ch', 'sh')
vowels = ('a', 'e', 'i', 'o', 'u')
if not s.endswith(cons + vowels):
s += 's'
return s

You need $ at the end of your regex if you only want to match the end of the string.

Related

write a code to replace 'the' with 'a' or 'an' using the vowels grammar

using simple python (no library using) to create function get string and then return that string with replace the with a or an using the grammar condition
i have written this code but whatever i write in the if condition it skips it and go to else
def replaceThe(txt: str) -> str:
vowels = ('a', 'e', 'i', 'o', 'u')
word=('a-z')
if txt== :
return(txt.replace('the', 'a'))
else:
return(txt.replace('the', 'an'))
well i left the txt condition empty cause i don't know what to write
Here is a naive implementation using the text splitted as words:
def replaceThe(txt: str) -> str:
vowels = {'a', 'e', 'i', 'o', 'u'}
words = txt.split()
for i, w in enumerate(words):
if w == 'the' and i<len(words)-1:
words[i] = 'an' if words[i+1][0] in vowels else 'a'
return ' '.join(words)
replaceThe('this is the test of the algorithm')
# 'this is a test of an algorithm'
NB. I kept the logic minimal, it doesn't handle case, punctuation, etc. I leave it to you to implement it!

Recreating the strip() method using list comprehensions but output returns unexpected result

I am trying to 'recreate' the str.split() method in python for fun.
def ourveryownstrip(string, character):
newString = [n for n in string if n != character]
return newString
print("The string is", ourveryownstrip(input("Enter a string.`n"), input("enter character to remove`n")))
The way it works is that I create a function that passes in two arguments: 1) the first one is a string supplied, 2) the second is a a string or char that the person wants to remote/whitespace to be moved from the string. Then I use a list comprehension to store the 'modified' string as a new list by using a conditional statement. Then it returns the modified string as a list.
The output however, returns the entire thing as an array with every character in the string separated by a comma.
Expected output:
Boeing 747 Boeing 787
enter character to removeBoeing
The string is ['B', 'o', 'e', 'i', 'n', 'g', ' ', '7', '4', '7', ' ', 'B', 'o', 'e', 'i', 'n', 'g', ' ', '7', '8', '7']
How can I fix this?
What you have set up is checking each individual character in a list and seeing if it matches 'Boeing' which will never be true so it will always return the whole input. It is returning it as a list because using list comprehension makes a list. Like #BrutusForcus said this can be solved using string slicing and the string.index() function like this:
def ourveryownstrip(string,character):
while character in string:
string = string[:string.index(character)] + string[string.index(character)+len(character):]
return string
This will first check if the value you want removed is in your string. If it is then string[:string.index(character)] will get all of the string before the first occurrence of the character variable value and string[string.index(character)+len(character):] will get everything in the string after the first occurrence of the variable value. That will keep happening until the variable value doesn't occur in the string anymore.

Why does this function result in ['h', '-', '-', '-', '-']?

The function hangman_guessed(guessed, secret) is supposed to take a string of guessed characters and a list of "secret" characters.
The function checks every character in the secret list and compares it with each character in the guessed character string to check if the character is in both. If the characters are not the same then the function places a - in a temporary list equal to the secret list (so that we can still compare other characters in the guessed list to the original secret list later).
def hangman_guessed(guessed, secret):
modified = secret
for i1 in range(len(secret)):
for i2 in range(len(guessed)):
if secret[i1] == guessed[i2]:
modified[i1] = secret[i1]
break
else:
modified[i1] = '-'
return modified
For example, when I run hangman_guessed('hl', ['h','e','l','l','o']), it should return ['h', '-', 'l', 'l', '-'], but currently it returns ['h', '-', '-', '-', '-'].
The problem here is that only the first character in the guessed list is considered, but I do not know why. It this case, it is expected that the program checks over the 'l' characters in ['h','e','l','l','o']) and sets the corresponding characters in the temporary list modified to -, but to my understanding after the for loop runs again and checks the original secret list for l characters it should overwrite the - in the modified list and the result should have the 'l' characters rather than the - characters.
A list-comprehension is perfectly suited to what you want to do. We want to create a list of each character (let this be i) in secret if i is in guessed else we want to have a hyphen ("-").
def hangman_guessed(guessed, secret):
return [i if i in guessed else "-" for i in secret]
and a test to show it works:
>>> hangman_guessed('hl', ['h','e','l','l','o'])
['h', '-', 'l', 'l', '-']
As you get more used to the flow of Python, you will find that comprehensions in general are extremely useful as well as being very readable for a whole variety of things.
If for some reason however, you had to use nested for-loops and weren't allowed to use the really simple in operator, then you need to / can make a couple of corrections to your current code:
make a copy of the secret list first
iterate through the characters in guessed, rather than the indexes
After making these two corrections, the function will look something like:
def hangman_guessed(guessed, secret):
modified = secret[:]
for i in range(len(secret)):
for g in guessed:
if secret[i] == g:
modified[i] = secret[i]
break
else:
modified[i] = '-'
return modified
which now works:
>>> hangman_guessed('hl', ['h','e','l','l','o'])
['h', '-', 'l', 'l', '-']

Is there a better way to check for vowels in the first position of a word?

I'm trying to check for a vowel as the first character of a word. For my code I currently have this:
if first == 'a' or first == 'e' or first == 'i' or first == 'o' or first == 'u':
I was wondering is there a much better way to do this check or is this the best and most efficient way?
You can try like this using the in:
if first.lower() in 'aeiou':
or better like
if first.lower() in ('a', 'e', 'i', 'o', 'u'):
Better create a set of vowels, like this
>>> vowels = set('aeiouAEIOU')
>>> vowels
set(['a', 'A', 'e', 'i', 'o', 'I', 'u', 'O', 'E', 'U'])
and then check if first is one of them like this
>>> if first in vowels:
...
Note: The problem with
if first in 'aeiouAEIOU':
approach is, if your input is wrong, for example, if first is 'ae', then the test will fail.
>>> first = 'ae'
>>> first in 'aeiouAEIOU'
True
But ae is clearly not a vowel.
Improvement:
If it is just a one-time job, where you don't care to create a set beforehand, then you can use if first in 'aeiouAEIOU': itself, but check the length of first first, like this
>>> first = 'ae'
>>> len(first) == 1 and first in 'aeiouAEIOU'
False
Here is the regex approach:
from re import match
if match(r'^[aieou]', first):
...
This regular expression will match if the first character of "first" is a vowel.
If your function is returning boolean value then easiest and simplest way will be
`bool(first.lower() in 'aeiou')`
Or
return first.lower() in 'aeiou'

Finding consecutive consonants in a word

I need code that will show me the consecutive consonants in a word. For example, for "concertation" I need to obtain ["c","nc","rt","t","n"].
Here is my code:
def SuiteConsonnes(mot):
consonnes=[]
for x in mot:
if x in "bcdfghjklmnprstvyz":
consonnes += x + ''
return consonnes
I manage to find the consonants, but I don't see how to find them consecutively. Can anybody tell me what I need to do?
You can use regular expressions, implemented in the re module
Better solution
>>> re.findall(r'[bcdfghjklmnpqrstvwxyz]+', "concertation", re.IGNORECASE)
['c', 'nc', 'rt', 't', 'n']
[bcdfghjklmnprstvyz]+ matches any sequence of one or more characters from the character class
re.IGNORECASE enables a case in sensitive match on the characters. That is
>>> re.findall(r'[bcdfghjklmnpqrstvwxyz]+', "CONCERTATION", re.IGNORECASE)
['C', 'NC', 'RT', 'T', 'N']
Another Solution
>>> import re
>>> re.findall(r'[^aeiou]+', "concertation",)
['c', 'nc', 'rt', 't', 'n']
[^aeiou] Negated character class. Matches anything character other than the one in this character class. That is in short Matches consonents in the string
+ quantifer + matches one or more occurence of the pattern in the string
Note This will also find the non alphabetic, adjacent characters in the solution. As the character class is anything other than vowels
Example
>>> re.findall(r'[^aeiou]+', "123concertation",)
['123c', 'nc', 'rt', 't', 'n']
If you are sure that the input always contain alphabets, this solution is ok
re.findall(pattern, string, flags=0)
Return all non-overlapping matches of pattern in string, as a list of strings.
The string is scanned left-to-right, and matches are returned in the order found.
If you are curious about how the result is obtained for
re.findall(r'[bcdfghjklmnpqrstvwxyz]+', "concertation")
concertation
|
c
concertation
|
# o is not present in the character class. Matching ends here. Adds match, 'c' to ouput list
concertation
|
n
concertation
|
c
concertation
|
# Match ends again. Adds match 'nc' to list
# And so on
You could do this with regular expressions and the re module's split function:
>>> import re
>>> re.split(r"[aeiou]+", "concertation", flags=re.I)
['c', 'nc', 'rt', 't', 'n']
This method splits the string whenever one or more consecutive vowels are matched.
To explain the regular expression "[aeiou]+": here the vowels have been collected into a class [aeiou] while the + indicates that one or more occurrence of any character in this class can be matched. Hence the string "concertation" is split at o, e, a and io.
The re.I flag means that the case of the letters will be ignored, effectively making the character class equal to [aAeEiIoOuU].
Edit: One thing to keep in mind is that this method implicitly assumes that the word contains only vowels and consonants. Numbers and punctuation will be treated as non-vowels/consonants. To match only consecutive consonants, instead use re.findall with the consonants listed in the character class (as noted in other answers).
One useful shortcut to typing out all the consonants is to use the third-party regex module instead of re.
This module supports set operations, so the character class containing the consonants can be neatly written as the entire alphabet minus the vowels:
[[a-z]--[aeiou]] # equal to [bcdefghjklmnpqrstvwxyz]
Where [a-z] is the entire alphabet, -- is set difference and [aeiou] are the vowels.
If you are up for a non-regex solution, itertools.groupby would work perfectly fine here, like this
>>> from itertools import groupby
>>> is_vowel = lambda char: char in "aAeEiIoOuU"
>>> def suiteConsonnes(in_str):
... return ["".join(g) for v, g in groupby(in_str, key=is_vowel) if not v]
...
>>> suiteConsonnes("concertation")
['c', 'nc', 'rt', 't', 'n']
A really, really simple solution without importing anything is to replace the vowels with a single thing, then split on that thing:
def SuiteConsonnes(mot):
consonnes = ''.join([l if l not in "aeiou" else "0" for l in mot])
return [c for c in consonnes.split("0") if c is not '']
To keep it really similar to your code - and to add generators - we get this:
def SuiteConsonnes(mot):
consonnes=[]
for x in mot:
if x in "bcdfghjklmnprstvyz":
consonnes.append(x)
elif consonnes:
yield ''.join(consonnes)
consonnes = []
if consonnes: yield ''.join(consonnes)
def SuiteConsonnes(mot):
consonnes=[]
consecutive = '' # initialize consecutive string of consonants
for x in mot:
if x in "aeiou": # checks if x is not a consonant
if consecutive: # checks if consecutive string is not empty
consonnes.append(consecutive) # append consecutive string to consonnes
consecutive = '' # reinitialize consecutive for another consecutive string of consonants
else:
consecutive += x # add x to consecutive string if x is a consonant or not a vowel
if consecutive: # checks if consecutive string is not empty
consonnes.append(consecutive) # append last consecutive string of consonants
return consonnes
SuiteConsonnes('concertation')
#['c', 'nc', 'rt', 't', 'n']
Not that I'd recommend it for readability, but a one-line solution is:
In [250]: q = "concertation"
In [251]: [s for s in ''.join([l if l not in 'aeiou' else ' ' for l in q]).split()]
Out[251]: ['c', 'nc', 'rt', 't', 'n']
That is: join the non-vowels with spaces and split again on whitespace.
Use regular expressions from re built-in module:
import re
def find_consonants(string):
# find all non-vovels occuring 1 or more times:
return re.findall(r'[^aeiou]+', string)
Although I think you should go with #nu11p01n73R's answer, this will also work:
re.sub('[AaEeIiOoUu]+',' ','concertation').split()

Categories