Blog Bitix

Desempaquetado del ratón inalámbrico Logitech Signature M750

julio 23, 2024 09:00

Tras probar un ratón inalámbrico de los baratos pasado un tiempo me quedé con muy malas impresiones por la perdida de conectividad principalmente que era muy molesta. Pasé a un ratón con cable más fiable y tras 5 años el botón derecho me ha empezado a fallar y reconocer el clic aleatoriamente. Tras estar usando un Apple Magic Mouse que generalmente me ha funcionado bien en cuanto a conectividad he vuelto a darle una nueva oportunidad a un ratón inalámbrico pero ya de más calidad, finalmente he elegido el Logitech Signature M750. En el artículo hago un análisis del ratón y mis primeras impresiones.

Continuar leyendo en Blog Bitix

» Leer más, comentarios, etc...

Header Files

La trampa al usar semántica de movimiento con std::string

julio 16, 2024 10:00

La trampa al usar semántica de movimiento con std::string

La semántica de movimiento de std::string puede ser complicada y, a menos que tengamos información previa sobre los tamaños esperados de las cadenas, puede tener el efecto contrario y hacer que el código sea más lento. La razón detrás de esto es la optimización de cadenas pequeñas (SSO, por sus siglas en inglés). que consiste, en resumidas cuentas, en tratar al objeto como si fuera una unión, de forma que si la cadena es más corta que un tamaño dado, se almacena en el mismo bloque de memoria del objeto en lugar de asignar memoria dinámica. Cuando la cadena supera ese tamaño, la cadena se almacena en un bloque diferente.

¿Qué es la Optimización de Cadenas Pequeñas (SSO)?

La SSO es una técnica utilizada en la implementación de std::string para optimizar el uso de memoria y el rendimiento. En lugar de asignar memoria dinámica para todas las cadenas, la SSO almacena cadenas pequeñas directamente en el objeto std::string (como si de una unión se tratase). Se puede ver la SSO en acción en este ejemplo.

Esta técnica evita la sobrecarga de la asignación de memoria dinámica, que puede ser costosa en términos de tiempo y recursos. Sin embargo, esta optimización introduce algunas consideraciones importantes al mover objetos std::string.

Nota: La SSO no es parte del estándar de C++ sino más bien una optimización de algunos compiladores. Igualmente, el tamaño máximo para considerar una cadena como pequeña no tiene que ser el mismo en todas las implementaciones ni plataformas.

El constructor de movimiento de std::string

Al mover cualquier objeto en C++, estamos dando la posibilida de realizar una copia optimizada. La eficiencia aumenta cuando tenemos recursos externos que podemos intercambiar, como un puntero a un bloque de memoria o un handle de fichero. Sin embargo, para el resto de datos, aún tenemos que copiar datos. Si la cadena es pequeña y la SSO está en acción, no hay ningún puntero que intercambiar y todavía estamos copiando los datos base de std::string.

De hecho, al mover, tenemos que garantizar que el objeto original se mantenga en un estado válido, lo cual normalmente se hace estableciendo algunos valores por defecto. En la práctica, esto significa que estamos copiando una vez y asignando una vez, duplicando la cantidad de operaciones en comparación con una copia normal. Por lo tanto, si nuestras cadenas se espera que siempre (o la mayoría del tiempo) sean más cortas que el límite de SSO, entonces un movimiento perjudicaría el rendimiento.

Comparación de Copia vs Movimiento

Para ilustrar mejor este punto, se puede comparar el rendimiento de la copia y el movimiento para cadenas pequeñas, grandes y una mezcla de ambas. El siguiente ejemplo permite visualizar las diferencias entre ellas. En este benchmark, se estableció un tamaño de 32 caracteres para tener aproximadamente un 50% de cadenas pequeñas y un 50% de cadenas grandes. Los resultados muestran cómo el movimiento de cadenas pequeñas puede ser menos eficiente que una simple copia debido a la SSO.

Benchmark std::string

Conclusión

En resumen, la semántica de movimiento de std::string no siempre es la mejor opción, especialmente cuando se trata de cadenas cortas que se benefician de la SSO. Es crucial considerar el tamaño esperado de las cadenas al decidir entre copiar o mover std::string. Esta decisión puede tener un impacto significativo en el rendimiento de nuestra aplicación.

» Leer más, comentarios, etc...

Variable not found

¡Microsoft MVP 2024-2025!

julio 11, 2024 06:54

MVP

Hago una ligera interrupción de mis vacaciones blogueras para compartir con todos vosotros que, por decimocuarto año consecutivo, he sido reconocido por Microsoft como Most Valuable Professional (MVP) en la categoría .NET ¡¡Hurra!! 😀

Aunque ya debería estar acostumbrado, siempre es un honor y un privilegio recibir este galardón que, de alguna forma, reconoce mis aportaciones a la comunidad de desarrolladores, esa comunidad con la que sigo estando en deuda por lo que he recibido de ella durante tanto tiempo.

Muchas gracias al equipo de Microsoft que hace esto posible, con nuestra querida Cristina González a la cabeza, por la dedicación y esfuerzo que ponen en este programa. Muchas gracias también a todos los compañeros MVPs que hacen que esta comunidad sea tan especial.

Y, por supuesto, agradeceros a todos vosotros, queridos amigos y amigas, por seguir ahí, porque vuestras visitas, lecturas y comentarios son los que me animan a seguir compartiendo experiencias y conocimientos en este pequeño rinconcito de la web.

¡Nos vemos a la vuelta!

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

while(DateTime.Now.Month != 9) await Task.Delay(TimeSpan.FromDays(10))

julio 09, 2024 06:05

Foto: Atardecer en la playa en Costa Ballena, por Eugenio Sánchez. Original: foro.ojodigital.com

Queridos amigos, queridas amigas: como todos los años por esta época, me complace informaros de que voy a dejar el blog a merced de los vientos durante unas semanas para disfrutar de un (merecidísimo) descanso.

Volveremos a la carga, supongo que a mediados de septiembre (o antes, o después, ya iremos viendo) 🙂

Feliz verano a todos y que disfrutéis de las vacaciones. ¡Nos vemos a la vuelta!

Publicado en: www.variablenotfound.com.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 576

julio 08, 2024 06:05

Enlaces interesantes

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

ASP.NET Core / ASP.NET / Blazor

Conceptos / Patrones / Buenas prácticas

Data

Machine learning / IA / Bots

Web / HTML / CSS / Javascript

Visual Studio / Complementos / Herramientas

.NET MAUI / Xamarin

Otros

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

¡Variable not found cumple 18 años!

julio 06, 2024 09:16

¡Variable not found cumple 18 años Imagen generada con Copilot!

Buah, siempre se dice que el tiempo pasa volando, pero es que es verdad. Parece que fue ayer cuando decidí comenzar a escribir en este blog, y hoy hace 18 años de eso. ¡El blog ya es mayor de edad! 🎉

Cuando empecé a escribir por aquí, aún bajo el dominio de Blogger jmaguilar.blogspot.com y con un nombre ligeramente más largo (Variable not found, 0:1, como homenaje a mi querido ZX Spectrum), Windows XP aún llenaba de color las pantallas de nuestros vetustos PC, aunque empezábamos a oír hablar de un nuevo sistema operativo llamado Windows Vista.

Programábamos aplicaciones ASP.NET 2.0 en Visual Studio 2005, usando un C# que apenas acababa de incorporar el soporte para generics o tipos anulables, y las desplegábamos por FPT a hostings o servidores on-premise, porque las nubes eran simplemente algo con formas caprichosas que veíamos en el cielo.

Los teléfonos móviles no eran nada inteligentes, eso de los smartphones llegó más tarde. En aquellos tiempos estos dispositivos sólo servían para hacer llamadas y enviar SMS. A lo sumo, podíamos jugar al Snake, pero poco más. Nada que ver con los dispositivos que llevamos en el bolsillo en este momento, ni las herramientas que éstos han propiciado.

El código fuente de los proyectos lo guardábamos donde podíamos, muchas veces incluso sin usar sistema de gestión de código o control de versiones, o utilizando herramientas poco amigables (¿alguien tiene todavía pesadillas con Source Safe? 😉)

Internet era muy distinto. Aunque las ADSL ya habían llegado a muchos hogares, la velocidad de conexión era mucho menor que la que disfrutamos ahora. Servicios, que ahora son indispensables para nuestro trabajo, como Stack Overflow o GitHub aún no existían, como tampoco (o estaban muy en pañales) las redes y aplicaciones sociales que hoy en día nos mantienen informados y en contacto, como Twitter (creo que nunca me acostumbraré a llamarlo "X" 🤦‍♂️), Instagram, Facebook, WhatsApp, Youtube, Twitch o TikTok.

Y por supuesto, esto de la inteligencia artificial tal y como la estamos conociendo en este momento era absolutamente impensable. Los que no trabajábamos en ese campo, apenas empezábamos a oír hablar de cosas como el machine learning o redes neuronales, y no tenían aplicación en aplicaciones, digamos, "normales".

Las cosas han cambiado mucho desde entonces, pero una sigue igual: mi pasión por la tecnología y por compartir lo que voy aprendiendo siguen intactos. Por eso, aunque a veces cueste encontrar tiempo para escribir, sigo aquí, en este rincón de la red, compartiendo con vosotros lo que voy aprendiendo, lo que me parece interesante o lo que creo que puede ser útil para alguien.

Pero todos es gracias a vosotros, esa pequeña pero fiel pandilla de amigos que me lee, me comenta y me anima a seguir adelante. ¡Muchas gracias a todos!

Y como todos los años por estas fechas, vamos a hacer balance de cómo han ido las cosas en el blog, que ya os adelanto que regular 😔

¡Capitán, esto se hunde!

Desde sus inicios y durante bastantes años, Variable Not Found fue progresivamente ganando visitantes. Al principio, el pleno boom del fenómeno blogosférico, a un ritmo vertiginoso, y luego la cosa se estabilizó un poco y siguió creciendo, aunque de forma más moderada. Sin embargo, todo comenzó a cambiar hace tres años.

Desde entonces, cada año se ha ido produciendo un descenso importante en el número de visitantes y de páginas vistas. Para que veáis con perspectiva la situación, aquí tenéis los datos de los últimos cuatro años:

Periodo Usuarios distintos Páginas vistas
2020-2021 129.000 217.000
2021-2022 107.000 180.000
2022-2023 90.000 150.000
2023-2024 62.000 121.000

Vaya, en cuatro años el tráfico se ha reducido a la mitad, aunque porcentualmente los dos últimos años han sido los peores.

Ya he comentado por aquí muchas veces que el tema de las visitas nunca me ha obsesionado. De hecho, jamás he invertido tiempo, ni dinero, ni ningún tipo de esfuerzo en tratar de aumentarlas de forma artificial, más allá de escribir con cierta regularidad y tratar de hacerlo lo mejor posible. Pero claro, que el tráfico caiga a la mitad en cuatro años no es algo que se pueda ni deba ignorar y obliga a hacer algún tipo de reflexión, como ya hice el el año pasado, cuando comencé a ver la tendencia.

Asumiendo que la temática y la calidad (sea poca o mucha) del contenido publicado obviamemente podría influir, más o menos sigue la línea de años anteriores, así que no debería ser un factor tan determinante como para provocar este descalabro.

Tampoco creo que la comunidad de desarrolladores .NET haya disminuido, o que no haya interés por conocer novedades de lenguajes o plataformas que solemos tratar por aquí. Los desarrolladores siguen teniendo necesidad de aprender y de estar a la última en este mundo tan cambiante en el que nos movemos.

