C# 2021: mucha magia y grandes riesgos

Cuanto más veo las nuevas características que están introduciendo C# más “miedito voy sintiendo”. Veo algunas características que se anuncian con un espíritu de “mucha funcionalidad con muy poco código“. Un ejemplo de esto es el tweet de ayer de David Fowler.

Cuando veo este tipo de anuncios no puedo evitar recordar los primeros años de .Net cuando ASP.NET WebForms generaba también ilusiones de simplicidad y productividad. En cierto modo la promesa sonaba como “podes hacer aplicaciones web como si fueran aplicaciones desktop y sin tener que aprender de tecnologías web“. Tiempo después descubrimos que el uso de WebForms tal como era promocionado (sin entender bien la web) tenía un conjunto de efectos colaterales que causaron estragos negativos en muchas aplicaciones y dolores de cabeza en muchos programadores.

Por otro lado, esta constante evolución de los lenguajes me resulta molesta y hasta inconveniente. En el caso de C# no bastaba con tener clases, enums, structs, interfaces, etc. que había que agregar records. Entiendo que la intención de gran parte de estos cambios es proveer mejores niveles de abstracción y simplificar el trabajo de programador. Si es así, estoy de acuerdo con la intención pero no comparto la estrategia. Yo personalmente me inclino más por la estrategia de Smalltalk, mantener el lenguaje al mínimo y agregar funcionalidades mediante el agregado de paquetes de clases.

Y ya que estamos, otra cuestión que no me gusta de .Net/C# es que el modelo de ejecución sync/async resulta extremadamente intrusivo, forzando a que las clases de dominio que contienen la lógica de negocio se vean “contaminadas” con elementos del modelo de ejecución (async, await, etc). Entiendo que esto es en favor de una mejor performance en mi opinión no vale la pena. Prefiero mantener el código más limpio y lidiar con el modelo de ejecución a nivel de infraestructura incluso cuando ello conlleve cierta penalidad de performance.

Es por todo esto que muchas veces mi código C# no hace uso de “las magias” recientes del lenguaje/plataforma y confío en que es mucho más claro que sí usara “esas magias”.

En fin, C# como lenguaje me gustó mucho desde un comienzo así que solo espero que quienes trabajan en su evolución no lo choquen.

DevOps sin DevOps

Este es título de la charla que estaré dando en el contexto de la primera conferencia de la Agile Alliance en Español. Esta conferencia será en modalidad online los días 27 y 28 de mayo. En particular mi charla será el jueves 27 de mayo a las 18 hs (GMT-3). Les comparto aquí el resumen de la charla.

Sin bien llevamos varios años hablando de DevOps, sigue habiendo mucho ruido y confusión respecto a su significado y estrategia de implementación. Muchos creen que DevOps implica tener un área o gente especializada con dicho nombre/rol, lo cual es completamente discutible y hasta en un punto contrario a lo que muestran varios casos de éxito.
En esta sesión repasaremos los pilares fundamentales de esta corriente junto algunos casos exitosos de implementación de DevOps sin “Ingenieros DevOps” ni un área especializada en DevOps.

Scrum: en general no alcanza pero en ocasiones es incluso demasiado

Scrum es el marco de trabajo ágil más utilizado en la actualidad. Es al mismo tiempo en muchos casos el punto de partida para equipos que pretenden comenzar a trabajar de forma ágil. A simple vista Scrum parece simple, la guía oficial de Scrum tiene apenas 15 páginas y un curso típico de Scrum ronda las 16 horas.

Sin embargo esta simplicidad aparente en la teoría resulta bastante distinta en la práctica. Que sea fácil de entender no implica que resulte fácil de poner en práctica.

Scrum es un marco de trabajo para gestión y colaboración que puede utilizarse tanto en proyectos de software como también en otro tipo de proyectos. El hecho de que sea un marco de trabajo es lo que permite utilizarlo en contextos muy distintos pero implica al mismo tiempo que al utilizarlo en un escenario concreto es necesario “completar alguno huecos”. Algunos de esos “huecos” son muy explícitos pues son simples parámetros, por ejemplo la duración de los sprint. Pero de esos huecos son mucho menos explícitos, por ejemplo la forma en que estimaremos y que forma tendrán nuestros items de backlog. Es así que para un equipo que desarrolla software no alcanza con Scrum en abstracto, es necesario “llenar huecos” con prácticas concretas. Un complemento que ha resultado muy efectivo es utilizar Scrum con Extreme Programming(XP), o sea, “llenar los huecos” de Scrum con las prácticas de XP. XP es una propuesta de trabajo concreta para desarrollo de software y como tal contempla tanto cuestiones de gestión/colaboración como cuestiones de programación/prueba/despliegue, etc.

