Historial de los últimos códigos añadidos

Listado de los últimos códigos introducidos.
Imágen de perfil
Actualizado

Generador de gifs a partir de video (nueva version)


Python

estrellaestrellaestrellaestrellaestrella(1)
Actualizado el 30 de Marzo del 2025 por Antonio (77 códigos) (Publicado el 29 de Enero del 2024)
9.867 visualizaciones desde el 29 de Enero del 2024
Programa para generar gifs animados a partir de vídeos, que se ejecuta en la línea de comandos.
ARGUMENTOS:
-src/--source: Nombre del vídeo original (obligatorio).
-dest/--destination: Nombre del archivo a generar (opcional).
-sz/--size: Tamaño en porcentaje del gif respecto al vídeo original (opcional).
-shw/--show: Muestra resultado en ventana emergente al finalizar el proceso de generado (opcional).
-st/--start: Segundo inicial para gif (opcional).
-e/--end: Segundo final (opcional).
-spd/--speed: Velocidad relativa de la animación (opcional)

PARA CUALQUIER DUDA U OBSERVACIÓN, USEN LA SECCIÓN DE COMENTARIOS.

imagge
Imágen de perfil
Actualizado

Vista 'grid' (demo)


Python

Actualizado el 29 de Marzo del 2025 por Antonio (77 códigos) (Publicado el 31 de Julio del 2023)
7.360 visualizaciones desde el 31 de Julio del 2023
El siguiente código muestra un grid en pantalla por el que se puede desplazar usando los botones de dirección:

Botón de dirección derecha: Desplazamiento hacia la derecha.
Botón de dirección izquierdo: Desplazamiento a la izquierda.
Botón de dirección superior: Desplazamiento hacia adelante.
Botón de dirección inferior: Desplazamiento hacia atrás.
Botones 'o', 'p', 'k' y 'l': Desplazamientos en diagonal.

grid
Imágen de perfil
Actualizado

Buscador de archivos mediante expresiones regulares (nueva versión)


Python

Actualizado el 29 de Marzo del 2025 por Antonio (77 códigos) (Publicado el 5 de Mayo del 2022)
3.448 visualizaciones desde el 5 de Mayo del 2022
Programa para buscar archivos mediante expresiones regulares.
COMANDOS:
cbd <dir> cambia el directorio base.
sch <string> realiza búsqueda por el sistema de carpetas a partir de la carpeta base.
cl realiza limpieza de pantalla.
help muestra lista de comandos.
q finaliza programa.

PARA CUALQUIER DUDA U OBSERVACIÓN, USEN LA SECCIÓN DE COMENTARIOS.
ff43
ff42
ff41
Imágen de perfil

Visor interactivo de modelos 3D


Python

Actualizado el 21 de Marzo del 2025 por Antonio (77 códigos) (Publicado el 7 de Febrero del 2025)
3.668 visualizaciones desde el 7 de Febrero del 2025
Este programa es un visor de modelos 3D en formato `.obj` que utiliza `OpenGL` y `pygame` para renderizar y manipular objetos 3D. Ofrece varias funciones de visualización como rotación, zoom, traslación, cambio entre vista en perspectiva y vista ortográfica, y otras acciones útiles para examinar el modelo cargado.

### Principales funciones del programa:

1. **Carga de modelo `.obj`:** El archivo `.obj` se especifica a través de un argumento y se carga mostrando los vértices, aristas y caras del modelo.
2. **Visualización en 3D:** Permite cambiar entre vista ortográfica y perspectiva.
3. **Rotación del modelo:** Utiliza cuaterniones para rotar el modelo sobre cualquier eje.
4. **Zoom y traslación:** Posibilidad de hacer zoom y mover el modelo en la pantalla.
5. **Información en pantalla:** Se puede mostrar/ocultar información como el nombre del modelo, escala, número de vértices, aristas y caras.

### Comandos principales:

- **Flechas del teclado:** Rotan el modelo en diferentes direcciones.
- **Tecla 'R':** Reinicia la rotación y escala del modelo.
- **Teclas 'M' y 'N':** Rotación en sentido horario y antihorario sobre el eje Z.
- **Tecla 'P':** Alterna entre vista en perspectiva y ortográfica.
- **Tecla 'X' y 'Z':** Zoom in y Zoom out, respectivamente.
- **Mouse:** Arrastrar con el clic izquierdo para mover la escena y usar la rueda del ratón para hacer zoom.
- **Tecla 'H':** Mostrar/ocultar la información en pantalla.
- **Tecla 'ESC':** Cierra el programa.
ov1
ov2
ship

Para cualquier duda u observación, usen la sección de comentarios.
Imágen de perfil

ChessPDFBrowser


Java

estrellaestrellaestrellaestrellaestrella(2)
Actualizado el 18 de Marzo del 2025 por Francisco Javier Rojas Garrido (26 códigos) (Publicado el 22 de Noviembre del 2017)
16.286 visualizaciones desde el 22 de Noviembre del 2017
chessPDF

Aplicación de ajedrez que permite trabajar con las partidas de los libros de ajedrez en PDF (siempre que los libros no sean escaneados y las partidas estén escritas en formato algebraico).

La nueva versión (v1.26), también permite extraer partidas en notación algebraica de figuras

También permite trabajar con listas de partidas leídas/escritas en formato PGN, y modificar los TAGs, NAGs y comentarios.

Los árboles de variantes pueden se modificados realizando movimientos con las piezas situadas en un tablero.

Permite trabajar con partidas incompletas (es decir, que empiecen en un movimiento posterior al inicial)

- Multi-idioma
- Multi-precisión
- Modo oscuro
- Conexión con motores tipo UCI
- OCR que convierte imágenes con una posición en un tablero, en una cadena estándar FEN

Compatible con el JDK-17

Vídeo de demostración de la nueva funcionalidad (v1.26)
(entrenamiento del reconocedor de figuras para la extracción de partidas en notación algebraica de figuras)

https://frojasg1.com:8443/resource_counter/resourceCounter?operation=countAndForward&url=https%3A%2F%2Ffrojasg1.com%2Fdemos%2Faplicaciones%2FChessPdfBrowser%2Fv1.26.ES.02.extraer.partidas.notacion.algebraica.de.figuras.mp4%3Forigin%3Dlawebdelprogramador&origin=web
Imágen de perfil

Colector de links


Python

Actualizado el 15 de Marzo del 2025 por Antonio (77 códigos) (Publicado el 6 de Marzo del 2022)
4.130 visualizaciones desde el 6 de Marzo del 2022
Aplicación para guardar accesos directos a internet (que se guardan en un archivo 'json' que se genera al ejecutar el programa por primera vez), mediante la introducción de la URL en la entrada superior (o su copia mediante el botón 'IMPORT NEW LINK'). El nuevo acceso se guarda mediante el botón "SAVE LINK AS:" que abrirá una ventana pidiendo el nombre del nuevo acceso. Una vez guardado el acceso, se podrá acceder a la correspondiente página seleccionando, en la lista, el elemento guardado y clicando en el botón 'ACCESS' (admite selección normal y múltiple). También permite la eliminación la totalidad de los link o solo los seleccionados. También permite la búsqueda por nombre entre los accesos guardados. El botón "SAVE LIST" generará un archivo de texto con los nombres de enlace y sus correspondientes URLs asociadas, que estén almacenados en el archivo JSON.
PARA CUALQUIER DUDA U OBSERVACIÓN, USEN LA SECCIÓN DE COMENTARIOS.
LNKC
Imágen de perfil

Minado de Bitcoins.


Python

estrellaestrellaestrellaestrellaestrella(1)
Publicado el 14 de Marzo del 2025 por Hilario (143 códigos)
220 visualizaciones desde el 14 de Marzo del 2025
**********************************************************************************************

Captura-de-pantalla-de-2025-03-13-10-23-01
Captura-de-pantalla-de-2025-03-13-10-23-08
Captura-de-pantalla-de-2025-03-13-10-23-15
Captura-de-pantalla-de-2025-03-13-10-23-22
Captura-de-pantalla-de-2025-03-13-10-23-27

************************************************************************************************


Ejercicio:

Aula_28_Minado_Bitcoin_Target_Marzo_14_25.py
********************************************************
Sobre el bitcoin, habíamos planteado anteriormente dos ejercicios sucesivos sobre arboles de Merkle, y el analisis de una transación de Bitcoins en formato RAW. Hoy propongo para el aula y taller 28, un sencillo ejercicio en Python que tratara sobre em minado de Bitcoins.

En líneas generales el minado de Bitcoin en qué consiste:
****************************************************************

El minado de Bitcoin es el proceso mediante el cual se validan y registran transacciones en la blockchain de Bitcoin, asegurando la red y emitiendo nuevas monedas como recompensa a los mineros. A grandes rasgos, implica lo siguiente:

Agrupación de transacciones en bloques:
-----------------------------------------------------


Los mineros recopilan transacciones pendientes de la mempool (el "pool de memoria" donde se almacenan temporalmente).
Crean un bloque con estas transacciones y añaden un encabezado que incluye el hash del bloque anterior, un marcador de tiempo y otros datos.
Resolución de una prueba de trabajo (PoW - Proof of Work):

Para añadir un bloque a la blockchain, los mineros deben encontrar un hash que cumpla con ciertos requisitos de dificultad.
Esto se hace probando diferentes valores (llamados nonce) y calculando el hash SHA-256 del bloque repetidamente hasta encontrar uno válido.
La dificultad del hash está determinada por el protocolo y se ajusta cada 2016 bloques (~cada dos semanas) para mantener un tiempo promedio de 10 minutos por bloque.
Difusión y validación del bloque:

Cuando un minero encuentra un hash válido, transmite el bloque a la red.
Otros nodos verifican que las transacciones sean legítimas y que la prueba de trabajo sea correcta.
Si el bloque es válido, se añade a la blockchain y la red sigue minando el siguiente bloque a partir de este.

