Doubt exercise with lists

Asked

Viewed 176 times

4

Follow the problem:

Create a Python function that takes a list and returns how many numbers are positive. If a list element is not an integer or real number (float), the function must stop and return an error stating that the list can only have elements with numerical values.

I managed to make a code, but it always runs until the end, the intention is that if the list entry is a string the code should stop and return only the error message.

Follow the code I wrote:

lista = input('Digite uma lista de numeros')  
def maior_que_zero(x):  
    if not type(x)is float and not type (x) is int:  
        print('Erro digite somente numeros')  
    elif (x) > 0:  
        return True  
    elif (x) < 0:   
        return False  
lista_valida = filter(maior_que_zero, lista)  
print 'Numeros positivos' + ' '+ str(len (lista_valida))  
  • Your lista will always be a string, because the return of the function input is that kind.

  • @Andersoncarloswoss to some way to change that?

3 answers

5

First, let’s create a function called main, which will be the entry point of your program, and put a if ensuring that the function will only be called when the script runs directly.

def main():
    pass

if __name__ == '__main__':
    main()

All right, now we can remove that pass and then write the program itself. The code I will show from here should be placed inside the function main.

At first, let’s initialize the positive number counter.

contagem_positivos = 0

Then we will ask the user to type in the input.

entrada = input('Digite uma lista de numeros, separada por espaços: ')

The line is a string, not a list. You need to call the method .split to break the string into whitespace and transfer it to a list of strings.

lista = entrada.split()

That is, if the user informed 1 0 -3 2, the return of .split will be ['1', '0', '-3', '2'] (note that this is a list of strings, not numbers!)

Once this is done, let’s iterate through each element of the list.

for elemento in lista:

Inside the loop, we try to convert each element to a number. If the conversion does not work, we print the error and close the program.

    try:
        numero = float(elemento)
    except ValueError:
        print('Erro: Somente números')
        return

If the conversion works, we check if the number is positive and, if it is, we increase the counter.

    if numero > 0:
        contagem_positivos += 1

Ready. After the loop, simply display the counter contents.

print('Quantidade de números positivos:', contagem_positivos)

Follow the full code.

def main():
    contagem_positivos = 0

    entrada = input('Digite uma lista de numeros, separada por espaços: ')

    lista = entrada.split()

    for elemento in lista:
        try:
            numero = float(elemento)
        except ValueError:
            print('Erro: Somente números')
            return

        if numero > 0:
            contagem_positivos += 1

    print('Quantidade de números positivos:', contagem_positivos)

if __name__ == '__main__':
    main()

Additional reading:

3

Although the two other answers follow the same reasoning as the code shown in the question and contain algorithms to count positive numbers in a list, neither of them meets the question statement.

Let’s see, in parts:

Create a Python function that receives a list

The purpose of the question is to create a function that has a parameter: a list.

The text does not ask to receive user data or to criticize if the value is numerical before calling this function, let alone receive data within of function.

And continues:

and returns how many numbers are positive

Again, the question does not ask the function to print how many numbers are positive. All it needs to do is return the counting of positive numbers.

Finally:

If a list element is not an integer or real number (float), the function must stop and return an error stating that the list can only have elements with numerical values.

In this case, it is unclear whether the "error" is an object of the type Error or a String, but considering that the code that will call the function knows that it can return an error, it is more convenient to use the principle of encapsulation and return an object of type Error. Also, any function Refactoring to include more information in the error return would be transparent to all lines calling this function.

Why is this important?

If this function is called from a unit test, none of the other answers will work.

But it’s not just that...

There’s a saying that says: "The computer doesn’t do what you want, it does what you say!"

Similarly, the programmer needs to understand the problem and be able to follow the given instructions.

The "gold plating", or "golden pill" in good Portuguese, is one of the causes of the failure of many software projects.

As a last thought, I suggest simplicity, citing Zen Of Python:

Simple is Better than Complex.

Readability Counts.

Based on all this, my answer is this:

def positivos(lista):
    try:
        positivos = [float(i) for i in lista if i > 0]
    except TypeError:
        raise TypeError('A lista só pode ter elementos com valores numéricos.')
    return len(positivos)

This answer uses a list comprehension to reduce the original list to one with only positive numbers.

The function float(i) ensures that the number is integer or real, or generates a Typeerror;

For each value of the list for i in lista;

If the value is positive if i > 0.

The return is the size of the list of positive numbers, ie the amount. return len(positivos)

Some test entries:

print(positivos([-1, 0, 1]))
print(positivos([-1, 0]))
print(positivos([-1, 0, 'a']))

1

One of the correct ways to solve this issue is to use the following algorithm...

def quantidade_positivos(numeros):
    cont = 0
    for x in numeros:  
        if x > 0:
            cont += 1  

    print(f'\033[32mA quantidade de números positivos é: {cont}\033[m')


while True:
    try:
        n = int(input('Desejas inserir quantos valores? '))
        break
    except ValueError:
        print('\033[31mValor INVÁLIDO! Digite apenas números inteiros!\033[m')

todos_numeros = list()
for c in range(1, n + 1):
    while True:
        try:
            v = float(input(f'Digite o {c}º valor: '))
            break
        except ValueError:
            print('\033[31mValor INVÁLIDO! Digite apenas números reais!\033[m')
    todos_numeros.append(v)

quantidade_positivos(todos_numeros)

Note that when we run this algorithm we receive the message Desejas inserir quantos valores?. Right now we must enter a number inteiro representing the amount of values we will insert in the list.

After that we received the message Digite o 1º valor: . At this point we must enter the first value. Then we must enter the other values.

OBSERVATION 1

During insertion of values, the block try except checks whether the entered values are actually real numbers. If so, the value will be added in the list todos_numeros. Otherwise we will receive the message Valor INVÁLIDO! Digite apenas números reais!.

After we have entered, correctly all values, the list will be sent to the function quantidade_positivos. Arriving in this role, the list will be covered by for and all positive values will be counted, accumulating their count in the variable cont.

Subsequently, the function quantidade_positivos displays the amount of positive numbers in the list.

OBSERVATION 2

To represent the number 2 as positive just type 2, whereas to represent the number 2 as negative just type -2.

Browser other questions tagged

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