Tu primer proyecto
Juntando todo
A lo largo de los últimos nueve capítulos, has aprendido variables, tipos, operaciones, flujo de control, funciones, arrays, strings, maps y structs. ¡Es mucho! Ahora es momento de combinar todo en un programa real.
Vamos a construir un seguimiento de notas de estudiantes: un programa que almacena estudiantes y sus notas, calcula promedios, encuentra al mejor y peor estudiante, e imprime un informe resumen.
Paso 1: Definir los datos
Primero, definamos cómo se ve un estudiante:
struct Estudiante { nombre: String, notas: Array }
Cada estudiante tiene un nombre y un array de notas (enteros).
Paso 2: Crear los estudiantes
fn crear_estudiante(nombre: String, notas: Array) -> Estudiante { return Estudiante { nombre: nombre, notas: notas } }
Esta función auxiliar facilita la creación de estudiantes.
Paso 3: Calcular el promedio
fn promedio(notas: Array) -> int { if notas.length() == 0 { return 0 } var total: int = 0 var i: int = 0 while i < notas.length() { total += notas[i] i += 1 } return total / notas.length() }
Esta función suma todas las notas y divide por la cantidad. Como usamos división entera, el resultado se redondea hacia abajo.
Paso 4: Encontrar la nota más alta
fn nota_mas_alta(notas: Array) -> int { var mejor: int = notas[0] var i: int = 1 while i < notas.length() { if notas[i] > mejor { mejor = notas[i] } i += 1 } return mejor }
Paso 5: Determinar la letra de calificación
fn letra_nota(prom: int) -> String { if prom >= 90 { return "A" } if prom >= 80 { return "B" } if prom >= 70 { return "C" } if prom >= 60 { return "D" } return "F" }
Paso 6: Imprimir el informe de un estudiante
fn imprimir_informe(s: Estudiante) { let prom: int = promedio(s.notas) let mejor: int = nota_mas_alta(s.notas) let letra: String = letra_nota(prom) print("Estudiante: " + s.nombre) print(" Notas: " + int_to_string(s.notas.length()) + " tareas") print(" Promedio: " + int_to_string(prom)) print(" Mejor: " + int_to_string(mejor)) print(" Letra: " + letra) print("") }
Paso 7: Encontrar al mejor estudiante
fn mejor_estudiante(estudiantes: Array) -> String { var mejor_nombre: String = "" var mejor_prom: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] let prom: int = promedio(s.notas) if prom > mejor_prom { mejor_prom = prom mejor_nombre = s.nombre } i += 1 } return mejor_nombre }
Paso 8: Estadísticas de la clase
fn promedio_clase(estudiantes: Array) -> int { var total: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] total += promedio(s.notas) i += 1 } return total / estudiantes.length() } fn contar_aprobados(estudiantes: Array) -> int { var cuenta: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] if promedio(s.notas) >= 60 { cuenta += 1 } i += 1 } return cuenta }
El programa completo
Aquí está todo junto:
struct Estudiante { nombre: String, notas: Array } fn crear_estudiante(nombre: String, notas: Array) -> Estudiante { return Estudiante { nombre: nombre, notas: notas } } fn promedio(notas: Array) -> int { if notas.length() == 0 { return 0 } var total: int = 0 var i: int = 0 while i < notas.length() { total += notas[i] i += 1 } return total / notas.length() } fn nota_mas_alta(notas: Array) -> int { var mejor: int = notas[0] var i: int = 1 while i < notas.length() { if notas[i] > mejor { mejor = notas[i] } i += 1 } return mejor } fn letra_nota(prom: int) -> String { if prom >= 90 { return "A" } if prom >= 80 { return "B" } if prom >= 70 { return "C" } if prom >= 60 { return "D" } return "F" } fn imprimir_informe(s: Estudiante) { let prom: int = promedio(s.notas) let mejor: int = nota_mas_alta(s.notas) let letra: String = letra_nota(prom) print("Estudiante: " + s.nombre) print(" Promedio: " + int_to_string(prom) + " (" + letra + ")") print(" Mejor nota: " + int_to_string(mejor)) print("") } fn mejor_estudiante(estudiantes: Array) -> String { var mejor_nombre: String = "" var mejor_prom: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] let prom: int = promedio(s.notas) if prom > mejor_prom { mejor_prom = prom mejor_nombre = s.nombre } i += 1 } return mejor_nombre } fn promedio_clase(estudiantes: Array) -> int { var total: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] total += promedio(s.notas) i += 1 } return total / estudiantes.length() } fn contar_aprobados(estudiantes: Array) -> int { var cuenta: int = 0 var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] if promedio(s.notas) >= 60 { cuenta += 1 } i += 1 } return cuenta } fn main() { let estudiantes: Array = [ crear_estudiante("Alice", [92, 88, 95, 90]), crear_estudiante("Bob", [78, 65, 72, 80]), crear_estudiante("Charlie", [95, 98, 92, 97]), crear_estudiante("Diana", [55, 62, 58, 61]), crear_estudiante("Eve", [88, 85, 90, 87]) ] print("=== Informe de Notas ===") print("") var i: int = 0 while i < estudiantes.length() { let s: Estudiante = estudiantes[i] imprimir_informe(s) i += 1 } print("=== Resumen de la Clase ===") print("Estudiantes: " + int_to_string(estudiantes.length())) print("Promedio de la clase: " + int_to_string(promedio_clase(estudiantes))) print("Aprobados: " + int_to_string(contar_aprobados(estudiantes)) + "/" + int_to_string(estudiantes.length())) print("Mejor estudiante: " + mejor_estudiante(estudiantes)) }
Salida esperada:
=== Informe de Notas === Estudiante: Alice Promedio: 91 (A) Mejor nota: 95 Estudiante: Bob Promedio: 73 (C) Mejor nota: 80 Estudiante: Charlie Promedio: 95 (A) Mejor nota: 98 Estudiante: Diana Promedio: 59 (F) Mejor nota: 62 Estudiante: Eve Promedio: 87 (B) Mejor nota: 90 === Resumen de la Clase === Estudiantes: 5 Promedio de la clase: 81 Aprobados: 4/5 Mejor estudiante: Charlie
Lo que construiste
Mira lo que hace este programa:
- Struct para modelar un estudiante con nombre y notas.
- Arrays para almacenar notas y listas de estudiantes.
- Funciones para cada tarea: promedio, nota más alta, letra, informe.
- Strings para formatear mensajes de salida.
- Flujo de control (if/while) para tomar decisiones y recorrer datos.
- Aritmética entera para promedios y conteos.
Así es como se construyen los programas reales: funciones pequeñas y enfocadas que hacen una sola cosa, combinadas para resolver un problema más grande.
Desafíos
Ahora que has completado la Parte 1, prueba estos desafíos para poner a prueba tus habilidades:
- Agregar nota más baja: Escribe
nota_mas_baja(notas: Array) -> inte inclúyela en el informe.
- Distribución de calificaciones: Cuenta cuántos estudiantes obtuvieron cada letra (A, B, C, D, F) e imprime un resumen.
- Notas con curva: Escribe una función que sume 5 puntos a cada nota (con tope en 100) y recalcula el informe.
- Cuadro de honor: Imprime una lista separada de estudiantes con promedio de 90 o más.
- Construye tu propio proyecto: Elige algo que te interese — un registro de recetas, un marcador deportivo, una lista de reproducción de música — y constrúyelo usando todo lo que has aprendido.
¿Qué sigue?
¡Felicitaciones! Has completado la Parte 1 de El Libro de Nyx. Ahora conoces los fundamentos de la programación: variables, tipos, flujo de control, funciones, arrays, strings, maps y structs.
En la Parte 2, aprenderás a construir programas más grandes con módulos e imports, leer y escribir archivos, usar closures, enums, traits, generics, y eventualmente construir un servidor web — todo en Nyx.
Siguiente capítulo: Imports y módulos →