Currículo: esta unidad cubre parte de los saberes básicos del Bloque A – Desarrollo de Software (TICO.2.A.1) correspondiente a 2º Bachillerato. Además, se evalúan los criterios que puedes encontrar al final de esta página.
Tabla de contenidos
- 1.1. Estructura de un programa informático.
- 1.2. Fundamentos.
- 1.3. Estructuras de control. Condicionales e iterativas.
- 1.4. Estructuras de Datos
- 1.5. Funciones y bibliotecas de funciones.
- 1.6. Manipulación de archivos.
- 1.7. Orientación a Objetos
La programación informática es similar a aprender un nuevo idioma, pero en lugar de comunicarte con personas, te comunicas con máquinas. Si alguna vez has querido dar órdenes a tu ordenador o móvil y que este las ejecute, estás en el camino correcto. Veámoslo como si estuviéramos aprendiendo a cocinar. Cada receta tiene sus ingredientes y pasos a seguir. Vamos a desglosar cada uno de estos ingredientes en este tema.
1.1. Estructura de un programa informático.
Siguiendo con el ejemplo de la introducción del tema, un programa informático es como una receta culinaria, con pasos claros a seguir y diferentes ingredientes para conseguir un resultado. Estas “recetas” las escribimos en un “idioma” específico para que el ordenador las entienda. En nuestro caso, el idioma o lenguaje de programación elegido es Python.
Esta sección te ayudará a comprender la estructura básica de estos programas y a familiarizarte con los lenguajes que utilizamos para comunicarnos con las máquinas.
Ejercicio 1.1 – Instalar un entorno de desarrollo
Para comenzar a escribir nuestros programas necesitamos un entorno de desarrollo. Esto no es otra cosa que una aplicación que nos permite escribir código fuente que podamos probar para ver si estamos haciendo las cosas correctamente (además de otras herramientas integradas).
Por ello, tu primera tarea será instalar en el portátil el entorno de desarrollo de Python por excelencia que es PyCharm. Veamos cómo hacerlo:
- Dirígete a Aplicaciones > Herramientas del sistema > Centro de Software de EducaAndOS.
- Usa la lupa de la esquina superior izquierda y busca PyCharm.
- Pulsa sobre el icono del programa y luego en Instalar. Cuando termine, simplemente cierra la ventana.
- Comprueba que aparece el programa instalado en Aplicaciones > Programación > PyCharm.
- Ábrelo, confirma los términos de uso y Continuar.
- En la siguiente ventana elegimos el botón Don’t Send o No enviar.
- Cuando aparezca la ventana de bienvenida de PyCharm pulsamos en Crear nuevo proyecto. Lo que aparece seleccionado lo cambiamos por el nombre que queramos darle al proyecto y pulsamos en el botón de continuar.
- Ya tenemos un proyecto creado. Ahora nos situamos a la izquierda sobre el nombre del proyecto, clicamos con el botón derecho del ratón, seleccionamos New > Python File y escribimos el nombre que queramos darle al archivo.
- Escribe tu código Python dentro de ese archivo y cuando quieras ejecutarlo usa el play verde que aparece arriba, o pulsa con el botón derecho del ratón y selecciona Run.
- Escribe un programa que muestre en pantalla “¡Hola mundo!”, ejecútalo y realiza una captura de pantalla tanto al código como al resultado de la ejecución. Luego sube la imagen a la correspondiente tarea de classroom.
1.1.1. Elementos básicos del lenguaje.
- Palabras Reservadas: Son términos que no podemos usar para otro propósito en un lenguaje específico porque tienen un significado especial. Por ejemplo, en Python, print es una palabra reservada para mostrar texto en pantalla. Es muy importante que respetes en todo momento la sintaxis de la expresión o el programa lanzará un error.

- Sintaxis: Es el conjunto de reglas que define cómo deben escribirse las instrucciones. En español, por ejemplo, usamos la estructura “sujeto + verbo + complemento”. En Python, para hacer una operación simple como sumar, la sintaxis es a + b.

- Semántica: Es el significado detrás de la sintaxis. Así como en español, “yo como manzana” significa que alguien está comiendo una fruta, en programación, x = 5 significa que estamos asignando el valor 5 a la variable x. O dicho de otra forma, almacenando un valor (la parte derecha del =) en una variable (la parte izquierda del =).

1.1.2. Tipos de lenguajes.
- Lenguajes de bajo nivel: Son aquellos que están más cerca de cómo funciona internamente una máquina. Son más complicados y requieren un conocimiento profundo del hardware. Imagínalos como instrucciones detalladas para alguien que no sabe cocinar en absoluto. Por ejemplo, el Lenguaje Ensamblador es uno de ellos.

- Lenguajes de alto nivel: Son más abstractos y fáciles de leer y escribir, porque están diseñados pensando en la lógica humana. Si el lenguaje de bajo nivel es como enseñar a alguien que no sabe cocinar, el de alto nivel es como una receta para alguien que ya tiene algo de experiencia en la cocina. Python es un lenguaje de alto nivel y es uno de los más populares por su sencillez.

Para visualizar mejor esto, pensemos en cómo le explicaríamos a un amigo cómo preparar una tostada. En un lenguaje de alto nivel, simplemente le diríamos: “Toma una rebanada de pan y tuéstala“. Pero si fuera un lenguaje de bajo nivel, sería algo así como: “Camina 3 pasos hacia la izquierda, extiende tu brazo y toma una rebanada de pan de la bolsa. Luego, camina 2 pasos hacia la tostadora, abre la ranura, coloca el pan, presiona el botón hacia abajo y espera 2 minutos“.
Es importante entender que, aunque los lenguajes de alto nivel son más sencillos para nosotros, siempre habrá una traducción en el fondo para que la máquina entienda esas instrucciones, y ahí es donde entran los compiladores e intérpretes, que se encargan de convertir ese código comprensible para nosotros en algo que el ordenador pueda ejecutar.
1.2. Fundamentos.
Cuando empezamos a adentrarnos en el mundo de la programación, es vital comprender los cimientos sobre los que construiremos. Estos fundamentos son como los ingredientes básicos en la cocina; no puedes hacer una tarta sin harina, huevos o azúcar. Además, depende de qué receta vayas a cocinar necesitarás harina de trigo, maíz, centeno, cebada, avena o cualquier otra. En programación ocurre exactamente lo mismo. Veamos qué elementos básicos necesitamos para construir nuestros programas.
1.2.1. Tipos de datos.
En la vida real, no tratamos de la misma manera un ticket que una carta, una foto o un flyer de publicidad. Todos ellos son trozos de papel pero tienen propiedades, utilidades y limitaciones distintas. Lo mismo ocurre en programación. Existen diferentes “tipos” para distintos datos. Estos son algunos de los tipos de datos más importantes:
- Integers (enteros): Representan números sin decimales. Por ejemplo, el número de días en una semana, 7.

- Float (números con decimales): Como la calificación de un examen, que puede ser 8.5 (observa que no se usa la coma para separar la parte entera de la decimal, sino el punto).

- Strings (cadenas de texto): Son secuencias o cadenas de caracteres. Un ejemplo es tu nombre o cualquier mensaje que se te ocurra.

