range(5)

"""
Explanation: Práctica 3 - Dinámica de manipuladores
List comprehensions
En esta práctica nos enfocaremos en temas avanzados de programación que se aplican directamente al lenguaje de programación Python y a algunos otros lenguajes de programación. En primer lugar veamos la instrucción range:
End of explanation
"""


for i in range(5):
    print(i)

"""
Explanation: Mmmm..., realmente no hizo nada... bueno, el objetivo de esta función de la libreria standard de Python es crear un arreglo de enteros desde $0$ hasta el numero que le demos como argumento:
End of explanation
"""


[i for i in range(5)]

"""
Explanation: En este caso es obvio como se estan generando los numeros, desde $0$ hasta ¿$4$?. Mas bien hasta que el numero de elementos sea el numero dado, o bien $n-1$; de cualquier manera, esta forma de utilizar el ciclo for es la que nos da el vinculo con el for tradicional de otros lenguajes de programación, pero en Python tenemos una manera diferente de usar este mismo for, List Comprehensions:
End of explanation
"""


A = []
for i in range(5):
    A.append(i)
    
A

"""
Explanation: Si recuerdas la práctica 1, para crear un arreglo con numeros adentro, podiamos utilizar el siguiente código:
End of explanation
"""


[i**2 for i in range(10)]

"""
Explanation: Sin embargo, comparandolo con la simplicidad del código anterior, este enfoque palidece, por lo que en Python es normal ver este tipo de construcciones, podemos diseccionarlo en dos partes:
Python
[i for i in range(5)]
en la primera, i ocupa el lugar del elemento que nos dicta que es lo que vamos a guardar en el arreglo final; en este caso, es el numero a secas, por lo que no hacemos ninguna operación, pero si queremos guardar en un arreglo, por ejemplo, los cuadrados de los primeros $10$ enteros positivos, tendremos:
End of explanation
"""


[x**2 for x in range(10)]

"""
Explanation: La segunda parte de este código,
Python
[i for i in range(5)]
es el for, esta es la razon por la que usamos i anteriormente, da lo mismo escribir:
End of explanation
"""


[x**2 for i in range(10)]

"""
Explanation: y por supuesto no funcionará si:
End of explanation
"""


range(5)

"""
Explanation: Pero regresemos por un momento al primer pedazo de código que escribimos:
End of explanation
"""


if False:
    A = []
    for i in range(5):
        A.append(i)
else:
    pass

"""
Explanation: Si ese... lo que esta pasando aqui es que Python realmente no quiere evaluar esta expresión hasta que sea completamente necesario, a este concepto se le llama Lazy Evaluation, o evaluación floja; a pesar de la mala reputación que tiene Python por ser lento, y por ocupar demasiada memoria de ejecución, tiene caracteristicas bastante interesantes, como el hecho de no evaluar expresiones que no van a ser necesarias.
Hagamos un ejemplo para que quede mas claro:
End of explanation
"""


%%timeit
A = [i for i in range(5)]

"""
Explanation: En este código las lineas dentro del if nunca serán ejecutadas, por lo que si tuvieramos un lenguaje de programación compilado (como C), en primer lugar tendría que reservar espacio en memoria para el arreglo que va a guardar los datos de A, sin embargo nunca se utilizaria ese espacio, en Python nunca se ejecutarán esas lineas y lo demostraremos:
End of explanation
"""


%%timeit
if False:
    A =[]
    for i in range(5):
        A.append(i)
else:
    pass

"""
Explanation: Una de las funciones especiales de Jupyter (no de Python) es que si escribo %%timeit al inicio de cualquier celda, la ejecutará muchas veces y me reportará el promedio de tiempo que se tardó en ejecutar esta celda, en este caso nuestro programa se tardó $739ns$ en promedio.
Si por el otro lado, ejecuto las lineas en donde saltará especificamente la creación de este arreglo tendremos:
End of explanation
"""


