Errors in the program to sort a triangle

Asked

Viewed 671 times

3

I’m in some trouble and I don’t know how to fix it:

1) An equilateral triangle, three equal sides and angles = 60°, is read as an isosceles triangle (two equal sides).

2) In addition to printing wrong, I can’t remove that 'NONE'.

3) When the triangle has one of the angles = 90, it is rectangle. But the program does not recognize.

4) The fourth and final problem is that I don’t know how to restart the program: 'Type S to restart or N to finish the program'

Can someone help me ???

import math


# lado a 
a = int(input('Digite o valor de um dos lados do triângulo '))

# lado b
b = int(input('Digite o valor do outro lado do triângulo '))

# angulo entre a e b
m = int(input('Digite o ângulo entre estes dois lados '))
ab = (m*math.pi)/180

# calculo do lado c
def lado_c ():
    global a,b,c,ab
    c = math.sqrt(a**2 + b**2 - 2*a*b*math.cos(ab))
    return round(c,2)

# angulo entre a e c
def angulo_ac ():
    global a,b,c,ac
    n = ((a**2+c**2)-(b**2))/(2*a*c)
    ac = (math.acos(n)*180)/math.pi 
    return (round(ac,2))

# angulo b e c
def angulo_bc ():
    global a,b,c,bc
    p = ((c**2+b**2)-(a**2))/(2*b*c)
    bc =(math.acos(p)*180)/math.pi
    return (round(bc,2))

# perímetro
def perimetro ():
    global P,a,b,c
    P =(a+b+c)
    return P

# área
def area ():
    global a,b,c,P,A
    p = (a+b+c)/2
    A = float(math.sqrt(p*(p-a)*(p-b)*(p-c)))
    return A

# altura
def altura ():
    global A
    h = (A*2)/c
    return h

# classificação quanto aos lados
def lado_class ():
    global a,b,c,ab
    if a!=b and a!=c and b!=c:
        print ('Escaleno')
    elif ab == 60 and a == b and b == c:
        print ('Equilátero')
    elif a != b and b == c or b !=c and c == a or c !=a and a==b:
        print ('Isósceles')
    return

# classificação quanto aos angulos
def angulo_class ():
    global ab, ac, bc            
    if ab == 90 or bc == 90 or ac == 90:
        print ('Retângulo')
    elif ab < 90 and bc < 90 and ac < 90:
        print ('Acutângulo')
    elif ab > 90 and bc < 90 and ac < 90   or   bc > 90 and ac < 90 and ab < 90    or   ac > 90 and ac < 90 and ab < 90 :
        print ('Obtusângulo')
    return 

#-----------------------------------------------------------------------------
print ('Lado c = '+ str(round(lado_c (),2)))

print ('Ângulo entre a e c '+str(angulo_ac ()))
print ('Ângulo entre b e c '+str(angulo_bc ()))
print('Área = '+str(round(area (),2))+' unidades de área')
print('Perímetro = '+str(round(perimetro(),2))+' unidades de comprimento')
print ('Altura, em relação ao lado c = '+str(round(altura (),2))+' unidades de comprimento')
print(lado_class ())
print (angulo_class ())

> import math

# lado a 
a = int(input('Digite o valor de um dos lados do triângulo '))

# lado b
b = int(input('Digite o valor do outro lado do triângulo '))

# angulo entre a e b
m = int(input('Digite o ângulo entre estes dois lados '))
ab = (m*math.pi)/180

# calculo do lado c
def lado_c ():
    global a,b,c,ab
    c = math.sqrt(a**2 + b**2 - 2*a*b*math.cos(ab))
    return round(c,2)

# angulo entre a e c
def angulo_ac ():
    global a,b,c,ac
    n = ((a**2+c**2)-(b**2))/(2*a*c)
    ac = (math.acos(n)*180)/math.pi 
    return (round(ac,2))

# angulo b e c
def angulo_bc ():
    global a,b,c,bc
    p = ((c**2+b**2)-(a**2))/(2*b*c)
    bc =(math.acos(p)*180)/math.pi
    return (round(bc,2))

# perímetro
def perimetro ():
    global P,a,b,c
    P =(a+b+c)
    return P