Recompensas por minado:

El minero que resuelve el bloque recibe una recompensa en Bitcoin (actualmente 6.25 BTC por bloque, pero se reduce a la mitad cada 210,000 bloques en el evento llamado halving).
Además, recibe las comisiones de transacción de las operaciones incluidas en el bloque.
En resumen, el minado de Bitcoin es una carrera entre mineros para resolver un problema matemático difícil con fuerza bruta, asegurando la red y permitiendo la emisión controlada de nuevos bitcoins.

Bien, esto que aprimera vista parece un tanto farragoso, lo explicamos en este ejercicio de Python.

QUÉ PARÁMETROS ENTRAN EN EL MINADO:
******************************************************

1. Parámetros técnicos del bloque.
**************************************
Merkle Root: Raíz del árbol de Merkle que agrupa todas las transacciones dentro del bloque.
Versión del bloque: Número que indica la versión del protocolo en uso.
Hash del bloque anterior: Identificador único del bloque anterior en la cadena.
Marca de tiempo (Timestamp): Hora en que se generó el bloque, expresada en segundos desde 1970 (UNIX time).
Bits (Dificultad objetivo): Indica el nivel de dificultad que debe cumplir el hash del bloque.
Nonce: Número aleatorio que los mineros modifican hasta encontrar un hash válido.

2. Parámetros de minado (Prueba de Trabajo - PoW)
************************************************************
Algoritmo de hashing: Bitcoin usa SHA-256 para generar los hashes.
Dificultad de minado: Ajustada cada 2016 bloques (~2 semanas) para que el tiempo promedio de creación de bloques siga siendo 10 minutos.
Objetivo (Target): Límite numérico que el hash del bloque debe cumplir (ser menor que un valor determinado por la dificultad).
Tasa de hash (Hashrate): Velocidad con la que un minero puede calcular hashes por segundo.
Consumo energético: Cantidad de electricidad utilizada por el minero para realizar cálculos.

3. Parámetros económicos.
*******************************
Recompensa por bloque: Actualmente 6.25 BTC, se reduce a la mitad cada 210,000 bloques (halving).
Comisiones de transacción: Pagos que los usuarios adjuntan a sus transacciones para incentivar a los mineros a incluirlas en el bloque.
Costo de hardware: Precio de los equipos de minería, como ASICs especializados.
Costo de electricidad: Factor crucial que afecta la rentabilidad del minero.

4. Parámetros de red.
************************

Mempool: Espacio donde esperan las transacciones antes de ser incluidas en un bloque.
Latencia de red: Velocidad con la que se propagan los bloques en la red, lo que puede afectar la probabilidad de éxito en la minería.
Competencia minera: Cantidad de mineros activos y su potencia de cómputo total en la red (hashrate global).
5. Parámetros de dificultad y ajuste.
****************************************

Retargeting de dificultad: Se ajusta cada 2016 bloques para mantener el tiempo promedio de generación en 10 minutos.
Número de mineros en la red: Mientras más mineros haya, mayor será la competencia y la dificultad.

***************************************************************************************

En nuestro ejercicio, queidos alumnos, nos fijaremos sólo en el punto 1.

Aqui pasamos a describir los pasos de nuestro ejercicio:
-------------------------------------------------------

1. Importación de módulos.
*************************

import hashlib
import time
import struct
hashlib: Para calcular el doble SHA-256, que se usa en la minería de Bitcoin.
time: Para manejar el timestamp y calcular el tiempo transcurrido.
struct: Para empaquetar los datos del bloque en el formato binario usado en Bitcoin.

2. Funciones principales.
*************************

2.1. Cálculo del doble SHA-256.
-----------------------------

def double_sha256(header):
return hashlib.sha256(hashlib.sha256(header).digest()).hexdigest()
Se aplica SHA-256 dos veces al encabezado del bloque, que es el método que usa Bitcoin.

2.2. Conversión de bits a target.
-------------------------------
def bits_to_target(bits):
bits_int = int(bits, 16)
exponent = (bits_int >> 24) & 0xFF
mantissa = bits_int & 0xFFFFFF
target = mantissa * (2 ** (8 * (exponent - 3)))
return hex(target)[2:].zfill(64)
Bitcoin usa una representación compacta de la dificultad llamada bits.
Esta función lo convierte en el valor real del target, que es el número máximo que puede tener un hash válido.

3. Parámetros del bloque.
***********************


version = "0x20000000"
previous_block_hash = "0000000000000000000aef1f5f7de00000000000000000000000000000000000"
merkle_root = "4a5e1e4baab89f3a32518a88c31bc87f00000000000000000000000000000000"
bits = "1E00FFFF" # Se ha aumentado para reducir la dificultad
nonce = 0
timestamp = int(time.time())
version: Versión del protocolo Bitcoin.
previous_block_hash: Hash del bloque anterior.
merkle_root: Raíz del árbol de Merkle (aglutina todas las transacciones).
bits: Representación compacta de la dificultad.
nonce: Número que cambia hasta encontrar un hash válido.
timestamp: Momento en que el bloque fue creado.

4. Creación del encabezado del bloque.
************************************


def create_block_header(version, prev_hash, merkle_root, timestamp, bits, nonce):
return struct.pack("<L32s32sLLL",
int(version, 16),
bytes.fromhex(prev_hash.zfill(64)),
bytes.fromhex(merkle_root.zfill(64)),
timestamp,
int(bits, 16),
nonce)
Empaqueta los datos del bloque en un formato binario para ser minado.
Formato:
<L32s32sLLL
Indica que los datos están en little-endian (el formato usado en Bitcoin).

5. Bucle de minado.
*****************


print("Comenzando el minado...")
start_time = time.time()
target_time = 160
Se inicia el minado y se establece un límite de tiempo para evitar que el código corra indefinidamente.

while True:
elapsed_time = time.time() - start_time
if elapsed_time > target_time:
print(f"Tiempo límite alcanzado ({target_time} segundos). Minado detenido.")
break
Si el tiempo excede target_time, se detiene la minería.

5.1. Creación del bloque y cálculo del hash.
******************************************


block_header = create_block_header(version, previous_block_hash, merkle_root, timestamp, bits, nonce)
block_hash = double_sha256(block_header)
Se genera el encabezado del bloque y se calcula su hash con doble SHA-256.

5.2. Verificación del hash.
**************************


if int(block_hash, 16) < int(target, 16):
print(f"¡Bloque minado! Nonce encontrado: {nonce}")
print(f"Hash del bloque: {block_hash}")
break
Si el hash generado es menor que el target, significa que el bloque ha sido minado con éxito.
Se imprime el nonce encontrado y el hash válido del bloque.

5.3. Incremento del nonce.
*************************


nonce += 1
Si el hash no es válido, se incrementa el nonce y se prueba de nuevo.

5.4. Mostrar progreso.
*********************

if nonce % 1000 == 0:
print(f"Intentos: {nonce}, Hash actual: {block_hash}")
Cada 1,000 intentos imprime el hash actual para ver el progreso del minado.

6. Impresión de estadísticas finales.
***********************************


end_time = time.time()
print(f"Tiempo total de minado: {end_time - start_time:.2f} segundos")
Muestra el tiempo total que tardó en encontrar el nonce correcto.


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Este ejercicio, fue realizado sobre plataforma Linux.
Ubuntu 20.04.6 LTS.
Editado, con Sublime text.

Ejecutado bajo consola Linux, con este comando:
python3 Aula_28_Minado_Bitcoin_Target_Marzo_14_25.py
Imágen de perfil

BITCOIN: Transación, formato raw.


Python

estrellaestrellaestrellaestrellaestrella(1)
Publicado el 4 de Marzo del 2025 por Hilario (143 códigos)
1.616 visualizaciones desde el 4 de Marzo del 2025
Captura-de-pantalla-de-2025-03-04-11-16-50

**********************************************




Ejercicio: Aula_28_Transacion_Bit_Coin_Marzo_25.py
**************************************************

Formato RAW de la transacción BITCOIN
//////////////////////////////////////////////////////////////////


Propongo un ejercicio interesante. Datos de una transacción de Bitcoin en formato raw (hexadecimal).Cuando una transacción se crea, se representa en un formato hexadecimal binario. Pero luego, ¿Cómo se calcula el txid de una transacción en Bitcoin?. Pues, queridos alumnos, de eso va este ejercicio propuesto.
IDEA INICIAL DEL CÓDIGO.
Necesitamos hacer en Python, bajo Ubuntu, un programa ejemplo de una transacción en formato raw (hexadecimal), teniendo en cuenta que se deben aportar los datos ficticios, es decir para tener una salida en formato raw, de la transación y posteriormente lograr el cálculo que nos dará el txid, correspondiente. Este es el punto de partida, para que una vez optenidos todos los TXID, de todas las transacciones podramos obtener :
Una vez que tenemos todos los TXID de las transacciones de un bloque, los organizamos en un árbol de Merkle, - que ya vimos en un ejercicio anterior, que se construye aplicando doble SHA-256 a pares de hashes hasta obtener un único hash raíz (Merkle root).

¿Qué significa esto en la práctica?
El hash final del bloque (Block Hash) es el identificador único de ese bloque en la blockchain.
Este hash será el "hash del bloque anterior" en el siguiente bloque de la cadena, asegurando la integridad y seguridad de la blockchain.

Bien, los datos ficticios que aportaremos en nuestro programa serán los siguientes:
*******************************************************************************
Este formato hexadecimal incluye:
• Version de la transacción.
• Entradas (Inputs):
• Hash de la transacción previa (UTXO).
• Índice de salida (vout).
• Script de firma.
• Salidas (Outputs):
• Cantidad de satoshis enviados.
• Script de bloqueo (scriptPubKey).
• Locktime (para definir si se puede gastar en el futuro).

