FINANZAS CON PYTHON: OBTENER DATOS INTRADIARIOS, CON ‘ALPHA VANTAGE’.

Los datos financieros intradiarios, también conocidos como datos intradía, son una fuente crucial de información para los inversores y traders. Estos datos proporcionan información sobre los movimientos de los precios de las acciones, divisas, criptomonedas y otros instrumentos financieros durante el transcurso de un día de negociación. ‘Alpha Vantage‘ es un servicio en línea que proporciona acceso a datos financieros intradiarios y una variedad de otros datos de la misma naturaleza. En este artículo, exploraremos cómo obtener tales datos, utilizando ‘Alpha Vantage‘ en Python.

Antes de comenzar, necesitaremos una clave de API gratuita de ‘Alpha Vantage’. Lo que nos permitirá acceder a los datos financieros proporcionados por la API. Para ello, podremos registrarnos en el sitio web de Alpha Vantage y obtener su clave de API gratuita.

Una vez que estemos registrados y tengamos nuestra clave, pasaremos a realizar la instalación de la correspondiente librería para Python, empleando el gestor de paquetes de Python, ‘pip‘:

Una vez hecho esto, ya podremos empezar a recopilar datos intradiarios. Para ello crearemos un nuevo archivo al que llamaremos ‘intraday.py‘ en el que después de realizar la pertinente importación de la librería, iniciaremos el objeto encargado de obtener la serie temporal de datos (al que en este ejemplo hemos dado el nombre de ‘ts‘) introduciendo la clave de API, que hayamos obtenido al registrarnos en el servicio:

Una vez que lo tengamos todo correctamente configurado, estaremos en condiciones de empezar a obtener datos intradiarios de cualquier activo. Así, imaginemos que queremos obtener la evolución de los precios de ‘Apple‘, y una periodicidad de actualización de 1 minuto:

OUTPUT:

Hemos de destacar que, al contrario de lo que estábamos acostumbrados cuando trabajábamos con series de datos por días, aquí los datos actualizados se van agregando por la parte superior de la tabla. Siendo por ello que para mostrar los datos más recientes, hemos utilizado la función «.head()» (que muestra las 5 primeras filas de la tabla) y «.tail()» (para mostrar las 5 últimas filas) para ver los 5 registros más antiguos (que en este caso se remontan al 25 de septiembre).

Antes, cuando hemos usado el método ‘get_intraday()‘ para obtener los datos, la información retornada por este ha sido almacenada en dos variables: ‘data’, en la que se ha guardado la serie temporal y ‘meta_data‘, en donde se guardan los metadatos de la serie, con las información por columnas que incluye:

OUTPUT:

Esta información nos puede ser de gran utilidad en el supuesto en que queramos acceder a un dato determinado de forma aislada. Por ejemplo, imaginemos que queremos elaborar una gráfica (utilizando ‘matplotlib‘) a partir de los datos antes obtenidos, mostrando solo el precio de cierre a lo largo de las últimas horas del pasado día:

OUTPUT:

Para concluir: ‘Alpha Vantage‘ es una fuente confiable y gratuita de datos financieros intradiarios que puede utilizar para sus análisis y estrategias de inversión. Con esta librería de Python, es fácil acceder y utilizar estos datos para tomar decisiones informadas en el mercado financiero.

Recuerda que ‘Alpha Vantage‘ ofrece una amplia variedad de datos financieros, no solo datos intradiarios. Pudiéndose explorar sus servicios y bibliotecas adicionales para obtener información más detallada sobre los mercados financieros.

Saludos.

ENCONTRANDO ARCHIVOS DUPLICADOS EN EL SISTEMA, CON «hashlib».

Hace unas semanas estuvimos hablando del módulo «hashlib«, con el que podíamos calcular, (pudiendo elegir entre varios algoritmos) el «hash» de un determinado archivo (el cual hace las veces de identificador único de dicho archivo). También hicimos una lista de posibles utilidades que al uso de dichas claves podíamos dar. Uno de aquellos usos era el de identificar archivos duplicados (entendiendo tales como aquellos que contienen idéntica información) en una base de datos o en un sistema. Así hoy, nos proponemos mostrar un sencillo ejemplo de como localizar dichos archivos duplicados usando «hashlib«.

Para ello, solamente vamos a hacer uso de la librería «hashlib» (con la que iremos calculando el valor «hash» de cada archivo) y el módulo «os» con el que iremos realizando (a partir de un directorio base que deberemos especificar) el recorrido de las carpetas y subcarpetas del sistema.

Así, nuestro script (al que daremos el nombre de «encuentra_duplicados.py«) constará basicamente de dos funciones: Una a la que llamaremos «encontrar_duplicados()» que, tomando como argumento el directorio base, a partir del cual, queremos que se efectúe la búsqueda por todas las subcarpetas, irá guardando todas las direcciones (y sus correspondientes valores «hash») en el diccionario «hash_dict» que definiremos previamente. De modo que si en el recorrido encuentra otro archivo con un «hash» ya almacenado en dicho diccionario, este será incluido en la lista «duplicados» (también definida con anterioridad):