Pero por otro lado, para un equipo que viene de trabajar en una dinámica desordenada de “code-and-fix” meterse de lleno con Scrum puede resultar demasiado. Pasar de la nada a iteraciones time-boxed, gestionar explícitamente el backlog e incorporar todas las ceremonias de un día para otro, no me parece un apropiado. Es así que para esos escenarios yo suelo proponer una adopción gradual de Scrum y en ese sentido el mi recomendación es comenzar haciendo retrospectivas. La retrospectiva tiene la particularidad de ser una práctica sin dependencias, o sea, uno puede hacer retrospectivas sin utilizar ninguna otra práctica de Scrum. Al mismo tiempo la retrospectiva debería guiarnos en nuestro proceso de mejora. Dicha mejora podría llevarnos a incorporar otras prácticas de Scrum o no, tal vez podríamos terminar incorporando otras prácticas. O sea, tal vez arrancamos con la intención de hacer Scrum pero terminamos haciendo algo distinto. Pero esto no está mal, porque Scrum no debería ser un fin en sí mismo, sino un medio para lograr un fin de nuestro equipo/organización que en términos de Agile es agregar valor.

Impulsando el cambio desde la trinchera

Este es el título de la charla que di la semana pasada en el contexto de un webinar organizado por la Agile Alliance. El webinar estaba titulado “Camino hacia la agilidad: Una mirada integral” y constó de 3 oradores: Israel Alcázar, Ana Carmona y yo.

Israel fue el primero en presentar, su charla se tituló “Un enfoque integral para entender la agilidad”. Luego fue mi turno. Finalmente fue el turno de Ana cuya charla se tituló “Cuando un equipo tiene que seguir siendo ágil”. Creo que las 3 charlas estuvieron muy alineadas, primero Israel habló sobre cuestiones de transformación nivel organización/empresa. Luego yo hablé desde mi rol de XP coach trabajando con equipos de desarrollo. Finalmente Ana se centró en las situaciones que enfrenta un equipo luego del primer momento de transformación, cuando ya el equipo trabaja de forma autónoma sin la guía de un coach externo.

Luego de las tres charlas hubo un espacio de preguntas y respuestas. Toda la actividad estuvo moderada por Juan Banda.

A pesar de llevar más de un año de eventos online, no termino de acostumbrarme, sigo sintiendo como que estoy hablando al aire.

Todo el evento fue grabado y está disponible aquí en la web de la Agile Alliance, el acceso es gratuito pero requiere registración.

Taller: Tddeando microservicios a kubenertes

Ayer completé el dictado de la primera edición de mi taller “TDD your Microservice from Git to Kubernetes“. El título está en inglés porque efectivamente fue en inglés. Asimismo, si bien en el título dice TDD, el taller es mucho más amplio. Incluye también varias prácticas relacionadas como Configuration Management, Continuous Integration, Design Patterns, Architecture guidance, etc.

Hace un tiempo decidí no dictar más cursos de TDD porque la experiencia me demostró que luego del curso, el salto que debían hacer los participantes entre la “simpleza didáctica” de los ejercicios del curso y su código de trabajo cotidiano era muy difícil de realizar. Luego de analizar el origen de esas dificultades decidí armar este curso que apunta precisamente a trabajar con ejercicios más “de mundo real”, lo cual implica lidiar con un proceso de desarrollo en equipo, versionado, integración con otros sistemas e infraestructura, entre otras cuestiones.

Obviamente cubrir todas estas cuestiones en un solo taller resulta muy desafiante, es por ello que el taller está estructurado en varios encuentros. Al mismo tiempo es un taller “avanzado”, en el sentido de que requiere que los participantes tengan:

  • experiencia en desarrollo de software en un contexto de industria
  • conocimiento de TDD (al menos conceptualmente)
  • práctica en la automatización de pruebas (al menos de tipo unitario)

