Find the largest and smallest element of a matrix

Asked

Viewed 2,073 times

8

I have the following code:

def processa(matriz):
    print('----- Matriz Lida -----')
    for i in range(len(matriz)):
        for j in range(len(matriz[0])):
            print(matriz[i][j].center(6), end=' ')
        print()
    return


def localizaCelulaComMaiorValor(matriz):
    resp = (0, 0)
    for lin in range(len(matriz)):
        for col in range(len(matriz[lin])):
            if matriz[lin][col] > matriz[resp[0]][resp[1]]:
                menor = matriz[lin][col]
                resp = (lin, col)
    print('-----------------------')
    print('Maior valor: ', menor, 'na posição: ', resp)
    return


def localizaCelulaComMenorValor(matriz):
    resp = (0, 0)
    for lin in range(len(matriz)):
        for col in range(len(matriz[lin])):
            if matriz[lin][col] < matriz[resp[0]][resp[1]]:
                maior = matriz[lin][col]
                resp = (lin, col)
    print('Menor valor: ', maior, 'na posição: ', resp)
    return

matriz =[]
condicao = 0

while condicao == 0:
  a = input().split()
  matriz.append(a)
  if not a:
    if not a and len(matriz) == 1:
      print('----- Matriz Lida -----')
      print('Matriz vazia, não existem valores')
      print('menor e maior!!!')
      exit()
    matriz.pop()
    processa(matriz)
    localizaCelulaComMaiorValor(matriz)
    localizaCelulaComMenorValor(matriz)
    exit()

When I type nothing, the displayed message is:

----- Matriz Lida ----  
Matriz vazia, não existem valores menor e maior!!!. 

That is correct.


When typing the matrix example:

132 232 

342 4 

222 234 

1232 13 

The message displayed is:

----- Matriz Lida ----  
   132    232     
   342     4      
   222    234     
   1232    13   
   Maior valor:  4 na posição:  (1, 1) 
   Menor valor:  1232 na posição:  (3, 0) 

That’s also correct.


When typing the matrix example:

8 5 6 7

13 -4 5 55 

2 3 300 2 

10 2 4 8

The message displayed is:

----- Matriz Lida ----  
   8 5 6 7     
   13 -4 5 55      
   2 3 300 2
   10 2 4 8


Traceback (most recent call last):
  File "LOCALIZAÇÃO_FILE", line 46, in <module>
    localizaCelulaComMaiorValor(matriz)
  File "LOCALIZAÇÃO_FILE", line 18, in localizaCelulaComMaiorValor
    print('Maior valor: ', menor, 'na posição: ', resp)
UnboundLocalError: local variable 'menor' referenced before assignment

Where am I going wrong for examples like this, since the first example works? In the second example is only working the display of the resulting matrix, does not display the largest/smallest number and its location. How to fix?

2 answers

7


Your mistake is in saving type inputs str in the matrix and want to compare them as if they were the type int after. The value of '13', for example, it is not greater than '8', although 13 is greater than 8. It was lucky to have run the other times.

Well, to fix that in your code without modifying too much, you can change that matriz.append(a) therefore matriz.append([int(entrada) for entrada in a]), to make your input whole.

And change that print(matriz[i][j].center(6), end=' ') therefore print(str(matriz[i][j]).center(6), end=' '), because you use the attribute .center, which only exists for objects of the type string.

Also, how was tapped by @hkotsubo, when the first position of the matrix is the largest, the variables maior and menor will also be undefined. In this case, we have to start them before entering the for: maior = matriz[0][0] and menor = matriz[0][0].

Your code would look like this:

def processa(matriz):
    print('----- Matriz Lida -----')
    for i in range(len(matriz)):
        for j in range(len(matriz[0])):
            print(str(matriz[i][j]).center(6), end=' ')
        print()
    return


def localizaCelulaComMaiorValor(matriz):
    resp = (0, 0)
    maior = matriz[0][0]
    for lin in range(len(matriz)):
        for col in range(len(matriz[lin])):
            if matriz[lin][col] > matriz[resp[0]][resp[1]]:
                maior = matriz[lin][col] # troquei o nome da variável para ficar coerente
                resp = (lin, col)
    print('-----------------------')
    print('Maior valor: ', maior, 'na posição: ', resp)
    return