Que duda cabe que para poder hacer la separación entre archivos duplicados y no duplicados en base al valor «hash» del archivo, la función hace una llamada a «calcular_hash_sha256()«. La otra función de nuestro script, encargada de calcular el valor «hash» del archivo, usando en este caso el algoritmo «sha256«:

Como hemos dicho, esta función irá realizando el calculo del valor «hash» de cada archivo (almacenado en la variable «nombre_archivo«) mediante la lectura del mismo en bloques de 64KB y retornando su valor «hash» con «sha256.hexdigest()«.

Finalmente, para que nuestro script funcione, tendremos que iniciarlo, estableciendo el directorio base a partir del cual queremos que se realice la búsqueda (variable «directorio_busqueda«) y la llamada a la función encargada de realizar la búsqueda. Finalmente utilizaremos un condicional para mostrar los resultados en pantalla, listando las rutas de archivos (con su respectivo «hash») que haya encontrado duplicados:

OUTPUT:

Y con esto quedaría visto este sencillo ejemplo de uso práctico del módulo «hashlib» en Python, cuyo código completo podéis examinar en el siguiente enlace:

https://github.com/antonioam82/ejercicios-python/blob/master/encuentra_duplicados.py

Saludos.

ALGORITMOS DE ORDENACIÓN EN PYTHON: ‘ORDENAMIENTO POR INSERCIÓN’

En el presente artículo nos proponemos continuar con el análisis de los diferentes métodos que podemos utilizar para la ordenación de una serie de elementos, en Python. Tras haber hablado en ocasiones anteriores del ‘ordenamiento en burbuja‘ hoy le toca el turno al conocido como ‘ordenamiento por inserción‘.

¿EN QUE CONSISTE?

El algoritmo de ‘ordenación por inserción‘ es un método de ordenación que trabaja construyendo una lista ordenada de elementos uno a uno. Este comienza con el primer elemento de la lista y, a medida que avanza, compara cada elemento con los que ya están ordenados. Si encuentra un elemento que es menor que el elemento anterior en la lista ordenada, lo inserta en su posición correcta. Este proceso se repite hasta que todos los elementos estén en su lugar y la lista esté ordenada. Se trata así de un procedimiento que podríamos sintetizar en los pasos siguientes:

1 – Partimos de una lista de elementos desordenados.

2 – Tomamos el primer elemento de la lista y lo consideramos una lista ordenada de un solo elemento.

3 – Pasamos al siguiente elemento de la lista desordenada y lo insertamos en la posición adecuada en la lista ordenada, realizando para ello la comparación a la que antes nos referimos.

4 – Repetimos este proceso hasta que todos los elementos de la lista desordenada estén en la lista ordenada.

IMPLEMENTACIÓN EN PYTHON.

Como es habitual, una vez definido nuestro algoritmo y explicado en líneas generales, como funciona, es el momento de ver como podemos implementarlo en Python. Para ello, vamos a definir una función (a la que hemos llamado ‘insertion_sort()‘) la cual llevará como argumento la lista de elementos cuyos valores queremos ordenar de menor a mayor (‘arr‘):

Tal y como se ve, el código implementa el algoritmo de ‘ordenación por inserción‘ iniciando un recorriendo de la lista desde el segundo elemento. Recorrido en el que va comparando cada elemento con los anteriores en una lista ordenada. De modo que si un elemento es menor que el anterior, lo desplaza hacia la derecha para abrir espacio y luego insertar el elemento en su posición correcta. Esto se repite hasta que todos los elementos estén ordenados. El ejemplo al final muestra la lista ordenada. A su vez, en cada iteración, iremos mostrando el estado actual de la lista para ver mejor su evolución. Este algoritmo tiene una complejidad O(n^2), que lo hace adecuado para listas pequeñas o casi ordenadas.

OUTPUT:

CONCLUSIÓN:

Como dijimos con anterioridad, el algoritmo de ‘ordenación por inserción‘ es un método simple y efectivo para ordenar listas en Python. Con una complejidad temporal de O(n^2) en el peor de los casos, lo que significa que su rendimiento disminuye a medida que aumenta el tamaño de la lista. Sin embargo, es eficiente para listas pequeñas o casi ordenadas.

En futuros artículos iremos viendo el resto de algoritmos de ordenación que podemos implementar en Python, con sus respectivos ejemplos.

Saludos.

COMPARACIÓN DE ARCHIVOS EN PYTHON, CON ‘hashlib’.

