Muchas gracias por tus comentarios Chema, voy a responder por trozos a
un par de cosas:
On 02/13/2013 11:15 PM, Chema Cortes wrote:
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.
IMHO, es un error que los lenguajes de programación se centren en POO
en detrimento de otros paradigmas como la programación funcional. Todo
lo que veo en tus preguntas son conceptos de la programación funcional
que no sabes encajar dentro de una jerarquía de objetos. Tú tienes
"fórmulas" y la mejor representación de una fórmula es como una
"función".
Bueno, en este momento en vez de funciones son básicamente métodos de
una clase.
Los principios SOLID los veo difíciles de cumplir sin contar con un
potente sistema de tipado de datos (y de anotaciones). Supongo que de
ahí tu comentario de que andas despistado con el "duck typing" de
python. Reconozco tener cierto escepticismo con este tipo de
principios. La teoría de tipos está evolucionado tanto últimamente con
los tipos genéricos y tipos cotravariantes que dejarían a algunos de
los principios SOLID, si no desfasados, al menos necesitados de
revisión.
Yo los veo algo útil, pero como dices tú sin un potente sistema de tipos
es complicado.
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`?
Las propiedades que dependen de un
argumento podrían quedar mejor como "funciones currificadas"
(funciones 'partial' para el módulo 'functools').
No conocía el concepto, he echado un ojo a la documentación y parece
interesante.
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.
Es justo lo que te sugería. Una vez encapsulada la ecuación como una
función, pásala como argumento donde sea necesario. Si no te gusta
polucionar el espacio de nombres, agrupa las funciones en módulos y
paquetes. Cambiando un import basta para probar un nuevo conjunto de
ecuaciones.
No me convence tanto tener ecuaciones agrupadas en módulos o paquetes.
Al estar derivadas de unas hipótesis y de unas simplificaciones que he
introducido en mi modelo, y mi modelo está representado por un objeto,
la idea de que la ecuación sea un método de la clase me convence más.
Otra vez, gracias por tus consejos, los tendré en cuenta en el futuro.
_______________________________________________
Python-es mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/