diff --git a/tareas/examen/Parcial2_solo codigo.py b/tareas/examen/Parcial2_solo codigo.py new file mode 100644 index 0000000..647e608 --- /dev/null +++ b/tareas/examen/Parcial2_solo codigo.py @@ -0,0 +1,152 @@ +NOMBRE = "Brandom Rodriguez" # TU NOMBRE AQUI +CARNET = "202506893" # TU CARNET AQUI +if NOMBRE == "Nombre Apellido" or CARNET == "202300000": + raise ValueError("Completa tu nombre y carnet antes de continuar.") +print(f"Estudiante : {NOMBRE}") +print(f"Carnet : {CARNET}") +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#Ejercicio 1 + +#Parte a +import requests +URL_BASE = "https://api.nasa.gov/DONKI/GST" +API_KEY = "DEMO_KEY" +# Agrega también los parámetros startDate y endDate: +startDate = "2024-05-01" +endDate = "2024-05-31" +# Construcción de la URL +url = ( + f"{URL_BASE}" + f"?startDate={startDate}" + f"&endDate={endDate}" + f"&api_key={API_KEY}" +) +# Completa la llamada — usa timeout=15 +respuesta = requests.get(url, timeout=15) +# Verifica que la respuesta fue exitosa antes de parsear el JSON +if not respuesta.ok: + print(f"Error {respuesta.status_code}: {respuesta.text}") + raise SystemExit("No se pudo obtener la respuesta. Intenta de nuevo.") +tormentas = respuesta.json() +print(f"Solicitud exitosa ✓ — {len(tormentas)} tormentas recibidas") + +#Parte b +print(f"Total de tormentas en el período: {len(tormentas)}") +# Recorrer cada tormenta +for tormenta in tormentas: + gst_id = tormenta.get("gstID", "N/A") + start_time = tormenta.get("startTime", "N/A") + print(f"ID: {gst_id} | Inicio: {start_time}") +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#Ejercicio 2 + +#Parte a +for tormenta in tormentas: + kp_max = 0 +# recorrer la lista allKpIndex + for medicion in tormenta.get("allKpIndex", []): + kp = medicion.get("kpIndex", 0) + if kp > kp_max: + kp_max = kp + print(f"{tormenta['startTime']} | Kp máx = {kp_max:.2f}") + +#Parte b +tormenta_mas_intensa = None +kp_global_max = 0 +for tormenta in tormentas: + kp_max = 0 +# calcular kp máximo de esta tormenta + for medicion in tormenta.get("allKpIndex", []): + kp = medicion.get("kpIndex", 0) + if kp > kp_max: + kp_max = kp +# comparar con el máximo global + if kp_max > kp_global_max: + kp_global_max = kp_max + tormenta_mas_intensa = tormenta +if tormenta_mas_intensa: + print("\nTormenta más intensa:") + print(f"Inicio: {tormenta_mas_intensa['startTime']}") + print(f"Kp máximo global: {kp_global_max:.2f}") +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#Ejercicio 3 + +#Parte a +def clasificar_kp(kp): + """Clasifica la intensidad de una tormenta según el índice Kp""" + kp = int(kp) # redondea hacia abajo + if kp < 4: + return "Quieto" + elif kp == 4: + return "Activo" + elif kp == 5: + return "G1 - Menor" + elif kp == 6: + return "G2 - Moderada" + elif kp == 7: + return "G3 - Fuerte" + elif kp == 8: + return "G4 - Severa" + else: # kp >= 9 + return "G5 - Fuerte" +#Prueba tu función con estos valores — verifica que los resultados son correctos: +for kp_prueba in [2.0, 4.0, 5.33, 6.67, 7.0, 8.67, 9.0]: + print(f"kp={kp_prueba:.2f} → {clasificar_kp(kp_prueba)}") + +#Parte b +print(f"\n{'Fecha inicio':<22} {'Kp máx':>7} {'Categoría'}") +print("-" * 50) +for tormenta in tormentas: + kp_max = 0 +# calcular el Kp máximo de la tormenta + for medicion in tormenta.get("allKpIndex", []): + kp = medicion.get("kpIndex", 0) + if kp > kp_max: + kp_max = kp + categoria = clasificar_kp(kp_max) + print(f"{tormenta['startTime']:<22} {kp_max:>7.2f} {categoria}") +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +#Ejercicio 4 + +def analizar_tormenta(tormenta): + """ + Analiza un evento de tormenta geomagnética. + Parámetro: + tormenta (dict): un elemento de la lista retornada por el endpoint GST. + Retorna: + dict con las claves: id, inicio, kp_max, kp_min, kp_promedio, + num_mediciones, categoria, eventos_vinculados. + """ + mediciones = tormenta["allKpIndex"] +# Extraer valores kpIndex + kp_valores = [m["kpIndex"] for m in mediciones] + resultado = { + "id": tormenta["gstID"], + "inicio": tormenta["startTime"], + "kp_max": max(kp_valores), + "kp_min": min(kp_valores), + "kp_promedio": round(sum(kp_valores) / len(kp_valores), 2), + "num_mediciones": len(mediciones), + "categoria": clasificar_kp(max(kp_valores)), + "eventos_vinculados": len(tormenta["linkedEvents"] or []), + } + return resultado +for tormenta in tormentas: + r = analizar_tormenta(tormenta) + print(f"ID: {r['id']}") + print(f"Inicio: {r['inicio']}") + print(f"Kp Máx: {r['kp_max']}") + print(f"Kp Mín: {r['kp_min']}") + print(f"Kp Promedio: {r['kp_promedio']}") + print(f"Número de mediciones: {r['num_mediciones']}") + print(f"Categoría: {r['categoria']}") + print(f"Eventos vinculados: {r['eventos_vinculados']}") + print("-" * 40) +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +print("Conculsiones:") + +print("1. La tormenta mas intensa fue Inicio:2024-05-10T15:00Z con un Kp maximo de 9.00 y su clasificacion G5-Fuerte. Su kp es el valor maximo posible lo que implica que fue una tormenta geomagnetica extrema") +print("2. Frecuencia :Se registraron 5 tormentas en un periodo de 15 dias, esto significa una alta activida geomagnetica. Tambien que hay una concentracion clara entre 10 y el 17 de mayor.Intensidad: 4 de las 5 tormantas fueron G2 con kp de 6.00 a 6.67, solo hubo una tormenta intesa de clasificacion G5. Esto implica una actividad moderada. Eventos vinculados: La tormenta mas intensa tiene un mayor numero de mediciones que en total son 13 y de cantidad de eventos vinculados 6 en total. La tormentas moderadas tienen solamente entr 1 o 2 eventos.") +print("3. Una tormenta nivel G5-Fuerte podria haber causado interrupciones en los sistemas de navegacion (GPS),apagones, Auroras visibles en latitudes inusualmente bajas y fallos en equipos ") + +#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/tareas/examen/examen_parcial2_estudiante.ipynb b/tareas/examen/examen_parcial2_estudiante.ipynb new file mode 100644 index 0000000..ffde3a3 --- /dev/null +++ b/tareas/examen/examen_parcial2_estudiante.ipynb @@ -0,0 +1,835 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "title", + "metadata": {}, + "source": [ + "# Examen Parcial 2 — Programación 1 (F12)\n", + "## Tormentas Geomagnéticas con la API de NASA / DONKI\n", + "\n", + "**Nombre:** Brandom Aroldo Rodriguez Gonzalez \n", + "**Carnet:** 202506893 \n", + "**Fecha:** 24/04/2026 \n", + "**Punteo total:** 100 puntos\n", + "\n", + "---\n", + "\n", + "| Ejercicio | Tema | Puntos |\n", + "|---|---|:---:|\n", + "| 1a | Construir la URL y realizar la solicitud HTTP | 10 |\n", + "| 1b | Explorar la lista de tormentas con un ciclo `for` | 10 |\n", + "| 2 | Calcular el Kp máximo e identificar la tormenta más intensa | 20 |\n", + "| 3 | Función `clasificar_kp()` con condicionales | 25 |\n", + "| 4 | Función `analizar_tormenta()` que retorna un diccionario | 35 |\n", + "| | **Total** | **100** |\n", + "\n", + "---\n", + "\n", + "> **Instrucciones generales**\n", + "> - Completa cada ejercicio en la celda indicada.\n", + "> - Ejecuta las celdas **en orden** de arriba hacia abajo.\n", + "> - Puedes consultar tus apuntes y el notebook de clase `XML_JSON_APIs.ipynb`.\n", + "> - Entrega el notebook con **todas las celdas ejecutadas** (con output visible)." + ] + }, + { + "cell_type": "markdown", + "id": "background", + "metadata": {}, + "source": [ + "---\n", + "## Contexto: ¿Qué es una tormenta geomagnética?\n", + "\n", + "El Sol emite constantemente partículas cargadas (viento solar). Cuando ocurre una erupción solar intensa, una ola de partículas choca con el campo magnético de la Tierra y provoca una **tormenta geomagnética**.\n", + "\n", + "Estos eventos pueden:\n", + "- Generar auroras boreales visibles en latitudes bajas\n", + "- Interferir con satélites GPS y comunicaciones de radio\n", + "- En casos extremos, dañar redes eléctricas (como el apagón de Quebec en 1989)\n", + "\n", + "### Índice Kp — escala de intensidad\n", + "\n", + "El **índice Kp** (0–9) mide la perturbación del campo magnético terrestre:\n", + "\n", + "| Kp | Categoría | Descripción |\n", + "|---|---|---|\n", + "| 0 – 3 | Quieto | Sin tormenta |\n", + "| 4 | Activo | Perturbación menor |\n", + "| 5 | **G1** — Menor | Auroras en latitudes altas |\n", + "| 6 | **G2** — Moderada | Auroras hasta latitud 55° |\n", + "| 7 | **G3** — Fuerte | Auroras hasta latitud 50° |\n", + "| 8 | **G4** — Severa | Problemas en redes eléctricas |\n", + "| 9 | **G5** — Extrema | Apagones posibles, auroras tropicales |\n", + "\n", + "La tormenta de mayo 2024 alcanzó **G5** — la más intensa en 20 años." + ] + }, + { + "cell_type": "markdown", + "id": "api-docs", + "metadata": {}, + "source": [ + "---\n", + "## El endpoint: DONKI / GST\n", + "\n", + "**DONKI** = Space Weather Database Of Notifications, Knowledge, Information \n", + "**GST** = Geomagnetic Storm\n", + "\n", + "```\n", + "GET https://api.nasa.gov/DONKI/GST\n", + "```\n", + "\n", + "| Parámetro | Tipo | Default | Descripción |\n", + "|---|---|---|---|\n", + "| `startDate` | YYYY-MM-DD | 30 días atrás | Inicio del rango de fechas |\n", + "| `endDate` | YYYY-MM-DD | hoy | Fin del rango de fechas |\n", + "| `api_key` | string | DEMO_KEY | Tu API key de api.nasa.gov |\n", + "\n", + "**Ejemplo de URL:**\n", + "```\n", + "https://api.nasa.gov/DONKI/GST?startDate=2024-05-01&endDate=2024-05-31&api_key=DEMO_KEY\n", + "```\n", + "\n", + "### Estructura de la respuesta\n", + "\n", + "La API devuelve una **lista** de eventos. Cada evento es un diccionario con esta estructura:\n", + "\n", + "```json\n", + "{\n", + " \"gstID\": \"2024-05-10T17:00:00-GST-001\",\n", + " \"startTime\": \"2024-05-10T17:00Z\",\n", + " \"allKpIndex\": [\n", + " { \"observedTime\": \"2024-05-10T21:00Z\", \"kpIndex\": 8.67, \"source\": \"NOAA\" },\n", + " { \"observedTime\": \"2024-05-11T00:00Z\", \"kpIndex\": 9.0, \"source\": \"NOAA\" }\n", + " ],\n", + " \"linkedEvents\": [\n", + " { \"activityID\": \"2024-05-08T21:08:00-CME-001\" }\n", + " ],\n", + " \"link\": \"https://webtools.ccmc.gsfc.nasa.gov/DONKI/view/GST/...\"\n", + "}\n", + "```\n", + "\n", + "**Campos importantes:**\n", + "- `gstID` — identificador único del evento\n", + "- `startTime` — cuándo comenzó la tormenta (formato ISO 8601 UTC)\n", + "- `allKpIndex` — lista de mediciones Kp durante la tormenta\n", + "- `linkedEvents` — eventos espaciales relacionados (erupciones, CME) — puede ser `None`" + ] + }, + { + "cell_type": "markdown", + "id": "setup-title", + "metadata": {}, + "source": [ + "---\n", + "## Paso 1 — Configuración de la API Key\n", + "\n", + "### Obtener tu API key (gratis)\n", + "\n", + "1. Ve a **https://api.nasa.gov**\n", + "2. Completa el formulario con tu nombre y correo electrónico\n", + "3. Haz clic en **\"Signup\"**\n", + "4. Revisa tu correo — recibirás la key en minutos\n", + "5. La key tiene este formato: `TU_API_KEY_AQUI_XXXXXXXXXXXXXXXXXXXXXXXX`\n", + "\n", + "Con tu propia key puedes hacer **1,000 solicitudes por hora** (vs 30 con DEMO_KEY).\n", + "\n", + "---\n", + "\n", + "### Configurar la variable de entorno `NASA_API_KEY`\n", + "\n", + "Una variable de entorno guarda tu key **fuera del código**, para que no quede expuesta \n", + "en el archivo del notebook ni en el historial de git.\n", + "\n", + "#### Linux / macOS — temporal (solo la sesión actual)\n", + "```bash\n", + "export NASA_API_KEY=\"tu_key_aqui\"\n", + "jupyter notebook\n", + "```\n", + "\n", + "#### Linux / macOS — permanente\n", + "Agrega esta línea al final de `~/.bashrc` (bash) o `~/.zshrc` (zsh):\n", + "```bash\n", + "echo 'export NASA_API_KEY=\"tu_key_aqui\"' >> ~/.bashrc\n", + "source ~/.bashrc # aplicar sin reiniciar\n", + "```\n", + "\n", + "#### Windows — PowerShell (temporal)\n", + "```powershell\n", + "$env:NASA_API_KEY = \"tu_key_aqui\"\n", + "jupyter notebook\n", + "```\n", + "\n", + "#### Windows — permanente (Panel de control)\n", + "1. Busca **\"Variables de entorno\"** en el menú Inicio\n", + "2. Clic en **\"Editar las variables de entorno del sistema\"**\n", + "3. Botón **\"Variables de entorno...\"**\n", + "4. En \"Variables de usuario\" → **Nueva**\n", + "5. Nombre: `NASA_API_KEY` | Valor: tu key\n", + "6. Aceptar y **reiniciar** Jupyter\n", + "\n", + "#### Verificar que está configurada\n", + "```bash\n", + "# Linux/macOS\n", + "echo $NASA_API_KEY\n", + "\n", + "# Windows PowerShell\n", + "echo $env:NASA_API_KEY\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "setup-code", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import requests\n", + "import json\n", + "import time\n", + "\n", + "# Cargar la API key desde la variable de entorno.\n", + "# Si no está configurada, usa DEMO_KEY como respaldo (30 req/hora).\n", + "API_KEY = os.getenv(\"NASA_API_KEY\", \"\").strip() or \"DEMO_KEY\"\n", + "\n", + "if API_KEY == \"DEMO_KEY\":\n", + " print(\"⚠ Usando DEMO_KEY — límite: 30 solicitudes/hora\")\n", + " print(\" Configura NASA_API_KEY para mayor límite (ver instrucciones arriba).\")\n", + "else:\n", + " print(f\"✓ API key cargada: {API_KEY[:4]}{'*' * (len(API_KEY) - 4)}\")\n", + "\n", + "print(\"\\nLibrerías importadas correctamente ✓\")" + ] + }, + { + "cell_type": "markdown", + "id": "ident-md", + "metadata": {}, + "source": [ + "---\n", + "## Identificacion del estudiante\n", + "\n", + "Completa tu nombre y carnet en la siguiente celda y **ejecutala antes de comenzar**. \n", + "Estos datos quedan registrados en el output del notebook junto con la posicion de la ISS \n", + "en el momento exacto en que realizas el examen." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ident-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Estudiante : Brandom Rodriguez\n", + "Carnet : 202506893\n" + ] + } + ], + "source": [ + "# Completa tus datos\n", + "NOMBRE = \"Brandom Rodriguez\" # TU NOMBRE AQUI\n", + "CARNET = \"202506893\" # TU CARNET AQUI\n", + "\n", + "if NOMBRE == \"Nombre Apellido\" or CARNET == \"202300000\":\n", + " raise ValueError(\"Completa tu nombre y carnet antes de continuar.\")\n", + "\n", + "print(f\"Estudiante : {NOMBRE}\")\n", + "print(f\"Carnet : {CARNET}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ej1-md", + "metadata": {}, + "source": [ + "---\n", + "## Ejercicio 1 — Obtener y explorar los datos (20 pts)\n", + "\n", + "### Parte a) — Solicitud al endpoint (10 pts)\n", + "\n", + "Se te da la URL base del endpoint. Construye la URL completa usando un f-string e incluye los parámetros `startDate`, `endDate` y `api_key`. Luego realiza la solicitud y verifica que fue exitosa.\n", + "\n", + "---\n", + "\n", + "### ¿Por qué verificar el código de estado antes de leer el JSON?\n", + "\n", + "Cuando hacemos una solicitud HTTP el servidor siempre responde con un **código de estado numérico** que indica si todo salió bien o hubo un problema.\n", + "\n", + "El código **200** significa *\"OK — la solicitud fue exitosa y el cuerpo de la respuesta contiene los datos pedidos\"*.\n", + "\n", + "Si el servidor devuelve un código diferente (por ejemplo **503 - Service Unavailable** o **429 - Too Many Requests**), el cuerpo de la respuesta **no contiene JSON válido** — puede estar vacío o contener un mensaje de error en texto plano. Si intentamos llamar `.json()` directamente sin verificar, el programa lanzará un `JSONDecodeError`.\n", + "\n", + "Por eso siempre debemos verificar que `respuesta.status_code == 200` (o equivalentemente `respuesta.ok`) **antes** de intentar parsear la respuesta.\n", + "\n", + "> **Escribe en la celda de código siguiente: ¿qué imprimirías tú para que el usuario sepa qué salió mal cuando el código no es 200?**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ej1-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solicitud exitosa ✓ — 5 tormentas recibidas\n" + ] + } + ], + "source": [ + "import requests\n", + "URL_BASE = \"https://api.nasa.gov/DONKI/GST\"\n", + "API_KEY = \"DEMO_KEY\"\n", + "# Agrega también los parámetros startDate y endDate:\n", + "# startDate = \"2024-05-01\"\n", + "# endDate = \"2024-05-31\"\n", + "# Hint: los parámetros van separados por \"&\" → ?param1=val1¶m2=val2\n", + "startDate = \"2024-05-01\"\n", + "endDate = \"2024-05-31\"\n", + "url = f\"{URL_BASE}?startDate={startDate}&endDate={endDate}&api_key={API_KEY}\" # TU CÓDIGO AQUÍ\n", + "\n", + "# Completa la llamada — usa timeout=15\n", + "respuesta = requests.get(url, timeout=15) # TU CÓDIGO AQUÍ\n", + "\n", + "# Verifica que la respuesta fue exitosa antes de parsear el JSON\n", + "# Hint: usa respuesta.ok o compara respuesta.status_code con 200\n", + "# Hint: si hay error, imprime el código y el cuerpo — respuesta.text tiene el mensaje\n", + "if not respuesta.ok: # TU CÓDIGO AQUÍ — condición de error\n", + " print(f\"Error {respuesta.status_code}: {respuesta.text}\") # TU CÓDIGO AQUÍ — mensaje informativo\n", + " raise SystemExit(\"No se pudo obtener la respuesta. Intenta de nuevo.\")\n", + "\n", + "tormentas = respuesta.json()\n", + "print(f\"Solicitud exitosa ✓ — {len(tormentas)} tormentas recibidas\")" + ] + }, + { + "cell_type": "markdown", + "id": "ej1-url-warning", + "metadata": {}, + "source": [ + "> ⚠️ **Cuidado con exponer tu API key** \n", + "> Puedes descomentar el `print` de la celda siguiente para verificar que la URL se formó correctamente, pero **vuelve a comentarlo antes de guardar y entregar el notebook**. Si lo dejas activo, tu API key quedará visible en el output del archivo." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ej1-url-check", + "metadata": {}, + "outputs": [], + "source": [ + "# Descomenta la siguiente línea para verificar que la URL se formó correctamente.\n", + "# ⚠ Vuelve a comentarla antes de entregar — el output guarda tu API key en el archivo.\n", + "\n", + "# print(\"URL:\", url)" + ] + }, + { + "cell_type": "markdown", + "id": "ej1b-md", + "metadata": {}, + "source": [ + "### Parte b) — Explorar la lista de tormentas (10 pts)\n", + "\n", + "Usando un ciclo `for`, imprime cuántas tormentas hubo en el período y el `gstID` y `startTime` de cada una." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ej1b-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total de tormentas en el período: 5\n", + "ID: 2024-05-02T15:00:00-GST-001 | Inicio: 2024-05-02T15:00Z\n", + "ID: 2024-05-10T15:00:00-GST-001 | Inicio: 2024-05-10T15:00Z\n", + "ID: 2024-05-12T21:00:00-GST-001 | Inicio: 2024-05-12T21:00Z\n", + "ID: 2024-05-16T06:00:00-GST-001 | Inicio: 2024-05-16T06:00Z\n", + "ID: 2024-05-17T18:00:00-GST-001 | Inicio: 2024-05-17T18:00Z\n" + ] + } + ], + "source": [ + "# Hint: len(tormentas) da el total de eventos\n", + "# Hint: cada elemento de tormentas es un dict — accede con tormenta[\"gstID\"], etc.\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "print(f\"Total de tormentas en el período: {len(tormentas)}\")\n", + "\n", + "# Recorrer cada tormenta\n", + "for tormenta in tormentas:\n", + " gst_id = tormenta.get(\"gstID\", \"N/A\")\n", + " start_time = tormenta.get(\"startTime\", \"N/A\")\n", + " \n", + " print(f\"ID: {gst_id} | Inicio: {start_time}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ej2-md", + "metadata": {}, + "source": [ + "---\n", + "## Ejercicio 2 — Kp máximo por tormenta (20 pts)\n", + "\n", + "Cada tormenta contiene una lista `allKpIndex` con múltiples mediciones a lo largo del tiempo.\n", + "\n", + "**a) (10 pts)** Para cada tormenta, encuentra el **valor máximo de Kp** usando un ciclo `for` sobre `allKpIndex`. Imprime el `startTime` y el Kp máximo de cada tormenta.\n", + "\n", + "**b) (10 pts)** Encuentra e imprime la tormenta **más intensa** del período (la que tuvo el mayor Kp máximo entre todas las tormentas)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ej2-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 2024-05-02T15:00Z Kp máx = 6.67\n", + " 2024-05-10T15:00Z Kp máx = 9.00\n", + " 2024-05-12T21:00Z Kp máx = 6.33\n", + " 2024-05-16T06:00Z Kp máx = 6.00\n", + " 2024-05-17T18:00Z Kp máx = 6.00\n", + "\n", + "Tormenta más intensa:\n", + "Inicio: 2024-05-10T15:00Z\n", + "Kp máximo global: 9.00\n" + ] + } + ], + "source": [ + "# ── Parte a) ──────────────────────────────────────────────────────────────────\n", + "# Hint: allKpIndex es una lista de dicts, cada uno con la clave \"kpIndex\"\n", + "# Hint: para encontrar el máximo de una lista puedes usar la función max()\n", + "# o un ciclo que compare con una variable auxiliar (kp_max = 0)\n", + "\n", + "for tormenta in tormentas:\n", + " # TU CÓDIGO AQUÍ — obtener el kp máximo de esta tormenta\n", + " kp_max = 0\n", + " for medicion in tormenta.get(\"allKpIndex\", []):\n", + " kp = medicion.get(\"kpIndex\", 0)\n", + " if kp > kp_max:\n", + " kp_max = kp\n", + "\n", + " print(f\" {tormenta['startTime']} Kp máx = {kp_max:.2f}\")\n", + "\n", + "# ── Parte b) ──────────────────────────────────────────────────────────────────\n", + "# Hint: necesitas dos variables auxiliares:\n", + "# tormenta_mas_intensa = None\n", + "# kp_global_max = 0\n", + "# Recorre todas las tormentas y actualiza estas variables cuando encuentres un Kp mayor\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "tormenta_mas_intensa = None\n", + "kp_global_max = 0\n", + "for tormenta in tormentas:\n", + " kp_max = 0\n", + " for medicion in tormenta.get(\"allKpIndex\", []):\n", + " kp = medicion.get(\"kpIndex\", 0)\n", + " if kp > kp_max:\n", + " kp_max = kp\n", + " if kp_max > kp_global_max:\n", + " kp_global_max = kp_max\n", + " tormenta_mas_intensa = tormenta\n", + "if tormenta_mas_intensa:\n", + " print(\"\\nTormenta más intensa:\")\n", + " print(f\"Inicio: {tormenta_mas_intensa['startTime']}\")\n", + " print(f\"Kp máximo global: {kp_global_max:.2f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ej3-md", + "metadata": {}, + "source": [ + "---\n", + "## Ejercicio 3 — Clasificar la severidad con condicionales (25 pts)\n", + "\n", + "**a) (15 pts)** Escribe una función `clasificar_kp(kp)` que reciba un valor de Kp (float) y retorne una cadena con la categoría según la tabla del contexto:\n", + "- Kp < 4 → `\"Quieto\"`\n", + "- Kp == 4 → `\"Activo\"`\n", + "- Kp == 5 → `\"G1 - Menor\"`\n", + "- Kp == 6 → `\"G2 - Moderada\"`\n", + "- Kp == 7 → `\"G3 - Fuerte\"`\n", + "- Kp == 8 → `\"G4 - Severa\"`\n", + "- Kp >= 9 → `\"G5 - Extrema\"`\n", + "\n", + "> **Nota:** el índice Kp puede ser decimal (ej. 8.67). Usa `int(kp)` para redondear hacia abajo y comparar.\n", + "\n", + "**b) (10 pts)** Usa tu función para imprimir una tabla con cada tormenta, su Kp máximo y su categoría." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ej3-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " kp=2.00 → Quieto\n", + " kp=4.00 → Activo\n", + " kp=5.33 → G1 - Menor\n", + " kp=6.67 → G2 - Moderada\n", + " kp=7.00 → G3 - Fuerte\n", + " kp=8.67 → G4 - Severa\n", + " kp=9.00 → G5 - Fuerte\n", + "\n", + "Fecha inicio Kp máx Categoría\n", + "--------------------------------------------------\n", + "2024-05-02T15:00Z 6.67 G2 - Moderada\n", + "2024-05-10T15:00Z 9.00 G5 - Fuerte\n", + "2024-05-12T21:00Z 6.33 G2 - Moderada\n", + "2024-05-16T06:00Z 6.00 G2 - Moderada\n", + "2024-05-17T18:00Z 6.00 G2 - Moderada\n" + ] + } + ], + "source": [ + "# ── Parte a) ──────────────────────────────────────────────────────────────────\n", + "# Hint: usa if / elif / else\n", + "# Hint: int(8.67) == 8 — esto te permite usar comparaciones exactas con enteros\n", + "\n", + "def clasificar_kp(kp):\n", + " \"\"\"Clasifica la intensidad de una tormenta según el índice Kp.\"\"\"\n", + " # TU CÓDIGO AQUÍ\n", + " kp = int(kp) # redondea hacia abajo\n", + " \n", + " if kp < 4:\n", + " return \"Quieto\"\n", + " elif kp == 4:\n", + " return \"Activo\"\n", + " elif kp == 5:\n", + " return \"G1 - Menor\"\n", + " elif kp == 6:\n", + " return \"G2 - Moderada\"\n", + " elif kp == 7:\n", + " return \"G3 - Fuerte\"\n", + " elif kp == 8:\n", + " return \"G4 - Severa\"\n", + " else: # kp >= 9\n", + " return \"G5 - Fuerte\"\n", + "\n", + "\n", + "# Prueba tu función con estos valores — verifica que los resultados son correctos:\n", + "for kp_prueba in [2.0, 4.0, 5.33, 6.67, 7.0, 8.67, 9.0]:\n", + " print(f\" kp={kp_prueba:.2f} → {clasificar_kp(kp_prueba)}\")\n", + "\n", + "# ── Parte b) ──────────────────────────────────────────────────────────────────\n", + "print(f\"\\n{'Fecha inicio':<22} {'Kp máx':>7} {'Categoría'}\")\n", + "print(\"-\" * 50)\n", + "\n", + "# TU CÓDIGO AQUÍ — recorre tormentas, calcula kp_max, llama clasificar_kp()\n", + "for tormenta in tormentas:\n", + " kp_max = 0\n", + " for medicion in tormenta.get(\"allKpIndex\", []):\n", + " kp = medicion.get(\"kpIndex\", 0)\n", + " if kp > kp_max:\n", + " kp_max = kp\n", + " categoria = clasificar_kp(kp_max)\n", + " print(f\"{tormenta['startTime']:<22} {kp_max:>7.2f} {categoria}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ej4-md", + "metadata": {}, + "source": [ + "---\n", + "## Ejercicio 4 — Función de análisis completa (35 pts)\n", + "\n", + "Escribe una función `analizar_tormenta(tormenta)` que reciba **un evento** de la lista `tormentas` y retorne un **diccionario** con las siguientes claves:\n", + "\n", + "| Clave | Valor esperado |\n", + "|---|---|\n", + "| `\"id\"` | el `gstID` del evento |\n", + "| `\"inicio\"` | el `startTime` |\n", + "| `\"kp_max\"` | el valor Kp más alto entre todas las mediciones |\n", + "| `\"kp_min\"` | el valor Kp más bajo entre todas las mediciones |\n", + "| `\"kp_promedio\"` | promedio de todos los valores Kp (redondeado a 2 decimales) |\n", + "| `\"num_mediciones\"` | cuántas mediciones hay en `allKpIndex` |\n", + "| `\"categoria\"` | resultado de llamar `clasificar_kp(kp_max)` |\n", + "| `\"eventos_vinculados\"` | número de eventos en `linkedEvents` (0 si es `None`) |\n", + "\n", + "Luego aplícala a **todas las tormentas** con un ciclo `for` e imprime un resumen de cada una." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ej4-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ID: 2024-05-02T15:00:00-GST-001\n", + "Inicio: 2024-05-02T15:00Z\n", + "Kp Máx: 6.67\n", + "Kp Mín: 6.67\n", + "Kp Promedio: 6.67\n", + "Número de mediciones: 2\n", + "Categoría: G2 - Moderada\n", + "Eventos vinculados: 2\n", + "----------------------------------------\n", + "ID: 2024-05-10T15:00:00-GST-001\n", + "Inicio: 2024-05-10T15:00Z\n", + "Kp Máx: 9.0\n", + "Kp Mín: 6.67\n", + "Kp Promedio: 8.13\n", + "Número de mediciones: 13\n", + "Categoría: G5 - Fuerte\n", + "Eventos vinculados: 6\n", + "----------------------------------------\n", + "ID: 2024-05-12T21:00:00-GST-001\n", + "Inicio: 2024-05-12T21:00Z\n", + "Kp Máx: 6.33\n", + "Kp Mín: 5.67\n", + "Kp Promedio: 6.0\n", + "Número de mediciones: 3\n", + "Categoría: G2 - Moderada\n", + "Eventos vinculados: 2\n", + "----------------------------------------\n", + "ID: 2024-05-16T06:00:00-GST-001\n", + "Inicio: 2024-05-16T06:00Z\n", + "Kp Máx: 6.0\n", + "Kp Mín: 6.0\n", + "Kp Promedio: 6.0\n", + "Número de mediciones: 1\n", + "Categoría: G2 - Moderada\n", + "Eventos vinculados: 1\n", + "----------------------------------------\n", + "ID: 2024-05-17T18:00:00-GST-001\n", + "Inicio: 2024-05-17T18:00Z\n", + "Kp Máx: 6.0\n", + "Kp Mín: 6.0\n", + "Kp Promedio: 6.0\n", + "Número de mediciones: 1\n", + "Categoría: G2 - Moderada\n", + "Eventos vinculados: 2\n", + "----------------------------------------\n" + ] + } + ], + "source": [ + "def analizar_tormenta(tormenta):\n", + " \"\"\"\n", + " Analiza un evento de tormenta geomagnética.\n", + " \n", + " Parámetro:\n", + " tormenta (dict): un elemento de la lista retornada por el endpoint GST.\n", + " \n", + " Retorna:\n", + " dict con las claves: id, inicio, kp_max, kp_min, kp_promedio,\n", + " num_mediciones, categoria, eventos_vinculados.\n", + " \"\"\"\n", + " mediciones = tormenta[\"allKpIndex\"]\n", + "\n", + " kp_valores = [m[\"kpIndex\"] for m in mediciones]\n", + " resultado = {\n", + " \"id\": tormenta[\"gstID\"],\n", + " \"inicio\": tormenta[\"startTime\"],\n", + " \"kp_max\": max(kp_valores),\n", + " \"kp_min\": min(kp_valores),\n", + " \"kp_promedio\": round(sum(kp_valores) / len(kp_valores), 2),\n", + " \"num_mediciones\": len(mediciones),\n", + " \"categoria\": clasificar_kp(max(kp_valores)),\n", + " \"eventos_vinculados\": len(tormenta[\"linkedEvents\"] or []),\n", + " }\n", + " return resultado\n", + "\n", + "\n", + "# Aplicar a todas las tormentas e imprimir resumen\n", + "for tormenta in tormentas:\n", + " r = analizar_tormenta(tormenta)\n", + " # Hint: accede a cada clave del dict retornado con r[\"clave\"]\n", + " # TU CÓDIGO AQUÍ — imprime los campos de r de forma legible\n", + " print(f\"ID: {r['id']}\")\n", + " print(f\"Inicio: {r['inicio']}\")\n", + " print(f\"Kp Máx: {r['kp_max']}\")\n", + " print(f\"Kp Mín: {r['kp_min']}\")\n", + " print(f\"Kp Promedio: {r['kp_promedio']}\")\n", + " print(f\"Número de mediciones: {r['num_mediciones']}\")\n", + " print(f\"Categoría: {r['categoria']}\")\n", + " print(f\"Eventos vinculados: {r['eventos_vinculados']}\")\n", + " print(\"-\" * 40)" + ] + }, + { + "cell_type": "markdown", + "id": "conclusion-md", + "metadata": {}, + "source": [ + "---\n", + "## Pregunta final — Conclusiones (incluida en el punteo del Ejercicio 4)\n", + "\n", + "Basandote en los datos que obtuviste a lo largo del examen, escribe en la celda de abajo \n", + "una conclusion en tus propias palabras. Puedes responder estas preguntas como guia:\n", + "\n", + "- ¿Cual fue la tormenta mas intensa del periodo analizado y que tan severa fue segun la escala Kp?\n", + "- ¿Que patrones observas en los datos? (frecuencia, intensidad, eventos vinculados)\n", + "- ¿Que impacto podria haber tenido una tormenta de esa magnitud en la vida cotidiana?" + ] + }, + { + "cell_type": "markdown", + "id": "conclusion-answer", + "metadata": {}, + "source": [ + "**Conclusiones:**\n", + "\n", + "1. La tormenta mas intensa fue Inicio:2024-05-10T15:00Z con un Kp maximo de 9.00 y su clasificacion G5-Fuerte. Su kp es el valor maximo posible lo que implica que fue una tormenta geomagnetica extrema\n", + "2. Frecuencia :Se registraron 5 tormentas en un periodo de 15 dias, esto significa una alta activida geomagnetica. Tambien que hay una concentracion clara entre 10 y el 17 de mayor.\n", + "Intensidad: 4 de las 5 tormantas fueron G2 con kp de 6.00 a 6.67, solo hubo una tormenta intesa de clasificacion G5. Esto implica una actividad moderada\n", + "Eventos vinculados: La tormenta mas intensa tiene un mayor numero de mediciones que en total son 13 y de cantidad de eventos vinculados 6 en total. La tormentas moderadas tienen solamente entr 1 o 2 eventos.\n", + "3. Una tormenta nivel G5-Fuerte podria haber causado interrupciones en los sistemas de navegacion (GPS),apagones, Auroras visibles en latitudes inusualmente bajas y fallos en equipos " + ] + }, + { + "cell_type": "markdown", + "id": "sello-md", + "metadata": {}, + "source": [ + "---\n", + "## Sello de entrega\n", + "\n", + "Ejecuta la siguiente celda **como ultimo paso**, justo antes de guardar y subir el notebook.\n", + "\n", + "Realiza una consulta a la API de la ISS para registrar tu posicion geografica aproximada \n", + "al momento de entregar. Dado que la ISS se desplaza ~30 km cada 4 segundos, dos estudiantes \n", + "que entreguen en momentos distintos obtendran coordenadas completamente diferentes.\n", + "\n", + "> Este sello es **unico e irrepetible**: queda vinculado a tu carnet y al instante \n", + "> exacto en que ejecutaste la celda." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "sello-code", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Consultando posicion de la ISS...\n", + "\n", + "=======================================================\n", + " SELLO DE ENTREGA -- PARCIAL 2\n", + "=======================================================\n", + " Estudiante : Brandom Rodriguez\n", + " Carnet : 202506893\n", + " Fecha/Hora : 2026-04-25 00:40:26 UTC\n", + " ISS Latitud : -40.0224 deg\n", + " ISS Longitud : -61.6840 deg\n", + " ISS Hora UTC : 2026-04-25 00:40:24 UTC\n", + "=======================================================\n" + ] + } + ], + "source": [ + "from datetime import datetime, timezone\n", + "\n", + "# Obtener la posicion actual de la ISS\n", + "print(\"Consultando posicion de la ISS...\")\n", + "try:\n", + " r_iss = requests.get(\"http://api.open-notify.org/iss-now.json\", timeout=8)\n", + " r_iss.raise_for_status()\n", + " iss_data = r_iss.json()\n", + " iss_lat = float(iss_data[\"iss_position\"][\"latitude\"])\n", + " iss_lon = float(iss_data[\"iss_position\"][\"longitude\"])\n", + " iss_ts = iss_data[\"timestamp\"]\n", + " iss_hora = datetime.fromtimestamp(iss_ts, tz=timezone.utc).strftime(\"%Y-%m-%d %H:%M:%S UTC\")\n", + " iss_ok = True\n", + "except Exception as e:\n", + " iss_lat, iss_lon, iss_hora = 0.0, 0.0, \"no disponible\"\n", + " iss_ok = False\n", + " print(f\" Advertencia: no se pudo obtener la posicion ISS ({e})\")\n", + "\n", + "# Timestamp local del momento de entrega\n", + "ts_entrega = datetime.now(tz=timezone.utc).strftime(\"%Y-%m-%d %H:%M:%S UTC\")\n", + "\n", + "# Imprimir el sello\n", + "print()\n", + "print(\"=\" * 55)\n", + "print(\" SELLO DE ENTREGA -- PARCIAL 2\")\n", + "print(\"=\" * 55)\n", + "print(f\" Estudiante : {NOMBRE}\")\n", + "print(f\" Carnet : {CARNET}\")\n", + "print(f\" Fecha/Hora : {ts_entrega}\")\n", + "print(f\" ISS Latitud : {iss_lat:+.4f} deg\")\n", + "print(f\" ISS Longitud : {iss_lon:+.4f} deg\")\n", + "print(f\" ISS Hora UTC : {iss_hora}\")\n", + "print(\"=\" * 55)\n", + "\n", + "if not iss_ok:\n", + " print(\" Advertencia: sello generado sin datos de ISS (sin conexion).\")\n", + " print(\" Guarda el notebook de todas formas.\")" + ] + }, + { + "cell_type": "markdown", + "id": "cierre", + "metadata": {}, + "source": [ + "---\n", + "## Entrega\n", + "\n", + "1. Ejecuta la celda **Sello de entrega** (arriba)\n", + "2. Guarda el notebook: **Archivo → Guardar** (o `Ctrl+S`)\n", + "3. Verifica que **todas las celdas tienen output** (ejecuta: **Kernel → Restart & Run All**)\n", + "4. Sube el archivo a Github y copia el link en el campo de entrega en la U Virtual" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e9a231d-3229-4072-92d4-bac281a69979", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tareas/examen/import.py b/tareas/examen/import.py new file mode 100644 index 0000000..458084c --- /dev/null +++ b/tareas/examen/import.py @@ -0,0 +1,16 @@ +import os +import requests +import json +import time + +# Cargar la API key desde la variable de entorno. +# Si no está configurada, usa DEMO_KEY como respaldo (30 req/hora). +API_KEY = os.getenv("NASA_API_KEY", "").strip() or "DEMO_KEY" + +if API_KEY == "DEMO_KEY": + print(" Usando DEMO_KEY - limite: 30 solicitudes/hora") + print(" Configura NASA_API_KEY para mayor limite (ver instrucciones arriba).") +else: + print(f" API key cargada: {API_KEY[:4]}{'*' * (len(API_KEY) - 4)}") + +print("\nLibrerias importadas correctamente ") diff --git a/tareas/prueba.tex b/tareas/prueba.tex new file mode 100644 index 0000000..4fbd3ba --- /dev/null +++ b/tareas/prueba.tex @@ -0,0 +1,5 @@ +\documentclass[options]{article} + +\begin{document} +hola mundo! +\end{document} \ No newline at end of file diff --git a/tareas/python/1.Hola Mundo y Print()/Ejercicio 1a.py b/tareas/python/1.Hola Mundo y Print()/Ejercicio 1a.py new file mode 100644 index 0000000..e34f410 --- /dev/null +++ b/tareas/python/1.Hola Mundo y Print()/Ejercicio 1a.py @@ -0,0 +1,2 @@ +print("Nombre: Brandom Aroldo Rodriguez Gonzalez") +print("Cartnet: 202506893") \ No newline at end of file diff --git a/tareas/python/1.Hola Mundo y Print()/Ejercicio 1b.py b/tareas/python/1.Hola Mundo y Print()/Ejercicio 1b.py new file mode 100644 index 0000000..ce39771 --- /dev/null +++ b/tareas/python/1.Hola Mundo y Print()/Ejercicio 1b.py @@ -0,0 +1,3 @@ +print("Hola ", end="") +print("desde ", end="") +print("python", end="") \ No newline at end of file diff --git a/tareas/python/10. Manejo de errores/Ejercicio 10a.py b/tareas/python/10. Manejo de errores/Ejercicio 10a.py new file mode 100644 index 0000000..62575fe --- /dev/null +++ b/tareas/python/10. Manejo de errores/Ejercicio 10a.py @@ -0,0 +1,13 @@ +def entero(n): + try: + resultado = int(n) + return resultado + except ValueError: + print("Error: No se puede convertir a entero") + return None + finally: + print(f"[intento con: {n}]") +print(entero("42")) +print(entero("3.14")) +print(entero("hola")) +print(entero(100)) \ No newline at end of file diff --git a/tareas/python/10. Manejo de errores/Ejercicio 10b.py b/tareas/python/10. Manejo de errores/Ejercicio 10b.py new file mode 100644 index 0000000..2a61a67 --- /dev/null +++ b/tareas/python/10. Manejo de errores/Ejercicio 10b.py @@ -0,0 +1,15 @@ +def v_n(n): + if not isinstance(n, int): + raise TypeError("La edad debe ser un entero") + if n < 0 or n > 150: + raise ValueError("La edad debe estar entre 0 y 150") + return True +x = [25, -5, 200, "veinte"] +for v in x: + try: + y = v_n(v) + print(f"{v} -> Edad valida:", y) + except TypeError as te: + print(f"{v} -> TypeError:", te) + except ValueError as ve: + print(f"{v} -> ValueError:", ve) \ No newline at end of file diff --git a/tareas/python/2.Variables y tipos de datos/Ejercicio 2a.py b/tareas/python/2.Variables y tipos de datos/Ejercicio 2a.py new file mode 100644 index 0000000..e8203ef --- /dev/null +++ b/tareas/python/2.Variables y tipos de datos/Ejercicio 2a.py @@ -0,0 +1,10 @@ +#variables +Nombre= "Brandom Aroldo Rodriguez Gonzalez" +Edad= int(21) +Promedio = float(72) +activo= bool(True) + +print("Nombre "+ str(Nombre) + type(Nombre).__name__) +print("Edad " + str(Edad) + type(Edad).__name__) +print("Promedio " + str(Promedio)+ type(Promedio).__name__) +print("activo " + str(activo) + type(activo).__name__) diff --git a/tareas/python/2.Variables y tipos de datos/Ejercicio 2b.py b/tareas/python/2.Variables y tipos de datos/Ejercicio 2b.py new file mode 100644 index 0000000..0838f46 --- /dev/null +++ b/tareas/python/2.Variables y tipos de datos/Ejercicio 2b.py @@ -0,0 +1,7 @@ +x= int(10) +y= int(20) +z= int(30) + +print(f"x=",x, end=" ") +print(f"y=",y, end=" ") +print(f"z=",z, end=" ") \ No newline at end of file diff --git "a/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3a.py" "b/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3a.py" new file mode 100644 index 0000000..4b78f45 --- /dev/null +++ "b/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3a.py" @@ -0,0 +1,5 @@ +a = int(23) +b = int(7) +print("Diviion: " +str(a/b)) +print("Residuo: " +str(a%b)) +print("a^b: " + str(a**b)) \ No newline at end of file diff --git "a/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3b.py" "b/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3b.py" new file mode 100644 index 0000000..074d258 --- /dev/null +++ "b/tareas/python/3.Operaciones aritm\303\251ticas/Ejercicio 3b.py" @@ -0,0 +1,9 @@ +import math +x=int(144) +print("La raiz cuadrada de 144 es: " + str( math.sqrt(x))) +y=int(7.3) +print("El techo de 7.3 es: " + str(math.ceil(y))) +z=int(7.9) +print("El piso de 7.9: " + str(math.floor(z))) +A= math.pi +print("El valor de pi redondeado a 4 decimales: " + str(round(A,4)) ) \ No newline at end of file diff --git "a/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4a.py" "b/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4a.py" new file mode 100644 index 0000000..5542dd6 --- /dev/null +++ "b/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4a.py" @@ -0,0 +1,13 @@ +cadena= " fisica y matematicas " + +x=cadena.strip() + +print("Paso 1: " + x) + +y=x.upper() + +print("Paso 2: " + y) + +z=y.replace("Y","&") + +print("Paso 3: " + z) \ No newline at end of file diff --git "a/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4b.py" "b/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4b.py" new file mode 100644 index 0000000..fa00c31 --- /dev/null +++ "b/tareas/python/4.Strings y m\303\251todos \303\272tiles/Ejercicio 4b.py" @@ -0,0 +1,10 @@ +colores_str = "rojo-verde-azul-amarillo" +x = colores_str.split("-") + +print("paso 1: "+ str(x)) + +y=" | ".join(x) + +print("Paso 2: " + str(y)) + +print("verde" in y) \ No newline at end of file diff --git a/tareas/python/5.Listas/Ejercicio 5a.py b/tareas/python/5.Listas/Ejercicio 5a.py new file mode 100644 index 0000000..95b9337 --- /dev/null +++ b/tareas/python/5.Listas/Ejercicio 5a.py @@ -0,0 +1,6 @@ +x = ["Calculo", "Fisica", "Programacion", "Algebra"] +x.append("Estadistica") +x.insert(1, "Quimica") +x.remove("Algebra") +print("Lista final:", x) +print("Longitud:", len(x)) \ No newline at end of file diff --git a/tareas/python/5.Listas/Ejercicio 5b.py b/tareas/python/5.Listas/Ejercicio 5b.py new file mode 100644 index 0000000..5ad86d5 --- /dev/null +++ b/tareas/python/5.Listas/Ejercicio 5b.py @@ -0,0 +1,11 @@ +notas = [78, 92, 65, 88, 74, 95, 61, 83] + +minimo = min(notas) +maximo = max(notas) +suma = sum(notas) +promedio = suma / len(notas) + +print(f"Minimo: {minimo}") +print(f"Maximo: {maximo}") +print(f"Suma: {suma}") +print(f"Promedio: {promedio:.2f}") \ No newline at end of file diff --git a/tareas/python/6.Diccionarios/Ejercicio 6a.py b/tareas/python/6.Diccionarios/Ejercicio 6a.py new file mode 100644 index 0000000..b83e79b --- /dev/null +++ b/tareas/python/6.Diccionarios/Ejercicio 6a.py @@ -0,0 +1,11 @@ + +curso = { + "nombre": "Programación", + "codigo": "1505", + "creditos": 10, + "activo": True +} + +curso["estudiantes"] = 35 +print("Creditos:", curso.get("creditos")) +print("Salon:", curso.get("salon", "Sin asignar")) \ No newline at end of file diff --git a/tareas/python/6.Diccionarios/Ejercicio 6b.py b/tareas/python/6.Diccionarios/Ejercicio 6b.py new file mode 100644 index 0000000..8e66483 --- /dev/null +++ b/tareas/python/6.Diccionarios/Ejercicio 6b.py @@ -0,0 +1,11 @@ + +curso = { + "nombre": "Programacion", + "codigo": "1505", + "creditos": 10, + "activo": True, + "estudiantes": 35 +} + +for clave, valor in curso.items(): + print(f"{clave:12} : {valor}") \ No newline at end of file diff --git a/tareas/python/7.Condicionales/Ejercicio 7a.py b/tareas/python/7.Condicionales/Ejercicio 7a.py new file mode 100644 index 0000000..5a09dcb --- /dev/null +++ b/tareas/python/7.Condicionales/Ejercicio 7a.py @@ -0,0 +1,15 @@ +def clasificar_imc(imc): + if imc<=18: + return "Bajo peso" + elif 19<=imc<=25 : + return "Normal" + elif 26<=imc<=29: + return "Sobrepeso" + elif 30<=imc: + return "Obesidad" +try: + imc_usuario = float(input("Ingresa tu IMC: ")) + resultado = clasificar_imc(imc_usuario) + print(f"Clasificacion: {resultado}") +except ValueError: + print("Ingresa un número valido.") \ No newline at end of file diff --git a/tareas/python/7.Condicionales/Ejercicio 7b.py b/tareas/python/7.Condicionales/Ejercicio 7b.py new file mode 100644 index 0000000..f04bb11 --- /dev/null +++ b/tareas/python/7.Condicionales/Ejercicio 7b.py @@ -0,0 +1,5 @@ +numeros = [4, 7, 0] + +for n in numeros: + resultado = "par" if n % 2 == 0 else "impar" + print(f"{n} es {resultado}") \ No newline at end of file diff --git a/tareas/python/8.Ciclos/Ejercicio 8a.py b/tareas/python/8.Ciclos/Ejercicio 8a.py new file mode 100644 index 0000000..2e1b4c0 --- /dev/null +++ b/tareas/python/8.Ciclos/Ejercicio 8a.py @@ -0,0 +1,4 @@ +planetas = ["Mercurio", "Venus", "Tierra", "Marte", "Jupiter", "Saturno", "Urano", "Neptuno"] + +for i, planeta in enumerate(planetas, start=1): + print(f"[{i}] {planeta}") \ No newline at end of file diff --git a/tareas/python/8.Ciclos/Ejercicio 8b.py b/tareas/python/8.Ciclos/Ejercicio 8b.py new file mode 100644 index 0000000..4f2c5a5 --- /dev/null +++ b/tareas/python/8.Ciclos/Ejercicio 8b.py @@ -0,0 +1,5 @@ +i = 1 + +while i <= 10: + print(f"7 x {i} = {7 * i}") + i += 1 \ No newline at end of file diff --git a/tareas/python/8.Ciclos/Ejercicio 8c.py b/tareas/python/8.Ciclos/Ejercicio 8c.py new file mode 100644 index 0000000..c308848 --- /dev/null +++ b/tareas/python/8.Ciclos/Ejercicio 8c.py @@ -0,0 +1,2 @@ +print([x**3 for x in range(1, 9)]) +print([x for x in range(1, 31) if x % 3 == 0 and x % 9 != 0]) \ No newline at end of file diff --git a/tareas/python/9.Funciones/Ejercicio 9a.py b/tareas/python/9.Funciones/Ejercicio 9a.py new file mode 100644 index 0000000..8340514 --- /dev/null +++ b/tareas/python/9.Funciones/Ejercicio 9a.py @@ -0,0 +1,11 @@ +def convertir_t(g, e="C"): + if e == "C": + return g * 9/5 + 32 + elif e == "F": + return (g - 32) * 5/9 + else: + return "Escala no válida" +print("100°C ->", convertir_t(100, "C"), "°F") +print("0°C ->", convertir_t(0, "C"), "°F") +print("32°F ->", convertir_t(32, "F"), "°C") +print("212°F ->", convertir_t(212, "F"), "°C") \ No newline at end of file diff --git a/tareas/python/9.Funciones/Ejercicio 9b.py b/tareas/python/9.Funciones/Ejercicio 9b.py new file mode 100644 index 0000000..32f3975 --- /dev/null +++ b/tareas/python/9.Funciones/Ejercicio 9b.py @@ -0,0 +1,10 @@ +def r_l(l): + minimo = min(l) + maximo = max(l) + promedio = sum(l) / len(l) + return minimo, maximo, promedio +n = [12, 45, 7, 89, 34, 56, 23] +minimo, maximo, promedio = r_l(n) +print("Minimo:", minimo) +print("Maximo:", maximo) +print("Promedio:", promedio) \ No newline at end of file diff --git a/tareas/python/9.Funciones/Ejercicio 9c.py b/tareas/python/9.Funciones/Ejercicio 9c.py new file mode 100644 index 0000000..629be9b --- /dev/null +++ b/tareas/python/9.Funciones/Ejercicio 9c.py @@ -0,0 +1,9 @@ +def fibonacci(n): + if n == 0: + return 0 + elif n == 1: + return 1 + else: + return fibonacci(n-1) + fibonacci(n-2) +for i in range(11): + print(f"fibonacci({i}) = {fibonacci(i)}") \ No newline at end of file diff --git a/tareas/python/Ejercicio integrador/Ejercicio integrador.py b/tareas/python/Ejercicio integrador/Ejercicio integrador.py new file mode 100644 index 0000000..ef67b33 --- /dev/null +++ b/tareas/python/Ejercicio integrador/Ejercicio integrador.py @@ -0,0 +1,32 @@ +def a(e): + aprobados = 0 + reprobados = 0 + print(f"{'Nombre':<15} {'Promedio':<10} {'Estado'}") + for alumno in e: + nombre = alumno["nombre"] + n = alumno["notas"] + if n: + p = sum(n) / len(n) + else: + p = None + if p is None: + estado = "Sin notas" + elif p >= 61: + estado = "Aprobado" + aprobados += 1 + else: + estado = "Reprobado" + reprobados += 1 + p_str = f"{p:.2f}" if p is not None else "N/A" + print(f"{nombre:<15} {p_str:<10} {estado}") + print(f"Aprobados: {aprobados}") + print(f"Reprobados: {reprobados}") +c = [ + {"nombre": "Ana Lopez", "notas": [85, 90, 78, 92]}, + {"nombre": "Carlos Ruiz", "notas": [55, 48, 60, 52]}, + {"nombre": "Maria Paz", "notas": [70, 75, 68, 80]}, + {"nombre": "Luis Gomez", "notas": [95, 98, 100, 92]}, + {"nombre": "Sara Diaz", "notas": [40, 55, 50, 45]}, + {"nombre": "Pedro Alva", "notas": []}, +] +a(c) \ No newline at end of file diff --git a/tareas/python/Numpy/Tarea 4_NumPy.ipynb b/tareas/python/Numpy/Tarea 4_NumPy.ipynb new file mode 100644 index 0000000..2c1f351 --- /dev/null +++ b/tareas/python/Numpy/Tarea 4_NumPy.ipynb @@ -0,0 +1,1595 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NumPy — Computación Numérica en Python\n", + "\n", + "## ¿Qué es NumPy?\n", + "\n", + "**NumPy** (Numerical Python) es la librería fundamental para computación científica en Python. Proporciona:\n", + "\n", + "- Un objeto de arreglo (array) multidimensional de alto rendimiento\n", + "- Herramientas para trabajar con estos arreglos\n", + "- Funciones matemáticas, lógicas, de ordenamiento, estadísticas, y más\n", + "\n", + "## ¿Para qué sirve?\n", + "\n", + "| Tarea | Sin NumPy | Con NumPy |\n", + "|---|---|---|\n", + "| Sumar dos listas de 1 millón de elementos | ~0.5 segundos | ~0.005 segundos |\n", + "| Multiplicar matrices | Código complejo con loops | Una línea |\n", + "| Operaciones matemáticas | Loop por cada elemento | Operaciones vectorizadas |\n", + "\n", + "NumPy es la base de casi todas las librerías de ciencia de datos: Pandas, Matplotlib, Scikit-learn, etc." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Instalación e Importación\n", + "\n", + "Para instalar NumPy (si no está instalado):\n", + "```bash\n", + "pip install numpy\n", + "```\n", + "\n", + "Por convención, se importa con el alias `np`:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NumPy versión: 2.3.5\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "print(\"NumPy versión:\", np.__version__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 1 — Conceptos Básicos: Arrays" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ¿Qué diferencia hay entre una lista de Python y un array de NumPy?" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lista Python: [1, 2, 3, 4, 5]\n", + "Tipo: \n", + "\n", + "Array NumPy: [1 2 3 4 5]\n", + "Tipo: \n" + ] + } + ], + "source": [ + "# Lista de Python\n", + "lista = [1, 2, 3, 4, 5]\n", + "print(\"Lista Python:\", lista)\n", + "print(\"Tipo:\", type(lista))\n", + "\n", + "print()\n", + "\n", + "# Array de NumPy\n", + "arreglo = np.array([1, 2, 3, 4, 5])\n", + "print(\"Array NumPy:\", arreglo)\n", + "print(\"Tipo:\", type(arreglo))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lista * 3: [1, 2, 3, 1, 2, 3, 1, 2, 3]\n", + "Array * 3: [3 6 9]\n" + ] + } + ], + "source": [ + "# La diferencia clave: operaciones elemento a elemento\n", + "lista_python = [1, 2, 3]\n", + "\n", + "# Con listas, el operador * repite la lista\n", + "print(\"Lista * 3:\", lista_python * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]\n", + "\n", + "arreglo_np = np.array([1, 2, 3])\n", + "\n", + "# Con NumPy, * multiplica cada elemento\n", + "print(\"Array * 3:\", arreglo_np * 3) # [3, 6, 9]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### ¿Por qué NumPy es tan rápido? — Comparación de rendimiento\n", + "\n", + "NumPy implementa las operaciones sobre arrays en **código C precompilado**. La misma operación que requiere un ciclo `for` en Python se ejecuta internamente sin ciclos explícitos. Esto se conoce como *código vectorizado* (Stewart & Mommert, §4.1)." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lista Python : 1.046 segundos\n", + "Array NumPy : 0.017 segundos\n", + "NumPy es 61× más rápido\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "N = 10_000_000 # 10 millones de elementos\n", + "\n", + "# ── Enfoque con lista Python ──────────────────────────────────────────────────\n", + "a_lista = list(range(N))\n", + "t0 = time.time()\n", + "b_lista = []\n", + "for i in range(len(a_lista)):\n", + " b_lista.append(a_lista[i] + 1)\n", + "t_lista = time.time() - t0\n", + "\n", + "# ── Enfoque con array NumPy ───────────────────────────────────────────────────\n", + "a_np = np.array(a_lista)\n", + "t0 = time.time()\n", + "b_np = a_np + 1 # ← una sola línea, sin ciclo explícito\n", + "t_numpy = time.time() - t0\n", + "\n", + "print(f\"Lista Python : {t_lista:.3f} segundos\")\n", + "print(f\"Array NumPy : {t_numpy:.3f} segundos\")\n", + "print(f\"NumPy es {t_lista / t_numpy:.0f}× más rápido\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Crear arrays de diferentes formas" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ceros: [0. 0. 0. 0. 0.]\n", + "Unos : [1. 1. 1. 1. 1.]\n", + "Vacío: [1. 1. 1. 1. 1.]\n", + "\n", + "Arange (0 a 10, paso 2): [0 2 4 6 8]\n", + "Linspace (6 puntos entre 0 y 1): [0. 0.2 0.4 0.6 0.8 1. ]\n", + "Logspace (10^0 a 10^3): [ 1. 10. 100. 1000.]\n", + "\n", + "zeros_like(base): [0 0 0 0 0]\n", + "ones_like(base) : [1 1 1 1 1]\n" + ] + } + ], + "source": [ + "# Array de ceros y unos\n", + "ceros = np.zeros(5)\n", + "unos = np.ones(5)\n", + "vacio = np.empty(5) # sin inicializar — muy rápido, valores arbitrarios\n", + "print(\"Ceros:\", ceros)\n", + "print(\"Unos :\", unos)\n", + "print(\"Vacío:\", vacio)\n", + "\n", + "# Array con rango (como range(), pero retorna array)\n", + "rango = np.arange(0, 10, 2) # inicio, fin (exclusivo), paso\n", + "print(\"\\nArange (0 a 10, paso 2):\", rango)\n", + "\n", + "# N valores igualmente espaciados — escala lineal\n", + "espacio = np.linspace(0, 1, 6) # inicio, fin (inclusivo), N puntos\n", + "print(\"Linspace (6 puntos entre 0 y 1):\", espacio)\n", + "\n", + "# N valores en escala logarítmica (base 10 por defecto)\n", + "log_esp = np.logspace(0, 3, 4) # 10^0 a 10^3, 4 valores\n", + "print(\"Logspace (10^0 a 10^3):\", log_esp)\n", + "\n", + "# Constructores \"look-alike\": misma forma que otro array\n", + "base = np.array([1, 2, 3, 4, 5])\n", + "print(\"\\nzeros_like(base):\", np.zeros_like(base))\n", + "print(\"ones_like(base) :\", np.ones_like(base))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(5,)\n", + "1\n" + ] + } + ], + "source": [ + "print(base.shape)\n", + "print(base.ndim)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Arrays 2D (matrices)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matriz:\n", + "[[1 2 3]\n", + " [4 5 6]\n", + " [7 8 9]]\n", + "\n", + "Forma (filas x columnas): (3, 3)\n", + "Número de dimensiones: 2\n", + "Total de elementos: 9\n", + "Tipo de dato: int64\n" + ] + } + ], + "source": [ + "# Crear una matriz 2D\n", + "matriz = np.array([\n", + " [1, 2, 3],\n", + " [4, 5, 6],\n", + " [7, 8, 9]\n", + "])\n", + "\n", + "print(\"Matriz:\")\n", + "print(matriz)\n", + "print(\"\\nForma (filas x columnas):\", matriz.shape)\n", + "print(\"Número de dimensiones:\", matriz.ndim)\n", + "print(\"Total de elementos:\", matriz.size)\n", + "print(\"Tipo de dato:\", matriz.dtype)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tipos de datos (`dtype`) y atributos del array\n", + "\n", + "Todos los elementos de un array NumPy tienen el **mismo tipo de dato** (`dtype`). NumPy infiere el tipo al crear el array, pero puedes especificarlo. Tipos comunes: `int64`, `float64`, `complex128`, `bool`. Puedes convertir con `.astype()` (Stewart & Mommert, §4.1.1)." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dtype inferido: float64\n", + "dtype=int : [1 2 3] → int64\n", + "dtype=complex: [1.+0.j 2.+0.j 3.+0.j] → complex128\n", + "\n", + "x_int.astype(float): [1. 2. 3.] → float64\n", + "\n", + "Array m:\n", + "[[1 2 3]\n", + " [4 5 6]]\n", + " ndim : 2\n", + " shape: (2, 3)\n", + " size : 6\n", + " dtype: int64\n" + ] + } + ], + "source": [ + "x = np.array([1, 2, 3.268999]) # Python convierte todo a float64\n", + "print(\"dtype inferido:\", x.dtype)\n", + "\n", + "# Especificar dtype manualmente\n", + "x_int = np.array([1.5566666666, 2, 3], dtype=int)\n", + "x_cpx = np.array([1, 2, 3], dtype=complex)\n", + "print(\"dtype=int :\", x_int, \"→\", x_int.dtype)\n", + "print(\"dtype=complex:\", x_cpx, \"→\", x_cpx.dtype)\n", + "\n", + "# Convertir dtype con astype()\n", + "x_float = x_int.astype(float)\n", + "print(\"\\nx_int.astype(float):\", x_float, \"→\", x_float.dtype)\n", + "\n", + "# Atributos importantes de un array\n", + "m = np.array([[1, 2, 3], [4, 5, 6]])\n", + "print(\"\\nArray m:\")\n", + "print(m)\n", + "print(\" ndim :\", m.ndim) # número de dimensiones\n", + "print(\" shape:\", m.shape) # (filas, columnas)\n", + "print(\" size :\", m.size) # total de elementos\n", + "print(\" dtype:\", m.dtype) # tipo de dato" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 2 — Indexación y Operaciones" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Acceder a elementos (indexación)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Arreglo: [10 20 30 40 50]\n", + "Primer elemento (índice 0): 10\n", + "Último elemento: 50\n", + "Elementos del índice 1 al 3: [20 30 40]\n", + "Cada dos elementos: [10 30 50]\n" + ] + } + ], + "source": [ + "v = np.array([10, 20, 30, 40, 50])\n", + "\n", + "print(\"Arreglo:\", v)\n", + "print(\"Primer elemento (índice 0):\", v[0])\n", + "print(\"Último elemento:\", v[-1])\n", + "print(\"Elementos del índice 1 al 3:\", v[1:4])\n", + "print(\"Cada dos elementos:\", v[::2])" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matriz:\n", + "[[1 2 3]\n", + " [4 5 6]\n", + " [7 8 9]]\n", + "\n", + "Elemento fila 0, columna 1: 2\n", + "Toda la primera fila: [1 2 3]\n", + "Toda la segunda columna: [2 5 8]\n", + "\n", + "Submatriz (filas 0-1, columnas 1-2):\n", + "[[2 3]\n", + " [5 6]]\n" + ] + } + ], + "source": [ + "# Indexación en matrices 2D\n", + "m = np.array([\n", + " [1, 2, 3],\n", + " [4, 5, 6],\n", + " [7, 8, 9]\n", + "])\n", + "\n", + "print(\"Matriz:\")\n", + "print(m)\n", + "print(\"\\nElemento fila 0, columna 1:\", m[0, 1]) # 2\n", + "print(\"Toda la primera fila:\", m[0, :]) # [1, 2, 3]\n", + "print(\"Toda la segunda columna:\", m[:, 1]) # [2, 5, 8]\n", + "print(\"\\nSubmatriz (filas 0-1, columnas 1-2):\")\n", + "print(m[0:2, 1:3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Indexación booleana (filtrado)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[72 88 91 78]\n", + "Todas las notas: [55 72 88 45 91 63 78]\n", + "Notas > 70: [72 88 91 78]\n", + "Cantidad de aprobados: 4\n", + "Notas en zona (61-70): [63]\n" + ] + } + ], + "source": [ + "notas = np.array([55, 72, 88, 45, 91, 63, 78])\n", + "\n", + "print(notas[notas > 70])\n", + "# ¿Cuáles notas son mayores de 70?\n", + "aprobados = notas[notas > 70]\n", + "print(\"Todas las notas:\", notas)\n", + "print(\"Notas > 70:\", aprobados)\n", + "print(\"Cantidad de aprobados:\", aprobados.shape[0])\n", + "\n", + "# Condición compuesta\n", + "zona = notas[(notas >= 61) & (notas <= 70)]\n", + "print(\"Notas en zona (61-70):\", zona)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operaciones matemáticas" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a + b = [11 22 33 44]\n", + "a * b = [ 10 40 90 160]\n", + "b / a = [10. 10. 10. 10.]\n", + "a ** 2 = [ 1 4 9 16]\n", + "\n", + "Raíz cuadrada de b: [3.16227766 4.47213595 5.47722558 6.32455532]\n", + "e^a: [ 2.71828183 7.3890561 20.08553692 54.59815003]\n" + ] + } + ], + "source": [ + "a = np.array([1, 2, 3, 4])\n", + "b = np.array([10, 20, 30, 40])\n", + "\n", + "print(\"a + b =\", a + b)\n", + "print(\"a * b =\", a * b)\n", + "print(\"b / a =\", b / a)\n", + "print(\"a ** 2 =\", a ** 2) # Elevar al cuadrado\n", + "print(\"\\nRaíz cuadrada de b:\", np.sqrt(b))\n", + "print(\"e^a:\", np.exp(a))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Broadcasting — reglas para operar arrays de distinta forma\n", + "\n", + "Cuando aplicas una operación entre un array y un escalar (o dos arrays de forma distinta), NumPy ajusta los tamaños automáticamente siguiendo **dos reglas** (Stewart & Mommert, §4.1.4):\n", + "\n", + "1. **Regla 1** — Si los arrays tienen distinto número de dimensiones, la forma del más pequeño se *extiende* a la izquierda con \"1\" hasta igualar.\n", + "2. **Regla 2** — Un eje de tamaño 1 se comporta como si tuviera el tamaño del eje más grande en esa dimensión (se \"replica\").\n", + "\n", + "```\n", + "array → [1, 2, 3, 4, 5] forma: (5,)\n", + "escalar → 10 forma: () → (1,) → (5,) [reglas 1 y 2]\n", + "resultado→ [11, 12, 13, 14, 15]\n", + "```\n", + "\n", + "Si dos ejes no son 1 y son distintos entre sí → **ValueError** (no se puede hacer broadcast)." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Array original: [1 2 3 4 5]\n", + "v + 10 : [11 12 13 14 15]\n", + "v * 3 : [ 3 6 9 12 15]\n", + "v ** 2 : [ 1 4 9 16 25]\n", + "v / 2 : [0.5 1. 1.5 2. 2.5]\n", + "v - 1 : [0 1 2 3 4]\n", + "\n", + "Matriz + 100:\n", + "[[101 102 103]\n", + " [104 105 106]]\n", + "\n", + "Matriz * 2:\n", + "[[ 2 4 6]\n", + " [ 8 10 12]]\n" + ] + } + ], + "source": [ + "v = np.array([1, 2, 3, 4, 5])\n", + "\n", + "print(\"Array original:\", v)\n", + "print(\"v + 10 :\", v + 10) # suma 10 a cada elemento\n", + "print(\"v * 3 :\", v * 3) # multiplica cada elemento por 3\n", + "print(\"v ** 2 :\", v ** 2) # eleva al cuadrado cada elemento\n", + "print(\"v / 2 :\", v / 2) # divide cada elemento entre 2\n", + "print(\"v - 1 :\", v - 1)\n", + "\n", + "# También funciona con matrices\n", + "m = np.array([[1, 2, 3],\n", + " [4, 5, 6]])\n", + "print(\"\\nMatriz + 100:\")\n", + "print(m + 100)\n", + "print(\"\\nMatriz * 2:\")\n", + "print(m * 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Funciones matemáticas (ufuncs)\n", + "\n", + "NumPy tiene versiones de las funciones matemáticas de `math` que funcionan directamente sobre **arrays completos** sin necesidad de un ciclo `for`. Estas se llaman *ufuncs* (universal functions)." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x : [0 1 2 3 4 5]\n", + "np.sqrt(x) : [0. 1. 1.41421356 1.73205081 2. 2.23606798]\n", + "np.exp(x) : [ 1. 2.71828183 7.3890561 20.08553692 54.59815003\n", + " 148.4131591 ]\n", + "np.log(x+1): [0. 0.69314718 1.09861229 1.38629436 1.60943791 1.79175947]\n", + "np.abs(x-3): [3 2 1 0 1 2]\n", + "np.sign(x-3): [-1 -1 -1 0 1 1]\n" + ] + } + ], + "source": [ + "x = np.array([0, 1, 2, 3, 4, 5])\n", + "\n", + "print(\"x :\", x)\n", + "print(\"np.sqrt(x) :\", np.sqrt(x)) # raíz cuadrada de cada elemento\n", + "print(\"np.exp(x) :\", np.exp(x)) # e^x\n", + "print(\"np.log(x+1):\", np.log(x + 1)) # logaritmo natural (evitamos log(0))\n", + "print(\"np.abs(x-3):\", np.abs(x - 3)) # valor absoluto\n", + "print(\"np.sign(x-3):\", np.sign(x - 3)) # -1, 0 o 1 según el signo" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ángulos (rad): [0. 0.5236 0.7854 1.0472 1.5708]\n", + "sin : [0. 0.5 0.7071 0.866 1. ]\n", + "cos : [1. 0.866 0.7071 0.5 0. ]\n", + "\n", + "Velocidad vertical (v0=10): [ 0. 5. 7.071 8.66 10. ]\n" + ] + } + ], + "source": [ + "# Funciones trigonométricas (el argumento está en radianes)\n", + "angulos = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])\n", + "\n", + "print(\"Ángulos (rad):\", angulos.round(4))\n", + "print(\"sin :\", np.sin(angulos).round(4))\n", + "print(\"cos :\", np.cos(angulos).round(4))\n", + "\n", + "# Caso práctico: calcular la componente vertical de lanzamientos\n", + "# con distintos ángulos y velocidad inicial v0 = 10 m/s\n", + "v0 = 10\n", + "v_vertical = v0 * np.sin(angulos)\n", + "print(\"\\nVelocidad vertical (v0=10):\", v_vertical.round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 3b — Valores especiales y operadores lógicos\n", + "\n", + "### Valores especiales: `nan` e `inf`\n", + "\n", + "Algunas operaciones producen resultados especiales:\n", + "- `np.nan` (*Not a Number*): resultado indefinido, como `log(-1)` o `0/0`\n", + "- `np.inf` (*infinito*): resultado de dividir un número entre cero\n", + "\n", + "NumPy tiene versiones de las funciones estadísticas que **ignoran** los `nan`:\n", + "`np.nanmean`, `np.nansum`, `np.nanmax`, `np.nanmin`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"np.pi =\", np.pi)\n", + "print(\"np.e =\", np.e)\n", + "print(\"np.inf =\", np.inf)\n", + "print(\"np.nan =\", np.nan)\n", + "\n", + "# nan aparece en operaciones indefinidas\n", + "x = np.array([-4.0, -1.0, 0.0, 1.0, 4.0])\n", + "print(\"\\nsqrt de\", x, \"→\", np.sqrt(x)) # sqrt de negativos → nan\n", + "\n", + "# Funciones que ignoran nan\n", + "notas = np.array([85.0, np.nan, 72.0, np.nan, 91.0])\n", + "print(\"\\nNotas con nan:\", notas)\n", + "print(\"Media normal :\", np.mean(notas)) # ← devuelve nan\n", + "print(\"Media sin nan :\", np.nanmean(notas)) # ← ignora nan\n", + "print(\"Suma sin nan :\", np.nansum(notas))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operadores lógicos sobre arrays\n", + "\n", + "Puedes comparar un array con un valor y obtienes un array de booleanos (`True`/`False`).\n", + "Luego ese array booleano puede usarse como filtro para seleccionar elementos." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "temps = np.array([18.5, 22.0, 35.1, 15.3, 28.7, 12.0, 30.0])\n", + "\n", + "# Comparación → array de True/False\n", + "print(\"Temperaturas:\", temps)\n", + "print(\"temps > 25 :\", temps > 25)\n", + "\n", + "# Usar el array booleano para filtrar\n", + "calurosos = temps[temps > 25]\n", + "print(\"\\nDías calurosos (> 25°C):\", calurosos)\n", + "\n", + "# Condición compuesta: & (y) , | (o)\n", + "moderados = temps[(temps >= 20) & (temps <= 30)]\n", + "print(\"Días moderados (20-30°C):\", moderados)\n", + "\n", + "# Contar cuántos cumplen la condición\n", + "print(\"\\n¿Cuántos días > 25?:\", np.sum(temps > 25))\n", + "print(\"¿Algún día < 10? :\", np.any(temps < 10))\n", + "print(\"¿Todos > 10? :\", np.all(temps > 10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### `np.where` — asignar valores según condición\n", + "\n", + "`np.where(condición, valor_si_True, valor_si_False)` crea un array nuevo aplicando una regla a cada elemento. Es el equivalente vectorizado del operador ternario." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "notas = np.array([55, 72, 88, 45, 91, 63, 78])\n", + "\n", + "# Etiquetar cada nota como \"Aprobado\" o \"Reprobado\"\n", + "estados = np.where(notas >= 61, \"Aprobado\", \"Reprobado\")\n", + "\n", + "for n, e in zip(notas, estados):\n", + " print(f\" Nota {n:3d} → {e}\")\n", + "\n", + "# También funciona con números\n", + "# Reemplazar notas menores a 61 con 0 (para penalización)\n", + "penalizadas = np.where(notas >= 61, notas, 0)\n", + "print(\"\\nNotas penalizadas:\", penalizadas)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Copias vs Vistas (*views*) — diferencia crítica con listas\n", + "\n", + "En NumPy existen **tres comportamientos** distintos al \"asignar\" un array:\n", + "\n", + "| Operación | Resultado | Modifica original |\n", + "|---|---|---|\n", + "| `b = a` | **alias** — misma memoria | Sí |\n", + "| `b = a[1:4]` | **vista** (*view*) — misma memoria | **Sí** ⚠️ |\n", + "| `b = a.copy()` | **copia** — memoria nueva | No |\n", + "\n", + "> **¡Diferencia clave con listas!** En Python, `l[1:4]` es siempre una copia. En NumPy, `a[1:4]` es una **vista** del array original — modificarla cambia el original. Esto es fuente frecuente de errores (Stewart & Mommert, §4.1.2)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "original = np.array([1, 2, 3, 4, 5])\n", + "\n", + "# ⚠ ALIAS — dos nombres, un solo array\n", + "alias = original\n", + "alias[0] = 999\n", + "print(\"Alias modifica 'original':\", original)\n", + "\n", + "# ⚠ VISTA (slice) — ¡diferente a listas Python!\n", + "original2 = np.array([1, 2, 3, 4, 5])\n", + "vista = original2[1:4] # NO es copia — es vista\n", + "vista[0] = 777\n", + "print(\"Slice (vista) modifica 'original2':\", original2)\n", + "\n", + "# ✅ COPIA independiente — usa .copy()\n", + "original3 = np.array([1, 2, 3, 4, 5])\n", + "copia = original3.copy()\n", + "copia[0] = 999\n", + "print(\"Copia NO modifica 'original3':\", original3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Unir arrays — concatenate, hstack, vstack, stack\n", + "\n", + "NumPy ofrece varias formas de unir arrays (Stewart & Mommert, §4.1.5):\n", + "\n", + "- `np.concatenate()`: función **general** — une a lo largo de un eje existente.\n", + "- `np.hstack()`: atajo para unir **horizontalmente** (eje 1 en 2D, eje 0 en 1D).\n", + "- `np.vstack()`: atajo para unir **verticalmente** (eje 0).\n", + "- `np.stack()`: apila creando un **nuevo eje**." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = np.array([1, 2, 3])\n", + "b = np.array([4, 5, 6])\n", + "\n", + "# Función general: np.concatenate\n", + "print(\"concatenate:\", np.concatenate((a, b)))\n", + "print(\"hstack :\", np.hstack((a, b))) # equivalente para 1D\n", + "\n", + "# Para matrices\n", + "m1 = np.array([[1, 2], [3, 4]])\n", + "m2 = np.array([[5, 6], [7, 8]])\n", + "\n", + "print(\"\\nvstack (apilar filas, axis=0):\")\n", + "print(np.vstack((m1, m2)))\n", + "\n", + "print(\"\\nhstack (unir columnas, axis=1):\")\n", + "print(np.hstack((m1, m2)))\n", + "\n", + "print(\"\\nstack — crea NUEVO eje (shape resultante: 2×2×2):\")\n", + "apilado = np.stack((m1, m2), axis=0)\n", + "print(apilado)\n", + "print(\"Shape:\", apilado.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ordenar y buscar — `np.sort` y `np.argsort`\n", + "\n", + "- `np.sort(x)` — retorna una **copia ordenada** (no modifica `x`).\n", + "- `np.argsort(x)` — retorna los **índices** que ordenarían `x`. Muy útil para ordenar arrays relacionados (e.g., ordenar nombres por nota) (Stewart & Mommert, §4.2.5)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "notas = np.array([78, 45, 92, 61, 88, 34, 73])\n", + "print(\"Notas originales:\", notas)\n", + "\n", + "# np.sort — retorna una copia ordenada (no modifica el original)\n", + "print(\"Ordenadas (asc) :\", np.sort(notas))\n", + "print(\"Ordenadas (desc):\", np.sort(notas)[::-1])\n", + "\n", + "# np.argsort — retorna los ÍNDICES que ordenarían el array\n", + "indices = np.argsort(notas)\n", + "print(\"\\nÍndices (argsort):\", indices)\n", + "print(\"Aplicando índices :\", notas[indices]) # equivale a sort\n", + "\n", + "# Caso práctico: obtener ranking de estudiantes\n", + "nombres = np.array([\"Ana\", \"Carlos\", \"Diana\", \"Eduardo\", \"Fátima\", \"Gabriel\", \"Helena\"])\n", + "ranking = np.argsort(notas)[::-1] # mayor a menor\n", + "print(\"\\nRanking:\")\n", + "for pos, i in enumerate(ranking, 1):\n", + " print(f\" {pos}. {nombres[i]}: {notas[i]}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Suma acumulativa — `np.cumsum`\n", + "\n", + "`np.cumsum` calcula la suma acumulada: cada elemento del resultado es la suma de todos los anteriores más el actual. Útil para calcular totales progresivos (gastos, puntajes acumulados, etc.)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "puntos_por_nivel = np.array([100, 250, 180, 320, 210])\n", + "\n", + "print(\"Puntos por nivel :\", puntos_por_nivel)\n", + "print(\"Puntos acumulados :\", np.cumsum(puntos_por_nivel))\n", + "\n", + "# Ejemplo: gastos diarios y total acumulado\n", + "gastos = np.array([50, 120, 30, 85, 200, 45])\n", + "print(\"\\nGastos diarios :\", gastos)\n", + "print(\"Total acumulado :\", np.cumsum(gastos))\n", + "print(\"Total de la semana :\", np.sum(gastos))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 3 — Estadística y Álgebra Lineal" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Funciones estadísticas" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datos = np.array([23, 45, 12, 67, 34, 89, 56, 78, 90, 11])\n", + "\n", + "print(\"Datos:\", datos)\n", + "print(\"\\n--- Estadísticas ---\")\n", + "print(f\"Mínimo: {np.min(datos)}\")\n", + "print(f\"Máximo: {np.max(datos)}\")\n", + "print(f\"Suma: {np.sum(datos)}\")\n", + "print(f\"Media (promedio): {np.mean(datos):.2f}\")\n", + "print(f\"Mediana: {np.median(datos):.2f}\")\n", + "print(f\"Desviación estándar: {np.std(datos):.2f}\")\n", + "print(f\"Varianza: {np.var(datos):.2f}\")\n", + "print(f\"\\nÍndice del máximo: {np.argmax(datos)}\")\n", + "print(f\"Índice del mínimo: {np.argmin(datos)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Estadísticas avanzadas — histograma, media ponderada, correlación\n", + "\n", + "- `np.histogram(x, bins)` — distribución de frecuencias (retorna conteo y bordes).\n", + "- `np.average(x, weights=w)` — **media ponderada** (cada dato tiene un peso diferente).\n", + "- `np.corrcoef(x, y)` — **coeficiente de correlación** de Pearson entre dos arrays.\n", + "- **API moderna de números aleatorios**: usar `default_rng(semilla)` en lugar de `np.random.seed()` (Stewart & Mommert, §4.4)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from numpy.random import default_rng\n", + "rng = default_rng(42) # semilla para reproducibilidad\n", + "\n", + "# Generar datos con distribución normal (media=70, desv=10)\n", + "calificaciones = rng.normal(loc=70, scale=10, size=200).clip(0, 100)\n", + "\n", + "# np.histogram — distribución de frecuencias\n", + "conteo, bordes = np.histogram(calificaciones, bins=10)\n", + "print(\"Conteo por intervalo:\", conteo)\n", + "print(\"Bordes de intervalos:\", bordes.round(1))\n", + "\n", + "# Media ponderada: notas con distintos pesos\n", + "mediciones = np.array([3.1, 2.7, 2.5, 3.1, 2.9])\n", + "incertidumbres = np.array([0.05, 0.15, 0.60, 0.10, 0.05])\n", + "print(\"\\nMedia simple :\", np.mean(mediciones).round(4))\n", + "print(\"Media ponderada :\", np.average(mediciones, weights=1/incertidumbres**2).round(4))\n", + "# Pesos = 1/σ² → mayor peso a mediciones más precisas\n", + "\n", + "# Correlación entre dos arrays\n", + "x = np.array([1, 2, 3, 4, 5])\n", + "y = np.array([2.1, 3.9, 6.2, 7.8, 10.1])\n", + "print(\"\\nCoeficiente de correlación Pearson:\")\n", + "print(np.corrcoef(x, y).round(4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reshape — cambiar la forma de un array" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Crear un arreglo de 12 elementos y reorganizarlo\n", + "v = np.arange(1, 13)\n", + "print(\"Arreglo original:\", v)\n", + "print(\"Forma:\", v.shape)\n", + "\n", + "# Convertir a matriz 3x4\n", + "m = v.reshape(3, 4)\n", + "print(\"\\nReorganizado a 3x4:\")\n", + "print(m)\n", + "\n", + "# Convertir a matriz 2x6\n", + "print(\"\\nReorganizado a 2x6:\")\n", + "print(v.reshape(2, 6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Multiplicación de matrices y operaciones esenciales\n", + "\n", + "| Operación | Sintaxis | Descripción |\n", + "|---|---|---|\n", + "| Elemento a elemento | `A * B` | Hadamard product |\n", + "| Matricial | `A @ B` o `np.matmul(A, B)` | Producto matricial |\n", + "| Transpuesta | `A.T` o `np.transpose(A)` | Intercambia filas↔columnas |\n", + "| Identidad | `np.identity(n)` | Matriz identidad n×n |\n", + "| Aplanar | `A.ravel()` o `np.ravel(A)` | Convierte a vector 1D |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A = np.array([[1, 2], [3, 4]])\n", + "B = np.array([[5, 6], [7, 8]])\n", + "\n", + "print(\"A * B (elemento a elemento):\")\n", + "print(A * B)\n", + "\n", + "print(\"\\nA @ B (multiplicación matricial):\")\n", + "print(A @ B)\n", + "\n", + "print(\"\\nA.T (transpuesta):\")\n", + "print(A.T)\n", + "\n", + "print(\"\\nnp.identity(3) — matriz identidad:\")\n", + "print(np.identity(3))\n", + "\n", + "# Aplanar una matriz a vector 1D\n", + "print(\"\\nA.ravel() — aplanar a 1D:\", A.ravel())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 3d — Álgebra Lineal (`numpy.linalg`)\n", + "\n", + "NumPy incluye el módulo `numpy.linalg` (importado como `la`) para operaciones matriciales avanzadas (Stewart & Mommert, §4.7):\n", + "\n", + "| Función | Descripción |\n", + "|---|---|\n", + "| `la.det(A)` | Determinante de A |\n", + "| `la.inv(A)` | Inversa de A (si det ≠ 0) |\n", + "| `la.norm(v)` | Norma euclidiana de un vector |\n", + "| `la.solve(A, b)` | Resuelve el sistema **Ax = b** |\n", + "| `la.eig(A)` | Eigenvalores y eigenvectores de A |\n", + "\n", + "> `la.solve(A, b)` es numéricamente más estable y eficiente que calcular `la.inv(A) @ b`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy.linalg as la\n", + "\n", + "A = np.array([[4, 2, 0],\n", + " [9, 3, 7],\n", + " [1, 2, 1]], dtype=float)\n", + "\n", + "print(\"Matriz A:\")\n", + "print(A)\n", + "\n", + "# Determinante\n", + "print(\"\\nDeterminante:\", la.det(A).round(4))\n", + "\n", + "# Inversa (si det ≠ 0)\n", + "A_inv = la.inv(A)\n", + "print(\"\\nInversa A⁻¹:\")\n", + "print(A_inv.round(4))\n", + "\n", + "# Verificación: A @ A⁻¹ debe ser la identidad\n", + "print(\"\\nA @ A⁻¹ (≈ identidad):\")\n", + "print((A @ A_inv).round(10))\n", + "\n", + "# Norma de un vector\n", + "v = np.array([3.0, 4.0])\n", + "print(\"\\nNorma del vector [3, 4]:\", la.norm(v)) # = 5.0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy.linalg as la\n", + "\n", + "# ─── Resolución de sistemas de ecuaciones: Ax = b ───────────────────────────\n", + "# Ejemplo: sistema de 3 ecuaciones\n", + "# 3x + 2y + z = 5\n", + "# 5x + 5y + 5z = 5\n", + "# x + 4y + 6z = -3\n", + "A = np.array([[3, 2, 1],\n", + " [5, 5, 5],\n", + " [1, 4, 6]], dtype=float)\n", + "b = np.array([5, 5, -3], dtype=float)\n", + "\n", + "x = la.solve(A, b)\n", + "print(\"Solución x:\", x.round(4))\n", + "print(\"Verificación Ax - b ≈ 0:\", (A @ x - b).round(10))\n", + "\n", + "# ─── Eigenvalores y eigenvectores ───────────────────────────────────────────\n", + "print(\"\\n--- Eigenvalores ---\")\n", + "M = np.array([[-2, -4, 2],\n", + " [-2, 1, 2],\n", + " [ 4, 2, 5]], dtype=float)\n", + "eigenvalores, eigenvectores = la.eig(M)\n", + "print(\"Eigenvalores:\", eigenvalores.round(3))\n", + "print(\"Primer eigenvector:\", eigenvectores[:, 0].round(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 3e — Polinomios\n", + "\n", + "NumPy permite representar polinomios por sus coeficientes y ofrece funciones para ajustar, evaluar y manipularlos (Stewart & Mommert, §4.6):\n", + "\n", + "- `np.polyfit(x, y, deg)` — ajusta un polinomio de grado `deg` a datos *(x, y)* por mínimos cuadrados. Retorna los coeficientes `[a_n, ..., a_1, a_0]`.\n", + "- `np.polyval(coefs, x)` — evalúa el polinomio con coeficientes `coefs` en los puntos `x`.\n", + "- `np.poly(roots)` — construye coeficientes desde las raíces.\n", + "- `np.roots(coefs)` — calcula las raíces a partir de los coeficientes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Datos: velocidad inicial vs distancia máxima (proyectil simplificado)\n", + "# Queremos ajustar un polinomio de grado 2: d = a*v^2 + b*v + c\n", + "v = np.array([10, 20, 30, 40, 50], dtype=float) # velocidad (m/s)\n", + "d = np.array([5.1, 20.4, 45.9, 81.6, 127.5]) # distancia (m)\n", + "\n", + "# np.polyfit: ajuste de mínimos cuadrados\n", + "coefs = np.polyfit(v, d, deg=2)\n", + "print(\"Coeficientes [a, b, c]:\", coefs.round(4))\n", + "print(f\"Modelo: d = {coefs[0]:.4f}·v² + {coefs[1]:.4f}·v + {coefs[2]:.4f}\")\n", + "\n", + "# np.polyval: evaluar el polinomio en nuevos valores\n", + "v_nuevo = np.array([25, 35, 45])\n", + "d_pred = np.polyval(coefs, v_nuevo)\n", + "print(\"\\nPredicciones:\")\n", + "for vi, di in zip(v_nuevo, d_pred):\n", + " print(f\" v={vi} m/s → d≈{di:.2f} m\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## Nivel 4 — Ejemplo Aplicado: Cálculo de Notas" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Simulación de notas de un curso\n", + "# Filas = estudiantes, Columnas = [Tarea1, Tarea2, Examen parcial, Examen final]\n", + "np.random.seed(42) # Para reproducibilidad\n", + "\n", + "notas = np.random.randint(40, 101, size=(8, 4))\n", + "pesos = np.array([0.15, 0.15, 0.30, 0.40]) # Pesos de cada evaluación\n", + "\n", + "nombres = [\"Ana\", \"Carlos\", \"Diana\", \"Eduardo\", \"Fátima\", \"Gabriel\", \"Helena\", \"Iván\"]\n", + "\n", + "print(\"Notas (Tarea1 | Tarea2 | Parcial | Final):\")\n", + "print(\"-\" * 50)\n", + "for nombre, fila in zip(nombres, notas):\n", + " print(f\"{nombre:<10} {fila}\")\n", + "\n", + "# Calcular nota final ponderada para cada estudiante\n", + "notas_finales = notas @ pesos\n", + "\n", + "print(\"\\n--- Resultados Finales ---\")\n", + "for nombre, nota in zip(nombres, notas_finales):\n", + " estado = \"APROBADO\" if nota >= 61 else \"REPROBADO\"\n", + " print(f\"{nombre:<10} Nota: {nota:.1f} → {estado}\")\n", + "\n", + "print(f\"\\nPromedio del curso: {np.mean(notas_finales):.2f}\")\n", + "print(f\"Nota más alta: {np.max(notas_finales):.2f}\")\n", + "print(f\"Nota más baja: {np.min(notas_finales):.2f}\")\n", + "print(f\"Aprobados: {np.sum(notas_finales >= 61)} / {len(notas_finales)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tarea 4 — NumPy en Práctica\n", + "\n", + "La programación se aprende haciendo, no leyendo. Esta tarea tiene dos partes:\n", + "\n", + "**Parte 1 — Descarga y ejecuta** (obligatorio)\n", + "Descarga este notebook y ejecútalo celda por celda en tu computadora. \n", + "Asegúrate de que todas las celdas corran sin errores antes de continuar.\n", + "\n", + "**Parte 2 — Ejercicios** (obligatorio) \n", + "Completa cada celda que dice `# TU CÓDIGO AQUÍ` con tu solución. \n", + "Ejecuta la celda para verificar que el resultado es correcto.\n", + "\n", + "**Entrega: 1 de mayo** \n", + "Sube el notebook a tu repositorio de GitHub y envía el **link directo al archivo `.ipynb`**.\n", + "El notebook debe tener todas las celdas ya ejecutadas (con outputs visibles).\n", + "\n", + "Ejemplo de link válido: \n", + "`https://github.com/tu-usuario/tu-repo/blob/main/Numpy.ipynb`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 1 — Crear y operar arrays\n", + "\n", + "Crea un array con los números del 1 al 10 usando `np.arange`. \n", + "Luego calcula e imprime:\n", + "- Cada número multiplicado por 5\n", + "- Solo los números pares (usa indexación booleana)\n", + "- La suma de todos los números" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Multiplicacion por 5: [ 5 10 15 20 25 30 35 40 45 50]\n", + "Numeros pares: [ 2 4 6 8 10]\n", + "Suma total: 55\n" + ] + } + ], + "source": [ + "# TU CÓDIGO AQUÍ\n", + "array = np.arange(1, 11)\n", + "multiplicacion=array*5\n", + "print(\"Multiplicacion por 5:\", multiplicacion)\n", + "pares=array[array % 2 == 0]\n", + "print(\"Numeros pares:\", pares)\n", + "suma = np.sum(array)\n", + "print(\"Suma total:\", suma)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 2 — Funciones matemáticas\n", + "\n", + "Dado el array de ángulos en grados, conviértelos a radianes y calcula su seno. \n", + "Fórmula: `radianes = grados * π / 180`\n", + "\n", + "Ángulos: 0°, 30°, 45°, 60°, 90°, 180°" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Radianes: [0. 0.52359878 0.78539816 1.04719755 1.57079633 3.14159265]\n", + "Senos: [0.00000000e+00 5.00000000e-01 7.07106781e-01 8.66025404e-01\n", + " 1.00000000e+00 1.22464680e-16]\n" + ] + } + ], + "source": [ + "grados = np.array([0, 30, 45, 60, 90, 180])\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "radianes= grados * np.pi/180\n", + "print(\"Radianes:\", radianes)\n", + "seno=np.sin(radianes)\n", + "print(\"Senos:\", seno)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 3 — Filtrado y estadísticas\n", + "\n", + "Dada la lista de temperaturas diarias de un mes, calcula:\n", + "1. La temperatura promedio, mínima y máxima\n", + "2. Cuántos días superaron los 28°C\n", + "3. Las temperaturas de los días fríos (menores a 20°C)\n", + "4. Reemplaza con `np.where` las temperaturas menores a 15°C por exactamente 15.0 (temperatura mínima registrada)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Promedio: 23.483333333333334\n", + "Minima: 12.4\n", + "maximo: 33.1\n", + "Dias > 28c: 8\n", + "Dias frios\n", + "Temperaturas modificadas\n" + ] + } + ], + "source": [ + "temperaturas = np.array([\n", + " 22.1, 19.5, 31.2, 28.0, 17.3, 25.8, 30.1,\n", + " 14.2, 26.7, 23.4, 18.9, 32.0, 29.5, 21.1,\n", + " 16.8, 27.3, 24.6, 13.5, 20.0, 28.9, 33.1,\n", + " 15.7, 22.8, 19.0, 31.5, 26.2, 18.1, 29.8,\n", + " 12.4, 25.0\n", + "])\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "promedio = np.mean(temperaturas)\n", + "minima = np.min(temperaturas)\n", + "maximo = np.max(temperaturas)\n", + "print(\"Promedio:\", promedio)\n", + "print(\"Minima:\", minima)\n", + "print(\"maximo:\", maximo)\n", + "dias = np.sum(temperaturas >28)\n", + "print(\"Dias > 28c:\", dias)\n", + "frio=temperaturas[temperaturas<20]\n", + "print(\"Dias frios\")\n", + "modificada = np.where(temperaturas <15, 15.0, temperaturas)\n", + "print(\"Temperaturas modificadas\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 4 — Matrices\n", + "\n", + "Crea una matriz de 4×4 con valores del 1 al 16 usando `np.arange` y `reshape`. \n", + "Luego:\n", + "1. Imprime la primera fila\n", + "2. Imprime la última columna\n", + "3. Imprime la submatriz de las 2 primeras filas y las 2 últimas columnas\n", + "4. Calcula la suma de cada fila (investiga `np.sum` con el parámetro `axis`)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matriz: \n", + " [[ 1 2 3 4]\n", + " [ 5 6 7 8]\n", + " [ 9 10 11 12]\n", + " [13 14 15 16]]\n", + "1ra fila: [1 2 3 4]\n", + "4ta columna [ 4 8 12 16]\n", + "Submatriz; \n", + " [[3 4]\n", + " [7 8]]\n", + "suma por filas: [10 26 42 58]\n" + ] + } + ], + "source": [ + "# TU CÓDIGO AQUÍ\n", + "matriz=np.arange(1,17).reshape(4,4)\n", + "print(\"Matriz: \\n\", matriz)\n", + "print(\"1ra fila:\", matriz[0])\n", + "print(\"4ta columna\", matriz[:,-1])\n", + "submatriz=matriz[:2,-2:]\n", + "print(\"Submatriz; \\n\", submatriz)\n", + "sumaf=np.sum(matriz, axis=1)\n", + "print(\"suma por filas:\" , sumaf)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 5 — Suma acumulativa\n", + "\n", + "Un estudiante anotó los puntos que obtuvo en cada una de las 8 tareas del curso. \n", + "Calcula e imprime los puntos acumulados después de cada tarea para saber en qué momento superó 100, 200 y 300 puntos.\n", + "\n", + "**Tip:** usa `np.cumsum` y filtra con indexación booleana." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Puntos acumulados: [ 45 83 135 164 225 272 327 360]\n", + "Supera 100 en tareas: 3\n", + "Supera 200 en tareas: 5\n", + "Supera 300 en tareas: 7\n" + ] + } + ], + "source": [ + "puntos_tareas = np.array([45, 38, 52, 29, 61, 47, 55, 33])\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "puntos_acumulados = np.cumsum(puntos_tareas)\n", + "print(\"Puntos acumulados:\", puntos_acumulados)\n", + "supera_100=np.where(puntos_acumulados>100)[0]\n", + "supera_200=np.where(puntos_acumulados>200)[0]\n", + "supera_300=np.where(puntos_acumulados>300)[0]\n", + "print(\"Supera 100 en tareas:\",supera_100[0]+1 if len(supera_100)>0 else \"No alcanza\")\n", + "print(\"Supera 200 en tareas:\",supera_200[0]+1 if len(supera_200)>0 else \"No alcanza\")\n", + "print(\"Supera 300 en tareas:\",supera_300[0]+1 if len(supera_300)>0 else \"No alcanza\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 6 — Álgebra Lineal\n", + "\n", + "El sistema de ecuaciones representa un balance de fuerzas en una estructura:\n", + "\n", + "$$2F_1 + F_2 = 100$$\n", + "$$F_1 + 3F_2 + F_3 = 200$$\n", + "$$F_2 + 2F_3 = 150$$\n", + "\n", + "Usando `numpy.linalg`:\n", + "1. Resuelve el sistema con `la.solve(A, b)` para encontrar $F_1$, $F_2$, $F_3$\n", + "2. Verifica la solución calculando `A @ x - b` (debe ser ≈ 0)\n", + "3. Calcula el determinante de A con `la.det(A)`\n", + "4. Calcula la norma de la solución `x` con `la.norm(x)`" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solucion [31.25 37.5 56.25]\n", + "Residuo: [0. 0. 0.]\n", + "Determinante: 8.000000000000002\n", + "Norma: 74.47734554883115\n" + ] + } + ], + "source": [ + "import numpy.linalg as la\n", + "\n", + "# Sistema de ecuaciones (balance de fuerzas en un puente):\n", + "# 2F1 + F2 = 100\n", + "# F1 + 3F2 + F3 = 200\n", + "# F2 + 2F3 = 150\n", + "\n", + "A = np.array([[2, 1, 0],\n", + " [1, 3, 1],\n", + " [0, 1, 2]], dtype=float)\n", + "b = np.array([100, 200, 150], dtype=float)\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "x=la.solve(A,b)\n", + "print(\"Solucion\", x)\n", + "residuo=A@x-b\n", + "print(\"Residuo:\", residuo)\n", + "detA=la.det(A)\n", + "print(\"Determinante:\", detA)\n", + "norma=la.norm(x)\n", + "print(\"Norma:\", norma)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ejercicio 7 — Polinomios (ajuste de curva)\n", + "\n", + "Un objeto en caída libre sigue la ecuación $x(t) = \\frac{1}{2}g t^2$.\n", + "\n", + "Con los datos de tiempo y posición dados, usa `np.polyfit` para ajustar un polinomio de grado 2 y:\n", + "1. Muestra los coeficientes obtenidos\n", + "2. Estima la aceleración de gravedad `g` a partir del coeficiente cuadrático\n", + "3. Usa `np.polyval` para predecir la posición en `t = 2.5` s y `t = 6` s\n", + "\n", + "**Pista:** el coeficiente de $t^2$ en el polinomio es $\\frac{g}{2}$." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Coeficientes a, b y c: [ 4.90000000e+00 2.87146301e-14 -3.66247436e-14]\n", + "gravedad: 9.799999999999988\n", + "t=2.5s: 30.625\n", + "t=6.0s: 176.39999999999992\n" + ] + } + ], + "source": [ + "t = np.array([0, 1, 2, 3, 4, 5], dtype=float) # tiempo (s)\n", + "pos = np.array([0.0, 4.9, 19.6, 44.1, 78.4, 122.5]) # posición (m)\n", + "\n", + "# TU CÓDIGO AQUÍ\n", + "coeficientes=np.polyfit(t,pos,2)\n", + "a, b, c=coeficientes\n", + "print(\"Coeficientes a, b y c:\", coeficientes)\n", + "g=2*a\n", + "print(\"gravedad:\", g)\n", + "p=np.poly1d(coeficientes)\n", + "print(\"t=2.5s:\", p(2.5))\n", + "print(\"t=6.0s:\", p(6))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.cpp b/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.cpp new file mode 100644 index 0000000..64590b6 --- /dev/null +++ b/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.cpp @@ -0,0 +1,42 @@ +#include +#include +using namespace std; +int busquedaDosEnDos(const vector& lista, int objetivo) { + int n = lista.size(); + for (int i = 0; i < n; i += 2) { + if (lista[i] == objetivo) { + return i; + } + if (i + 1 < n && lista[i + 1] == objetivo) { + return i + 1; + } + } + return -1; +} +int main() { + vector lista; + int n, x; + cout << "ingrese la cantidad de elementos: "; + cin >> n; + cout << "ingrese los elementos:\n"; + for (int i = 0; i < n; i++) { + cin >> x; + lista.push_back(x); + } + char continuar = 's'; + while (continuar == 's' || continuar == 'S') { + int objetivo; + cout << "\ningrese el numero a buscar: "; + cin >> objetivo; + int resultado = busquedaDosEnDos(lista, objetivo); + if (resultado != -1) { + cout << "objetivo encontrado en : " << resultado << endl; + } else { + cout << "objetivo no existe" << endl; + } + + cout << "\n desea buscar otro numero? (s/n): "; + cin >> continuar; + } + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.exe b/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.exe new file mode 100644 index 0000000..8c408ff Binary files /dev/null and b/tareas/tarea_3/busqueda_dos_en_dos/busqueda_dos_en_dos.exe differ diff --git a/tareas/tarea_3/busqueda_lineal/busqueda_lineal.cpp b/tareas/tarea_3/busqueda_lineal/busqueda_lineal.cpp new file mode 100644 index 0000000..d87031e --- /dev/null +++ b/tareas/tarea_3/busqueda_lineal/busqueda_lineal.cpp @@ -0,0 +1,47 @@ +#include +using namespace std; + +// --------- BUSQUEDA LINEAL --------- +int busquedaLineal(int arr[], int n, int valor) { + for (int i = 0; i < n; i++) { + if (arr[i] == valor) { + return i; // retorna la posición donde se encontró + } + } + return -1; // no encontrado +} + +// --------- MAIN --------- +int main() { + int n, valor; + char repetir; + + do { + cout << "\nCantidad de datos: "; + cin >> n; + + int arr[1000]; + + cout << "Ingrese los datos:\n"; + for (int i = 0; i < n; i++) { + cin >> arr[i]; + } + + cout << "\nIngrese el valor a buscar: "; + cin >> valor; + + int resultado = busquedaLineal(arr, n, valor); + + if (resultado != -1) { + cout << "Valor encontrado en la posicion: " << resultado << endl; + } else { + cout << "Valor no encontrado.\n"; + } + + cout << "\nDesea repetir? (s/n): "; + cin >> repetir; + + } while (repetir == 's' || repetir == 'S'); + + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/busqueda_lineal/busqueda_lineal.exe b/tareas/tarea_3/busqueda_lineal/busqueda_lineal.exe new file mode 100644 index 0000000..05e7485 Binary files /dev/null and b/tareas/tarea_3/busqueda_lineal/busqueda_lineal.exe differ diff --git a/tareas/tarea_3/contar_hasta_10/contar_hasta_10.cpp b/tareas/tarea_3/contar_hasta_10/contar_hasta_10.cpp new file mode 100644 index 0000000..32ca739 --- /dev/null +++ b/tareas/tarea_3/contar_hasta_10/contar_hasta_10.cpp @@ -0,0 +1,9 @@ +#include +using namespace std; + +int main() { + for (int i = 1; i <= 10; i++) { + cout << i << "\n"; + } + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/contar_hasta_10/contar_hasta_10.exe b/tareas/tarea_3/contar_hasta_10/contar_hasta_10.exe new file mode 100644 index 0000000..6167ba9 Binary files /dev/null and b/tareas/tarea_3/contar_hasta_10/contar_hasta_10.exe differ diff --git a/tareas/tarea_3/contar_vocales/contar_vocales.cpp b/tareas/tarea_3/contar_vocales/contar_vocales.cpp new file mode 100644 index 0000000..99a010d --- /dev/null +++ b/tareas/tarea_3/contar_vocales/contar_vocales.cpp @@ -0,0 +1,27 @@ +#include +using namespace std; +int contarVocales(string texto) { + int contar = 0; + for (char x : texto) { + x = tolower(x); + if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u') { + contar++; + } + } + return contar; +} +int main() { + string oracion; + char continuar; + do { + cout << "ingrese una oracion: "; + getline(cin, oracion); + int total = contarVocales(oracion); + cout << "total de vocales: " << total << endl; + cout << "desea ingresar otra oracion? (s/n): "; + cin >> continuar; + cin.ignore(); + } while (continuar == 's' || continuar == 'S'); + cout << "programa terminado." << endl; + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/contar_vocales/contar_vocales.exe b/tareas/tarea_3/contar_vocales/contar_vocales.exe new file mode 100644 index 0000000..28481c4 Binary files /dev/null and b/tareas/tarea_3/contar_vocales/contar_vocales.exe differ diff --git a/tareas/tarea_3/numero_primo/numero_primo.cpp b/tareas/tarea_3/numero_primo/numero_primo.cpp new file mode 100644 index 0000000..524ee00 --- /dev/null +++ b/tareas/tarea_3/numero_primo/numero_primo.cpp @@ -0,0 +1,29 @@ +#include +using namespace std; +bool esprimo(int x) { + if (x <= 1) return false; + if (x == 2) return true; + for (int i = 2; i * i <= x; i++) { + if (x % i == 0) { + return false; + } + } + return true; +} +int main() { + int numero; + char continuar; + do { + cout << "ingrese un numero: "; + cin >> numero; + if (esprimo(numero)) { + cout << "primo" << endl; + } else { + cout << "no primo" << endl; + } + cout << "desea ingresar otro numero? (s/n): "; + cin >> continuar; + } while (continuar == 's' || continuar == 'S'); + cout << "programa terminado." << endl; + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/numero_primo/numero_primo.exe b/tareas/tarea_3/numero_primo/numero_primo.exe new file mode 100644 index 0000000..18b580b Binary files /dev/null and b/tareas/tarea_3/numero_primo/numero_primo.exe differ diff --git a/tareas/tarea_3/ordenamiento/ordenamiento.cpp b/tareas/tarea_3/ordenamiento/ordenamiento.cpp new file mode 100644 index 0000000..a842863 --- /dev/null +++ b/tareas/tarea_3/ordenamiento/ordenamiento.cpp @@ -0,0 +1,99 @@ +#include +using namespace std; +// bubble +void bubble(int arr[], int n) { + for (int x = 0; x < n - 1; x++) { + for (int y = 0; y < n - x - 1; y++) { + if (arr[y] > arr[y + 1]) { + swap(arr[y], arr[y + 1]); + } + } + } +} +// seleccion +void Selection(int arr[], int n) { + for (int x = 0; x < n - 1; x++) { + int min = x; + for (int y = x + 1; y < n; y++) { + if (arr[y] < arr[min]) { + min = y; + } + } + swap(arr[x], arr[min]); + } +} +// merge sort +void merge(int arr[], int start, int medium, int end) { + int x = start, y = medium + 1, z = 0; + int temp[100]; + while (x <= medium && y <= end) { + if (arr[x] < arr[y]) { + temp[z++] = arr[x++]; + } else { + temp[z++] = arr[y++]; + } + } + while (x <= medium) { + temp[z++] = arr[x++]; + } + while (y <= end) { + temp[z++] = arr[y++]; + } + for (int x = start, y = 0; x <= end; x++, y++) { + arr[x] = temp[y]; + } +} +void mergesort(int arr[], int start, int end) { + if (start < end) { + int medium = (start + end) / 2; + mergesort(arr, start, medium); + mergesort(arr, medium + 1, end); + merge(arr, start, medium, end); + } +} +// --------- MOSTRAR --------- +void mostrar(int arr[], int n) { + for (int x = 0; x < n; x++) { + cout << arr[x] << " "; + } + cout << endl; +} +// --------- MAIN --------- +int main() { + int opcion, n; + char repetir; + do { + cout << "\nCantidad de datos: "; + cin >> n; + int arr[1000]; + cout << "Ingrese los datos:\n"; + for (int x = 0; x < n; x++) { + cin >> arr[x]; + } + cout << "\nMetodos de ordenamiento:\n"; + cout << "1. bubble\n"; + cout << "2. Selection\n"; + cout << "3. Merge Sort\n"; + cout << "Elija una opcion: "; + cin >> opcion; + switch (opcion) { + case 1: + bubble(arr, n); + break; + case 2: + Selection(arr, n); + break; + case 3: + mergesort(arr, 0, n - 1); + break; + default: + cout << "Opcion invalida\n"; + continue; + } + cout << "\nArreglo ordenado:\n"; + mostrar(arr, n); + cout << "\nDesea repetir? (s/n): "; + cin >> repetir; + } while (repetir == 's' || repetir == 'S'); + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/ordenamiento/ordenamiento.exe b/tareas/tarea_3/ordenamiento/ordenamiento.exe new file mode 100644 index 0000000..0f2702b Binary files /dev/null and b/tareas/tarea_3/ordenamiento/ordenamiento.exe differ diff --git a/tareas/tarea_3/suma_digitos/suma_digitos.cpp b/tareas/tarea_3/suma_digitos/suma_digitos.cpp new file mode 100644 index 0000000..dcd22a8 --- /dev/null +++ b/tareas/tarea_3/suma_digitos/suma_digitos.cpp @@ -0,0 +1,21 @@ +#include +#include +using namespace std; +int main() { + char continuar; + do { + int x, suma = 0; + cout << " ingresa un numero entero: "; + cin >> x; + x = abs(x); + while (x > 0) { + suma += x % 10; + x /= 10; + } + cout << "La suma de los digitos es: " << suma << endl; + cout << "deseas volverlo a intentar? (s/n): "; + cin >> continuar; + } while (continuar == 's' || continuar == 'S'); + cout << "programa terminado." << endl; + return 0; +} \ No newline at end of file diff --git a/tareas/tarea_3/suma_digitos/suma_digitos.exe b/tareas/tarea_3/suma_digitos/suma_digitos.exe new file mode 100644 index 0000000..85c9728 Binary files /dev/null and b/tareas/tarea_3/suma_digitos/suma_digitos.exe differ