- Boolean (valores booleanos): Sólo pueden ser True (verdadero) o False (falso). Se emplean, por ejemplo, para saber si una afirmación es correcta o no. Además, normalmente todo lo que sea True se asemeja a cualquier valor distinto de 0, y False a un valor igual a 0.

1.2.2. Constantes y variables.
- Variables: Son como “cajas” donde guardamos datos para usar más tarde. El valor dentro de una variable puede cambiar, de ahí su nombre. Piensa en ellas como mochilas donde puedes guardar y sacar objetos.

- Constantes: Son similares a las variables, pero su valor nunca cambia. Imagina una caja cerrada con llave donde guardas algo muy valioso y no quieres que nadie lo toque.

1.2.3. Operadores y expresiones.
Los operadores son símbolos que realizan acciones sobre nuestros datos. Las expresiones son combinaciones de valores y operadores, algo así como las operaciones matemáticas que ya conoces.
- Operadores aritméticos: Como sumar (+), restar (–), multiplicar (*) o dividir (/). Existen algunos otros muy útiles como el operador módulo (%) que representan el resto de la división entera, pero ya los iremos viendo conforme los vayamos necesitando.

- Operadores de comparación: Como igual (==), diferente (!=), mayor que (>) o menor que (<).

1.2.4. Entrada/salida.
Son aquellas instrucciones que nos permiten leer valores desde el teclado o mostrar valores en la pantalla.
- Entrada: Son datos que el usuario proporciona al programa. Imagina que tu programa es una máquina de café y necesita saber qué tipo de café quieres.

- Salida: Es la manera en que el programa muestra información al usuario en pantalla. Es la salida más común, aunque también podríamos ofrecer la salida en un fichero o en otros destinos que veremos más adelante.

1.2.5. Comentarios.
Los comentarios son como las notas al margen en un libro de texto. No afectan cómo funciona el programa, pero son útiles para quien lo lee. Los comentarios comienzan con el carácter # y terminan al final de la línea.

Ejercicio 1.2 – Mis primeros programas
Resuelve con la ayuda del profesor cada uno de estos 10 ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python para cada uno –1.py, 2.py, 3.py, …, 10.py-, luego comprime los 10 archivos y sube el archivo comprimido –ejercicio1_2.zip-):
- Solicita al usuario su nombre y salúdale.
- Solicita dos números al usuario y muestra su suma.
- Pide al usuario su edad y muestra cuántos años tendrá el próximo año.
- Solicita al usuario su nombre y el nombre de su mejor amigo/a. Muestra un mensaje que indique que ambos son grandes amigos.
- Solicita el nombre de una persona y su color favorito. Muestra un mensaje personalizado.
- Pide al usuario dos números y muestra su producto.
- Solicita al usuario un texto y muestra cuántos caracteres tiene.
- Pide al usuario su año de nacimiento y muestra cuántos años cumplirá este año.
- Solicita un precio y un descuento. Muestra el precio final tras aplicar el descuento.
- Pide al usuario la longitud y el ancho de un rectángulo. Calcula y muestra su área.
Con estos fundamentos, ya podemos empezar a construir programas más elaborados. Es como aprender a combinar piezas de lego para construir un edificio. Si entiendes estos conceptos, tendrás una base sólida para continuar tu camino en la programación.
1.3. Estructuras de control. Condicionales e iterativas.
La programación, en muchas ocasiones, requiere que tomemos decisiones basadas en ciertas condiciones (a estas las llamamos Estructuras de Control Condicionales). Otras veces necesitamos repetir algunas acciones múltiples veces (a estas las llamamos Estructuras de Control Iterativas). Las estructuras de control permiten manejar el flujo de un programa (qué rama del programa se ejecuta en cada momento) de manera efectiva.
1.3.1. Condicionales.
En la vida cotidiana, constantemente tomamos decisiones basadas en condiciones. Por ejemplo, si llueve, llevamos paraguas; si hace sol, usamos gafas de sol. En programación, estas decisiones se toman mediante estructuras condicionales.
Veamos algunas de las más importantes.
La sentencia if: Es la estructura condicional más básica. Permite ejecutar un bloque de código sólo si se cumple una condición. Reconocerás un bloque de código porque se escribe tabulado más a la derecha (debes usar la tecla tabulador, no la tecla espacio). Observa bien la sintaxis y no olvides los : al final.

La sentencia elif: Es una extensión de if que permite comprobar múltiples condiciones en orden. Si no se cumple la primera condición, se pasará a evaluar la segunda, y así sucesivamente mientras haya alternativas condicionales.

La sentencia else: Es el bloque de código que se ejecuta cuando ninguna de las condiciones anteriores se cumple.

1.3.2. Iterativas.
A veces, es necesario repetir una acción varias veces. Por ejemplo, si te propones hacer ejercicio, podrías decidir hacer 10 flexiones. En programación, este concepto de repetición se maneja con estructuras iterativas.
El bucle for: Es utilizado para recorrer una secuencia (ya veremos esas estructuras de datos) y ejecutar un bloque de código para cada elemento de la secuencia, o también para repetir una o varias acciones una cantidad de veces que nos interese. Esto último lo hacemos usando la función range().

La pieza de código anterior incluye un range(5). Esta expresión es equivalente a escribir range(0,5), es decir, desde un número a otro, desde 0 a 5. El detalle que no debes olvidar es que el segundo número nunca está incluido en la cuenta. range(0,5) significa repetir del 0 al 5, sin contar el 5: 0, 1, 2, 3 y 4, es decir, 5 veces.
El bucle while: Se utiliza para lo mismo que el for, es decir, realizar una o varias acciones de forma repetitiva, pero en este caso, mientras se cumpla una condición. Además, existe un importante matiz que la diferencia del for. En el while no sabemos a priori cuántas veces vamos a ejecutar el bucle. En el for si.

Estas estructuras de control son fundamentales para cualquier programa y forman la base para desarrollar aplicaciones más complejas. Experimentar con ellas y practicar diferentes situaciones es la mejor manera de comprender su utilidad y funcionamiento.
Ejercicio 1.3 – Estructuras condicionales e iterativas
Resuelve con la ayuda del profesor cada uno de estos 10 ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python para cada uno –1.py, 2.py, 3.py, …, 10.py-, luego comprime los 10 archivos y sube el archivo comprimido –ejercicio1_3.zip-):
- Pide al usuario un número y muestra si es par o impar.
- Solicita al usuario dos números. Indica cuál de los dos es mayor o si son iguales.
- Usando un bucle, muestra los números del 1 al 10.
- Pide al usuario un número e imprime su tabla de multiplicar.
- Solicita un número al usuario y muestra si es positivo, negativo o cero.
- Pide al usuario un número y muestra su factorial.
- Solicita un número al usuario y muestra si es o no es múltiplo de 5.
- Solicita al usuario un número y muestra si es primo o no.
- Solicita al usuario un número n y muestra los primeros n números pares.
- Pide al usuario dos números e indica cuántos números hay entre ellos.
1.4. Estructuras de Datos
Cuando programamos, es habitual que no trabajemos con un único valor a la vez. Por ejemplo, si queremos guardar la nota de un alumno en un examen, usaríamos una variable llamada nota y ahí almacenaríamos la nota del alumno. ¿Pero qué ocurriría si quisiéramos guardar todas las notas de ese alumno a lo largo del año, o las notas de un examen de todos los alumnos de una clase? ¿Y si queremos tener una lista de nuestros amigos en una red social? Aquí es donde las estructuras de datos entran en juego. Permiten organizar, almacenar y manipular conjuntos de datos usando un único identificador de variable.
1.4.1. Listas
Una lista es una estructura de datos que permite almacenar una colección ordenada de elementos, que pueden ser de cualquier tipo. En Python, las listas se crean colocando los elementos separados por comas, entre corchetes.