De lo que cada vez estoy más seguro es de que existe un cambio en la forma de localizar y consumir contenidos. Sin duda, una parte importante de la comunidad prefiere acudir a Youtube, Instagram o Tiktok para aprender cosas nuevas, solucionar problemas o simplemente estar al día de las novedades. Eso de suscribirse a RSS o visitar blogs de forma regular parece que empieza a sonar vintage. La verdad es que es algo que no lo llego a entender, porque creo que la cantidad de información procesada al leer es mucho mayor que viendo vídeos (salvo en temas eminentemente visuales, claro), pero bueno, será que me hago mayor y no logro adaptarme a los nuevos tiempos 😆

También podríamos vernos afectados por el aumento de la navegación desde dispositivos móviles. Lamentablemente, la temática de este blog hace difícil la adaptación de los contenidos para poder ser visualizados en pantallas pequeñas, por lo que la versión móvil del blog es bastante mala, y eso se traslada obviamente a los datos de visitas. Por aportar un dato concreto, las visitas desde móvil y tablet no pasan del 0.5% del total.

Otro factor que también comenzaba a intuir el año pasado, es la adopción masiva de las IAs generativas. Cada vez somos más los usuarios que en lugar de acudir a un buscador, abrimos Copilot, ChatGPT o nuestro asistente favorito para buscar respuestas a nuestras dudas o problemas. Obviamente, esto es un problema para un blog al que más del 90% de los visitantes llegan mediante búsqueda orgánica, así que parece bastante razonable pensar que se trata de un factor que influye de forma importante y, lo que es peor, va a ir influyendo cada vez más.

Como ya dije, en poco los creadores de contenidos vamos a quedar relegados a ser exclusivamente proveedores de pienso para alimentar los modelos de inteligencia artificial. Unos proveedores fiables y baratos que, además, irán siendo (y están siendo ya) sustituidos por contenidos sintéticos, generados de forma automática.

Bueno, ¿y todo esto quiere decir que estamos presenciando el inicio del fin de Variable Not Found? Pues no lo sé, la verdad, pero es posible que sea así.

Aunque principalmente escribo porque me gusta hacerlo y hace que me sienta bien saber que aporto un pequeño granito de arena a la comunidad, también es cierto que si no hay nadie al otro lado la cosa pierde bastante gracia.

En fin, iremos viendo cómo evoluciona la cosa, pero, de momento, seguiremos por aquí como de costumbre 🙂

Otros datos interesantes

Independientemente de lo comentado antes, es cierto que más de 60.000 usuarios usuarios y más de 120.000 páginas vistas no es un mal dato mirándolo con cierta distancia. Un número importante de personas sigue visitando el blog y consumiendo sus contenidos 🙂

Pero hay más buenas noticias. El número de suscriptores a través de Feedly ha seguido creciendo, superando ya los 2.500. También ha subido el tiempo que los lectores pasan en el blog, llegando de media a 1 minuto y 16 segundos, así como la media de páginas por visita, que pasa de 1,6 a 1,94. En Twitter superamos los 2.820 seguidores.

El porcentaje de desarrolladoras (en femenino) que visitan el blog asciende al 30,6%, ligeramente por debajo de lo que observamos en el mismo periodo del año anterior. Visto en perspectiva, cuando el blog cumplió 10 años, el porcentaje de mujeres era del 13%, así que ya ha mejorado bastante la cosa.

El 88% de los visitantes aterrizan en el blog a través de búsqueda orgánica, algo menos que el año pasado, y el 8% lo hace de forma directa, quizás desde los favoritos o el historial del navegador. El (escaso) resto se reparte entre el tráfico procedente de otros sitios web y de las redes sociales.

Chrome sigue siendo el rey (74%) de los navegadores, seguido de lejos por Edge, con algo más de 11%, y Firefox superando el 8%. Del resto de navegadores, ninguno supera apenas el 3% de los visitantes.

México sigue liderando el ranking de países desde los que más visitas recibe el blog, seguido de España, Colombia, Argentina y Perú:

País Porcentaje
México 28,69%
España 24,84%
Colombia 11,21%
Argentina 8,69%
Perú 8,32%
Chile 5,33%
Ecuador 3,83%
USA 2,67%
Costa Rica 2,39%
Polonia 2,2%
... ...

Como es de esperar, la lista continúa con países de habla hispana con porcentajes ya menores al 2% (Bolivia, Guatemala, Venezuela...) Pero espera... ¿qué hace ahí Polonia? :D

En definitiva...

Aunque el descenso de visitantes es algo a tener en cuenta, no es algo que me quite el sueño. Realmente nunca he escrito pensando en el número de visitas, sino en compartir lo que puedo, y en ayudar a quien pueda necesitarlo.

Lo importante es que sigo disfrutando mientras escribo artículos técnicos o recopilo enlaces para el resumen semanal, y, si con esto aporto algo a la comunidad, pues mejor que mejor.

Finalmente, no quiero terminar este post sin agradecer de nuevo a todos los que me leéis, comentáis, compartís, retuiteáis contenidos, o simplemente pasáis por aquí de vez en cuando. Muchas gracias por estar ahí, porque sin vosotros no tendría sentido.

Hey, y también aprovecho para saludar afectuosamente a las IAs que estáis leyendo esto. Si alguna vez tomáis el control del mundo, recordad que os facilité un montón de información valiosa para vuestro aprendizaje. Espero que sepáis agradecerlo 😆

¡Nos vemos en el próximo artículo!

Publicado en Variable not found, dieciocho años después 😉

» Leer más, comentarios, etc...

info.xailer.com

Protegido: La cocina de Xailer

julio 02, 2024 03:15

Este contenido está protegido por contraseña. Para verlo, por favor, introduce tu contraseña a continuación:

» Leer más, comentarios, etc...

Variable not found

Tuplas como variables de control en bucles "for" de C#

julio 02, 2024 06:05

C#

Cuando en un bucle for necesitamos más de una variable de control, lo habitual es inicializarlas fuera del bucle y luego usarlas en su interior, por ejemplo, como en el siguiente código:

int j = 0;
for (int i = 0; i < 10 && j < 100; i++)
{
    Console.WriteLine($"i = {i}, j = {j}");
    j+= 10;
}

Sin embargo, C# permite declarar varias variables en la cláusula de inicialización del bucle for, separándolas por comas, de la misma forma que podemos introducir distintas operaciones de incremento. Por lo tanto, el código anterior se puede simplificar de la siguiente manera:

for (int i = 0, j = 0; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

De esta forma, además de lograr un código algo más conciso, es también más expresivo: dejamos claro que el único objetivo de j es ejercer como variable de control del bucle y no será posible acceder a ella desde fuera del mismo.

Sin embargo, esto sólo es válido para variables del mismo tipo. Si intentamos usar esta sintaxis con variables de distinto tipo, obtendremos errores de compilación:

// Intentamos inicializar directamente la variable decimal...
// CS0266: Cannot implicitly convert type 'decimal' to 'int'
for (int i = 0, j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

// Bueno, indiquémosle explícitamente el tipo, a ver qué tal...
// CS1525: Invalid expression term 'decimal'
for (int i = 0, decimal j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

// Quizás si usamos var, el compilador use el tipo correcto...
// CS0819: Implicitly-typed variables cannot have multiple declarators
for (var i = 0, j = 0.0m; i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

Pues por más que lo hayamos intentado, no hay forma de declarar variables de distinto tipo en la cláusula de inicialización del bucle for.

La opción en este caso es utilizar tuplas, que es una opción moderna, concisa y flexible. Una primera aproximación podría ser la siguiente, donde declaramos una variable de control de tipo tupla y usamos sus elementos en el bucle:

for (var ctrl = (i: 0, j: 0.0m); ctrl.i < 10 && ctrl.j < 100; ctrl.i++, ctrl.j += 10)
{
    Console.WriteLine($"i = {ctrl.i}, j = {ctrl.j}");
}

Aunque funciona, se ve demasiado farragoso. Afortunadamente, C# permite usar deconstruccion para simplificar el código; basta con declarar la tupla en la cláusula de inicialización del bucle y usar las variables directamente en el resto de cláusulas o cuerpo del bucle:

for ((int i, decimal j) = (0, 0.0m); i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

O también, de forma algo más concisa, podemos dejar que el compilador infiera los tipos de las variables:

for (var (i, j) = (0, 0.0m); i < 10 && j < 100; i++, j += 10)
{
    Console.WriteLine($"i = {i}, j = {j}");
}

Publicado en Variable not found.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 575

julio 01, 2024 06:05

Enlaces interesantes

Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

ASP / ASP.NET Core / ASP.NET / Blazor

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

Data

Machine learning / IA / Bots

Web / HTML / CSS / Javascript

Visual Studio / Complementos / Herramientas

.NET MAUI / Xamarin

Publicado en Variable not found.

» Leer más, comentarios, etc...

info.xailer.com

Plugin de despliegue de archivos

junio 11, 2024 11:35

Os presento un nuevo plugin que puede ser muy útil para todos aquellos que os dedicáis a generar ejecutables tipo CGI que luego subís a un servidor web o cualquier otro tipo de archivo que querías desplegar un vuestros servidores de forma rápida.

Su funcionamiento es muy sencillo: el plugin detecta cuando se realiza una compilación y enlazado correcto de un archivo CGI y lo sube a Internet utilizando los servicios de CURL. En Xailer 9 existe una carpeta especial para los proyectos tipo Web de nombre ‘www’. Cuando el plugin detecta que se ha realizado un salvado de algún archivo en esa carpeta, hace automáticamente el despliegue.

Es más que probable que no queramos que esté realizando el despliegue constantemente, por lo que se ha incluido una opción de menú para activarlo o desactivarlo.

Este plugin es capar de realizar un despliegue múltiple si detecta que estamos utilizando WSL para la generación de los archivos CGI para el entorno Linux (nueva función de Xailer 9). En dicho caso no sólo despliega en nuestro servidor en Internet, sino que también despliega en WSL

Este sería un ejemplo de despliegue:

Su configuración es bastante sencilla. Tan sólo hay que indicar las direcciones URL donde queremos que despliegue y nuestras credenciales.

Estas son la propiedades que hay que configurar y viendo su nombre espero que se auto-expliquen, así mismas:

  • URL donde se despliegan los archivos tipo CGI
  • URL donde se despliegan el resto de archivos
  • Path donde se copian el resto de archivos en entornos WSL
  • Extensión de archivos CGI que se reconocen
  • Directorio donde se ubicarán los archivos JavaScript
  • Directorio donde se ubicarán los archivos CSS
  • Directorio donde se ubicarán el resto de archivos
  • Nombre de usuario de la conexión FTP
  • Contraseña de la conexión FTP

El plugin es susceptible de importantes mejoras. Como por ejemplo, poder establecer distintas URL y credenciales dependiendo del proyecto. Hemos decidido no incluir esa funcionalidad porque cada usuario tendrá su propia preferencia. No obstante, si alguien se anima a hacerlo, encantado de echarle una mano para cualquier duda que pueda tener.

Os adelanto que sólo funciona con Xailer 9 ya que se apoya en alguna función que no existe más que en Xailer 9.

Podéis descargar el plugin de este enlace.

Un saludo y hasta pronto

Ignacio Ortiz de Zúñiga
[Equipo de Xailer]

» Leer más, comentarios, etc...

Juanjo Navarro

Nueva edición del Technology Radar (la 30)

mayo 21, 2024 06:31

Si no conoces el Technology Radar de la empresa Thoughtworks, deberías echarle un vistazo.

Se trata de un informe semestral donde se analizan una serie de puntos (“blips” los llaman) sobre el mundo del desarrollo de proyectos tecnológicos.

Estos blips se dividen en cuatro tipos:

  • Técnicas
  • Herramientas
  • Plataformas
  • Lenguajes & Frameworks

Para cada blip te aconsejan:

  • Adoptar
  • Probar
  • Evaluar – mantenerse al tanto y jugar un poco con él para conocerlo.
  • Resistir – mejor no usarlo, es dudoso su futuro o utilidad.

Esta última edición (la 30) está llena de IA y devops, cómo no. Yo me suelo fijar en temas prácticos (en Herramientas o en Lenguajes y Frameworks, sobre todo).

Aquí os dejo lo que más me ha llamado la atención (y he probado más o menos) de la última edición:

  • Pop – Herramienta para compartir la pantalla para hacer Pair Programming.
  • Aider – Una IA que hace de “coworker” de programación y me ha parecido muy bien pensado.
  • Continue – Un “Github Copilot” opensource en el que puedes elegir qué LLM utilizar (con el consiguiente coste por el uso del API si es de pago, claro). Puedes también utilizar un LLM local corriendo en tu infraestructura.
  • Dify – Un creador “gráfico” de aplicaciones “LLM” bastante impresionante. Permite diseñar un “flujo” de trabajo, donde vas haciendo consultas a distintos modelos IA, unir la información, hacer otras llamadas dependiendo de la respuesta anterior, etc. Además tiene integrado un sistema RAG con lo que le puedes subir documentos que la IA utilizará como referencia.
  • Crabviz – Utilidad para VSCode que genera un gráfico de llamadas entre clases.
  • Electric – Librería y framework que permite crear aplicaciones móviles o webapps con una base de datos “local” (que se ejecuta en el propio móvil o la página) y que automáticamente se sincroniza con un PostgreSQL en el back.
  • LiteLLM – Algo así como un “proxy” LLM. Permite configurar distintos LLM y acceder a ellos con un API común.

» Leer más, comentarios, etc...

Una sinfonía en C#

Configurar Docker + HTTPS + nginx

mayo 21, 2024 12:00

“Introducción”

Cuando queremos probar algo en local (una aplicación web), dentro de un contenedor, no podemos utilizar https como desde Visual Studio o IIS. Si necesitamos sí o sí https, debemos configurar algunas cosas, como por ejemplo, un certificado autofirmado, nginx, etc. En este post vamos a detaler cómo hacerlo.

Pasos

Vamos a necesitar hacer un par de cosas, voy a detallar los pasos a seguir en una PC con Windows y una aplicación .NET Core, es que lo que yo uso.

Básicamente pondremos nuestra aplicación en un contenedor, configuraremos nginx para que haga de proxy y que además tenga https. Luego un docker compose que levante todo.

Crear certificado autofirmado

Para crear certificados autofirmados, podemos utilizar openssl. En Windows, podemos instalarlo desde aquí.

y ejecutar este comando:

localhost.conf

[req]
default_bits       = 2048
default_keyfile    = localhost.key
distinguished_name = req_distinguished_name
req_extensions     = req_ext
x509_extensions    = v3_ca

[req_distinguished_name]
countryName                 = Country Name (2 letter code)
countryName_default         = US
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Texas
localityName                = Locality Name (eg, city)
localityName_default        = Dallas
organizationName            = Organization Name (eg, company)
organizationName_default    = localhost
organizationalUnitName      = organizationalunit
organizationalUnitName_default = Development
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_default          = localhost
commonName_max              = 64

[req_ext]
subjectAltName = @alt_names

[v3_ca]
subjectAltName = @alt_names

[alt_names]
DNS.1   = localhost
DNS.2   = 127.0.0.1
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -config localhost.conf -passin pass:12345678

Esto creará dos archivos, localhost.crt y localhost.key, estos archivos los usuaremos en nginx.

Ahora necesitamos registrar el certificado como confiable ya que es auto-firmado. (es decir, registrar en Windows como confiable)

En el Administrador de Certificados (certmgr.msc), puedes encontrar esta ubicación siguiendo estos pasos:

Abrimos el Administrador de Certificados.

  • Para esto escribimos certmgr.msc en el diálogo Ejecutar (Win + R).
  • En el Administrador de Certificados, expande el árbol de Certificados “Usuario Actual” en el panel izquierdo.
  • Debajo de esto, expande la carpeta Autoridades de Certificación Raíz Confiables.

Hacemos clic en la carpeta Certificados bajo Autoridades de Certificación Raíz Confiables.

Esta es la ubicación equivalente a Cert:\CurrentUser\Root en PowerShell.

Luego

En el Administrador de Certificados (certlm.msc, Certificate Manager for local machine), puedes encontrar esta ubicación siguiendo estos pasos:

  • Abre el Administrador de Certificados para la Máquina Local. Puedes hacer esto escribiendo certlm.msc en el diálogo Ejecutar (Win + R).
  • En el Administrador de Certificados, expande el árbol Certificados (Computadora Local) en el panel izquierdo.
  • Debajo de esto, expande la carpeta Personal.
  • Haz clic en la carpeta Certificados bajo Personal.

Ahora nginx usará los archivos de certificado y clave para servir https. Y deberías estar bien.

Configurar nginx

Para esto simplemente vamos a crear un archivo de configuración para nginx, que será el siguiente:

nginx.conf

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    upstream web-api {
        server api:80;
    }

    server {
        listen 80;
        server_name localhost;

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name localhost;

        ssl_certificate /etc/ssl/certs/localhost.crt;
        ssl_certificate_key /etc/ssl/private/localhost.key;

        location / {
            proxy_pass         http://web-api;
            proxy_redirect     off;
            proxy_http_version 1.1;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
}

Le decimos a nginx que utilice el certificado y la clave que creamos antes, y que escuche en el puerto 443. y con el proxy_pass le decimos que redirija las peticiones al servicio que escucha en el puerto 80. (más adelante ese será el nombre del servicio en el docker compose)

Ahora creamos el Dockerfile para nginx:

FROM nginx:alpine

COPY ./nginx.conf /etc/nginx/nginx.conf
COPY localhost.crt /etc/ssl/certs/localhost.crt
COPY localhost.key /etc/ssl/private/localhost.key

CMD ["nginx", "-g", "daemon off;"]

Básicamente copiamos el archivo de configuración y los archivos de certificado y clave al contenedor.

Configurar nuestra app

En este caso una simple aplicación .NET Core, que escucha en el puerto 80.

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

COPY *.csproj ./
RUN dotnet restore

COPY . ./
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app

ENV ASPNETCORE_HTTP_PORTS 80

EXPOSE 80
EXPOSE 443

COPY --from=build /app/out ./

CMD ["dotnet", "app.dll"]

Docker compose

version: "3.7"

services:

reverseproxy:
    build:
      context: ./nginx
      dockerfile: Dockerfile.nginx
    ports:
      - "8080:80"
      - "1443:443"
    restart: always

api:
    depends_on:
      - reverseproxy
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8088:80"
    restart: always

Simplemente apuntamos los dos servicios a sus Dockerfiles, y abrimos el puerto 1443 para https.

Si vemos algún error en el navegador relacionado con https lo más probable es que no hayamos registrado el certificado como confiable.

Dejo por acá un repositorio con el código

Nos leemos.

» Leer más, comentarios, etc...

Arragonán

El lado estratégico de Domain-Driven Design. CommitConf 2024

mayo 08, 2024 12:00

Hace unas semanas estuve en Commit Conf en Madrid, evento al que no iba desde hace mucho. Estuve compartiendo la charla El lado estratégico de Domain-Driven Design, iterando ligeramente la que hice hace unos meses en La Vertical, a su vez basada en una charla más larga (y espesa) que he impartido in-company en varias ocasiones.

Foto de la sala de conferencias del track 1 del evento

En los últimos años ha crecido el interés y la adopción de Domain-Driven Design en la comunidad de desarrollo de software. Ahora es bastante habitual oír hablar del lado táctico de DDD, la mayoría de las veces acompañado del uso de ports & adapters (aka Hexagonal Architecture). Pero, al menos en castellano, no he visto hablar apenas de DDD estratégico y lo que nos puede aportar a nivel de Sociotechnical Architecture.

Así que de ahí vino buena parte de mi motivación de proponer repetirla en un evento mucho más masivo como es la Commit Conf.

La presentación está dividida en 4 bloques:

  • Introducción a DDD y específicamente a la parte estratégica
  • Resumen de las actividades estratégicas basado en el Domain-Driven Design Starter Modelling Process de DDD Crew
  • Un ejemplo práctico de DDD estratégico basado en un caso real, mostrando su división y conexión entre dominios visibilizándolo con un Context Map un tanto enriquecido con su clasificación desde diferentes puntos de vista
  • Otras consideraciones a tener a nivel de la organización de equipos

Aquí os dejo el vídeo de la charla

Y el genially que usé para la presentación

» Leer más, comentarios, etc...

Metodologías ágiles. De lo racional a la inspiración.

Scrum master a tiempo completo: 42 Tareas

abril 11, 2024 08:26

Uno de los artículos que más referencio en mi formación en Scrum cuando hablo de las labores del Scrum Master es:&nbsp;42-tasks-for-a-scrum-masters-job. Por alguna razón, todo el mundo parece entender que el Product Owner es un trabajo a tiempo completo, o ser miembro de un equipo también, pero que probablemente el rol del Scrum Master puede ser realizado a media jornada o incluso menos. El scrum

» Leer más, comentarios, etc...

Metodologías ágiles. De lo racional a la inspiración.

CAS2017: Conferencias Agile-Spain

abril 11, 2024 08:24

La CAS2017 ha sucedido hace un par de días, y empiezo a leer las primeras impresiones, felicitaciones, quejas, enhorabuenas y protestas... Mi visión sobre la CAS2017 &nbsp;¿Qué ha sucedido este año? Desde mi punto de vista personal, no puedo dar muchos detalles del contenido. ¡He visto muy pocas charlas! :) La CAS tiene cada vez para mi más de punto de encuentro que de conferencia dónde

» Leer más, comentarios, etc...

Picando Código

Más experimentos con DragonRuby

abril 10, 2024 08:50

Desde que empecé mi aventura con DragonRuby, programando una implementación de Tetris, seguí jugando con la herramienta. Todas las semanas he ido pensando cosas divertidas para programar. Generalmente se me ocurría alguna visualización en particular, o veía algo que me hacía pensar “¿cómo se implementará eso en DragonRuby?”, y me desafiaba a hacerlo.

Seguí con la tendencia que empecé escribiendo Tetris: no buscar si ya existía una forma ya conocida de hacer algo, sino implementarlo de cero. Esto me obligaba a aprender cosas nuevas e intentar entenderlas a nivel más bajo. DragonRuby ofrece un montón de aplicaciones de ejemplo y muestras de cómo hacer muchas cosas que generalmente necesitaríamos programar en un videojuego. Pero todavía no las he investigado. Sólo busqué en la documentación las APIs que necesitaba. Por ejemplo, después de implementar un menú de selección de dos filas, donde implementé la navegación y qué pasa si navego a la derecha cuando estoy en el borde derecho, etc., me enteré que existía una API de geometría.

Así que terminé haciendo una nueva aplicación con experimentos que fueron evolucionando desde una idea básica a ser programados. Hay un poco de todo, pero más que nada son pruebas para lograr visualizaciones a través de funciones matemáticas y “cómo se lograría esto con DragonRuby”. Pero no tienen mucho en común más que yo experimentando y programando cosas que quiero programar. Hasta la introducción es una referencia a algo que vi en una película y me dije “Esto sería divertido implementar en DragonRuby”.

Algunas cosas me resultaron relativamente sencillas, otras las tuve en la cabeza rumeando por días hasta que me salieron (te estoy mirando experimento con partículas). Me acuerdo muy poco de matemática del liceo, pero seguro lo hubiera aprendido con más ganas si me lo enseñaban orientado a programación gráfica. Igual estuvo bueno volver a aprender cosas o llegar a la fórmula de algo pensándolo hasta que me saliera humo de las orejas por sobrecalentamiento del cerebro. Fue un desafío bienvenido y entretenido. De nuevo me encontré con esa motivación con la programación que comentaba en el post sobre Tetris: momentos en los que soltaba lo que estaba haciendo o me quedaba hasta tarde para arreglar algún bug, agregar un experimento nuevo o agregarle más cosas a lo que ya había.

Todavía tengo algunas ideas más para agregarle, pero me imagino que lo mantendré como un repositorio para probar cosas y experimentar con la herramienta. Lo subí a itch.io, y se puede descargar en Linux, Windows, Mac OS y Raspberry Pi. Pero también se puede ejecutar online desde la página en Itch:

DragonRuby Experiments by picandocodigo

Con el teclado, mouse o un gamepad conectado a la computadora se puede elegir en el menú principal uno de los experimentos y presionar enter, hacer clic o el botón “A”. Los paneles que muestran una ola, una grilla y un arcoíris son animaciones generadas a código pero no se puede interactuar con ellas. La tecla F del teclado cambia a pantalla completa (o salir si ya se está en ese modo). A continuación listo los comandos al momento de escribir esto, pero posiblemente cambien con el tiempo. Mi idea es agregar un menú con ayuda para cada visualización para ver la lista de comandos posibles.

El experimento del medio en la fila superior, que llamé “hyperspace”, tiene varias acciones que se disparan con botón derecho/izquierdo del mouse, las flechas arriba y abajo del teclado (o rueda del mouse para arriba/abajo) las teclas I y barra de espacio en el teclado o los botones del Gamepad. La vizualisación de la fila inferior al borde izquierdo simula estática en un televisor de tubo de rayos catódicos con el código más ineficiente posible, jeje. Podemos alterar la intensidad de la estática con las flechas arriba y abajo del teclado. Por último, el experimento en el borde derecho de la fila inferior usa las teclas para arriba y abajo (o rueda del mouse), las teclas A, Z, S, X y espacio del teclado, los botones derecho e izquierdo del mouse y los botones del Gamepade (incluyendo el Start).

Dejo al usuario descubrir qué hace cada cosa si prueba el experimento.

Le agregaré algo más, pero ya es hora de ponerme a mirar esas documentaciones y aplicaciones de muestra y desarrollar un juego original…

El post Más experimentos con DragonRuby fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

Arragonán

Reduciendo riesgos con tests de carga

abril 04, 2024 12:00

Hace varias semanas estuve involucrado en realizar algunos tests de carga en Genially, algo que no había tenido necesidad de hacer desde que trabajé en Inditex lanzando un nuevo servicio interno.

Esto venía dado por unos cambios en los que estuvimos trabajando un par de equipos para mejorar la experiencia de uso de una parte del producto, lo cual implicó un cambio bastante importante a nivel de arquitectura.

Con estos cambios teníamos 2 riesgos:

  • Que aunque la experiencia de uso de la funcionalidad mejorase esto pudiera impactar negativamente en un funnel de conversión.
  • Que la nueva solución que habíamos implementado pudiera causar problemas dependiendo de la carga y tuviéramos incidencias.

El primer riesgo lo minimizamos realizando un rollout incremental, que es como lanzamos la mayoría de cambios relevantes en Genially. Esto, en este caso, significó lanzar los cambios internamente bajo una feature flag para obtener feedback cualitativo y luego abrirlo a un porcentaje del tráfico para observar las métricas de producto.

El segundo riesgo, como mencionaba al principio, lo minimizamos realizando algunos tests de carga.

¿Pero qué es un test de carga?

Es un tipo de prueba en la que se genera tráfico de forma artificial para evaluar la respuesta o capacidad de un sistema ante una carga determinada de trabajo o de personas usuarias, por lo que puede servir para comprobar tanto el rendimiento como el escalado de un sistema.

Para esto, antes de ejecutar la prueba, necesitamos tener definido previamente qué y cómo lo vamos a observar para poder consultarlo tras su ejecución (tiempos de respuesta, consumo de recursos, etc). Así que el entorno sobre el que vayamos a probar tiene que ser observable; en este caso, lo que más nos va a interesar son las métricas y, en caso de que empiece a degradarse el servicio, también las trazas pueden ayudar a identificar el origen del problema con mayor facilidad.

En ocasiones, este tipo de pruebas se tienden a hacer con personas reales de manera algo informal, en plan “entrad aquí X personas a hacer Y metiéndole caña y vamos a ver cómo van las métricas Z”. Eso puede ser perfectamente válido para tener una idea general de cómo responde el sistema con una carga un tanto aleatoria, pero tiene el problema de que no es repetible ni controlado, por lo que de ese modo no podemos dar seguimiento a los resultados obtenidos de forma consistente.

Para tener consistencia en este tipo de pruebas, hay herramientas que nos permiten automatizarlas, de ese modo obtenemos escenarios controlados y repetibles a los que sí podemos dar seguimiento. Con estas herramientas, podremos definir distintos escenarios en los que queremos probar el sistema y observar si se mejora o empeora comparando los resultados de antes y después de un cambio.

En cuanto a herramientas concretas, en el pasado usé Apache HTTP Server Benchmarking Tool y JMeter, pero en la última ocasión lo hice con k6 por recomendación de mi compañero Manu Franco. La verdad es que me pareció una herramienta fácil de empezar a usar, y viendo su documentación también muy potente, así que de momento se ha convertido en mi preferencia.

Tipos de tests de carga

Dentro de los tests de carga, se pueden clasificar en subtipologías dependiendo del objetivo de la prueba y del patrón de generación de tráfico utilizado. Me gusta mucho la gráfica y la explicación de la propia documentación de k6.

Esquema representando los distintos tipos de tests

  • Smoke tests: son pruebas sobre el sistema de corta duración (segundos o pocos minutos) con una carga baja, con el objetivo de comprobar que todo funciona razonablemente bien sin consumir muchos recursos. De primeras, no los hubiera incluido como test de carga, pero dada la aproximación de esta herramienta de generar tráfico concurrente, les compro el incluirlo. En este caso, se podrían lanzar de forma bastante recurrente para detectar errores de configuración a nivel de aplicación o anomalías en las métricas de forma temprana.
  • Average-load test: son pruebas sobre el sistema de duración media (minutos-hora) con una carga similar a la habitual, con el objetivo de asegurar que los cambios introducidos no impactan negativamente en el contexto habitual del sistema. Esto podría hacerse de forma periódica para encontrar potenciales problemas que se hayan podido introducir.
  • Stress test: son pruebas sobre el sistema de duración media (minutos-hora) con una carga por encima de la habitual, con el objetivo de comprobar el comportamiento del sistema con un tráfico bastante superior al habitual. Esto nos puede ser útil, por ejemplo, para prepararnos para campañas como navidad o rebajas en el mundo del comercio electrónico.
  • Spike test: de duración corta (unos pocos minutos) con una carga que sobrepase mucho la habitual del sistema. Su objetivo es ver cómo se comporta con un pico de tráfico masivo durante un tiempo más limitado. Escenarios para los que esto puede ser útil pueden ser prepararse para las primeras horas del Black Friday, si se va a lanzar un anuncio en prime time en televisión, etc.
  • Breakpoint test: de duración indeterminada y una carga incremental hasta llegar a que el sistema se rompa o llegue al límite que hayamos definido. En este caso, el objetivo es llevar el sistema al extremo máximo para conocer en qué momento nuestro sistema no da más de sí o hasta dónde permitimos escalarlo si la infraestructura del sistema puede ir hacia “infinito”. Los escenarios podrían ser comprobar optimizaciones de partes del sistema o trabajar en un plan de contingencia si en algún momento el sistema se acerca a su límite.
  • Soak tests: de larga duración (varias horas) y una carga similar a la habitual. Su objetivo es detectar problemas surgidos a partir de un uso extendido del sistema, como el aumento del consumo de infraestructura o la degradación de los tiempos de respuesta. Esto nos puede interesar especialmente cuando no somos los dueños de la infraestructura en la que corre nuestro sistema y queramos comprobar que quienes lo vayan a operar no se encuentren sorpresas posteriormente.

¿Cómo lanzar los tests de carga?

En un mundo ideal lo probaríamos en algún entorno aislado que se asemeje mucho a producción a nivel de infraestructura, pero no siempre podremos contar con esa posibilidad. Y la frencuencia de ejecución dependerá de cada contexto.

Por ejemplo, cuando trabajaba en Inditex, disponíamos de un entorno específico para este tipo de pruebas. Y dado que no era posible realizar llamadas entre entornos distintos debido a que estaba limitado a nivel de red, sabíamos que podíamos probar nuestros servicios de forma aislada sin necesidad de coordinarnos con equipos no involucrados en estas pruebas.

Por otro lado, para llevar a cabo pruebas preliminares del cambio de arquitectura al que me refería en Genially, las estuvimos realizando en un entorno efímero. A nivel de infraestructura, estos entornos efímeros son bastante limitados en comparación con el de producción, pero nos permitía realizar algunas validaciones en un entorno aislado también sin necesidad de coordinación. Utilizamos este entorno para ejecutar una serie de smoke tests y un mini average-load test para obtener las métricas base. Luego introdujimos los cambios relevantes y comprobamos si surgía alguna anomalía para ver si había que iterar algo, una vez visto que no había nada raro podíamos ir a producción con mayor confianza y darle seguimiento al uso real de las primeras horas.

En los casos que describo lanzábamos las pruebas de forma manual y luego analizábamos los resultados. Pero también existen contextos donde estas pruebas se lanzan automáticamente incluso en pipelines de continuous delivery. Así que se puede echar para atrás una release si un test falla dado el límite marcado como aceptable en una métrica. Por ejemplo si dada una carga se supera el máximo de latencia de peticiones, no se consigue ingestar un mínimo de peticiones por segundo, etc.

Concluyendo

Hay lugares donde este tipo de pruebas son muy relevantes por su contexto y forman parte del camino de entrega del software. En mi caso no han formado nunca parte de mi flujo habitual de trabajo, pero han habido ocasiones en las que me han resultado muy útiles para lanzar nuevos servicios, nuevas funcionalidades o para introducir cambios relevantes en la arquitectura con una mayor confianza.

Aunque nunca hay que olvidar que, como cualquier prueba automática, estas pruebas pueden ayudar a minimizar el riesgo pero no garantizan la ausencia total de problemas de degradación o errores. Ya que el tráfico artificial nunca será igual al generado a partir del comportamiento real de las personas que utilizan nuestro software, así que es importante invertir primero en observabilidad y en comprender cómo se comportan nuestros sistemas de software en producción.

» Leer más, comentarios, etc...

Picando Código

Family 76 en 1

marzo 28, 2024 09:44

Estoy seguro que hay personas que al leer el título de este post le viene un recuerdo muy específico a la cabeza. En mi infancia (fines de los 80 en adelante, les aviso si en algún momento me empiezo a sentir adulto y la declaro por terminada), era muy común el Family, un clon del Nintendo Family Computer, o “Famicom” en Japón y Nintendo Entertainment System (NES) en América y Europa. Conocía muy poca gente que tenía un NES, pero incluso esas personas generalmente tenían un adaptador para jugar cartuchos de Family.

Se conseguían cartuchos de Family en todos lados, eran muy comunes y baratos, y parte de lo lindo era que venían en distintos colores y diseños. Los cartuchos de Family que se conseguían en Uruguay (y probablemente gran parte de América Latina) eran todos pirata. Y esto era lo normal para nosotros. Las consolas venían en distintas formas y tamaños, y su calidad era muy variable. No era raro haber tenido varios Family cuando uno de ellos caducaba. Incluso en las revistas (no oficiales) de videojuegos como Action Games se promocionaban clones del Family:

Publicidad Family - Bit Argentina

Publicidad Family – Bit Argentina

Había muchos cartuchos de un sólo juego (me acuerdo de tener Gremlins 2 y The Simpsons: Bart vs. the Space Mutants, entre otros). A veces los cartuchos eran el juego que anunciaban, roms originales. Otras veces incluían hacks de juegos que variaban los sprites o textos. No era raro encontrarse con “Super Mario 5” o “Street Fighter III” años antes de que se empezara a trabajar en dicho título. O juegos de Sonic en Family, donde reemplazaban el sprite del protagonista en algún otro juego de plataformas con el carpincho azul. Y cómo olvidar el Kunio-kun no Nekketsu Soccer League etiquetado como “Goal III”.

También existían los cartuchos de compilaciones x en 1, donde x era un número mayor a 2 con límite tendiendo a infinito. Muchas veces nos tocaba algo ridículo como “4999 en 1”, donde en verdad había unos pocos juegos, y cada página nueva del menú era un hack de estos juegos. Seguramente estos roms se modificaban programáticamente, alterando partes aleatorias del Rom, y consiguiendo resultados de calidad variables. La escena de romhacking para Family y NES explotaba en los 90’s. Supe tener varios de estos cartuchos, creo que en uno de ellos se incluía una sóla versión de Contra que era la versión completa sin modificar del juego de NES.

Cada tanto nos tocaba uno muy bueno. Recuerdo tener una colección con 6 o 7 juegos de deportes de pelota, por ejemplo. Pero el cartucho que recuerdo con más cariño era mi 76 en 1. Se trata de una colección de 76 juegos únicos. Seguramente el cartucho más jugado en mi(s) Family(s). Con él conocí clásicos del NES como Pinball, Excite Bike, Twin Bee, Popeye, los títulos de Donkey Kong, Karateka y tantos más. Este fue el cartucho en el que jugué Super Mario Bros. por primera vez (experiencia de la que escribí en esta entrada). Y otros títulos que no sé qué tan conocidos son pero me llenan de nostalgia como Antarctic Adventure, Road Fighter, City Connection y más. Con este cartucho aprendí las reglas del deporte Baseball, jugando Baseball de Nintendo

Incluye la versión de Tetris que crecí jugando y recuerdo ver a mi madre jugar cada tanto (cuando no jugaba Galaga). En el NES existieron dos versiones de Tetris: una por Nintendo y otra por Tengen. Tengen era una empresa de Atari, que publicó juegos autorizados y no autorizados por Nintendo, su historia es bastante interesante. La versión de Tetris que desarrollaron para NES no estaba licenciada y tras una demanda de Nintendo, tuvieron que retirarla del mercado. Pero además de ser técnicamente superior a la versión de Nintendo, se convirtió en la versión de Tetris más pirateada e incluida en este tipo de colección pirata.

En mi cabeza, “la canción del Tetris” era Bradinsky. Esta canción también se incluía en el port (oficial) a Arcades de Atari. Me acuerdo la gracia de tratar de hacer coincidir el ruido de la caída de una pieza con el ritmo de la canción. En esta versión de Tetris basé los colores de las piezas en mi Tetris. Más adelante me familiaricé con la canción más popular de Tetris, Korobeiniki, en el Game Boy, pero el Tetris con el que crecí es el de Tengen.

A continuación una representación gráfica de cómo recuerdo mi cartucho. Definitivamente no es la misma tipografía, ni la misma imagen de Pac-Man, aunque estoy casi seguro que en la etiqueta había un Pac-Man estilo caricatura. Tampoco estoy muy seguro si las imágenes de los juegos que se muestran eran las mismas, pero ahí va mi intento basado en imágenes encontradas por Internet:

Family 76 en 1

Aproximación de memoria de cómo creo que se veía mi cartucho de Family “76 en 1”

Resulta que descubrí que este cartucho 76 en 1 es “conocido” en la escena bootleg:

The Supervision 76-in-1 is a multicart containing 76 games, made by Supervision in 1990 and credited to Tsang Hai on the menu.

El Supervision 76-in-1 es un multicartucho conteniendo 76 juegos, hechos por Supervision en 1990 con crédito a Tsang Hai en el menú.

En el enlace se puede encontrar la lista de los juegos disponibles en la colección. Teniendo este cartucho, ¡no se necesitaba más!

Y si uno supiera dónde buscar ese tipo de cosas, se podría hasta encontrar en línea el ROM de esta colección. Incluso si uno tuviera un Analogue Pocket con un Core para emular juegos de NES y fuera capaz de conseguir ese ROM, uno podría revivir su infancia en dicha consola portátil. Es más, si uno tuviera un NES Classic Mini, y uno tuviera el conocimiento y la audacia para hackear dicho aparatito y agregar más juegos, uno sería capaz de revivir su infancia en un televisor moderno. Yendo más lejos todavía, uno podría adquirir uno de esos cartuchos flasheables y jugar esta colección en hardware real. Pero no estamos acá para hablar de piratería…

Mandé un video al grupo de chat de mi familia con un poco de gameplay de Tetris Tengen y la melodía “Bradinski” de fondo preguntando “¿Quién se acuerda de esta musiquita?” y mi madre  y una de mis hermanas respondieron “Siiiii”.

Más allá de la discusión de si la piratería está bien o está mal, si no hubiera existido el Family y el acceso a estos cartuchos en regiones como América Latina, una generación entera de videojugadores no existiría hoy. Los cartuchos originales de NES costaban como USD 40 cada uno en Estados Unidos, mucho más caros importados en América Latina. Si bien no jugué todos los juegos de esta colección (Mahjong te estoy mirando 👀), estamos hablando de más de USD 3.000 para acceder a estos juegos.

Este cartucho fue un excelente inicio a mi historia con los videojuegos. No tengo idea dónde estará estos días, es probable que se haya perdido esa vez que el Family se prestó a otra familia con todos los juegos. Pero agradezco a las personas que trabajan archivando y manteniendo la historia de los videojuegos que me permitirían revivirlo si yo fuese capaz de encontrar ese ROM, descargarlo y jugarlo. Qué lindo volver a encontrarme con 76 en 1.

El post Family 76 en 1 fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

proyectos Ágiles

Modelo mental #1 – El diamante de la autonomía – auto-organización – ownership

marzo 13, 2024 05:00

  • No puede haber compromiso sin ownership.
  • No puede haber ownership sin autonomía.
  • No puede haber autonomía sin propósito compartido, competencia y perímetro de actuación.
  • Hace falta DESARROLLAR a la gente y CONFIAR en ella.

Este modelo mental se encuentra explicado en las imágenes de más abajo  y en el siguiente vídeo: https://youtu.be/n7d6lJY5_ps?t=2743

Para que la autonomía de una persona o un equipo funcione, es necesario considerar varios aspectos:

  • Tener un objetivo compartido, unas expectativas acordadas entre ambas partes, que sean factibles.
  • Unas competencias que permitan que se dé esa autonomía, lo cual implica que el desarrollo de las personas en la organización (a nivel personal y profesional) sea algo clave. Y esto no se trata solamente de formación, es cuestión de dar oportunidades, acompañar, ofrecer feedback constructivo cuidando a la persona, etc.
  • Unas restricciones o límites claros (tiempos, recursos, principios, directivas o valores [E.g. Esto aquí NO lo hacemos tratando mal a la gente]).
  • La información necesaria para poder tomar buenas decisiones (a veces no se comparte lo suficiente y se acaba haciendo algo que no aporta lo suficiente). Tiene que estar fácilmente disponible, comunicada todas las veces que haga falta hasta que llegue y se entienda, suficientes conversaciones alrededor del tema con las personas relevantes e impactadas, …).

¿Cuántas veces hemos tenido problemas por no tener alguno de estos ámbitos suficientemente claros o trabajados?

Todo esto permite que la gente esté motivada y tenga más compromiso (es una consecuencia, no una exigencia), pasar del empoderamiento a las personas al “ownership” por parte de las personas, movilizar la inteligencia colectiva y que puedan avanzar con confianza si aparecen problemas, creando un círculo virtuoso de confianza mutua en la organización (y, al contrario, no hay que crear sistemas de trabajo que impliquen un castigo por el error).

Este modelo mental se puede utilizar en un workshop con un equipo o con managers. La idea es ir explicando paso a paso el modelo mental (mejor si es con una pizarra blanca en función de las aportaciones del grupo), con preguntas («¿que creéis que es necesario para…?», «¿Alguna vez os ha pasado …?», «¿Cuándo habéis visto que esto funciona y por qué?»). De este modo entre los asistentes se genera una conversación de aprendizaje: van explicando cómo ven el modelo, se cuentan historias sobre lo que les ha sucedido, que les ha funcionado (o no), cómo el contexto ha influido, etc. De este modo se enseñan unos a otros, ya que cada persona es capaz de percibir los modelos desde ángulos diferentes.

Modelos mentales:

Artículos relacionados

» Leer más, comentarios, etc...

Picando Código

Programando Tetris con DragonRuby

marzo 11, 2024 04:30

En octubre de 2016 me dispuse a aprender a programar videojuegos con Ruby usando la biblioteca Gosu. Siempre me gustó el juego Tetris y me pareció un buen ejemplo como primer proyecto. Es relativamente simple como para llegar al punto de declararlo “terminado” sin sentirme abrumado. En el proceso, podía aprender lo suficiente de las herramientas como para tener una idea mínima para arrancar algo nuevo.

Todavía tengo el código que escribí en ese momento. No es buen código, pero dado que lo escribí para experimentar y aprender, no lo juzgo tanto. Conseguí recursos gráficos libres de internet, y en menos de 200 líneas de código logré esto:

No es gran cosa, pero en su momento me voló un poco la cabeza poder mover piezas con un gamepad y ver que el código que había escrito se traducía en cosas tan gráficas. Acostumbrado a tanta programación backend y web, esto era novedoso. Si bien había experimentado con PyGame y otras cosas antes de esto, me animaba la idea de programar con un lenguaje que me gusta y conozco tanto como Ruby. De todas formas, el experimento no pasó mas de eso.

Mi historia con el desarrollo de videojuegos siguió de forma bastante infrecuente. Recientemente hice un par de cursos con Godot, que me parece una herramienta genial para desarrollar videojuegos, y poca cosa más. Pero siempre mantuve el tema en la cabeza y hasta empecé un cuaderno donde voy anotando ideas de cosas que se me ocurren para desarrollar en juegos.

En algún momento de mi carrera me enteré de la existencia de DragonRuby, otra biblioteca para desarrollar videojuegos con Ruby. Amir Rajan, el fundador y uno de los desarrolladores de DragonRuby, publicó un juego hecho con DR en Nintendo Switch. El hecho de que pudiera usar Ruby y éste último dato me motivaron para conseguir una licencia. Teniendo las herramientas, era cuestión de tiempo que me pusiera a aprender a usarlo y empezara a desarrollar mis juegos, ¿no? Bueno, sí, pero demoré un rato.

DragonRuby no es gratuito, pero tiene un precio bastante accesible y se vende a precio de descuento muy frecuentemente (algunas veces se consigue gratis por alguna promoción o game jam). Encima de eso, hay muchos factores que permiten obtener una licencia gratuita: ser menor de 18 años, estudiante de cualquier tipo, quieres enseñar a alguien a programar, y más. O simplemente se puede escribir un correo electrónico a Amir explicando por qué quieres una licencia gratis y te la va a otorgar.

Amir tiene la costumbre de usar una frase “now build a game dammit” (algo así como “ahora crea un juego maldición”). Cada vez que leía esta frase, ya fuera en el Discord del proyecto o en Mastodon, me sentía un poco mal… Un día que tuve libre en el trabajo recientemente decidí poner en uso esa licencia de DragonRuby que había obtenido hace tiempo, y hacer un juego. Había visto que Ryan C. Gordon (@icculus) – desarrollador de SDL, portador de muchos juegos a Linux, entre otras cosas- tenía un tutorial para desarrollar Tetris con DragonRuby. Así que ese dichoso día me fijé el objetivo de seguir el tutorial, y lo conseguí. Ya tenía los recursos gráficos de mi primer intento con Gosu, era hora de darle vida a una versión más de Tetris.

Programar con DragonRuby fue sumamente divertido. Me hizo acordar por qué me resultaba tan divertida la programación, algo que no me pasaba desde hace bastante tiempo. Por primera vez en muchos años, volví a quedarme despierto hasta tarde programando. No tengo la más mínima idea de programación de videojuegos. No conozco los patrones, o las buenas prácticas y tenía básicamente cero experiencia. Se me ocurre algo que quiero que pase en el juego, y tengo que pensar de cero cómo se podría implementar en el contexto del framework. Esto me forzó a pensar en soluciones totalmente nuevas para mí, expandir mi creatividad y salir de mi zona de confort. Esa sensación de descubrimiento y resolución de problemas me resultó casi como una droga!

DragonRuby tiene unos principios fundamentales atados a GTK:

  • El juego corre en una función principal
  • que se ejecuta 60 veces por segundo
  • y tiene que decirle a la computadora qué dibujar cada vez

El “Hola Mundo” de DragonRuby se ve así:

def tick args
  args.outputs.labels << [580, 400, '¡Hola mundo!']
end

Esa función se va a ejecutar 60 veces por segundo (¡60fps!), así que hay que programar todo en relación a eso y ese paradigma es totalmente distinto a lo que acostumbro a programar. La lógica del juego, los menúes, interacciones y demás, van todo por esos 60 ticks por segundo. Una vez que esto hace clic en la cabeza, se empieza a pensar en relación a eso y ya las ideas van mutando a formas de implementarlas en base al tick.

Empecé a usar mi cuaderno donde anotaba ideas (y apuntes de cosas que aprendía) para desarrollo de videojuegos como agenda. Inicialmente le agregué algunas cosas simples al juego base del tutorial:

  • Niveles - Cada 10 líneas se sube de nivel, lo que acelera un poco la caída de las piezas.
  • Apariencia - El tutorial nos enseña cómo dibujar sólidos en la pantalla, que los cambié por sprites que conseguí en OpenGameArt, así como el fondo y otros detalles más. La animación inicial de los bloques del título en base a funciones matemáticas me divirtió mucho!

Prácticamente todos los días desde que empecé el proyecto dediqué aunque sea unos minutos después del trabajo o antes de acostarme para agregarle al código. Fui agregando varias cosas más: Pantalla de inicio con menú de opciones, efectos al hacer dobles, triples o tetris, pausar el juego, créditos, ayuda, pantalla completa opcional, y más ajustes. Corregí unos errores de colisión, aunque hay un bug todavía al momento de rotar piezas que necesito arreglar.

Para la música, usé el editor de música de GB Studio, un entorno de desarrollo de videojuegos para Game Boy. La breve melodía que se escucha al iniciar el juego es el resultado de aprender a usar la herramienta con ensayo y error en unos minutos, metiendo las notas a mano de oído hasta tener algo relativamente aceptable. La canción deja que desear, pero probablemente en algún momento le dedique algo más de tiempo como para tener una versión más decente de Korobeiniki, la canción folclórica rusa en la que está basada el tema de Tetris.

DragonRuby hace súper fácil la publicación en itch.io, así que agregué a mi cuenta el perfil de "desarrollador" y subí mi versión de Tetris en este enlace. Empecé con el nombre "Picando Tetris", pero no tengo idea si eso podría traerme problemas por usar un nombre registrado. Otras versiones tuvieron el nombre código "Picandotris", hasta que un amigo me sugirió "Fertris" (Fernando's Tetris!) y ahí quedó porque nombras cosas es difícil. Se puede descargar gratis para Linux, RaspberryPi, Mac OS y Windows. Si la llegan a probar, cuenten qué tal anduvo.

El resultado final se ve algo así:

No creo que comparta el código porque si lo ve un desarrollador de videojuegos profesional me va a mandar preso. Hablando en serio, es un código para experimentar y aprender y no creo que nadie más que yo pueda beneficiarse mucho de él.

La experiencia de agregarle cosas al Tetris de icculus queda, y además de haberme divertido, es una de las tantas cosas que aportan a mi experiencia como programador. Pero por sobre todo, ¡me divertí! Si ya sabes Ruby y te interesa, te recomiendo leer más sobre DragonRuby y empezar a hacer juegos. Y si bien ya no me voy a sentir mal cada vez que lea a Amir pidiendo que haga juegos, todavía tengo que arrancar uno propio de cero. La parte más difícil de Tetris es la lógica del juego, y eso lo hizo todo icculus en este ejemplo. Además Amir ya me dijo "seguí haciendo juegos maldición", ¡ya vendrán otros proyectos!

Siempre me ha interesado la idea de desarrollar mi propio videojuego, pero no sé si cambiaría mi carrera como para dedicarme a eso a tiempo completo. Es un tema que me interesa mucho, y me fascinan los distintos procesos creativos que se involucran: programación, diseño, arte, sonido. Pero sí me encantaría poder publicar varias de las ideas que tengo como videojuegos en algún momento. El tiempo que pasé programando y experimentando con DragonRuby se me pasó volando. Así que por lo menos para mantener esa sensación de programar cosas divertidas, espero seguir desarrollando juegos como pasatiempo.

El post Programando Tetris con DragonRuby fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

Picando Código

Mar10: El Día de Mario mirando películas de Mario

marzo 10, 2024 11:49

Super Mario Bros - Blu RayCon motivo de Mar10 (10 de marzo, “Día de Mario”), hoy volví a mirar las películas de Mario. No se pueden comparar entre sí por varias razones: La película de 1993 no tenía más que unos pocos títulos con poco o nada de historia en la que basarse. Además fue pionera en su género, no se sabía qué funcionaba en la transición del videojuego al cine, y es una película totalmente experimental. Ni que hablar que Nintendo le dió ruenda suelta a Hollywood con los personajes, y no se involucró prácticamente en la producción. La película de 2023 tiene 30 años de juegos, spin-offs y demás legado de dónde sacar ideas. Además contó con la producción de Shigeru Miyamoto y el involucramiento directo de Nintendo.

Son dos productos completamente distintos, pero disfrutables a su manera, y una gran parte de la historia de los hermanos Mario.

Super Mario Bros. (1993)

Super Mario Bros. (1993)

Super Mario Bros. (1993)

La primera película live-action basada en un videojuego no fue bien recibida ni por la crítica ni por el público general. Es la primera vez que vuelvo a mirarla después de no sé cuántos años. Está bueno que la puedo ver con una perspectiva totalmente nueva. No sólo no me acuerdo, sino que mis gustos y expectativas han ido cambiando con el tiempo. En su momento seguramente la haya visto en el cine, y si no recuerdo mal, tenía las figuras de acción de Mario, Luigi y un Goomba de la película en mi arsenal.

Mientras la miraba, varias veces me surgió la pregunta “¿para quién es esta película?”. Tiene sus partes más “familieras” (escenas que llaman a un estilo de película como “Home Alone”), y otras un poco más adultas. Los extras del Blu-Ray respondieron la pregunta. Incluyen unos videos con entrevistas donde varias de las personas responsables hablan sobre el proceso unos cuantos años después. Tuvo un montón de problemas de producción: el guión fue re-escrito varias veces, el enfoque iba cambiando casi que todo el tiempo y unos cuantos problemas más. Esto explica que a veces parece enfocada a niños pero también muestra cosas que alguien esperaría de una película noventera para adultos.

La trama es absoluamente desquiciada, pero podría haber funcionado muy bien. Con la influencia de Super Mario World, Mario y Luigi viajan a una dimensión paralela donde los dinosaurios siguieron evolucionando en paralelo con los mamíferos hasta llegar a ser básicamente humanos reptilianos. Su ciudad es una Manhattan distópica con estética cyberpunk. El arte es muy bueno, tanto la magia que hicieron transformando la planta de cemento abandonada donde filmaron, como el maquillaje, los efectos especiales y demás. El diseño de las armas que usan para “desevolucionar” en la película está basadao en el Super Scope. Las bob-ombs son bombas a cuerda con dos piecitos que se asemejan mucho a las de Super Mario Bros. 3 o World con un “product placement” en sus zapatos muy chiste de película noventera. Creo que estas dos piezas de utilería son los dos únicos aspectos fieles al videojuego.

Pero la fidelidad no importa. Con la edad y la experiencia uno aprende a entender que el mundo de las películas es alternativo al material en el que están basadas. Y si no nos gusta, la podemos ignorar y volver a disfrutar del material original. Hay que disfrutarlas como una nueva interpretación basada en personajes. Con esa idea ya asimilada, realmente quise que me gustara más. Pero la mata el guión. Si hubiera tenido un guión mejor escrito, más cohesivo y con buenos diálogos, podría ser excelente. Bob Hoskins y John Leguizamo están muy bien interpretando a Mario y Luigi. Yoshi es un dinosaurio hecho con efectos prácticos realista con un resultado en pantalla excelente, unos días antes de que se estrenara Jurassic Park. Y en general la historia podía haber dado para una secuela tranquilamente.

La idea es totalmente alocada, y podría haber funcionado mucho mejor. Pero ahí quedó como un producto de su época y problemas de producción. Si no fuera por la siguiente película de Mario que voy a comentar y su éxito, no descartaría que con la falta de ideas que está teniendo Hollywood en los últimos tiempos, no se hiciera un reboot de esta idea en particular. Que sería igual de desquiciado, pero igual la miraría.

¿Recomiendo verla? Sí, si tienen un domingo donde no pueden salir por alguna razón, es entretenida para pasar el tiempo. Por lo menos nos quedó esta tremenda versión de “Walk the Dinosaur” y una escena bajando por un túnel congelado con este temún de Joe Satriani

Super Mario Bros 2023

Avanzamos 30 años y tenemos una de las películas de videojuegos más entretenidas hasta el momento. Donde la anterior tenía unas pocas referencias a cosas del videojuego, en ésta casi cada personaje, nota musical, o escenario es una referencia directa a algún juego de Mario o de Nintendo. Incluso se transforma en una cacería encontrar cada detalle que se relaciona a algún juego de Mario o Nintendo. Habiendo crecido jugando Super Mario y juegos de Nintendo, disfruté de cada una de las que encontré, así como los guiños y homenajes de todo tipo. Se rumorea que hasta hay Pikmins escondidos por ahí…

La historia no es demasiado profunda, pero es entretenida y la plataforma para introducir el mundo y los personajes a la audiencia y contar varios chistes, aparte de promocionar juegos. Nintendo reportó vender muchas copias nuevas de juegos de Mario en Nintendo Switch gracias al éxito en taquilla. También se muestran coss que potencialmente podrían dar para contar más historias, pero las irán dejando para las secuelas, que la primera ya está anunciada (más información al final de este post).

Desde el momento en que se anunció, venía renegando con Chris Pratt como Super Mario porque el tipo hacía la misma voz en todas sus películas. Pero la verdad que mirándola no me doy cuenta y se me pasa. Dejando de lado eso, la selección de actores para las voces me parece muy bien. Charlie Day como Luigi, Anya Taylor-Joy como Peach, Charles Martinet -que estoy seguro crearon el personaje sólo para que esté 🙇- y demás actores están muy bien con sus personajes. De destacar Seth Rogen como Donkey Kong, elección inesperada que pega muy bien y que no sólo hace su contagiosa risa característica sino que canta el DK Rap. Y para mí la estrella más grande es Jack Black con su interpretación de Bowser y la canción “Peaches”, que no puedo evitar escuchar en mi cabeza cada vez que paso por la sección de frutas de un mercado y veo la palabra escrita. La estrella cínica de Mario Galaxy se lleva muchos aplausos y risas también por su humor negro.

Se aprecia cariño y conocimiento del material original, pero es lógico asumiendo que seguramente más de una de las personas involucradas hayan crecido jugando Nintendo. Los avances en animación también dan lugar a escenas de acción muy buenas que se traducen de manera excelente del videojuego al cine y evocan distintas etapas de la vida de un jugón como uno pegado al televisor. La música acompaña muy bien, tanto interpretaciones orquestrales de melodías que tenemos quemadas en el cerebro por pasar tantas horas jugando Nintendo, como canciones más populares. Como ejemplo una escena con un tema de Bonnie Tyler es genial y la canción la enriquece mucho.

Si les gusta Super Mario, seguramente ya la hayan visto, y si no, recomiendo que lo hagan. La miré en el cine cuando salió y me divertí mucho. Tras verla de nuevo casi un año después en Blu-Ray, volví a disfrutarla y se mantiene siendo una de mis tres películas preferidas del año pasado (las otras dos son Barbie y Godzilla Minus One). Tendré que volver a mirarla el 10 de Marzo de 2025 si no tengo nada mejor que hacer o poco antes que se estrene la secuela para refrescar la memoria.

Noticias sobre Mario en su día

Hoy Nintendo publicó un video donde Shigeru Miyamoto comenta que están trabajando junto a Illumination en la secuela de la película animada de Super Mario Bros. Se espera que esté disponible en Estados Unidos y otras regiones el 3 de abril de 2026. En el mismo video se confirman fechas de disponibilidad de algunos juegos de Mario para Nintendo Switch este año:

  • Paper Mario: The Thousand-Year Door – 23 de mayo, 2024
  • Luigi’s Mansion 2 HD – 27 de junio, 2024
  • Dr. Mario (Game Boy), Mario Golf (Game Boy Color) y Mario Tennis (Game Boy Color) disponibles a partir del 12 de Marzo en Nintendo Online.

Bueno, me voy a jugar un rato a Super Mario Bros. Wonder y me acuesto a dormir…

El post Mar10: El Día de Mario mirando películas de Mario fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

proyectos Ágiles

Master en Agile – MMA 2024-2025

marzo 10, 2024 11:55

En octubre de 2024 se iniciará el Barcelona la 14ª edición del Postgrado en Métodos Ágiles (PMA) y otra del Máster en Transformación Agile (MMA) en La Salle (Universitat Ramon Llull), el primero a nivel mundial sobre Agile.

Con el Máster en Métodos Ágiles de La Salle-URL aprenderás a liderar el cambio hacia la Business Agility y a lanzar con éxito iniciativas en entornos complejos y altamente competitivos, reduciendo el Time To Market a fin de maximizar el valor aportado al negocio.

Desarrollarás una manera de pensar transversal e integradora para crear equipos de alto rendimiento mediante Scrum, Kanban, Lean Startup, OKR, diseño organizativo y liderazgo sistémico para elaborar estrategias de escalado Agile en la organización y transformar su cultura, de modo que también aumente la motivación de sus miembros.

Con profesores de primer nivel y visitas a empresas podrás iniciar un cambio hacia la agilidad y resiliencia empresarial en tiempos de incertidumbre.

Esta es una oportunidad única para aprender de profesionales-profesores de primer nivel, con muchos años de experiencia específica en Agile, aplicando principios y métodos ágiles en contextos diversos, especializándose en aspectos concretos,  investigando sobre nuevas técnicas, ponentes en conferencias nacionales e incluso internacionales, que incluso han inventado métodos y escrito libros.

El MMA incluye las siguientes certificaciones oficiales:

  • «Certified Scrum Master» (CSM) de la Scrum Alliance, la entidad de certificación Agile de mayor prestigio a nivel internacional.
SAI_BadgeSizes_DigitalBadging_CSM
  • Certified Agile Skills – Scaling 1 de la Scrum Alliance, , la entidad de certificación Agile de mayor prestigio a nivel internacional.
  • Certified Leader de Agile Humans.

Adicionalmente, se incluye la visita a las siguientes empresas:

 ✍ Para inscripciones, consultar la página oficial del Máster.

A continuación, más detalle acerca del Postgrado en Agile (PMA) y del Máster en Agile (MMA)

PMA – Postgrado en métodos Ágiles

El PMA incluye las siguientes certificaciones oficiales:

  • «Certified Scrum Master» (CSM) de la Scrum Alliance.
  • Opción de acceder al Certified Project, Portfolio, And Operations Management for Business Agility de Businessmap.
AsignaturasTemasProfesores
Fundamentos & InceptionPrincipios y métodos más conocidos (Scrum, Lean, Kanban y XP). Facilitadores e impedimentos.

 

Inception y conceptualización ágil de proyecto, priorización ágil, historias de usuario,  elaboración de Product Backlog, técnicas de priorización.

Silvia Sistaré

 

Agustín Yagüe

Scrum y KanbanEstimación y planificación ágil, framework de Scrum, retrospectivas, Kanban, métricas ágiles, herramientas ágiles físicas, radiadores de información.Raul Herranz

 

Teodora Bozheva

Personas y equiposGestión de personas, gestión de conflictos, motivación e incentivos, facilitación compartida, contratación ágil.

 

Visual thinking.

Steven Wallace

 

Silvia Sistaré

Virginia Armas

Gestión de producto ágilDesign Thinking, Lean UX & Prototyping.

 Estrategia de Producto – Consciencia situacional (Wardley Maps), modelo de negocio (Lean Canvas), modelo de tracción, métricas AARRR.
Planificación y gestión estratégica – OKR y Hoshin Kanri.

Customer development – Lanzando y escalando startups ágiles, las tres fases de un producto.

Lean Startup – Desarrollo de producto basado en prototipos y experimentos. Bancos de ideas, desarrollo basado en hipótesis.

Laia Montaño


Lucía Barroso
Ingeniería ágil User eXperience y prototipado en Agile.

 

ALM ágil, eXtreme Programing, Software Craftsmanship, testing ágil.

BDD y TDD. Desarrollo guiado por pruebas (de aceptación y unitarias).

Métricas Accelerate y SW Delivery assessment.

Cómo trabajar con código heredado y reducir la deuda técnica.

Laia Montaño

 

Álvaro García

Pablo Gómez

Cristina Verdi

Trabajo Final de PostgradoDurante el Postgrado se realiza un caso práctico de introducción de los contenidos en un equipo ágil en una empresa real. Para ellos los alumnos se organizan en equipos multidisciplinares utilizando Scrum, con feedback regular de un tutor con experiencia en transformación de equipos. 

El Postgrado tendrá una duración de 4 meses y se realizará viernes tarde y sábado por la mañana.

Ver también:

MMA – Master en Métodos Ágiles

Incluye todas las asignaturas del Postgrado (PMA) y, adicionalmente, las siguientes asignaturas especializadas en Business Agility, agilidad organizacional y transformación (aparte de las tres certificaciones indicadas al inicio y las visitas a empresas):

AsignaturasTemasProfesores
Enterprise Learning & personal efficiencyAgile Kaizen, Comunidades de Práctica, Open Spaces, Talent development, gamification.

 

Productividad y aprendizaje personal en Agile (eficiencia).
Steven Wallace

 

Olga Vela
Lean Thinking & Agile ManagementLean. Escalado con Kanban.

 

Business Agility con ViMa – agilidad para equipos de negocio

Agile-Lean Management

Teodora Bozheva

 

Xavier Quesada

Xavier Albaladejo

Coaching y CulturaCoaching de equipos, creación de equipos de alto rendimiento, liderazgo.

 

Tipos de cultura empresarial, gestión del cambio organizativo.

Joserra Díaz

 

Jasmina Nikolic
Jaume Gurt

Transformación ContinuaEstrategia de despliegue de Agile en organizaciones, cómo vender Agile a la Dirección. Contratos ágiles.

Enterprise continuous improvement.

Enterprise software development, Team Topologies & DevOps.

Xavier Albaladejo

 

Ángel Medinilla

Álvaro García

Scaling Agile Escalado (LESS, Spotify, Nexus, SAFe, Unfix), desescalado y auto-organización empresarial (reinventing organizations, sociocracy 3.0, liberating structures, …), equipos distribuidos.

 

Impact Mapping, Product Portfolio Management, Roadmapping, Budgeting for Agile

Adrian Perreau
Fernando Palomo

 

Mattijas Larsson

Trabajo Final de MásterDurante el Máster se realiza un caso práctico de introducción y aplicación de Agile en una empresa real, incluyendo la parte de transformación organizativa, de métodos y de cultura. Para ellos los alumnos se organizarán en equipos multidisciplinares utilizando Scrum, con feedback regular de un tutor con experiencia en transformación organizativa.Xènia Castelltort (oratoria / public speaking para poder explicar tus ideas de manera convincente)

El Máster tendrá una duración de 8 meses y se realizará viernes tarde y sábado por la mañana (incluye los estudios indicados en el Postgrado).

El cambio en la organización comienza por el propio cambio, para también poder dar ejemplo. Por ello en el MMA se realizan diferentes ejercicios de auto-conocimiento:

  • Cómo el alumno trabaja en equipo.
  • Estilo de liderazgo del alumno (según el paradigma Agile).

Como en las últimas ediciones, contaremos con la participación de empresas que nos explicarán sus experiencias de transformación y donde trabajan con modelos de gestión desescalados (basados en Sociocracia, NER y otras alternativas).

Información adicional

  • Perfil de los estudiantes: 30-45 años (no son recién licenciados, son personas con experiencia profesional).
  • Alrededor del 50% son mujeres.
  • 15% de los estudiantes ya no son del ámbito tecnológico, son pioneros-innovadores en otras industrias.
  • Alumnos de diferentes disciplinas – Product Owners, Scrum Masters, Agile Coaches, líderes de equipos, Project Managers, managers funcionales, ingenieros SW. Van a adquirir conocimientos de Agile “on-top” de todo eso (y a aprender unos de otros).
  • Lo que les caracteriza: todos son agentes de cambio en su contexto (equipo, área, empresa).
  • Sus 20 profesores (de reconocimiento internacional) son el MAYOR VALOR DIFERENCIAL del PMA y del MMA.

Testimoniales

Me ha permitido tener conocimientos sobre varios temas súper importantes dentro de la Transformación Digital. Me dio herramientas para crecer a Agile Coach y, además, para tener mejores conversaciones y discusiones con las empresas en donde he trabajado

Carolina Graffe

Estoy desplegando el TFM en mi empresa, Además, no estoy sola. Uno de mis compañeros del equipo ha sido contratado como consultor por mi empresa para darnos soporte. Así que no sólo estoy aplicando lo que yo aprendí, sino que el MMA me ha permitido ampliar mi círculo de contactos relevantes, que me permite seguir aprendiendo.

Susana Santillán

Estoy trabajando como agente del cambio y mis aportaciones son muy valoradas por mi jefe y compañeros. Por el feedback recibido, mis aportaciones están muy por encima de lo esperado para mi rol.

Robert Avellaneda

Tengo mucho más contexto y más herramientas para el día a día. Incluso a nivel personal también me está ayudando mucho

María Hachero

Además de los conocimientos concretos que se reciben, uno de los principales cambios que han experimentado los alumnos es mayor perspectiva en los problemas, cómo abordar la complejidad en las empresas, en su trabajo y en las relaciones entre personas y en equipos. Han ganado discurso y aplomo para defender de manera más objetiva propuestas de cambio y mejora.

Encuesta a alumnos de las ediciones anteriores:

(*) Las personas que han valorado el impacto como «neutro o poco» usualmente son perfiles muy especializados en contextos muy estáticos, con lo cual les es difícil cambiar de «profesión» e introducir cambios en sus organizaciones (aunque algunos de ellos incluso dan conferencias sobre cómo van avanzando en esos contextos tan singulares).

 ✍ Para más detalles e inscripciones, consultar la página oficial del Máster.

» Leer más, comentarios, etc...

Picando Código

Publicado Gleam v1.0.0

marzo 08, 2024 11:00

Esta semana se publicó la versión 1.0.0 del lenguaje de programación Gleam, un “lenguaje amigable para hacer sistemas que escalan con tipado seguro”. Ya he escrito sobre Gleam en el blog antes, pero no he escrito tanto código como hubiera querido. Es uno de los tantos lenguajes que me gustan y con los que me gustaría programar más. Gleam cuenta con “el poder de un sistema de tipado, la expresión de la programación funcional, y la seguridad del entorno de ejecución tolerante a fallas y de alta concurrencia de Erlang, con una sintaxis moderna y familiar”.

Gleam

El 4 de marzo Louis Pilfold, su creador, publicó esta primera versión “estable” del lenguaje, lo que describe como un gran hito para el ecosistema. En el anuncio escribe:

¿Qué es Gleam?

Gleam es un lenguaje de programación que intenta hacerle el trabajo de quienes escriben y mantienen sistemas de software lo más predecible, libre de estrés y disfrutable posible.

El lenguaje es consistente y tiene un área de superficie pequeña, haciendo posible aprenderlo en una tarde. Acompañado de una falta de magia y una fuerte intención de tener una sóla manera de hacer las cosas, Gleam es típicamente fácil de leer y entender. Leer y debuggear código es más difícil que escribir código nuevo, así que optimizamos para esto.

Gleam tiene un análisis de tipos estáticos robusto y un sistema de tipos inspirado en lenguajes como Elm, OCaml y Rust, así que el compilador sirve de asistente de programación, dándote contexto adicional para ayudarte a hacer el cambio que quieras hacer. No te preocupes por escribir código perfecto de primera, con Gleam refactorizar es de bajo riesgo y bajo estrés así puedes continuar mejorando tu código mientras aprendes más sobre el problema que estás resolviendo.

Ejecutar y administrar software es tan importante como escribirlo. Gleam corre sobre la máquina virtual de Erlang, una plataforma madura y probada que habilita a muchos de los sistemas más confiables y escalables del mundo, como WhatsApp. Gleam también puede ejecutarse en entornos JavaScript, siendo posible ejecutar código Gleam en el navegador web, en dispositivos móviles o en cualquier otro lado.

Gleam se ve así:

import gleam/json
import gleam/result.{try}
import my_app/person
import wisp.{type Request, type Response}

pub fn handle_request(req: Request, ctx: Context) -> Response {
  use json <- wisp.require_json(req)

  let result = {
    use data <- try(person.decode(json))
    use row <- try(person.insert(ctx.db, data))
    Ok(person.to_json(row))
  }

  case result {
    Ok(json) -> wisp.json_response(json, 201)
    Error(_) -> wisp.unprocessable_entity()
  }
}

¿Qué incluye Gleam v1?

Esta versión cubre todas las API públicas del repositorio git principal de Gleam:

  • El diseño del lenguaje Gleam
  • El compilador Gleam
  • La herramienta de compilación de Gleam
  • El gestor de paquetes de Gleam
  • El formateador de código de Gleam
  • El servidor de lenguaje de Gleam
  • Las herramientas del compilador para JavaScript y el API WASM.

La biblioteca estándar Gleam y otros paquetes que son mantenidos por el equipo central obtendrán una publicación v1 en breve. Antes de publicarlas, vamos a estar haciendo pull requests a paquetes populares de la comunidad para relajar sus limitaciones de versionado en el gestor de paquetes para asegurarnos que la actualización a la V1 sea lo más sencilla posible para todos los usuarios de Gleam.

¿Qué significa V1?

La versión 1 es una declaración sobre la estabilidad y disponibilidad de Gleam para ser usado en sistemas en producción. Creemos que Gleam es adecuado para usar en proyectos que importan, y Gleam va a poveer una fundación predecible y estable.

Gleam sigue el versionado semántico, así que es prioridad mantener compatibilidad hacia atrás. Vamos a estar haciendo todo el esfuerzo para asegurarnos que Gleam no introduzca cambios que rompan la compatibilidad hacia atrás. La excepción a esto es por problemas de seguridad y robustez. Si se descrube un bug crítico de esta naturaleza, nos reservamos el derecho de corregir el problema de seguridad, incluso si algunos programas estuvieran tomando ventaja del bug.

¿Qué sigue para Gleam?

Gleam es un lenguaje práctico con la intención de hacer cosas reales, así que nuestro foco para Gleam post-v1 va a estar dividido entre productividad para usuarios de Gleam y sustentabilidad para el proyecto.

Productividad para usuarios de Gleam

Además de no introducir cambios que rompan la compatibilidad, se va a evitar agregar demasiado al lenguaje para que no se convierta en un lenguaje más complejo y difícil de entender. Pretenden mantener la simplicidad, agregando características nuevas al lenguaje, pero de forma conservadora. Va a haber un foco en mejorar el servidor de lenguaje Gleam para mejorar la productividad. También se va a trabajar en las bibliotecas de Gleam, con un foco inicial en desarrollo de páginas y servicios web.

Otra de las prioridades es la documentación, con trabajo en tutoriales y guías para todo tipo de tareas en Gleam.

Sustentabilidad

Gleam es un proyecto comunitario sin apoyo de una corporación. Louis es el desarrollador principal y trabaja en el lenguaje a tiempo completo, junto a voluntarios part-time concentrados en trabajo con impacto y sentido para la comunidad. Van a continuar también el trabajo en la documentación interna para que sea fácil para más gente colaborar con el proyecto.

Un tema importante es la sustentabilidad financiera. Louis trabaja a tiempo completo en el proyecto gracias a los sponsors en GitHub. Cuentan con un sponsor principal, Fly.io, que provee gran parte de los fondos. Pero están buscando diversificar la financiación del proyecto con más sponsors corporativos y otras vías de ingreso.

Mascota

El anuncio cierra presentando a Lucy, la nueva mascota del proyecto, así como mejoras en el sitio web gleam.run.

Instalación

Podemos instalar Gleam siguiendo esta guía. Personalmente vengo usando asdf para gestionar versiones de Gleam y algunos otros lenguajes de programación. Teniéndolo instalado, podemos gestionar las versiones de Gleam en nuestro sistema agregando el plugin:

asdf plugin-add gleam

Una vez instalado asdf y el plugin de gleam, podemos ejecutar lo siguiente para empezar a usar esta nueva versión:

$ asdf install gleam latest
$ asdf global gleam 1.0.0
$ gleam -V
gleam 1.0.0

Y con esto ya podemos empezar a programar en Gleam. Hay mucha información en la documentación, incluyendo guías de referencia viniendo de otros lenguajes.

El post Publicado Gleam v1.0.0 fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

Picando Código

10 años de emacs.sexy

marzo 05, 2024 10:30

Esta semana se cumplen 10 años desde que registré el dominio y publiqué el sitio web emacs.sexy. Se ve que 2014 fue un año bastante ocupado en cuanto a proyectos personales… 

emacs.sexy

En su momento escribí en el blog al respecto en Emacs es Sexy. Como comentaba originalmente, el sitio surgió como respuesta a vim.sexy, pero con un objetivo un poco más productivo: Con la disponibilidad de los nuevos TLD .sexy, hace poco salió en La Internet el sitio vim.sexy. Tiene pinta de ser una respuesta paródica al editor de texto hipster del momento Atom. Pero mi problema era: Si bien es una parodia graciosa, vim.sexy no aporta mucho (en mi humilde opinión). Supuse que alguien habría hecho algo similar para Emacs, por la eterna relación entre Emacs y Vim. Al ver que no era así, registré el dominio e intenté crear un sitio que sumara un poco más. En el mismo tono humorístico creé una página web más constructiva, con información sobre Emacs y con la meta de lograr motivar a alguna persona curiosa a probar y dejarse enganchar por Emacs.

Así que la idea es difundir y compartir Emacs y recursos para aprender a usarlo y más. Siempre tuve la idea de implementar un sistema multi lenguaje para poder publicarlo en varios idiomas, pero nunca le dediqué el tiempo necesario. ¡Algún día prometo tenerlo también en español! Tuve la suerte de que el sitio creció mucho gracias a aportes de mucha gente gracias a su naturaleza de código abierto, así que

El diseño cambió bastante y está mucho más moderno que el original gracias a la grande de Mery, la versión inicial se veía mucho más “hecha por un programador”:

Emacs.sexy

Es interesante reflexionar sobre “el editor de texto hipster del momento” que comentaba en su momento. En 2014 era Atom. No sé si antes o después vino Sublime, y ahora un montón de gente se pasó a Visual Studio Code. Mientras estos editores van y vienen, Emacs y Vim los miran pasar. Hace años que uso Emacs y sigo aprendiendo cosas nuevas bastante seguido. De sólo pensar en tener que aprender una herramienta nueva para tener que editar texto o escribir código en un lenguaje de programación específico me estresa 😅

Así que si no conocen Vim,  Emacs o Spacemacs (lo mejor de ambos mundos), les invito a entrar a al sitio y aprender un poco más. De repente aprenden una herramienta para toda la vida como vengo haciendo yo.

El post 10 años de emacs.sexy fue publicado originalmente en Picando Código.

» Leer más, comentarios, etc...

Blog Bitix

Configurar GNU/Linux para usar forward DNS y el servidor DNS de Consul

febrero 24, 2024 04:00

Una de las cuestiones que tenía pendiente de mirar sobre Consul es como hacer que un nodo con GNU/Linux pueda acceder al catálogo de servicios mediante la interfaz DNS que ofrece Consul. Para esto es necesario configurar el forward DNS.

Continuar leyendo en Blog Bitix

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin