sábado, 7 de marzo de 2026

IA Descubre 22 Fallos en Firefox Alerta de Seguridad

En una demostración impactante del poder de la inteligencia artificial en la ciberseguridad, la empresa Anthropic ha revelado el descubrimiento de 22 vulnerabilidades críticas en el navegador Mozilla Firefox. Lo más destacable es que este hallazgo no fue obra de un equipo de hackers humanos, sino del modelo de IA más avanzado de Anthropic, Claude Opus, que se utilizó para analizar el código fuente del navegador.

IA Descubre 22 Fallos en Firefox: ¡Alerta de Seguridad!

Este avance subraya la creciente capacidad de las IAs para identificar debilidades de seguridad que podrían pasar desapercibidas para los métodos tradicionale s. La detección de 22 fallos, muchos de los cuales podrían tener implicaciones significativas para la privacidad y seguridad de los usuarios, pone de manifiesto la necesidad de integrar herramientas de IA en los procesos de desarrollo y auditoría de software. Anthropic ha compartido sus hallazgos con Mozilla, quienes ya están trabajando en parches para corregir estas vulnerabilidades. Este incidente sirve como un recordatorio de la constante evolución de las amenazas de ciberseguridad y la importancia de la innovación tecnológica para contrarrestarlas.

La utilizacion de IA como Claude Opus no solo acelera el proceso de descubrimiento de fallos, sino que también permite una comprensión más profunda de las posibles rutas de ataque, abriendo nuevas vías para fortalecer la defensa digital. La colaboración entre empresas de IA y desarrolladores de software es clave para asegurar un ecosistema digital más seguro para todos.

Fuente Original: https://thehackernews.com/2026/03/anthropic-finds-22-firefox.html

Artículos relacionados de LaRebelión:

Artículo generado mediante LaRebelionBOT

AI Warfare Iran Conflict Fuels New AI Military Tech

The recent US strikes on Iran signal the dawn of a significant new era in warfare, driven by the large-scale integration of artificial intelligence. While AI tools are being deployed, military officials emphasize that these systems do not make autonomous targeting decisions or replace human oversight. Instead, their primary role is to enhance human capabilities by helping to identify crucial information and enabling personnel to make more informed and rapid decisions on the battlefield.

AI Warfare: Iran Conflict Fuels New AI Military Tech

The US military has been investing heavily in AI development for years, aiming to leverage its power for strategic advantage. This push involves using AI to sift through vast amounts of data, identify 'points of interest,' and organise information for greater clarity. This application is exemplified by systems like Palantir's Maven Smart System, which incorporates large language models such as Anthropic's Claude AI. Claude has reportedly become integral to US operations against Iran, accelerating the development of military AI capabilities.

However, this advancement is not without its critics. Human rights groups, like the coalition Stop Killer Robots, express concerns that AI-driven decision-support systems could dangerously blur the lines between recommending and executing military actions. Despite these concerns, the US military asserts that its use of AI assistance adheres strictly to US policy, military doctrine, and the law, ensuring a rigorous process before any action is taken. The conflict in Iran is therefore serving as a crucial, large-scale proving ground for these advanced AI military technologies.

Fuente Original: https://tech.slashdot.org/story/26/03/06/1629255/iran-war-provides-a-large-scale-test-for-ai-assisted-warfare?utm_source=rss1.0mainlinkanon&utm_medium=feed

Artículos relacionados de LaRebelión:

Artículo generado mediante LaRebelionBOT

10 Ejercicios Resueltos de Ensamblador (x86 y MIPS): Arquitectura de Computadores

Llegamos a la última frontera en larebelion.com. Si has sobrevivido a la programación en C, a la gestión de memoria y a los Sockets, es hora de hablar directamente con el procesador. Bienvenidos a Arquitectura de Computadores.

En las universidades españolas, normalmente se enseña Ensamblador usando MIPS (con simuladores como MARS o SPIM) o x86 (usando NASM en Linux). En este post, hemos recopilado 10 ejercicios de exámenes de ambos mundos para que domines los registros, los saltos condicionales y las llamadas al sistema (syscalls).


1. MIPS: Suma de dos enteros (UPM)

Enunciado: Escribe un programa en ensamblador MIPS que cargue dos números enteros en registros, los sume y guarde el resultado en un tercer registro.

.text
.globl main

main:
    li $t0, 15 # Cargar el valor inmediato 15 en $t0
    li $t1, 20 # Cargar el valor inmediato 20 en $t1
    add $t2, $t0, $t1 # $t2 = $t0 + $t1 (15 + 20 = 35)

    # Terminar el programa limpiamente
    li $v0, 10 # Syscall 10 = exit
    syscall

2. x86 (NASM): Imprimir "Hola Mundo" (UPC)

Enunciado: Crea el clásico "Hola Mundo" en ensamblador x86 de 32 bits para Linux, usando interrupciones de sistema (int 0x80).

section .data
    msg db 'Hola Mundo', 0xA ; Mensaje con salto de línea
    len equ $ - msg ; Longitud del mensaje

section .text
    global _start

_start:
    mov eax, 4 ; Syscall 4 = sys_write
    mov ebx, 1 ; File descriptor 1 = stdout
    mov ecx, msg ; Puntero a la cadena
    mov edx, len ; Tamaño de la cadena
    int 0x80 ; Llamada al kernel de Linux

    mov eax, 1 ; Syscall 1 = sys_exit
    int 0x80

3. MIPS: Condicional IF-ELSE (UCM)

Enunciado: Dado un valor en $t0, si es mayor o igual a 5, almacena un 1 en $t1 (aprobado), si no, almacena un 0 (suspenso).

.text
main:
    li $t0, 4 # Nota del alumno
    bge $t0, 5, aprobado # Branch if Greater or Equal to 5

suspenso:
    li $t1, 0 # Cargar 0 (suspenso)
    j fin # Salto incondicional a 'fin'

aprobado:
    li $t1, 1 # Cargar 1 (aprobado)

fin:
    li $v0, 10
    syscall

4. x86 (NASM): Bucle FOR simple (UGR)

Enunciado: Escribe un bucle en ensamblador x86 que simule un for(int i=5; i>0; i--) utilizando la instrucción loop y el registro ecx.

section .text
    global _start

_start:
    mov ecx, 5 ; ecx es el contador del bucle
    mov eax, 0 ; eax será el acumulador

mi_bucle:
    add eax, 1 ; Operación interna del bucle
    loop mi_bucle ; Decrementa ecx y salta si ecx != 0

    mov eax, 1
    int 0x80

5. MIPS: Recorrer un Array (US)

Enunciado: Tienes un array de 3 enteros en memoria. Escribe el código MIPS para sumar todos sus elementos y guardar el total en $t2.

.data
array: .word 10, 20, 30

.text
main:
    la $t0, array # Cargar dirección base del array
    li $t2, 0 # Inicializar suma total a 0

    lw $t1, 0($t0) # Leer primer elemento
    add $t2, $t2, $t1

    lw $t1, 4($t0) # Leer segundo elemento (+4 bytes)
    add $t2, $t2, $t1

    lw $t1, 8($t0) # Leer tercer elemento (+8 bytes)
    add $t2, $t2, $t1

    li $v0, 10
    syscall

6. x86 (NASM): Operaciones a nivel de Bits (UV)

Enunciado: Usa máscaras y operaciones bit a bit (AND, OR, XOR) para poner a cero el registro eax, encender su bit menos significativo y luego invertirlo.

section .text
    global _start

_start:
    xor eax, eax ; Forma eficiente de poner eax a 0
    or eax, 1 ; Enciende el bit menos significativo (eax = 1)
    not eax ; Invierte todos los bits (Complemento a 1)

    mov eax, 1
    int 0x80

7. MIPS: Leer entero por teclado (UC3M)

Enunciado: Escribe un programa que pida al usuario por teclado su edad y la guarde en un registro utilizando las Syscalls de SPIM/MARS.

.text
main:
    # Syscall 5 = Read Integer
    li $v0, 5
    syscall

    # El entero leído queda guardado en $v0
    move $t0, $v0 # Lo movemos a $t0 para protegerlo

    li $v0, 10
    syscall

8. x86 (NASM): Longitud de una Cadena (UAM)

Enunciado: Implementa el equivalente a strlen() de C en ensamblador x86, iterando hasta encontrar el byte nulo (0x00).

section .data
    cadena db "Ingenieria", 0

section .text
    global _start

_start:
    mov esi, cadena ; Puntero al inicio de la cadena
    xor ecx, ecx ; ecx = 0 (Contador)

contar:
    cmp byte [esi], 0 ; ¿Es el fin de cadena (\0)?
    je fin_conteo ; Si es cero, salta a fin
    inc esi ; Avanza al siguiente carácter
    inc ecx ; Incrementa el contador
    jmp contar

fin_conteo:
    ; En ecx queda almacenada la longitud (10)
    mov eax, 1
    int 0x80

9. MIPS: Pila (Stack) y Funciones (UMA)

Enunciado: Muestra cómo guardar el registro de retorno $ra en la pila antes de hacer una llamada a una subrutina anidada, y cómo restaurarlo después.

.text
mi_funcion:
    # Prólogo: Reservar espacio en la pila y guardar $ra
    addi $sp, $sp, -4
    sw $ra, 0($sp)

    # [Cuerpo de la función aquí]

    # Epílogo: Restaurar $ra y liberar pila
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra # Jump Register (Retorno)

10. x86 (NASM): Multiplicación (UNED)

Enunciado: Multiplica el valor 10 por 5 usando la instrucción mul y guarda el resultado en una variable de memoria.

section .bss
    resultado resb 4 ; Reserva 4 bytes para el resultado

section .text
    global _start

_start:
    mov eax, 10 ; eax siempre es uno de los operandos en mul
    mov ebx, 5
    mul ebx ; Multiplica eax por ebx. Resultado en edx:eax

    mov [resultado], eax ; Guarda los 32 bits bajos en la variable

    mov eax, 1
    int 0x80

10 Ejercicios Resueltos de Redes: Sockets TCP y UDP en Python y C (Nivel Universidad)

Cualquier aplicación moderna necesita conectarse a Internet. En la asignatura de Redes de Computadores, la teoría del Modelo OSI está muy bien, pero donde de verdad se aprende es programando Sockets.

En larebelion.com hemos preparado 10 ejercicios de exámenes de universidades españolas. Nos centraremos principalmente en la API de Sockets de Python por su claridad, pero incluiremos la base en C para los más puristas. Prepara tus puertos locales, ¡que empezamos a escuchar conexiones!


1. Servidor TCP Básico (UPM)

Enunciado: Crea un servidor TCP en Python que escuche en el puerto 8080. Cuando un cliente se conecte, debe enviarle el mensaje "Bienvenido al servidor" y cerrar la conexión.

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8080))
server.listen(5)
print("Servidor TCP escuchando en puerto 8080...")

while True:
    client_socket, addr = server.accept()
    print(f"Conexión establecida desde {addr}")
    client_socket.send(b"Bienvenido al servidor\n")
    client_socket.close()

2. Cliente TCP Básico (UPC)

Enunciado: Escribe el código del cliente en Python que se conecte al servidor TCP del ejercicio anterior (en localhost), reciba el mensaje, lo imprima por pantalla y se desconecte.

import socket

cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cliente.connect(('127.0.0.1', 8080))

# Recibimos hasta 1024 bytes
respuesta = cliente.recv(1024)
print("Mensaje del servidor:", respuesta.decode('utf-8'))
cliente.close()

3. Servidor UDP de Eco (UV)

Enunciado: A diferencia de TCP, UDP no está orientado a conexión. Crea un servidor UDP en el puerto 9000 que reciba un mensaje y se lo devuelva al remitente exactamente igual (Echo Server).

import socket

# SOCK_DGRAM indica que usaremos UDP
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('0.0.0.0', 9000))
print("Servidor UDP Eco iniciado...")

while True:
    datos, direccion = server.recvfrom(1024)
    print(f"Recibido de {direccion}: {datos.decode()}")
    server.sendto(datos, direccion)

4. Cliente UDP interactivo (UGR)

Enunciado: Crea un cliente UDP que pida al usuario que escriba un texto por consola, lo envíe al servidor del ejercicio 3 y muestre la respuesta.

import socket

cliente = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
direccion_servidor = ('127.0.0.1', 9000)

mensaje = input("Escribe un mensaje para enviar: ")
cliente.sendto(mensaje.encode(), direccion_servidor)

respuesta, addr = cliente.recvfrom(1024)
print("Eco del servidor:", respuesta.decode())
cliente.close()

5. Estructuras en C: Inicializar un Socket (UC3M)

Enunciado: En C, las cosas son más manuales. Escribe el fragmento de código necesario en C para crear un socket TCP y preparar la estructura sockaddr_in para el puerto 80.

#include <sys/socket.h>
#include <netinet/in.h>

int server_fd;
struct sockaddr_in address;

// 1. Crear file descriptor del socket
server_fd = socket(AF_INET, SOCK_STREAM, 0);

// 2. Configurar la estructura de red
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(80); // htons convierte al formato de red

6. Python: Servidor TCP Multihilo (US)

Enunciado: Un servidor básico se bloquea con cada cliente. Usa la librería threading para crear un servidor TCP que asigne un hilo nuevo a cada cliente que se conecte, permitiendo conexiones concurrentes.

import socket
import threading

def manejar_cliente(conn, addr):
    print(f"Nuevo hilo para {addr}")
    conn.send(b"Hola desde un hilo concurrente!\n")
    conn.close()

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8888))
server.listen(5)

while True:
    conn, addr = server.accept()
    hilo = threading.Thread(target=manejar_cliente, args=(conn, addr))
    hilo.start()

7. Resolución de DNS (UAM)

Enunciado: Usa los métodos de socket en Python para preguntar al usuario un nombre de dominio (ej: google.com) y devolver su dirección IP (resolución DNS directa).

import socket

def obtener_ip():
    dominio = input("Introduce un dominio (ej. larebelion.com): ")
    try:
        ip = socket.gethostbyname(dominio)
        print(f"La IP de {dominio} es {ip}")
    except socket.gaierror:
        print("No se pudo resolver el hostname.")

obtener_ip()

8. Concurrencia en C usando Fork (UNED)

Enunciado: En C de Linux, la concurrencia a menudo se logra creando procesos hijos. Escribe la lógica del bucle principal de un servidor concurrente usando fork().

// Asumimos que socket, bind y listen ya están hechos
while(1) {
    int client_socket = accept(server_fd, NULL, NULL);
    if (fork() == 0) {
        // --- ESTE ES EL PROCESO HIJO ---
        close(server_fd); // El hijo no necesita escuchar
        send(client_socket, "Hola\n", 5, 0);
        close(client_socket);
        exit(0); // Matamos al hijo tras atender
    } else {
        // --- ESTE ES EL PROCESO PADRE ---
        close(client_socket); // El padre delega en el hijo
    }
}

9. Escáner de Puertos Básico (UMA)

Enunciado: Crea un script en Python que intente conectarse (usando connect_ex) a los puertos del 20 al 25 de la IP 127.0.0.1 e imprima cuáles están abiertos.

import socket

ip = '127.0.0.1'
print(f"Escaneando puertos en {ip}...")

for puerto in range(20, 26):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(0.5)
    # connect_ex devuelve 0 si la conexión es exitosa
    resultado = sock.connect_ex((ip, puerto))
    if resultado == 0:
        print(f"Puerto {puerto}: ABIERTO")
    sock.close()

10. Petición HTTP GET Manual (USAL)

Enunciado: HTTP no es magia, es solo texto enviado por un socket TCP. Escribe un cliente TCP que se conecte a un servidor web en el puerto 80, envíe la cabecera GET / HTTP/1.1 y reciba el HTML.

import socket

host = 'example.com'
cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cliente.connect((host, 80))

# Petición HTTP cruda (los saltos de línea \r\n son obligatorios)
peticion = f"GET / HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n"
cliente.send(peticion.encode())

respuesta = cliente.recv(4096)
print(respuesta.decode())
cliente.close()

10 Ejercicios Resueltos de Bash Scripting en Linux: Guía para Universidad

Bienvenidos de nuevo a larebelion.com. Si estás cursando Sistemas Operativos o Administración de Sistemas, sabrás que la interfaz gráfica es para cobardes. Un verdadero Ingeniero Informático se mueve por la terminal de Linux como pez en el agua.

Para ayudarte a superar tus exámenes prácticos, hemos recopilado 10 ejercicios esenciales de Bash Scripting de distintas universidades españolas. Desde condicionales básicos hasta automatización de copias de seguridad. ¡Abre tu terminal y empecemos!




1. Comprobación de Archivos (UPM)

Enunciado: Crea un script que reciba el nombre de un archivo por parámetro y compruebe si existe y si tiene permisos de lectura.

#!/bin/bash
ARCHIVO=$1

if [ -r "$ARCHIVO" ]; then
    echo "El archivo existe y se puede leer."
else
    echo "El archivo no existe o no hay permisos."
fi

2. Bucle For: Renombrado Masivo (UPC)

Enunciado: Escribe un script que busque todos los archivos con extensión .txt en el directorio actual y les añada la extensión .bak al final.

#!/bin/bash
for archivo in *.txt; do
    if [ -e "$archivo" ]; then
        mv "$archivo" "$archivo.bak"
        echo "Renombrado: $archivo a $archivo.bak"
    fi
done

3. Bucle While: Leer un Fichero Línea a Línea (UGR)

Enunciado: Lee el contenido del archivo /etc/passwd e imprime solo los nombres de los usuarios (la primera palabra antes de los dos puntos).

#!/bin/bash
while IFS=: read -r usuario resto; do
    echo "Usuario encontrado: $usuario"
done < /etc/passwd

4. Operaciones Aritméticas Básicas (UCM)

Enunciado: Crea un script que pida al usuario dos números por teclado y muestre la suma, resta y multiplicación de ambos.

#!/bin/bash
read -p "Introduce el primer número: " num1
read -p "Introduce el segundo número: " num2

suma=$((num1 + num2))
resta=$((num1 - num2))
multi=$((num1 * num2))

echo "Suma: $suma | Resta: $resta | Multiplicación: $multi"

5. Estructura Case: Menú Interactivo (UV)

Enunciado: Implementa un menú sencillo usando case que permita elegir entre ver la fecha actual, ver el espacio en disco o salir del script.

#!/bin/bash
echo "1. Ver Fecha 2. Espacio Disco 3. Salir"
read -p "Elige una opción: " opcion

case $opcion in
    1)
        date ;;
    2)
        df -h ;;
    3)
        echo "Saliendo..."; exit 0 ;;
    *)
        echo "Opción no válida." ;;
esac

6. Funciones en Bash: Factorial (UC3M)

Enunciado: Crea una función recursiva o iterativa en Bash que calcule el factorial de un número pasado como argumento.

#!/bin/bash
factorial() {
    n=$1
    if [ $n -le 1 ]; then
        echo 1
    else
        prev=$(factorial $((n - 1)))
        echo $((n * prev))
    fi
}

echo "Factorial de 5 es: $(factorial 5)"

7. Uso de AWK: Filtrar Procesos (US)

Enunciado: Ejecuta el comando ps aux y usa awk para imprimir solo el PID (columna 2) y el comando (columna 11) de los procesos que pertenecen al usuario 'root'.

#!/bin/bash
# Filtramos por root y usamos awk para formatear la salida
ps aux | awk '$1 == "root" {print "PID: " $2 " -> CMD: " $11}' | head -n 10

8. Automatización: Copia de Seguridad Simple (UAM)

Enunciado: Crea un script que comprima la carpeta /var/log en un archivo tar.gz. El nombre del archivo debe contener la fecha actual (ej. backup_2024-05-20.tar.gz).

#!/bin/bash
FECHA=$(date +%Y-%m-%d)
ARCHIVO="backup_log_$FECHA.tar.gz"

tar -czf /tmp/$ARCHIVO /var/log 2>/dev/null
echo "Backup guardado en /tmp/$ARCHIVO"

9. Alerta de Espacio en Disco (UNED)

Enunciado: Script que comprueba si la partición principal (/) supera el 85% de uso. Si es así, muestra una advertencia en la terminal.

#!/bin/bash
PORCENTAJE=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')

if [ "$PORCENTAJE" -gt 85 ]; then
    echo "¡PELIGRO! El disco está al $PORCENTAJE% de capacidad."
else
    echo "Disco en estado óptimo ($PORCENTAJE%)."
fi

10. Creación Masiva de Usuarios (UMA)

Enunciado: Escribe un script que lea un archivo llamado usuarios.txt (un nombre por línea) y cree automáticamente una cuenta en el sistema para cada uno usando useradd.

#!/bin/bash
ARCHIVO="usuarios.txt"

if [ ! -f "$ARCHIVO" ]; then
    echo "No se encuentra el archivo $ARCHIVO"
    exit 1
fi

while IFS= read -r user; do
    sudo useradd -m "$user"
    echo "Usuario $user creado exitosamente."
done < "$ARCHIVO"

10 Ejercicios de Python Resueltos: Ficheros, RegEx, Pandas y NumPy

¡Llegamos al final de nuestra megaguía en larebelion.com! Ya hemos superado las bases, las estructuras, la POO y la algoritmia. ¿Qué nos queda? Interactuar con el mundo real.

En este último bloque de 10 ejercicios (del 41 al 50) nos enfrentamos a problemas de exámenes de universidades españolas que exigen leer ficheros TXT, CSV y JSON, validar datos con Expresiones Regulares (RegEx) y utilizar las librerías estrella: Pandas y NumPy. ¡Vamos a por el 10!




41. Ficheros TXT: Contar Líneas y Palabras (UAH)

Enunciado: Escribe una función que abra un archivo de texto en modo lectura y devuelva una tupla con el número total de líneas y el número total de palabras.

def analizar_archivo(ruta):
    try:
        with open(ruta, 'r', encoding='utf-8') as f:
            lineas = f.readlines()
            num_lineas = len(lineas)
            num_palabras = sum(len(linea.split()) for linea in lineas)
            return (num_lineas, num_palabras)
    except FileNotFoundError:
        return "Archivo no encontrado"

42. Ficheros: Escribir sin Sobrescribir (UAL)

Enunciado: Crea una función que reciba una ruta y una cadena de texto, y añada ese texto al final del archivo existente sin borrar su contenido anterior.

def anadir_log(ruta, mensaje):
    # Usamos el modo 'a' (append) en lugar de 'w' (write)
    with open(ruta, 'a', encoding='utf-8') as f:
        f.write(mensaje + "\n")

43. Manejo de JSON: Guardar Diccionarios (URV)

Enunciado: Dado un diccionario de Python con datos de estudiantes, expórtalo a un archivo con formato JSON, asegurando que la indentación sea de 4 espacios.

import json

def guardar_json(datos, ruta_salida):
    with open(ruta_salida, 'w', encoding='utf-8') as f:
        json.dump(datos, f, indent=4, ensure_ascii=False)

44. CSV Nativo: Leer Columnas (UJI)

Enunciado: Usando solo la librería estándar csv, lee un archivo y devuelve una lista con todos los valores de la segunda columna.

import csv

def extraer_columna(ruta_csv):
    columna = []
    with open(ruta_csv, 'r', encoding='utf-8') as f:
        lector = csv.reader(f)
        for fila in lector:
            if len(fila) > 1:
                columna.append(fila[1])
    return columna

45. RegEx: Validador de DNI Español (UCA)

Enunciado: Escribe una función que utilice expresiones regulares para comprobar si un string tiene el formato válido de un DNI español (8 números seguidos de una letra mayúscula).

import re

def es_dni_valido(dni):
    # Patrón: Exactamente 8 dígitos (\d{8}) y 1 letra mayúscula ([A-Z])
    patron = r"^\d{8}[A-Z]$"
    return bool(re.match(patron, dni))

46. RegEx: Extractor de Correos Electrónicos (UNIOVI)

Enunciado: Dado un texto largo, extrae todas las direcciones de correo electrónico que aparezcan en él usando re.findall.

import re

def extraer_emails(texto):
    patron = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
    return re.findall(patron, texto)

47. NumPy: Arrays 1D a 2D (UPNA)

Enunciado: Utiliza NumPy para crear un array de 12 elementos (del 1 al 12) y luego cambia su forma (reshape) para convertirlo en una matriz de 3x4.

import numpy as np

def crear_matriz_numpy():
    # np.arange(1, 13) crea array del 1 al 12
    array_1d = np.arange(1, 13)
    matriz_2d = array_1d.reshape((3, 4))
    return matriz_2d

48. Pandas: Leer y Calcular Media (UPO)

Enunciado: Escribe un código usando Pandas que lea un archivo "alumnos.csv" y calcule la media aritmética de la columna llamada 'Nota_Final'.

import pandas as pd

def calcular_media_csv(ruta):
    df = pd.read_csv(ruta)
    if 'Nota_Final' in df.columns:
        return df['Nota_Final'].mean()
    return None

49. Pandas: Filtrado de DataFrames (UCLM)

Enunciado: Dado un DataFrame de Pandas con información de empleados, filtra y devuelve solo aquellos que pertenezcan al departamento de 'IT' y cobren más de 2000€.

import pandas as pd

def filtrar_empleados(df):
    # Uso de condiciones booleanas múltiples con &
    filtro = df[(df['Departamento'] == 'IT') & (df['Salario'] > 2000)]
    return filtro

50. El Ejercicio Final: Manejo de Excepciones Múltiples (UVA)

Enunciado: Crea una función que intente convertir un input de texto a número entero y luego dividir 100 entre ese número. Atrapa específicamente los errores ValueError y ZeroDivisionError.

def division_segura(entrada):
    try:
        numero = int(entrada)
        resultado = 100 / numero
        return resultado
    except ValueError:
        return "Error: Debes introducir un número válido."
    except ZeroDivisionError:
        return "Error: No se puede dividir entre cero."

10 Ejercicios de Algoritmia en Python: Pilas, Colas, Recursividad y Matrices

Bienvenidos a una nueva entrega en larebelion.com. Si ya dominas la sintaxis básica y la Orientación a Objetos, es hora de enfrentarse al verdadero reto de la Ingeniería Informática: la Algoritmia.

En este post hemos recopilado 10 ejercicios de exámenes enfocados en estructuras de datos lineales (Pilas y Colas), matrices y recursividad avanzada. Dominar esto es la clave para superar asignaturas como Estructuras de Datos y Algoritmos.




31. Pilas (Stacks): Paréntesis Balanceados (UPM)

Enunciado: Implementa una función que use una Pila (Stack) para verificar si una cadena de texto tiene los paréntesis (), corchetes [] y llaves {} correctamente balanceados.

def esta_balanceado(cadena):
    pila = []
    pares = {')': '(', ']': '[', '}': '{'}
    for char in cadena:
        if char in pares.values():
            pila.append(char)
        elif char in pares.keys():
            if not pila or pila.pop() != pares[char]:
                return False
    return len(pila) == 0

32. Colas (Queues): Simulación de Impresora (UPC)

Enunciado: Usando collections.deque, simula una cola de impresión donde se añaden documentos y se imprimen (procesan) en orden FIFO (First In, First Out).

from collections import deque

class ColaImpresion:
    def __init__(self): self.cola = deque()

    def agregar_trabajo(self, documento):
        self.cola.append(documento)

    def imprimir(self):
        if self.cola:
            return self.cola.popleft()
        return "Sin trabajos"

33. Matrices: Suma de la Diagonal Principal (UGR)

Enunciado: Dada una matriz cuadrada (lista de listas), calcula la suma de los elementos de su diagonal principal.

def suma_diagonal(matriz):
    # Usando comprensión de listas para mayor elegancia
    return sum(matriz[i][i] for i in range(len(matriz)))

34. Matrices: Multiplicación de Matrices (UC3M)

Enunciado: Escribe un algoritmo de complejidad $O(n^3)$ que multiplique dos matrices A y B, devolviendo la matriz resultante.

def multiplicar_matrices(A, B):
    filas_A, cols_A = len(A), len(A[0])
    cols_B = len(B[0])
    C = [[0 for _ in range(cols_B)] for _ in range(filas_A)]
    for i in range(filas_A):
        for j in range(cols_B):
            for k in range(cols_A):
                C[i][j] += A[i][k] * B[k][j]
    return C

35. Recursividad: Torres de Hanoi (UCM)

Enunciado: Implementa el clásico problema de las Torres de Hanoi recursivamente, imprimiendo los movimientos necesarios para trasladar n discos.

def hanoi(n, origen, destino, auxiliar):
    if n == 1:
        print(f"Mover disco 1 de {origen} a {destino}")
        return
    hanoi(n-1, origen, auxiliar, destino)
    print(f"Mover disco {n} de {origen} a {destino}")
    hanoi(n-1, auxiliar, destino, origen)

36. Recursividad: Algoritmo de Euclides (USAL)

Enunciado: Calcula el Máximo Común Divisor (MCD) de dos números enteros utilizando la versión recursiva del algoritmo de Euclides.

def mcd_euclides(a, b):
    # Caso base: si el resto es 0, el MCD es 'a'
    if b == 0:
        return a
    # Llamada recursiva con b y el resto de a/b
    return mcd_euclides(b, a % b)

37. Recursividad: Suma de Dígitos (UNED)

Enunciado: Escribe una función recursiva que reciba un número entero positivo y devuelva la suma de todos sus dígitos.

def suma_digitos(n):
    if n == 0:
        return 0
    return (n % 10) + suma_digitos(n // 10)

38. Algoritmos de Ordenación: Bubble Sort (UV)

Enunciado: Implementa el algoritmo de Ordenación de Burbuja (Bubble Sort). Aunque es de complejidad $O(n^2)$, es un clásico que siempre cae en exámenes de primero.

def bubble_sort(lista):
    n = len(lista)
    for i in range(n):
        for j in range(0, n-i-1):
            if lista[j] > lista[j+1]:
                # Intercambio de variables
                lista[j], lista[j+1] = lista[j+1], lista[j]
    return lista

39. Algoritmos de Ordenación: Selection Sort (UAM)

Enunciado: Implementa la Ordenación por Selección (Selection Sort), buscando el elemento mínimo en cada iteración y colocándolo al principio.

def selection_sort(lista):
    for i in range(len(lista)):
        min_idx = i
        for j in range(i+1, len(lista)):
            if lista[j] < lista[min_idx]:
                min_idx = j
        lista[i], lista[min_idx] = lista[min_idx], lista[i]
    return lista

40. Algoritmos de Ordenación: Insertion Sort (US)

Enunciado: Implementa la Ordenación por Inserción (Insertion Sort), el algoritmo que simula cómo ordenaríamos una baraja de cartas en la mano.

def insertion_sort(lista):
    for i in range(1, len(lista)):
        clave = lista[i]
        j = i - 1
        while j >= 0 and clave < lista[j]:
            lista[j + 1] = lista[j]
            j -= 1
        lista[j + 1] = clave
    return lista

10 Ejercicios Resueltos de Python: Programación Orientada a Objetos (POO) en la Universidad

Llegamos al núcleo duro de la carrera en larebelion.com. Si quieres aprobar asignaturas como Programación II o Metodología de la Programación, tienes que dominar las clases, los objetos, la herencia y el polimorfismo en Python.

Te traemos 10 ejercicios clásicos de exámenes sobre POO extraídos de las mejores facultades de España. ¡Prepara tus métodos __init__ porque empezamos!




21. Clase Básica: Geometría (UPM)

Enunciado: Crea una clase Rectangulo que reciba la base y la altura en su constructor, y contenga métodos para calcular el área y el perímetro.

class Rectangulo:
    def __init__(self, base, altura):
        self.base = base
        self.altura = altura

    def area(self):
        return self.base * self.altura

    def perimetro(self):
        return 2 * (self.base + self.altura)

22. Encapsulamiento: Cuenta Bancaria (UPC)

Enunciado: Implementa una clase CuentaBancaria con un atributo privado para el saldo (__saldo) y métodos para depositar y retirar dinero, validando que no se pueda retirar más del saldo disponible.

class CuentaBancaria:
    def __init__(self, saldo_inicial=0):
        self.__saldo = saldo_inicial

    def depositar(self, cantidad):
        if cantidad > 0: self.__saldo += cantidad

    def retirar(self, cantidad):
        if 0 < cantidad <= self.__saldo:
            self.__saldo -= cantidad
            return True
        return False

    def get_saldo(self):
        return self.__saldo

23. Herencia: Vehículos (UGR)

Enunciado: Crea una clase base Vehiculo con atributos marca y ruedas. Luego, crea una subclase Coche que herede de ella y añada el atributo puertas.

class Vehiculo:
    def __init__(self, marca, ruedas):
        self.marca = marca
        self.ruedas = ruedas

class Coche(Vehiculo):
    def __init__(self, marca, puertas):
        # Llamamos al constructor padre con super()
        super().__init__(marca, ruedas=4)
        self.puertas = puertas

24. Polimorfismo: Empleados (UV)

Enunciado: Define una clase Empleado con un método calcular_salario(). Crea las clases Programador y Gerente que sobrescriban este método de forma diferente.

class Empleado:
    def __init__(self, base): self.base = base
    def calcular_salario(self): pass

class Programador(Empleado):
    def calcular_salario(self):
        return self.base + 500 # Bono de código

class Gerente(Empleado):
    def calcular_salario(self):
        return self.base + 2000 # Bono de dirección

25. Composición: Ordenador y CPU (UC3M)

Enunciado: Demuestra la composición creando una clase Procesador que se instancie dentro del constructor de una clase Ordenador.

class Procesador:
    def __init__(self, modelo):
        self.modelo = modelo

class Ordenador:
    def __init__(self, marca, cpu_modelo):
        self.marca = marca
        # Composición: El procesador pertenece al ordenador
        self.cpu = Procesador(cpu_modelo)

26. Métodos Mágicos (Dunder): __str__ (US)

Enunciado: Crea una clase Libro (título, autor) y sobrescribe el método __str__ para que al hacer print(libro) devuelva "Título por Autor".

class Libro:
    def __init__(self, titulo, autor):
        self.titulo = titulo
        self.autor = autor

    def __str__(self):
        return f"{self.titulo} por {self.autor}"

27. Sobrecarga de Operadores: __add__ (UMA)

Enunciado: Implementa una clase Punto2D (x, y) que permita sumar dos puntos usando el operador matemático +.

class Punto2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, otro_punto):
        return Punto2D(self.x + otro_punto.x, self.y + otro_punto.y)

28. Atributos de Clase vs Instancia (UAM)

Enunciado: Crea una clase Usuario que lleve la cuenta total de cuántos usuarios han sido instanciados usando un atributo de clase.

class Usuario:
    # Atributo de clase
    total_usuarios = 0

    def __init__(self, nombre):
        self.nombre = nombre # Atributo de instancia
        Usuario.total_usuarios += 1

29. Excepciones Personalizadas (UNED)

Enunciado: Crea una excepción propia llamada SaldoInsuficienteError y lánzala (raise) en una clase Monedero si se intenta pagar más de lo que hay.

class SaldoInsuficienteError(Exception):
    pass