Acceso a elementos: podemos acceder a los elementos de la lista mediante índices, que comienzan siempre por 0 (para el primer elemento).

Modificar elementos: Las listas son mutables, lo que significa que podemos cambiar un elemento por otro. Modificar un elemento no es más que acceder al elemento que queremos modificar y cambiar el valor (almacenar un valor nuevo).

Operaciones útiles: existen una serie de funciones (utilidades que incorporan los lenguajes de programación), que nos permiten realizar algunas operaciones con las listas. Por ejemplo: append() añade un elemento al final de la lista, remove() elimina un elemento, len() nos devuelve cuántos elementos hay en la lista, sum() devuelve la suma de todos los elementos, insert() inserta el elemento que le indiques en la posición que especifiques, pop() elimina el último elemento de la lista. Además si sumamos dos listas, obtenemos una lista cuyos elementos son todos los que estaban en la primera lista y todos los que estaban en la segunda lista.

Recorrer una lista: recorrer una lista significa idear un método iterativo para ir pasando elemento a elemento con el objetivo de satisfacer alguna tarea de nuestro interés, como por ejemplo encontrar un elemento, ver qué elementos cumplen determinadas condiciones, realizar operaciones matemáticas, etc. Para recorrer listas se puede utilizar cualquier bucle que nos interese, aunque el más utilizado es el bucle for:

En este caso, como puedes ver, el for no utiliza un range() para establecer cuántas veces debe iterar, sino que utiliza el operador in asociado a una lista. La línea 2 se leería así: para cada elemento que haya en la variable amigos, guárdalo en amigo y realiza las operaciones indicadas en el bloque de sentencias interior.
Una forma equivalente de hacer lo anterior, podría ser usar el range() con el número de elementos de la lista. ¿Pero cómo sabemos la cantidad de elementos que tiene la lista? Utilizando la función que ya conocemos, len().

Si te preguntas en qué casos estaría indicado usar una lista, aquí te dejo tres ejemplos prácticos muy clarificadores:
- Gestión de tareas en una aplicación: Supongo que conoces las aplicaciones como como “Todoist” o “Trello” (si no, son aplicaciones para gestionar tareas). Cuando añades tareas a tu día o a un proyecto, las registras en una lista. Puedes añadir nuevas tareas, eliminar tareas completadas o incluso reordenarlas según su prioridad o fecha de vencimiento.
- Historial de navegación en un navegador web: Cuando visitas páginas web en navegadores como Chrome o Firefox, estas páginas se almacenan en un historial, que es esencialmente una lista. Puedes ver las páginas que visitaste recientemente, eliminar elementos del historial o incluso buscar dentro de él.
- Carrito de compras en una tienda online: Al comprar en sitios como Amazon o Shein, vas añadiendo productos a tu carrito de compras. Este carrito es una lista de productos que puedes modificar, añadiendo nuevos productos, eliminando los que ya no quieres o cambiando la cantidad de un ítem específico.
Como ves, estos ejemplos ilustran las características inherentes a las listas: estructura de datos dinámica y modificable.
Ejercicio 1.4 – Listas
Resuelve con la ayuda del profesor cada uno de estos 10 ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python para cada uno –1.py, 2.py, 3.py, …, 10.py-, luego comprime los 10 archivos y sube el archivo comprimido –ejercicio1_3.zip-):
- Crea una lista con los nombres de tus 5 amigos favoritos y muestra el tercer elemento de la lista.
- Dada la lista de números [5, 10, 15, 20, 25], suma todos los elementos y muestra el resultado.
- Crea una lista con tus tres películas favoritas y añade una cuarta al final.
- Dada la lista [“a”, “b”, “c”, “d”, “e”], muestra la lista invertida.
- Crea una lista con los números del 1 al 10 y muestra todos los números en posición par.
- Dada la lista [“gato”, “perro”, “loro”], inserta la palabra “tortuga” en la segunda posición.
- Elimina el último elemento de la lista anterior ([“gato”, “tortuga”, “perro”, “loro”]).
- Dada una lista de nombres, cuenta cuántos nombres tienen una longitud mayor a 4 caracteres.
- Crea una lista con los números del 1 al 5 y otra con los números del 6 al 10. Une ambas listas y muestra el resultado.
- Dada la lista [1, 2, 3, 2, 2, 3, 4, 5], elimina todos los números 2.
1.4.2. Tuplas.
Una tupla es una estructura de datos similar a la lista, pero inmutable, lo que significa que una vez definida no se pueden modificar sus elementos. En este caso, en vez de definirse con corchetes [ ], se utilizan los paréntesis ( ).

Como decíamos más arriba, se usan en situaciones donde necesitamos asegurarnos que los datos no sean modificados. Por ello, no podemos modificar, añadir o eliminar elementos.
No obstante, sí que podemos hacer otras operaciones comunes como acceder a sus elementos (mediante índices), obtener su longitud (número de elementos) con len(), verificar si un elemento está en la tupla con in, y obtener la posición que ocupa un elemento en la tupla con index().

De la misma manera que con las listas, es muy frecuente tener que recorrer una tupla para realizar las operaciones que nos interesen.