[x**2 + 1 for x in [2,4,6,8,10]]

"""
Explanation: En esta ocasión se tarda $12.4ns$ ya que en realidad no esta haciendo nada...
Por cierto, una cosa más... las list comprehensions funcionan no solo con range, sino con cualquier arreglo, como en el siguiente caso:
End of explanation
"""


[caracter + " abc" for caracter in "pizza"]

"""
Explanation: o incluso este:
End of explanation
"""


from sympy.physics.mechanics import mechanics_printing
mechanics_printing()

from sympy import var
# ESCRIBE TU CODIGO AQUI
raise NotImplementedError
longs

from nose.tools import assert_equal
from sympy import var
assert_equal(longs, [var("l1"), var("l2"), var("l3"), var("l4"), var("l5")])

"""
Explanation: Ejercicio
Utilizando list comprehensions:

Genera un arreglo con los simbolos de sympy que representan la longitud de 5 eslabones, recuerda que para generar el simbolo de $l_1$ tenemos que escribir:

Python
var("l1")
End of explanation
"""


parametros_DH = [[ "0", "l1", "0", "q1"],
                 ["l2",  "0", "0", "q2"],
                 [ "0", "l3", "0", "q3"],
                 ["l4",  "0", "0", "q4"],
                 [ "0", "l5", "0", "q5"]]

from sympy import var
# ESCRIBE TU CODIGO AQUI
raise NotImplementedError
matrices

from nose.tools import assert_equal
from sympy import Matrix, var, sin, cos
l1, q1, cero = var("l1"), var("q1"), var("0")
A1 = Matrix([[cos(q1), -sin(q1)*cos(cero), sin(cero)*sin(q1), cero*cos(q1)],
             [sin(q1), cos(cero)*cos(q1), -sin(cero)*cos(q1), cero*sin(q1)],
             [0, sin(cero), cos(cero), l1],
             [0, 0, 0, 1]])
assert_equal(matrices[0], A1)
l2, q2, cero = var("l2"), var("q2"), var("0")
A2 = Matrix([[cos(q2), -sin(q2)*cos(cero), sin(cero)*sin(q2), l2*cos(q2)],
             [sin(q2), cos(cero)*cos(q2), -sin(cero)*cos(q2), l2*sin(q2)],
             [0, sin(cero), cos(cero), cero],
             [0, 0, 0, 1]])
assert_equal(matrices[1], A2)
l3, q3, cero = var("l3"), var("q3"), var("0")
A3 = Matrix([[cos(q3), -sin(q3)*cos(cero), sin(cero)*sin(q3), cero*cos(q3)],
             [sin(q3), cos(cero)*cos(q3), -sin(cero)*cos(q3), cero*sin(q3)],
             [0, sin(cero), cos(cero), l3],
             [0, 0, 0, 1]])
assert_equal(matrices[2], A3)
l4, q4, cero = var("l4"), var("q4"), var("0")
A4 = Matrix([[cos(q4), -sin(q4)*cos(cero), sin(cero)*sin(q4), l4*cos(q4)],
             [sin(q4), cos(cero)*cos(q4), -sin(cero)*cos(q4), l4*sin(q4)],
             [0, sin(cero), cos(cero), cero],
             [0, 0, 0, 1]])
assert_equal(matrices[3], A4)
l5, q5, cero = var("l5"), var("q5"), var("0")
A5 = Matrix([[cos(q5), -sin(q5)*cos(cero), sin(cero)*sin(q5), cero*cos(q5)],
             [sin(q5), cos(cero)*cos(q5), -sin(cero)*cos(q5), cero*sin(q5)],
             [0, sin(cero), cos(cero), l5],
             [0, 0, 0, 1]])
assert_equal(matrices[4], A5)

"""
Explanation: Genera un arreglo con las matrices simbolicas de sympy que contengan las matrices de transformación homogéneas de los 5 grados de libertad descritos en el siguiente arreglo con parametros DH:
End of explanation
"""