SIGNIFICADOS:
***********************
1. Versión de la transacción
Este es un número que indica la versión del formato de la transacción. A medida que el protocolo de Bitcoin evoluciona, pueden introducirse nuevas versiones para mejorar la funcionalidad y seguridad de las transacciones.

Actualmente, las versiones más comunes son 1 y 2.
La versión 2 se introdujo para admitir Replace-By-Fee (RBF), permitiendo reemplazar una transacción no confirmada con una versión de mayor comisión.
2. Entradas (Inputs)
Las entradas indican de dónde provienen los bitcoins que se están gastando en la transacción.

2.1. Hash de la transacción previa (UTXO)
Cada entrada hace referencia a una salida no gastada (UTXO, Unspent Transaction Output) de una transacción anterior. Para identificar de dónde provienen los fondos, se usa el hash de la transacción previa que contenía la salida que ahora queremos gastar.

Este hash es un identificador único de 256 bits (64 caracteres en hexadecimal).
Se obtiene aplicando SHA-256 dos veces a los datos de la transacción anterior.
2.2. Índice de salida (vout)
Dado que una transacción puede tener múltiples salidas, necesitamos especificar cuál de esas salidas estamos gastando.

vout es un número entero que indica el índice de la salida en la transacción anterior (comienza desde 0).
Ejemplo:
Si la transacción anterior tiene dos salidas y queremos gastar la segunda, vout será 1.

2.3. Script de firma
También llamado scriptSig, es un script que prueba que el usuario tiene permiso para gastar los bitcoins de la UTXO referenciada.

Contiene la firma digital generada con la clave privada del propietario de los bitcoins.
También incluye la clave pública del firmante.
Se ejecuta junto con el script de bloqueo (scriptPubKey) de la transacción anterior para validar la autenticidad del gasto.
3. Salidas (Outputs)
Cada salida define a dónde van los bitcoins en esta transacción.

3.1. Cantidad de satoshis enviados
Especifica la cantidad de bitcoins que se enviarán en esta salida, expresados en satoshis (1 BTC = 100,000,000 satoshis).

Ejemplo:
Si queremos enviar 0.01 BTC, la cantidad en satoshis será 1,000,000.

3.2. Script de bloqueo (scriptPubKey)
Es un script que define las condiciones para gastar esta salida en el futuro.

Generalmente, es un Pay-to-PubKey-Hash (P2PKH), que especifica que solo la persona que tenga la clave privada correspondiente a la clave pública hash puede gastar esos bitcoins.
También puede ser un Pay-to-Script-Hash (P2SH), Pay-to-Witness-PubKey-Hash (P2WPKH) u otros formatos de pago.
Ejemplo de scriptPubKey para una dirección P2PKH:


OP_DUP OP_HASH160 <PublicKeyHash> OP_EQUALVERIFY OP_CHECKSIG
4. Locktime (para definir si se puede gastar en el futuro)
Locktime es un campo opcional que define a partir de cuándo la transacción puede ser confirmada.

Si locktime es 0, la transacción se procesa inmediatamente.
Si es un número mayor que 500,000,000, representa una fecha en formato timestamp UNIX (segundos desde 1970).
Si es menor, representa el número de bloque a partir del cual la transacción será válida.
Ejemplo:

locktime = 800000 → Solo se confirmará después del bloque 800,000.
locktime = 1700000000 → Solo se confirmará después del 14 de noviembre de 2023 (según la fecha UNIX).
Resumen final
La transacción en Bitcoin tiene una versión para definir su formato.
Cada entrada (input) hace referencia a una UTXO anterior mediante su hash y un índice de salida (vout).
Para validar el gasto, la transacción incluye un script de firma (scriptSig).
Cada salida (output) especifica cuántos satoshis se envían y a quién, mediante un script de bloqueo (scriptPubKey).
Locktime puede definir un tiempo de espera antes de que la transacción sea válida.

**********************************************************************************

• Locktime (para definir si se puede gastar en el futuro).
Deberas de tener en cuenta que los datos aportados en formato hash, deberan ser chequeados para que cumplan las normas, es decir deben de ser exadecimales de 0 a 9, y letras de A a la F, sin espacios etc, si no eres cuidado en esto, el programa siempre dara errores.
Una vez que tengas la transacción en formato raw (hexadecimal), deberás Calcular el txid
1. Hash SHA-256 sobre los datos en formato hexadecimal.
2. Aplicar SHA-256 de nuevo al resultado del primer hash (doble SHA-256).
3. Invertir el orden de los bytes (little-endian).
Deberá verse por consola la transacion en formato Hexadecimal.
También deberá verse por consola el TXID.
Según la foto adjunta del programa.

*****************************************************************
No os explico aquí el programa, porque he intentado explicaros en el propio código
cada paso.
------------------------------------------------------------------------------------
Programa realizado en linux Ubuntu.
Con el editor sublime text.
Ejecución bajo consola linux:
python3 Aula_28_Transacion_Bit_Coin_Marzo_25.py
------------------------------------------------------------------------------------------

En las clases sucesivas, explicaremos dudas, que supongo serán muchas.
Imágen de perfil

Mojo Perl


Perl

Publicado el 3 de Marzo del 2025 por Augusto (9 códigos)
339 visualizaciones desde el 3 de Marzo del 2025
use DBI;
use Try::Tiny;
use URI;
use Mojolicious::Lite;

get '/index' => sub{
my $self = shift;

$self->render(text=> 'hola mundo');
};
Imágen de perfil

Árbol hash de Merkle.


Python

Publicado el 1 de Marzo del 2025 por Hilario (143 códigos)
458 visualizaciones desde el 1 de Marzo del 2025
Captura-de-pantalla-de-2025-03-01-12-25-07
Figure_1
----------------------------------------------------------------------------------


python3 Aula_28_Arbol_Merkle_Marz_25.py
---------------------------------------


Problema, para el Aula 28, a estudiar por partes en la primera semana de Marzo/25.
***********************************************************************************************
Vamos a plantear hoy un clásico problema, muy habitual en la criptomoneda Bitcoin, donde se aplica el arbol de Merkle, para optener el hash final de las transaciones pertenecientes a un bloke, este dato es uno de los fundamentales con el fin de poder proceder a su minado.
Plantearemos el problema resumido de la siguiente forma:
Queremos desarrollar un arbol de Merkle, en python, en sistema operativo Ubuntu. Necesitamos que las entradas del árbol sean de 8 opciones por consola.Las entradas deben admitir datos alfanumericos. Deberemos optener el hash final del resultado del arbol, de los datos introducidos. El lenguaje que vamos a aplicar es python3, bajo un istema operativo linux ubuntu, trabajando en consola.
**************************************************
Inicialmente vamos a definir, para entenderlo, que es un árbol de Merkle.
------------------------------------------------------------------------
Bien. Decimos que un árbol de Merkle es una estructura de datos en forma de árbol binario que se usa para verificar la integridad y autenticidad de los datos de manera eficiente.
Se utiliza en criptografía, sistemas de archivos distribuidos, y , como hemos indicado antes, en los blockchain para asegurar que la información no ha sido alterada.
El aula, deberá profundizar un poco más en esta definición, con el fin de comprender su significado.

***************************************************************************************************
Este programa fue desarrollado con Python V3.
Editado con Sublime Text.
Bajo una plataforma Linux,
Ubuntu 20.04.6 LTS.
Ejecución bajo este comado en consola:
python3 Aula_28_Arbol_Merkle_Marz_25.py
**********************************************

EXPLICACION DE LOS PASOS DEL EJERCICIO PHYTHON.
------------------------------------------------------------------------------

1️⃣ Importación de Módulos de módulos
--------------------------------------
necesario para el desarrollo de python.

import hashlib
import networkx as nx
import matplotlib.pyplot as plt

hashlib: Se usa para calcular los hashes SHA-256 de los datos.
networkx: Permite crear y visualizar grafos (en este caso, el árbol de Merkle).
matplotlib.pyplot: Se usa para graficar el árbol de Merkle.

2️⃣ Función para Calcular el Hash de un Dato
---------------------------------------------

def hash_data(data):
return hashlib.sha256(data.encode()).hexdigest()
Recibe un data (cadena de texto).
Usa SHA-256 para calcular su hash hexadecimal y lo devuelve.

3️⃣ Construcción del Árbol de Merkle
------------------------------------

def merkle_tree_hash(data_list):
if len(data_list) % 2 != 0:
data_list.append(data_list[-1]) # Duplicar el último si es impar
Si la cantidad de datos es impar, se duplica el último dato para asegurar que haya pares.

hashes = [hash_data(data) for data in data_list]
tree_levels = [hashes]
Se generan los hashes SHA-256 de cada dato y se almacenan en la primera capa del árbol.

while len(hashes) > 1:
temp_hashes = []
for i in range(0, len(hashes), 2):
combined_hash = hash_data(hashes[i] + hashes[i + 1])
temp_hashes.append(combined_hash)
hashes = temp_hashes
tree_levels.append(hashes)

Se combinan de dos en dos, se concatenan y se vuelven a hashear hasta llegar a un único hash raíz.
Ejemplo de construcción:


Entradas: A, B, C, D, E, F, G, H
Nivel 0: hash(A), hash(B), hash(C), hash(D), hash(E), hash(F), hash(G), hash(H)
Nivel 1: hash(hash(A)+hash(B)), hash(hash(C)+hash(D)), hash(hash(E)+hash(F)), hash(hash(G)+hash(H))
Nivel 2: hash(hash_AB + hash_CD), hash(hash_EF + hash_GH)
Nivel 3 (Raíz): hash(hash_ABCD + hash_EFGH)

4️⃣ Dibujar el Árbol de Merkle
--------------------------------

def plot_merkle_tree(tree_levels):
G = nx.DiGraph()
pos = {}
level_offset = 2.5
node_id = 0
Se crea un grafo dirigido G para representar el árbol.
pos almacena las posiciones de los nodos.
level_offset controla la separación vertical de los niveles.