Al mismo tiempo, para achicar más el salto entre el taller y los proyectos diarios de los participantes, este taller está basado en tecnologías concretas incorporando también patrones de uso común en dichas tecnologías. Esta versión en particular la hice utilizando C# (netCore),NUnit, Moq, Gitlab y Kubernetes.

En los próximos meses estaré haciendo una edición en castellano. Los interesandos pueden contactarme aquí.

Recomendaciones para alumnos de MeMo2

Como de costumbre en cada cuatrimestre intentamos incorporar mejoras en base al feedback recibido el cuatrimestre anterior. Entre esas mejoras vienen algunas recomendaciones para los alumnos:

  • Dado que gran parte del trabajo de la materia es en grupo te recomendamos que ya de entrada coordines con otros alumnos para conformar grupos 3 integrantes.
  • La materia se dicta en modalidad virtual con lo cual es mandatorio para cursarla contar con sistema de audio (parlante y micrófono). Asimismo es importante que cuentes con cámara.
  • Si aún no tienes una cuenta @fi.uba.ar es un buen momento para que la tramites.
  • La materia tiene un flujo importante de mails durante la época de trabajos grupales con lo cual podría resultar muy útil (y conveniente) aprender a armar filtros en tu herramienta de correo electrónico.
  • En la materia utilizamos Git y Ruby pero no dedicamos tiempo de clases a enseñar ninguna de estas dos herramientas, por ello si aún no estas familiarizado con estas herramientas te recomendamos que comiences a estudiarlas a la brevedad.
  • Si sos alumnos de Ingeniería Informática y como tal debes cursar Técnicas de Diseño (75.10) te recomendamos que leas este artículo donde explicamos que MeMo2 no es TDD.
  • Más allá de las 6 horas de clases semanales (de asistencia obligatoria), la materia suele demandar una dedicación semanal constante de otras ~6 horas semanales de trabajo/estudio fuera del horario de clase todas las semanas. Durante las primeras semanas puede que sea un poco menos y durante las últimas semanas puede que sea un poco más.
  • Es muy importante que asistas las primera clase, pues ahí explicamos varias cuestiones sobre la dinámica de la materia y la modalidad de evaluación. Si por alguna razón no puedes asistir por favor comunícate conmigo a la brevedad.

Antes cualquier duda puedes contactarme por aquí.

FIUBA: MeMo2 no es TDD

Escribo esta líneas para potenciales alumnos de mi materia y por ello agrego un poco de contexto para los lectores ajenos a FIUBA. En FIUBA se dictan actualmente dos carreras relacionadas a sistemas/informática/computación. Por una lado está la Licenciatura en Análisis de Sistemas y por otro la Ingeniería en Informática. Son dos carreras separadas, no es que la licenciatura es un paso intermedio de la ingeniería. Son dos carreras distintas, totalmente independientes pero que comparten varias materias.

La materia que yo dicto actualmente se llama Métodos y Modelos en la Ingeniería de Software 2 (código 95.21). Comúnmente es conocida como MeMo2. Es una materia que surgió a partir de la reforma 2015 del plan de estudios de la carrera de Licenciatura en Análisis de Sistemas. En el plan anterior había dos materias de ingeniería de software, una enfocada en cuestiones de análisis (Análisis de la Información – 75.09, comúnmente conocida como AnInfo) y otra enfocada en cuestiones de diseño (Técnicas de Diseño – 75.10, comúnmente conocida como TDD). Estas dos materias eran compartidas entre ambas carreras. Con el nuevo plan de estudios de la licenciatura se actualizó la visión de la ingeniería de software y esa dos materias (75.09 y 75.10) fueron reemplazadas por dos materias nuevas (95.20-MeMo1 y 95.21-MeMo2) que apuntan a cubrir con distinto nivel de profundidad todas las actividades de la ingeniería de software. Adicionalmente también se agregaron temas de ingeniería de software a otras materias del plan. De esta forma MeMo2 quedaba exclusivamente para la Licenciatura y TDD exclusivamente para la ingeniería.

En este contexto yo armé la materia MeMo2 en base al programa de la licenciatura. Cuando comencé a dictar la materia tuve muy pocos alumnos pues el plan era nuevo. Al poco tiempo, el Departamento de Computación decidió que mi materia, MeMo2, del plan de la licenciatura, era equivalente a TDD del plan de la ingeniería, una decisión polémica a mi parecer. Esto implicó que mi materia sea formal y simultáneamente MeMo2 y TDD. Yo siempre consideré esta decisión muy polémica ya que en términos formales los programas de TDD y MeMo2 tienen muy poco en común (a simple vista no más de un 30%).

