Identify amount of upper and lower case letters in a string

Asked

Viewed 464 times

1

I need to check if a word has more upper case letters and replace the whole word for lower case only, also check if it has more lower case letters and replace the whole word for upper case. For example, the word "House" should be replaced by "house" and the word "Legal" by "LEGAL". If a word contains an equal number of upper and lower case letters, all upper case letters should be replaced by lower case letters, for example the word "Pagode" should be replaced by "pagode". What I did only returns the word in lowercase but not uppercase. What I have to change?

palavra = input()

if any(x.islower() for x in palavra) > any(x.isupper() for x in palavra):
    print(palavra.lower())
elif any(x.islower() for x in palavra) < any(x.isupper() for x in palavra):
    print(palavra.upper())
elif any(x.islower() for x in palavra) == any(x.isupper() for x in palavra):
    print(palavra.lower())

3 answers

1


According to the documentation of any:

Returns True if any element of iterable is true. If iterable is empty, returns False.

As this function returns a boolean, it makes no sense to compare them as you are doing in each of the three ifs. Each any simply checks that each list satisfies, at least once, the condition of the predicate.

Therefore, you must count how many upper case letters and how many lower case letters that word has in order to make the comparison once it is in possession of those two numbers.

One option would be to change the any for sum, which returns the sum of all the elements in the list. The list of boolean is correctly summed since boolean is a subclass of int (which means that True amounts to 1 and False, to 0). Learn more here.

In that case, we shall have:

word = input("Uma palavra: ")

if sum(x.islower() for x in word) > sum(x.isupper() for x in word):
    print(word.lower())
elif sum(x.islower() for x in word) < sum(x.isupper() for x in word):
    print(word.upper())
elif sum(x.islower() for x in word) == sum(x.isupper() for x in word):
    print(word.lower())

The problem is, just to count, we’d have to sweep the string twice, once for each sum.

If this is a problem, you can make use of a counter, so just iterate (to count) once. Something like this:

def count_casing(word):
    upper = lower = 0

    for char in word:
        if char.isupper():
            upper += 1
        elif char.islower():
            lower += 1

    return upper, lower


word = input("Uma palavra: ")

upper, lower = count_casing(word)
if upper > lower:
    print(word.upper())
else:
    print(word.lower())

Note that upper and lower also travel the string again. Therefore, the above code "scans" the string twice.

Also note that the last if (in case the number of upper and lower case letters are equal) is not necessary, since the else covers that case as well. :)

  • 1

    This Javascript mania of creating object for everything :-) In Python you can create the counters separately and return them in a tuple: https://ideone.com/tfTarV

  • 1

    @hkotsubo, indeed, becomes much more succinct without the dictionary; it was in fact a language addiction. :Thank you very much for the suggestion, I edited the reply.

  • 1

    Just to be pedantic, sum does not convert booleans into numbers. Actually, according to documentation, Boolean is a sub-type of int, so much so that isinstance(True, int) returns True (and True and False are equivalent to 1 and 0 respectively - so much so that True == 1 and False == 0 are true, and remembering that Python does not do the crazy coercion of JS). See more here and here

0

One possibility would be to "play" with internal functions and libraries.

Let’s see how the map and class Counter

map

The function map applies a function to each element of an eternal object. The syntax of this is':

result = map(function, iterable)

The result is like iterator

Counter

The Counter is used to count the frequency of the elements in an iterable.

c = Counter(iterable)

That said, let’s go for the solution

# Carrega o método Counter da library collections
from collections import Counter

# Define a palavra
palavra = "PaGoDe"

# Identificando se a letra é minúscula ou maiúscula 
def identifica_case(letra):
    if letra.islower():
        return "l"
    elif letra.isupper():
        return "U"

# Criando o mapa
mapa = map(identifica_case, palavra)

As stated above, the map returns an iterator, if you want to see the contents of it, you can just run a print(list(mapa))

The result of this word PaGoDe would be:

['U', 'I', 'U', 'I', 'U', 'I']

c = Counter(mapa)

The print of c for this example would be:

Counter({'U': 3, 'I': 3})

maior_qtd = max([c["l"], c["U"]])

if c["U"] == maior_qtd:
    print(palavra.lower())
else:
    print(palavra.upper())

Note The goal of creating the variable maior_qtd, by means of the max, is due to the fact that the word may contain other characters (e.g..: "Python!!!!!!!!!!!!!")

Note The class Counter has the method most_common(N), but I believe that in this case it would not help. (N is the amount of items you want to return). This is very used for the Top N

I hope I’ve helped

0

Another interesting way to resolve this issue is to implement the following code:

def forma_letras(v):

    upper = lower = 0
    for d in v:
        if d.isupper():
            upper += 1
        else:
            lower += 1

    if upper >= lower:
        return v.lower()
    return v.upper()


print(forma_letras(''.join(input('Digite uma palavra: '))))

Note that when we execute this code, we must enter a word. From that moment on the string is passed as parameter to the function forma_letras(v). Getting there, the block for will traverse this string and, with the help of the block 1st block if will verify whether the letter of the respective interaction is upper. If positive, upper is incremented. If negative, Lower is incremented. Then, the 2nd block if check whether upper is greater than or equal to Lower. If so, the return of the function will display all letters in lowercase. If not, the function return will display all letters in capital letters.

Browser other questions tagged

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