La librería ‘hashlib‘ en Python es una herramienta poderosa que nos permite calcular hashes criptográficos de datos, como archivos. Un hash es una cadena de caracteres generada por una función de hash criptográfica que representa de manera única los datos de entrada. En este artículo, exploraremos cómo utilizar ‘hashlib‘ para identificar la identidad de dos archivos y cómo esta técnica se utiliza en diversas aplicaciones del mundo real.

¿QUE ES ‘hashlib’?

La librería ‘hashlib‘ es una biblioteca estándar de Python que proporciona una interfaz fácil de usar para calcular hashes criptográficos de datos. Ofrece varias funciones de hash criptográfico, como MD5, SHA-1, SHA-256, entre otros. Estas funciones toman una entrada y producen un valor hash único y fijo, que es esencialmente una representación digital de los datos originales.

Para acceder al listado de algoritmos para creación de hashes, que ofrece ‘haslib‘, podemos hacer uso del método ‘algorithms_guaranteed()‘ tal y como se muestra a continuación:

IDENTIFICANDO IDENTIDAD DE DOS ARCHIVOS.

Tal y como hemos señalado más arriba, el propósito de la siguiente práctica es la de utilizar el hash criptográfico para determinar si un archivo de imagen dado es o no idéntico a otro (aquí usamos archivos de imagen, aunque este procedimiento puede aplicarse sobre cualquier otro tipo de archivo) que tomaremos como original. En nuestro caso, dicho archivo original será el llamado ‘portrait.jpg‘ que mostramos a continuación:

‘portrait.jpg’

Ya tenemos nuestro archivo fuente, a continuación, vamos a crear un script que, usando el algoritmo ‘SHA256‘, genere el valor hash de nuestra imagen (así como de la imagen a comparar) Para, a continuación comparar ambos valores para determinar la identidad (o falta de ella) entre ambas. El referido script se llamará ‘ejercicio_hash.py‘ y su código es el que se muestra a continuación:

‘ejercicio_hash.py’

Este código utiliza la biblioteca ‘Pillow‘ (‘PIL‘) para abrir y cargar las imágenes en lugar de simplemente leer el archivo en modo binario. Luego, calcula y compara los hashes de ambas. De modo que si los hashes son idénticos, se concluye que las imágenes son idénticas, mientras que en caso contrario se determinará que son diferentes.

Como se ve en el script, en esta primera ocasión vamos a comparar nuestra imagen original (‘portrait.jpg‘) con una copia exacta de la misma (‘portarit_copia.jpg‘) para ver el resultado.

OUTPUT:

Vemos como los valores hash tanto de ‘portarit.jpg‘ como de ‘portrait_copia.jpg‘, generados a partir de la información en bytes de cada una de las imágenes, son idénticos, con los que se determina que ambas imágenes son iguales.

Ya hemos visto como se determina la igualdad entre las imágenes. Pasemos ahora a identificar la diferencia entre ambas. Para ello vamos a coger la imagen original ‘portrait.jpg‘ y le vamos a aplicar una disminución de su dimensionalidad.

Antes de continuar, diremos que la reducción de la dimensionalidad (de la que hablaremos en mayor profundidad, en un futuro artículo), aplicada a un archivo de imagen, consiste en la disminución del número de píxeles o características que componen la misma, generalmente mediante técnicas de compresión o transformación. Pudiendo reducir el espacio de almacenamiento y el costo computacional, pero a menudo implicando también una pérdida parcial de detalles y calidad en la misma.

Pues bien, a continuación procederemos a aplicar dicho proceso sobre nuestra imagen original usando el script ‘SVD2.py‘ (cuyo código puede verse en el enlace que dejo al final) para crear una versión reducida de la misma, a la que llamaremos ‘portrait_diff.jpg‘:

Generando imagen reducida ‘portrait_diff.jpg’ a partir de ‘portrait.jpg’.

Aplicado el script de reducción, obtendremos una nueva imagen (‘portrait_diff.jpg‘) con menos información que la original, pero cuya escasa tasa de compresión y porcentaje de reducción de la dimensionalidad, hacen que la diferencia apenas sea perceptible a simple vista:

‘portrait_diff.jpg’

Ahora pasemos las dos imágenes casi idénticas a nuestro script ‘ejercicio_hash.py‘ para ver que resultado obtenemos:

OUTPUT:

Vemos como en la salida, a pesar de ser dos imágenes visualmente casi idénticas, el valor hash generado para cada una es totalmente distinto, quedando determinada la falta de identidad entre ambas.

APLICACIONES.

Por último, señalar que la identificación de la identidad de archivos mediante el uso de hashes criptográficos tiene diversas aplicaciones en el mundo real como las que a continuación enumeramos:

1- Integridad de Archivos: Se utiliza para verificar la integridad de los archivos descargados o transferidos. Si el hash del archivo descargado coincide con el hash proporcionado por la fuente original, se garantiza que el archivo no ha sido modificado durante la transferencia.