# área
def area ():
    global a,b,c,P,A
    p = (a+b+c)/2
    A = float(math.sqrt(p*(p-a)*(p-b)*(p-c)))
    return A

# altura
def altura ():
    global A
    h = (A*2)/c
    return h

# classificação quanto aos lados
def lado_class ():
    global a,b,c,ab
    if a!=b and a!=c and b!=c:
        print ('Escaleno')
    elif ab == 60 and a == b and b == c:
        print ('Equilátero')
    elif a != b and b == c or b !=c and c == a or c !=a and a==b:
        print ('Isósceles')
    return

# classificação quanto aos angulos
def angulo_class ():
    global ab, ac, bc            
    if ab == 90 or bc == 90 or ac == 90:
        print ('Retângulo')
    elif ab < 90 and bc < 90 and ac < 90:
        print ('Acutângulo')
    elif ab > 90 and bc < 90 and ac < 90   or   bc > 90 and ac < 90 and ab < 90    or   ac > 90 and ac < 90 and ab < 90 :
        print ('Obtusângulo')
    return 

#-----------------------------------------------------------------------------
print ('Lado c = '+ str(round(lado_c (),2)))

print ('Ângulo entre a e c '+str(angulo_ac ()))
print ('Ângulo entre b e c '+str(angulo_bc ()))
print('Área = '+str(round(area (),2))+' unidades de área')
print('Perímetro = '+str(round(perimetro(),2))+' unidades de comprimento')
print ('Altura, em relação ao lado c = '+str(round(altura (),2))+' unidades de comprimento')
print(lado_class ())
print (angulo_class ())

I also published the code here (it is better to view): https://code.sololearn.com/cUh4dY3oul2A/#py

  • First of all, do the [tour] to learn how to use the site.

  • Why does it seem to have duplicate code in question? You have pasted twice or are different?

  • @Raphael , in item 1, if a triangle has two equal sides and has 60 degrees between them, you can guarantee that it is equilateral. Then, the if could be ab == 60 and a == b.

  • @Raphael, NONE is because it is printing the empty Return.

2 answers

1

As questions 1 and 3 can be answered with the analysis of their variables and the returns of their functions. In an example where I define one side of the triangle as 50, another side as 50 and the angle between them 60°, I will get as a response from your script:

a: 50                         # Valor do lado a - int
b: 50                         # Valor do lado b - int
c: 49.99999999999999          # Valor do lado c não arredondado
m: 60                         # Ângulo ab (graus) - int
ab: 1.0471975511965976        # Ângulo ab (radianos) não arredondado
ac: 60.00000000000001         # Ângulo ac (graus) não arredondado
bc: 60.00000000000001         # Ângulo bc (graus) não arredondado
lado_c: 50.0                  # Valor do lado c arredondado ---- Retorno de função
angulo_ac: 60.0               # Ângulo ac (graus) arredondado ---- Retorno de função
angulo_bc: 60.0               # Ângulo bc (graus) arredondado ---- Retorno de função

From this data it is possible to see why its functions return with some errors. When analyzing the function lado_class() we have:

def lado_class ():
    global a,b,c,ab
    if a != b and a != c and b != c:
    """ Comparação a, b e c.
        Sua variável c não está arredondada, o que vai influenciar na sua comparação.
    """
        print ('Escaleno')
    elif ab == 60 and a == b and b == c:
    """ Comparação a, b e c + análise do ângulo ab.
        Novamente sua variável c não está arredondada.
        A variável ab está definida como o ângulo entre a e b em RADIANOS,
        porém você compara ela com o valor em graus.
    """
        print ('Equilátero')
    elif a != b and b == c or b !=c and c == a or c != a and a == b:
    """ Comparação a, b e c.
        Novamente o mesmo problema com a variável c.
    """
        print ('Isósceles')
    return

The same problem will be repeated in its angulo_class() function, but with other variables. I always recommend knowing the return of all your variables, even if it is only for testing.

To fix this issue you have two options: Adjust your comparisons or modify its functions.

# Opção 1. Ajuste dos condicionais.
if a != b and a != lado_c() and b != lado_c():
    (...)

# Opção 2. Ajuste das funções.
def lado_c ():
    """ Arredonde a variável c, e não apenas o retorno da função. 
        NOTA: Lembre-se que arredondar c irá influenciar
        os próximos cálculos que o utilizarem.
    """
    global a,b,c,ab
    c = round(math.sqrt(a**2 + b**2 - 2*a*b*math.cos(ab)))   
    return c

