problema de principiante

Josef Meile jmeile en hotmail.com
Vie Feb 11 22:36:28 CET 2005


Hola Rafael,

> Os comento mi Problema. Lo primero de todo es que no tengo ni idea de 
> programacion. Supongo que leyendo tutoriales y teniendo paciciencia 
> podria resolver el problema, lo que ocurre es que ando algo mal de 
> tiempo y los tutoriales son chino mandarin pa mi.
> La cuestion es que me han pasado Vpython para que haga una 
> simulacion.Tengo simular un rayo atravesando distintos elementos, 
> cada vez que el rayo atraviese uno de esos elementos quiero que haga 
> una determinada funcion. he sacado la funcion , el problema es que 
> tengo un monton de elementos y no se como generalizar la funcion para 
> para no tener que repetirla 40 veces
> 
> Los elementos son del tipo:
> 
> Pbs1 = box(pos=(0,0,0), axis=(-1,1,0), size=(0.1,2,2), 
> color=color.blue)
> 
> Pbs2 = box(pos=(3,0,0), axis=(-1,1,0), size=(0.1,2,2), 
> color=color.blue)
> 
> Y la funcion que quiero hacer es:
> 
> def setPbs():
>    if ball.color == color.red and Pbs.x-0.1 < ball.x  < Pbs.x+0.1 and 
> Pbs.y-0.1 < ball.y < Pbs.y+0.1 and Pbs.z-0.1 < ball.z < Pbs.z+0.1 and 
> ball.velocity.x != 0 and ax != 0:    
>           ball.velocity.z = -ax*100*Pbs.axis.z 
>           ball.velocity.x = 0
>           ball.velocity.y = -ax*100*Pbs.axis.y
>    if ball.color == color.red and Pbs.x-0.1 < ball.x  < Pbs.x+0.1 and 
> Pbs.y-0.1 < ball.y < Pbs.y+0.1 and Pbs.z-0.1 < ball.z < Pbs.z+0.1 and 
> ball.velocity.z != 0 and az != 0:                     
>           ball.velocity.x = -az*Pbs.axis.x*100 
>           ball.velocity.z = 0
>           ball.velocity.y = -az*Pbs.axis.y*100
>    if ball.color == color.red and Pbs.x-0.1 < ball.x  < Pbs.x+0.1 and 
> Pbs.y-0.1 < ball.y < Pbs.y+0.1 and Pbs.z-0.1 < ball.z < Pbs.z+0.1 and 
> ball.velocity.y != 0 and ay != 0:                     
>           ball.velocity.x = -ay*Pbs.axis.x*100 
>           ball.velocity.y = 0
>           ball.velocity.z = -ay*Pbs.axis.z*100
> 
> Creo que deberia intentar crear una Clase?  pero no se mu bien como 
> hacerlo.
Bueno, con una función es suficiente, pero la clase es más elegante. Por
lo que veo, sólo la última línea del condicional varía de acuerdo a la
coordenada. El código dentro del condicional también varía de acuerdo a
la coordenada. Para poder hacer la generalización, se tuvieron que mover
dos lineas de sitio: Las líneas 10 y 12 dentro de la función setPbs
(segundo condicional) se intercambiaron de sitio. En las siguientes
líneas utilizo los caracteres !! y ?? para hacer énfasis en lo que
varía.

ball.velocity.!!x!! != 0 and !!ax!! != 0    -> Coordenada x
ball.velocity.!!z!! != 0 and !!az!! != 0    -> Coordenada z
ball.velocity.!!y!! != 0 and !!ay!! != 0    -> Coordenada y

ball.velocity.z = -a!!x!!*Pbs.axis.??z??*100    -> Coordenada x, z=x-1
ball.velocity.y = -a!!z!!*Pbs.axis.??y??*100    -> Coordenada z, y=z-1
ball.velocity.x = -a!!y!!*Pbs.axis.??x??*100    -> Coordenada y, x=y-1


ball.velocity.!!x!! = 0    -> Coordenada x
ball.velocity.!!z!! = 0    -> Coordenada z
ball.velocity.!!y!! = 0    -> Coordenada y

ball.velocity.??y?? = -a!!x!!*100*Pbs.axis.??y??  -> Coordenada x, y=x+1
ball.velocity.??x?? = -a!!z!!*100*Pbs.axis.??x??  -> Coordenada z, x=z+1
ball.velocity.??z?? = -a!!y!!*100*Pbs.axis.??z??  -> Coordenada y, z=y+1

La idea es utilizar una lista con tres elementos: 'x', 'y', 'z', y jugar
con las posiciones de dicha lista:

listCoord=['x','y','z']
listDeltas=[ax,ay,az]
def setPbs(index):
   velocity=getattr(listCoord[index])
   if ball.color == color.red and \
      Pbs.x-0.1 < ball.x  < Pbs.x+0.1 and \
      Pbs.y-0.1 < ball.y < Pbs.y+0.1 and \
      Pbs.z-0.1 < ball.z < Pbs.z+0.1 and \
      velocity != 0 and listDeltas[index] != 0:

      #Aquí no es necesario mirar si axis=-1,
      #pues python considera el índice -1
      #como el último elemento de la lista
      axis=index-1
      PbsAxis=getattr(Pbs.axis,listCoord[axis])
      formula=-listDeltas[index]*PbsAxis*100
      setattr(ball.velocity,listCoord[axis],formula)

      setattr(ball.velocity,listCoord[index],0)

      axis=index+1
      if axis=3:
        axis=0

      PbsAxis=getattr(Pbs.axis,listCoord[axis])
      formula=-listDeltas[index]*100*PbsAxis
      setattr(ball.velocity,listCoord[axis])

Y se llama como:

setPbs(0)
setPbs(2)
setPbs(1)


De hecho creo que podría usarse tan sólo un diccionario:

listCoord={'x':ax, 'y':ay ,'z':az}

pero habría que hacerle unas modificaciones al código.


Saludos,
Josef




Más información sobre la lista de distribución Python-es