Quizás te has quedado pensando en qué tipo de situaciones aplicarías esta estructura de datos. Yo te ayudo:
- Coordenadas geográficas: Las aplicaciones de mapas y navegación, como Google Maps o Waze, utilizan coordenadas para representar ubicaciones. Una coordenada (latitud, longitud) se puede representar como una tupla, ya que no cambiará una vez definida.
- Información de un libro en una biblioteca: En un sistema de gestión de bibliotecas, cada libro podría representarse mediante una tupla que contenga (título, autor, ISBN, año de publicación). Dado que esta información no debería modificarse arbitrariamente, es apropiado usar una tupla.
- Datos de un estudiante en un registro escolar: Un estudiante podría tener un registro que contenga (nombre, fecha de nacimiento, matrícula). Dicha información, una vez registrada, suele ser inmutable, por lo que una tupla es una elección adecuada.
¿Y qué es lo que convierte a estos tres casos en idóneos para tuplas? Pues en que necesitamos una estructura de datos que sea estática e inmutable. Como las tuplas.
Ejercicio 1.5 – Tuplas
Resuelve con la ayuda del profesor este ejercicio y súbelo a su correspondiente entrega en classroom (debes crear un archivo Python –1.py-, luego comprímelo y sube el archivo comprimido –ejercicio1_5.zip-):
- Dada la siguiente tupla (‘Madrid’, ‘Barcelona’, ‘Valencia’, ‘Sevilla’, ‘Zaragoza’), encuentra la posición del elemento ‘Sevilla’ y la longitud total de la tupla.
1.4.3. Conjuntos (Sets).
Los conjuntos en Python son una colección no ordenada de elementos únicos. A diferencia de las listas y las tuplas, no pueden tener múltiples apariciones del mismo elemento. Están diseñados para modelar las propiedades y operaciones matemáticas de los conjuntos convencionales.
Aunque a priori pueda parecer una utilidad compleja y con pocas aplicaciones, déjame enseñarte tres escenarios en los que podrían ser útiles:
- Sistema de recomendación musical: piensa en una aplicación como Spotify. Dos usuarios, Juan y Ana, han escuchado y hecho like diferentes canciones. Si queremos hacer una lista de reproducción que contenga canciones que a ambos hayan gustado, podemos representar las listas de canciones de cada usuario como conjuntos y encontrar su intersección. Del mismo modo, si queremos encontrar canciones que Juan haya likeado pero Ana no, usaríamos la diferencia entre los conjuntos. Si quisiéramos combinar sus gustos en una lista única sin repetir canciones, usaríamos la unión de conjuntos.
- Gestión de membresías en un club: Supongamos que gestionas el patronato de deportes y tienes diferentes categorías: fútbol, baloncesto y tenis. Cada categoría tiene su lista de miembros. Si quieres saber quiénes están inscritos en más de un deporte, podrías usar la intersección de conjuntos. Si quisieras saber todos los miembros del club sin duplicados (porque algunos están en más de una categoría), usarías la unión de conjuntos.
- Sistema de filtrado de correos electrónicos: Si tienes una lista de contactos a los que envías correos informativos y otra lista de personas que han solicitado no recibir esos correos (lista negra), antes de hacer un envío masivo, deberías coger la diferencia entre el conjunto de contactos y el conjunto de la lista negra para asegurarte de que no estás enviando correos a quienes han optado por no recibirlos.
En todos estos ejemplos, los conjuntos serían útiles porque permiten realizar operaciones de unión, intersección y diferencia de manera eficiente y garantizan la unicidad de los elementos, evitando duplicados.
Ahora que ya conoces la utilidad de los conjuntos, veamos cómo los programamos en Python.
Creación de conjuntos: los conjuntos se pueden crear usando las llaves { } o con la función set().

Acceder a elementos: Debido a que los conjuntos son no ordenados, no se puede acceder a un elemento por su índice. Sin embargo, se puede recorrer un conjunto usando un bucle for.

Añadir elementos: Se utiliza el método add() para agregar un elemento y el método update() para agregar múltiples elementos.

Eliminar elementos: Existen varios métodos para eliminar elementos de un conjunto, como remove(), discard(), y pop(). La diferencia entre remove() y discard() es que el primero generará un error si el elemento no existe, mientras que el segundo no.

Operaciones con conjuntos: Python también admite operaciones matemáticas con conjuntos, como unión, intersección y diferencia.

Veamos cómo programar estas operaciones.

Otros métodos útiles:
- clear(): Elimina todos los elementos del conjunto.
- copy(): Devuelve una copia del conjunto.
- issubset(): Verifica si un conjunto es subconjunto de otro.
- issuperset(): Verifica si un conjunto contiene a otro conjunto.
- symmetric_difference(): Devuelve un conjunto con los elementos que están en uno de los conjuntos, pero no en ambos.
Ejercicio 1.6 – Conjuntos
Resuelve con la ayuda del profesor estos ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python por cada ejercicio –1.py, 2.py,…, 5.py-, luego comprímelo y sube el archivo comprimido –ejercicio1_6.zip-):
- Dado dos conjuntos de números, encuentra todos los números que están presentes en ambos conjuntos.
- Dado un conjunto de números, elimina el número 5 (si está presente).
- Encuentra la unión de dos conjuntos de números dados.
- Dado dos conjuntos de números, determina si el primero es un subconjunto del segundo.
- Dado un conjunto de estudiantes que aprueban Matemáticas y otro conjunto de estudiantes que aprueban Física, encuentra un conjunto de estudiantes que aprueben ambas materias pero no ninguna otra.
1.4.4. Diccionarios.
Un diccionario es una estructura de datos que permite guardar una colección no ordenada de pares clave-valor, siendo las claves únicas dentro de un mismo diccionario (es decir que no pueden existir dos elementos con una misma clave).
Ahondemos un poco más en sus interesantes características:
- No ordenados: Aunque los diccionarios de Python mantienen el orden de inserción, por definición, un diccionario no tiene un orden específico.
- Mutables: Podemos agregar, modificar y eliminar pares clave-valor después de la creación del diccionario.
- Claves únicas: Cada clave puede aparecer solo una vez. Si se asigna un valor a una clave existente, se sobrescribe el valor anterior.
Quizás todavía no visualices el aspecto de un diccionario. Vamos a ver cómo se crean para que te aproximes un poco más a su entendimiento. Los diccionarios se pueden crear utilizando llaves { } y especificando la clave y el valor de cada elemento, separados por dos puntos :

A veces resulta más sencillo escribir los diccionarios de otra manera para mejorar la lectura del código:

Ahora sí que queda más claro, ¿verdad? Bueno, para que termines de entenderlo, veamos algunos ejemplos de la vida real donde podríamos aplicar esta estructura de datos:
- Traductor Inglés-Español Básico: Imagina que estás creando una herramienta sencilla de traducción entre inglés y español para palabras comunes. Un diccionario sería perfecto para almacenar las traducciones.

Así, al buscar la palabra “apple” en el diccionario, obtendrías “manzana”.
- Lista de Precios de una Cafetería: Si estás gestionando una pequeña cafetería, podrías utilizar un diccionario para representar la lista de precios de los productos que vendes.

Cuando un cliente pide un café, simplemente buscas “café” en el diccionario para saber su precio.
- Códigos de Países y sus Capitales: Para alguien que esté aprendiendo geografía, un diccionario puede ser útil para relacionar códigos de países con sus respectivas capitales.

De esta forma, si te preguntas cuál es la capital de Italia (“IT”), puedes consultar el diccionario y ver que es “Roma”.
Ahora sí, ¿verdad? Confío en que sí. Sigamos analizando su funcionamiento.
Acceso a los elementos.
Se accede a los valores del diccionario utilizando la clave correspondiente entre corchetes.

Si intentamos acceder con una clave que no existe, Python nos arrojará un error. Para evitar esto, podemos usar el método get() que devolverá None si la clave no existe (o un valor por defecto que podemos especificar).

Añadir y modificar elementos.
Añadir un nuevo par clave-valor es tan sencillo como asignar un valor a una nueva clave:

Para modificar el valor asociado a una clave, simplemente asignamos un nuevo valor a esa clave:

Eliminación de elementos.
Podemos eliminar un par clave-valor utilizando la instrucción del:

El método pop() también nos permite eliminar un elemento y, además, devuelve el valor del elemento eliminado:

Algunas otras utilidades interesantes.
- keys(): Devuelve una lista con todas las claves del diccionario.
- values(): Devuelve una lista con todos los valores del diccionario.
- items(): Devuelve una lista de tuplas, cada tupla consta de dos elementos: la clave y su correspondiente valor.
Recorrer un diccionario.
Un diccionario se puede recorrer de diversas formas dependiendo de lo que necesitemos:

Los diccionarios son herramientas poderosas y versátiles en Python, útiles en numerosas situaciones donde necesitamos una asociación clave-valor.
Ejercicio 1.7 – Diccionarios
Resuelve con la ayuda del profesor estos ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python por cada ejercicio –1.py, 2.py,…, 6.py-, luego comprímelo y sube el archivo comprimido –ejercicio1_7.zip-):
- Crea un diccionario que contenga 10 colores y sus traducciones al inglés.
- A partir del diccionario colores del ejercicio anterior, muestra la traducción al inglés de “verde”.
- Añade al diccionario colores la traducción de “celeste”.
- Elimina la traducción de “azul” del diccionario colores.
- Comprueba si “verde” está en el diccionario colores.
- Cuenta cuántos colores en inglés se escriben con más de 5 caracteres.
1.5. Funciones y bibliotecas de funciones.
Las funciones son bloques de código reutilizables que realizan una tarea específica. Son fundamentales en la programación, ya que permiten dividir el código en partes más pequeñas y manejables, evitando la repetición y haciendo que el código sea más modular y fácil de mantener.
Se trata de crear código de un programa, elaborando pequeñas utilidades individuales que podamos reutilizar en otras aplicaciones. Por ejemplo: la funcionalidad de iniciar sesión se utiliza en muchas aplicaciones, ¿por qué programarlo nuevamente desde cero en cada nueva aplicación que desarrollamos? Lo ideal es escribir esa parte del programa una vez, de manera que podamos reutilizar el código en cada nuevo proyecto que necesitemos esa utilidad.
1.5.1. ¿Qué es una función?
Una función es un bloque de código con un nombre asociado que puede recibir algunos valores (denominados parámetros o argumentos) y devolver un valor de resultado. Una vez que una función está definida, puede ser utilizada (o “llamada”) desde cualquier parte de su programa, tantas veces como se desee.

En este ejemplo, se ha definido una función llamada saludo que toma un parámetro nombre. La función devuelve un saludo personalizado con ese nombre. Luego, la función se llama con el argumento “Ana”. Las líneas 1 y 2 representan la definición de la función, y la línea 4 representa cómo usamos la función, se dice que “se llama a la función”.
El ordenador va leyendo el código de arriba a abajo. Cuando llega a la primera línea y se encuentra la palabra clave def, sabe que no debe ejecutar esa línea, porque simplemente se está definiendo una función. Esa función no se ejecutará hasta que alguien la llame desde algún otro punto del programa. Esto ocurre en la línea 4. La función print llama a la función saludo indicándole el argumento “Ana”. En ese momento, el ordenador vuelve a la línea 1, sustituye nombre por “Ana”, ejecuta la línea 2 y devuelve esa cadena de texto. Como ya ha terminado la función, el ordenador vuelve al punto donde lo dejó (la línea 4). En ese momento saludo(“Ana”) se sustituye por la cadena que devolvió la función, y el print la saca por la pantalla.
1.5.2. Parámetros y argumentos
Los términos parámetro y argumento pueden ser un poco confusos, pero en general:
- Parámetro es una variable que se utiliza en la declaración de una función.
- Argumento es el valor que se pasa a la función cuando se llama.

1.5.3. Valores predeterminados
En Python, es posible asignar valores predeterminados a los parámetros, lo que significa que si no se proporciona un argumento al llamar a la función, se utilizará el valor predeterminado.

1.5.4. Bibliotecas de funciones (Módulos)
En programación, es común reutilizar código para tareas que se repiten con frecuencia. Python proporciona una rica biblioteca estándar de módulos que contienen funciones, variables y clases para realizar una amplia variedad de tareas.
Para usar estas funciones y clases, es necesario importar el módulo correspondiente. Una vez importado, podemos acceder a sus funciones y clases usando la notación de punto.

En el código anterior, hemos importado la biblioteca math (que contiene una larga lista de funciones dedicadas a cálculos matemáticos) y a continuación hemos usado su función sqrt que calcula la raíz cuadrada (square root) del número que le pasemos como argumento (25 en este caso).
Quizás esto te haya parecido poco espectacular, pero déjame enseñarte algunas de las capacidades de otra librería estándar de Python, una llamada Matplotlib. Entre otras muchas utilidades esta librería nos permite graficar datos en pantalla. De esta forma tan sencilla podemos mostrar un histograma de las ventas de frutas en un mes:

Primero importamos la parte de la librería que vamos a usar y la renombramos como plt. Después creamos dos listas, una para el nombre de las frutas y otra para su número de ventas. También definimos los colores que queremos que tenga cada barra del histograma y, por último, construimos el gráfico indicando el título y la leyenda que debe llevar en cada eje. El resultado es este:

Precioso.
Si aún te quedan dudas de la utilidad de las librerías, en este enlace tienes una lista de 20 bibliotecas de Python que son una maravilla. Échales un vistazo por curiosidad, simplemente para que veas qué cantidad de cosas útiles están ya programadas y listas para que podamos usarlas en nuestros programas.
Y eso es sólo una pequeñísima muestra, porque existen miles.
Además, para organizar mejor nuestros programas, es recomendable separar en ficheros (módulos = bibliotecas = librerías) aquellas utilidades comunes entorno a algún criterio de nuestro interés.
Por ejemplo: piensa que estas desarrollando un aplicación que necesita realizar muchas operaciones matemáticas por un lado, y también muchas tareas gráficas por otro. Lo ideal sería crear un fichero operaciones.py cuyo contenido sea la definición de todas las funciones que necesitarás para las operaciones matemáticas:

Y luego en tu aplicación, cada vez que necesites realizar una de las operaciones contenidas en ese fichero, importas tu librería operaciones y usas la función que desees:

De la misma manera, podrías escribir un fichero graficas.py cuyo contenido fueran una relación de funciones dedicadas a realizar tareas gráficas sobre imágenes. Luego en el programa principal, podrías importar esa librería y trabajar de la misma manera que con las funciones del fichero operaciones.py. Esta es una forma tremendamente útil y reutilizable de organizar las aplicaciones. Además, la próxima vez que estés en otro proyecto completamente distinto que también necesite realizar operaciones matemáticas y/o tareas gráficas sobre imágenes, podrás recuperar tus ficheros operaciones.py y graficas.py, y te ahorrarás montones de horas de trabajo.
1.5.5. Reutilización de código
Como ya hemos visto más arriba, las funciones y bibliotecas, nos permiten reutilizar código, lo que significa que podemos escribir una función una vez y usarla en diferentes lugares de nuestro programa, o incluso en otros programas. Esto no solo ahorra tiempo y reduce errores, sino que también hace que nuestro código sea más limpio y legible.
Veamos un ejemplo muy clarificador. Supongamos que estás creando un programa para una tienda de frutas y quieres calcular el precio total de varios tipos de frutas que compres. Sin la reutilización de código, podrías hacer algo así:

Puedes ver que estamos repitiendo el mismo cálculo una y otra vez. Con la reutilización de código mediante funciones, esto puede ser mucho más eficiente:

En el segundo ejemplo, hemos definido una función calcular_total() que realiza el cálculo del precio total por nosotros. Luego, simplemente llamamos a esta función para cada tipo de fruta que queramos calcular.
En este ejemplo tan sencillo nos hemos ahorrado un 35% de líneas de código simplemente definiendo una función que usamos tres veces. Imagina el ahorro que supondría si aplicáramos este mismo principio a un programa de miles de líneas de código, en el que además nuestras funciones estuvieran organizadas en bibliotecas propias. La diferencia sería abismal.
La reutilización de código es uno de los principios fundamentales de la programación, y aprender a usar funciones efectivamente es esencial para convertirse en un buen programador.
Ejercicio 1.8 – Funciones
Resuelve con la ayuda del profesor estos ejercicios y súbelos a su correspondiente entrega en classroom (debes crear un archivo Python por cada ejercicio –1.py, 2.py,…, 6.py-, luego comprímelo y sube el archivo comprimido –ejercicio1_8.zip-):
- Escribe una función llamada saludo que acepte un nombre como argumento y devuelva “¡Hola, [nombre]!”.
- Importa la biblioteca math y utiliza la función sqrt para calcular la raíz cuadrada de 81.
- Escribe una función potencia que tome dos argumentos: una base y un exponente. El exponente debería tener un valor por defecto de 2.
- Supongamos que tienes dos funciones: suma (que recibe dos parámetros a y b, y devuelve la suma de los dos a+b) y resta (que recibe dos parámetros a y b, y devuelve la resta del primero menos el segundo a-b). Escribe una tercera función llamada operacion (que recibe dos parámetros a y b) y haciendo uso de las dos funciones anteriores, devuelva 2*suma(a,b)-resta(a,b). En tu programa debes escribir el contenido de las tres funciones. La última línea de tu programa debe ser print(operacion(5,3)).
- Importa la biblioteca datetime y muestra la fecha actual (debes investigar por tu cuenta).
- Crea un módulo llamado mimodulo que contenga al menos tres funciones (tienes libertad para elegir su utilidad). Importa ese módulo y utiliza sus funciones.
1.6. Manipulación de archivos.
Manipular archivos es esencial en programación, ya que permite a los programas interactuar con datos persistentes. En Python, esta tarea es relativamente directa gracias a su biblioteca estándar.
En los siguientes apartados veremos qué operaciones podemos realizar con ellos.
1.6.1. Abrir un archivo.
La función open() es la principal herramienta para abrir un archivo. Su sintaxis básica es:

- ruta_del_archivo: Es la dirección del archivo que deseas abrir. Puede ser una ruta relativa o absoluta.
- modo: Indica cómo se abrirá el archivo. Los modos comunes son r (lectura), w (escritura), a (añadir) y b (modo binario).
1.6.2. Leer un archivo.
Una vez abierto un archivo en modo lectura (r), puedes usar algunas de estas funciones:
- archivo.read(): Lee todo el archivo.
- archivo.readline(): Lee una línea del archivo.
- archivo.readlines(): Devuelve una lista donde cada elemento es una línea del archivo.
Por ejemplo, si tenemos un archivo con los nombres de los alumnos:

Podemos escribir un programa en Python que lo abra en modo lectura, lea su contenido y lo muestre en pantalla.

1.6.3. Escribir en un archivo.
Al abrir un archivo en modo escritura (w) o añadir (a), puedes escribir en él:
- archivo.write(‘texto’): Escribe “texto” en el archivo.
Vamos a crear un sencillo programa que le pida al usuario que introduzca el nombre de un alumno nuevo y el programa automáticamente lo guarde en el archivo que habíamos visto anteriormente.

El resultado lo podrás ver si vas al directorio donde tenías el archivo y lo abres:

¿Magia? No, programación.
Hay un pequeño pero importantísimo detalle que no puedes pasar por alto. El nombre que hemos añadido se ha situado al final del fichero porque lo abrimos en modo a (append). Si hubiéramos abierto el archivo en modo w (write), nos habríamos cargado el contenido que tenía el archivo y aparecería únicamente el último nombre que hemos añadido durante la ejecución del programa. Mucho ojo con esto.
1.6.4. Cerrar un archivo.
Es importante cerrar un archivo después de usarlo, de hecho, muchos de los problemas que se producen en los programas que manipulan archivos del dispositivo es precisamente porque el programador olvidó cerrar un archivo tras manipularlo.
Como has podido ver en todos los ejemplos de esta sección, la última instrucción siempre debe ser la de cierre del archivo:

1.6.5. Usar with .. as
La declaración with en Python es útil porque se encarga automáticamente de cerrar el archivo, incluso si se producen errores durante su manipulación. Considéralo como un seguro de vida cuando manipulamos archivos.

1.6.6. Manipulación de archivos binarios.
Como podrás imaginar, cuando estamos desarrollando una aplicación, los archivos que queremos manipular no son siempre archivos de texto.
Podríamos necesitar manipular una imagen, un vídeo, un audio o cualquier otra estructura de almacenamiento persistente. Son los llamados archivos binarios.
Para manejar archivos binarios, se utiliza el modo b (binary). Por ejemplo, para copiar una imagen:

1.6.7. Otros métodos y funciones útiles.
Hasta ahora hemos visto una pequeña parte de las utilidades que ofrece Python para manipular archivos. Aparte del inmenso catálogo de bibliotecas que existen para ellos, hay otras funciones sencillas que podrían interesarnos para tareas muy comunes, como por ejemplo:
- archivo.tell(): Devuelve la posición actual del cursor en el archivo.
- archivo.seek(posicion): Mueve el cursor a una posición determinada.
- os.path.exists(‘ruta_del_archivo’): Verifica si un archivo existe.
- os.remove(‘ruta_del_archivo’): Elimina un archivo.
Te invito a investigar por tu cuenta cada una de ellas y escribir un pequeño ejemplo de su uso.
La manipulación de archivos en Python es esencial para muchas tareas, como la lectura de datos, la persistencia de información o la manipulación de archivos binarios. Afortunadamente, Python ofrece herramientas intuitivas y potentes para estas operaciones tal y como hemos comprobado en esta sección.
Ejercicio 1.9 – Ficheros
Resuelve con la ayuda del profesor este enunciado y súbelo a su correspondiente entrega en classroom (debes crear un único archivo Python –1.py-, luego comprímelo y sube el archivo comprimido –ejercicio1_9.zip-):
Escribe un programa que le pida al usuario nombres de grupos de música y los vaya añadiendo a un archivo de texto llamado misgrupos.txt. El programa dejará de pedir grupos cuando el usuario escriba la palabra Salir. Cuando se guarde un grupo en el fichero debe quedar claro el orden en el que introdujeron. Al finalizar el programa, el contenido del fichero debe ser algo parecido a esto:
- Metallica.
- Guns N’ Roses.
- Nightwish.
- Héroes del Silencio.
- Celtas Cortos.
- Antílopez.
- Vetusta Morla.
- Love of Lesbian.
- U2.
- The Rolling Stones.
1.7. Orientación a Objetos
La programación orientada a objetos (POO) se ha consolidado como uno de los principales paradigmas de programación desde su concepción en la década de 1960. Su filosofía se centra en la construcción de programas a partir de “objetos“, entidades que encapsulan datos (atributos, también llamados propiedades) y las operaciones (métodos) que pueden realizar con o sobre esos datos. Este enfoque se contrapone a la programación procedural, donde el énfasis recae en las funciones y la secuencia de operaciones.
La POO se inspira en la forma en que percibimos y categorizamos los objetos en el mundo real. Consideremos cómo identificamos un coche: tiene atributos como color, marca y velocidad máxima, y tiene operaciones asociadas como arrancar, acelerar y frenar. Del mismo modo, en POO, podríamos tener una clase “Coche” con atributos y métodos que modelan estas características y comportamientos.
El paradigma orientado a objetos ofrece varias ventajas:
- Abstracción: permite modelar entidades del mundo real (como coches, libros o personas) en términos de atributos (datos) y comportamientos (funciones o métodos).
Imagina que estamos modelando un sistema para una biblioteca. Una entidad fundamental en una biblioteca es el libro. Sin embargo, no necesitamos todos los detalles del libro para representarlo en nuestro sistema, sólo los aspectos relevantes como título, autor, ISBN y estado de disponibilidad. No nos interesa, por ejemplo, el tipo de papel o tinta utilizada. Esta selección de características específicas y relevantes del libro es una forma de abstracción.
- Encapsulamiento: oculta los detalles internos de cómo un objeto opera y almacena sus datos, mostrando solo las operaciones relevantes. Esto facilita la modificación y mejora de los objetos sin afectar otras partes del código.
Siguiendo con el libro, cada libro puede tener una función prestar() para cuando un cliente desea tomarlo prestado. Sin embargo, el proceso interno de qué sucede cuando se presta un libro (cambiar su estado a no disponible, registrar quién lo tomó, establecer una fecha de devolución) queda oculto para el resto del sistema. Sólo sabemos que al invocar prestar(), el libro ya no estará disponible.
- Modularidad: los programas se construyen a partir de objetos bien definidos, lo que facilita su diseño, prueba y mantenimiento.
Nuestra biblioteca, además de libros, tiene clientes, empleados, estantes, y áreas de lectura. Cada una de estas entidades puede ser modelada como un objeto independiente con sus propios atributos y métodos, permitiendo trabajar en ellas de manera separada. De esta forma, podemos mejorar el sistema de registro de clientes sin afectar cómo funcionan los libros o los empleados.
- Reutilización: las clases, una vez definidas, pueden reutilizarse en diferentes partes del programa o incluso en diferentes programas, reduciendo la redundancia y acelerando el desarrollo.
Supongamos que queremos ampliar nuestro sistema para incluir revistas además de libros. Muchas características de los libros (como título, autor, estado de disponibilidad) también se aplican a las revistas. En lugar de escribir un nuevo objeto desde cero, podemos reutilizar gran parte del código de nuestro objeto libro para crear el objeto revista.
- Herencia: permite definir nuevas clases basadas en clases existentes, heredando sus atributos y comportamientos. Esto promueve una jerarquía y una organización estructurada del código.
A raíz de la ventaja anterior, podemos tener una clase general llamada MaterialImpreso que contenga atributos y métodos comunes como título y autor. Tanto la clase Libro como la clase Revista pueden heredar de MaterialImpreso, y así automáticamente tener esos atributos y métodos, y agregar o modificar los específicos para cada uno (por ejemplo, una revista podría tener un atributo numero_edicion).
- Polimorfismo: los objetos de diferentes clases pueden ser tratados como objetos de una clase común, especialmente cuando se heredan de una superclase común. Esto proporciona flexibilidad en cómo se implementan y se invocan las operaciones.
Si queremos mostrar en nuestro sistema una lista de todos los materiales impresos disponibles para préstamo, gracias al polimorfismo, podemos tratar tanto los libros como las revistas como si fueran del mismo tipo (MaterialImpreso) y llamar al método mostrar_informacion() en cada uno, sin preocuparnos si es un libro o una revista. Si el método está implementado de manera diferente para libros y revistas, mostrará la información correspondiente automáticamente.
Estas ventajas han llevado a la adopción generalizada de la POO en muchas áreas del desarrollo de software, desde aplicaciones de escritorio y desarrollo web hasta programación de sistemas y juegos. Python, siendo un lenguaje multiparadigma, no solo soporta la programación orientada a objetos, sino que la integra profundamente en su diseño, ofreciendo herramientas y estructuras para aprovechar plenamente los beneficios de la POO. En esta sección, nos sumergiremos en los fundamentos de la programación orientada a objetos en Python, explorando conceptos como clases, objetos, constructores, herencia, y más.
1.7.1. Clases y objetos.
Las clases y objetos son conceptos centrales en la programación orientada a objetos. Estos términos, aunque parezcan abstractos al principio, están directamente relacionados con cómo conceptualizamos y modelamos cosas en el mundo real.
Clase.
Es una plantilla o prototipo que define y organiza propiedades (variables) y comportamientos (métodos) comunes a cualquier objeto de esa categoría. Piensa en una clase como un plano o un molde.
Objeto.
Es una instancia o manifestación concreta de una clase. Un objeto representa una entidad específica que posee las características definidas por su clase y tiene un estado particular.
Supongamos que eres un diseñador de videojuegos y estás creando un juego de carreras. Tienes diferentes tipos de coches en el juego.
Clase: Coche
Propiedades:
- Marca.
- Modelo.
- Velocidad máxima.
- Color.
Métodos:
- Acelerar.
- Frenar.
- Girar.
Cada coche en el juego, como un Seat León de color gris que puede alcanzar los 220 km/h, es un objeto. Es una instancia de la clase Coche.
Veamos qué aspecto tiene todo lo anterior si programamos esta clase con sus propiedades y métodos.

Ahora, si queremos crear un Seat León de color gris en nuestro juego, simplemente creamos una instancia de la clase Coche:

Con este objeto, leon_gris, podemos acelerar, frenar o girar:

Cada vez que quieras agregar un nuevo coche al juego, no necesitas reescribir toda la lógica del coche. Simplemente creas una nueva instancia de la clase Coche, y eso es la magia de la programación orientada a objetos: reutilización y organización.
Si sueles jugar a videojuegos, o incluso si te interesa el diseño gráfico o animación, puedes ver fácilmente cómo estos conceptos se aplican en mundos virtuales y simulaciones. Además, comprender estos conceptos es fundamental si deseas entrar en campos como el desarrollo de juegos y muchos otros tipos de software en el futuro.
1.7.2. Constructores.
Los constructores son métodos especiales que tienen la tarea de inicializar los objetos de una clase. Es la primera pieza de código que se ejecuta cuando se crea un nuevo objeto a partir de una clase. En Python, el constructor se conoce como __init__.
El propósito de un constructor es establecer un estado inicial para el objeto, asignando valores a sus atributos o realizando cualquier otra configuración necesaria.
Características del constructor:
- Nombre especial: en Python, siempre se llama __init__.
- Se ejecuta automáticamente: no es necesario llamar al constructor explícitamente. Se invoca automáticamente cuando se crea una instancia de la clase.
- Puede tener parámetros: estos parámetros permiten pasar valores al objeto durante su creación para inicializar sus atributos.
- Un objeto no está completamente formado hasta que se ha ejecutado el constructor: esto significa que no puedes interactuar completamente con un objeto hasta que su constructor haya finalizado.
Ponte en situación. Imagina que estás construyendo una red social para estudiantes de tu edad. Cada vez que un nuevo usuario se registra en la plataforma, necesita crear un perfil. El perfil tendrá información básica, como nombre, fecha de nacimiento, correo electrónico y una foto de perfil.
Clase: PerfilUsuario
El constructor de esta clase inicializará estos atributos. Aquí te muestro cómo sería:

Aquí, el constructor __init__ inicializa el perfil del usuario con su nombre, fecha de nacimiento, correo electrónico y una foto de perfil (que tiene un valor predeterminado si el usuario no proporciona una).
Cuando un nuevo usuario se registra y crea un perfil, el código podría verse así:

Con este objeto nuevo_usuario, ahora se puede interactuar con el perfil de Alicia, agregar amigos, publicar actualizaciones, etc.
Es importante destacar que el constructor no solo está inicializando los datos pasados como parámetros. También está estableciendo estructuras de datos vacías (amigos y publicaciones) para el perfil del usuario. De esta manera, cada perfil es una “instancia completamente formada” con todo lo necesario para funcionar en la red social desde el momento de su creación.
Es posible que ahora pensar en cómo funcionan “por detrás” las redes sociales puede ser intrigante. Sin embargo, desarrollar una red social, aunque sea una versión simple, puede ser un proyecto fascinante y educativo que involucre muchos de los conceptos de programación que estás aprendiendo.
1.7.3. Herencia.
La herencia es uno de los cuatro pilares fundamentales de la programación orientada a objetos (junto con la encapsulación, la abstracción y el polimorfismo). La herencia permite a una clase (denominada clase derivada o subclase) heredar atributos y métodos de otra clase (denominada clase base o superclase). Esta relación de “padre-hijo” entre clases ayuda a reutilizar y organizar el código, reduciendo la redundancia.

Estas son algunas de las principales ventajas de la herencia:
- Reutilización de código: una subclase hereda los atributos y métodos de la superclase, lo que evita tener que reescribir el mismo código.
- Extensibilidad: una subclase puede extender o modificar los comportamientos que ha heredado.
- Estructura lógica: permite una organización jerárquica y una relación clara entre clases.
- Polimorfismo: una subclase puede ser tratada como si fuera de su tipo de superclase o de cualquier tipo en su línea de ascendencia.
Supongamos que estás diseñando un videojuego RPG (Role-Playing Game, juego de rol) para jugar con tus amigos. En este juego, hay diferentes tipos de personajes con habilidades y características distintas.
Esta sería la jerarquía de clases:

Veamos cómo podemos programar cada una de las clases.
Clase Base: Personaje
Todos los personajes, independientemente de su tipo, tendrán ciertos atributos y habilidades comunes, como salud, energía, nombre y la capacidad de moverse.

Clase Derivada: Mago
El mago es un tipo de personaje que, además de las características comunes, tiene la capacidad de lanzar hechizos.

Clase Derivada: Guerrero
El guerrero es otro tipo de personaje que tiene la capacidad de atacar con armas.

Gracias a la herencia, las clases Mago y Guerrero pueden reutilizar el código de la clase Personaje y agregar sus propias características y habilidades únicas.
A la hora de jugar:

Esto crea una experiencia de juego dinámica y extensible, ya que siempre se pueden añadir más clases de personajes con habilidades únicas, pero sin tener que reescribir las características comunes.
Como ves, el mundo de los videojuegos puede ser un campo apasionante para explorar y entender la programación orientada a objetos con herencia (una característica que facilita enormemente un desarrollo de aplicaciones mucho más intuitivo).
1.7.4. Bibliotecas de clases.
Las bibliotecas de clases (al igual que cuando hablábamos de funciones), a menudo referidas como librerías o módulos, son colecciones de clases predefinidas y relacionadas entre sí, diseñadas para realizar tareas específicas o manejar conjuntos particulares de funcionalidades. Estas bibliotecas pueden ser proporcionadas por el lenguaje de programación en sí, desarrolladas por terceros o creadas por nosotros mismos para reutilizar en diferentes proyectos.
Veamos algunas de las ventajas principales de las bibliotecas de clases:
- Reutilización de código: en lugar de reinventar la rueda, puedes aprovechar las clases y métodos que ya han sido escritos y probados por otros.
- Organización: las clases relacionadas se agrupan juntas, lo que facilita encontrar y utilizar las funcionalidades que necesitas.
- Eficiencia: las clases en las bibliotecas a menudo están optimizadas para rendimiento y se actualizan regularmente para incorporar mejoras.
- Estándares de codificación: al usar bibliotecas de terceros, te aseguras de que tu código se adhiere a estándares de la industria, lo que puede facilitar el trabajo en equipo y el mantenimiento a largo plazo.
Sigamos con el ejemplo de la creación de un videojuego, pero esta vez utilizando una biblioteca de clases que ya existe llamada pygame, que proporciona clases y funciones para facilitar el desarrollo de juegos en Python.
Instalación.
Primero, necesitas instalar pygame (para ello abre la consola de tu sistema operativo y lanza):
pip install pygame
Supongamos que quieres hacer un juego en el que un jugador pueda mover un círculo por la pantalla.

En este ejemplo, se utilizan clases y funciones de la biblioteca pygame. Las clases y funciones de pygame nos permiten manejar fácilmente la ventana del juego, los eventos de entrada del usuario y el dibujo en pantalla. Sin una biblioteca como esta, crear un juego incluso tan simple como este sería una tarea muchísimo más costosa.
Te animo a que sigas profundizando en el mundo de la POO y las bibliotecas de clases disponibles. A poco tiempo que inviertas verás las inmensas posibilidades que se abren ante tus ojos. Todo está en internet a tu alcance. Sólo tu iniciativa y ganas de aprender te separan de ser el creador del próximo juego de éxito.
Ejercicio 1.10 – POO
Resuelve con la ayuda del profesor estos enunciados y súbelos a su correspondiente entrega en classroom (debes crear los archivos Python que necesites, luego comprímelos y sube el archivo comprimido –ejercicio1_10.zip-):
- Crear una clase llamada Libro que contenga los siguientes atributos: titulo, autor y paginas. También, debe tener un método info que retorne la información del libro en el formato: “Título: [titulo], Autor: [autor], Páginas: [paginas]“.
- Extender la clase Libro del ejercicio anterior. Agregar un constructor en el cual se inicialice el libro con un título, un autor y una cantidad de páginas. También, agregar un método leer que reduzca el número de páginas pendientes conforme se va leyendo.
- Crear una clase llamada Ebook que herede de la clase Libro. Esta clase tendrá un atributo extra llamado porcentaje_bateria y un método leer que, además de reducir el número de páginas pendientes, reducirá la batería en un 1% por cada 10 páginas leídas.
- Añadir una clase llamada Biblioteca que contenga una lista de libros y otra de ebooks. Esta clase deberá tener métodos para agregar libros y ebooks, y un método para mostrar todos los títulos disponibles.
- Utilizar una biblioteca de clases para trabajar con fechas. Crear una clase Prestamo que tenga un atributo fecha_devolucion y un método tiempo_restante que muestre cuántos días faltan para la devolución del libro.