2- Detección de Duplicados: Puede ayudar a identificar archivos duplicados en un sistema de archivos o una base de datos, lo que puede ser útil para ahorrar espacio de almacenamiento.

3- Seguridad de Contraseñas: A menudo, las contraseñas se almacenan en forma de hashes para proteger la información del usuario. Cuando un usuario inicia sesión, el sistema compara el hash de la contraseña ingresada con el hash almacenado.

4- Verificación de Autenticidad: En la seguridad digital, se utilizan firmas digitales que implican el uso de hashes criptográficos para verificar la autenticidad de documentos y mensajes.

5- Blockchain: Las cadenas de bloques, como la de Bitcoin, utilizan hashes para garantizar la seguridad y la integridad de las transacciones.

En resumen, la librería ‘hashlib‘ en Python es una herramienta esencial para calcular y comparar hashes criptográficos, lo que permite identificar la identidad de dos archivos. Esta técnica se utiliza en una variedad de aplicaciones del mundo real, como hemos visto, para garantizar la integridad, autenticidad y seguridad de los datos.

En los dos enlaces tenéis los códigos de los scripts utilizados en este artículo: ‘ejercicio_hash.py‘ y ‘SVD2.py‘:

https://github.com/antonioam82/ejercicios-python/blob/master/ejercicio_hash.py

https://github.com/antonioam82/ejercicios-python/blob/master/SVD2.py

Saludos.

MOSTRANDO BARRA DE PROGRESO EN TERMINAL, CON «tqdm» (TUTORIAL BÁSICO).

A medida que trabajamos con bucles en Python para realizar tareas repetitivas, a menudo nos encontramos deseando tener una forma más visual y efectiva de rastrear el progreso de esos bucles. Aquí es donde entra en juego la biblioteca ‘tqdm‘ (que significa «taqaddum» en árabe, que se traduce como «progreso») la cual nos permitirá mostrar barras de progreso en nuestra terminal.

El módulo ‘tqdm‘ es una herramienta útil para crear barras de progreso en bucles, proporcionando una forma elegante y eficaz de monitorear el progreso de las operaciones, especialmente cuando se trabaja con tareas que requieren tiempo, como la descarga de archivos, el procesamiento de datos o la iteración a través de grandes conjuntos de estos. En este artículo, exploraremos cómo utilizar ‘tqdm‘ para mejorar la experiencia de seguimiento del progreso en tus scripts de Python.

INSTALACIÓN:

Primero, asegurémonos de que tenemos ‘tqdm‘ instalado. Para ello podemos utilizar ‘pip’, el gestor de paquetes de Python:

Una vez hecho esto, probaremos a importar el recurso en nuestro script y ejecutarlo, de modo que si no se produce ningún error, significará que la instalación se ha efectuado correctamente.

USO BÁSICO:

Pongamos el caso que tenemos un bucle que realiza una tarea repetitiva y deseas agregar una barra de progreso para hacer un seguimiento más claro del progreso de esta. Aquí tienes un ejemplo simple, en el que monitorizaremos un total de 10 iteraciones, utilizando ‘tqdm‘, a cuyo script le daremos el nombre de ‘tqdm_ejemplo1.py‘:

Como se ve, hemos empezado importando la librería ‘tqdm‘ para mostrar la barra en el terminal, y la librería ‘time‘ para detener el programa durante medio segundo al final de cada iteración (esto lo hemos hecho simplemente para ver mejor el proceso de actualización de la barra). Por su parte, el bucle ‘for‘ itera 10 veces, y para cada iteración, ‘tqdm‘ actualiza la barra de progreso. De modo que la función ‘tqdm‘ toma una secuencia (en este caso, un rango) y muestra el progreso en la barra. Por su parte, el argumento ‘desc‘ se utiliza para proporcionar una descripción opcional que se mostrará junto a la barra de progreso (en este ejemplo hemos puesto el texto ‘Procesando‘):

OUTPUT:

Con ‘tqdm‘ también podemos hacer el seguimiento sobre conjuntos de elementos iterables, como en este caso, listas:

OUTPUT:

Otra de las características que permite personalizar ‘tqdm‘ es la relativa a los caracteres que conforman la barra de progreso. Esto lo podemos definir con la variable ‘ascii‘, que si la hacemos igual a ‘True’, nos mostrará la barra conformada por caracteres ascii:

OUTPUT:

Así también podemos escoger nosotros, los caracteres que van a conformar la barra (utilizando también la variable «ascii«). De ese modo, pongamos que queremos una barra que este formada por el símbolo ‘$‘ y ‘‘ para el remanente. Para ello modificaremos el script anterior de la siguiente forma:

OUTPUT:

A su vez, si no queremos que la barra de progreso ocupe todo el ancho de la ventana del terminal, podemos utilizar el parámetro ‘ncols‘ para especificar la longitud de la barra, tal y como se muestra en este ejemplo:

OUTPUT:

CONCLUSIÓN:

La biblioteca ‘tqdm‘ es una herramienta sencilla pero poderosa para mejorar la experiencia de seguimiento del progreso en tus bucles y tareas repetitivas en Python. Proporciona una barra de progreso visualmente atractiva y personalizable que hace que el proceso de seguimiento sea mucho más intuitivo y agradable. Ya sea para proyectos pequeños o tareas más grandes, ‘tqdm‘ puede ayudarte a llevar un registro más eficiente del progreso de tus scripts. En el presente artículo nos hemos limitado a dar unas breves pinceladas acerca de las posibilidades, pero que constituyen un buen punto de partida a partir del cual, empezar a experimentar con esta herramienta. ¡Así que adelante y dale un toque de elegancia a tus bucles con ‘tqdm‘!

Saludos.

AÑADIENDO CONTRASTE A UNA IMAGEN A COLOR, EN PYTHON, CON «OpenCV».

Hace algún tiempo, estuvimos viendo el modo en que podíamos (usando el método de ecualización de histogramas) aumentar el contraste de una imagen en escala de grises. En el día de hoy vamos a ver como hacer eso mismo sobre una imagen a color utilizando la librería «OpenCV«. La imagen que vamos a utilizar como muestra es la siguiente:

Tal y como hemos señalado, para realizar la operación propuesta vamos a utilizar la librería «OpenCV«. También necesitaremos la librería «numpy«. Con lo que, antes de empezar, deberemos tener ambas instaladas en nuestro equipo:

Una vez que hayamos realizado la instalación de ambas, procederemos a su importación en nuestro script, y a cargar la imagen en cuestión incluyendo la ruta a la misma en el caso en que se encuentre alojada en un directorio distinto de aquel en el que estemos trabajando:

Una vez hecho esto, tendremos el arreglo de valores de intensidad de nuestra imagen en una variable a la que hemos dado el nombre de «imagen«. A continuación, procederemos a modificar el contraste de la imagen usando un procedimiento que podemos dividir en 5 fases:

1- Se define el valor de gamma como 2.5. Teniendo en cuenta que un valor de gamma mayor que 1 aumentará el contraste, mientras que un valor inferior a dicha cifra disminuirá este.

2- Se crea una tabla de consulta (look-up table) ‘lookUpTable‘, que se utiliza para mapear los valores de píxeles originales a los nuevos valores después de aplicar la transformación de gamma. Esta tabla tiene una fila y 256 columnas, correspondientes a los valores de intensidad de píxeles (0 a 255).

3- Luego, se realiza un bucle ‘for‘ para iterar sobre los valores de intensidad de píxeles (0 a 255).

4- En cada iteración, se aplica la fórmula de la transformación de gamma para calcular el nuevo valor de píxel utilizando la función ‘np.clip()‘, que asegura que el valor esté en el rango [0, 255].

5- Finalmente, la función ‘cv2.LUT()‘ aplica la tabla de consulta ‘lookUpTable‘ a la imagen ‘imagen‘, lo que resulta en una imagen con mayor contraste.

Los 5 pasos planteados quedan plasmados en las siguientes líneas de código:

Por último, podemos mostrar el resultado de la transformación empleando la función ‘imshow()’ de ‘cv2‘:

OUTPUT:

Como puede verse, obtenemos una imagen mucho más nítida que la original, lo cual, se ve especialmente en el color de la montaña (parcialmente oculto por la niebla, en la imagen original) permitiendo la apreciación de una mayor cantidad de detalles en la imagen.

Resumiendo, este código carga una imagen, aumenta su contraste mediante una transformación de gamma con un valor de 2.5 mostrando el resultado de dicha transformación en una ventana. Recuerden que siempre podéis cambiar el valor de ‘gamma’ para obtener diferentes niveles de contraste en la imagen resultante, ajustando el resultado a vuestras necesidades.

Saludos.

PROGRAMANDO COMPRESOR DE CARPETAS EN «ZIP» EN PYTHON, CON «zipfile» Y «PyQt5».

En el día de hoy os traemos una de esas aplicaciones que, de vez en cuanto, nos gusta hacer, poniendo en práctica los conocimientos ya adquiridos en artículos anteriores. La propuesta de esta semana consiste en crear una aplicación (cuyo código completo podéis consultar en el enlace que dejamos al final del artículo) que nos permita comprimir una carpeta en un archivo de extensión «.zip«, pudiendo navegar por nuestro sistema de archivos para seleccionar la carpeta a comprimir.

Para la confección de nuestra aplicación, 2 son las librerías principales (de las que ya hemos hablado en sendos artículos) que vamos a usar: «zipfile«, mediante la que realizaremos la compresión de los archivos de la carpeta que vayamos a seleccionar y «PyQt5«, con la que elaboraremos la interfaz que nos permitirá navegar por nuestro sistema de carpetas para seleccionar dicha carpeta a comprimir.