Hoy en día mi materia sigue siendo formalmente MeMo2 y TDD pero en términos reales en su contenido es MeMo2. Esto hace que en habitualmente alumnos de la ingeniería vengan a cursar mi materia con una determinada expectativa (contenidos de TDD) pero se encuentran con algo distinto (contenidos de MeMo2).

Comparto una tabla comparativa de los programas de ambas materias, resaltando en verde los temas de TDD que cubrimos en MeMo2.

Curso gratuito de Unit Testing

Una de las dificultades que suelo encontrar al intentar enseñar Test-Driven Development a gente que ya tiene varios años de experiencia en desarrollo de software (con los principiantes es distinto), es que muchas veces no saben hacer pruebas unitarias automatizadas. Por eso, hace un par de semanas cuando decidí experimentar haciendo un curso 100% en video, no dudé en hacerlo sobre unit testing.

Ayer finalmente, luego de un par de semana de trabajo completé el curso, son 2 horas de video divididas en varios videos de no más de 10 minutos. Además de los videos, incluye varios recursos de lectura y ejecicios. Todo el código del curso está basado en C# (netCore) y NUnit, pero todo el contenido es fácilmente extrapolable a otros lenguajes/frameworks. Personalmente creo que tomar el curso completo (videos + lecturas + ejercicios) podría llevar unas 4 o 5 horas dependiendo de la experiencia de programación de la persona.

El curso está publicado con acceso gratuito en la plataforma Udemy

Cierre del segundo cuatrimestre 2020 en MeMo2@fiuba

Terminamos nuestro segundo cuatrimestre en modalidad 100% online. Fue un cuatrimestre muy particular, porque más allá de la virtualidad, tuvimos un cuatrimestre partido: por la situación de pandemia el inicio de clases en 2020 se retrasó y eso impactó en todo el calendario quedando el segundo cuatrimestre partido en 2. La primera parte terminó a mediados de diciembre permitiendo completar 12 semanas de clase. La segunda se retomó en febrero y contempló 4 semanas de clases para así completar las correspondiente 16 semanas de clases del cuatrimestre. Este particionamiento generó ciertas incomidades tanto para alumnos como para docentes.

Por otro lado, al margen de la particulidad del calendario y la virtualidad, este cuatrimestre hicimos 2 cambios mayores en la dinámica del TP2.

En primera instancia, no escribimos una descripción detalla de consigna. Previamente solíamos darle a los alumnos una especificación funcional de la aplicación a desarrollar en forma de pruebas de aceptación, las mismas no eran completas pero daban un nivel de detalle suficiente para marcar el comportamiento y alcance esperado. Este cuatrimestre cambiamos esto pues nos parecía que en cierto modo era una situación demasiado ficticia en el sentido que esas pruebas de aceptación no son típicamente provistas por el cliente/usuario sino que se desarrollan conjuntamente (equipo de desarrollo + usuarios) a medida que “se va descubriendo” el software a construir. En línea con esto, este cuatrimestre no les dimos las pruebas de aceptación, hicimos un product discovery y luego dejamos que cada equipo haga el trabajo de descrubimiento con su Product Owner (miembro del equipo docente). Obviamente que puertas adentro, todos los product owners (o sea el equipo docente) acordamos y alineamos ciertos puntos centrales de cara a intentar asegurar que todos los grupos construyan la misma aplicación más allá de algunas diferencias en términos de reglas de negocio. Esto trajo de la mano ciertas situaciones de negociación y trabajo de más ida y vuelta entre product owner y equipos de desarrollo, lo cual fue intencional para llevar a la práctica el slicing de funcionalidades. Respecto de este cambio, nos gustó y seguiremos con esta estrategia pero somos concientes que es necesario realizar algunos ajustes en la dinámica.

