Dart SDK
Flutter SDK
Variables de entorno
Verificar
flutter doctor
.flutter doctor
.Continuando con nuestro estudio sobre las estructuras en Python, las matrices, que asemejan tablas bidimensionales, son herramientas fundamentales para el análisis y la manipulación de datos en Python.
Si bien las listas anidadas ofrecen una forma básica de crear matrices, NumPy emerge como la opción poderosa y eficiente. Acompáñame y sigamos descubriendo estas útiles estructuras, y si te perdiste el anterior post te dejo el enlace aquí.
Un matriz es una estructura de datos bidimensional que se asemeja a una tabla rectangular. Está formada por filas y columnas, y cada elemento de la matriz se encuentra en una posición específica determinada por su índice de fila y columna.
En Python, existen dos formas principales de crear matrices:
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
import numpy as np
matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix_1)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
Si bien ambas formas permiten crear matrices, los arrays NumPy presentan ventajas significativas:
Ya que las matrices con NumPy son estructuras matemáticas, además de poderse aplicar las mismas transformaciones que vimos con las listas, podemos aplicar la transposición, que consiste en una operación que intercambia las filas y las columnas. En otras palabras, los elementos de cada fila pasan a formar las columnas de la matriz transpuesta, y viceversa. Esta operación es muy importante en ciencia de datos e inteligencia artificial, ya que nos permite trabajar con derivadas, pero veamos algunos de sus usos:
import numpy as np
# Crea una matriz de ejemplo
matriz = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# Imprime la matriz original
print("Matriz original:\n", matriz)
# Transpone la matriz usando la función transpose()
matriz_transpuesta = matriz.transpose()
# Imprime la matriz transpuesta
print("\nMatriz transpuesta:\n", matriz_transpuesta)
Matriz original: [[1 2 3] [4 5 6] [7 8 9]] Matriz transpuesta: [[1 4 7] [2 5 8] [3 6 9]]
Una de las mayores ventajas de usar matrices con NumPy la obtenemos en la Multiplicación de matrices, aquí es donde NumPy destaca. La multiplicación de matrices puede ser computacionalmente costosa. Los métodos tradicionales tienen una complejidad temporal de para matrices de tamaño
. Sin embargo, NumPy utiliza algoritmos optimizados, como el algoritmo de Strassen, que reduce significativamente este costo. Si no te queda muy claro lo del calculo de complejidad puedes ampliar en este post.
Espero hayas comprendido los temas que vimos aquí, si tienes alguna duda o comentario compártelo para aprender juntos y no olvides suscribirte para estar al pendiente de los próximos post, se vienen los Vectores, así que hasta la próxima!
¿Cansado de software complejo y difícil de mantener? La DDD podría ser la solución que necesitas. Este enfoque innovador al diseño de software pone el foco en el dominio del problema, es decir, en el corazón del negocio que la aplicación está tratando de resolver. La DDD no es una solución mágica, pero ofrece un conjunto de beneficios que pueden ayudarte a crear software de mejor calidad.
La DDD (por sus siglas en inglés) es una metodología de diseño de software que se centra en el dominio del problema a resolver. En lugar de organizar el código por capas o componentes técnicos, la DDD se basa en los conceptos y reglas del negocio para estructurar la aplicación.
Olvídate de las capas y componentes técnicos. Con la DDD, el código se organiza en torno a los conceptos y reglas del negocio. Esto crea una estructura más natural y comprensible, que facilita la colaboración entre los equipos de desarrollo y los expertos en el negocio.
En DDD, se definen contextos delimitados, que son áreas del dominio con un vocabulario y lógica propios. Cada contexto se modela con entidades, agregados, servicios y otros elementos que representan los conceptos del negocio. Te voy a plantear dos ejemplos:
Esta arquitectura nos sirve cuando queremos por ejemplo tener múltiples bases de datos, ya sea por que tenemos diferentes orígenes o por que estamos en procesos de migración.
En este ejemplo imaginemos que tenemos un Gateway, donde lo que queremos tener separado es la lógica de las integraciones, es decir el consumo de APIs, ya que puede que tengan bastante movimiento y queremos mantenerlas aisladas.
Esperamos que esta introducción te haya servido para comprender los conceptos básicos de la arquitectura orientada a dominio (DDD). En próximas publicaciones, profundizaremos en los diferentes aspectos de esta metodología. No olvides dejar tus comentarios y dudas.
Java es un lenguaje de programación de propósito general, orientado a objetos y robusto que ha dominado la industria del software durante décadas. Su versatilidad lo hace ideal para desarrollar una amplia gama de aplicaciones, desde aplicaciones web y móviles hasta grandes sistemas empresariales. En este post, exploraremos las características clave de Java, sus ventajas y desventajas, qué necesitas para empezar, algunos proyectos para iniciarte y enlaces para ampliar tu conocimiento.
Una vez tengas dominadas las estructuras de control para Java y entiendas como trabajarlos saltaremos al Framework de Spring. También te dejo es link que es un tutorial oficial de Oracle para Java. Practica mucho y hasta la próxima, deja tus dudas y comentarios.
Dart es un lenguaje de programación desarrollado por Google, diseñado para ser eficiente, fácil de aprender. Su sintaxis limpia y su tipado estático facilitan la detección de errores y la escritura de código robusto.
Aunque originalmente se desarrolló para el desarrollo web, su potencial se ha extendido a la creación de aplicaciones móviles multiplataforma con Flutter.
¿Qué es? Flutter, también desarrollado por Google, es un framework de código abierto que utiliza Dart como su lenguaje principal. Es ampliamente reconocido por su capacidad para construir interfaces de usuario atractivas y de alto rendimiento que se ejecutan de manera consistente en iOS, Android y la web con un único código fuente.
Dart y Flutter son herramientas poderosas que combinan versatilidad, rendimiento y facilidad de uso. Si estás buscando un lenguaje de programación moderno para desarrollar aplicaciones web o móviles multiplataforma, Dart y Flutter son una excelente opción. Así que comparte tus comentarios y dudas. Suscríbete y hasta la próxima!
El mundo de la programación está en constante evolución, con nuevos paradigmas y tecnologías emergiendo constantemente. Dos de los enfoques más importantes en la actualidad son la programación imperativa y la reactiva. Cada uno tiene sus propias ventajas y desventajas, y la elección del más adecuado dependerá de las necesidades específicas de tu proyecto.
En este post, exploraremos en profundidad las características de la programación imperativa y reactiva, comparando sus similitudes y diferencias. Te guiaremos a través de ejemplos prácticos para que puedas comprender mejor cómo funcionan estos paradigmas y cuál se adapta mejor a tus necesidades como desarrollador.
La programación imperativa es el paradigma tradicional, donde el código se ejecuta en una secuencia de instrucciones paso a paso. El enfoque se centra en cómo se deben realizar las tareas, especificando cada detalle del proceso. Este paradigma ha sido la base de la programación durante décadas y es utilizado en lenguajes como C, C++, Java y Python.
La programación reactiva es un paradigma más reciente que se basa en el manejo de flujos de datos y la respuesta a cambios en el estado del sistema. En lugar de enfocarse en cómo realizar las tareas, la programación reactiva se centra en qué hacer cuando algo cambia. Este paradigma es ideal para aplicaciones que necesitan ser altamente sensibles a eventos y cambios en tiempo real, como interfaces de usuario, aplicaciones web y sistemas distribuidos.
Optimización de recursos: La programación reactiva mejora el uso de recursos del hardware, como el procesador, la memoria, la red, etc. Esto lo logra mediante la reducción de la serialización, permitiendo que el sistema trabaje en múltiples tareas simultáneamente sin bloquearse. Esto se traduce en un mejor rendimiento general de la aplicación.
Mejor experiencia de usuario: Gracias a su naturaleza asíncrona, la programación reactiva permite crear aplicaciones más fluidas, responsivas y fáciles de interactuar. Los usuarios no experimentarán bloqueos ni esperas innecesarias mientras la aplicación procesa información, mejorando su experiencia general.
Consistencia: Con la programación reactiva, puedes diseñar APIs más consistentes para diferentes aspectos de tu aplicación, incluyendo llamadas a bases de datos, interfaz de usuario, red, cálculos y cualquier otra funcionalidad que necesites. Esto se debe a que todo se maneja bajo el mismo paradigma, facilitando el entendimiento y mantenimiento del código.
Fácil manejo de operaciones asíncronas: La programación reactiva brinda soporte integrado y mecanismos claros para manejar operaciones asíncronas. Esto simplifica la interacción con la interfaz de usuario, la gestión de eventos y cualquier otra tarea que requiera trabajar con información que llega en distintos momentos.
Gestión simplificada de hilos: Comparado con los mecanismos tradicionales de hilos, la programación reactiva ofrece una forma más simple de gestionarlos. Implementar tareas paralelas de manera sincrónica y ejecutar callbacks cuando las funciones finalizan se vuelve más sencillo con este paradigma.
Mayor productividad para desarrolladores: En la programación imperativa tradicional, los desarrolladores deben realizar mucho trabajo para lograr un enfoque directo al computo asincrónico y no bloqueante. La programación reactiva, por otro lado, proporciona estas características de forma inmediata, eliminando la necesidad de coordinar manualmente diferentes elementos del código. Esto libera a los desarrolladores de tareas repetitivas y les permite enfocarse en la lógica de negocio de la aplicación, aumentando su productividad.
Amplié bastante destacando sus bondades, ya que para muchos es nuevo este tema, sin embargo también hay que tener en cuenta que presenta ciertos retos trabajar con esta metodología:
La respuesta a esta pregunta depende de varios factores, como el tipo de aplicación que estás desarrollando, la complejidad del proyecto, la experiencia del equipo de desarrollo y las necesidades específicas del cliente. Para acercarte un poco a que tomes tu propia decisión voy a resumir los tópicos claves de este post, así puedes tener un panorama general de cuando usarlo:
Deja tus comentarios y dudas para ayudarnos entre todos y no olvides suscribirte que en los próximos post empezaremos a adentrarnos mas en la programación reactiva y como implementarla en Java.
En Python, ya sea para minería de datos o trabajo con grandes volúmenes de información estructurada, el procesamiento se realiza comúnmente utilizando funciones y estructuras de datos de la biblioteca pandas. En este post nos vamos a centrar en dos estructuras de datos clave de esta librería, las series y los dataframes.
Este es el tercer post de una serie donde hemos venido hablando de estructuras de datos aplicadas en Python. Si te has perdido el contenido anterior lo puedes ver aquí.
En la biblioteca pandas, una Serie es un array unidimensional de valores para datos homogéneos. Podemos visualizar una Serie como una única columna en una hoja de cálculo, la cual contiene varios valores de una variable específica. En esencia, una Serie en pandas es utilizada para representar y manipular información unidimensional de manera eficiente.
import pandas as pd
personaje = pd.Series(['Jack',"Frost",16,True])
print(personaje)
# 0 Jack
# 1 Frost
# 2 16
# 3 True
En las estructuras de datos basadas en Series de pandas, es importante destacar el término “axis“(eje) que se utiliza para representar una secuencia de valores en una dimensión específica. La Serie tiene solo eje 0 debido a que es unidimensional. En la siguiente sección, exploraremos cómo se aplica este concepto de eje a un DataFrame.
Un DataFrame se construye sobre la estructura de datos de la Serie. Se almacena como datos tabulares bidimensionales y se utiliza para procesar datos estructurados de manera tradicional. Puedes pensar en un DataFrame como una tabla con filas y columnas, similar a una hoja de cálculo. La información se organiza en una cuadrícula donde cada fila representa una observación o registro, y cada columna representa una variable o característica específica.
En este contexto un DataFrame ofrece una manera eficiente y flexible de trabajar con conjuntos de datos complejos, ya que cada columna es esencialmente una Serie, permite aplicar operaciones y análisis de datos de manera coherente en toda la estructura.
pilares = pd.DataFrame([
['1', 'Kyojuru Rengoku', 'Llama'],
['2', 'Muichiro Tokito', 'Niebla'],
['3', 'Mitsuri Kanroji', 'Amor']])
pilares.columns = ['id', 'nombre', 'pilar']
print(pilares)
id | nombre | pilar | |
0 | 1 | Kyojuru Rengoku | Llama |
1 | 2 | Muichiro Tokito | Niebla |
2 | 3 | Mitsuri Kanroji | Amor |
En el código anterior, df.columns es una lista que especifica los nombres de las columnas. En un DataFrame, una sola columna o fila se denomina un eje.
Entender y manipular los ejes es fundamental al trabajar con DataFrames, ya que proporciona la capacidad de acceder, indexar y realizar operaciones a lo largo de filas o columnas de manera eficiente.
La selección de características es esencial para mejorar la eficiencia y evitar problemas como la redundancia y la dimensionalidad excesiva. En lugar de utilizar todas las características disponibles, es común seleccionar un subconjunto relevante que contribuya significativamente al rendimiento del modelo. Puedes recuperar una columna específica por su nombre, lo cual se ilustra en el siguiente fragmento de código. Este enfoque permite trabajar de manera más selectiva con las características necesarias para una etapa particular del algoritmo, mejorando así la eficacia y la interpretación.
pilares[['id','nombre']]
id | nombre | |
0 | 1 | Kyojuru Rengoku |
1 | 2 | Muichiro Tokito |
2 | 3 | Mitsuri Kanroji |
La disposición de una columna en un DataFrame es determinística, lo que significa que su posición está fijada de manera predecible. Puedes recuperar una columna específica no solo por su nombre, como se mencionó anteriormente, sino también por su posición dentro del DataFrame.
Para hacer esto, puedes utilizar la notación de corchetes y proporcionar el índice numérico de la columna que deseas recuperar. Es decir, la posición de la columna en el DataFrame. Por ejemplo:
pilares.iloc[:,2]
# 0 Llama
# 1 Niebla
# 2 Amor
En este caso, iloc
es un método que se utiliza para la indexación basada en ubicación en pandas. La expresión [:, 2]
significa que estás seleccionando todas las filas (:
) de la tercera columna (2
).
Este enfoque de recuperación por posición es útil en situaciones en las que conoces el orden específico de las columnas y prefieres referenciarlas por su posición numérica en lugar de su nombre. Sin embargo, es crucial tener en cuenta que esta metodología depende del orden en el que se han definido las columnas en el DataFrame, ya que esa secuencia determina las posiciones.
Cada fila en un DataFrame corresponde a un punto de datos en nuestro espacio de problemas. Si deseamos crear un subconjunto específico de los elementos de datos en nuestro espacio de problemas, es necesario realizar la selección de filas.
La selección de filas en un DataFrame es fundamental para trabajar con conjuntos de datos extensos y centrarse en segmentos particulares que son relevantes para nuestro análisis o aplicación de algoritmos de aprendizaje automático. Hay varias formas de llevar a cabo la selección de filas en pandas:
pilares.iloc[1:2,:]
id | nombre | pilar | |
1 | 2 | Muichiro Tokito | Niebla |
Una de las maneras más interesantes de selección es mediante el uso de condiciones booleanas.
Por ejemplo, si queremos seleccionar todas las filas que cumplen con ciertos criterios, podemos utilizar una expresión condicional. Supongamos que queremos seleccionar todas las filas donde el valor en la columna “pilar” sea igual a “Lama”:
pilares[pilares.pilar=='Llama']
Claro, podemos utilizar cualquier condición que se pueda comparar contra los datos.
Eso seria por ahora, dejamos este post aquí y te espero en el próximo donde hablaremos de matrices. No olvides dejar tus dudas y comentarios.
Este enfoque no solo redefine la forma en que concebimos la interacción entre componentes, sino que también desencadena una revolución en la capacidad de respuesta, la resiliencia y la elasticidad de nuestras aplicaciones.
Imaginen un equipo de jugadores colaborando para alcanzar un objetivo común, donde cada componente desempeña un papel crucial. Este escenario, similar a la dinámica de un Sistema Reactivo, ilustra cómo los elementos individuales pueden operar de forma independiente o en sincronía para lograr un resultado conjunto. Pero, ¿qué distingue a un Sistema Reactivo? Es la clave de su funcionamiento: la interacción dinámica entre componentes, que puede ser tan fluida como individual o tan armoniosa como colectiva.
En este blog, exploraremos los sistemas reactivos y la programación reactiva. Desentrañaremos los conceptos esenciales, desde las herramientas y metodologías de diseño hasta los principios de implementación que constituyen la columna vertebral de estos sistemas. Además, desafiaremos la confusión común entre los términos “Sistema Reactivo” y “Programación Reactiva”, destacando sus diferencias clave y sus roles cruciales en el desarrollo de software.
Prepárense para sumergirse en el universo de la reactividad, donde la capacidad de respuesta, la resiliencia y la elasticidad son mucho más que simples características; son los cimientos de un enfoque revolucionario en la creación de software para entornos distribuidos. ¡Bienvenidos a la nueva era de la programación reactiva y sistemas reactivos!
Un sistema reactivo se refiere a un conjunto de técnicas de diseño y principios utilizados en arquitecturas distribuidas. Se compone de herramientas, metodologías de diseño y procedimientos de implementación. Donde los componentes trabajan juntos para lograr un objetivo común. Lo que diferencia a un sistema reactivo a un sistema por defecto es la interacción entre los componentes, pudiendo operar de manera individual o en armonía para lograr un resultado conjunto. Recuerda el post de microservicios.
En el contexto de diseño y desarrollo de software, a menudo se usan indistintamente los términos “Sistema Reactivo” y “Programación Reactiva”, aunque no son exactamente lo mismo. Un Sistema Reactivo está asociado con la comunicación de procesos distribuidos a través de la red, mientras que la Programación Reactiva es generalmente basada en eventos y manejada localmente.
Un Sistema Reactivo se caracteriza por ser “responsivo” (responder a solicitudes en tiempo razonable), “resiliente” (mantener la respuesta incluso en caso de fallos) y “elástico” (capaz de adaptarse a cargas variables). Además, utiliza la comunicación de mensajes asincrónica entre componentes para lograr una interacción suelta, aislamiento de responsabilidades y transparencia en la ubicación.
La clave que distingue a un sistema reactivo es su enfoque en el procesamiento de flujos, utilizando un mecanismo de paso de mensajes asincrónico y no bloqueante entre componentes. Se centra en el procesamiento de flujos para lograr una mayor capacidad de respuesta, resiliencia y elasticidad en entornos distribuidos.
Es una práctica alineada con el flujo de datos y la propagación de cambios, y puede ser utilizada para construir un sistema reactivo. Se centra en manejar de manera efectiva flujos de datos asíncronos, permitiendo que los cambios en los datos se propaguen automáticamente a través del modelo de ejecución subyacente.
Se enfoca en gestionar flujos de datos como eventos de teclado, cambios en campos HTML, solicitudes HTTP, actualizaciones de datos, entre otros. Cuando ocurren cambios en un componente, una biblioteca o framework reactivo propaga automáticamente esos cambios a otros componentes, manteniendo una reacción dinámica en el flujo de datos.
A diferencia de la programación imperativa, donde los hilos se comunican de manera sincrónica, Reactive Programming no requiere esperar y puede realizar otras tareas mientras espera que un recurso esté disponible. Esto reduce el riesgo de que el sistema se bloquee, mejora la utilización eficiente de recursos y mantiene la capacidad de respuesta del sistema. Uno de los lenguajes que mas facilita el trabajo con hilos es GO, te dejo un post donde hacemos una introducción.
En el contexto de Reactive Programming, la asincronía implica que el procesamiento de mensajes o eventos ocurre en algún momento futuro. Esta naturaleza asíncrona y no bloqueante es especialmente útil en entornos de aplicaciones donde los recursos son compartidos, ya que no es necesario detener la ejecución mientras un recurso está ocupado en otro lugar.
En los próximos post nos enfocaremos en la programación reactiva, para ver sus principios y llegar a implementarla, así que suscríbete, deja tus comentarios y dudas.
Continuando nuestra ruta de estructuras de datos en Python, el segundo tipo de estructura de datos que se puede utilizar para almacenar una colección es una tupla.
A diferencia de las listas, las tuplas son estructuras de datos inmutables (de solo lectura). Las tuplas consisten en varios elementos rodeados por paréntesis ().
Al igual que las listas, los elementos dentro de una tupla pueden ser de diferentes tipos. También permiten que sus elementos sean tipos de datos complejos. Por lo tanto, puede haber tuplas anidadas.
vocales=('a','e','i','o','u')
print(vocales[1])
# 'e'
print(vocales[2:]}")
# ('i','o','u')
#Tupla anidada
mi_typla_anidada=('a',1,(3,True),8)
Como vemos, podemos aplicar el mismo slicing que hicimos para las listas.
Se recomienda usar estructuras de datos inmutables (como las tuplas) en lugar de estructuras de datos mutables (como las listas) siempre que sea posible, debido a cuestiones de rendimiento. Especialmente al tratar con grandes conjuntos de datos, las estructuras de datos inmutables son considerablemente más rápidas que las mutables. Cuando se pasa una estructura de datos a una función como inmutable, no es necesario crear una copia, ya que la función no puede modificarla. Esto se llama transparencia referencial y mejora el rendimiento. Aunque la capacidad de cambiar elementos de datos en listas tiene un costo, se debe analizar cuidadosamente si es realmente necesario.
Almacenar datos como pares clave-valor es crucial, especialmente en algoritmos distribuidos. En Python, esta colección se conoce como un diccionario.
Seleccionar una clave adecuada es esencial para identificar datos de manera eficiente durante el procesamiento. Las claves deben ser de tipos hashables(valor único y constante durante su vida útil) para garantizar su unicidad y rapidez en las búsquedas. Ejemplos de tipos hashables incluyen números enteros, cadenas de texto y tuplas.
Los valores pueden ser de cualquier tipo, incluso listas o diccionarios anidados. Para crear un diccionario simple, solo se requiere encerrar los pares clave-valor en llaves {}.
personaje ={
"nombre": "Juanito",
"apellido": "Escarcha",
"elemento": "Agua"
}
Para obtener un valor asociado a una clave, se utiliza la función get o simplemente utilizar la clave como índice. Veamos como:
personaje.get('nombre')
personaje['apellido']
Para actualizar un valor asociado a una clave lo usamos de manera similar al anterior ejemplo y “seteamos” su valor:
personaje['elemento']="Fuego"
print(personaje)
# {'nombre': 'Juanito', 'apellido': 'Escarcha', 'elemento': 'Fuego'}
Cuando iteramos un diccionario en Python, a menudo necesitamos tanto las claves como los valores. Fíjate en el siguiente ejemplo:
for k,v in personaje.items():
print(k,'->',v)
# nombre -> Juanito
# apellido -> Escarcha
# elemento-> Fuego
Para eliminar un elemento de un diccionario, utilizaremos la función del.
del personaje['elemento']
print(personaje)
# {'nombre': 'Juanito', 'apellido': 'Escarcha'}
Estrechamente relacionado con un diccionario está un conjunto, que se define como una colección desordenada de elementos distintos que pueden ser de diferentes tipos. Una de las formas de definir un conjunto es encerrar los valores entre llaves { }. Si un valor esta duplicado en este conjunto lo omitirá.
colores={'blanco','negro'}
Por ahora hemos llegado al final, pero aun nos falta estructuras por revisar, así que suscríbete y comparte este blog con tus compañeros de programación y amigos interesados en Python.
¡Gracias por ser parte de nuestra comunidad! ¡Esperamos con entusiasmo tus comentarios y contribuciones!
Interesado en las APIs(Interfaces de Programación de Aplicaciones), exploremos que es y además te dejo una lista de APIs públicas que puedes utilizar para realizar pruebas de desarrollo.
Antes de sumergirnos en el cómo, hablemos sobre el qué. Una API es esencialmente un conjunto de reglas que permite que diferentes aplicaciones se comuniquen entre sí. En términos más simples, actúa como un puente que permite que tu aplicación solicite y comparta datos con otra; para establecer esta comunicación se trabaja con un lenguaje común, actualmente la mayoría de APIs trabajan con JSON.
Recuerda revisar la documentación de cada API para entender cómo realizar solicitudes y qué datos puedes obtener. ¡Diviértete explorando y probando en tu desarrollo! 🚀🌐