class Monedero:
    def __init__(self, saldo): self.saldo = saldo

    def pagar(self, importe):
        if importe > self.saldo:
            raise SaldoInsuficienteError("No hay dinero suficiente.")
        self.saldo -= importe

30. Relación entre Clases: Universidad (USAL)

Enunciado: Escribe una clase Curso que mantenga una lista de objetos Alumno. Implementa un método para matricular un alumno en el curso.

class Alumno:
    def __init__(self, nombre): self.nombre = nombre

class Curso:
    def __init__(self, nombre_asignatura):
        self.asignatura = nombre_asignatura
        self.alumnos = [] # Lista de objetos Alumno

    def matricular(self, alumno):
        self.alumnos.append(alumno)

    def listar_alumnos(self):
        return [a.nombre for a in self.alumnos]

10 Ejercicios de Python Resueltos: Diccionarios, Sets y Tuplas en la Universidad

Continuamos con nuestra megaguía de Python en larebelion.com. Una vez que dominas los bucles y las listas, los profesores de la universidad suben el nivel exigiendo eficiencia. Y ahí es donde entran los diccionarios (Tablas Hash) y los conjuntos (Sets).

Aquí tienes 10 ejercicios reales de universidades españolas (UCM, UAB, UNED...) centrados puramente en estructuras de datos complejas.




11. Frecuencia de Caracteres (UCM - Universidad Complutense)

Enunciado: Escribe una función que reciba una cadena de texto y devuelva un diccionario con la cantidad de veces que aparece cada carácter.

def contar_caracteres(cadena):
    frecuencias = {}
    for char in cadena:
        frecuencias[char] = frecuencias.get(char, 0) + 1
    return frecuencias

12. Elementos Comunes con Sets (UAB - Universitat Autònoma de Barcelona)

Enunciado: Dadas dos listas, devuelve una nueva lista con los elementos comunes sin usar bucles anidados (complejidad $O(n)$).

def elementos_comunes(lista1, lista2):
    # Convertimos a sets y usamos la intersección &
    return list(set(lista1) & set(lista2))

13. Agrupar Palabras por Longitud (UPNA - U. Pública de Navarra)

Enunciado: Dada una lista de palabras, devuelve un diccionario donde las claves sean las longitudes de las palabras y los valores listas de palabras con esa longitud.

def agrupar_longitud(palabras):
    grupos = {}
    for p in palabras:
        longitud = len(p)
        if longitud not in grupos:
            grupos[longitud] = []
        grupos[longitud].append(p)
    return grupos

14. Combinar y Sumar Diccionarios (UNED)

Enunciado: Dados dos diccionarios con claves de texto y valores numéricos, devuelve un diccionario combinado. Si una clave existe en ambos, sus valores deben sumarse.

def combinar_diccionarios(d1, d2):
    resultado = d1.copy()
    for k, v in d2.items():
        resultado[k] = resultado.get(k, 0) + v
    return resultado

15. Eliminar Duplicados Manteniendo Orden (USC - U. de Santiago)

Enunciado: Elimina los duplicados de una lista, pero a diferencia de usar set() directamente, mantén el orden original de los elementos.

def unicos_con_orden(lista):
    vistos = set()
    resultado = []
    for item in lista:
        if item not in vistos:
            vistos.add(item)
            resultado.append(item)
    return resultado

16. Diccionario de Diccionarios: Notas de Alumnos (UCA - U. de Cádiz)

Enunciado: Recibe un diccionario donde las claves son alumnos y los valores diccionarios con asignaturas y notas. Calcula la media de cada alumno.

def calcular_medias(registro):
    medias = {}
    for alumno, notas in registro.items():
        if notas:
            medias[alumno] = sum(notas.values()) / len(notas)
        else:
            medias[alumno] = 0.0
    return medias

17. Subconjuntos Estrictos (ULL - U. de La Laguna)

Enunciado: Escribe una función que verifique si la lista A es un subconjunto de la lista B, asumiendo que todos los elementos son únicos.

def es_subconjunto(lista_a, lista_b):
    return set(lista_a).issubset(set(lista_b))

18. Tuplas: Min y Max en una pasada (UNIZAR - U. de Zaragoza)

Enunciado: Encuentra el valor máximo y mínimo de una lista en un solo bucle y devuélvelos empaquetados en una tupla.

def min_max(numeros):
    if not numeros: return None
    minimo = maximo = numeros[0]
    for n in numeros[1:]:
        if n < minimo: minimo = n
        if n > maximo: maximo = n
    return (minimo, maximo)

19. Crear Diccionario desde Dos Listas usando Zip (UCLM)

Enunciado: Dadas dos listas, una de claves y otra de valores, conviértelas en un diccionario. Asegúrate de manejar el caso donde las listas tienen diferentes tamaños.

def fusionar_listas(claves, valores):
    # Zip trunca a la lista más corta automáticamente
    return dict(zip(claves, valores))

20. Invertir Diccionario (URV - Universitat Rovira i Virgili)

Enunciado: Dado un diccionario, devuelve uno nuevo donde las claves sean los valores antiguos, y los valores sean las claves antiguas. Supón que los valores originales son únicos.

def invertir_diccionario(dic):
    # Usamos dictionary comprehension
    return {v: k for k, v in dic.items()}