21 marzo 2025

Fundamentos de Python: Una guía de programación para principiantes

Python es un lenguaje de programación versátil y ampliamente utilizado, conocido por su sintaxis clara y legibilidad. Esto lo convierte en una opción ideal para principiantes porque se utiliza en todo, desde el desarrollo web hasta la ciencia de datos, abriendo muchas trayectorias profesionales. Este artículo te guiará a través de los conceptos fundamentales de Python con ejemplos de código simples y fáciles de entender.

Tu primer programa en Python: “¡Hola, mundo!”

Comencemos con el tradicional programa "¡Hola, mundo!". En Python, esto es excepcionalmente sencillo:

print("Hello, Beginner!")

Esta única línea logra lo siguiente:

  1. print(): Esta es una función incorporada. Las funciones son bloques de código reutilizables que realizan tareas específicas. print() muestra la salida al usuario.
  2. ("Hello, Beginner!"): Dentro de los paréntesis hay una cadena literal. Una cadena es una secuencia de caracteres, encerrada entre comillas simples ('...') o dobles ("...").

Cuando ejecutas esto, el intérprete de Python ejecuta print(), mostrando “Hello, Beginner!” en tu pantalla.

Variables en Python

Las variables son cruciales para almacenar datos. Piensa en ellas como contenedores etiquetados. Es una buena práctica usar nombres descriptivos, comenzar con letras minúsculas y usar guiones bajos para separar palabras (por ejemplo, mi_variable, edad_usuario). Aquí tienes un ejemplo:

# Asignando valores a variables
message = "Welcome to Python!"
number = 10
pi = 3.14159

# Imprimiendo los valores de las variables
print(message)
print(number)
print(pi)

Explicación:

  1. message = "Welcome to Python!": Se crea una variable llamada message que almacena la cadena "Welcome to Python!".
  2. number = 10: Una variable llamada number almacena el entero 10.
  3. pi = 3.14159: Una variable llamada pi almacena el número de punto flotante 3.14159.

print() luego muestra estos valores. Python es de tipado dinámico: no necesitas declarar explícitamente el tipo de la variable (cadena, entero, flotante). Python lo infiere del valor asignado.

Interacción del usuario en Python

Los programas interactivos a menudo necesitan la entrada del usuario. Así es como se obtiene:

# Obteniendo la entrada del usuario
name = input("Please enter your name: ")

# Imprimiendo un saludo personalizado
print("Hello, " + name + "!")  # Concatenación de cadenas

Explicación:

  1. name = input("Please enter your name: "): input() pausa el programa, espera a que el usuario escriba algo y presione Enter, y lo almacena como una cadena en name.
  2. print("Hello, " + name + "!"): Esto imprime un saludo. El operador +, con cadenas, realiza la concatenación de cadenas, uniéndolas. Es una buena práctica agregar espacios alrededor del + al concatenar para mejorar la legibilidad.

Lógica condicional: if, else y elif

Las declaraciones condicionales permiten que tu programa tome decisiones, controlando qué bloques de código se ejecutan en función de que las condiciones sean verdaderas o falsas.

age = int(input("Enter your age: "))

if age >= 18:
    print("You are eligible to vote.")
elif age < 0:
    print("That is an incorrect age.")
else:
    print("You are not eligible to vote yet.")

Desglose:

  1. age = int(input("Enter your age: ")): Toma la entrada del usuario para la edad. int() convierte la entrada (una cadena por defecto) en un entero.
  2. if age >= 18:: Comprueba si age es mayor o igual que 18. Si es verdadero, se ejecuta la declaración print indentada.
  3. elif age < 0:: Si la condición if anterior es falsa, se comprobará esta condición. Si es verdadera, se ejecutará el bloque correspondiente. elif significa “else if” (si no) y permite comprobar múltiples condiciones en secuencia.
  4. else:: Si ninguna de las condiciones if o elif es verdadera, se ejecuta el código indentado debajo de else. La indentación es vital en Python; define los bloques de código asociados con if, elif y else. Una indentación consistente (generalmente 4 espacios) es crucial para que el código Python funcione correctamente.

Bucles: Repetición de código con for

Los bucles repiten bloques de código. El bucle for itera sobre una secuencia (por ejemplo, una lista o un rango de números).

# Imprimiendo números del 0 al 4
for i in range(5):
    print(i)

# Imprimiendo elementos de una lista
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

Explicación:

  1. for i in range(5):: range(5) genera números desde 0 hasta (pero sin incluir) 5. El bucle itera a través de esta secuencia; en cada iteración, el número actual se asigna a i.
  2. for fruit in fruits:: Este bucle itera a través de la lista fruits. En cada iteración, el elemento actual de la lista se asigna a fruit.

Bucles: Repetición de código con while

El bucle while continúa mientras una condición sea verdadera.

count = 0
while count < 5:
    print(count)
    count += 1  # Incrementar el contador

Explicación:

  1. count = 0: Inicializa count a 0.
  2. while count < 5:: El bucle continúa mientras count sea menor que 5.
  3. count += 1: Dentro del bucle, count se incrementa en 1 en cada iteración. Esto evita un bucle infinito (donde la condición siempre sería verdadera).

