# =============================================================================
# RECORRIDO DE CADENAS EN PYTHON
# =============================================================================
# Una cadena (string) es una secuencia de caracteres: letras, espacios, comas...
# Python nos permite recorrer esa secuencia carácter a carácter de varias formas.
#
# En este programa veremos:
# 1. Tres maneras distintas de recorrer una cadena con su posición
# 2. Cómo usar esa posición para hacer cosas distintas según sea par o impar
# 3. Cómo meter todo eso en una función reutilizable
# 4. Cómo aplicar esa función a una lista de textos
#
# ¿Qué es la posición (índice)?
# Cada carácter de una cadena tiene un número de posición que empieza en 0.
#
# Cadena: H o l a q u e ...
# Posición: 0 1 2 3 4 5 6 7 ...
#
# IMPORTANTE: en Python los índices empiezan en 0, no en 1.
# =============================================================================
cadena = "Hola que tal, Python es genial"
# Declaramos la cadena con la que vamos a trabajar en los tres primeros ejemplos.
# Podría ser cualquier texto: cadena = input("Escribe algo: ")
resultado = ""
# Variable donde iremos construyendo la cadena transformada.
# Empieza vacía y le iremos añadiendo letras una a una.
# NUNCA la inicialices con otro valor o aparecerá texto extra al inicio.
# =============================================================================
# MANERA 1: CONTADOR MANUAL
# =============================================================================
# La forma más intuitiva para un principiante.
# Usamos una variable "posicion" que aumentamos nosotros a mano en cada vuelta.
# =============================================================================
posicion = 1
# Empezamos en 1 porque queremos mostrar posiciones "humanas" (del 1 en adelante).
# Nota: internamente Python usa 0, pero aquí lo mostramos desde 1 para el usuario.
for letra in cadena:
# El bucle for recorre la cadena carácter a carácter.
# En cada vuelta, "letra" toma el valor del siguiente carácter.
# Ejemplo: vuelta 1 → letra="H", vuelta 2 → letra="o", etc.
print(posicion, letra)
# Imprime la posición actual y la letra correspondiente.
# Salida ejemplo:
# 1 H
# 2 o
# 3 l
# 4 a
# 5 (el espacio también es un carácter)
posicion = posicion + 1
# Incrementamos el contador manualmente para que en la próxima vuelta
# indique la siguiente posición.
# ALTERNATIVA más corta: posicion += 1
# SIN esta línea, "posicion" siempre valdría 1 → mostraría siempre "1"
# =============================================================================
# MANERA 2: CON range() Y len()
# =============================================================================
# En lugar de recorrer las letras directamente, recorremos los números
# de posición (0, 1, 2, ...) y accedemos a cada letra por su índice.
#
# len(cadena) → devuelve el número total de caracteres de la cadena
# range(n) → genera los números 0, 1, 2, ..., n-1
# cadena[i] → accede a la letra que está en la posición i
# =============================================================================
for posicion in range(len(cadena)):
# range(len(cadena)) con nuestra cadena genera: 0, 1, 2, ..., 29
# (porque "Hola que tal, Python es genial" tiene 30 caracteres)
# En cada vuelta, "posicion" vale el índice actual (empieza en 0).
print(posicion + 1, cadena[posicion])
# cadena[posicion] → accede a la letra en esa posición.
# cadena[0] → "H"
# cadena[1] → "o"
# cadena[4] → " " (espacio)
# Sumamos +1 al mostrar para que el usuario vea 1, 2, 3... en lugar de 0, 1, 2...
#
# VENTAJA de esta manera sobre la 1: con "posicion" podemos acceder a
# la letra anterior (cadena[posicion-1]) o siguiente (cadena[posicion+1])
# =============================================================================
# MANERA 3: CON enumerate() ← LA MÁS USADA EN PYTHON
# =============================================================================
# enumerate() nos da automáticamente DOS cosas en cada vuelta:
# - La posición (índice, empezando en 0)
# - El carácter en esa posición
# Es la manera más "pythónica" (la preferida por los programadores Python).
# =============================================================================
for posicion, letra in enumerate(cadena):
# enumerate() devuelve pares (posición, carácter) en cada vuelta.
# Desglosamos ese par en dos variables: "posicion" y "letra".
# Equivale a hacer las maneras 1 y 2 a la vez, sin código extra.
# Ejemplo: vuelta 1 → posicion=0, letra="H"
# vuelta 2 → posicion=1, letra="o"
print(posicion + 1, letra)
# Mostramos posición (desde 1) y letra, igual que en las maneras anteriores.
if posicion % 2 == 0:
# El operador % calcula el RESTO de la división.
# posicion % 2 → si el resto es 0, la posición es PAR; si es 1, es IMPAR.
# Posiciones pares: 0, 2, 4, 6, 8, ... (H, l, ' ', u, ' ', t, ...)
# Posiciones impares: 1, 3, 5, 7, 9, ... (o, a, q, e, a, ...)
# RECUERDA: la posición 0 (la primera) es PAR en Python.
resultado = resultado + letra.lower()
# .lower() convierte la letra a minúscula.
# Si ya era minúscula, no cambia nada.
# La añadimos al final de "resultado".
# ALTERNATIVA más corta: resultado += letra.lower()
else:
# Si la posición es impar (resto 1)
resultado = resultado + letra.upper()
# .upper() convierte la letra a mayúscula.
# Los espacios y comas no cambian con upper() ni lower().
print(resultado)
# Muestra la cadena transformada al estilo "camello alternado":
# "Hola que tal, Python es genial"
# ↓
# "hOlA QuE TaL, pYtHoN Es gEnIaL"
# (posiciones pares en minúscula, impares en mayúscula)
# =============================================================================
# FUNCIÓN texto_camello()
# =============================================================================
# Metemos todo el proceso en una función para poder reutilizarlo con
# cualquier texto sin tener que reescribir el código.
#
# Entrada: una cadena de texto cualquiera
# Salida: la misma cadena con letras alternadas mayúscula/minúscula
#
# Ejemplo: texto_camello("hola") → "hOlA"
# =============================================================================
def texto_camello(cadena):
# "def" define la función. "cadena" es el parámetro:
# el texto que recibirá la función cuando la llamemos.
# Este "cadena" es LOCAL a la función, no tiene nada que ver
# con la variable "cadena" que declaramos arriba.
resultado = ""
# IMPORTANTE: declaramos resultado DENTRO de la función.
# Cada vez que llamemos a la función, resultado empieza vacío desde cero.
# Si estuviera fuera, las llamadas anteriores acumularían texto sobrante.
for posicion, letra in enumerate(cadena):
# Recorremos la cadena que nos han pasado como parámetro,
# obteniendo posición y letra en cada vuelta.
print(posicion + 1, letra)
# Muestra el progreso por pantalla mientras trabaja.
# En un programa real probablemente quitaríamos este print,
# ya que solo nos interesa el resultado final.
if posicion % 2 == 0:
resultado = resultado + letra.lower()
# Posición par → minúscula
else:
resultado = resultado + letra.upper()
# Posición impar → mayúscula
return resultado
# Devuelve la cadena transformada al lugar donde se llamó la función.
# Sin "return" la función haría todo el trabajo pero no compartiría el resultado.
# =============================================================================
# LLAMADAS A LA FUNCIÓN
# =============================================================================
cadena = "Hola que tal, Python es genial"
# Reasignamos la variable cadena (la anterior también valía, pero así
# queda claro con qué texto trabajamos en esta sección).
print(texto_camello("hola que tal"))
# Llamada con texto directo (literal de cadena).
# La función recibe "hola que tal" como parámetro.
# Imprime: "hOlA QuE TaL"
print(texto_camello(cadena))
# Llamada pasando una variable como argumento.
# La función recibe el contenido de "cadena": "Hola que tal, Python es genial"
# Imprime: "hOlA QuE TaL, pYtHoN Es gEnIaL"
versos = ["Vi un gato muerto", "espanzurrado en la carretera", "una gaviota acechaba", "y la tormenta tronaba"]
# Lista de cadenas. Cada elemento es una línea de un poema.
# Podría ser cualquier colección de textos: nombres, frases, párrafos...
for verso in versos:
# Recorremos la lista. En cada vuelta "verso" toma el valor de la siguiente línea.
# Vuelta 1: verso = "Vi un gato muerto"
# Vuelta 2: verso = "espanzurrado en la carretera"
# ...
print(texto_camello(verso))
# Aplicamos la función a cada verso y mostramos el resultado.
# Salida:
# "vI Un gAtO MuErTo"
# "eSpAnZuRrAdO En lA CaRrEtErA"
# "uNa gAvIoTa aCeChAbA"
# "y lA ToRmEnTa tRoNaBa"
#
# ALTERNATIVA con comprensión de listas:
# transformados = [texto_camello(v) for v in versos]
# print('\n'.join(transformados))