No suelo preguntar nada en esta lista, pero hoy me gustaría plantearos una cuestión un poco abierta a la que llevo dando vueltas algunos meses. No tengo una formación reglada en programación así que me gustaría recabar algunas ideas sobre cómo llevar a cabo este diseño DeLaManeraCorrecta™. Os cuento (aviso de que es un email largo, un poco denso, posiblemente incomprensible y con algún tecnicismo):

Estoy escribiendo una biblioteca llamada scikit-aero para cálculos comunes en ingeniería aeronáutica con Python.

https://github.com/Pybonacci/scikit-aero

Uno de los módulos es de dinámica de gases. Y uno de los «objetos» que he definido es `IsentropicFlow`, que representa un flujo con unas determinadas características. Tiene varias propiedades, que se pueden obtener con expresiones matemáticas definidas en los métodos:

https://github.com/Pybonacci/scikit-aero/blob/master/skaero/gasdynamics/isentropic.py#L65

Al definir un `IsentropicFlow` especifico todas las variables que lo determinan *unívocamente*, y de ahí obtengo las propiedades.

Me surgen dos preguntas:

1. (Menos importante) Cada vez que quiero una propiedad de uno de estos objetos la calculo con la fórmula matemática y la devuelvo. Por ejemplo, defino un `IsentropicFlow` y puedo obtener de él ciertas propiedades en función de otro argumento `M`, el número de Mach incidente.

Pero aquí tengo otro ejemplo, los objetos `NormalShock`, que representan ondas de choque:

https://github.com/Pybonacci/scikit-aero/blob/master/skaero/gasdynamics/shocks.py#L22

donde las propiedades vienen determinadas por las variables que definen el `NormalShock`, nada más.

*Pregunta*: Si no dependen de argumentos extra, ¿tal vez sería mejor calcularlas en `__init__`, almacenarlas y simplemente devolver los valores cuando se pidan? Si es así, ¿hasta qué punto tiene sentido definir una clase, cuando prácticamente podría conseguir lo mismo utilizando un diccionario, o un `namedtuple`?

2. (Más importante) Digamos que otro tipo de objetos, `ObliqueShock` (ondas de choque oblicuas) vienen caracterizados por dos variables: `M` (número de Mach incidente) y `beta` (ángulo de la onda de choque). Definido un `ObliqueShock`, puedo obtener su ángulo de deflexión correspondiente, `theta`, a través de una relación matemática. Sin embargo si conozco `M` y `theta`, esa relación se tiene que resolver iterativamente para hallar `beta`, y además hay dos valores posibles entre los que tengo que discriminar.

Como me interesa, por motivos prácticos, disponer de una manera de instanciar `ObliqueShock` dados `M` y `theta`, mi aproximación al problema ha sido crear una función que:

* Recibe como argumentos `M`, `theta` y un argumento booleano que discrimina entre las dos soluciones posibles. * Comienza un proceso iterativo: construye un `ObliqueShock` con `M` dado y `beta` cualquiera; si el `theta` resultante es el dado, devuelvo ese `ObliqueShock`, en caso contrario sigo iterando.

Una idea parecida está recogida en la función `mach_from_area_ratio`:

https://github.com/Pybonacci/scikit-aero/blob/master/skaero/gasdynamics/isentropic.py#L25

que itera sobre un `IsentropicFlow`.

*Pregunta*: ¿esto va bien? Supongo que sería una idea tipo «factoría» de clases. La razón del embrollo es no escribir la misma ecuación «fuera» y «dentro» de la clase, teniendo así que repetir código.

Estoy muy interesado en los principios SOLID y en intentar escribir código POO de buena calidad pero no parece haber mucho material disponible en la red y por otro lado sin una orientación a objetos «purista» no me resulta tan sencillo. Cuando programaba en ActionScript 3 hacía y deshacía con interfaces, encapsulación, herencia... ahora Python y su «duck typing» me despistan un poco en este sentido.

Espero no haber aburrido a nadie más de la cuenta, si hacen falta más aclaraciones sobre lo anterior las daré gustoso y si alguien tiene comentarios sobre esto o sobre otros aspectos del código de scikit-aero estaría enormemente agradecido de recibirlos.

Un saludo,

Juan Luis Cano
_______________________________________________
Python-es mailing list
Python-es@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

Responder a