El segundo cambio importante requiere explicar un poco el contexto. Típicamente el TP2 tiene 3 ejes: alcance/funcionalidad, proceso y diseño/implementación. Previamente cada equipo de alumnos tenia un docente asignado que trabaja sobre los 3 ejes, proveía definiciones funcionales (tomando un rol típicamente de Product Owner), verificaba el cumplimiento del proceso (más en onda PMO que facilitador) y finalmente hacía seguimiento/evaluación de las cuestiones de diseño/implementación. Este cuatrimestre dividimos estas responsabilidades/ejes. Por un lado cada equipo tuvo asignado un docente que se encargaba del seguimiento del proceso y jugaba el rol de product owner proveyendo definiciones funcionales y validando su aprobación. Por otro lado, otro docente (yo en este caso) se encagó de la guíar técnicamente a todos los equipos y hacer el seguimiento y correcciones de diseño e implementación. También nos gustó este cambio y por ello vamos a mantenerlo.

Algunos otros cambios de menores que hicimos fueron que recortamos algunos temas (como escalamiento de agile y performance tests) e incluimos algunos nuevos. En realidad no es que agregamos nuevos temas sino que agregamos práctica de algunos temas que solo dábamos teoricamente como infra as code y contenedores.

Por otro lado, en la retro y en la encuesta de fin de curso, detectamos algunos puntos a ajustar entre los que se destacan dos: la gran dedicación requerida para el TP2 y la forma de dar feedback del código en las correcciones del TP2. Tomamos ambas cuestiones considerando que:

  1. En algunos casos hubo falta de foco durante el TP2 que llevó a invertir esfuerzo en funcionalidades no necesarias.
  2. Incluso cuando haya cuestiones que no esten bien al revisar el código hay que buscarle la vuelta en la redacción del feedback para también destacar algunos puntos positivos, pues siempre hay algo positivo para destacar y es necesario destacarlo para mantener la motivación del equipo,

Un tema intersante para descatar es que el primer cuatrimestre que no tuvimos abandonos. Los 21 alumnos que asistieron la primera clase, completaron la materia.

Ya para cerrar comparto algunas estadísticas:

  • Evaluación general del curso: 8.6 / 10
  • Claridad de los docentes: 4.3 / 5
  • Conocimiento de los docentes: 4.9 / 5
  • Dinámica de clases: 4.1 / 5
  • Materiales de estudio: 4.1 / 5
  • Dedicación promedio extra clase: 9.7 hs. semanales
  • Conformidad con la nota de aprobación: 4.3 / 5
  • Cantidad de tareas individuales: 38 (incluyendo 10 cuestionarios y 7 ejercicios de programación además de lecturas y videos)
  • Visita de la industria: Mariano Simone (gracias totales)
  • Nota promedio de aprobación de la materia: 7.9

De Android a iPhone y devuelta a Andriod

Resumen: tenía andriod, me pasé a iphone y ahora volví a andriod. Aquí voy a contar brevemente la experiencia.

Mi primer teléfono en la era de los smartphones fue un Samsung que corria Andriod 2.2 y cuyo modelo exacto no recuerdo. Creo que fue allá por 2010. Luego pasé por otro teléfonos alternando entre Motorola y Samsung, siempre en Andriod y siempre con teléfonos de gama media.

A mediados de 2017 me pasé a iPhone, concretamente compré un iPhone SE motivado casi exclusivamente por la relación potencia/tamaño, era en aquel momento el teléfono con mayores capacidades técnicas con ese tamaño “pequeño”. El cambio fue enorme, en parte por el salto de gama, el iPhone SE (y creo que todos los iPhones) es de gama alta y en parte por el cambio de sistema. En aquella época no utilizaba muchas aplicaciones en el télefono, apenas whatsapp, twitter y la cámara de fotos, con lo cual la migración fue muy simple. Mandé las fotos a google drive y los contactos que ya tenia sincronizados con Google, los importé fácilmente en el nuevo teléfono. Así fue que en 2 semanas ya estaba completamente acostumbrado al nuevo teléfono.

A pesar de tener una computadora MacBook, nunca exploté los beneficios de la integración/sincronización macbook-iphone-icloud. Tampoco me metí en cuestiones de desarrollo, si bien había hecho algunos experimentos programando Andriod, n unca tuve la inquietud ni la necesidad de ponerme a codear para iphone.

Por otro lado, aproveché las capacidades del nuevo teléfono y comencé a utilizar más aplicaciones: Spotify, Netflix, Mail, el navegador (antes del iphone creo que fueron contadas las veces que me puse navegar en el teléfono),. etc. En un punto algunas de las actividades que hacía exclusivamente en la computadora empecé a hacerlas con el teléfono. En este sentido algo que me resultó muy útil fue poder participar en videos llamadas (zoom, jitsi, google meet, etc) directamente desde el teléfono.