Funciones: Bloques de código reutilizables

Las funciones son esenciales para la reutilización, organización y legibilidad del código. En lugar de repetir el mismo código varias veces, puedes definir una función una vez y llamarla siempre que necesites esa funcionalidad específica. Define las tuyas propias usando def.

# Definiendo una función
def greet(name):
    print("Hello, " + name + "!")

# Llamando a la función
greet("Alice")
greet("Bob")

Puntos clave:

  1. def greet(name):: Define una función llamada greet que toma un parámetro llamado name.
  2. print("Hello, " + name + "!"): El cuerpo de la función: el código que se ejecuta cuando se llama a la función.
  3. greet("Alice"): Llama a la función greet, pasando “Alice” como argumento.

Combinando conceptos: Una calculadora de área simple

Combinemos conceptos en un programa un poco más complejo:

def calculate_area(length, width):
    """Calcula el área de un rectángulo."""  # Docstring
    area = length * width
    return area

# Obtener dimensiones
length = float(input("Enter length: "))
width = float(input("Enter width: "))

# Calcular el área
rectangle_area = calculate_area(length, width)

# Imprimir el resultado
print("Area:", rectangle_area)

Explicación:

  1. def calculate_area(length, width):: Define una función para calcular el área del rectángulo, tomando length y width como parámetros. Las """...""" son un docstring, que describe la función. Los docstrings se utilizan para la documentación y se puede acceder a ellos mediante la función help().
  2. return area: La función devuelve el área calculada. La declaración return sale de la función y devuelve el valor al lugar donde se llamó a la función.
  3. El programa obtiene la entrada del usuario para la longitud y el ancho, convirtiéndolos en números de punto flotante usando float(). El uso de float() permite valores decimales, lo que hace que la calculadora sea más versátil.
  4. Llama a calculate_area, pasando las dimensiones, y almacenando el valor devuelto en rectangle_area.
  5. Finalmente, imprime el área.

Más herramientas de control de flujo

Python proporciona otras herramientas para controlar el flujo del programa.

break, continue y else en bucles

  • break: Sale del bucle for o while más interno.
  • continue: Continúa con la siguiente iteración del bucle.
  • Cláusula else del bucle: En for, se ejecuta después de que el bucle termina (a menos que ocurra break). En while, se ejecuta después de que la condición se vuelve falsa (a menos que ocurra break).
#Ejemplo para break
numbers = [1, 2, 3, 4, 5]
for number in numbers:
    if number == 3:
        break  # Sale del bucle cuando number es 3
    print(number)  # Salida: 1 2

#Ejemplo para continue
numbers = [1, 2, 3, 4, 5]
for number in numbers:
    if number == 3:
        continue  # Salta a la siguiente iteración cuando number es 3
    print(number)  # Salida: 1 2 4 5

#Ejemplo para else
for i in range(5):
    print(i)
else:
    print("Loop finished") #Se ejecutará

for i in range(5):
    if i==3:
        break
    print(i)
else:
    print("Loop finished") #No se ejecutará

La declaración match

match compara un valor con patrones. Es como las declaraciones switch en otros lenguajes, pero con una coincidencia de patrones más potente. Está disponible a partir de Python 3.10.

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 401 | 403 | 404:  # Múltiples casos
            return "Not allowed"
        case 418:
            return "I'm a teapot"
        case _:  # Por defecto
            return "Something's wrong"

print(http_error(404))
print(http_error(500))

_ es un comodín, que coincide con cualquier cosa si ningún otro caso coincide.

Estructuras de datos

Python tiene estructuras de datos integradas para organizar los datos.

  • Listas: Secuencias ordenadas y mutables (modificables).
my_list = [1, 2, 3, "apple"]
my_list.append("cherry")  # Añade un elemento al final
print(my_list[0])       # Accede al elemento por índice (empezando desde 0)
my_list.remove(2)        # Elimina un elemento por valor
print(my_list)
  • Tuplas: Secuencias ordenadas e inmutables.
my_tuple = (1, 2, 3, "apple")
# my_tuple[0] = 5  # Error (inmutable) - Las tuplas no se pueden modificar después de la creación
print(my_tuple[1])
  • Conjuntos: Colecciones no ordenadas de elementos únicos.
my_set = {1, 2, 3, 3, 4, 5}  # Los duplicados se eliminan automáticamente
print(my_set)  # Salida: {1, 2, 3, 4, 5}
  • Diccionarios: Pares clave-valor. Las claves deben ser inmutables (como cadenas, números o tuplas).
my_dict = {"name": "Alice", "age": 30}
print(my_dict["name"])  # Accede al valor por clave
my_dict["age"] = 31      # Modifica un valor
print(my_dict)
  • Comprensiones de lista: Sintaxis concisa para crear listas.
squares = [x**2 for x in range(10)]      # Lista de cuadrados
even = [x for x in range(20) if x % 2 == 0]  # Números pares
print(squares)
print(even)

Módulos

Los módulos organizan el código en archivos reutilizables. Usa import para acceder a la funcionalidad de otros módulos.

