Wednesday, January 25, 2023

Recursos para aprender los fundamentos de Inteligencia Artificial (AI)

Introducción

Estos últimos días he estado jugando con ChatGPT (prototipo de chatbot de inteligencia artificial desarrollado por OpenAI). Realmente estoy impresionado con los resultados obtenidos hasta el momento. Lo he estado probando principalmente con temas relacionados al estudio y práctica del idioma inglés, y puedo decir que he encontrado un asistente con el cual progresaré más rápido en mi aprendizaje.

Todo esto ha despertado mi curiosidad en la Artificial intelligence (AI). Estoy motivado por entender sus fundamentos, sus casos de uso y sus consecuencias en nuestra sociedad. Siento que esta tecnología es un punto de inflexión que nos permitirá construir soluciones innovadoras en diferentes industrias. Realmente estamos viviendo un momento tecnológico interesante. 


El propósito de post es dejar una colección de enlaces a distintos recursos de aprendizajes sobre AI. Esto podría ser un buen punto inicio para cualquiera que quiera iniciarse en este campo específico que forma parte de las tecnologías que impulsan la transformación digital. 

Y ya que hablamos de ChatGPT, me animé a pedir una mano generando un plan de estudio de Inteligencia Artifificial para personas sin experiencias. He aquí el resultado. 

Un programa de estudio de Inteligencia Artificial para personas sin experiencia en programación podría incluir los siguientes temas:
    1. Introducción a la Inteligencia Artificial: Este módulo proporcionaría una comprensión general de lo que es la IA, sus aplicaciones y los desafíos actuales en el campo.
    2. Aprendizaje automático: Este módulo presentaría los conceptos básicos del aprendizaje automático, como los diferentes tipos de algoritmos y cómo se utilizan para resolver problemas.
    3. Procesamiento del lenguaje natural: Este módulo se enfocaría en cómo las computadoras pueden comprender y generar texto humano, incluyendo técnicas como el análisis de sentimientos y la traducción automática.
    4. Visión por computadora: Este módulo se centraría en cómo las computadoras pueden interpretar imágenes y videos, incluyendo técnicas como el aprendizaje profundo y el análisis de objetos.
    5. Aplicaciones de IA: Este módulo se centraría en cómo la IA se utiliza en diferentes campos, como la salud, la finanzas, la robótica y el transporte.
    6. Proyectos prácticos: En esta parte del curso, los estudiantes tendrían la oportunidad de aplicar lo que han aprendido mediante proyectos prácticos y tal vez utilizando herramientas de inteligencia artificial de código abierto para no programadores.
    7. Ética e impacto de la IA: Este módulo se centraría en los desafíos éticos y sociales que surgen con el uso cada vez mayor de la IA, como la privacidad y la seguridad, así como el impacto económico y laboral.
Es importante también mencionar que este curso debería estar diseñado para ser accesible para personas no programadores, utilizando un lenguaje sencillo y ejemplos prácticos para ilustrar los conceptos.

Monday, January 23, 2023

Build Passive Income With ChatGPT OpenAI

Riesgos en la gestión de proyectos



Mejor práctica para escribir un riesgo

Debido a la <CAUSA(s)> puede ocurrir el <RIESGO o EVENTO_INCIERTO>, lo que provocaría el <EFECTO(s)> en el proyecto.


Enlaces


Notas de testing de aplicaciones .NET con xUnit y Moq


Una deuda pendiente durante mi carrera profesional dentro de la Industria del Software ha sido dedicarle tiempo y esfuerzo a profundizar en temas de Calidad de Software. Por eso he decidido investigar sobre testing de aplicaciones .NET con xUnit y Moq. El objetivo es obtener los conocimientos necesarios para contribuir una estrategia de pruebas de un proyecto.

Intro a las pruebas de código

  • Dos aspectos a tener en cuenta cuando creas tus pruebas de código son: Organización y Optimización.
  • Prácticas de diseño de software que impactan en la mejora de las pruebas: SRP, DIP 
  • Las pruebas van en un proyecto independiente del código que se quiere probar.
  • Con las pruebas de código podemos intentar asegurar que tu proyecto hace lo que se espera de él.
  • Organización de las pruebas: Separar totalmente el código de producción del código de pruebas.
    • Carpeta /src para proyectos de código para producción
    • Carpeta /test para proyectos de código para pruebas
  • Cómo implementar las pruebas: AAA
    • Arrange (Aprovisiona/Organiza): Para crear escenario de prueba
    • Act (Actúa): Ejecutamos el código que queremos probar
    • Assert (Afirma): Comprobar los resultados obtenidos vs los esperados.

  • Las pruebas se lanzan a través de: 
    • El explorador de pruebas
    • La terminal --> dotnet test
    • Live Testing (ejeución en segundo plano) --> Con Visual Studio edición Enterprise
  • Convención para los nombres: NombreDelMétodo_QueDeberíaDevolver_Condiciones
    • Sumar_ShouldBe5_IfA3AndB2()
    • Par_ShouldBeTrue_IfA2()
    • Dividir_ShouldBe4_IfA8AndB2()
    • Dividir_ShouldThrowDivideByZeroException_IfA8AndB0()

xUnit.net

  • Con xUnit.net podemos realizar pruebas de código mediante hechos y teorías.
  • Fact (Hecho): Una prueba de código única que te permite probar unas condiciones concretas.
  • Theory (Teoría): Pruebas de código múltiples. Cada ejecución de una teoría se lleva a cabo de manera independiente.
  • Para que las pruebas sean útiles, no solo hay que probar el resultado, sino todos los caminos lógicos que pueda seguir el código. Esto incluye las excepciones y los retornos nulos.
  • Una aserción no es más que una comprobación que, en caso de no cumplirse, lanza una excepción. xUnit.net trae un conjunto de asersiones, pero también se puede agregar nuevas a través de librerías.
  • Alguna veces es necesario preparar el entorno para las pruebas, por ejemplo incluir ciertos archivos en una carpeta. Podemos hacer esto a través del propio constructor de la clase para preparar las pruebas, e implementar IDisposable para limpiar los recursos una vez que hayamos terminado. Todo este código auxiliar que estamos usando en el constructor lo podemos sacar a una clase independiente a través de los Fixture (Accesorios).
  • In xUnit, a test fixture is all the things we need to have in place in order to run a test and expect a particular outcome. Existen 2 tipos de Fixture: 
    • De clase --> IClassFixture<T>
    • De colección --> ICollectionFixture<T>
  • Con el accesorio de clase (ClassFixture) vamos a poder compartir funcionalidad entre todas las ejecuciones de las pruebas de una clase.
  • La forma de indicar a mi clase de prueba que necesita un accesorio es la siguiente:
  • Para tener un código auxiliar que sea transversal a la ejecución de varias clases de prueba usamos un accesorio de colección (ICollectionFixture<T>). Con una colección agrupamos diferentes clases de prueba dentro de una misma ejecución.
  • xUnit.net permite agrupar/organizar pruebas. Esto lo logramos a través de los rasgos, es decir, a través del uso del atributo [Trait].
  • Los rasgos nos van a permitir filtrar dentro del explorador de pruebas
  • Tambien podemos crear rasgos personalizados. Con estos podemos agrupar bugs, agrupar historias de trabajo, tipos de prueba, funcionalidad, etc.
  • xUnit.net ofrece la posibilidad de registrar los logs que nos interese, y se añadirán al resultado de la prueba, independientemente de si esta pasa o no.


Simulaciones con Moq

  • Un Mock es un objeto simulado: fake object, dummy object, simulated object...
  • Moq es un framework de mocking.
  • Los mock (objetos simulados) nos van a permitir sustituir elementos de nuestro código por otros cuya respuesta controlamos. Esto lo conseguimos reimplementamos la interfaz con lo que a nosotros nos interese.
  • El hecho de ineyectar las dependencias nos permite redefinir comportamientos para poder hacer pruebas.
  • Podemos simular código creando código auxiliar para poder simular los objetos en las pruebas, pero esto tiene limitaciones cuando la aplicación escala en tamaño y funcionalidades (mucho código extra para mantener).
  • Frameworks para crear objetos simulados: NSubstitute, Moq, RhinoMocks, Foq, etc
  • Cómo usar Moq: 1) crear un objeto tipo Mock<T>, 2) configurar el mock, 3) Reemplazar un objeto desde un mock.
  • Lo más habitual es crear estos mock en el constructor de la clase de pruebas o en un accesorio, ya que así los vamos a poder utilizar en todas las pruebas aunque, si tienes la seguridad de que sólo vas a necesitarlo en una prueba en concreto, puede ir dentro de ella, en el Arrange.

Temas varios

  • Tipos de pruebas
    • Unitarias: Probar una única clase. Reciben un mock de las cosas que necesitan para poder funcionar.
    • De integración: Verifican que la integración de las diferentes clases y servicios funcionan correctamente. En este tipo de pruebas es posible utilizar mocks para algunos niveles que todavía no se pueden probar, como por ejemplo un servicio de terceros.
    • Funcionales: Probar el funcionamiento completo del sistema en base a los requisitos que tiene.
  • TDD
    • Es una forma de desarrollo ligada a las pruebas de código.
    • Pasos
      • Escribir las pruebas sobre un requisito concreto
      • Hacer el código que haga pasar la prueba
      • Por último, se hace una refactorización para dejar el código limpio
    • TDD permite desarrollar funcionalidades de una manera muy sólida.
  • Cobertura de código
    • Es una métrica porcentual que nos da información sobre qué código se ha probado y cuál no.
    • Los criterios (tipos) de cobertura del código  más usados en un proyecto son: a) Cobertura de líneas (line coverage), b) Cobertura de ramas (branch coverage).
    • Herramientas para medir la cobertura de código: Visual Studio Enterprise, extensión Resharper, Rider IDE, etc.
    • Hay diferencias a la hora de generar un informe de cobertura de código en .NET Clásico y .NET
  • Probar código Legacy
    • Si se añade nueva funcionalidad, agregarle sus respectivo código de prueba
    • Si se tiene que modificar compartamiento de un método viejo, evaluar si es viable crear un conjunto de pruebas para asegurar que no se rompe nada de ese código en concreto.
    • Consejo: Al trabajar con código heredado se deben contener esas ansias de conseguir la perfección que nos caracteriza a los desarrolladores.

Integración Continua y testing

  • Detectar que nuestro código funciona en otros servidores además de nuestro entorno local.
  • La integración continua es la parte del desarrollo de software que se encarga de integrar cambios con mucha frecuencia para detectar fallos de manera rápida.
  • Con la mayor frecuencia posible se compile el código desde 0 y se pasen todas las pruebas que haya en la solución.
  • Problemas derivados del desarrollo en equipo:
    • El código no compile
    • Se haya roto alguna funcionalidad
  • Con la Integración Continua podemos detectar errores relativos a dependencias. 
  • Gracias a la CI podemos tener siempre a mano una versión compilada con todos los cambios del equipo de desarrollo unidos.
  • Herramientas para hacer CI: 
    • Online: Azure DevOps, GitHub Actions
    • On-Premise: Jenkins
  • La integración continua de nuestro proyecto se puede iniciar de diversas maneras: a través de un commit + push de Git, con un Webhook, programada a determinadas horas cada día...
  • Proceso general de Integración Continua:

Links

Software Engineering Body of Knowledge (SWEBOK)

 


SWEBOK, Software Engineering Body of Knowledge, es un documento creado por la Software Engineering Coordinating Committee, promovido por el IEEE Computer Society, que se define como una guía al conocimiento presente en el área de la Ingeniería del Software.

Fuente: https://www.computer.org/education/bodies-of-knowledge/software-engineering

Software Engineering Design

Software design is an indispensable phase of the software engineering process for creating and evaluating software models that guide the construction effort for developing high-quality software systems on time and within budget. 

Conceptually, design is the process of transforming functional and nonfunctional requirements into models that describe the technical solution before construction begins. To achieve this, the concept of software design, its activities, and tasks must be well understood so that a problem-solving framework for designing quality into software products can be established. 

In today’s modern software systems, there are numerous design principles, processes, strategies, and other factors affecting how designers execute the software design phase. When equipped with the proper design foundation knowledge, an understanding of the designer’s roles and responsibilities can be acquired, allowing designers to become effective in designing large-scale software systems under a wide variety of challenging conditions.



API Gateway with ASP.NET Core

Grandes preguntas: ¿Repites mucho código en cada nuevo microservicio? ¿Haces que tus frontends llamen múltiples endpoints para obtener lo qu...