for level, nodes in enumerate(tree_levels):
y_pos = -level * level_offset
x_step = 2 ** (len(tree_levels) - level - 1)
for i, node in enumerate(nodes):
label = node if level == len(tree_levels) - 1 else node[:6] + "..."
pos[node_id] = (i * x_step, y_pos)
G.add_node(node_id, label=label)
node_id += 1
Se añaden nodos con etiquetas:
Se muestran solo los primeros 6 caracteres seguidos de ..., excepto en el hash final.

node_id = 0
for level in range(len(tree_levels) - 1):
for i in range(0, len(tree_levels[level]), 2):
parent_id = node_id + len(tree_levels[level])
G.add_edge(node_id, parent_id)
G.add_edge(node_id + 1, parent_id)
node_id += 2
Se añaden las conexiones entre nodos padre e hijos.

labels = nx.get_node_attributes(G, 'label')
plt.figure(figsize=(15, 10))
nx.draw(G, pos, with_labels=True, labels=labels, node_size=5000, node_color='lightblue', font_size=8, font_weight='bold', edge_color='gray')
plt.title("Árbol de Merkle", fontsize=14)
plt.show()
Se genera la gráfica con matplotlib, usando networkx para dibujar el árbol.

5️⃣ Función Principal
----------------------

def main():
print("Introduce 8 valores alfanuméricos:")
data_list = [input(f"Dato {i+1}: ") for i in range(8)]
Se piden 8 entradas de datos por consola.

tree_levels = merkle_tree_hash(data_list)
root_hash = tree_levels[-1][0]
print("\nHash final del árbol de Merkle:", root_hash)
Se construye el árbol de Merkle.
Se imprime el hash raíz (Merkle Root).

plot_merkle_tree(tree_levels)
Se dibuja la gráfica del árbol.

6️⃣ Ejecución del Programa
----------------------------

if __name__ == "__main__":
main()
Se ejecuta main() solo si el script se ejecuta directamente.
Imágen de perfil

Cálculo de la/s constante/s de Kaprekar


Basic

Publicado el 28 de Febrero del 2025 por Ángel (5 códigos)
543 visualizaciones desde el 28 de Febrero del 2025
Permite calcular la/s constante/s de Kaprekar.
Escoge un número entero positivo. Ordena sus dígitos en orden ascendente y lo resta a la ordenación descendente de los mismos.
Repite el proceso hasta que obtenga una constante o se meta en un bucle.(Para salir pulse ESC)
Imágen de perfil

Generador de ternas pitagóricas


Basic

Publicado el 27 de Febrero del 2025 por Ángel (5 códigos)
352 visualizaciones desde el 27 de Febrero del 2025
A partir de dos números enteros positivos genera una terna pitagórica.
Genera un gráfico del triángulo rectángulo situando los valores de la terna pitagórica.
Imágen de perfil

Stock Monitor


Python

Actualizado el 28 de Enero del 2025 por Antonio (77 códigos) (Publicado el 22 de Octubre del 2023)
1.898 visualizaciones desde el 22 de Octubre del 2023
El siguiente script muestra en tiempo real las cotizaciones en bolsa, de acciones e índices bursátiles.
El programa utiliza un bucle en el que va realizando sucesivas peticiones de datos, usando 'yfinance'. Entre una petición y la siguiente, media un tiempo en segundos que viene determinado por la opción '-delay/--time_delay', teniendo un valor por defecto de 5 segundos y no pudiendo ser inferior a 0.5
Para detener la obtención de datos, pulsar la barra espaciadora. Al hacerlo, el programa mostrará el texto 'wait until application ends..' ya que tendrá que esperar el tiempo que quede restante del especificado por '-delay/--time_delay'. Finalizando definitivamente, transcurrido dicho tiempo restante.

ARGUMENTOS:
'-tick/--ticker' : Ticker o símbolo del valor cuya cotización se quiere obtener.
'-delay/--time_delay': Periodicidad, en segundos, entre una petición de datos y la siguiente.
'-clr/--color': Mostrar precio de cierre en color, en función de su fluctuación respecto del valor anterior.
'-uind/--use_index': Incluir esta opción para obtener cotizaciones de índices bursátiles (ej: ^IXIC, ^DJI..)

La petición de valores se interrumpe pulsando la barra espaciadora.
PARA CUALQUIER DUDA U OBSERVACIÓN, UTILICEN LA SECCIÓN DE COMENTARIOS.

sm1
sm2
sm3
Imágen de perfil

Ordenamiento Quick Sort


Basic

Publicado el 20 de Enero del 2025 por Ángel (5 códigos)
791 visualizaciones desde el 20 de Enero del 2025
Programa para ordenar un vector con el método Quick Sort, un método muy eficiente que permite reducir el tiempo de procesamiento en un 90%, muy útil para ordenar cantidades elevadas de elementos.
Imágen de perfil

Números primos


Basic

estrellaestrellaestrellaestrellaestrella(1)
Publicado el 19 de Enero del 2025 por Ángel (5 códigos)
744 visualizaciones desde el 19 de Enero del 2025
El programa pide un número entero y comprueba si es primo o no lo es.
Imágen de perfil

Cx_Contabilidad Financiera


Visual Basic

estrellaestrellaestrellaestrellaestrella(18)
Actualizado el 14 de Enero del 2025 por Rafael (24 códigos) (Publicado el 21 de Diciembre del 2022)
40.975 visualizaciones desde el 21 de Diciembre del 2022
Cx es un programa para Windows.
Sirve para gestionar la contabilidad.
Produce: libro diario, auxiliar,
balanzas, recapitulación, estados financieros,
balance general, estado de pérdidas y ganancias,
estado de resultados y estados de cuentas.
Servosistema que administra
la oficina sin papeles.
Multiusuario cliente/servidor, red inalámbrica.
Código abierto. Trabajo a distancia.
Adjunto Cx Guía del rey de la creación

Sin-titulo
Imágen de perfil

Contador Dinámico con JS solamente


JavaScript

Publicado el 20 de Diciembre del 2024 por Alejandro
430 visualizaciones desde el 20 de Diciembre del 2024
Este código sirve para crear una cuenta regresiva que muestra el tiempo restante hasta una fecha y hora específicas, como el lanzamiento de un producto, un evento o una página web. Se actualiza en tiempo real y muestra los días, horas, minutos y segundos restantes de forma dinámica.

Es ideal para incluir en páginas web o proyectos donde quieras mantener a tus usuarios informados sobre el tiempo restante para un hito importante. Cuando el temporizador llega a cero, se puede mostrar un mensaje personalizado, como "¡Ya estamos en directo!" o cualquier texto que elijas. Ni necesitas más pildoras de Javascript, soy Alejandro Tamargo Desarrollador Web en Asturias
Imágen de perfil

Base de datos sqlite.


Python

Publicado el 16 de Diciembre del 2024 por Hilario (143 códigos)
1.127 visualizaciones desde el 16 de Diciembre del 2024
Captura-de-pantalla-de-2024-12-15-21-08-21
Captura-de-pantalla-de-2024-12-15-21-10-06

************************************************////*******************************************



Aula_28_Diciembre_15_sql.py
**********************************


Programa realizado bajo paltaforma Linux, concretamente con Ubuntu 20.04.6 LTS.
Editado con Sublime text

#Ejecución.
#Bajo consola linux.
python3 Aula_28_Diciembre_15_sql.py
Alumnos, para entender mejor este ejercicio, inicialmente vamos a instalar el programa para Linux: DB Browser for SQLite
------------------------------------------//--------------------------------
Utilizaremos este comando por consola de linux, en mi caso utilizo Ubuntu.
sudo apt install sqlitebrowser

***************************************************************************************************
Vamos a realizar un ejercicio en Python, con el fin de relacionar un programa orientado a base de datos, para ir cargandolos secuencialmente en nuestra base datos y poder ver bajo genome, con el programa DB Browser for SQLite, los resultados.
Creo que es lo más sencillo que podemos hacer, queridos alumnos, para aprender sobre este importante tema, las bases SQL.


Bien, vamos a ver un poco este ejercicio.

Explicación General del Ejercicio: Aula_28_Diciembre_15_sql.py
Clase del 18 de Diciembre - Aula 28 (Mañana)

Este ejercicio tiene como objetivo enseñar a los alumnos cómo crear, gestionar y manipular una base de datos utilizando SQLite en Python. Se presenta una agenda de contactos como ejemplo práctico, con funcionalidades para agregar, buscar, eliminar y listar contactos. El archivo generado se llama Aula_28_Agenda.db y será almacenado localmente.

Conceptos Clave:
SQLite:
Es un sistema de gestión de bases de datos ligero y sin servidor. No requiere configuración previa, lo que lo hace ideal para proyectos pequeños o educativos.

Base de datos:
Un lugar donde almacenamos datos organizados en tablas. En este caso, tenemos una tabla llamada contactos que almacena:

id: Identificador único (autoincremental).
nombre: Nombre del contacto.
telefono: Número de teléfono.
ciudad: Ciudad del contacto.

Python y SQL:
Python se conecta con SQLite usando la biblioteca sqlite3. Los comandos SQL (CREATE, INSERT, SELECT, DELETE) nos permiten manipular los datos.

Estructura del Programa:

1. Inicialización de la Base de Datos:

La función inicializar_db() crea el archivo Aula_28_Agenda.db si no existe.
Dentro de este archivo, se define la tabla contactos con sus columnas (id, nombre, telefono, ciudad).
Se utiliza SQL para asegurar que la tabla se cree solo si no existe previamente.

Código relevante:

CREATE TABLE IF NOT EXISTS contactos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nombre TEXT NOT NULL,
telefono TEXT NOT NULL,
ciudad TEXT NOT NULL
)

2. Agregar Contactos

