Lenguaje Python

Introducción a Python: sintaxis, tipos de datos, programación orientada a objetos y desarrollo de aplicaciones

Objetivos de Aprendizaje

Introducción a Python

¿Qué es Python?

Python es un lenguaje de programación de alto nivel, interpretado y de propósito general. Creado por Guido van Rossum en 1991, se caracteriza por su sintaxis clara y legible, lo que lo convierte en una excelente opción tanto para principiantes como para desarrolladores experimentados.

Sintaxis Clara

Código legible y fácil de entender

Desarrollo Rápido

Prototipado y desarrollo ágil

Versátil

Web, IA, ciencia de datos, automatización

Gran Comunidad

Amplio ecosistema de librerías

Sintaxis Básica, Indentación y Comentarios

Reglas Fundamentales

Indentación

Python usa indentación (espacios o tabs) para definir bloques de código en lugar de llaves {}.

if edad >= 18:
    print("Eres mayor de edad")
    print("Puedes votar")
else:
    print("Eres menor de edad")

Comentarios

Los comentarios se crean con # para líneas simples y """ """ para múltiples líneas.

# Esto es un comentario de una línea

"""
Esto es un comentario
de múltiples líneas
o docstring
"""

Sensibilidad a Mayúsculas

Python distingue entre mayúsculas y minúsculas en nombres de variables y funciones.

nombre = "Juan"
Nombre = "María"
NOMBRE = "Pedro"
# Son tres variables diferentes

Convenciones de Nomenclatura

Se recomienda usar snake_case para variables y funciones, PascalCase para clases.

mi_variable = 10
def mi_funcion():
    pass

class MiClase:
    pass

Variables, Cadenas y Números

Variables
Cadenas
Números

Variables en Python

Las variables en Python son dinámicas, no necesitan declaración de tipo explícita.

Asignación de Variables

# Asignación simple
nombre = "Ana"
edad = 25
altura = 1.65
es_estudiante = True

# Asignación múltiple
x, y, z = 1, 2, 3
a = b = c = 0

# Intercambio de variables
x, y = y, x

Tipos de Variables

# Verificar tipo de variable
print(type(nombre))    # <class 'str'>
print(type(edad))      # <class 'int'>
print(type(altura))    # <class 'float'>
print(type(es_estudiante))  # <class 'bool'>

Cadenas de Texto (Strings)

Las cadenas en Python son inmutables y ofrecen múltiples métodos para manipulación.

Creación y Formateo

# Diferentes formas de crear strings
texto1 = "Hola mundo"
texto2 = 'Python es genial'
texto3 = """Texto de
múltiples líneas"""

# Formateo de strings
nombre = "Carlos"
edad = 30
mensaje = f"Hola {nombre}, tienes {edad} años"
mensaje2 = "Hola {}, tienes {} años".format(nombre, edad)

Métodos de Cadenas

texto = "Python Programming"

# Métodos comunes
print(texto.upper())        # PYTHON PROGRAMMING
print(texto.lower())        # python programming
print(texto.title())        # Python Programming
print(texto.replace("Python", "Java"))  # Java Programming
print(texto.split())        # ['Python', 'Programming']
print(len(texto))           # 18

Números

Python maneja diferentes tipos numéricos: enteros, flotantes y complejos.

Tipos Numéricos

# Enteros (int)
entero = 42
entero_negativo = -15

# Flotantes (float)
decimal = 3.14159
cientifico = 2.5e-4  # 0.00025

# Complejos (complex)
complejo = 3 + 4j

# Conversiones
int_a_float = float(42)      # 42.0
float_a_int = int(3.14)      # 3
str_a_int = int("123")       # 123

Operaciones Matemáticas

# Operadores básicos
suma = 10 + 5        # 15
resta = 10 - 5       # 5
multiplicacion = 10 * 5    # 50
division = 10 / 3    # 3.333...
division_entera = 10 // 3  # 3
modulo = 10 % 3      # 1
potencia = 2 ** 3    # 8

# Funciones matemáticas
import math
print(math.sqrt(16))   # 4.0
print(math.ceil(3.2))  # 4
print(math.floor(3.8)) # 3

