Hasta ahora, todos los datos de tus programas estaban escritos dentro del propio código. En esta lección tus scripts empezarán a conversar con el usuario: aprenderás a pedir datos con input() (y a lidiar con el hecho de que siempre devuelve texto), a controlar la salida de print() con sus parámetros sep y end, y a dar formato profesional a los resultados con f-strings (alineación, anchos, decimales). Todo culmina en el primer programa realmente interactivo de Papyrus: la ficha de alta de un libro. La entrada y salida es la cara visible de cualquier programa; dominarla hace que tus scripts pasen de "ejercicios" a "herramientas".
Contenido
- Leer datos del usuario:
input() input()siempre devuelvestr: conversión de la entradaprint()a fondo: los parámetrossepyend- Formateo avanzado con f-strings: decimales, anchos y alineación
- Proyecto: ficha interactiva de un libro para Papyrus
Leer datos del usuario: input()
La función input() detiene el programa, muestra un mensaje (el prompt) y espera a que el usuario escriba algo y pulse Intro. Lo escrito se devuelve como resultado, y lo habitual es guardarlo en una variable:
Ejecución (lo que escribe el usuario va tras el prompt):
Anatomía de la línea nombre = input("¿Cómo te llamas? "):
input(...)— llama a la función de lectura."¿Cómo te llamas? "— el mensaje que ve el usuario. Fíjate en el espacio final: sin él, el cursor quedaría pegado al signo de interrogación. Es un pequeño detalle que da mucha calidad.nombre = ...— guarda lo tecleado para usarlo después.
El programa queda bloqueado en la línea del input() hasta que el usuario pulsa Intro. Puedes encadenar varias preguntas y se irán haciendo en orden:
titulo = input("Título del libro: ")
autor = input("Autor: ")
print(f"Anotado: {titulo}, de {autor}")input() siempre devuelve str: conversión de la entrada
Este es el concepto crítico de la lección: input() devuelve siempre una cadena de texto (str), aunque el usuario teclee un número.
>>> stock = input("¿Cuántos ejemplares? ")
¿Cuántos ejemplares? 5
>>> stock
'5'
>>> type(stock)
<class 'str'>
>>> stock + 1
TypeError: can only concatenate str (not "int") to strEl usuario tecleó 5, pero la variable contiene '5' (texto). Intentar operar con él como número falla o, peor, produce resultados absurdos:
La solución es la conversión de tipos que aprendiste en la lección 01-03, aplicada justo al leer:
stock = int(input("¿Cuántos ejemplares? ")) # texto -> entero
precio = float(input("¿Precio en euros? ")) # texto -> decimalSe lee de dentro hacia fuera: primero input() obtiene el texto, luego int() o float() lo convierten.
| El usuario teclea | Código | La variable contiene | Tipo |
|---|---|---|---|
5 |
input(...) |
'5' |
str |
5 |
int(input(...)) |
5 |
int |
12.50 |
float(input(...)) |
12.5 |
float |
hola |
int(input(...)) |
— | ValueError |
La última fila es importante: si el usuario escribe algo que no es un número, el programa se detiene con ValueError. Por ahora asumiremos usuarios bienintencionados; en el módulo 7 (excepciones) aprenderás a capturar ese error y volver a preguntar con elegancia.
Ejemplo completo para Papyrus:
# valor_stock.py - ¿cuánto dinero hay en el estante?
precio = float(input("Precio del libro: "))
unidades = int(input("Unidades en el estante: "))
valor_total = precio * unidades
print(f"Valor del estante: {valor_total:.2f} euros")print() a fondo: los parámetros sep y end
Ya sabes que print() muestra valores. Dos cosas nuevas. La primera: puede recibir varios valores separados por comas, y los muestra separados por un espacio:
La segunda: print() acepta dos parámetros especiales que controlan su comportamiento:
| Parámetro | Qué controla | Valor por defecto |
|---|---|---|
sep |
El separador entre los valores | " " (un espacio) |
end |
Lo que se escribe al final | "\n" (salto de línea) |
Se indican por su nombre, al final de la llamada:
Con sep="-" obtendrías La Odisea-Homero-12.50; con sep="", todo pegado. Es la forma rápida de montar líneas tabulares o códigos.
En cuanto a end: por defecto cada print() termina con un salto de línea ("\n" es el carácter especial que lo representa). Cambiándolo, puedes hacer que el siguiente print() continúe en la misma línea:
Ambos parámetros pueden combinarse:
Un truco útil con sep: imprimir un ticket de línea única a partir de datos sueltos:
fecha = "2026-07-13"
titulo = "Hamlet"
total = 9.95
print(fecha, titulo, total, sep=" ; ") # 2026-07-13 ; Hamlet ; 9.95Este estilo de línea con separadores te sonará mucho cuando trabajes con archivos CSV en el módulo 6.
Formateo avanzado con f-strings: decimales, anchos y alineación
En la lección 01-03 viste las f-strings básicas y el formato :.2f. La sintaxis general es {valor:especificación}, y la especificación permite controlar decimales, ancho y alineación. Lo esencial:
Decimales
precio = 12.5
print(f"{precio:.2f}") # 12.50 -> 2 decimales
print(f"{precio:.1f}") # 12.5 -> 1 decimal
print(f"{precio:.0f}") # 12 -> sin decimales (redondea)f significa "formato de número decimal fijo" y el número tras el punto indica cuántos decimales. Redondea, no trunca: {9.987:.2f} produce 9.99.
Ancho mínimo y alineación
Puedes reservar un ancho fijo de caracteres y decidir hacia dónde se alinea el contenido:
| Especificación | Significado | f"[{x:...}]" con x = "Ana" |
|---|---|---|
:10 |
ancho 10, texto a la izquierda (por defecto) | [Ana ] |
:>10 |
ancho 10, alineado a la derecha | [ Ana] |
:<10 |
ancho 10, alineado a la izquierda | [Ana ] |
:^10 |
ancho 10, centrado | [ Ana ] |
Con números, la alineación por defecto es a la derecha, y puede combinarse con los decimales: :{ancho}.{decimales}f.
El uso estrella: tablas alineadas
Combinando anchos y alineaciones, la salida de texto se convierte en tablas legibles. El catálogo de Papyrus:
print(f"{'TITULO':<22}{'AUTOR':<12}{'PRECIO':>8}")
print("-" * 42)
print(f"{'La Odisea':<22}{'Homero':<12}{12.50:>8.2f}")
print(f"{'Hamlet':<22}{'Shakespeare':<12}{9.95:>8.2f}")
print(f"{'El Quijote':<22}{'Cervantes':<12}{15.90:>8.2f}")TITULO AUTOR PRECIO
------------------------------------------
La Odisea Homero 12.50
Hamlet Shakespeare 9.95
El Quijote Cervantes 15.90Observa los detalles:
- Los títulos y autores usan
:<22y:<12(texto a la izquierda, ancho fijo): las columnas quedan verticalmente alineadas. - Los precios usan
:>8.2f(derecha, dos decimales): los decimales quedan unos debajo de otros, como en cualquier factura seria. - Dentro de las llaves puede ir un literal (
'La Odisea') o una variable; en programas reales serán variables. "-" * 42genera la línea separadora repitiendo el guion (la repetición de cadenas de la lección 01-03).
Proyecto: ficha interactiva de un libro para Papyrus
Juntémoslo todo. Ana quiere una pequeña herramienta para dar de alta libros: el programa pregunta los datos y presenta una ficha bien formateada, con el valor total del stock calculado.
# ficha_libro.py - Alta interactiva de un libro en Papyrus
NOMBRE_TIENDA = "PAPYRUS"
print("=" * 40)
print(f"{NOMBRE_TIENDA:^40}")
print(f"{'Alta de libro en el catalogo':^40}")
print("=" * 40)
# --- Entrada de datos ---
titulo = input("Titulo: ")
autor = input("Autor: ")
precio = float(input("Precio (euros): "))
stock = int(input("Unidades recibidas: "))
valor_stock = precio * stock
# --- Salida: ficha formateada ---
print() # línea en blanco separadora
print("-" * 40)
print(f"{'FICHA DEL LIBRO':^40}")
print("-" * 40)
print(f"{'Titulo:':<16}{titulo}")
print(f"{'Autor:':<16}{autor}")
print(f"{'Precio:':<16}{precio:>8.2f} euros")
print(f"{'Stock:':<16}{stock:>8} uds.")
print(f"{'Valor total:':<16}{valor_stock:>8.2f} euros")
print("-" * 40)
print("Libro registrado.", "Hasta pronto!", sep=" ")Una ejecución de ejemplo:
========================================
PAPYRUS
Alta de libro en el catalogo
========================================
Titulo: La Odisea
Autor: Homero
Precio (euros): 12.50
Unidades recibidas: 4
----------------------------------------
FICHA DEL LIBRO
----------------------------------------
Titulo: La Odisea
Autor: Homero
Precio: 12.50 euros
Stock: 4 uds.
Valor total: 50.00 euros
----------------------------------------
Libro registrado. Hasta pronto!Repaso de las técnicas empleadas:
- Constante
NOMBRE_TIENDAen mayúsculas (lección 01-04). - Cabecera centrada con
:^40y líneas decorativas con"=" * 40. - Entrada convertida:
float()para el precio,int()para el stock; el título y el autor se quedan comostr, que es lo que son. - Cálculo con los datos recibidos (
valor_stock). - Ficha alineada: etiquetas a la izquierda con ancho fijo (
:<16) y números a la derecha con decimales (:>8.2f), estilo factura. print()vacío para dejar una línea en blanco, y unsepfinal a modo de despedida.
Este script es, de verdad, el primer módulo funcional del sistema de Papyrus: pide datos reales, calcula y presenta resultados con aspecto profesional. Guárdalo: lo iremos mejorando en los próximos módulos (validar la entrada, repetir el alta para varios libros, guardar en archivo...).
Errores Comunes y Consejos
- Operar con
input()sin convertir:input()devuelvestrsiempre. Si vas a hacer cuentas, envuélvelo enint()ofloat()en el momento de leer. El síntoma típico:'5' * 2da'55'o aparece unTypeErroral sumar. - Usar coma decimal al teclear: si el usuario escribe
12,50,float()lanzaValueError(Python espera punto:12.50). Indícalo en el prompt:"Precio (usa punto decimal): ". - Convertir a
intun número con decimales tecleado:int("12.50")falla conValueError(no es un entero válido como texto). Si esperas decimales, usafloat(). - Olvidar el espacio final del prompt:
input("Titulo:")deja el cursor pegado.input("Titulo: ")respira. - Confundir
sepyend:sepva entre los valores de un mismoprint();endva al final de la llamada. Si tu salida sale toda en una línea inesperadamente, revisa si tocasteend. - Descuadres en tablas: si una columna baila, revisa que todas las filas usen el mismo ancho en la especificación (
:<22en todas, no:<22en una y:<20en otra). - Consejo: diseña primero la salida "a mano" en un papel o comentario (cómo quieres que se vea el ticket o la ficha) y luego escribe los
print(). Formatear con un objetivo visual claro es mucho más fácil.
Ejercicios
Ejercicio 1
Sin ejecutarlo, escribe exactamente qué muestra este programa si el usuario teclea 3 y luego 2:
a = input("Primer número: ")
b = input("Segundo número: ")
print(a + b)
print(int(a) + int(b))
print(a, b, sep="")Ejercicio 2
Escribe un script ticket.py que pregunte el título de un libro, su precio y cuántas unidades lleva el cliente, y muestre un mini-ticket de Papyrus con este aspecto exacto (los números, con dos decimales y alineados a la derecha en un ancho de 8):
Ejercicio 3
Escribe un script que pregunte al usuario su nombre y su año de nacimiento, calcule su edad aproximada en 2026 y muestre: Hola, Ana. En 2026 cumples 34 años. usando una sola f-string. Usa una constante ANIO_ACTUAL = 2026.
Soluciones
Solución 1
Explicación línea a línea:
print(a + b)→32:aybson cadenas ('3'y'2'), y+entre cadenas concatena.print(int(a) + int(b))→5: convertidas a enteros,+suma de verdad.print(a, b, sep="")→32: imprime ambas cadenas sin separador. Mismo resultado visual que la primera, por un camino distinto.
Solución 2
# ticket.py
titulo = input("Titulo: ")
precio = float(input("Precio: "))
unidades = int(input("Unidades: "))
total = precio * unidades
print("=" * 6, "PAPYRUS", "=" * 6, sep=" ")
print(titulo)
print(f"{unidades} x {precio:>8.2f}")
print(f"TOTAL: {total:>10.2f} EUR")Con la entrada Hamlet, 9.95 y 3:
Claves: el precio se lee con float() y las unidades con int(); {precio:>8.2f} alinea a la derecha en 8 caracteres con 2 decimales; la primera línea usa sep=" " para separar los tres fragmentos con un espacio (también valdría un único literal "====== PAPYRUS ======").
Solución 3
# edad.py
ANIO_ACTUAL = 2026
nombre = input("Tu nombre: ")
anio_nacimiento = int(input("Año de nacimiento: "))
print(f"Hola, {nombre}. En {ANIO_ACTUAL} cumples {ANIO_ACTUAL - anio_nacimiento} años.")Con la entrada Ana y 1992:
Fíjate en que dentro de las llaves de la f-string puede ir directamente la expresión ANIO_ACTUAL - anio_nacimiento: no hace falta una variable intermedia (aunque crearla también sería correcto y quizá más legible).
Conclusión
Tus programas ya son bidireccionales: leen datos del usuario con input() —recordando siempre que devuelve str y que hay que convertir con int()/float() lo que sea numérico— y escriben resultados con control total: separadores y finales de línea con sep/end, y formato profesional con f-strings (decimales :.2f, anchos y alineaciones :<, :>, :^). Con todo ello has construido la ficha de alta de libros de Papyrus, el primer programa interactivo del proyecto.
Queda una última pieza para cerrar el módulo de introducción: preparar tu entorno para trabajar como un profesional con librerías externas. En la próxima lección, Entornos Virtuales y Gestión de Paquetes, aprenderás a aislar las dependencias de cada proyecto con venv y a instalar paquetes con pip.
Curso de Programación en Python
Módulo 1: Introducción a Python
- Introducción a Python
- Configuración del Entorno de Desarrollo
- Sintaxis de Python y Tipos de Datos Básicos
- Variables y Constantes
- Entrada y Salida Básica
- Entornos Virtuales y Gestión de Paquetes
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for y while
- Herramientas de Control de Flujo
- Comprensiones de Listas
Módulo 3: Funciones y Módulos
- Definición de Funciones
- Argumentos de Función
- Funciones Lambda
- Módulos y Paquetes
- Visión General de la Biblioteca Estándar
Módulo 4: Estructuras de Datos
Módulo 5: Programación Orientada a Objetos
Módulo 6: Manejo de Archivos
- Lectura y Escritura de Archivos
- Trabajo con Archivos CSV
- Manejo de Datos JSON
- Operaciones con Archivos y Directorios
Módulo 7: Manejo de Errores y Excepciones
- Introducción a las Excepciones
- Manejo de Excepciones
- Lanzamiento de Excepciones
- Excepciones Personalizadas
- Buenas Prácticas y Registro de Errores con logging
Módulo 8: Temas Avanzados
- Anotaciones de Tipos (type hints)
- Decoradores
- Generadores
- Administradores de Contexto
- Concurrencia: Hilos y Procesos
- Asyncio para Programación Asíncrona
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con unittest
- Pruebas con pytest
- Desarrollo Guiado por Pruebas
- Técnicas de Depuración
- Uso de pdb para Depuración
Módulo 10: Desarrollo Web con Python
- Introducción al Desarrollo Web
- Fundamentos del Framework Flask
- Construcción de APIs REST con Flask
- Introducción a Django
- Construcción de Aplicaciones Web con Django
Módulo 11: Ciencia de Datos con Python
- Introducción a la Ciencia de Datos
- NumPy para Computación Numérica
- Pandas para Manipulación de Datos
- Matplotlib para Visualización de Datos
- Introducción al Aprendizaje Automático con scikit-learn