Instalación de ‘PyQt5’ y ‘zipfile’.

Una vez que tengamos listos, los recursos a utilizar, comenzaremos a escribir nuestra aplicación. La cual (tal y como se puede intuir viendo la imagen) nos mostrará en vista de árbol las carpetas (y el contenido de estas) que tenemos en nuestro sistema a partir de un directorio raiz (el cual podremos cambiar con el botón «Cambiar Directorio«) de modo que, una vez seleccionada una carpeta, podamos crear su versión «zip», donde queramos usando el botón «Crear ZIP«.

Así, lo primero que vamos a hacer es empezar a desarrollar nuestra aplicación empezando por crear la vista en árbol que nos permitirá movernos por nuestro sistema de carpetas. Para ello empezaremos importando las librerías y módulos que vamos a necesitar:

Tras ello, definiremos la clase «FileSystemView()«, con la que crearemos la vista de los archivos de nuestro sistema, mostrando en la parte superior, la ruta al directorio actual, estableciendo parámetros tales como las dimensiones de la ventana (con la función «setGeometry()«), el sistema de archivos, para a continuación, usar la función «QTreeView()» para mostrar las carpetas y archivos:

OUTPUT:

Dado que nuestra intención es poder movernos por todo el sistema de carpetas (para elegir la carpeta que queremos comprimir) y al abrirse la aplicación, esta muestra las carpetas del directorio de ejecución, nos interesa poder cambiar dicho directorio inicial. Por ello, crearemos un botón que nos permita dicho cambio y asociar a este, una función ( a la que llamaremos «changeDirectory()«):

OUTPUT:

De este modo ya podremos navegar por nuestro sistema de archivos y carpetas. No obstante el objetivo de nuestra aplicación es el de generar archivos «zip» de una carpeta que seleccionemos. Para ello incluiremos un segundo botón que nos permita dicha operación (la cual se efectuará mediante el empleo de la librería «zipfile«):

Finalmente, que duda cabe que para ello, necesitaremos definir una nueva función ( a la que hemos llamado «createZip()«) que se encargará de recorrer los archivos y subcarpetas de la carpeta a comprimir, escribiendo el nuevo archivo de extensión «.zip«) el cual, podremos guardar en el directorio que elijamos (usando la función «getExistingDirectory()«):

La referida función nos permitirá la creación de nuestro archivo comprimido, utilizándose, a su vez, «QMessageBox.information()» para mostrar una ventana emergente al finalizar el proceso:

De modo que una vez hecha la operación, podremos ver en el directorio de destino elegido, la nueva carpeta comprimida:

Con esto tendríamos creada nuestra sencilla aplicación para comprimir carpetas utilizando la librería gráfica «PyQt5» y «zipfile«. Cuyo código completo está a vuestra disposición en el siguiente enlace:

https://github.com/antonioam82/PyQtZip/blob/main/pyqtzip.py

Saludos.

VECTORIZACIÓN EN PYTHON, CON «numpy».

La vectorización es una técnica poderosa en el análisis de datos y el cálculo numérico. Permite realizar operaciones en arreglos de datos de manera eficiente y rápida, sin la necesidad de utilizar bucles explícitos. En Python, la biblioteca «numpy» es ampliamente utilizada para realizar operaciones vectorizadas. En este artículo, exploraremos el concepto de vectorización y cómo utilizarla con «numpy» para mejorar el rendimiento y la legibilidad de tu código.

1). ¿QUE ES LA VECTORIZAZCIÓN?.

La vectorización es una técnica que se basa en realizar operaciones en conjuntos de datos de manera simultánea, en lugar de iterar sobre ellos uno por uno. De ese modo, en lugar de utilizar bucles explícitos, aprovecharemos las capacidades de cálculo de arreglos que ofrece «numpy» para efectuar operaciones matemáticas y de manipulación de datos de forma eficiente.

2). BENEFICIOS DE LA VECTORIZACIÓN:

La vectorización tiene varios beneficios clave, que incluyen:

A) Mejor rendimiento: Al evitar bucles explícitos, las operaciones vectorizadas aprovechan las capacidades de cálculo altamente optimizadas de «numpy«, lo que resulta en un código más rápido y eficiente.

B) Código más conciso y legible: La vectorización permite expresar operaciones matemáticas y de manipulación de datos de manera más clara y concisa, lo que facilita la comprensión del código y reduce la posibilidad de errores.

3). USO DE OPERACIONES VECTORIZADAS CON «NUMPY»:

Tenemos así, que «numpy» proporciona una amplia gama de funciones vectorizadas que pueden aplicarse directamente a arreglos de datos. Estas funciones están optimizadas para operar de manera eficiente en grandes conjuntos de datos. Algunos ejemplos comunes incluyen:

A) Operaciones matemáticas elementales: Suma, resta, multiplicación, división, exponenciación, etc:

OUTPUT:

B) Funciones matemáticas: seno, coseno, logaritmo, raíz cuadrada, etc:

OUTPUT:

C) Operaciones de comparación y lógicas: igualdad, mayor que, menor que, operaciones booleanas, etc:

OUTPUT:

4). VECTORIZACIÓN PARA MANIPULACIÓN DE DATOS:

Además de operaciones matemáticas, la vectorización también es útil en la manipulación de datos. Así, «numpy» proporciona funciones para filtrar, ordenar y transformar arreglos de datos de manera eficiente. Algunos ejemplos incluyen:

A) Filtrado de elementos de un arreglo:

OUTPUT:

B) Ordenar un arreglo:

OUTPUT:

C) Aplicar transformaciones a un arreglo:

OUTPUT:

Conclusión:

La vectorización con «numpy» es una técnica poderosa que permite realizar operaciones matemáticas y de manipulación de datos de manera eficiente y legible. Al evitar bucles explícitos y aprovechar las funciones vectorizadas de «numpy«, puedes mejorar el rendimiento y la eficiencia de tu código. Esperamos que este artículo te haya brindado una guía útil sobre cómo utilizar la vectorización con «numpy» en Python. ¡Empieza a explorar y descubre el potencial de la vectorización en tus proyectos de análisis de datos!

Saludos.

ALGORITMOS DE ORDENACIÓN EN PYTHON: ‘ORDENAMIENTO DE BURBUJA BIDIRECCIONAL’

Hace algunas semanas iniciamos una serie de artículos en las que nos proponíamos analizar los distintos algoritmos que podemos implementar en Python, para ordenar los elementos de una lista empezando, en aquella primera ocasión, por el algoritmo de ordenación en burbuja. Hoy, por su parte, hablaremos del algoritmo de ordenación de burbuja bidireccional, el cual, constituye una variante de aquel. De modo que, a diferencia del algoritmo de burbuja tradicional que solo realiza pasadas hacia adelante, el algoritmo de burbuja bidireccional realiza pasadas hacia adelante y hacia atrás, lo que permite una optimización adicional al ordenar una lista de elementos.

El objetivo principal de cualquier algoritmo de ordenación es organizar los elementos de una lista en un orden específico, como ascendente o descendente. El algoritmo de burbuja bidireccional compara pares adyacentes de elementos y los intercambia si están en el orden incorrecto. La principal diferencia con el algoritmo de burbuja clásico es que realiza pasadas desde el principio de la lista hacia el final y desde el final hacia el principio, en forma alternada, hasta que no haya más intercambios por realizar. Este procedimiento puede verse ilustrado en la siguiente imagen:

Ordenamiento en burbuja bidireccional.

IMPLEMENTACIÓN EN PYTHON.

A continuación, crearemos una función (a la que hemos llamado «bubble_sort_bidi()«) mediante la que realizaremos una implementación en Python de dicho algoritmo:

En esta implementación, el algoritmo recibe una lista llamada «arr» y devuelve la lista ordenada. Donde la variable «n» representa la longitud de la lista (que obtenemos mediante la función «len()«) y las variables «left» y «right» indican los límites izquierdo y derecho de la porción de la lista aún no está ordenada.

En cada pasada hacia adelante, se compara cada par adyacente de elementos. Si están en el orden incorrecto, se intercambian. Después de cada pasada hacia adelante, se decrementa el valor de «right» en uno, ya que el elemento más grande de la porción no ordenada se coloca al final.

Luego, se realiza una pasada hacia atrás desde «right» hasta «left«, comparando e intercambiando los pares adyacentes de elementos si es necesario. Después de cada pasada hacia atrás, se incrementa el valor de «left» en uno, ya que el elemento más pequeño de la porción no ordenada se coloca al principio.

El bucle «while» continúa hasta que no haya más intercambios por realizar o hasta que los índices «left» y «right«se crucen, lo que indica que la lista está completamente ordenada.

Este proceso nos terminará devolviendo nuestra lista de elementos ordenados tal y como se puede comprobar en la salida, al pasar una lista de valores («my_list«) como argumento de nuestra función creada:

OUTPUT:

El algoritmo de burbuja bidireccional tiene una complejidad de tiempo de O(n^2) en el peor caso. Aunque puede ser eficiente en algunos casos, existen algoritmos de ordenación más rápidos para listas grandes (de los que iremos hablando en futuros artículos). Sin embargo, el algoritmo de burbuja bidireccional es fácil de entender y puede ser útil en situaciones donde se necesita una implementación simple para una lista de tamaño pequeño o moderado.

Y hasta aquí este breve artículo en el que hemos hablado de esta versión mejorada del algoritmo de burbuja que vimos hace un tiempo. En próximos artículos, veremos y analizaremos nuevos algoritmos de ordenación mas complejos y eficientes, usando Python.