Tipos de Datos: Listas, Tuplas y Diccionarios

Listas

Colecciones ordenadas y mutables que pueden contener elementos de diferentes tipos.

Operaciones con Listas

# Crear listas
frutas = ["manzana", "banana", "naranja"]
numeros = [1, 2, 3, 4, 5]
mixta = ["texto", 42, 3.14, True]

# Acceso y modificación
print(frutas[0])        # manzana
frutas[1] = "pera"      # Modificar elemento
frutas.append("uva")    # Agregar al final
frutas.insert(1, "kiwi")  # Insertar en posición
frutas.remove("naranja")  # Eliminar elemento
ultimo = frutas.pop()   # Eliminar y retornar último

# Métodos útiles
print(len(frutas))      # Longitud
print("pera" in frutas) # Verificar existencia
frutas.sort()           # Ordenar
frutas.reverse()        # Invertir

Tuplas

Colecciones ordenadas e inmutables, ideales para datos que no cambian.

Trabajando con Tuplas

# Crear tuplas
coordenadas = (10, 20)
colores = ("rojo", "verde", "azul")
tupla_mixta = ("Python", 3.9, True)

# Acceso a elementos
x, y = coordenadas      # Desempaquetado
print(colores[0])       # rojo
print(colores[-1])      # azul (último elemento)

# Métodos de tuplas
print(len(colores))     # 3
print(colores.count("rojo"))  # 1
print(colores.index("verde")) # 1

# Tuplas anidadas
punto_3d = ((1, 2), (3, 4), (5, 6))
print(punto_3d[0][1])   # 2

Diccionarios

Colecciones de pares clave-valor, no ordenadas y mutables.

Manipulación de Diccionarios

# Crear diccionarios
persona = {
    "nombre": "Ana",
    "edad": 28,
    "ciudad": "Madrid"
}

# Acceso y modificación
print(persona["nombre"])     # Ana
persona["edad"] = 29         # Modificar valor
persona["profesion"] = "Ingeniera"  # Agregar nueva clave

# Métodos útiles
print(persona.keys())        # Todas las claves
print(persona.values())      # Todos los valores
print(persona.items())       # Pares clave-valor

# Verificaciones
print("nombre" in persona)   # True
edad = persona.get("edad", 0)  # Obtener con valor por defecto

# Eliminar elementos
del persona["ciudad"]        # Eliminar clave específica
profesion = persona.pop("profesion")  # Eliminar y retornar

Condicionales y Estructuras de Control

Condicionales

Estructuras que permiten ejecutar código basado en condiciones específicas.

if, elif, else

# Condicional simple
edad = 18
if edad >= 18:
    print("Eres mayor de edad")
else:
    print("Eres menor de edad")

# Condicional múltiple
nota = 85
if nota >= 90:
    calificacion = "A"
elif nota >= 80:
    calificacion = "B"
elif nota >= 70:
    calificacion = "C"
else:
    calificacion = "F"

# Operadores lógicos
usuario = "admin"
contraseña = "123456"
if usuario == "admin" and contraseña == "123456":
    print("Acceso concedido")
elif usuario == "admin" or contraseña == "123456":
    print("Credenciales parcialmente correctas")
else:
    print("Acceso denegado")

Bucles

Estructuras que permiten repetir código múltiples veces.

for y while

# Bucle for con listas
frutas = ["manzana", "banana", "naranja"]
for fruta in frutas:
    print(f"Me gusta la {fruta}")

# Bucle for con range
for i in range(5):          # 0, 1, 2, 3, 4
    print(f"Número: {i}")

for i in range(1, 11, 2):   # 1, 3, 5, 7, 9
    print(f"Impar: {i}")

# Bucle while
contador = 0
while contador < 5:
    print(f"Contador: {contador}")
    contador += 1

# Control de bucles
for i in range(10):
    if i == 3:
        continue    # Saltar iteración
    if i == 7:
        break       # Salir del bucle
    print(i)

Funciones Imperativas y Retorno de Valores

Definición y Uso de Funciones