import math

print(math.sqrt(16))  # Accede a la función sqrt del módulo math
print(math.pi)        # Accede a la constante pi

from math import sqrt  # Importa una función específica

print(sqrt(25))

from math import *  # Importa todo (generalmente evitar)

print(pi)

Esto demuestra el uso del módulo math (que proporciona funciones matemáticas). Importar funciones o constantes específicas puede mejorar la legibilidad del código y evitar conflictos de nombres. Importar todo con * generalmente se desaconseja en proyectos más grandes.

Definiendo funciones: Técnicas avanzadas

Valores de argumentos por defecto

Las funciones pueden tener valores por defecto para los argumentos.

def greet(name, greeting="Hello"):
    print(greeting + ", " + name + "!")

greet("Bob")           # Usa el saludo por defecto
greet("Alice", "Hi")  # Sobrescribe el valor por defecto

Argumentos con palabras clave

Llama a las funciones usando la sintaxis palabra_clave=valor.

def describe_pet(animal_type, pet_name):
    print("I have a " + animal_type + " named " + pet_name + ".")

describe_pet(pet_name="Harry", animal_type="hamster")  # El orden no importa

Listas de argumentos arbitrarios

Las funciones pueden aceptar un número arbitrario de argumentos posicionales usando *args.

def make_pizza(*toppings):
    print("Making a pizza with:")
    for topping in toppings:
        print("- " + topping)

make_pizza("pepperoni")
make_pizza("mushrooms", "cheese", "peppers")

*toppings recoge todos los argumentos posicionales en una tupla llamada toppings.

Argumentos con palabras clave arbitrarios

Las funciones pueden aceptar un número arbitrario de argumentos con palabras clave usando **kwargs.

def build_profile(first, last, **kwargs):
    # Combina argumentos fijos y de palabra clave arbitrarios para crear un perfil de usuario.
    profile = {'first_name': first, 'last_name': last}
    profile.update(kwargs)  # Actualiza el perfil con los pares clave-valor de kwargs.
    return profile

user = build_profile("Albert", "Einstein", location="Princeton", field="physics")
print(user)  # Salida: {'first_name': 'Albert', 'last_name': 'Einstein', 'location': 'Princeton', 'field': 'physics'}

**kwargs significa “keyword arguments” (argumentos de palabras clave) y es una convención de nomenclatura común para recopilar argumentos nombrados adicionales en un diccionario. Esto permite que las funciones manejen entradas flexibles.

Expresiones Lambda

Funciones pequeñas y anónimas creadas con lambda.

add = lambda x, y: x + y
print(add(5, 3))  # Salida: 8

pairs = [(1, 'one'), (2, 'two'), (3, 'three')]
pairs.sort(key=lambda pair: pair[1]) #ordenar por el segundo elemento de la tupla
print(pairs)

Las funciones lambda se utilizan a menudo como argumentos para funciones de orden superior (funciones que toman otras funciones como argumentos), como sort en este ejemplo.

Clases

Las Clases proporcionan una forma de agrupar datos (atributos) y funcionalidad (métodos) que operan sobre esos datos. Es una de las principales características de la programación orientada a objetos, lo que le permite crear planos para los objetos.

class Dog:
    def __init__(self, name, age): #constructor
        self.name = name
        self.age = age

    def bark(self):
        print("Woof!")

my_dog = Dog("Buddy", 3) #instancia de la clase
print(my_dog.name)
my_dog.bark()

Explicación:

  • class Dog:: Define una clase llamada Dog.
  • def __init__(self, name, age):: Este es el constructor (o inicializador). Se llama automáticamente cuando creas un nuevo objeto Dog.
    • self: Se refiere a la instancia de la clase (el objeto Dog específico con el que estás trabajando). Es el primer parámetro en todos los métodos dentro de una clase.
  • def bark(self):: Este es un método—una función que pertenece a la clase Dog. Puede acceder a los datos del perro (como self.name, aunque no lo hace en este sencillo ejemplo).
  • my_dog = Dog("Buddy", 3) Crea una instancia de la clase Dog llamada my_dog.

Iteradores

Un iterador es un objeto que permite recorrer todos los elementos de una colección, independientemente de su implementación específica.

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))
print(next(myiter))
print(next(myiter))

Generadores

Los generadores son un tipo de iterable, como listas o tuplas. A diferencia de las listas, no almacenan su contenido en la memoria, sino que generan valores sobre la marcha, utilizando la palabra clave yield. Esto los hace eficientes en memoria para secuencias grandes. Esto también los distingue de las comprensiones de lista, que crean la lista completa en la memoria.

def my_generator():
  yield 1
  yield 2
  yield 3

for value in my_generator():
  print(value)

#expresión generadora
squares = (x*x for x in range(10))
print(list(squares))

Estos fundamentos proporcionan una base sólida para tu viaje en Python. Experimentando con estos conceptos y combinándolos, puedes construir programas cada vez más sofisticados. Recuerda que la práctica y la exploración son clave para dominar cualquier lenguaje de programación.

Noticias relacionadas

Artículos relacionados