if and logical connectives

Asked

Viewed 183 times

3

I need to find the fewer number and the second to smallest number of five typed numbers.

But this strange fact is happening:

#Subtrair o menor numero encontrado do numero digitado
dif1 = n1 - menor
dif2 = n2 - menor
dif3 = n3 - menor
dif4 = n4 - menor
dif5 = n5 - menor

#O menor resultado diferente de zero é o segundo menor numero
print(dif1, dif2, dif3, dif4, dif5)

#O erro se encontra aqui!
if (dif1>0) & (dif1<dif2) & (dif1<dif3) & (dif1<dif4) & (dif1<dif5):
    print("n1 é o segundo menor numero")

if (dif2>0) & ((dif2<dif1) & (dif2<dif3) & (dif2<dif4) & (dif2<dif5)):
    print("n2 é o segundo menor numero")

if (dif3>0) & ((dif3<dif2) & (dif3<dif1) & (dif3<dif4) & (dif3<dif5)):
    print("n3 é o segundo menor numero")

if (dif4>0) & ((dif4<dif2) & (dif4<dif3) & (dif4<dif1) & (dif4<dif5)):
    print("n4 é o segundo menor numero")

if (dif5>0) & ((dif5<dif2) & (dif5<dif3) & (dif5<dif4) & (dif5<dif1)):
    print("n5 é o segundo menor numero")


print(menor)

If I declare only

if (dif1>0):
...
.

The print message is executed on the screen. In the same way if I declare:

if (dif1<dif2) & (dif1<dif3) & (dif1<dif4) & (dif1<dif5):
..
.

But if I declare the sentence complete:

if (dif1>0) & (dif1<dif2) & (dif1<dif3) & (dif1<dif4) & (dif1<dif5):
..
.

The print message does not appear at all! I also tried with if(dif1!=0) and other combination of relatives and nothing. And anyway in the terminal shows no error.

Would anyone know why?

PS.: It seems to me that this case also happens in other languages.

  • Do you need to do manual like this? Because if you ordered the numbers and took only the first two you would have the two smaller ones.

3 answers

6

In Python there is no kabulose syntax!

You can use the function nlargest() of the standard library heapq, look at you:

import heapq

lista = [ 9, 6, 3, 5, 0, 7, 8, 2, 1, 4 ]

maiores = heapq.nlargest( 2, lista )

print(maiores)

Exit:

[9, 8]

An alternative solution is to sort the list in descending order using the function sorted() and use Slice Notation to extract the first two elements:

lista = [ 9, 6 , 3, 5, 0, 7, 8, 2, 1, 4 ]

lstord = sorted( lista, reverse=True ) # Ordena a lista em ordem reversa

maiores = lstord[:2] # extrai apenas os dois primeiros elementos da lista

print( maiores )

Exit:

[9, 8]

5

PS.: It seems to me that this case also happens in other languages.

It’s not a language problem, it’s a logic problem. The idea you used is quite interesting, to subtract the smallest number and check again the smallest among them that is not zero, however, its conditions will never be satisfied by the fact that one of the differences will be zero.

To explain better, let’s assume the inputs:

n1 = 3
n2 = 5
n3 = 1
n4 = 6
n5 = 2

So the lowest value will be n3, therefore, menor = 1. After that, you subtract from all the lower values:

#Subtrair o menor numero encontrado do numero digitado
dif1 = n1 - menor  # 2
dif2 = n2 - menor  # 4 
dif3 = n3 - menor  # 0
dif4 = n4 - menor  # 5
dif5 = n5 - menor  # 1

You do this precisely with the intention of searching again for the smallest number among dif1, dif2, dif3, dif4 and dif5, other than zero. That is, it would be expected to indicate the n5 as the second lowest number, as it is the lowest among the differences other than zero. Therefore, it would be expected to display the message:

if (dif5>0) & ((dif5<dif2) & (dif5<dif3) & (dif5<dif4) & (dif5<dif1)):
    print("n5 é o segundo menor numero")

But here you check whether dif5 is less than dif3, that is zero. In other words, always some of the differences will be zero and, thus, never the difference concerning the second smallest number will be the smallest difference, which explains the message of the second smallest number ever to be displayed. In this case, you would have to verify each difference value if it is not zero, to disregard the one referring to the smallest number; its condition would be gigantic, illegible (even more) and impossible to use.


Another way would be, like the Lacobus commented in his reply, use the function heapq.nsmallest (nlargest to the largest numbers):

dois_menores = heapq.nsmallest(2, [n1, n2, n3, n4, n5])

However, this form is equivalent to you ordering the list and returning the first two values, which I think is even more readable:

dois_menores = sorted([n1, n2, n3, n4, n5])[:2]

Or, implement a function that iterates its list of numbers checking which two are smaller:

def retorna_dois_menores(numeros):
     m1, m2 = float('inf'), float('inf')
     for x in numeros:
         if x <= m1:
             m1, m2 = x, m1
         elif x < m2:
             m2 = x
     return m1, m2

dois_menores = retorna_dois_menores([n1, n2, n3, n4, n5])

Adapted from How to find the second smallest value of a python array without using built-in functions?

  • Yeah, I got that question, too. It looks like an exercise, and if it is, it probably needs to implement the algorithm without its existing function, as well as the function you did

2

How are you tagged , follows a solution using the functions of Matlab.

I make it clear that the answers from Anderson and of Lacobus are great and has a great analysis of logic.

In Matlab, you can order a array using the function Sort and use their outputs, with indexes and values.

As what you want is the two largest, follow an exit at the prompt for such.

a=[7 3 4 5 8 7 ];
[asorted,aindex]=sort(a)

%saida
as =
     3     4     5     7     7     8
aindex =
     2     3     4     1     6     5

%Apenas os dois primeiros 
Menores_valores=asorted(1:2)
Menores_valores =
     3     4 
Menores_indices=aindex(1:2)
Menores_indices =
     2     3

Browser other questions tagged

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