Las funciones permiten organizar y reutilizar código de manera eficiente.

Funciones Básicas

# Función simple
def saludar():
    print("¡Hola mundo!")

saludar()  # Llamar la función

# Función con parámetros
def saludar_persona(nombre):
    print(f"¡Hola {nombre}!")

saludar_persona("Ana")

# Función con múltiples parámetros
def sumar(a, b):
    resultado = a + b
    return resultado

total = sumar(5, 3)
print(total)  # 8

Parámetros Avanzados

# Parámetros por defecto
def presentarse(nombre, edad=25):
    print(f"Soy {nombre} y tengo {edad} años")

presentarse("Carlos")        # Usa edad por defecto
presentarse("Ana", 30)       # Especifica edad

# Argumentos variables
def sumar_todos(*numeros):
    return sum(numeros)

print(sumar_todos(1, 2, 3, 4, 5))  # 15

# Argumentos con nombre
def crear_perfil(**datos):
    for clave, valor in datos.items():
        print(f"{clave}: {valor}")

crear_perfil(nombre="Luis", edad=28, ciudad="Barcelona")

Funciones Lambda

# Función lambda (anónima)
cuadrado = lambda x: x ** 2
print(cuadrado(5))  # 25

# Uso con funciones de orden superior
numeros = [1, 2, 3, 4, 5]
cuadrados = list(map(lambda x: x ** 2, numeros))
print(cuadrados)  # [1, 4, 9, 16, 25]

pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares)  # [2, 4]

Programación Orientada a Objetos

Encapsulamiento, Herencia y Polimorfismo

Clases y Objetos

# Definir una clase
class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre    # Atributo público
        self._edad = edad       # Atributo protegido
        self.__id = 12345       # Atributo privado
    
    def presentarse(self):
        return f"Hola, soy {self.nombre} y tengo {self._edad} años"
    
    def cumplir_años(self):
        self._edad += 1
    
    @property
    def edad(self):
        return self._edad
    
    @edad.setter
    def edad(self, nueva_edad):
        if nueva_edad >= 0:
            self._edad = nueva_edad

# Crear objetos
persona1 = Persona("Ana", 25)
persona2 = Persona("Carlos", 30)

print(persona1.presentarse())
persona1.cumplir_años()
print(f"Nueva edad: {persona1.edad}")

Herencia

# Clase padre
class Animal:
    def __init__(self, nombre, especie):
        self.nombre = nombre
        self.especie = especie
    
    def hacer_sonido(self):
        pass
    
    def dormir(self):
        return f"{self.nombre} está durmiendo"

# Clases hijas
class Perro(Animal):
    def __init__(self, nombre, raza):
        super().__init__(nombre, "Canino")
        self.raza = raza
    
    def hacer_sonido(self):
        return f"{self.nombre} dice: ¡Guau!"
    
    def buscar_pelota(self):
        return f"{self.nombre} está buscando la pelota"

class Gato(Animal):
    def __init__(self, nombre, color):
        super().__init__(nombre, "Felino")
        self.color = color
    
    def hacer_sonido(self):
        return f"{self.nombre} dice: ¡Miau!"

# Uso de herencia
mi_perro = Perro("Rex", "Labrador")
mi_gato = Gato("Whiskers", "Gris")

print(mi_perro.hacer_sonido())
print(mi_gato.hacer_sonido())

Polimorfismo

# Polimorfismo en acción
def hacer_sonidos(animales):
    for animal in animales:
        print(animal.hacer_sonido())

# Lista de diferentes animales
mascotas = [
    Perro("Buddy", "Golden Retriever"),
    Gato("Luna", "Negro"),
    Perro("Max", "Bulldog")
]

hacer_sonidos(mascotas)

# Herencia múltiple
class Volador:
    def volar(self):
        return "Estoy volando"

class Nadador:
    def nadar(self):
        return "Estoy nadando"

class Pato(Animal, Volador, Nadador):
    def hacer_sonido(self):
        return f"{self.nombre} dice: ¡Cuac!"

pato = Pato("Donald", "Pato")
print(pato.hacer_sonido())
print(pato.volar())
print(pato.nadar())

