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

  1. Leer datos del usuario: input()
  2. input() siempre devuelve str: conversión de la entrada
  3. print() a fondo: los parámetros sep y end
  4. Formateo avanzado con f-strings: decimales, anchos y alineación
  5. 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:

nombre = input("¿Cómo te llamas? ")
print(f"Bienvenido a Papyrus, {nombre}")

Ejecución (lo que escribe el usuario va tras el prompt):

¿Cómo te llamas? Luis
Bienvenido a Papyrus, Luis

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 str

El usuario tecleó 5, pero la variable contiene '5' (texto). Intentar operar con él como número falla o, peor, produce resultados absurdos:

>>> stock * 2      # ¡repite el texto, no multiplica el número!
'55'

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 -> decimal

Se 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")
Precio del libro: 12.50
Unidades en el estante: 4
Valor del estante: 50.00 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:

>>> print("La Odisea", 12.50, "euros")
La Odisea 12.5 euros

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:

print("La Odisea", "Homero", "12.50", sep=" | ")
La Odisea | Homero | 12.50

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:

print("Comprobando stock", end="... ")
print("OK")
Comprobando stock... OK

Ambos parámetros pueden combinarse:

print("Papyrus", "Libreria", "Barrio", sep=" · ", end=" ***\n")
Papyrus · Libreria · Barrio ***

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.95

Este 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.

print(f"[{12.5:8.2f}]")    # [   12.50]  -> ancho 8, 2 decimales

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.90

Observa los detalles:

  • Los títulos y autores usan :<22 y :<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.
  • "-" * 42 genera 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_TIENDA en mayúsculas (lección 01-04).
  • Cabecera centrada con :^40 y líneas decorativas con "=" * 40.
  • Entrada convertida: float() para el precio, int() para el stock; el título y el autor se quedan como str, 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 un sep final 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() devuelve str siempre. Si vas a hacer cuentas, envuélvelo en int() o float() en el momento de leer. El síntoma típico: '5' * 2 da '55' o aparece un TypeError al sumar.
  • Usar coma decimal al teclear: si el usuario escribe 12,50, float() lanza ValueError (Python espera punto: 12.50). Indícalo en el prompt: "Precio (usa punto decimal): ".
  • Convertir a int un número con decimales tecleado: int("12.50") falla con ValueError (no es un entero válido como texto). Si esperas decimales, usa float().
  • Olvidar el espacio final del prompt: input("Titulo:") deja el cursor pegado. input("Titulo: ") respira.
  • Confundir sep y end: sep va entre los valores de un mismo print(); end va al final de la llamada. Si tu salida sale toda en una línea inesperadamente, revisa si tocaste end.
  • Descuadres en tablas: si una columna baila, revisa que todas las filas usen el mismo ancho en la especificación (:<22 en todas, no :<22 en una y :<20 en 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):

====== PAPYRUS ======
Hamlet
3 x     9.95
TOTAL:     29.85 EUR

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

32
5
32

Explicación línea a línea:

  • print(a + b)32: a y b son 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:

====== PAPYRUS ======
Hamlet
3 x     9.95
TOTAL:      29.85 EUR

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:

Hola, Ana. En 2026 cumples 34 años.

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

Módulo 2: Estructuras de Control

Módulo 3: Funciones y Módulos

Módulo 4: Estructuras de Datos

Módulo 5: Programación Orientada a Objetos

Módulo 6: Manejo de Archivos

Módulo 7: Manejo de Errores y Excepciones

Módulo 8: Temas Avanzados

Módulo 9: Pruebas y Depuración

Módulo 10: Desarrollo Web con Python

Módulo 11: Ciencia de Datos con Python

Módulo 12: Proyecto Final

© Copyright 2026. Todos los derechos reservados