Hace un par de semanas, tuve un accedente doméstico, caí a la pileta con mi teléfono en un bolsillo. Chau iphone, probé con el arroz, lo llevé a un técnico especilizado pero no hubo caso. Así murió mi iphone al cabo de casi 4 años, sin tener ni una raya, ni golpe, estéticamente impecable pero ya no encendió más. El díagnostico del técnico fue “la placa está en corto”.

Mi primera reacción fue volver a comprar el mismo modelo pero resulta que ya no se fabrica. Hay una nueva edición 2020 pero que es de mayor tamaño. El tamaño había sido determinante en la eleccíon de mi primer iPhone. Esto me llevó a analizar algunas opciones Andriod. No encontré ningún teléfono Andriod que pudiera competir en la relación potencia/tamaño con el iPhone SE 2020. Todo teléfono Andriod disponible en el mercado local es al menos 1 o 2 centímetros más grande que el iPhone SE 2020. Consulté varios colegas y finalmente, a pesar del mayor tamaño, decidí volver a Andriod. Compré un teléfono Samsung de gama media porque por lo que vi la mayor diferencia entre los de gama media y gama alta pasaba por las capacidades/cantidad de cámaras y tamaño/definición de la pantalla, dos cuestiones que no son relevantes para mi.

La transición iPhone > Andriod fue mucho más dura que lo que había sido la transición Andriod > iPhone cuatro años atrás. En lo que respecta al setup, esto se debió en parte a que mi uso actual del teléfono es mucho más importante que lo era años atrás. Tenia en el iPhone unas ~15 aplicaciones que tuve que instalar y configurar en Andriod. Mientras hacía el setup descrubrí que tanto iPhone como Android proveen un funcionalidad de migración/setup de teléfonos cuando uno se migra a otro teléfono del mismo tipo: o sea, si se pasa de un iPhone a otro iPhone, casi que con acercar los teléfonos y activar el bluetooth, todas las aplicaciones, configuraciónes y datos se “transfieren” al nuevo teléfono y en cuestión de ~20 minutos quedá listo para andar. Algo análogo ocurre con de Android a Android. Al margen de las aplicaciones, la migración de contacto fue muy simple: exportar de icloud contacts e importantar en google contacts.

Una de clas cuestiones que me encontré en Android y que me genera cierta molesta es el “doble store”, o sea: mi teléfono Samsung tiene el store de Google (como todo teléfono Andriod) y el story de Samsung (como estimo que ocurre con todo teléfono Samsung). Esta situación de doble store ocurre también con algunas aplicaciones como ser contactos, navegador, etc. En el caso de iPhone hay un solo store porque tanto hardware como software son del mismos proveedor.

Otra cuestión que noté es que cuando quiero acceder funcionalidades “de hardware” (como las llamadas telefónicas y la radio) hay un pequeño delay/espera/retardo en su inicialización. Tal vez sea algo particular de mi modelo de teléfono pero en iphone nunca noté tal delay.

Un punto que aún no termino de entender es que en Andriod varias aplicaciones me envían notificaciones cuando sus respectivas versiones de iPhone no lo hacían. Tal vez sea que dichas aplicaciones están programadas de forma distinta o tal vez sea que la configuración default de notificación sea distinta a lo que tenia en el iPhone.

Al momento llevo unas 3 semanas con este nuevo Android, aún no me acostumbro, el hecho de que sea pura pantalla sin ningún boton de control (a excepción del encendido y el volumen) me resulta molesto.

Luego de todo lo contando debo decir que a pesar de no estár completamente habituado (aún), estoy conforme con la decisión, sobre todo cuando pongo en la balanza alguna cuestiones que van más allá de la usabilidad como la libertad (android es open source) y el costo (este teléfono android me costo un cuarto de lo que costaba el iPhone). De todas formas, nobleza obliga, debo decir que iPhone siempre me anduvo de 10, y tuve que cambiarlo por el accidente que mencioné, pero lo usé casi 4 años sin ningún problema. Quiero ver si este Samsung/Andrioid me dura el mismo tiempo 😉

Mi Samsung 2016, mi IPhone SE de 2017 y mi nuevo Samsung 2021