In relation to question 2: The None is the empty return of the function that stems from the very way you wrote your functions. I will work with only one of them, but the reasoning is the same for both.

def lado_class():
    global a,b,c,ab
    if a != b and a != c and b != c:
        print ('Escaleno')
    elif ab == 60 and a == b and b == c:
        print ('Equilátero')
    elif a != b and b == c or b != c and c == a or c != a and a == b:
        print ('Isósceles')
    return    # <----- Essa é a linha que está definindo o retorno vazio.

You have the two options to fix this. The first is to change the return of your function to:

def lado_class():
    global a,b,c,ab
    if a != b and a != c and b != c:
        return 'Escaleno'     # Nesse caso o retorno será 'Escaleno'.
    elif ab == 60 and a == b and b == c:
        return 'Equilátero'   # Nesse caso o retorno será 'Equilátero'.
    elif a != b and b == c or b != c and c == a or c != a and a == b:
        return 'Isósceles'    # E finalmente aqui o retorno será 'Isósceles'.

Writing this way the function will not print when used but will only return the given value. In this case, if you want to print the return of the function you will write:

print(lado_class())

If you don’t want to modify your function you can use it yourself. No need for print:

angulo_class()

So you won’t print the return None of its function. As you have already programmed the print within the function, there is no need to print in the return of it.

In short: When defining a function watch out for when to use Return and print. (doc. Return; doc. print)

Question 4: I’d put it all inside a while, but I don’t know if that’s the right way to do it. while running your script until you give the condition for it to stop (doc. while).

Example with while:

import math

repetir = True

while repetir is True:

    ##### Seu script aqui #####

    consulta_repet = input('Deseja repetir? (S/N)')
    comando_ok = False

    while comando_ok is False:
        if consulta_repet.lower() == 's':
            repetir = True
            comando_ok = True
        elif consulta_repet.lower() == 'n':
            repetir = False
            comando_ok = True
        else:
            consulta_repet = input('Comando não entendido. Deseja repetir? (S/N)')

0

You can use the code below. This code will receive the measurements of the three sides of the triangle in the same line separated by only one space, then the program will check if the measures of the sides form a triangle and, if in fact they form a triangle, will return the type of the triangle.

The code is as follows:...

continuar = True
while continuar == True:
    try:
        l = list(map(float, input('Medida dos lados: ').split()))
        l.sort(reverse=True)
        print()

        if l[0] >= (l[1] + l[2]):
            print('NAO FORMA TRIANGULO')
        else:
            if (l[0] ** 2) == (l[1] ** 2 + l[2] ** 2):
                print('TRIANGULO RETANGULO')
            if (l[0] ** 2) > (l[1] ** 2 + l[2] ** 2):
                print('TRIANGULO OBTUSANGULO')
            if (l[0] ** 2) < (l[1] ** 2 + l[2] ** 2):
                print('TRIANGULO ACUTANGULO')
            if l[0] == l[1] == l[2]:
                print('TRIANGULO EQUILATERO')
            if l[0] == l[1] != l[2] or l[1] == l[2] != l[0] or l[0] == l[2] != l[1]:
                print('TRIANGULO ISOSCELES')

        resposta = input('Digite "S" para reiniciar ou "N" para encerrar: ')
        while resposta not in 'SsNn':
            print(f'Valor INVÁLIDO! Digite apenas uma das duas letras sugeridas!')
            resposta = input('Digite "S" para reiniciar ou "N" para encerrar: ')
        if resposta == 's' or resposta == 'S':
            continuar = True
        else:
            break

    except:
        break

As you can notice, this algorithm does not need to know the measurements of the angles to identify them. It identifies them by analyzing only the behavior of the largest side in relation to the others.

To use this program correctly, just run the program and type the measurements of the sides on the same line, separated by a space, as shown below...

Medida dos lados: 3 4 5

... then type "Enter" and the program will resolve the situation by displaying the following result...

TRIANGULO RETANGULO
Digite "S" para reiniciar ou "N" para encerrar: 

... and then, you can type "S" or "N" according to the situation.

Browser other questions tagged

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