La función agregar_contacto(nombre, telefono, ciudad) permite al usuario añadir contactos a la base de datos.
Se utiliza una consulta SQL INSERT para insertar los datos proporcionados por el usuario.

INSERT INTO contactos (nombre, telefono, ciudad) VALUES (?, ?, ?)

3. Buscar Contactos

La función buscar_contacto(nombre) permite buscar contactos en la base de datos que coincidan parcialmente con un nombre.
Utiliza SELECT con una condición LIKE para encontrar coincidencias.
SELECT nombre, telefono, ciudad FROM contactos WHERE nombre LIKE ?

4. Eliminar Contactos

La función eliminar_contacto(nombre) elimina todos los contactos cuyo nombre coincida con el criterio de búsqueda.
Utiliza DELETE para borrar los registros encontrados.

DELETE FROM contactos WHERE nombre LIKE ?

5. Mostrar Todos los Contactos

La función mostrar_agenda() lista todos los contactos almacenados en la base de datos.
Utiliza SELECT para recuperar toda la información de la tabla contactos.


SELECT nombre, telefono, ciudad FROM contactos
Interacción con el Usuario
El programa incluye un menú interactivo que guía al usuario por las diferentes funcionalidades de la agenda.
Este menú permite:

Opción 1: Agregar un contacto.
Opción 2: Buscar un contacto.
Opción 3: Eliminar un contacto.
Opción 4: Mostrar todos los contactos.
Opción 5: Salir del programa.

El menú se ejecuta dentro de un bucle while hasta que el usuario elige salir.

Ejemplo Práctico
Al ejecutar el programa, se crea el archivo Aula_28_Agenda.db.
Desde el menú:
Seleccionas 1. Agregar contacto, introduces Juan, 123456789 y Madrid.
Seleccionas 2. Buscar contacto, introduces Juan y ves los detalles de ese contacto.
Seleccionas 3. Eliminar contacto, introduces Juan y confirmas que se ha eliminado.
Seleccionas 4. Mostrar todos los contactos, y verificas que no hay contactos.

Objetivos de Aprendizaje
Comprender cómo funcionan las bases de datos relacionales.
Conectar y manipular bases de datos SQLite desde Python.
Implementar operaciones básicas de bases de datos:
Crear tablas (CREATE).
Insertar datos (INSERT).
Leer datos (SELECT).
Eliminar datos (DELETE).

Desarrollar un programa estructurado y modular.
-----------------------------------------------------------------------------------------------------
Conclusión
Este ejercicio combina teoría y práctica para ayudar a los alumnos del Aula 28 a entender el manejo de bases de datos desde Python. Los conceptos aprendidos pueden ser aplicados en proyectos más complejos en el futuro.
sin imagen de perfil

bloqueos


Visual Basic

estrellaestrellaestrellaestrellaestrella(1)
Publicado el 13 de Diciembre del 2024 por Elizabeth
353 visualizaciones desde el 13 de Diciembre del 2024
Public Class Form4
Dim T, Ru, A0, B0, a, b, c, V, M, vem, vem2, R1, R2, R3, R4, R5, R6, R7, R8, Var As Double


Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Text = ""
TextBox2.Text = ""
Label5.Text = ""
ComboBox2.Text = "m3/kg"
ComboBox3.Text = "K"
ComboBox4.Text = "Kpa"

End Sub

Private Sub ComboBox4_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox4.SelectedIndexChanged
ComboBox4.DropDownStyle = ComboBoxStyle.DropDownList
If ComboBox4.Text = "Kpa" Then
Label5.Text = R7
Label5.Text = Math.Round(Convert.ToDouble(R7), 4)
ElseIf ComboBox4.Text = "Pascal" Then
Label5.Text = R7 * 1000
Label5.Text = Math.Round(Convert.ToDouble(R7 * 1000), 4)
ElseIf ComboBox4.Text = "Atmosfera" Then
Label5.Text = R7 / 101.3
Label5.Text = Math.Round(Convert.ToDouble(R7 / 101.3), 4)
ElseIf ComboBox4.Text = "Bar" Then
Label5.Text = R7 / 100
Label5.Text = Math.Round(Convert.ToDouble(R7 / 100), 4)
ElseIf ComboBox4.Text = "Psi" Then
Label5.Text = R7 / 6.895
Label5.Text = Math.Round(Convert.ToDouble(R7 / 6.895), 4)
End If
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox1.Text = ""
TextBox2.Text = ""
Label5.Text = ""
ComboBox2.Text = "m3/kg"
ComboBox3.Text = "K"
ComboBox4.Text = "Kpa"
Label5.Text = ""
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
If ComboBox1.Text = "Nitrógeno" Then
A0 = 136.2315
B0 = 0.05046
a = 0.02617
b = -0.00691
c = 42000
M = 28.013
Ru = 8.314

ElseIf ComboBox1.Text = "Hidrógeno" Then
A0 = 20.0117
B0 = 0.02096
a = -0.00506
b = -0.04359
c = 504
M = 2.015
Ru = 8.314

ElseIf ComboBox1.Text = "Argón" Then
A0 = 130.7802
B0 = 0.03931
a = 0.02328
b = 0.0
c = 59900
M = 39.984
Ru = 8.314
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If ComboBox2.Text = "m3/kg" Then
V = Val(TextBox1.Text)
ElseIf ComboBox2.Text = "cm3/g" Then
V = Val(TextBox1.Text) * 1000
ElseIf ComboBox2.Text = "ft3/lb" Then
V = Val(TextBox1.Text) * 16.01846337
ElseIf ComboBox2.Text = "in3/Oz" Then
V = Val(TextBox1.Text) * 1729.994044
End If
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Var = False
If ComboBox1.Text = "" Then
MessageBox.Show("Escoge el gas")
Var = True
ElseIf TextBox1.Text = "" Then
MessageBox.Show("Introduce el volumen")
Var = True

ElseIf TextBox1.Text <= 0 Then
Label5.Text = ""
MsgBox("Error, Proporciona un volumen mas alto")
Var = True
'Label5.Visible = False
ElseIf TextBox2.Text = "" Then
MessageBox.Show("Introduce la tempertura")
Var = True
ElseIf TextBox1.Text = "" Then
MessageBox.Show("Introduce el volumen")
Var = True
End If
If Var = False Then

If ComboBox3.Text = "K" Then
Label5.Text = ""
If TextBox2.Text < 60 Or TextBox2.Text > 300 Then
MessageBox.Show("error el rango de la T debe ser >60 y <300 K")
Var = True
Else
T = Val(TextBox2.Text)
End If
ElseIf ComboBox3.Text = "C" Then
If TextBox2.Text < -213.15 Or TextBox2.Text > 26.85 Then
MessageBox.Show("error el rango de la T debe ser >-213.15 y <26.85 C")
Var = True
Else
T = Val(TextBox2.Text) + 273.15
End If
ElseIf ComboBox3.Text = "F" Then
If TextBox2.Text < -351.67 Or TextBox2.Text > 80.33 Then
MessageBox.Show("error el rango de la T debe ser -351.67 y 80.33 F")
Var = True
Else
T = ((TextBox2.Text - 32) / 1.8) + 273.15
End If
End If
End If
If Var = False Then
vem = V * M
vem2 = vem ^ 2
R1 = A0 * (1 - (a / vem))
R2 = B0 * (1 - (b / vem))
R3 = (Ru * T) / (vem2)
R4 = 1 - (c / (vem * T ^ 3))
R5 = vem + R2
R6 = R1 / vem2
R7 = R3 * R4 * R5 - R6
If R7 < 0 Then
Var = True
MsgBox("Error, la presiòn resultante no debe ser negativa")
Else
Label5.Text = R7
Label5.Text = Math.Round(Convert.ToDouble(R7), 4)
End If
End If
ComboBox4.SelectedIndex = 0

End Sub


Private Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged

If ComboBox2.Text = "m3/kg" Then
V = Val(TextBox1.Text)
ElseIf ComboBox2.Text = "cm3/g" Then
V = Val(TextBox1.Text) * 1000
ElseIf ComboBox2.Text = "ft3/lb" Then
V = Val(TextBox1.Text) * 16.01846337
ElseIf ComboBox2.Text = "in3/Oz" Then
V = Val(TextBox1.Text) * 1729.994044
End If
End Sub
Private Sub ComboBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ComboBox1.KeyPress
e.Handled = True
End Sub
Private Sub ComboBox4_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ComboBox4.KeyPress
e.Handled = True
End Sub
Private Sub TextBox2_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox2.KeyPress
If Not Char.IsDigit(e.KeyChar) AndAlso Not Char.IsControl(e.KeyChar) AndAlso e.KeyChar <> "." AndAlso e.KeyChar <> "-" Then
e.Handled = True
End If
If e.KeyChar = "."c AndAlso TextBox2.Text.Contains(".") Then
e.Handled = True
End If
If e.KeyChar = "0"c AndAlso TextBox2.Text = "0" Then
e.Handled = True
End If
If e.KeyChar = "-"c AndAlso TextBox2.Text.Contains("-") Then
e.Handled = True
End If
End Sub

Private Sub TextBox3_KeyPress(sender As Object, e As KeyPressEventArgs)
If (Not Char.IsDigit(e.KeyChar) AndAlso e.KeyChar <> "." AndAlso e.KeyChar <> ControlChars.Back) Then
e.Handled = True
End If
End Sub
Private Sub TextBoxt1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
If (Not Char.IsDigit(e.KeyChar) AndAlso e.KeyChar <> "." AndAlso e.KeyChar <> ControlChars.Back) Then
e.Handled = True
End If
If e.KeyChar = "."c AndAlso TextBox1.Text.Contains(".") Then
e.Handled = True
End If
If e.KeyChar = "0"c AndAlso TextBox1.Text = "0" Then
e.Handled = True
End If
End Sub


Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click

End Sub

Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click

End Sub