Saludos.

TRANSFORMACIÓN RADIAL, AFÍN Y TANGENCIAL EN IMAGENES, CON PYTHON Y «OPENCV».

La transformación de imágenes es una técnica fundamental en el campo del procesamiento de imágenes y visión por computadora. Permite modificar la geometría y la apariencia de una imagen mediante la aplicación de diversas operaciones matemáticas. En este artículo, exploraremos tres tipos comunes de transformaciones: la transformación radial, la transformación afín y la transformación tangencial, y cómo implementarlas utilizando el lenguaje de programación Python y la librería «OpenCV» que deberemos tener previamente instalada en nuestro equipo. También vamos a necesitar hacer uso de «Numpy» por lo que igualmente deberemos instalarla, de no haberlo hecho:

Una vez instalada las librerías y recursos que vamos a usar, procederemos a aplicar las transformaciones referidas sobre la siguiente imagen:

«lenna.jpg»

1). TRANSFORMACIÓN RADIAL.

La transformación radial se utiliza para distorsionar una imagen de manera que se parezca a una proyección esférica o cilíndrica. Esta transformación es especialmente útil para corregir distorsiones de lente en fotografías. En Python, podemos utilizar la biblioteca «OpenCV» para realizar esta transformación. A continuación se muestra un ejemplo de código:

OUTPUT:

Tal como se ve en el código, creamos la función «radial_transform()«, la cual, toma como entrada una imagen y un factor de distorsión «k«. En ella, primero, se obtienen las dimensiones de la imagen y se calcula el centro de la misma. Luego, se crea una malla de coordenadas utilizando la función «np.meshgrid()«, para, a continuación, calcular la distancia desde el centro de la imagen a cada punto de la malla. Hecho esto, se calculan las nuevas posiciones de los píxeles de acuerdo a una fórmula que involucra el factor de distorsión y la distancia al centro. Estas nuevas posiciones se utilizan para interpolar los valores de los píxeles de la imagen original y generar una imagen distorsionada utilizando la función «cv2.remap()«. Finalmente, se muestra la imagen distorsionada utilizando «cv2.imshow()«. Al ejecutar el código, se carga una imagen, se aplica la transformación radial con un factor de distorsión específico mostrándose el resultado.

2). TRANSFORMACIÓN AFÍN.

La transformación afín es una transformación lineal que conserva la paralelismo de las líneas. Permite realizar operaciones como rotación, traslación, escalado y cizallamiento en una imagen. A continuación, veremos un ejemplo en el que realizaremos una traslación de 50 pixeles en el eje «x» y 20 en el eje «y«:

OUTPUT:

En este ejemplo, cargamos una imagen y definimos una matriz de transformación afín utilizando la función «np.float32«. Los parámetros «tx» y «ty» representan las cantidades de traslación en el eje x y eje y, respectivamente. Luego, utilizamos la función «cv2.warpAffine» para aplicar la transformación afín a la imagen.

3) TRANSFORMACIÓN TANGENCIAL.

La transformación tangencial permite corregir la distorsión de una imagen causada por lentes o cámaras. Se basa en el modelo de proyección de la cámara y utiliza coeficientes de distorsión para ajustar la imagen (se trata, así, de una transformación que nos permitirá modificar el ángulo de la imagen).

Para aplicar una transformación tangencial, necesitamos conocer los coeficientes de distorsión de la cámara. Estos coeficientes se pueden obtener mediante técnicas de calibración de cámaras (aunque para nuestro caso, nos limitaremos a definirlos nosotros para ver el resultado). Una vez obtenidos estos, podemos utilizar el siguiente código para aplicar la transformación tangencial a una imagen:

OUTPUT:

En este ejemplo, cargamos una imagen y definimos los coeficientes de distorsión «k1«, «k2«, «p1» y «p2«. Luego, creamos una matriz de cámara «matriz_camara» utilizando la función «np.array«, donde especificamos los parámetros intrínsecos de la cámara (que en este caso, nos hemos inventado). A continuación, definimos una matriz de distorsión «matriz_distorsion» con los coeficientes de distorsión. Finalmente, utilizamos la función «cv2.undistort» para aplicar la transformación tangencial a la imagen y mostramos la imagen original y la imagen transformada.

En este artículo, hemos explorado cómo aplicar transformaciones radial, afines y tangenciales a imágenes utilizando Python y la librería «OpenCV«. Estas transformaciones ofrecen la posibilidad de modificar la geometría y corregir distorsiones en las imágenes, lo que resulta útil en una amplia gama de aplicaciones en el campo del procesamiento de imágenes y la visión por computadora. Con las herramientas adecuadas, como «OpenCV«, Python se convierte en una poderosa opción para realizar estas transformaciones y manipular imágenes de manera eficiente y efectiva.

Saludos.