Indicate whether a character is a vowel or a consonant

Asked

Viewed 6,866 times

2

Write the function vogal which takes a single character as parameter and returns True if it is a vowel and False if it is a consonant.

Note that:

  • vogal("a") must return True
  • vogal("b") must return False
  • vogal("E") must return True

I tried to put this little code but it didn’t work:

v= str("a"),("e"),("i"),("o"),("u")
def vogal (v):
    if v == ("a")("e")("i")("o")("u"):
        return true
    else:
        return false 
  • 1

    And vogal('á'), with the accented, should return what?

5 answers

10

Problems

The returns you have are not right:

return true
...
return false

True and False take the first letter uppercase. As has gives error of execution because neither true nor false exist.

This comparison is not right either:

v == ("a")("e")("i")("o")("u")

It’s like I’m wearing the "a" as a function it does "a"("e"). And so it doesn’t compare to all the values as I would be imagining. Maybe I wanted to do this:

if v == "a" or v == "e" or v == "i" or v == "o" or  v =="u":

That although not very idiomatic would already work.

Solution

The simplest is to even use the operator in testing with a string that contains only vowels. This makes your code very simple and easy to read:

def vogal (v):
    if v in "aeiou": # aqui testa com o operador in
        return True
    else:
        return False

Now it gives you the expected result:

print(vogal('e')) # True
print(vogal('b')) # False

See the code running on Ideone

It even manages to turn the function into a line, although generally this is already a style for more experienced programmers:

def vogal (v):
    return v in "aieou"

To also consider capital letters, just inform them on string:

def vogal(v):
    return v in "aeiouAEIOU"

Or use the method lower to always convert the input to lowercase:

def vogal(v):
    return v.lower() in "aeiou"

1

Just complementing, and being a little pedantic about the title ("Indicate whether a character is a vowel or a consonant"): I understand that the function should return True if you receive a vowel, and False if you receive a consonant, but what if it receives a string like '&', '2' or ','? Must return False also? Because in these cases, the characters are not vowels or consonants, so I understand that should not return True nor False - maybe throw an exception then?

Anyway, one option would be to:

def vogal_ou_consoante(letra):
    letra = letra.lower()
    if letra in ('a', 'e', 'i', 'o', 'u'):
        return True
    elif letra in ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'):
        return False
    else:
        raise ValueError('Não é vogal nem consoante')

print(vogal_ou_consoante('a')) # True
print(vogal_ou_consoante('B')) # False
print(vogal_ou_consoante('2')) # ValueError

Another detail is that I used tuples instead of strings on operator in. Of course if the string is 'a', then do letra in 'aeiou' works. But what if we have this:

def vogal(v):
    return v.lower() in "aeiou"

print(vogal('eio')) # True

Note that if the string is 'eio', the return is also True, since the operator in, when applied to strings, checks if one string is substring the other.

It’s okay that 'eio' only has vowels, but if the goal is to verify that a string of any size contains only vowels, then it should also validate 'oi' and 'uia', but these cases return False. So if we want the function to validate only if the string has only one character (and that character must be vowel or consonant), then we should use the first solution above with ('a', 'e', 'i', 'o', 'u').


And the accents?

If I have the string 'á' (letter "a" with acute accent), it is also a vowel, right? But the above function only considers letters not accented.

A solution would be to add the accented letters in the options, something like letra in ('a', 'e', 'i', 'o', 'u', 'á', 'é', 'í', ... ) (not forgetting to put options in the consonants as well, to include characters such as 'ç' and the 'ñ').

Another option is to normalize the strings to the NFD form. To understand in detail what this is, I suggest you read here, here and here. But in summary, when normalizing to NFD, letters like "á" are decomposed into two characters: the letter "a" (without accent) and the own accent ("") - the same goes for consonants such as "ç", which is broken down into two characters: the letter "c" and a cedilla.

Therefore, it would be enough to normalize the string and take the first character (because the normalization in NFD ensures that the letter without accent is always placed before the accent). For this, we use the module unicodedata:

from unicodedata import normalize

def vogal_ou_consoante(letra):
    if len(letra) == 0:
        raise ValueError('string vazia')

    letra = normalize('NFD', letra)[0].lower()
    if letra in ('a', 'e', 'i', 'o', 'u'):
        return True
    elif letra in ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'):
        return False
    else:
        raise ValueError('Não é vogal nem consoante')

print(vogal_ou_consoante('á')) # True
print(vogal_ou_consoante('Ç')) # False
print(vogal_ou_consoante('')) # ValueError

I included an extra check for the case where the string is empty (because there is no point normalizing and picking the first character), and in this case also throws an exception, since an empty string is neither vowel nor consonant.


There is only one detail: this implementation is kind of "naive", because as it always takes the first character, then it returns True if the string starts with an accented character (e.g., for the string 'ábaco', the above function returns True).

To correct this, we can check whether the second character onwards only has accents. For this we use combining, that checks if the character is a Combining (category in which accents fit):

from unicodedata import normalize, combining

def vogal_ou_consoante(letra):
    if len(letra) == 0:
        raise ValueError('string vazia')

    letra = normalize('NFD', letra)

    # se do segundo caractere em diante tiver algum que não é acento
    if not all(combining(c) for c in letra[1:]):
        raise ValueError('string tem mais de um caractere')

    letra = letra[0].lower()
    if letra in ('a', 'e', 'i', 'o', 'u'):
        return True
    elif letra in ('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'):
        return False
    else:
        raise ValueError('Não é vogal nem consoante')

print(vogal_ou_consoante('á')) # True
print(vogal_ou_consoante('ábaco')) # ValueError

I use all to check that all characters after the second (letra[1:]) sane Combining. If any is not, launch the ValueError.


Of course, that doesn’t mean that the another answer is wrong. She only considered the simplest case - and given the description of the question, it was unclear whether she needed to be as strict about the criteria as I did above. Anyway, here are the options.

0

To complement the answers already posted, I present three solutions, one that includes "pure" vowels the second, "accented" vowels, and the third returns if it is vowel or consonant, all consider both upper and lower case:

Solution for "pure" vowels (without accentuation)

def is_pure_vowel(c): 
   return True if str.lower(c) in ('a','e','i','o','u') else False 

Solution considering any vowels ('accented' or not):

$ pip install unidecode

from unidecode import unidecode 
def is_vowel(c): 
   return True if unidecode(str.lower(c)) in ('a','e','i','o','u') else False 

Solution to return whether it is a vowel or a consonant

def vowel_or_consonant(c): 
    if not c.isalpha(): 
       return f'{c} não é uma letra do alfabeto' 
    return 'Vogal' if unidecode(str.lower(c)) in ('a','e','i','o','u') else 'Consoante' 

Obs.: The solutions do not check whether a numerical value has been entered (unless it is in quotes), but this can be contemplated with a simple Try.. except.

-2

def vogal(x):
    y= ['a','e','i','o','u']
    i=0
    prov = []
    for i in y:
        if i == x:
            prov.append(True)
        else:
            prov.append(False)
    if any(prov):
        print('True')
    else:
        print("False")
  • 3

    Hello Gilberto, besides adding only the code, we at stackoverflow suggest you explain it, beauty?

  • 1

    Put more information about the logic of how code works. Usually who asks wants to learn and not just acquire a piece of code.

-2

I was able to solve your question with the following code:

def vogal(v):
    vogais = {'a':'a', 'e':'e', 'i':'i', 'o':'o', 'u':'u'}
    try:
        if vogais[v]:
            print('True')
        else:
            print('False')
    except KeyError:
        print('False')

vogal('b')

The code consists of a vowel function and loads a variable with the vowel dictionary. So I thought it would be a good idea to assign exception handling to the code, because if you pass a consonant in the vowel function, e.g.: vogal('b') it will return a Keyerror.

  • thank you very much!!

  • I took the last line because already presented False at the beginning, I executed the code and was show ball :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.