**Revisando la participación continua**
En esta narrativa de datos partimos de un problema real, que tenía que ver con capturar información de los repositorios de código en Fossil para las distintas asignaturas que usaran dicha herramienta y a partir del mismo,
introducimos un problema alterno, que usa el mismo formato de datos JSON, pero permite más consultas:
_usar el PokeAPI para tomar la información de distintos pokemones y modelar un muy sencillo torneo pokemon_.
La clave de este tipo de ejercicios, ya sea con datos reales, como los de Fossil, o con datos ficticios, como los de los Pokemon,
es continuar nuestra introducción al pensamiento computacional,
de modo que podamos aplicar lo aprendido hasta el momento
en la consulta, composición y manipulación de información estructurada.
Esto cierra nuestro encuentro del semestre en esta ocasión.
Pero, a futuro, se espera que la dichas competencias con información estructurada, sean la antesala que nos permita pasar a manejar la información no estructurada, como la que se encuentra en los modelos vectoriales de lenguaje.
# Siguiendo la participación desde los repositorios de código
En las sesiones bimodales es importante la participación proactiva de los aprendices y el docente, que puede ocurrir de maneras síncronas y asíncronas.
En nuestro caso, dicha participación proactiva se ve a partir de la publicación continua en el repositorio propio y el repositorio compartido del LabCI, de las distintas actividades.
Cuando hablamos de participación proactiva, intentamos contrastarla con otras formas de baja o nula participación, como las que se evidenciaron durante la pandemia, entre otras:
- Conectarse de avatar presente en la sesiones síncronas, pero nunca prender el microfono, formular dudas, o intervenir.
- No estar presente en las sesiones síncronas y tampoco hacer uso de las mediaciones asíncronas, en particular, no hacer commits a los repositorios y/o comentarios en los sistemas de lectura anotada.
Dado que estas actividades dejan huella computacional, podemos usar el computador mismo para hacer seguimiento de dichos cambios continuos.
Este será el problema con el que introduciremos la aplicación del control de lectura.

Dado que la sesión 13 tiene el listado los repositorios del primer corte, usemos este documento para revisar la participación reciente
Con esa información revisemos aquellas líneas que contienen repositorios en ChiselApp
Separemos ahora el texto de cada enlace de la dirección como tal a la que apuntan

Si nos fijamos en la respuesta anterior, hemos introducido informalmente algunos elementos que revisaremos en mayor detalle luego: colecciones, iteradores, variables y diccionarios.
Por lo pronto, enfoquémonos en el diccionario que contiene la respuesta.
Este tiene dos partes, que se muestran en la figura anterior: las llaves, ubicadas a la izquierda, y los valores, ubicados a la derecha.
Si queremos seleccionar un repositorio aleatoriamente, para ver su evolución, apelamos a sus llaves, que equivalen a los nombres de les estudiantes:
`>>> #('Eduar Daza' 'Nestor Cristancho' 'Maxi López-Gómez' 'Valentina Vanegas' 'Rubén Torres' 'Thomas Martínez' 'Lizeth Colorado' 'Dario Montenegro' 'Juan Pablo Arias Romero' 'Valentina Penagos Ariza')`
Podemos aplicar aleatoriedas a esas llaves con el siguiente código.
Lo cual quiere decir que es posible seleccionar un repositorio también aleatoriamente para revisar su evolución (sin detrimento de quienes quieran socializar sus repositorios de modo voluntario)
`>>> 'https://chiselapp.com/user/Valentina.P/repository/Valentina-P/timeline'`
Si vemos la línea de tiempo desde la interfaz web, veremos algo de este estilo:

Nos interesa ver los datos en el repositorio y para ello apelaremos a su interfaz [JSON](https://es.wikipedia.org/wiki/JSON), que es un formato ampliamente utilizado en el intercambio de datos en la web y que está habilitado para los repositorios publicados en ChiselApp.
La información previa es información estructurada. Sin embargo su resultado está en HTML.
Que es difícil de consumir.
Podemos pasar de una línea de tiempo a información estructurada en JSON de la siguiente manera:
* https://chiselapp.com/user/Valentina.P/repository/Valentina-P/timeline
Grafoscopio tiene soporte para líneas de tiempo en Fossil.
Sin embargo no lo usaremos en nuestro caso no lo usaremos, debido a un error, usaremos como ejemplo el PokeAPI, que exploraremos en detalle a continuación.
# Pokemones e información a partir de datos en JSON
En este ejemplo empezaremos por una revisión exploratoria de cómo funcionan el API JSON de los Pokemon, llamada [PokeAPI](https://pokeapi.co/) y la iremos abstrayendo y estructurando progresivamente,
hasta que podamos definir una sencilla batalla Pokemon, para desde allí formularnos preguntas futuras para evaluar nuestro conocimiento e intuiciones de diseño.
Definamos el enlace como una cadena de texto:
Convirtamos la cadena de texto en un enlace y recuperemos sus contenidos:
Usando bloques podemos pensar en algo como:
Sin embargo, la aproximación original puede ser más sencilla.
Usar colecciones en Pharo/Smalltalk para coleccionar los datos de esos tres Pokemones.

Supongamos que queremos comparar alturas de los pokemones. Para ello usamos el selector `#at:`, de los diccionarios, de manera que podamos ubicarnos en su nombre y su peso.

Esto nos da una "tabla" rudimentaria de un algunos pokemones y algún atributo que nos interesa (en el ejemplo anterior, su altura).
Sin embargo, si abstraemos más la manera en que creamos Pokemones y coleccionamos su información en una nueva estructura de datos, llamada Data Frame,
estaremos en condiciones de modelar asuntos un poco más complejos. En nuestro caso, una batalla Pokemon, rudimentaria, pero interesante.
A eso nos dedicaremos en la siguiente sección.
# Batalla Pokemon
Lo que hemos hecho con los bloques, vamos a abstraerlo usando la clase Pokemon, que viene incluida en el paquete MiniDocs.
Supongamos que queremos modelar una batalla entre Pokemones.
Definamos nuestros contrincantes:
Esto nos permite preguntar datos particulares a cada peleador:

Podemos seleccionar un movimiento al azar, y conocer su nombre.
Para ello usamos llaves de diccionarios anidadas, en las que una vez seleccionado un movimiento al azar, queremos adentrarnos en ese movimiento, usando el mensaje `at: 'move'` y una vez adentro seleccionamos su nombre, usando el mensaje `at: 'name'`, lo que es lo mismo que anidar ambos mensajes en uno sólo, `at: 'move' at: 'name'`.
El equivalente en código de lo anterior sería:
Lo que gráficamente puede ser representado como recorrer una jerarquía el en diccionario de datos de los movimientos de un pokemon, hasta llegar al nombre de uno de ellos, como se muestra en la siguiente figura:

De este modo, podemos modelar una ronda de lucha como la selección aleatoria de un movimiento de ataque:
E incluso podemos definir un ganador al azar:
Supongamos que queremos colocar toda la información en una tabla.
Para ello usaremos los llamados [Data Frames](https://mutabit.com/repos.fossil/labci/uv/wiki/herramientas/25A-DataFrame-wip.pdf), particularmente, adaptando, el ejemplo de la página 21, haciendo que las columnas guarden la información sobre los contrincantes, sus movimientos y el ganador y las filas guarden información sobre cómo se llevó a cabo cada ronda de combate.
Creemos una primera ronda de combate:
Como nos damos cuenta, la ronda anterior sólo depende de los valores de los dos peleadores,
que empleamos repetidamente en el código anterior, así que podemos convertir esto en un bloque:
Con lo cual podemos invocar este para diferentes peleadores, o para los mismos con resultados distintos.
Por ejemplo, cada vez que invoquemos el siguiente código, **debería darnos algo distinto**:

Y agreguémosla a nuestro torneo:
Y veamos lo que tenemos hasta el momento:

{{overfill-container}}
!!! info: Importante
Obsérvese que, para ver los elementos del Data Frame es **necesario** cliquear en la solapa "Tree", pues la vista de la solapa "Data" nos da el error de la siguiente gráfica:

Hasta acá hemos visto unos rudimentos de cómo traer la información de un API, en este caso la de los Pokemones para manipularla y organizarla de manera que nos permita modelar un aspecto real o ficticio, en nuestro caso la primera batalla de un torneo Pokemon entre dos contrincantes fijos.
Con estos insumos y lo visto de introducción al pensamiento computacional durante el semestre,
ya estamos en condiciones de aplicar lo visto en un último entregable.
# Proyecto final
!!! tip: Importante:
Para este proyecto se debe tener MiniDocs atualizado al menos a la versión `3f26595` o posteriores, de acuerdo al procedimiento mostrado en clase.

Para el proyecto final se extenderá esta narrativa de datos, usando la narrativa misma y los recursos vistos hasta el momento.
La intensión es ver hasta qué punto cada estudiante maduró su pensamiento computacional y está en condiciones de usarlo, junto con las estrategias metacognitivas propias,
para abordar un problema, incluyendo la búsqueda de información y su lectura crítica,
de manera que pueda concebir estrategias para resolver un problema, modificar una narrativa de datos, crear nuevos elementos e indicar claramente dónde tiene dudas e inquietudes frente a una narrativa de datos o recursos y literactura técnica.
Se espera que cada estudiante:
1. Haga una lectura anotada en Hypothesis de la narrativa de datos inicial, formulando preguntas, sugerencias o aclaraciones al texto, como hicimos con representando y procesando datos en Pharo y con Challenge Yourself. **Importante**: Las anotaciones las haremos todæs a un mismo documento ubicado en esta dirección.
2. Importe esta narrativa a su propio GToolkit/Grafoscopio y exportarla en su propio portafolio, indexándolo desde la portada, de manera similar a como hizo cada cual con su ejercicio de _Challenge Yourself_.
3. Extender esta narrativa, dentro del repositorio de cada cual, de manera que se pueda:
- [ ] Agregar 2 rondas más de combates a la tabla `pokemenTournament`, para un total de 3 rondas, incluyendo la primera ronda agregada en el código previo.
- [ ] Usar las utilidades de Data Frame para determinar quién es el Pokemon ganador, es decir, quien haya gando dos de los tres combates.
Para esto es necesario leer apartados de [libro de Data Frame](https://mutabit.com/repos.fossil/labci/uv/wiki/herramientas/25A-DataFrame-wip.pdf), encontrando cómo se utiliza para contar las ocurrencias de un valor.
En caso de dudas, anotarlas con Hypothesis en el libro mismo y compartirlas por correo electrónico.
4. Si sabemos que el código `Pokemon atRandom` , permite seleccionar un Pokemon al azar, ¿cómo debería modificarse el código anterior para que el Data Frame `pokemonTournament` guarde la batalla de dos Pokemones elegidos al azar en lugar de dos Pokemones predefinidos?
- [ ] Describir las modificaciones solicitadas, como un conjunto de pasos finitos en frases, en español.
- [ ] Si se alcanza, intentar traducir esas frases anteriores en español a su equivalente en código.
# Preguntas e inquietudes síncornas y asíncronas
A continuación un listado de las preguntas que se dieron durante las clases (síncronas) y entre ellas (asíncronas) con motivo de la presente narrativa de datos.
## ¿Podemos trabajar con sustición de cadenas?
Para reemplazar un Pokemon por otro podemos usar sustición de cadenas.
Si quisieramos hacerlo explícitamente con dos variables sería algo como:
Sin embargo, esto sólo funciona para esos dos pokemones en particular.
Para abstraerlo en un bloque de manera que podamos usar pokemones arbitrarios, escribiríamos:
# BATALLA FINAL POKEMÓN
A través de la información de Pokeapi y Pharo realizaremos una batalla pokemon de tres rounds entre dos pokemones.

# Sustracción de la data de los nombres de los pokemón

# Verificación aleatoría de la información de los pokemón
Una vez sustraida la información de los Pokemones, se corrobora a través de la funcionalidad atRandom que permite obtener la data de uno de los 1.302 pokemones de manera aleatoria:

# Selección de los dos contrincantes Pokemón
Vamos a confrontar a dos pokemones, para ello se determina en Pharo que el peleador 1 es Charizard y el peleador número 2 es Greninja.

# Información de cada contrincante Pokemón
Vamos a identificar la información de cada pokemon que peleará


# Selección de los movimientos (ataques) de los Pokemón en batalla
Seleccionaremos un movimiento (ataque) al azar de los Pokemón a través de un bloque
Se modelará una lucha con los movimientos al azar

# Creación data frame de la batalla Pokemón
Con el apoyo del capítulo 2.14 **Creating empty data frames** del libro [Data Analysis Made Simple with Pharo DataFrame](https://mutabit.com/repos.fossil/labci/uv/wiki/herramientas/25A-DataFrame-wip.pdf) colacaremos la información en una tabla que indique en las columnas la siguiente información
* Peleador 1 (Charizard)
* Peleador 2 (Greninja)
* Movimiento Peleador 1 (Charizard)
* Movimiento Peleador 2 (Geninja)
* Ganador
Por otro lado se crean las tres filas que representan los tres rounds para definidir al vencedor las cuales por ahora estarán vacías.
Una vez creadas las columnas , haremos la **primera ronda de combate**

# Realización del combate
Ahora registraremos los combates de la batalla Pokemón en el Data Frame, la cual se resolverá en 3 rounds.
Código aplicado en bloque
Resultado arrojado por GTK donde se aprecian unicamente las columnas, sin embargo no aparecieron las filas

Una vez generado el bloque y con base en la lectura anotada se procede a realizar los tres combates
# Pokemón ganador

# Registro del ganador en Dataframe
Inicialmente se toma como base lo indicado en el capítulo 2.4 (creating data series) del libro Data Analysis Made Simple with Pharo DataFrame para reconstruir el código reflejado para la medición del tiempo, que en este caso es para la batalla Pokemón., por otro lado, a parte del proceso explicado en clase, se aplica un bloque que toma como argumento "each", que representa cada elemento de la colección. Dentro del bloque, se concatena el valor de "each" con la cadena '"round", lo cual ya permite visualizar el ganador de cada Round.

# Registro de conteo del ganador
Como registro del conteo se aplica el siguiente código que permitira validar a Charizar como el ganador de 2 de las tres batallas Pokemón

# Cambio de Pokemón (En construcción...)
# Incidencia GT
Durante el trabajo realizado se identificaron unas incidencias que quzás no permitieron la ejecución de algunos códigos como lo fueron los tres rouns después de las 2:00 p. m. del 3 de junio de 2025.
