Displaying message of no number read and accepting different types of input

Asked

Viewed 74 times

1

I have the following code:

def maior(colecao):
    if len(colecao) > 1:
        r = maior(colecao[1:])
        if r[0] < colecao[0]:
            r[0] = colecao[0]
    elif len(colecao) == 1:
        r = [colecao[0]]
    else:
        r = [None]
    return r


def imprimir(colecao):
    if len(colecao) != 0:
        print("Maior Valor Encontrado:", colecao[0])
    else:
        print("nenhum número foi lido!!!")


valores = input().split()
for i in range(len(valores)):
    valores[i] = float(valores[i])

imprimir(maior(valores))

When I type values, for example: 1, 10, 50, 5, it has the right output:

inserir a descrição da imagem aqui

When I enter no value and give ENTER, it does not report that no number has been read, and has that output:

inserir a descrição da imagem aqui

I would like it to display the correct message when no number is read ("no number has been read!!!") and also that in addition to accepting entry 1, 10, 50, 5 accept also input:

1 
10
50
5

And I can’t implement.

3 answers

2


Your problem is that maior is returning a list instead of a single element. And then, just function imprimir test by None.

def maior(colecao):
    if len(colecao) == 0:
        return None
    if len(colecao) == 1:
        return colecao[0]
    r = maior(colecao[1:])
    if r < colecao[0]:
        r = colecao[0]
    return r

def imprimir(e):
    if e is None:
        print("nenhum número foi lido!!!")
    else:
        print("Maior Valor Encontrado:", e)

valores = input().split()
for i in range(len(valores)):
    valores[i] = float(valores[i])

imprimir(maior(valores))

If for some reason you want to insist that maior should return a list, just change the [None] for []:

def maior(colecao):
    if len(colecao) > 1:
        r = maior(colecao[1:])
        if r[0] < colecao[0]:
            r[0] = colecao[0]
    elif len(colecao) == 1:
        r = [colecao[0]]
    else:
        r = []
    return r


def imprimir(colecao):
    if len(colecao) != 0:
        print("Maior Valor Encontrado:", colecao[0])
    else:
        print("nenhum número foi lido!!!")


valores = input().split()
for i in range(len(valores)):
    valores[i] = float(valores[i])

imprimir(maior(valores))

Although I think it’s better than the code of maior were so, for being more direct:

def maior(colecao):
    if len(colecao) == 0:
        return r
    if len(colecao) == 1:
        return [colecao[0]]
    r = maior(colecao[1:])
    if r[0] < colecao[0]:
        r[0] = colecao[0]
    return r

1

If you want the input to accept both numbers on the same line and on different lines, one option is to loop this way:

numeros = []
while True:
    valores = input().split();
    if not valores: # lista vazia, nenhum número foi digitado, encerrar a leitura
        break
    for s in valores:
        try:
            # tenta transformar em número
            numeros.append(float(s))
        except ValueError:
            pass # não é número, ignorar (ou pode imprimir uma mensagem, se quiser)

When the user types something, I do the split. If the resulting list is empty, it means that it has not typed anything (or typed only spaces), and then I exit the loop with break.

If something was typed, I go through the values and try to turn them into numbers. If the user type something that is not a number (like abc, for example), I am ignoring (but you could print a message, exit the loop and terminate the program, etc.). With this the input can have multiple lines, and in each row can have one or more numbers.


Then, to find the largest number, you do not need to use a recursive function (unless it is an exercise that the teacher asked to be recursive, and in this case can be based on victor’s response, which explains how to fix it). Instead, you can simply make a simple loop:

def maior(numeros):
    r = numeros[0]
    for n in numeros:
        if n > r:
            r = n
    return r

Although the above loop has a redundancy: I start by initiating r with the first element of the list and then go through the whole list, comparing each element of it to know which one is bigger. This means that in the first iteration I am comparing the first element with itself, which would be redundant. Anyway, you could start the loop from the second element with for i in range(1, len(numeros)). And she too could return None if the list is empty, as already suggested in victor’s response.

But if this is not an exercise that you need to manually implement the algorithm, just use the function max:

# encontrar o maior número da lista
maior = max(numeros)

Another detail is that you are using float to convert the string to number, which implies that the user will be able to type numbers as 1.5, for example. But if you only want whole numbers (with no decimal places), just swap with int.


In short, the code could look like this:

numeros = []
while True:
    valores = input().split();
    if not valores: # lista vazia, nenhum número foi digitado, encerrar a leitura
        break
    for s in valores:
        try:
            # tenta transformar em número
            numeros.append(float(s))
        except ValueError:
            pass # não é número, ignorar

if numeros: # lista não é vazia
    print("Maior valor encontrado: {}".format(max(numeros)))
else: # lista vazia, nem tento encontrar o maior número
    print("Nenhum número foi lido")

There is no reason why the largest number should be returned in a list that only has one element, and then you should test the size of this list. Just check before if the list of all numbers is empty (if it is, then there is no reason to try to find the highest value, and it already falls right into the else).


In the above example I used the function max to find the largest number. But if you really want to use your own function to find the largest, and also the function that prints the number, it would look like this:

numeros = []
while True:
    ... igual ao código anterior

def maior(numeros):
    if not numeros: # lista vazia, retornar None
        return None
    r = numeros[0]
    for n in numeros:
        if n > r:
            r = n
    return r

def imprimir(n):
    if n is None:
        print("Nenhum número foi lido")
    else:
        print("Maior valor encontrado: {}".format(n))

imprimir(maior(numeros))

0

First, put what you want to 'split' into the split() function: Change

    valores = input().split()

for

    valores = input().split(',')

Then make a if in case the input comes empty:

    if valores == ['']:
    print("Nenhum valor lido")
    return

The code will look something like this:

def maior(colecao):
    if len(colecao) > 1:
        r = maior(colecao[1:])
        if r[0] < colecao[0]:
            r[0] = colecao[0]
    elif len(colecao) == 1:
        r = [colecao[0]]
    else:
        r = [None]
    return r


def imprimir(colecao):
    if len(colecao) != 0:
        print("Maior Valor Encontrado:", colecao[0])
    else:
        print("nenhum numero foi lido!!!")


valores = input("Digite o valor").split(',')
if valores == ['']:
    print("Nenhum valor lido")
    return
for i in range(len(valores)):
    valores[i] = float(valores[i])

imprimir(maior(valores))

Browser other questions tagged

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