Excepciones y Módulos

Manejo de Excepciones

Las excepciones permiten manejar errores de manera elegante y controlada.

try, except, finally

# Manejo básico de excepciones
try:
    numero = int(input("Ingresa un número: "))
    resultado = 10 / numero
    print(f"Resultado: {resultado}")
except ValueError:
    print("Error: Debes ingresar un número válido")
except ZeroDivisionError:
    print("Error: No se puede dividir por cero")
except Exception as e:
    print(f"Error inesperado: {e}")
finally:
    print("Operación completada")

# Lanzar excepciones personalizadas
def validar_edad(edad):
    if edad < 0:
        raise ValueError("La edad no puede ser negativa")
    if edad > 150:
        raise ValueError("La edad no puede ser mayor a 150")
    return True

try:
    validar_edad(-5)
except ValueError as e:
    print(f"Error de validación: {e}")

Módulos y Paquetes

Los módulos permiten organizar y reutilizar código en diferentes archivos.

Importación de Módulos

# Importar módulos estándar
import math
import datetime
from random import randint, choice

# Usar funciones de módulos
print(math.pi)
print(math.sqrt(16))
print(datetime.datetime.now())
print(randint(1, 10))
print(choice(['a', 'b', 'c']))

# Crear módulo personalizado (archivo: mi_modulo.py)
# def saludar(nombre):
#     return f"Hola {nombre}"
# 
# PI = 3.14159

# Importar módulo personalizado
# import mi_modulo
# from mi_modulo import saludar, PI

# Alias para módulos
import numpy as np
import pandas as pd

# Verificar contenido de módulos
print(dir(math))  # Ver funciones disponibles

Laboratorio 10: Aplicación con Python

Objetivos del Laboratorio

  • Desarrollar una aplicación completa usando Python
  • Aplicar conceptos de POO en un proyecto real
  • Implementar manejo de excepciones y archivos
  • Crear una interfaz de usuario funcional
  • Documentar y estructurar el código adecuadamente

Proyecto: Sistema de Gestión de Biblioteca

Desarrollaremos un sistema completo para gestionar una biblioteca, incluyendo libros, usuarios y préstamos.

Gestión de Libros

  • Agregar, editar y eliminar libros
  • Búsqueda por título, autor o género
  • Control de disponibilidad

Gestión de Usuarios

  • Registro de nuevos usuarios
  • Actualización de información
  • Historial de préstamos

Sistema de Préstamos

  • Préstamo y devolución de libros
  • Control de fechas y multas
  • Reportes de actividad

Persistencia de Datos

  • Guardado en archivos JSON
  • Carga automática al iniciar
  • Backup de seguridad

Estructura del Proyecto

biblioteca/
├── main.py              # Archivo principal
├── models/
│   ├── __init__.py
│   ├── libro.py         # Clase Libro
│   ├── usuario.py       # Clase Usuario
│   └── prestamo.py      # Clase Prestamo
├── services/
│   ├── __init__.py
│   ├── biblioteca_service.py  # Lógica de negocio
│   └── archivo_service.py     # Manejo de archivos
├── utils/
│   ├── __init__.py
│   └── validaciones.py  # Funciones de validación
└── data/
    ├── libros.json
    ├── usuarios.json
    └── prestamos.json

Resumen Semana 10

Fundamentos de Python

Dominio de sintaxis básica, indentación, comentarios y convenciones de nomenclatura para escribir código Python limpio y legible.

Tipos de Datos

Comprensión profunda de variables, cadenas, números, listas, tuplas y diccionarios con sus métodos y operaciones.

Estructuras de Control

Implementación efectiva de condicionales, bucles y funciones para crear lógica de programación robusta.

Programación Orientada a Objetos

Aplicación de conceptos de POO incluyendo encapsulamiento, herencia múltiple y polimorfismo en Python.

Manejo de Errores

Gestión profesional de excepciones y organización de código mediante módulos y paquetes.

Proyecto Práctico

Desarrollo de una aplicación completa de gestión de biblioteca aplicando todos los conceptos aprendidos.