Private Sub Label4_Click(sender As Object, e As EventArgs) Handles Label4.Click

End Sub

Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
If ComboBox3.Text = "K" Then
T = Val(TextBox2.Text)
ElseIf ComboBox3.Text = "C" Then
T = Val(TextBox2.Text) + 273.15
ElseIf ComboBox3.Text = "F" Then
T = Val(TextBox2.Text) - 32 * (5 / 9) + 273.15
ElseIf T > 60 Then
MessageBox.Show("ERROR NUMERO NO VALIDO")
ElseIf T < 300 Then
MessageBox.Show("ERROR NUMERO NO VALIDO")
End If
End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Close()
End Sub
End Class
Imágen de perfil

Problemas de Ajedrez.


C/Visual C

estrellaestrellaestrellaestrellaestrella(1)
Actualizado el 7 de Diciembre del 2024 por Adelino (27 códigos) (Publicado el 24 de Octubre del 2024)
1.752 visualizaciones desde el 24 de Octubre del 2024
Resuelve problemas de mate de ajedrez.
Funciona con el teclado.
3mate
Imágen de perfil

Elíptica_Criptografía


Python

Publicado el 27 de Noviembre del 2024 por Hilario (143 códigos)
486 visualizaciones desde el 27 de Noviembre del 2024
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Figure_1

---------------------------------------------------------------------------------------------------------------------------

Captura-de-pantalla-de-2024-11-27-12-07-57

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Aula_28_Nov_Eliptica_Criptografia.py
+++++++++++++++++++++++++++++




Dentro de todas las partes, digamos, técnologicas, que hemos ido estudiando y procesando. Comenzamos un tema nuevo,
para el que seguiremos utilizando el lengua Python, y un sistema operativo basado en linux.
Nos adentramos en el mundo de la criptografía y de las claves, en principio, en los sistemas más utilizados
por el secure shel SSH, en principio con un ejemplo sencillo, que intentaré explicar lo mejor posible.
Como siempre, en nuestras sucesivas clases de técnología iremos aclarando las dudas que surjan, lo que supondrá, como siempre
ocurre en nuestras clases, profundizar mucho más sobre el tema. Os pido, que dentro de lo posible, intenteis razonar el código.
Luego ya aclararemos todo lo que surja, pero es más fácil su comprensión si llevamos, digamos, trillado, un poco de lo que se trata.

EMPECEMOS:
++++++++++++++

-¿Qué es una curva elíptica?
Una curva elíptica es una curva matemática que tiene la forma general:
y2=x3+ax+b (Ya sabeis, y elevado a 2, igual a x elevado a 3, más a por x, más b)
Esta curva tiene propiedades interesantes que se aprovechan en criptografía para generar claves. En criptografía de curvas elípticas (ECC, por sus siglas en inglés), usamos puntos sobre esta curva para construir un sistema de claves.


¿Cómo se construyen las claves con una curva elíptica?
1. Selección de la curva elíptica:
◦ Primero, se elige una curva elíptica específica. La ecuación y2=x3+ax+b tiene parámetros como a, b, y un número primo p que define el campo finito (es decir, trabajamos con números que están "limitados" por un número p).
◦ Un ejemplo común de curva elíptica es la curva secp256k1, que se usa en Bitcoin.

2. Punto generador (G):
◦ Sobre la curva elíptica, hay un punto generador G que es un punto específico de la curva, que se conoce de antemano. Este punto sirve para generar las claves.

3. Clave privada:
◦ La clave privada es un número aleatorio que se elige de manera segura. Es como una "semilla" que vamos a usar para generar la clave pública.
◦ Este número privado es secreto, y nunca se debe compartir.

4. Clave pública:
◦ La clave pública se genera multiplicando el punto generador G por el número privado (clave privada). Esto se hace mediante una operación llamada multiplicación escalar.
◦ Matemáticamente, si tienes una clave privada k, la clave pública P es: P=k⋅G
◦ Aquí, P es un nuevo punto sobre la curva que depende de k y G. Es casi imposible calcular k solo a partir de P, lo que hace la curva elíptica segura para su uso en criptografía.

5. Uso en criptografía:
◦ En criptografía de clave pública, puedes usar la clave pública para verificar la autenticidad de un mensaje o para cifrar datos.
◦ Solo la persona que tiene la clave privada puede descifrar los datos o firmar mensajes, porque se necesita la clave privada para generar la firma o descifrar.

Ejemplo práctico en criptografía
Imagina que quieres enviar un mensaje seguro a alguien:
1. La otra persona te envía su clave pública.
2. Tú usas esa clave pública para cifrar el mensaje.
3. La otra persona usa su clave privada para descifrarlo.
Y cuando firmes un mensaje:
1. Usas tu clave privada para firmar el mensaje (de forma que solo tú puedas hacerlo).
2. Cualquier persona que tenga tu clave pública puede verificar que la firma es auténtica y que no ha sido modificada.

¿Por qué es segura?
La seguridad de este sistema se basa en que, aunque la multiplicación escalar de un número por un punto en la curva es fácil de hacer, el proceso inverso (saber la clave privada a partir de la clave pública) es extremadamente difícil. Este problema se llama el problema del logaritmo discreto, y es la base de la seguridad de las curvas elípticas.

En fin, alumnos, resumiendo:
1. Clave privada: Número secreto que eliges.
2. Clave pública: Punto en la curva generado a partir de la clave privada.
3. Suma de puntos: Usada para multiplicar el punto generador G para obtener la clave pública.
4. Seguridad: Es muy difícil calcular la clave privada a partir de la clave pública.


Este enfoque se usa en criptografía moderna para asegurar comunicaciones y transacciones, como en Bitcoin o en protocolos TLS/SSL para la navegación segura por Internet.
----------------------------------------------------------------------------------------------------------------------------------

Bien, después de esta pequeña introducción, que ampliaremos en clase, la próxima semana y sucesivas, vamos con algo más práctico:

1. Representación gráfica de la curva elíptica.
---------------------------------------------------------------
El programa comienza generando una gráfica de la curva elíptica definida por y2=x3+8x+12 sobre los números reales:
• Cálculo de y2:
La ecuación se evalúa para valores de x en un rango definido [−10,10] para obtener los valores de y2.
• Raíces cuadradas positivas y negativas:
La raíz cuadrada de y2 se toma tanto positiva como negativa (y=±y2​) para trazar ambas ramas de la curva.
• Visualización:
Usa matplotlib para graficar las ramas positiva y negativa en colores distintos. También incluye líneas de referencia para los ejes x e y, junto con una cuadrícula para mejorar la legibilidad.
Propósito:
Este gráfico permite entender visualmente la forma de una curva elíptica sobre los números reales antes de trabajar con el caso modular (campo finito).

2. Implementación de una curva elíptica modular (campo finito pequeño)
-------------------------------------------------------------------------------------------------------
En esta sección, se define una clase EllipticCurve para manejar operaciones básicas en una curva elíptica sobre un campo finito

Fp​:
• Parámetros de la curva:
La curva está definida por y2=x3+ax+bmodp, donde:
◦ a=8, b=12, y p=97 (un número primo que define el campo).
• Validación de singularidades:
Verifica que la curva no sea singular usando la condición 4a3+27b2=0modp.

• Operaciones básicas:
◦ Pertenencia a la curva: Verifica si un punto (x,y) está en la curva.
◦ Suma de puntos: Implementa la adición de puntos, considerando casos como:
▪ P+O=P (punto identidad).
▪ Suma de puntos distintos.
▪ Duplicación de un punto (derivada de la tangente).
◦ Multiplicación escalar: Repite la suma k⋅P usando el algoritmo de duplicación y adición.

• Generación de claves:
◦ Se generan todos los puntos válidos en la curva para el campo F97​.
◦ Selecciona un punto generador G (el primero de la lista).
◦ La clave privada es un entero aleatorio entre 1 y p−1.
◦ La clave pública es el resultado de k⋅G, donde k es la clave privada.

Resultados:
Imprime:
• La ecuación de la curva modular.
• El punto generador G.
• Las claves privada y pública generadas.

3. Criptografía realista con secp256k1
Esta sección introduce una curva elíptica de uso práctico en criptografía, secp256k1, utilizada por Bitcoin:
• Definición:
La curva está definida por y2=x3+7modp, donde:
◦ p es un número primo grande (2256−232−977).
◦ G es un punto generador predeterminado en la curva.
◦ n es el orden del punto generador.
• Operaciones similares:
Implementa las mismas operaciones (pertenencia, suma de puntos, multiplicación escalar) adaptadas a los parámetros de secp256k1.
• Generación de claves:
◦ La clave privada es un número aleatorio de hasta 256 bits (1≤k<n).
◦ La clave pública es k⋅G, donde G y n aseguran un espacio de claves inmenso y seguridad criptográfica.
Resultados:
Muestra:
• La ecuación de secp256k1.
• El punto generador G.
• Las claves privada y pública.


Como véis, queridos alumnos, el propósito formativo del programa es:
++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++
1. Introducción visual a las curvas elípticas:
La gráfica inicial ayuda a entender cómo luce una curva elíptica y su simetría sobre los números reales.
2. Conceptos básicos de curvas elípticas en campos finitos:
◦ Explica cómo las curvas se definen y operan en un espacio modular, con un ejemplo simple (p=97).
◦ Introduce operaciones críticas como suma de puntos y multiplicación escalar.
3. Aplicación práctica en criptografía:
◦ Usa una curva criptográfica estándar (secp256k1) para mostrar cómo generar claves privadas y públicas.
◦ Destaca las diferencias entre un ejemplo educativo y un caso práctico con parámetros reales.

Bien, y como posibles mejoras, vamos a implementar lo siguiente:
---------------------------------------------------------------
• Implementar firmas digitales (ECDSA) como extensión práctica.
• Mostrar cómo la clave pública se convierte en un formato útil (como direcciones en Bitcoin).
• Incluir explicaciones más detalladas sobre seguridad y resistencia frente a ataques.


