Archivo de la categoría: Python

Geometría computacional

Hace un par de años estuve trabajando con el TSP (Travelling salesman problem), y hice una ruta visitando árboles singulares de Barcelona. La unión de los árboles se hacía con líneas rectas.

Partiendo de aquella idea, quiero hacer un camino que una todos los puntos, pero con suavidad. Para esto se utiliza la interpolación (com las cubic-splines, por ejemplo). Voy con la idea de hacer dibujos de un solo trazo (single line drawing, dibujos que teselan toda una superficie con suavidad. Hay artistas que están haciendo dibujos con esta idea. Y esto se podría trasladar a la CNC para hacer cosas chulas y divertidas.

Bot de Twitter sobre reavivar el catalán

Empieza un nuevo curso, y proyectos nuevos. Durante 10 años he estado recopilando información de palabras que me gustan, y que están cayendo en desuso. Además, el escritor Jordi Badia acaba de publicar el libro Salvem els Mots que precisamente va sobre esta problemática.

Ya hacía tiempo que me rondaba hacer un bot de Twitter. Así pues, lo que he hecho es coger la información que tengo, y estructurarla en una base de datos (recordemos: información > conocimiento). Y utilizando el paquete Tweepy de Python, y registrándome en Tweeter como desarrollador, después de un proceso más o menos rápido, ya tengo mi bot de Twitter en marcha.

Se trata de moment de enviar un mensaje cada dos días, con un contenido humorístico y picante, relacionado con palabras y expresiones del catalán que nos gustaría recuperadas y normalizadas. La cuenta de Twitter es @CatalaRevifat

Referencias:

Segmentos de ciclismo con la API de Strava

De la API de Strava me interesa sobretodo la parte de segmentos, que son trozos de rutas donde la gent se cronometra y se publican los rankings. Sin una subscripción Premium no se puede acceder a toda la información. Jugando un rato con la API de Strava he llegado a poder ver los segmentos que hay en una zona geográfica, y poder ver los puntos de este segmento, que se pueden representar en cualquier mapa.

Para acceder a la información de un segmento:

$ curl -X GET https://www.strava.com/api/v3/segments/229781 -H 'Authorization: Bearer *******************'

Y el resultado:

{"id":229781,"resource_state":3,"name":"Hawk Hill","activity_type":"Ride","distance":2684.82,"average_grade":5.8,"maximum_grade":10.9,"elevation_high":247.2,"elevation_low":92.0,"start_latlng":[37.833112,-122.483436],"end_latlng":[37.828072,-122.498139],"elevation_profile":"https://d3o5xota0a1fcr.cloudfront.net/v6/charts/KO5P7GCFLK5P5NF5GNUX3D6IVFLIEYRYD6JRBEGMXHOCPENJUQZXD5IIEJOYINQE2HX3XLZMYRTF5GHG5JLQ====","start_latitude":37.833112,"start_longitude":-122.483436,"end_latitude":37.828072,"end_longitude":-122.498139,"climb_category":1,"city":"San Francisco","state":"CA","country":"United States","private":false,"hazardous":false,"starred":false,"created_at":"2009-09-21T20:29:41Z","updated_at":"2021-03-13T09:01:33Z","total_elevation_gain":155.2,

"map":{"id":"s229781","polyline":"}g|eFnpqjVl@En@Md@HbAd@d@^h@Xx@VbARjBDh@OPQf@w@d@k@XKXDFPF\\CbGT`AV`@v@|@NTNb@?XOb@cAxAWLuE@eAFMBoAv@eBt@q@b@}@tAeAt@i@dAC`AFZj@dBA~@Yh@MbAVn@b@b@\\d@Ef@Qd@_@d@eB|@c@h@YfBI|AMpA?VF\\\\t@f@t@h@j@|@b@hCb@b@XTd@Bl@GtA?jAL`ALp@Tr@RXd@Rx@Pn@^Zh@Tx@Zf@`@FTCzDy@f@Yx@m@n@Op@VJr@","resource_state":3},

"effort_count":556805,"athlete_count":49100,"star_count":5022,"athlete_segment_stats":{"pr_elapsed_time":null,"pr_date":null,"pr_activity_id":null,"effort_count":0},"xoms":{"kom":"5:37","qom":"6:42","destination":{"href":"strava://segments/229781/leaderboard","type":"overall","name":"All-Time"}},"local_legend":{"athlete_id":54312907,"title":"Dalton Nonweiler","profile":"https://dgalywyr863hv.cloudfront.net/pictures/athletes/54312907/14907176/5/large.jpg","effort_description":"86 efforts in the last 90 days","effort_count":"86","effort_counts":{"overall":"86 efforts","female":"41 efforts"},"destination":"strava://segments/229781/local_legend?categories%5B%5D=overall"}}

Vemos que la polilinea está codificada en una cadena de texto. La podemos decodificar y obtener las coordenadas:

$ pip3 install polyline

$ python3
>> import polyline
>> #polyline.decode(summary_polyline)
>> polyline.decode("gxu{Fem|Kc@fAq@fAoApAMR[ZMXw@v@a@VQZi@j@sAhAk@hA_@f@oDxCiAhA_@j@a@~@{@pCC`@EFD^H`B?`@BNNZV@JGDMEqA@q@H]NOFSLo@t@eB^i@d@i@t@m@n@Yz@EHBR\\`AdDFdEJ`@RNHIVGf@ATH`At@VXDl@GJU@WY[e@YSKC_@GgA@YMKMc@eBYeBSWg@AUTSVa@|@[tAAPDb@Nr@@TCb@[bACd@BNJ^Xh@N^BNB`@Nn@DJTNZ\\Rn@?\\c@zAA^B\\JZHHh@NZDVHTRHJBNAb@I|@B\\Th@PTVf@F`@Cl@Sj@WJ{Ae@{@OKBSPOr@IvA[z@UTw@JWE_@]QUUKKCu@Hs@NMEIIi@kAOUGE]OUMGIGY?y@XiB@]E]U[SGU?c@XcA`Aw@|@i@~@WbASPK?IC_Au@q@_@SAI@g@Lo@XK?YB[MYOQSQYi@Y_@AK@CDg@X]Bg@KUMi@e@[k@GU@MHQb@a@DIFU@WIYg@u@]y@IqAP{ABq@Is@e@iB}@wAw@oBk@aAa@g@g@w@Km@Q{AYkB_AmCc@eB?]H]NWxAiBZq@JYFm@@m@C[G]OWa@k@eAu@o@k@iBkCm@k@SKc@CK@]LS@e@]]]E@GDEH@`@PZJd@CHEFI?OSMe@Uk@")

[(41.40436, 2.11683), (41.40454, 2.11647), (41.40479, 2.11611), (41.40519, 2.1157), (41.40526, 2.1156), (41.4054, 2.11546), (41.40547, 2.11533), 
...
(41.41868, 2.11667), (41.41859, 2.11653), (41.41853, 2.11634), (41.41855, 2.11629), (41.41858, 2.11625), (41.41863, 2.11625), (41.41871, 2.11635), (41.41878, 2.11654), (41.41889, 2.11676)]

Referències:

Introducción a Jupyter Notebooks

Ya hace tiempo que tenía ganas de mirar qué es esto de Jupyter Notebook, del que se está hablando mucho y cada vez se hablará más. Este es el primer ejemplo que hago, la solución de la ecuación de 2o grado con python y la librería sympy, que he cogido de una página que me gusta mucho: arachnoid.com.

El siguiente paso será mirar Jupyter Lab, que proporciona una interfície más moderna, y tengo ganas de jugar con widgets y sliders para poder hacer cosas más interactivas. Ahora que estoy programando bastante con Python para preparar ejemplos para las clases de CNED en la UPC, hacerlo con las Notebooks de Jupyter sería una manera muy puntera de hacer clases interactivas.

Referencias:

Ruta por los árboles singulares de Barcelona (minimizando la distancia)

El problema del viajante de comercio (traveling salesman problem) es un problema clásico de la algorítmica: se trata de pasar por una serie de puntos, sin repetir ninguno, y minimizando la distancia recorrida. Hace unas pocas semanas que importé los árboles singulares de Barcelona a OpenStreetMaps, y creo que es una buena actividad didáctica para conocer los árboles de la ciudad hacer una ruta por unos cuantos de estos árboles.

Para hacerlo más interesante, podemos plantearnos el problema de hacer un recorrido que minimice la distancia, pasando por todos los árboles, y que vuelva al punto de partida. Estuve buscando diferentes implementaciones con Python que resolvieran el problema, hasta que encontré una que satisfacía mi restricción de volver al punto de partida.

Sobre esta solución he hecho alguna modificación para que me genere un fichero JSON con la solución. Finalmente, hemos de pintar sobre un mapa OSM nuestros punts (nodos); trazar una línea recta entre los puntos; y añadir un label-texto informativo sobre estos puntos. El resultado se puede ver en la imagen.

Evidentmente hemos hecho unas simplificaciones: la distancia mínima entre dos puntos es la línea recta, pero por la ciudad no podemos ir en línea recta, y además pueden haber subidas y bajadas. Pero como ejercicio didáctico creo que es interesante.

Aquí en Catalunya son populares las Carreras de Orientación. Creo que se podría aprovechar estas actividades en el tiempo de ocio y añadir una capa de conocimiento, como puede ser conocer los árboles, conocer monumentos, etc. Creo que para los niños y jóvenes puede ser una actividad divertida.

Referencias:

Libro: Elementary Mechanics Using Python

Tengo un nuevo reto para lo que queda de 2019 y para el primer semestre del 2020. He empezado a leer el libro Elementary Mechanics Using Python: A Modern Course Combining Analytical and Numerical Techniques, de Anders Malthe-Sørenssen. Es todo un curso de física, y combina de manera comprensible los ejemplos clásicos de movimiento, fuerzas, energía,… con sus soluciones numéricas, utilizando las libreriías matemáticas y de gráficos de Python.

Se trata de implementar todos los ejemplos del libro a código Python. No he visto ningún enlace para descargar todo el código, en cualquier caso, los ejemplos quiero adaptarlos y hacérmelos míos. He empezado por el ejemplo del peso suspendido de un muelle, que como todo el mundo sabe la solución del movimiento es sinusoidal entorno al punto de equilibrio, la velocidad es cero en los puntos máximo y mínimo, y la velocidad es máxima en el punto de equilibrio. Este ejemplo se explica en el apartado 5.7, que habla de fuerzas, y no basta con copiar y pegar el código, sino que lo he tenido que adaptar. Esta es mi solución:

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np

# Initialize
m = 1.0
# kg
k = 100.0 # N/m
v0 = 1.0
# in m/s
time = 2.0 # s
g = 9.8 # m/s^2

# Numerical setup
dt = 0.0001 # s
n = int(round(time/dt))
t = np.zeros(n,float)
y = np.zeros(n,float)
v = np.zeros(n,float)
# Initial values
y[0] = 0.0
v[0] = v0
# Simulation loop
for i in range(n-1):
\tF = -k*y[i] – m*g
\ta = F/m
\tv[i+1] = v[i] + a*dt
\ty[i+1] = y[i] + v[i+1]*dt
\tt[i+1] = t[i] + dt

fig = plt.figure()
fig.suptitle(u»Objecte suspès d’una molla»)
plot1 = fig.add_subplot(211)
#plot1.set_xlabel(‘t [s]’)
plot1.set_ylabel(‘y [m]’)
plot1.xaxis.grid()
plot1.plot(t,y)
plot2 = fig.add_subplot(212)
plot2.set_xlabel(‘t [s]’)
plot2.set_ylabel(‘v [m/s]’)
#plot1.grid(axis=’y’)
#plt.grid(b=True, which=’minor’, color=’#666666′, linestyle=’-‘)
plot2.xaxis.grid()
plot2.plot(t,v)

for i in range(10, n-1, 400):
\tplot1.plot(t[i],y[i],’ob’)
\tplot2.plot(t[i],v[i],’ob’)

plt.show()

Estos son los capítulos y temas que se tratan en el libro:

4. Motion in One Dimension .
5. Forces in One Dimension .
6. Motion in Two and Three Dimensions
7. Forces in Two and Three Dimensions
8. Constrained Motion
9. Forces and Constrained Motion
10. Work
11. Energy
12. Momentum, Impulse, and Collisions
13. Multiparticle Systems
14. Rotational Motion
15. Rotation of Rigid Bodies
16. Dynamics of Rigid Bodies

Curso de Inteligencia l’Artificial en edx.org

Estoy haciendo el curso ColumbiaX: CSMM.101x de Inteligencia Artificial de edx.org. De hecho. ya lo estoy acabando. Ya estamos en la última semana, y para mi suerte, el último proyecto ya lo tengo entregado y me ha llevado menos faena de lo que me pensaba, sin especiales contratiempos. Ahora sólo me falta hacer el examen final que será el 23 de abril, Sant Jordi.

Los proyectos que se han realizado, todos ellos en Python, son:

  • Proyecto 1: Search Algorythms. BFS, DFS,… Se ha resuelto el 8-puzzle
  • Proyecto 2: Adversarial Search and Games. Se ha resuelto el juego del 2048, que de hecho yo lo he jugado bastante. Este proyecto me costó bastante, y efectivamente llegué a 2048 en una ocasión combinando diferentes heurísticas.
  • Proyecto 3: Machine Learning. Había tres problemas diferentes: I. Perceptron Learning Algorithm; II. Linear Regression; III. Classification
  • Proyecto 4: Constraint Satisfaction Problems. Aquí resolvimos el juego del sudoku con los algoritmos del AC-3 y del backtracking.
  • Proyecto 5: NLP, Natural Language Processing. Un proyecto muy interesante. Había un train data de 25000 comentarios de películas, valoradas del 0 al 10. Y después también hi havía un test data de 25000 comentarios que se tenían que valorar después de entrenar el sistema.

El resumen de las semanas ha sido:

  • Week 1: Introduction to AI
  • Week 2: Intelligent Agents and Uniformed Search
  • Week 3: Heuristic Search
  • Week 4: Adversarial Search and Games
  • Week 5: Machine Learning I
  • Week 6: Machine Learning II
  • Week 7: Machine Learning III
  • Week 8: CSP
  • Week 9: Reinforcement Learning
  • Week 10: Logical Agents
  • Week 11: AI Applications: NLP

Por suerte el curso ya se está acabando porque me ha tomado más tiempo del que tenía y del que quería dedicarles. Pero realmente ha sido interesante y exigente, y me he tenido que poner las pilas con el Python. Realmente el tema de las estructuras de datos, y las diferentes librerías que se han utilizado con Python, son muy potentes.

Intentaré seguir leyendo cosas sobre Inteligencia Artificial (IA) y Machine Learning (ML).

NOTA: todavía no tengo acabado el proyecto de la máquina de dardos, y de hecho me doy cuenta de que el problema de acertar dónde ha tocado el dardo y qué puntuación tiene, a parte de un problema de CV (Computer Vision), también es un problema de ML (Machine Learning).