Introducción a la Programación
El curso definitivo para aprender los fundamentos de la programación. Desde conceptos básicos hasta la creación de tus primeros programas, con teoría, ejemplos prácticos y ejercicios.
Bienvenido al Curso de Programación
¡Bienvenido al curso de Introducción a la Programación! Utiliza el menú de navegación superior para explorar cada módulo a tu propio ritmo. Cada módulo incluye explicaciones claras, ejemplos prácticos y ejercicios para consolidar tu aprendizaje.
La programación es una habilidad fundamental en el mundo digital actual. Aprender a programar te permite crear soluciones, automatizar tareas y desarrollar tu pensamiento lógico. Este curso te proporcionará una base sólida, independientemente de tu experiencia previa.
Lógica
Desarrolla tu capacidad para resolver problemas complejos de manera estructurada y eficiente.
Creatividad
Crea soluciones innovadoras y personalizadas, transformando tus ideas en realidad digital.
Oportunidades
Accede a un mundo de oportunidades profesionales en constante crecimiento y demanda global.
Módulo 1: Fundamentos de Programación
La programación es el proceso de crear un conjunto de instrucciones que le dicen a una computadora cómo realizar una tarea específica. Estas instrucciones se escriben en un lenguaje que la máquina puede entender.
Piensa en la programación como la receta para que una computadora prepare un plato. Cada ingrediente y cada paso deben ser exactos para obtener el resultado deseado. Si un paso falta o es incorrecto, el «plato» no saldrá bien.
Conceptos clave:
- Algoritmo: Es una serie de pasos lógicos y finitos para resolver un problema o completar una tarea. Es la base de cualquier programa. Por ejemplo, un algoritmo para «hacer una taza de café» incluiría pasos como «calentar agua», «añadir café», etc.
- Lenguaje de programación: Es un idioma formal diseñado para comunicar instrucciones a una máquina. Hay muchos lenguajes, cada uno con sus propias fortalezas. Algunos populares son Python (fácil de aprender, usado en IA y web), JavaScript (para desarrollo web interactivo), Java (aplicaciones empresariales y Android) y C# (desarrollo de Windows y juegos).
- Sintaxis: Son las reglas gramaticales y de estructura de un lenguaje de programación. Al igual que en los idiomas humanos, si no sigues la sintaxis, el programa no se entenderá o producirá errores.
- Compilación vs Interpretación: Son dos formas principales en que el código fuente se convierte en un programa ejecutable.
- Compilación: Un compilador traduce todo el código fuente a código máquina antes de la ejecución. Esto suele resultar en programas más rápidos (ej: C++, Java).
- Interpretación: Un intérprete lee y ejecuta el código línea por línea. Esto permite mayor flexibilidad y depuración más sencilla, pero puede ser más lento (ej: Python, JavaScript).
Cada lenguaje de programación tiene su nicho y características distintivas:
Python: Versátil, legible, IA, ciencia de datos, web (Django, Flask).
JavaScript: Web interactiva (frontend y backend con Node.js), aplicaciones móviles (React Native).
Java: Aplicaciones empresariales robustas, desarrollo de Android, sistemas de gran escala.
C#: Desarrollo de aplicaciones Windows, juegos (Unity), desarrollo web con .NET.
Módulo 2: Variables y Tipos de Datos
Las variables son fundamentales en programación; actúan como contenedores o «cajas» con un nombre, donde puedes **almacenar diferentes tipos de información** que tu programa necesita para funcionar. Imagina que son etiquetas que pones en diferentes valores para poder referenciar y manipular esos valores fácilmente a lo largo de tu código.
Cada variable tiene un **tipo de dato**, el cual le indica a la computadora qué clase de información guardará esa «caja» (un número, texto, una verdad/falsedad, etc.) y qué operaciones son válidas para ese tipo de información. Por ejemplo, no puedes multiplicar una palabra, pero sí dos números.
Tipos de datos básicos:
- Enteros (int): Representan números enteros, es decir, sin parte decimal. Pueden ser positivos, negativos o cero. Ejemplos:
5,-10,0,1000. Son ideales para contar elementos o para IDs. - Flotantes (float) o Decimales: Representan números con parte decimal. Son cruciales para cálculos que requieren precisión o para magnitudes continuas. Ejemplos:
3.14,-0.5,98.6. - Cadenas de caracteres (string): Representan secuencias de texto. Se encierran entre comillas simples (
' ') o dobles (" "). Ejemplos:"Hola Mundo",'Python',"123"(aunque contenga números, es tratado como texto). - Booleanos (bool): Representan valores lógicos:
True(verdadero) oFalse(falso). Son fundamentales para la toma de decisiones en tu programa (condicionales).
nombre = «Alicia» # Variable de tipo String (cadena de caracteres)
edad = 25 # Variable de tipo Entero (int)
precio_producto = 19.99 # Variable de tipo Flotante (float)
esta_activo = True # Variable de tipo Booleano (bool)
# Imprimir los valores y sus tipos para verificar
print(«Nombre:», nombre, «(Tipo:», type(nombre), «)»)
print(«Edad:», edad, «(Tipo:», type(edad), «)»)
print(«Precio:», precio_producto, «(Tipo:», type(precio_producto), «)»)
print(«Activo:», esta_activo, «(Tipo:», type(esta_activo), «)»)
En este ejemplo, la función type() de Python nos ayuda a confirmar el tipo de dato que el intérprete ha asignado a cada variable.
Declara las siguientes variables para almacenar información sobre ti o un personaje ficticio:
mi_nombre(cadena de caracteres)mi_edad(entero)mi_ciudad_natal(cadena de caracteres)tiene_mascota(booleano)estatura_metros(flotante)
Módulo 3: Estructuras de Control de Flujo
Las **estructuras de control** son los pilares de la lógica en programación. Permiten que tu programa tome decisiones y realice acciones repetitivas, desviando el flujo de ejecución del código de una línea a la siguiente de manera secuencial a un camino diferente, basado en ciertas condiciones o por un número específico de veces.
Estructuras principales:
- Condicionales (If-Else / If-Elif-Else): Estas estructuras permiten que un programa ejecute diferentes bloques de código basándose en si una condición es verdadera o falsa. Son como un «si esto es cierto, haz esto; de lo contrario, haz aquello».
if: Ejecuta un bloque de código si la condición es verdadera.elif(else if): Permite evaluar múltiples condiciones en secuencia.else: Ejecuta un bloque de código si ninguna de las condiciones anteriores fue verdadera.
- Bucles (Loops – For, While): Los bucles se utilizan para repetir un bloque de código varias veces. Son esenciales para tareas que implican procesar listas de datos, realizar cálculos iterativos o esperar una condición.
- Bucle
for: Se usa cuando sabes de antemano cuántas veces quieres que se repita el código (por ejemplo, iterar sobre una lista de elementos o un rango de números). - Bucle
while: Se usa cuando quieres que el código se repita mientras una condición específica sea verdadera. El bucle continuará ejecutándose hasta que la condición se vuelva falsa.
- Bucle
- Switch-case (o estructuras de selección múltiple): Presente en algunos lenguajes (como Java, C++, JavaScript moderno), permite seleccionar un bloque de código a ejecutar entre varias opciones predefinidas, basándose en el valor de una variable. Es una alternativa más limpia a múltiples
if-elif-elseanidados cuando se compara una sola variable con muchos valores posibles.
let numero = 10;
if (numero % 2 === 0) { // El operador % (módulo) da el resto de una división
console.log(«El número « + numero + » es par.»);
} else {
console.log(«El número « + numero + » es impar.»);
}
// Bucle for: Imprimir números del 1 al 5
for (let i = 1; i <= 5; i++) {
console.log(«Contador For: « + i);
}
// Bucle while: Contar hacia atrás desde 3
let contador = 3;
while (contador > 0) {
console.log(«Contador While: « + contador);
contador–; // Es crucial cambiar la condición para evitar un bucle infinito
}
La serie de Fibonacci es una secuencia donde cada número es la suma de los dos anteriores, comenzando con 0 y 1. Los primeros números son: 0, 1, 1, 2, 3, 5, 8, 13…
Escribe un programa (usando cualquier lenguaje de tu preferencia, pero preferiblemente Python o JavaScript para mantener la coherencia con los ejemplos) que **imprima los primeros 10 números de la serie Fibonacci**. Deberás utilizar un bucle (
for o while) y algunas variables para almacenar los dos números anteriores de la secuencia.
Módulo 4: Funciones y Modularización
Las **funciones** son uno de los conceptos más importantes en programación. Son bloques de código autocontenido y reutilizable que realizan una tarea específica. Imagina que son como mini-programas dentro de tu programa principal, diseñados para hacer un trabajo particular.
La **modularización** es la práctica de dividir un programa grande en módulos más pequeños y manejables (funciones es un tipo de módulo). Esto hace que el código sea más organizado, fácil de entender, depurar y mantener. Si una parte del código necesita ser modificada, solo cambias la función relevante sin afectar el resto del programa.
Beneficios de usar funciones:
- Reusabilidad: Escribes el código una vez y lo usas muchas veces, en diferentes partes del programa o incluso en otros programas.
- Organización y legibilidad: El código se vuelve más limpio y fácil de leer, ya que cada función tiene un propósito claro.
- Mantenimiento: Es más fácil encontrar y corregir errores, y también actualizar o añadir nuevas funcionalidades.
- Colaboración: Facilita el trabajo en equipo, ya que diferentes programadores pueden trabajar en distintas funciones simultáneamente.
Partes clave de una función:
Nombre
Es un identificador único que le das a la función, permitiéndote «llamarla» o «invocarla» cuando la necesitas.
Parámetros (Entradas)
Son las variables o datos que la función puede recibir para realizar su tarea. Son opcionales; no todas las funciones necesitan parámetros.
Cuerpo
Es el bloque de código que contiene las instrucciones que la función ejecutará cuando sea llamada.
Retorno (Salida)
Es el valor que la función «devuelve» al código que la llamó después de completar su tarea. También es opcional; algunas funciones solo realizan una acción y no devuelven nada (funciones «void»).
«»»
Esta función calcula el área de un rectángulo.
Recibe la base y la altura como argumentos.
«»»
area = base * altura # Cuerpo de la función: realiza el cálculo
return area # La función devuelve el valor calculado del área
# Llamar a la función con diferentes valores y almacenar el resultado
area1 = calcular_area_rectangulo(5, 3) # base=5, altura=3
print(«El área del primer rectángulo es:», area1) # Salida: 15
area2 = calcular_area_rectangulo(10, 4) # Reutilizamos la función con nuevos valores
print(«El área del segundo rectángulo es:», area2) # Salida: 40
En este ejemplo, calcular_area_rectangulo es el nombre de la función. Recibe dos parámetros (base y altura) y utiliza la instrucción return para devolver el resultado del cálculo.
Crea una función llamada
celsius_a_fahrenheit que tome como único parámetro una temperatura en grados Celsius y la convierta a grados Fahrenheit. La fórmula de conversión es:
$$ F = C \times \frac{9}{5} + 32 $$
Donde $F$ es Fahrenheit y $C$ es Celsius.
Tu función debe:
- Aceptar un número (Celsius) como entrada.
- Realizar el cálculo.
- Retornar el resultado en Fahrenheit.
Módulo 5: Programación Orientada a Objetos (POO)
La **Programación Orientada a Objetos (POO)** es un **paradigma de programación** (un estilo o forma de pensar sobre cómo estructurar programas) que se basa en el concepto de «objetos». La idea es modelar entidades del mundo real o conceptos abstractos como objetos dentro de tu código. Esto permite crear software más modular, reutilizable y fácil de mantener.
En lugar de una serie de instrucciones secuenciales (como en la programación procedural), la POO organiza el código alrededor de **datos** (atributos) y **comportamientos** (métodos) que pertenecen a los objetos.
Conceptos fundamentales de la POO:
| Concepto | Descripción Detallada | Ejemplo Aplicado |
|---|---|---|
| Clase | Es una **plantilla, plano o molde** para crear objetos. Define la estructura (atributos) y el comportamiento (métodos) que todos los objetos de ese tipo tendrán. Una clase por sí sola no ocupa memoria para datos específicos, solo define cómo se verán los objetos que se creen a partir de ella. | class Perro { ... } (Define que un perro tiene nombre, raza, edad y puede ladrar, comer). |
| Objeto (Instancia) | Es una **instancia concreta** de una clase. Cuando creas un objeto a partir de una clase, le estás dando «vida» a esa plantilla, asignándole valores específicos a sus atributos y permitiéndole realizar sus métodos. Cada objeto es independiente de los demás. | miPerro = new Perro("Buddy", "Golden", 3); (miPerro es un objeto real, con sus propios valores: nombre=»Buddy», raza=»Golden», edad=3). |
| Atributo (Propiedad) | Son las **características o datos** que describen el estado de un objeto. Se definen dentro de la clase y cada objeto tendrá su propio conjunto de valores para estos atributos. Son como las «variables» asociadas a un objeto. | Para un objeto Perro, los atributos podrían ser: nombre, raza, edad, color. |
| Método | Son las **acciones o comportamientos** que un objeto puede realizar. Son funciones que pertenecen a una clase y operan sobre los datos (atributos) del objeto. Definen cómo el objeto interactúa con el mundo exterior o cómo cambia su estado interno. | Para un objeto Perro, los métodos podrían ser: ladrar(), comer(), dormir(), obtenerEdad(). |
Principios clave de POO (Pilares):
- Encapsulamiento: Empaquetar datos y métodos que operan sobre esos datos dentro de una sola unidad (la clase). Esto oculta los detalles internos de cómo funciona un objeto y expone solo lo necesario, protegiendo los datos de accesos externos no deseados.
- Herencia: Permite que una nueva clase (subclase o clase hija) adquiera las propiedades y comportamientos de una clase existente (superclase o clase padre). Promueve la reutilización de código y establece relaciones «es un tipo de» (e.g., un «Gato» es un tipo de «Animal»).
- Polimorfismo: Significa «muchas formas». Permite que objetos de diferentes clases sean tratados a través de una interfaz común, o que un mismo método pueda comportarse de manera diferente en distintas clases (ej: un método
hacerSonido()podría hacer «Guau» en un Perro y «Miau» en un Gato). - Abstracción: Enfocarse en los aspectos esenciales de un objeto y ocultar los detalles de implementación complejos. Muestra solo lo que es relevante para el usuario.
Persona en Java:// Atributos (variables de instancia)
private String nombre; // ‘private’ significa que solo la clase Persona puede acceder directamente
private int edad;
// Constructor: Método especial para crear nuevas instancias de la clase Persona
public Persona(String nombre, int edad) {
this.nombre = nombre; // ‘this’ se refiere al atributo de la instancia actual
this.edad = edad;
}
// Método: Comportamiento del objeto Persona
public void saludar() {
System.out.println(«Hola, mi nombre es « + nombre + » y tengo « + edad + » años.»);
}
// Otro método: Getters para acceder a los atributos (ejemplo de encapsulamiento)
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
}
// Cómo se usaría la clase Persona en otra parte del código (ej. en el método main)
public class Main {
public static void main(String[] args) {
Persona persona1 = new Persona(«Ana», 30); // Creamos un objeto ‘persona1’ de la clase Persona
persona1.saludar(); // Llamamos a un método del objeto: «Hola, mi nombre es Ana y tengo 30 años.»
Persona persona2 = new Persona(«Pedro», 22);
System.out.println(«El nombre de la segunda persona es: « + persona2.getNombre()); // Accedemos a un atributo a través de un getter
}
}
Este ejemplo demuestra cómo la clase Persona sirve como un molde para crear objetos individuales (persona1, persona2), cada uno con sus propios valores para nombre y edad, y la capacidad de realizar la acción saludar().
Define una clase llamada
Circulo. Esta clase debe tener:
- Un **atributo** llamado
radio(de tipo flotante o entero) que represente el radio del círculo. - Un **constructor** que permita inicializar el
radioal crear un nuevo objetoCirculo. - Un **método** llamado
calcularArea()que calcule y retorne el área del círculo. La fórmula del área es: $ \text{Área} = \pi \times \text{radio}^2 $ (puedes usar 3.14159 para $\pi$). - Un **método** llamado
calcularPerimetro()que calcule y retorne el perímetro (circunferencia) del círculo. La fórmula del perímetro es: $ \text{Perímetro} = 2 \times \pi \times \text{radio} $.
Después de definir la clase, crea al menos dos objetos
Circulo con diferentes radios, llama a sus métodos para calcular y mostrar su área y perímetro.
Módulo 6: Algoritmos y Estructuras de Datos
Este módulo profundiza en dos pilares fundamentales de la informática: los **algoritmos** y las **estructuras de datos**. Son cruciales para escribir programas eficientes y bien organizados. Un buen algoritmo con una estructura de datos adecuada puede resolver un problema de forma mucho más rápida y con menos recursos que una solución ineficiente.
Algoritmos: El corazón de la solución
Como vimos en el Módulo 1, un algoritmo es una secuencia finita y bien definida de pasos para resolver un problema o lograr un objetivo. Aquí exploramos su importancia y algunos ejemplos comunes:
- Eficiencia (Complejidad Algorítmica): No todos los algoritmos son igual de buenos. Evaluamos la eficiencia de un algoritmo en términos de tiempo (cuánto tarda en ejecutarse) y espacio (cuánta memoria consume) a medida que el tamaño de la entrada aumenta. Esto se mide con la «Notación Big O».
- Algoritmos de Búsqueda:
- Búsqueda Lineal: Recorre cada elemento de una lista hasta encontrar el objetivo. Simple pero ineficiente para listas grandes.
- Búsqueda Binaria: Mucho más eficiente, pero requiere que la lista esté ordenada. Divide repetidamente por la mitad la porción de la lista donde el elemento podría estar.
- Algoritmos de Ordenamiento:
- Burbuja (Bubble Sort): Un algoritmo simple pero ineficiente. Compara pares de elementos adyacentes y los intercambia si están en el orden incorrecto, repitiendo hasta que la lista esté ordenada.
- Selección (Selection Sort): Encuentra el elemento mínimo (o máximo) en la parte no ordenada de la lista y lo coloca al principio.
- Inserción (Insertion Sort): Construye la lista ordenada de a un elemento a la vez, insertando cada nuevo elemento en su posición correcta en la parte ya ordenada.
- Merge Sort / Quick Sort: Algoritmos mucho más eficientes para grandes conjuntos de datos, basados en la estrategia «divide y vencerás».
Estructuras de Datos: Cómo organizar la información
Una estructura de datos es una forma particular de organizar y almacenar datos en una computadora para que puedan ser utilizados de manera eficiente. La elección de la estructura de datos correcta es fundamental para el rendimiento de un algoritmo.
Arrays (Arreglos)
Colecciones de elementos del mismo tipo almacenados en posiciones de memoria contiguas. Se accede a los elementos por un índice. Tamaño fijo en muchos lenguajes, acceso rápido por índice.
Listas Enlazadas
Colecciones de elementos (nodos) donde cada nodo contiene un dato y una referencia (puntero) al siguiente nodo. Flexibles en tamaño, inserción/eliminación eficientes, pero acceso secuencial.
Pilas (Stacks)
Estructura de datos que sigue el principio **LIFO** (Last In, First Out – Último en Entrar, Primero en Salir). Similar a una pila de platos. Operaciones principales: push (añadir), pop (quitar).
Colas (Queues)
Estructura de datos que sigue el principio **FIFO** (First In, First Out – Primero en Entrar, Primero en Salir). Similar a una fila de personas. Operaciones principales: enqueue (añadir), dequeue (quitar).
Árboles
Estructuras jerárquicas donde los datos se organizan de forma no lineal. Un nodo raíz tiene nodos hijos, y así sucesivamente. Útiles para organizar información jerárquica (ej. sistema de archivos, árboles de búsqueda binaria).
Tablas Hash (Hash Maps)
Asignan claves a valores, permitiendo una búsqueda y recuperación de datos muy rápida. Útiles para almacenar y acceder a información por «nombre» (clave).
«»»
Realiza una búsqueda binaria en una lista ordenada.
Retorna el índice del objetivo si se encuentra, de lo contrario -1.
«»»
izquierda, derecha = 0, len(arr) – 1
while izquierda <= derecha:
medio = (izquierda + derecha) // 2 # Calcula el índice medio
if arr[medio] == objetivo:
return medio # Objetivo encontrado
elif arr[medio] < objetivo:
izquierda = medio + 1 # Buscar en la mitad derecha
else:
derecha = medio – 1 # Buscar en la mitad izquierda
return -1 # Objetivo no encontrado en la lista
# Ejemplo de uso:
lista_ordenada = [1, 5, 8, 12, 16, 23, 38, 56, 72, 91]
buscar_numero = 23
indice = busqueda_binaria(lista_ordenada, buscar_numero)
if indice != -1:
print(f»El número {buscar_numero} se encuentra en el índice {indice}.»)
else:
print(f»El número {buscar_numero} no se encuentra en la lista.»)
Implementa en tu lenguaje de programación preferido (Python o JavaScript recomendado) el algoritmo de **ordenamiento de burbuja** para ordenar una lista de números de menor a mayor.
El algoritmo de burbuja funciona repetidamente intercambiando los elementos adyacentes si están en el orden incorrecto. Las pasadas a través de la lista se repiten hasta que no se necesiten más intercambios, lo que indica que la lista está ordenada.
Prueba tu implementación con la siguiente lista:
[64, 34, 25, 12, 22, 11, 90]. Imprime la lista antes y después de aplicar el algoritmo.
Módulo 7: Depuración y Buenas Prácticas de Código
Escribir código es solo una parte del trabajo de un programador. Otra parte crucial es asegurarse de que ese código funcione correctamente y sea fácil de entender y mantener, tanto para ti como para otros. Aquí es donde entran la **depuración (debugging)** y las **buenas prácticas de código**.
Depuración: Cazando errores (Bugs)
Un «bug» es un error o fallo en un programa de computadora que produce un resultado incorrecto o inesperado. La depuración es el proceso de identificar, analizar y eliminar estos errores. Es una habilidad esencial para cualquier desarrollador.
Técnicas de depuración comunes:
- Impresión de valores (Print/Console.log): La técnica más sencilla y común. Consiste en insertar sentencias de impresión en tu código para mostrar el valor de variables en puntos específicos o para indicar si ciertas partes del código se están ejecutando. Es rudimentario pero efectivo para errores simples.
- Uso de un Depurador (Debugger): La herramienta más poderosa. Un depurador permite ejecutar tu código paso a paso, línea por línea. Puedes:
- Establecer **puntos de ruptura (breakpoints)**: El programa se pausa automáticamente en esas líneas.
- Inspeccionar el estado de las variables: Ver sus valores en tiempo real.
- Recorrer el código: Ejecutar una línea a la vez (step over), entrar en funciones (step into), o salir de funciones (step out).
- Ver la pila de llamadas (call stack): Rastrear cómo se llegó a la línea de código actual.
- Mensajes de Error y Excepciones: Aprender a leer y entender los mensajes de error que genera el compilador o intérprete de tu lenguaje es vital. Estos mensajes a menudo te dan pistas sobre dónde y por qué algo salió mal. Implementar el manejo de excepciones (
try-catchen Java/JavaScript,try-excepten Python) ayuda a tu programa a recuperarse de errores inesperados de forma controlada. - Pruebas Unitarias: Escribir pequeños fragmentos de código que verifican que componentes individuales (unidades) de tu software funcionan correctamente de forma aislada. Esto ayuda a identificar bugs temprano y a garantizar que los cambios futuros no rompan funcionalidades existentes (regresiones).
Buenas Prácticas de Código: Escribiendo código de calidad
Un código de calidad no solo funciona, sino que también es legible, mantenible y escalable. Seguir estas prácticas hace tu vida y la de tus colaboradores mucho más fácil:
- Nombres Descriptivos y Consistentes: Usa nombres claros y significativos para variables, funciones, clases y archivos. Evita abreviaturas crípticas. Por ejemplo, en lugar de
xpara una edad, usaedad_usuarioouserAge. Mantén una convención de nombrado (camelCase, snake_case, PascalCase). - Comentarios Claros y Concisos: Los comentarios deben explicar el «por qué» de una decisión de diseño o una lógica compleja, no el «qué» (el código ya lo dice). Mantén los comentarios actualizados y evita el exceso de comentarios triviales.
- Código Limpio y Formateado:
- Indentación Consistente: Usa una indentación uniforme (espacios o tabulaciones) para mostrar la estructura jerárquica de tu código.
- Espaciado: Usa espacios alrededor de operadores y después de comas para mejorar la legibilidad.
- Líneas en Blanco: Separa bloques lógicos de código con líneas en blanco para mejorar el flujo visual.
- Líneas Cortas: Intenta mantener las líneas de código a una longitud razonable (ej., 80-120 caracteres) para evitar el desplazamiento horizontal.
- Modularización y Funciones Pequeñas: Como vimos en el Módulo 4, divide tu código en funciones pequeñas y con una única responsabilidad. Una función debería hacer una sola cosa y hacerla bien.
- Evitar la Duplicación de Código (DRY – Don’t Repeat Yourself): Si te encuentras escribiendo el mismo bloque de código varias veces, es una señal de que necesitas crear una función o un método para reutilizarlo.
- Manejo de Errores y Excepciones: Anticipa posibles errores (entrada de usuario inválida, archivos no encontrados, división por cero) y maneja las excepciones de forma elegante para que tu programa no falle inesperadamente.
- Control de Versiones (Git): Usa un sistema de control de versiones como Git para llevar un registro de los cambios en tu código, colaborar con otros y revertir a versiones anteriores si es necesario. Es una herramienta indispensable en el desarrollo profesional.
# MAL:
num = 10
res = num * 2
# BIEN:
precio_unitario = 10.50
cantidad_productos = 5
precio_total = precio_unitario * cantidad_productos
# 2. Comentarios útiles que explican el «por qué» o la lógica compleja
# MAL:
i += 1 # Incrementa i
# BIEN:
# Incrementar el contador de intentos de login. Si supera 3, bloquear cuenta.
intentos_login += 1
# 3. Funciones pequeñas y con una única responsabilidad (DRY)
# MAL: Una función que hace varias cosas
def procesar_datos_y_mostrar_reporte(datos):
# … código para limpiar datos …
# … código para calcular promedios …
# … código para generar PDF …
# … código para enviar email …
pass
# BIEN: Dividir en funciones con responsabilidades únicas
def limpiar_datos(datos_sucios):
pass
def calcular_metricas(datos_limpios):
pass
def generar_reporte_pdf(metricas):
pass
def enviar_notificacion_email(reporte_pdf):
pass
Identifica y corrige los problemas de **malas prácticas** y posibles **errores lógicos** en el siguiente fragmento de código (asume que es Python, pero las ideas son generales). Luego, reescríbelo siguiendo las buenas prácticas aprendidas en este módulo.
y = x*2
return y
a = 5
b = f(a)
print(b)
# Otro fragmento
saldo = 1000
retiro = 1200
if retiro > saldo:
print(«No tienes suficiente dinero»)
else:
saldo = saldo – retiro
print(«Nuevo saldo:», saldo)
Considera aspectos como:
- Nombres de variables y funciones.
- Claridad de los comentarios (si son necesarios).
- Modularidad (¿se puede dividir en funciones más pequeñas?).
- Manejo de errores/condiciones (¿qué pasa si el retiro es inválido?).
Módulo 8: Proyectos Prácticos y Próximos Pasos
Has llegado a un punto crucial: la mejor manera de consolidar todo lo aprendido en los módulos anteriores es **aplicándolo en proyectos prácticos**. Los proyectos te permiten integrar conceptos, enfrentar desafíos reales, depurar problemas y, en última instancia, construir algo funcional. Es donde la teoría cobra vida y donde realmente se solidifican tus habilidades.
¿Por qué los proyectos son tan importantes?
- Aplicación Real: Te permiten ver cómo los diferentes conceptos (variables, estructuras de control, funciones, POO) se conectan y trabajan juntos en un contexto real.
- Resolución de Problemas: Te obligan a pensar lógicamente, a descomponer problemas grandes en partes más pequeñas y a encontrar soluciones creativas.
- Errores y Depuración: Es natural cometer errores. Los proyectos son el campo de juego perfecto para practicar tus habilidades de depuración.
- Construcción de Portafolio: Si te interesa una carrera en programación, los proyectos que construyas serán la evidencia más valiosa de tus habilidades para futuros empleadores.
- Motivación: Ver algo que has creado funcionar es increíblemente gratificante y te mantiene motivado para seguir aprendiendo.
Ideas de proyectos para principiantes (usando Python o JavaScript):
Aquí tienes algunas ideas de proyectos con un nivel de complejidad creciente. ¡Elige uno que te entusiasme y empieza a construir!
- Calculadora Simple:
- Permite operaciones básicas (suma, resta, multiplicación, división).
- Puede ser de línea de comandos inicialmente, luego quizás con una interfaz gráfica simple.
- Aplica: variables, operadores, condicionales, funciones.
- Lista de Tareas (To-Do List):
- Permite añadir nuevas tareas, marcar tareas como completadas y eliminar tareas.
- Las tareas pueden almacenarse en una lista (array).
- Aplica: listas/arrays, funciones, bucles, entrada/salida de usuario.
- Juego de Adivinanzas de Números:
- La computadora elige un número aleatorio y el usuario debe adivinarlo.
- El programa da pistas («demasiado alto», «demasiado bajo»).
- El usuario tiene un número limitado de intentos.
- Aplica: números aleatorios, bucles
while, condicionales, entrada/salida.
- Conversor de Unidades:
- Convierte entre diferentes unidades (ej. Celsius a Fahrenheit, Metros a Pies, Kilogramos a Libras).
- Puedes tener un menú para que el usuario elija la conversión.
- Aplica: funciones, condicionales (
if-elif-elseoswitch-case), cálculos.
- Simulador de Cajero Automático (ATM):
- Un usuario tiene un saldo inicial.
- Pueden realizar depósitos, retiros y consultar saldo.
- Maneja casos como fondos insuficientes para retiro.
- Aplica: variables, condicionales, bucles (para el menú), funciones.
- Juego de Piedra, Papel o Tijera:
- El usuario juega contra la computadora.
- La computadora elige aleatoriamente.
- Determina el ganador y lleva un registro de puntuaciones.
- Aplica: números aleatorios, condicionales, entrada/salida, bucles.
# Inicializamos una lista vacía para almacenar las tareas
tareas = []
def mostrar_tareas():
# Imprime todas las tareas con su estado
if not tareas:
print(«\nNo hay tareas pendientes.»)
return
print(«\n— Tus Tareas —«)
for i, tarea in enumerate(tareas):
estado = «[X]» if tarea[‘completada’] else «[ ]»
print(f»{i + 1}. {estado} {tarea[‘descripcion’]}»)
print(«——————\n»)
def agregar_tarea(descripcion):
# Añade una nueva tarea a la lista
nueva_tarea = {‘descripcion’: descripcion, ‘completada’: False}
tareas.append(nueva_tarea)
print(f»Tarea ‘{descripcion}’ agregada.»)
def marcar_completada(numero_tarea):
# Marca una tarea como completada si el número es válido
if 0 <= numero_tarea - 1 < len(tareas):
tareas[numero_tarea – 1][‘completada’] = True
print(f»Tarea {numero_tarea} marcada como completada.»)
else:
print(«Número de tarea inválido.»)
# … otras funciones como eliminar_tarea, etc.
# Bucle principal del programa (menú)
while True:
print(«1. Mostrar tareas»)
print(«2. Agregar tarea»)
print(«3. Marcar tarea completada»)
print(«4. Salir»)
opcion = input(«Elige una opción: «)
if opcion == ‘1’:
mostrar_tareas()
elif opcion == ‘2’:
desc = input(«Describe la nueva tarea: «)
agregar_tarea(desc)
elif opcion == ‘3’:
try:
num = int(input(«Número de tarea a marcar como completada: «))
marcar_completada(num)
except ValueError:
print(«Por favor, ingresa un número válido.»)
elif opcion == ‘4’:
print(«¡Adiós!»)
break
else:
print(«Opción no válida. Intenta de nuevo.»)
Este es un esqueleto simple de cómo podrías empezar una aplicación de lista de tareas en Python, utilizando las funciones y estructuras de control aprendidas.
Quiz Final de Programación
¡Felicidades por llegar hasta aquí! Este quiz evaluará tu comprensión de los conceptos clave cubiertos en el curso. Tómate tu tiempo, lee cada pregunta con atención y selecciona la opción que consideres correcta.