Comoos lo expuesto, tengo por sentado que os resultará un tanto farragoso, deseo que, como ya dije, comencéis su estudio-
Iremos puliendo dudas, y asentando conceptos los próximos días.



///////////////////////////////////////////////////////////////////////////
Como casi todos los ejercicios, este fue realizado, bajo una plataforma Linux,
en concreto con Ubuntu 20.04.6 LTS.
Fue editado con Sublime Text.
Se utilizó, Python3.
Y como smpre indico, se deberán de tener cargadas en el sistema, todas las librerias
que el código pide importar para su ejecucucíon.

Comando de ejecucuón bajo consola linux:

python3 Aula_28_Nov_Eliptica_Criptografia.py
Imágen de perfil

COPIAR PESTAÑAS DE UN LIBRO DE EXCEL A OTRO


Excel

Publicado el 24 de Noviembre del 2024 por Demon Jr (6 códigos)
799 visualizaciones desde el 24 de Noviembre del 2024
EL EJEMPLO TRATA SOBRE COMO COPIAR CIERTAS PESTAÑAS DE UN LIBRO DE EXCEL EN UN NUEVO LIBRO (RECIEN CREADO)
PODRIA SER UTIL EN EL CASO QUE TENGAS UN ARCHIVO
DINAMOCO Y TENGAS QUE ESTAR GENERANDO REPORTES
ya metiéndole mas coco le puedes agregar instrucciones y guardarlo donde gustes.
es solo un ejemplo básico que espero le sea util a alguien
Imágen de perfil

3 en raya


C/Visual C

Actualizado el 30 de Octubre del 2024 por Adelino (27 códigos) (Publicado el 27 de Agosto del 2024)
5.589 visualizaciones desde el 27 de Agosto del 2024
Juego de Tres en raya en pantalla de texto.
Screenshot_20240828-012423_lDosBox
Imágen de perfil

Transformers


Python

Publicado el 23 de Octubre del 2024 por Hilario (143 códigos)
401 visualizaciones desde el 23 de Octubre del 2024
Captura-de-pantalla-de-2024-10-23-11-26-59

-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ejercicio:
<<<<<<<<<
Aula_28_Redaccion_IA.py

----------------------
Avanzando más en el tratamiento de textos, dentro de la Inteligencia Artificial. Proponemos ahora este ejercicio sencillo en el que vamos a utilizar un módulo ya entrenado en la elaboración de textos congruentes.
Como siempre trabajaremos bajo consola de Linux, con un sistema operativo Ubuntu 20.04.6 LTS. Utilizando como editor Sublime text.

Bien, queridos, alumnos. Para crear un programa que redacte textos amplios sobre un tema introducido por consola, puedemos usar modelos de lenguaje preentrenados, como los de la biblioteca transformers de Hugging.
Estos modelos son capaces de generar textos de manera coherente sobre prácticamente
cualquier tema. Es importante que el tema introducido por consola, sea descriptivo en el tema planteado, para que nuestro Módulo tenga más posibilidades de concretar la pequeña redacción resultante. En nuestro caso hemos planteado el tema de la siguiente forma:
"El mar es hermoso, pero esclavo para los pescadores que trabajan en ella"

Primero, asegúrate de tener instalada la biblioteca transformers y torch si aún no las tienes.
Puedes instalarlas ejecutando en la terminal:

pip install transformers torch

***************************************************************************************
Vamos a explicar de forma breve, en que consiste y como importamos el módulo entrenado.
----------------------------------------------------------------------------------------

Módulos Importados:

GPT2LMHeadModel:
Este es un modelo preentrenado basado en GPT-2, un tipo de modelo de lenguaje desarrollado por OpenAI que genera texto. La parte LMHead se refiere a la cabeza del modelo, que está diseñada específicamente para tareas de generación de lenguaje. El modelo puede generar nuevas secuencias de texto basadas en una entrada inicial.

GPT2Tokenizer:
Este es el tokenizador de GPT-2, encargado de convertir el texto que introduces (en formato de palabras) en un formato numérico que el modelo puede entender (tokens). Cuando quieres que el modelo genere texto o lo procese, el tokenizador traduce el texto a tokens, y después de que el modelo trabaja con ellos, el tokenizador traduce esos tokens de nuevo a texto legible.

Funcionamiento:
1. Tokenización -como recordareis ya hemos explicado este tema en un ejercicio anterior-:

El texto en lenguaje natural no puede ser entendido directamente por el modelo; necesita ser convertido a un formato que pueda procesar, llamado tokens (que son números que representan palabras o partes de palabras).
Ejemplo:
Si introduces la frase "Hola mundo", el tokenizador puede convertirla en algo como [15496, 1107], donde cada número representa una palabra o fragmento de una palabra.

2. Generación del texto:
El modelo GPT-2 toma esos tokens y predice cuál debería ser el siguiente token (o secuencia de tokens) basándose en lo que ya ha "visto". Se basa en patrones que ha aprendido de grandes cantidades de datos durante su entrenamiento.
Usando el mismo ejemplo, si das el input "Hola mundo", el modelo podría generar una continuación como "es un lugar hermoso" o cualquier secuencia plausible que siga.

3. Proceso completo:
Input: Tú introduces una frase (por ejemplo, "El cielo es azul").
Tokenización: El tokenizador convierte esta frase en tokens numéricos.
Modelo GPT-2: El modelo procesa esos tokens y genera nuevos tokens que representan la continuación del texto (basado en lo que ha aprendido).
Des-tokenización: El tokenizador traduce esos nuevos tokens de vuelta a palabras legibles, generando un texto nuevo como salida.

***************************************************************************
Explicación del código:

GPT2LMHeadModel.from_pretrained('gpt2'): Carga el modelo GPT-2 preentrenado.
tokenizador.encode(): Convierte el texto de entrada en tokens.
modelo.generate(): Genera la continuación del texto basado en los tokens de entrada.
tokenizador.decode(): Convierte los tokens generados nuevamente a texto para que puedas leer la salida.

Este enfoque permite que los modelos como GPT-2 generen texto natural en una gran variedad de tareas, como responder preguntas, redactar historias o completar oraciones. Todo esto se hace aprovechando la capacidad del modelo para aprender patrones del lenguaje y generar textos coherentes basados en un contexto previo.

**************************************************************************************
La ejecucion de este programa se realiza con el siguiente comando, bajo consola de Linux:
python3 Aula_28_Redaccion_IA.py
////////////////////////////////////////////////////////////////////////////////////////////
-------------------------------------------------------------------------------------------
Como veremos en clase, el próximo 29 de Octubre, existen muchas limitaciones en este proceso.
Revisaremos el ejercicio paso a paso, y comrobaremos cómo funciona.
He de decir que partimos de una forma básica, pero intentaremos poner las bases, para aumentar la complejidad y la efectividad con nuevos ejercicios.

Nuestras limitaciones son muchas, somos meros mortales en limitaciones tecnologicas, a continuacion
os hago un resumen de nuetras limitaciones, digamos, caseras:

Cuando ejecutas módulos como GPT2LMHeadModel y GPT2Tokenizer en un ordenador normal (casero), hay algunas limitaciones que debes tener en cuenta. Aquí te detallo las más importantes:

1. Recursos de hardware:
**********************

Memoria RAM: Los modelos como GPT-2 requieren bastante memoria. Incluso el modelo GPT-2 pequeño puede ocupar varios GB de RAM. Si tu ordenador tiene poca memoria (por ejemplo, menos de 8 GB de RAM), puede que se bloquee o funcione muy lentamente, especialmente con textos largos.
GPU (Unidad de Procesamiento Gráfico): Aunque los modelos se pueden ejecutar en CPU, los modelos como GPT-2 son mucho más rápidos si se ejecutan en una GPU. Los ordenadores caseros generalmente no tienen GPUs tan potentes como las de los servidores especializados o las tarjetas gráficas usadas para IA (como las NVIDIA de la serie RTX). Sin una GPU potente, la generación de texto puede ser extremadamente lenta.
CPU: Si no tienes una GPU, el modelo se ejecutará en la CPU, pero esto hará que el procesamiento sea mucho más lento. Procesar o generar textos largos podría tomar minutos en lugar de segundos.


2. Tamaño del modelo:
********************

Versiones grandes de GPT-2: GPT-2 tiene varios tamaños (pequeño, mediano, grande y extra grande). Los modelos más grandes requieren mucha más memoria y procesamiento, lo que los hace casi impracticables en un ordenador casero promedio. Por ejemplo, el modelo más grande (GPT-2 XL) ocupa más de 6 GB solo para cargar, y esto sin contar el procesamiento del texto.
Tiempo de carga: Incluso si tu ordenador puede manejar el tamaño del modelo, cargar el modelo en la memoria puede ser lento, y cada nueva inferencia (generación de texto) puede tomar bastante tiempo.

3. Almacenamiento:
*****************

Espacio en disco: Los modelos preentrenados de GPT-2 ocupan varios gigabytes de almacenamiento. Si tienes un disco duro pequeño o poco espacio disponible, descargar y guardar estos modelos puede ser problemático.
Actualizaciones de modelos: Los modelos mejorados o adicionales también ocupan más espacio y descargar varios de ellos podría llenar el almacenamiento disponible rápidamente.

4. Rendimiento limitado en generación de texto:
**********************************************

Latencia: En un ordenador casero, puede haber una latencia significativa entre la entrada de texto y la generación de salida. Generar texto en tiempo real o manejar peticiones rápidas no es tan fluido como en infraestructuras especializadas.
Longitud del texto: La longitud del texto que puedes procesar o generar también está limitada por los recursos de tu máquina. Textos muy largos podrían hacer que el modelo consuma más memoria de la disponible, lo que puede llevar a fallos o tiempos de procesamiento extremadamente largos.