def localizaCelulaComMenorValor(matriz):
    resp = (0, 0)
    menor = matriz[0][0]
    for lin in range(len(matriz)):
        for col in range(len(matriz[lin])):
            if matriz[lin][col] < matriz[resp[0]][resp[1]]:
                menor = matriz[lin][col] # troquei o nome da variável para ficar coerente
                resp = (lin, col) 
    print('Menor valor: ', menor, 'na posição: ', resp)
    return

matriz =[]
condicao = 0

while condicao == 0:
  a = input().split()
  matriz.append([int(entrada) for entrada in a])
  if not a:
    if not a and len(matriz) == 1:
      print('----- Matriz Lida -----')
      print('Matriz vazia, não existem valores')
      print('menor e maior!!!')
      exit()
    matriz.pop()
    processa(matriz)
    localizaCelulaComMaiorValor(matriz)
    localizaCelulaComMenorValor(matriz)
    exit()

3

In your algorithm to check the highest value, you start with the first position of the matrix:

resp = (0, 0)

Then within the loops you make the comparison:

if matriz[lin][col] > matriz[resp[0]][resp[1]]:
    menor = matriz[lin][col]
    resp = (lin, col)

But what happens if the element at position (0, 0) is the largest of all?

Then you’ll never get into if (because no element of the matrix will be greater than the first), and therefore the variable menor will never be initialized. And when trying to print it out of the if, occurs the UnboundLocalError (since you tried to print a variable that was not initialized).

The solution is to initialize it with some initial value before the loop. How are you already initiating the starting position with (0, 0), can initialize the variable with its value.

I also suggest changing the name to maior, since you are looking for the biggest element. Better names help you think better about the problem.

Another suggestion is to use enumerate to go through the matrix, so you have at the same time the index and the respective element. And since your function is not returning any value, you can even take the return of the end.

def localiza_celula_com_maior_valor(matriz):
    resp = (0, 0)
    # maior valor começa com o primeiro elemento
    maior = matriz[0][0]
    for indice_linha, linha in enumerate(matriz): # cada elemento da matriz é uma "linha" (na verdade é uma lista)
        for indice_coluna, numero in enumerate(linha): # cada elemento da linha é um número
            if numero > maior:
                maior = numero
                resp = (indice_linha, indice_coluna)
    print('-----------------------')
    print('Maior valor: ', maior, 'na posição: ', resp)

Of course, when initializing maior With the first element, the first loop iteration will be redundant, as it will compare the element with itself. It’s not the "cumulus of inefficiency," but if it bothers you, you can initialize the variable with a very small value (such as -1000000, for example, or the lowest possible value for an integer, for then "any" value of the matrix will be greater than it).


The same goes for finding the lowest value:

def localiza_celula_com_menor_valor(matriz):
    resp = (0, 0)
    menor = matriz[0][0]
    for indice_linha, linha in enumerate(matriz):
        for indice_coluna, numero in enumerate(linha):
            if numero < menor:
                menor = numero
                resp = (indice_linha, indice_coluna)
    print('-----------------------')
    print('Menor valor: ', menor, 'na posição: ', resp)

In also initialized menor with the first element, making the first iteration of the loop redundant, but if you want, you can also initialize with as high a value as possible to an integer, ensuring that any element of the matrix will be smaller than it.


On the matrix reading itself, use matriz.append([int(entrada) for entrada in a]), as suggested and explained in answer from Rafael.

Already to print, you can use format with a ^ in the format, which serves to center the numbers. Also note that you do not need the indexes to get the elements, since you are not printing the indexes:

def processa(matriz):
    print('----- Matriz Lida -----')
    for linha in matriz:  # cada elemento da matriz é uma "linha" (na verdade é uma lista)
        for numero in linha:  # cada elemento da linha é um número
            print('{:^6}'.format(numero), end = '')
        print()

Browser other questions tagged

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