Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Elabore uma classe para a equação de uma linha reta a partir de dois pontos e retorne o valor y para um determinado x

0 votos
19 visitas
perguntada Out 19 em Programação Computacional por Renan Abrantes (16 pontos)  
editado Out 19 por Renan Abrantes

O exercício é proveniente do livro A Primer on Scientific Programming with Python, 5ª edição, de Hans Petter Langtangen.

O autor pede para elaborar uma classe cujo construtor utilize como insumo dois pontos na reta. Pede-se, também, para criar um método que calcule o valor de y para um determinado x, dada a equação de reta derivada a partir dos pontos dados. Por fim, requisita uma função para testar se a implementação da classe é possível a partir dos dados dispostos.

Segue transcrição do exercício:
"7.6 Make a class Line whose constructor takes two points p1 and p2 (2-tuples or 2-lists) as input. The line goes through these two points (see function line in Sect. 3.1.11 for the relevant formula of the line). A value(x) method computes a value on the line at the point x. Also make a function test_Line() for verifying the implementation."

Compartilhe

1 Resposta

0 votos
respondida Out 19 por Renan Abrantes (16 pontos)  
editado Nov 8 por Renan Abrantes

Conforme a equação fundamental da reta, temos que o coeficiente angular \(m\) é:

\(m=\frac{(y-y_0)}{(x-x_0)}\)

Já o coeficiente angular \(a\) pode ser definido como:

\(a=y - xm\)

Agora vamos construir a classe no Python:

#implementar classe a partir da equação fundamental da reta.

class Line:

    def __init__(self, p0, p):
        x0, y0 = p0
        x, y = p
        self.angular = float((y - y0)/(x - x0)) #coeficiente angular
        self.linear = float(y-x*self.angular) #coeficiente linear

    def value(self, x):
        return self.angular*x + self.linear #retorna o ponto y para o x estabelecido conforme equação derivada

O exercício pede para fazer um teste com os pontos \((0,-1), (2,4)\). A partir da reta desenhada por esses pontos, pede para retornar o valor das ordenadas para os seguintes valores das abcissas: \(0.5, 0, 1\). Segue o código:

if __name__ == '__main__':

    reta = Line((0, -1), (2, 4))
    print(reta.value(0.5), reta.value(0), reta.value(1))

Os resultados para esses valores das abcissas são, respectivamente: \(0.25, -1.0, 1.5\).

Agora vamos criar uma função para testar se os valores de input servem para a classe criada:

def test_Line(pontos):
    print("Testando cada valor dos pontos...")
    try:
        if isinstance(pontos, tuple): #verifica se é uma tupla
            for par in pontos:
                if len(par)==2: #verifica se o tamanho de cada item da tupla é igual a 2: (x, y)
                    for valor in par:
                        if not (isinstance(valor, float) or isinstance(valor, int)): #verifica se os valores associados para cada eixo são números
                            print("Você deve colocar um par de NÚMEROS para cada da reta, tal como: (x0, y0), (x, y). Erro: ", valor)
                        else: print("Valor OK: ", valor)
                else:
                    print("Cada ponto deve ser composto de exatos dois valores, um para cada eixo da reta. Erro: ", par)
        else:
            print("Você deve colocar um par válido de números na reta em formato de 2-tupla, tal como: (x0, y0), (x, y).")
    except:
        print("Você deve colocar um par válido de números na reta em formato de 2-tupla, tal como: (x0, y0), (x, y).")
    return ""

Essa função verifica os valores imputados nos seguinte níveis:

  • Verifica se é uma tupla.
  • Verifica para cada item da tupla se o seu
    tamanho é igual a dois, conforme ponto (x, y).
  • Verifica para cada valor dentro de (x, y) se este é um número.

Elaborei alguns testes, tais como:

if __name__ == '__main__':

    print(test_Line(((0, -1), (2, 4))))
    print(test_Line(((0, 'hello world'), (2, 4))))
    print(test_Line(((0, -1, 3), (2, 4))))
    print(test_Line((2)))

Veja os resultados:

A imagem será apresentada aqui.

comentou Nov 2 por Alan Antunes Rosendo (41 pontos)  
Parabéns pela implementação, bem intuitiva.
Como sugestão, faria as seguintes modificações:
Utilizaria o comando:
if __name__ == '__main__':
Para testar a execução do programa, isso deixa seu código mais limpo e mais claro.
Além disso, modificaria o texto no caso em que a coordenada está errada, ao invés de "Erro:" eu incluiria: "a coordenada que está errada é a:"

As duas sugestões são apenas para a clareza do código, ele está funcionando perfeitamente.
comentou Nov 4 por Renan Abrantes (16 pontos)  
editado Nov 8 por Renan Abrantes
Obrigado pelos comentários, Alan! Coloquei o comando do name/main para deixar o código mais limpo. Quanto ao aviso de erro, não achei necessário apontar qual coordenada estaria errada, uma vez que ela já estaria explicitada pelos valores "printados".
...