5. Optimización limitada:
************************

Uso eficiente del hardware: Los modelos como GPT-2 están optimizados para funcionar mejor en infraestructuras de alto rendimiento, donde los recursos se pueden gestionar de manera más eficiente. En un ordenador casero, la falta de optimizaciones específicas para tu hardware (como las que se usan en servidores o clusters) hará que el rendimiento sea más bajo.

6. Entrenamiento o ajuste fino (fine-tuning):
********************************************

Imposibilidad de reentrenar: Entrenar o ajustar finamente un modelo como GPT-2 en un ordenador casero es prácticamente inviable debido a la cantidad de recursos que consume. Necesitarías GPUs especializadas y días o semanas de procesamiento para reentrenar el modelo, algo que no es posible en un equipo casero normal.
Acceso a grandes datasets: Para ajustar finamente el modelo, necesitarías un conjunto de datos extenso y adecuado, lo que no siempre es fácil de gestionar ni de almacenar en un ordenador personal.

7. Conexión a internet (si usas modelos en la nube):
***************************************************

Como recurso, os digo:
Aunque puedes ejecutar los modelos localmente, algunos prefieren usar versiones en la nube o APIs (como OpenAI GPT-3) para ahorrar recursos en el ordenador local. En estos casos, dependes de una conexión a internet rápida y estable para obtener resultados eficientes. Las conexiones lentas podrían hacer que el proceso sea menos fluido.

Como os comento, los de nuestra Aula, somos puramente terrenales.
Gracias, amigos, y a trabajar.

----------------------------------------------------------------------------------------------------------
Imágen de perfil

Tokenización.


Python

Publicado el 19 de Octubre del 2024 por Hilario (143 códigos)
308 visualizaciones desde el 19 de Octubre del 2024
Captura-de-pantalla-de-2024-10-19-13-08-55

*****************************************************************************************************************

Ejercicio:Aula_28_token_sep_24.py
*********************************

Vamos a avanzar en el Aula 28, e iniciar, el tratamiento de textos en la Inteligencia Artificial.

Empezaremos con algo muy básico, ¿Qué es la tokenización?.
--------------------------------------------------------

-¿Qué es la tokenización?
Dividir el texto: La tokenización consiste en dividir un texto en partes más pequeñas llamadas tokens. Estos tokens pueden ser palabras, frases o incluso caracteres, dependiendo de cómo quieras analizarlos.

Ejemplo: Si tienes la frase "El perro ladra", la tokenización a nivel de palabras dividiría el texto en los siguientes tokens:

"El"
"perro"
"ladra"

Importancia:
-----------
Facilita el análisis: Al descomponer el texto, es más fácil realizar análisis, como contar palabras, buscar patrones o entender el significado.
Prepara para modelos:
Muchos modelos de IA trabajan con números, no con texto. La tokenización es un primer paso para convertir texto en un formato que los modelos puedan entender.

Tipos de tokenización:
---------------------
Por palabra: Divide el texto en palabras.
Por frase: Divide el texto en oraciones o frases.
Por carácter: Divide el texto en caracteres individuales.


Como ya digimos, la tokenización es el proceso de separar el texto en unidades más pequeñas (tokens) para que puedan ser analizadas y procesadas por algoritmos de IA. Es un paso esencial para entender y trabajar con el lenguaje en aplicaciones de inteligencia artificial.

*****************************************************************************************
Como se almacenaría, por ejemplo, en una matriz del tipo Tensor.
---------------------------------------------------------------
Definición: Un tensor es una estructura de datos que puede ser vista como una generalización de matrices y vectores.

Un escalar es un tensor de orden 0 (por ejemplo, un solo número).
Un vector es un tensor de orden 1 (una lista de números).
Una matriz es un tensor de orden 2 (una tabla de números).
Un tensor de orden superior puede tener más de dos dimensiones.
Representación: En matemáticas, los tensores se utilizan para representar datos de múltiples dimensiones. Por ejemplo, una imagen puede ser representada como un tensor de 3 dimensiones (alto, ancho, canales de color).


¿Cómo se utilizan los tensores en IA y procesamiento de texto?
Representación de texto:

Después de la tokenización, los tokens (palabras o frases) deben convertirse en números para que los algoritmos de IA puedan procesarlos. Esto se hace a menudo usando técnicas de embeddings (representaciones vectoriales de palabras).
Cada token se convierte en un vector (tensor de orden 1). Por ejemplo, la palabra "perro" podría representarse como un vector de características [0.5, 0.1, 0.9, ...].
Tensores en redes neuronales:

Los tensores son fundamentales en el entrenamiento de redes neuronales, donde los datos se alimentan a través de capas de la red. Cada capa procesa los tensores de entrada y produce tensores de salida.
Por ejemplo, en un modelo de procesamiento del lenguaje natural (como Transformers), el texto tokenizado se convierte en tensores, que luego son procesados en múltiples capas para generar resultados (como predicciones de texto).
Operaciones con tensores:

Se realizan varias operaciones matemáticas sobre tensores, como la suma, la multiplicación y la transformación, para aprender patrones en los datos. Esto se hace utilizando bibliotecas de programación como TensorFlow o PyTorch, que son especialmente diseñadas para manejar tensores y operaciones sobre ellos.
Batching:

En el entrenamiento de modelos, es común agrupar múltiples ejemplos en un batch (lote). Esto se hace representando varios textos como un tensor de 2 dimensiones (batch_size, longitud del texto), donde batch_size es el número de ejemplos en el lote y longitud del texto es el número máximo de tokens por ejemplo.

Diriamos, como conclusion.
------------------------

Los tensores son estructuras de datos esenciales en IA y procesamiento de texto. Se utilizan para representar texto, imágenes y otros tipos de datos en múltiples dimensiones. En el contexto del procesamiento de texto, los tensores permiten a los modelos de IA realizar cálculos complejos y aprender patrones a partir de datos tokenizados. Su uso se ha vuelto fundamental en la mayoría de las aplicaciones modernas de inteligencia artificial y aprendizaje profundo.

***************************************************************************************
EXPLICACCION DE NUESTRO EJERCICIO.
****************************************************************************************
Vamos a desglosar el ejercicio proporcionado paso a paso para entender cómo funciona y qué hace cada parte del código.

1. Importación de bibliotecas
****************************

import nltk
from nltk.tokenize import word_tokenize
import nltk: Importa la biblioteca Natural Language Toolkit (NLTK), que es una biblioteca popular en Python para el procesamiento del lenguaje natural.
from nltk.tokenize import word_tokenize: Importa la función word_tokenize, que se utiliza para dividir un texto en palabras (tokens).

2. Definición de la función
**************************

def tokenizar_con_matriz(frase):
Aquí se define una función llamada tokenizar_con_matriz, que acepta una cadena de texto (frase) como argumento.

3. Docstring
***********

"""Tokeniza una frase y crea una matriz 2D con los tokens y sus índices.

Args:
frase: La frase a tokenizar.

Returns:
Una lista de listas donde cada sublista contiene el token y su índice.
"""
Este bloque de texto es un comentario (docstring) que describe lo que hace la función, los argumentos que recibe y lo que devuelve. Es útil para que otros programadores (o tú mismo en el futuro) entiendan el propósito de la función.

4. Tokenización
**************
tokens = word_tokenize(frase)
word_tokenize(frase): Esta función toma la frase y la divide en una lista de tokens (palabras y puntuaciones). Por ejemplo, si la entrada es "El mar, amplio y profundo", tokens podría ser ['El', 'mar', ',', 'amplio', 'y', 'profundo'].

5. Creación de la matriz de tokens
*********************************
matriz_tokens = [[token, str(indice)] for indice, token in enumerate(tokens, start=1)]
enumerate(tokens, start=1): Esta función permite iterar sobre tokens, proporcionando tanto el índice (número de posición) como el valor del token. La opción start=1 significa que los índices comenzarán desde 1 en lugar de 0.
Lista de listas: Se crea una lista llamada matriz_tokens, donde cada sublista contiene un token y su índice correspondiente. Por ejemplo, si tokens es ['El', 'mar', ',', 'amplio', 'y', 'profundo'], matriz_tokens sería:
css

[['El', '1'],
['mar', '2'],
[',', '3'],
['amplio', '4'],
['y', '5'],
['profundo', '6']]
6. Solicitar entrada al usuario
*******************************
# Solicitar al usuario que introduzca la frase
frase = input("Introduce una frase: ")
Aquí se le pide al usuario que introduzca una frase a través de la consola. Lo que escriba el usuario se almacenará en la variable frase.

7. Llamada a la función y almacenamiento del resultado
******************************************************
matriz = tokenizar_con_matriz(frase)
Se llama a la función tokenizar_con_matriz, pasando la frase que el usuario introdujo como argumento. El resultado (la matriz de tokens) se guarda en la variable matriz.

8. Impresión de la matriz
************************
# Imprimir la matriz completa
for fila in matriz:
print(fila)
Este bucle for recorre cada sublista (fila) en matriz y las imprime. Cada fila contendrá un token y su índice, mostrando el resultado de la tokenización de forma estructurada.
Ejemplo de uso
Si el usuario ingresa la frase:


El mar, amplio y profundo
La salida sería:

css

['El', '1']
['mar', '2']
[',', '3']
['amplio', '4']
['y', '5']
['profundo', '6']
Podemos decir, queridos alumnos, como esumen que:
-------------------------------------------------
Este programa tokeniza una frase ingresada por el usuario, crea una estructura de datos en forma de matriz que muestra cada token y su índice correspondiente, y luego imprime esa matriz. Este ejercicio que os propuse, es un ejemplo básico pero efectivo de cómo manipular texto en Python utilizando NLTK.

*************************************************************************************************
Este ejercicio fue ralizado bajo Linux, en sistema operativo Ubuntu,
Editado con sublime text.