0% encontró este documento útil (0 votos)
73 vistas

PDF Python Curso Crash Compress

Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
73 vistas

PDF Python Curso Crash Compress

Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 260

MachineTranslatedbyGoogle

2ª EDICIÓN

PYTON
CURSO CRASH
UNA PRÁCTICA , PROYECTO BASADO
INTRODUCCIÓN A LA PROGRAMACIÓN

ERIC MATTHES
MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

ALABANZA POR Curso acelerado de Python

“Ha sido interesante ver a No Starch Press producir futuros clásicos que

deberían estar junto a los libros de programación más tradicionales. Python


Crash Course es uno de esos libros”.
—Greg Laden, Blogs de ciencia

“Trata de algunos proyectos bastante complejos y los presenta de una manera


coherente, lógica y agradable que atrae al lector hacia el tema”.

—Revista de círculo completo

“Bien presentado con buenas explicaciones de los fragmentos de código. El


libro trabaja con usted, un pequeño paso a la vez, construyendo un código más
complejo, explicando lo que está pasando todo el camino”.
—FlickThrough Reseñas

“¡Aprender Python con Python Crash Course fue una experiencia extremadamente
positiva! Una gran elección si eres nuevo en Python.”
—Mikke empieza a programar

“Hace lo que dice en la lata, y lo hace muy bien. . . . Presenta


una gran cantidad de ejercicios útiles, así como tres proyectos desafiantes y
entretenidos”.
—RealPython.com

“Una introducción rápida pero completa a la programación con Python, Python

Crash Course es otro libro excelente para agregar a su biblioteca y ayudarlo a


finalmente dominar Python”.
—TutorialEdge.net

“Una opción brillante para principiantes


principiantes completos sin ninguna experiencia en
codificación. Si está buscando una introducción sólida y sin complicaciones a este
lenguaje tan profundo, tengo que recomendar este libro”.
—WhatPixel.com

"Contiene literalmente todo lo que necesita saber sobre Python y aún más".

—FireBearStudio.com
—FireBearStudio.com
MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

pitón
Curso intensivo
2da edición

Una práctica , Proyecto basado


Introducción
Introducción a la Programación

por Eric Mathes

San Francisco
MachineTranslatedbyGoogle

Sobre el Autor
Eric Matthes es un profesor de ciencias y matemáticas de secundaria que
vive en Alaska, donde imparte un curso de introducción a Python. Ha estado
escribiendo programas desde que tenía cinco años.
añ os. Eric actualmente se enfoca
en escribir software que aborde las ineficiencias en la educación y traiga los
beneficios del software de código abierto al campo de la educación. En su
tiempo libre le gusta escalar montañas y pasar tiempo con su familia.

Acerca del revisor técnico

Kenneth
de PythonLove ha sido
durante programador,
muchos años. Haprofesor
hablado yy organizador
enseñado endemuchas
conferencias
conferencias, ha sido autónomo de Python y Django y actualmente es ingeniero
de software para O'Reilly Media. Kenneth es co-creador del paquete django-
braces, que proporciona varios mixins útiles para las vistas basadas en clases
de Django. Puedes seguirlo en Twitter en @kennethlove.
MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

Para mi padre, que siempre se hizo un


tiempo para responder a mis dudas sobre
programación, y para Ever, que apenas empieza
a hacerme sus preguntas.
MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

Contenidos breves

Prefacio a la Segunda Edición. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii

Agradecimientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii

Parte I: Fundamentos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Capítulo 1: Primeros pasos. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . ..3

Capítulo 2: Variables y tipos de datos simples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Capítulo 3: Introducción a las listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Capítulo 4: Trabajar con listas.................................................. 49

Capítulo 5: Sentencias if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Capítulo 6: Diccionarios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

Capítulo 7: Entrada de usuario y bucles while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Capítulo 8: Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Capítulo 9: Clases. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

Capítulo 10: Archivos y excepciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

Capítulo 11: Prueba de su código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209

Parte II: Proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

Proyecto 1: Invasión alienígena

Capítulo 12: Un barco que dispara balas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

Capítulo 13: ¡Alienígenas! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

Capítulo 14: Puntuación. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279


MachineTranslatedbyGoogle

Proyecto 2: Visualización de datos

Capítulo 15: Generación de datos........


datos..................
.....................
......................
.............
.. 305

Capítulo 16: Descarga de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

Capítulo 17: Trabajo con API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359

Proyecto 3: Aplicaciones Web

Capítulo 18: Primeros pasos con Django . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379

Capítulo 19: Cuentas de usuario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

Capítulo 20: Estilo e implementación de una aplicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437

Epílogo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465

Apéndice A: Instalación y solución de problemas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467

Apéndice B: Editores de texto e IDE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473

Apéndice C: Obtención de ayuda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479

Apéndice D: Uso de Git para el control de versiones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485

índice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
x Contenido breve

MachineTranslatedbyGoogle

Contenidos en detalle

Prefacio a la segunda edición xvii

Expresiones de gratitud xxi

Introducción xxxii
¿Para quién es este libro? . . . . . . . . . . .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. . xiv
¿Qué puedes esperar aprender? . .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. . xiv
Recursos en línea . . . . . . . . . . . . . . .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. . . xxxv
¿Por qué Python? . . . . . . . . . . . . . . . . . .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. . xxxvi

Parte I: Fundamentos 1

1
Empezando 3

Configuración
Configuración de su entorno de programación
programación ............................. 3
Versiones de Python. 4. . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. ..
Ejecución de fragmentos de código Python. 4. . . . . . . . . . . . . . . .. .. .. . .. .. .. .. ..
Acerca del editor de texto sublime. 4. . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. ..
Python en diferentes sistemas operativos. . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. ..5
Pitón en Windows. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. ..5
Pitón en macOS. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. ..7
Python es Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. ..8
Ejecución de un programa Hola Mundo. . . . . . . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. ..9
Configuración de Sublime Text para usar la versión correcta de Python. . .. . .. .. .. .. ..9
Ejecutando hello_world.py . . . . . . . . . . .. .. .. .. . .. .. .. .. .. . .. .. .. .. . 10
Solución de problemas . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. . .. .. .. .. . 11
Ejecución de programas de Python desde una terminal. . . . .. .. .. .. . .. .. .. .. .. . .. .. .. .. . 12
En Windows .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. . 12
En macOS y Linux. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Ejercicio 1-1: python.org. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Ejercicio 1-2: Errores tipográficos de Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Ejercicio 1-3: Habilidades Infinitas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. ..
Resumen . . . 13

2
Variables y tipos de datos simples 15

Qué sucede realmente cuando ejecutas hello_world.py . . . 15 . . . . . .. .. .. .. . .. .. .. ..


.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . ..
variables . . dieciséis .. .. .. .. . .. .. .. ..
Nombrar y usar variables. . 17 .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. ..
Evitar errores de nombre al utilizar variables. . . 17 . .. .. .. .. .. . .. .. .. ..
Las variables son etiquetas.................
etiquetas....................................
................... 18
Ejercicio 2-1: Mensaje Sencillo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Ejercicio 2-2: Mensajes simples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
MachineTranslatedbyGoogle

.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. ..
cuerdas . 19 .. .. .. . .. .. ..
Cambio de mayúsculas y minúsculas en una cadena con métodos. .. .. 20. . . . . . . . . .. .. .. . .. .. ..
Uso de variables en cadenas. 21 . . . . . . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .
Adición de espacios en blanco a cadenas con tabulaciones o saltos de línea. . 22 .. .. .. .. . .. .. .. .
.. .. .. . .. .. .. .. .. . .. .. ..
Eliminación de espacios en blanco. . 22 .. .. .. . .. .. .. .
Evitar errores de sintaxis con cadenas. . 24 . . . . . . . . . . . . . . . .. .. .. . .. .. .. .
Ejercicio 2-3: Mensaje personal. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Ejercicio 2-4: Casos de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Ejercicio 2-5: Cita Famosa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Ejercicio 2-6: Cita Famosa 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Ejercicio 2-7: Eliminación de nombres. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
numeros . . 25. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
enteros . 26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
flotadores . . .26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Enteros y Flotantes. . . 27 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Guiones bajos en Números. . . 28. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Asignación Múltiple. . 28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
constantes . . 28 .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Ejercicio 2-8: Número Ocho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Ejercicio 2-9: Número Favorito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
¿Cómo se escriben los comentarios? . .. 29 .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
¿Qué tipo de comentarios debe escribir? . . 29 .. . .. .. .. .. .. .. . .. .. ..
Ejercicio 2-10: Adición de comentarios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
El Zen de Python. . . 30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 2-11: Zen de Python. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3
Introducción a las listas 33
¿Qué es una lista? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Acceso a los elementos de una lista. . .. .34. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Las posiciones de índice empiezan en 0, no en 1 ........................... 35
Uso de valores individuales de una lista. . . 35 .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Ejercicio 3-1: Nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Ejercicio 3-2: Saludos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Ejercicio 3-3: Su Propia Lista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Cambio, adición y eliminación de elementos. . . 36 .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Modificación de elementos en una lista. .. ..36. . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Adición de elementos a una lista. . .. .37. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Eliminación de elementos de una lista. . .. 38 .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Ejercicio 3-4: Lista de invitados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Ejercicio 3-5: Cambiar la lista de invitados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Ejercicio 3-6: Más invitados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Ejercicio 3-7: Reducción de la lista de invitados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Organización de una lista. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Ordenar una lista de forma permanente con el método sort(). .. 43 .. .. .. .. .. .. . .. .. ..
Ordenar una lista temporalmente con la función sorted() . . 44 . . . . . . . . . . . . . . . . . .
Imprimir una lista en orden inverso. . . 45 . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Encontrar la longitud de una lista. .. .45. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 3-8: Viendo el Mundo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Ejercicio 3-9: Invitados a cenar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Ejercicio 3-10: Cada función. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

xi Contenidos en detalle

MachineTranslatedbyGoogle

Evitar errores de índice al trabajar con listas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46


Ejercicio 3-11: Error intencional. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4
Trabajar con listas que 49
recorren una lista completa.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Una mirada más cercana a los bucles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Hacer más trabajo dentro de un bucle for. . . . . . . . . . . . . . . . . . . . . . . .. .. . . . 51
Hacer algo después de un bucle for. .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . . 52
Evitar errores de sangría. . 53 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. ..
Olvidarse de sangrar. . . 53 .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Olvidarse de aplicar sangría a las líneas adicionales.. . .54. . . . . . . . . . . . . . . . . . . . .. .. ..
Sangría innecesariamente. . .55 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Sangría innecesariamente después del bucle. . .. .55. . . . . . . . . . . . . . . . . . .. .. ..
Olvidando el Colón. . 56 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. ..
Ejercicio 4-1: Pizzas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Ejercicio 4-2: Animales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Realización de listas numéricas.. ..57. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. ..
Usando la función range(). . 57 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. ..
Usando range() para hacer una lista de números. . .. 58 . .. . .. .. .. .. .. .. . .. .. ..

Estadísticas simples con una lista de números. .. .59. . . . . . . . . . . . . . . . . . . . . . . .


Comprensiones de lista. . .59 . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Ejercicio 4-3: Contar hasta Veinte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-4: Un Millón . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-5: Sumar un millón. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-6: Números impares. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-7: Treses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-8: Cubos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Ejercicio 4-9: Comprensión del Cubo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Trabajar con parte de una lista. . .61. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Cortar una lista. . .. 61
Bucle a través de una rebanada. . .. .62. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copiar una lista. . . 63. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 4-10: Rebanadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sesenta y cinco
Ejercicio 4-11: Mis Pizzas, Tus Pizzas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sesenta y cinco
Ejercicio 4-12: Más bucles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sesenta y cinco
.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
tuplas. . . sesenta y cinco

Definición de una tupla... .66 . .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..


Recorriendo en bucle todos los valores de una tupla. .. ..67. . . . . . . . . . . . . . . . . . . . . . . .
Escribiendo sobre una Tupla.. ..67. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 4-13: Buffet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Estilo de su código. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
La guía de estilo. . 68. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
sangría . 69 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Longitud de la línea.. .. 69. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Líneas en blanco . ..69. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Otras pautas de estilo. . . 70 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


Ejercicio 4-14: PEP 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Ejercicio 4-15: Revisión de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Contenidos en detalle XIII

MachineTranslatedbyGoogle

5
si declaraciones 71

Un ejemplo sencillo. . . 72. . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. ..


Pruebas condicionales... .72. . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. ..
Comprobación de la igualdad. . .. .72. . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. ..
Ignorar mayúsculas y minúsculas al comprobar la igualdad. ... .73. .. .. .. .. .. .. . .. .. ..
Comprobación de la desigualdad.. ..74. . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. ..
comparaciones numéricas. . . 74 . . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. ..
Comprobación de múltiples condiciones... .75. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comprobar si un valor está en una lista. . . 76 . . . . . . . . . . . . . . . . . . . . . . . . . .
Comprobar si un valor no está en una lista. . 77 .. .. . .. .. .. .. .. .. . .. .. ..
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Expresiones booleanas. . 77
Ejercicio 5-1: Pruebas condicionales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Ejercicio 5-2: Más pruebas condicionales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Si declaraciones. . . .78. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sentencias if simples. . 78 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Declaraciones if-else. .. 79.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
La cadena if-elif-else. . 80 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Uso de múltiples bloques elif. . . 82 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Omitiendo el bloque else. . 82. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Prueba de múltiples condiciones. .. .83. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 5-3: Colores alienígenas #1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Ejercicio 5-4: Alien Colors #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Ejercicio 5-5: Colores alienígenas #3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Ejercicio 5-6: Etapas de la Vida. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Ejercicio 5-7: Fruta favorita. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Uso de sentencias if con listas. . . 85 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comprobación de artículos especiales.. ..86. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comprobación de que una lista no está vacía ........................... 87
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Uso de listas múltiples. . . 88
Ejercicio 5-8: Hola administrador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Ejercicio 5-9: Sin Usuarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Ejercicio 5-10: Comprobación de nombres de usuario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Ejercicio 5-11: Números ordinales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Estilizando sus sentencias if. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Ejercicio 5-12: Dar estilo a declaraciones if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Ejercicio 5-13: Sus Ideas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

6
Diccionarios 91
.. .. . .. .. .. .. .. . ..
Un diccionario sencillo. . 92 .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Trabajar con diccionarios. . 92 . . . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Acceso a valores en un diccionario. . 93 . . .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Adición de nuevos pares clave-valor. .. .93. . . .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Comenzar con un diccionario vacío ................................ 94
Modificación de valores en un diccionario. .. .95. . . . . . . . . . . .. .. .. .. .. . .. .. ..
Eliminación de pares clave-valor. .. .96. . . . . . . . . . . . . . . . .. .. .. .. .. . .. .. ..
Un diccionario de objetos similares. . . 97 . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Usando get() para acceder a los valores. .. ..98. . . . . . . . . . . . . . .. .. .. .. .. . .. .. ..
xiv Contenidos en detalle

MachineTranslatedbyGoogle

Ejercicio 6-1: Persona . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99


Ejercicio 6-2: Números Favoritos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Ejercicio 6-3: Glosario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Bucle a través de un diccionario. . 99. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. ..
Bucle a través de todos los pares clave-valor ....................
...........................
....... 99
Recorriendo todas las claves de un diccionario. . . 101 .. . .. .. .. .. .. .. . .. ..
Bucle a través de las teclas de un diccionario en un orden particular.. .. . .103 . .. . .. ..
Bucle a través de todos los valores en un diccionario. .. .. . .104 .. .. .. .. .. .. . .. ..
Ejercicio 6-4: Glosario 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Ejercicio 6-5: Ríos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Ejercicio 6-6: Sondeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Anidamiento. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. .
. .. ..106 .. ..
Una lista de diccionarios. .. .. 106
.. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. .. . .. .. .. .. .. . .. .. .. .. .. .. .
Una lista en un diccionario.. .. . .108 .. ..
Un diccionario en un diccionario. . . .. .110 . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 6-7: Personas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Ejercicio 6-8: Mascotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Ejercicio 6-9: Lugares favoritos.
favoritos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Ejercicio 6-10: Números Favoritos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Ejercicio 6-11: Ciudades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Ejercicio 6-12: Extensiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

7
Entrada de usuario y bucles while 113

Cómo funciona la función input() . . 114 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


.. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Escribir indicaciones claras. . 114
Uso de int() para aceptar entradas numéricas.. .. . .115 . .. .. . .. .. .. .. .. .. . .. ..
El Operador Módulo. . . . 116 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 7-1: Coche de alquiler. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Ejercicio 7-2: Asientos en restaurante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Ejercicio 7-3: Múltiplos de Diez. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Introducción a los bucles while. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
El ciclo while en acción. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Permitir que el usuario elija cuándo salir. . .. .. .. . .. .. .. .. .. .. . .. .. . . 118
Uso de una bandera. . . . . . . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 120
Usando break para salir de un bucle. . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 121
Uso de continuar en un bucle. . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 122
Evitar bucles infinitos. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 122
Ejercicio 7-4: Ingredientes
Ingredientes para pizza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Ejercicio 7-5: Boletos de cine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Ejercicio 7-6: Tres Salidas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Ejercicio 7-7: Infinito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Uso de un bucle while con listas y diccionarios. .. .. .. .. . .. .. .. .. .. .. . .. . . . . 124
Mover elementos de una lista a otra. . 124 .. .. .. . .. .. .. .. .. .. . .. .. ..
Eliminación de todas las instancias de valores específicos de una lista. . .. . .125
. .. .. .. . .. ..
Llenar un diccionario con la entrada del usuario... .. ..126 . .. .. . .. .. .. .. .. .. . .. ..

Ejercicio 7-8: Charcutería . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127


Ejercicio 7-9: Sin pastrami. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Ejercicio 7-10: Vacaciones
Vacaciones de ensueño. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

Contenidos en detalle xv

MachineTranslatedbyGoogle

8
Funciones 129
. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Definición de una función.. .. . .130
Pasar información a una función. . . 130 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Argumentos y Parámetros. . . 131. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 8-1: Mensaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Ejercicio 8-2: Libro Favorito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Pasar Argumentos. . . . 131 .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Argumentos posicionales.. .. . .132 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Argumentos de palabras clave.. .. ..133 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
predeterminados .. . .. . 134
Valores predeterminados .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Llamadas de funciones equivalentes .......................... 135
Evitar errores en los argumentos.. .. . .136 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 8-3: Camiseta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Ejercicio 8-4: Camisas Grandes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Ejercicio 8-5: Ciudades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Valores de retorno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Devolviendo un valor simple. . . ..138 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Haciendo un Argumento Opcional. . . . 138 . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Devolver un diccionario. . . . 140 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
.. .. .. .. . .. .. .. .. .. .. . .. .. ..
Uso de una
Ejercicio 8-6:función
Nombresconde unciudades
bucle while.
. . . .. 141
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Ejercicio 8-7: Álbum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Ejercicio 8-8: Álbumes de usuario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Pasar una lista. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
.. .. .. .. .. . .. .. .. .. .. .. .
Modificación de una lista en una función.. .. . .143 .. ..
Evitar que una función modifique una lista. . . . 145 . . . . . . . . . . . . . . . . .. ..
Ejercicio 8-9: Mensajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Ejercicio 8-10: Envío de mensajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Ejercicio 8-11: Mensajes archivados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Pasar un número arbitrario de argumentos. . . 147 . . . . . . . . . . . . . . . . . . . . . . . . .. ..
Mezcla de argumentos posicionales y arbitrarios. . . . 148 .. . .. .. .. .. .. .. . .. ..
Uso de argumentos arbitrarios de palabras clave.. .. ..148 . .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 8-12: Sándwiches. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Ejercicio 8-13: Perfil de usuario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Ejercicio 8-14: Coches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Almacenamiento de sus funciones en módulos. .. .. ..150
Importación de un módulo completo. .. .. ..150 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Importación de funciones específicas. .. .. . .152 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Uso de as para dar un alias a una función. . .. .152 .. .. .. . .. .. .. .. .. .. . .. ..
Uso de as para dar un alias a un módulo. . . .153 . .. .. .. . .. .. .. .. .. .. . .. ..
Importación de todas las funciones en un módulo.. .. ..153 . .. .. . .. .. .. .. .. .. . .. ..
. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Funciones de estilo. . .. 154
Ejercicio 8-15: Modelos de impresión. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Ejercicio 8-16: Importaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Ejercicio 8-17: Funciones de estilo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
xvi Contenidos en detalle

MachineTranslatedbyGoogle

9
Clases 157
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación y uso de una clase. . . 158
Creando la Clase Perro. . . 158 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación de una instancia de una clase.. .. . .160 . .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 9-1: Restaurante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Ejercicio 9-2: Tres Restaurantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

Ejercicio 9-3: Usuarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162


Trabajando con Clases e Instancias. . . 162 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. .
La clase de coche.. .. . .162 .. ..
Establecer un valor predeterminado para un atributo.. .. . .163 . .. . .. .. .. .. .. .. . .. ..
. . .. .. .. .. .. . .. .. .. .. .. .. .
Modificación de valores de atributos.. .. . .164 .. ..
Ejercicio 9-4: Número servido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Ejercicio 9-5: intentos de inicio de sesión. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Herencia . . . 167
El método __init__() para una clase secundaria.. .. . .167 . .. . .. .. .. .. .. .. . .. ..
Definición de atributos y métodos para la clase secundaria. . .. .169 .. .. .. .. . .. ..
Anulación de métodos de la clase principal. . . 170. . . . . . . . . . . . . . . . . . . . . .
Instancias como Atributos. . .. .. 170 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Modelado de objetos del mundo real. . .. .. .173 .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 9-6: puesto de helados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Ejercicio 9-7: Admin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Ejercicio 9-8: Privilegios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Ejercicio 9-9: Actualización de la batería. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Importación de clases.. .. . .174
Importación de una sola clase. . .. .. 174 .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
iento de varias clases en un módulo.. .. . .175
Almacenamiento
Almacenam . .. .. . .. .. .. .. .. .. . .. ..
Importación de varias clases desde un módulo. . .. 177 . .. . .. .. .. .. .. .. . .. ..
Importación de un módulo completo. .. .. . .177 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Importación de todas las clases de un módulo.. .. ..177 . .. .. . .. .. .. .. .. .. . .. ..
Importación de un módulo en un módulo. . .. .. 178 .. .. .. . .. .. .. .. .. .. . .. ..
Uso de alias. . . 179 .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Encontrar su propio flujo de trabajo.. .. . .179 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 9-10: Restaurante importado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Ejercicio 9-11: Administrador importado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Ejercicio 9-12: Múltiples Módulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
La biblioteca estándar de Python. . . .. .180.. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 9-13: Dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Ejercicio 9-14: Lotería. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Ejercicio 9-15: Análisis de lotería. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Ejercicio 9-16: Módulo Python de la semana. . . . . . . . . . . . . . . . . . . . . . . . . 181
Clases de estilismo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

10
Archivos y excepciones 183

Lectura de un archivo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184


Lectura de un archivo completo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Rutas de archivos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Lectura línea por línea.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Elaboración de una lista de líneas a partir de un archivo.

Trabajar con el contenido de un archivo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188


Contenidos en detalle xvii

MachineTranslatedbyGoogle

.. .. .. .. . .. .. .. .. .. .. . .. ..
Archivos grandes: un millón de dígitos. .. ... .189
¿Tu cumpleaños está contenido en Pi? .. .. . .190 . .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 10-1: Aprendiendo Python. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Ejercicio 10-2: Aprendizaje C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Escribir en un archivo. .. .. . .191
Escribir en un archivo vacío. . . .. 191 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Escritura de varias líneas. . ... .192 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Anexando a un archivo. . .. .. 193 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 10-3: Invitado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Ejercicio 10-4: Libro de Visitas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Ejercicio 10-5: Encuesta de programación. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
excepciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Manejo de la excepción ZeroDivisionError . . . 194 .. .. . .. .. .. .. .. .. . .. ..
Uso de bloques try-except. . .. .194 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Uso de excepciones para evitar bloqueos. .. .. 195 .. .. .. . .. .. .. .. .. .. . .. ..
.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
El otro bloque. . . 196
Manejo de la excepción FileNotFoundError . . . 197 .. .. . .. .. .. .. .. .. . .. ..
Analizando Texto. . . .. .198. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Trabajando
Trabajand .. .. .. .. .. . .. .. .. .. .. .. . .. ..
o con Múltiples Archivos. .. .. . .199
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Fallando en silencio. .. ....200
Decidir qué errores informar. . . 201 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 10-6: Suma . . . 201. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 10-7: Calculadora de Sumas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Ejercicio 10-8: Gatos y Perros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Ejercicio 10-9: Perros y gatos silenciosos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Ejercicio 10-10: Palabras Comunes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Almacenamiento de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

Usando json.dump() y json.load() . . . 203 .. .. .. .. .. . .. .. .. .. .. .. . .. ..


Guardar y leer datos generados por el usuario. . .. 204 . .. . .. .. .. .. .. .. . .. ..
Refactorización.. .. . .206. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 10-11: Número favorito. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Ejercicio 10-12: Número favorito recordado. . . . . . . . . . . . . . . . . . . . . . 208
Ejercicio 10-13: Verificar usuario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

11
Probando tu código 209
.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Prueba de una función. ... .. 210
.. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Pruebas unitarias y casos de prueba. . 211
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Una prueba de aprobación. . .211
Una prueba fallida .................................................
................................................. 212
Responder a una prueba fallida. . ... .213 . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Adición de nuevas pruebas. .214
Ejercicio 11-1: Ciudad, País . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Ejercicio 11-2: Población . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Prueba de una clase. .. .. . .216
.. .. .. .. .. . .. .. .. .. .. .. . .. ..
Una variedad de métodos de afirmación... .. ..216

.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Una clase para probar. .. . .. 217
Prueba de la clase AnonymousSurvey . . . 218 .. .. .. .. . .. .. .. .. .. .. . .. ..
El método setUp(). . . . 220 .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 11-3: Empleado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Resumen . 222

xviii Contenidos en detalle

MachineTranslatedbyGoogle

Parte II: Proyectos 223

Proyecto 1: Invasión alienígena

12

Un barco que dispara balas 227


Planificación de su proyecto ...........................
..........................................
............... 228
Instalando Pygame. . . 228. . . . . . . . . . . . . . . . . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Comenzando el Proyecto del Juego. .. .. .. .. . .. .. .. .. .. . .. .. .. .. ..
. .. .. 229 .. . .. ..
Creación de una ventana de Pygame y respuesta a la entrada del usuario. . . . .. . .. .. . . 229
Configuración del color de fondo. . . . . . . . . . . . . . . . . . . . . . . . . .. . .. .. . . 230
Creación de una clase de configuración. . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . .. .. . . 231
Adición de la imagen del barco. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . .. .. . . 232
Creación de la clase de barco. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . .. .. . . 233
Dibujando el Barco a la Pantalla. . . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 235
Refactorización: los métodos _check_events() y _update_screen() ................. 236
.. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
El método _check_events() . . . . 236
El método _update_screen() . . . 237.. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..

Ejercicio 12-1: Cielo azul. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238


Ejercicio 12-2: Personaje del juego. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Pilotaje del barco. . . .. 238
Respondiendo
Respondien do a una pulsación de tecla. . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. .. 238
Permitir el movimiento continuo. . . 239. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . .. 240
Mover tanto a la izquierda como a la derecha. . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ajuste de la velocidad del barco. 241 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Limitación del alcance del barco. .. .. . .243 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Refactorización de _check_events() . .. .. . .243 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Presionando Q para Salir. .244 . .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
Ejecutar el juego en modo de pantalla completa. . 244 .. .. .. . .. .. .. .. .. .. . .. .. ..
Un resumen rápido. . .. .. 245 .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
alien_invasion.py . . . 245 .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
configuración.py. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 246
. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
barco.py . . ..246
Ejercicio 12-3: Documentación de Pygame. . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Ejercicio 12-4: Cohete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Ejercicio 12-5: Teclas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
.. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Disparar balas. . . . 246 ..
Adición de la configuración de viñetas.. ... .. 247 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación de la clase Bullet. . . . .247 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Almacenamiento de balas en un grupo. . . .. .. .. .. .. . .. .. .. .. .. .. . ..
. .. . .248 ..
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Disparando balas. .. .. . .249 ..
. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Eliminación de viñetas antiguas.. .. . .. 250 ..
Limitación del número de balas. . . .251 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creando el método _update_bullets() . . . . 252. . . . . . . . . . . . . . . . . . . . . . ..
Ejercicio 12-6: tirador lateral. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Resumen . . . .253
Contenido en detalle xix

MachineTranslatedbyGoogle

13
¡Alienígenas! 255
Revisando el Proyecto. . .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 256
Creando el primer alienígena. . . . . . . . . . . . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 256
Creando la clase alienígena. . . . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 257
Creando una Instancia del Alien . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 258
Construyendo la flota alienígena. . . . . . . . . . . . .. . .. .. .. .. .. . .. .. .. .. .. .. . . . . . . . 259

Determinar cuántos alienígenas caben en una fila. . . . . . . . . . . . . . . . . . . . . . . . 260


Creación de una fila de alienígenas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Refactorización de _create_fleet() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Adición de filas. . . . . . . . . . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 262
Ejercicio 13-1: Estrellas. . . . . . .. ... .. .. .. .. ... .. .. .. .. ... .. .. .. . . 264
Ejercicio 13-2: Mejores Estrellas. .. ... .. .. .. .. ... .. .. .. .. ... .. .. .. . . 264
Haciendo el movimiento de la flota. . . . . . . . . . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 265
Moviendo a los alienígenas a la derecha. . . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 265
Creación de ajustes para la dirección de la flota. . . . . . . . .. . .. .. .. .. .. .. . .. .. . . 266
Comprobando si un alienígena ha tocado el borde. . . .. .. .. .. .. .. . .. .. . . 266
Dejar caer la flota y cambiar de dirección. . .. . .. .. .. .. .. .. . .. .. . . 267
Ejercicio 13-3: Gotas de lluvia. . . . . . . . . . . . . . . ... .. .. .. .. ... .. .. .. . . 268
Ejercicio 13-4: Lluvia constante. . . . . . . . . . . . . . ... .. .. .. .. ... .. .. .. . . 268
.. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 268
Disparando a los extraterrestres. .
Detección de colisiones de balas. . . . . . . . . . . . . . . .. . .. .. .. .. .. .. . .. .. . . 268
Fabricación de balas más grandes para pruebas. . . . . . . . . . .. . .. .. .. .. .. .. . .. .. . . 270
Repoblación de la Flota. . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 270
Acelerando las balas. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 271
Refactorización de _update_bullets() . . . . . . . . . . . . .. . .. .. .. .. .. .. . .. .. . . 271
Ejercicio 13-5: tirador lateral, parte 2 . .. ..
.. ... .. .. .. ... .. .. .. . . 272
Finalización del juego .. . . . . . . . . . . . . . . . . . . . . . . . . . .. .. . .. .. .. .. .. . .. .. . . 272
Detección de colisiones de naves y alienígenas. . . . . . . .
.. . .. .. .. .. .. .. . .. .. . . 272
.. .
Respuesta a colisiones de naves y extraterrestres. . . . .. .. .. .. .. .. . .. .. . . 273
Alienígenas que llegan al fondo de la pantalla. .. . .. .... .. .. .. .. . .. .. . . 276
.. . .. ..
¡Juego terminado! . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. . .. .. . . 276
Identificar cuándo deben ejecutarse partes del juego. . .. .. .. .. .. .. . .. .. . . 277
Ejercicio 13-6: Fin del juego. .. ... .. .. .. .. ... .. .. .. .. ... .. .. .. . . 278
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278

14
Puntuación 279

Adición del botón de reproducción. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 280


Creación de una clase de botón. . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 280
Dibujar el botón en la pantalla. .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 281
Comenzando el Juego. . . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 283
Restablecimiento del juego. . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 283
Desactivación del botón de reproducción. . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 284
Ocultar el cursor del ratón. . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 284
Ejercicio 14-1: Presione P para reproducir. . . . . . .. .. .. ... .. .. .. .. ... .. .. .. . . 285
Ejercicio 14-2: Práctica de tiro . ... .. .. .. .. ... .. .. .. .. ... .. .. .. . . 285
Subir de nivel . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . . . . . . . 285
Modificación de la configuración de velocidad. . . . . . .. .. .. .. . .. .. .. .. .. .. . . . . . . . 285
Restablecimiento
Restablecimiento de la velocidad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

xx Contenido en detalle

MachineTranslatedbyGoogle

Ejercicio 14-3: Práctica de tiro desafiante. . . . . . . . . . . . . . . . . . . . . . . . . 288


Ejercicio 14-4: Niveles de dificultad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Puntuación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Visualización de la partitura ...........................
.................................
...... 288
Realización de un marcador. .. .. . .289 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Actualizando la partitura mientras los alienígenas son derribados. . .. . .291
.. .. .. .. .. .. . .. ..
. .. .. . .. .. .. .. .. . ..
Puesta a cero de la puntuación.. ... ..291 .. .. .. .. .. . .. ..
Asegurarse de anotar todos los golpes.. .. . .292 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Aumento de los valores de los puntos. . . . .. 292
. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Redondeando el marcador. .. .. . .293 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Puntuaciones altas..............
altas.............................
.............................
.....................
....... 294
. .
Visualización del nivel. . . . 296. . . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. ..
Visualización del número de barcos. . .. 298 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 14-5: Puntuación más alta de todos los tiempos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Ejercicio 14-6: Refactorización. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Ejercicio 14-7: Expandiendo el Juego. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Ejercicio 14-8: tirador lateral, versión final. . . . . . . . . . . . . . . . . . . . . 302
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302

Proyecto 2: Visualización de datos


15
Generación de datos 305
. . .. .. .. .. .. . .. .. .. .. .. . .. ..
Instalación de Matplotlib.. .. . .306 .. .. .. .. . .. ..
Trazar un gráfico de línea simple. . .. .. 306.. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Cambiar el tipo de etiqueta y el grosor de línea. . . 307 .. . .. .. .. .. .. .. . .. ..
. .. .. .. . .. .. .. .. .. . .. ..
Corrección de la Trama.. .. . .309 .. .. .. .. . .. ..
. .. .. . .. .. .. .. .. . .. ..
Uso de estilos integrados. .. .. . .310 .. .. .. .. . .. ..
Trazado y estilo de puntos individuales con scatter() . . . 310 .. .. .. .. .. .. . .. ..
Trazar una Serie de Puntos con scatter() . . . . .312 . .. .. . .. .. .. .. .. .. . .. ..
Cálculo de datos automáticamente. . . .. 312 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. . . .. 314
Definición de colores personalizados. . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Uso de un mapa de colores.
. .. .. 314
. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Guardar sus parcelas automáticamente.. ... .315 .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 15-1: Cubos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Ejercicio 15-2: Cubos de colores. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Paseos aleatorios. . . . .315
.. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creando la Clase RandomWalk() . . . 316 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Elegir direcciones. . . 316 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ..
Trazado del Paseo Aleatorio. . . .317 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Generación de paseos aleatorios múltiples.. .. . .318 . .. .. . .. .. .. .. .. .. . .. ..
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Estilizando el Paseo.. . .. .319 ..
Ejercicio 15-3: Movimiento Molecular. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Ejercicio 15-4: Paseos aleatorios modificados. . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Ejercicio 15-5: Refactorización. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Tirar dados con Plotly.
Instalación de Plotly. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Creación de la clase de troquel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Tirar el dado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

Contenido en detalle xxi

MachineTranslatedbyGoogle

.. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Análisis de los resultados.. .. . 325
Elaboración de un histograma ....................................... 326
. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Tirar dos dados. . . 328
Dados rodantes de diferentes tamaños.. .. ..329 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 15-6: Dos D8. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Ejercicio 15-7: Tres dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Ejercicio 15-8: Multiplicación. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Ejercicio 15-9: Comprensiones de dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Ejercicio 15-10: Practicando con Ambas Bibliotecas. . . . . . . . . . . . . . . . . . . . . . . 331
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331

dieciséis

Descarga de datos 333


El formato de archivo CSV. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
. . . .. 334
Análisis de los encabezados del archivo CSV. .... .. .. .. . .. .. .. .. .. .. . .. ..
Impresión de los encabezados y sus posiciones.. .. . .335 . .. . .. .. .. .. .. .. . .. ..
Extracción y lectura de datos. . . 336. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Trazado de datos en un gráfico de temperatura.. .. . .336 . .. .. . .. .. .. .. .. .. . .. ..
El módulo de fecha y hora.. . . .337 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Trazado de fechas.. .. . .338.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
.. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Trazar un marco de tiempo más largo. .. .. . .340 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Trazado de una segunda serie de datos. . . 340
Sombreado de un área en el gráfico.. .. . .342 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Comprobación de errores .. . .. .. 343
Descarga de sus propios datos. . . . 345. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 16-1: Lluvia de Sitka. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Ejercicio 16-2: Comparación Sitka-Valle de la Muerte . . . . . . . . . . . . . . . . . . . . . . 346
Ejercicio 16-3: San Francisco. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Ejercicio 16-4: Índices automáticos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Ejercicio 16-5: Explora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Asignación de conjuntos de datos globales: formato JSON.. .. .. 347 .. .. .. .. . .. .. .. .. .. .. . .. ..
Descarga de datos de terremotos. . . . 347 . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Examinando datos JSON. . . .. 347 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Hacer una lista de todos los terremotos.. .. .. 350 .. .. .. .. . .. .. .. .. .. .. . .. ..
Extrayendo Magnitudes. . . . 350 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Extracción de datos de ubicación. .. .. . .351 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Construcción de un mapa del mundo.. .. . .. 351
Una Manera Diferente de Especificar los Datos del Gráfico ......... 353
Personalizaciónn del tamaño del marcador.. .. . .. 353
Personalizació . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Personalización de los colores de los marcadores. .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. . .. 354
Otras escalas de colores.. . . .356 . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Adición de texto flotante. . .. .. 356 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 16-6: Refactorización. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Ejercicio 16-7: Título automatizado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Ejercicio 16-8: Terremotos Recientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
Ejercicio 16-9: Incendios Mundiales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
xxii Contenido en detalle

MachineTranslatedbyGoogle

17
Trabajar con API 359

Usando una API . .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 359


web Git y GitHub. . . . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 360
Solicitud de datos mediante una llamada a la API. . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 360
Solicitudes de instalación. . . . . . . . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 361
Procesamiento de una respuesta API. . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 361

Trabajando con el Diccionario de respuestas. . .. .. .. . .. .. .. .. .. .. . .. .. . . 362


Resumen de los repositorios principales. . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 364
Supervisión de los límites de velocidad de la API. . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 365
Visualización de repositorios usando Plotly. . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 366
Refinación de gráficos plotly. . . . . . . . . . . . . . .. .. .. . .. .. .. .. .. .. . .. .. . . 368
Adición de información sobre herramientas personalizada.
.. .. .. . .. ..
.. .. .. . .. .. .. .. .. .. . .. .. . . 369
Agregar enlaces en los que se puede hacer clic a nuestro gráfico. . . . .. .. . .. .. .. .. .. .. . .. .. . . 370
Más sobre Plotly y la API de GitHub .. .. .. .. . .. .. .. .. .. .. . .. .. . . 371
La API de noticias de hackers . . . . . . . . . . . . . . . . . . . . . . .. .. . .. .. .. .. .. .. . .. .. . . 372
Ejercicio 17-1: Otros idiomas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Ejercicio 17-2: Debates activos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Ejercicio 17-3: Probando python_repos.py
python_repos.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Ejercicio 17-4: Exploración adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
. .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Resumen . . . 375

Proyecto 3: Aplicaciones Web

18
Primeros pasos con Django 379

Configuración de un proyecto. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. . . . . 380


.. .. .. .. . ..
Escribir una especificación.. ... .. 380 .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación de un entorno virtual. . . . 380 . . . .. .. .. .. . .. .. .. .. .. .. . .. ..
Activación del Entorno Virtual. . . 381 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Instalando Django. . ..381 .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
.. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación de un proyecto en Django. . . .. . .382
Creación de la base de datos. .. .. . .382 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Visualización del Proyecto. .. .. . .383 . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 18-1: Nuevos Proyectos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Inicio de una aplicación. .. .. ..384
. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Definición de modelos.. .. ..385 .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Activación de modelos.. .. . .386 . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
El sitio de administración de Django. . .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
. . . .. 387 ..
Definición del modelo de entrada. .. .. . .390 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Migración del modelo de entrada.. .. . .391 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Registro de entrada con el sitio de administración. . .. . .391
. .. .. . .. .. .. .. .. .. . .. ..
El caparazón de Django. . .. .. 392
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 18-2: Entradas cortas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Ejercicio 18-3: La API de Django. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Ejercicio 18-4: Pizzería. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Creación de páginas: la página de inicio del registro de aprendizaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
Mapeo de una URL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
Escribir una vista. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396

Contenidos en detalle XXIII

MachineTranslatedbyGoogle

.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Escribir una plantilla. . . . 397
Ejercicio 18-5: Planificador de comidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Ejercicio 18-6: Página de inicio de pizzería . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Creación de páginas adicionales.. ... .398
Herencia de plantilla. . . 398.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
La página de temas. .. .. 400
. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Páginas de temas individuales. .. .. . .403
Ejercicio 18-7: Documentación de plantilla. . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Ejercicio 18-8: Pizzería Páginas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

19
Cuentas de usuario 409
. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Permitir a los usuarios ingresar datos. .. .. . .410
Adición de nuevos temas..... 410 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Adición de nuevas entradas. .414 . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Edición de entradas.. .. . .418
Ejercicio 19-1: Blog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Configuración de cuentas de usuario. .421 .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. ..
La aplicación de los usuarios.. 421

La página de inicio de sesión. .. 422


..
. . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
. .
Saliendo de tu cuenta . ..424
La página de registro. . . . 426. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ejercicio 19-2: Cuentas de blog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Permitir que los usuarios sean dueños de sus datos.. ... ..428 ..
Restricción de acceso con @login_required . . .. .429 .. .. . .. .. .. .. .. .. . .. ..
Conexión de datos a ciertos usuarios. . .. 430 . .. .. .. .. . .. .. .. .. .. .. . .. ..
Restricción del acceso a los temas a los usuarios apropiados. .. .. ..433 .. .. .. .. .. . .. ..
Protección de los temas de un usuario. . . .. .. .. .. .. . .. .. .. .. .. .. . ..
. .. .. 434 ..
Protegiendo la página edit_entry. . .. 434 . . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Asociación de nuevos temas con el usuario actual. . . . 435 . .. .. .. .. .. .. . .. ..
Ejercicio 19-3: Refactorización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Ejercicio 19-4: Protección de new_entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Ejercicio 19-5: Blog Protegido. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436

20
Diseño e implementación de una aplicación 437
. . . .. 438
Registro de aprendizaje de estilo. . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
La aplicación django-bootstrap4. . . .. .438 . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
. .. . .. .. .. .. .. .. . ..
Uso de Bootstrap para diseñar el registro de aprendizaje.. ... ..438 ..
Modificando base.html. . ..439 . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Diseñar la página de inicio usando un Jumbotron... .. 443 .. . .. .. .. .. .. .. . .. ..
. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . ..
Estilo de la página de inicio de sesión. ..444 .. ..
Dar estilo a la página de temas.. .. . .445 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Dar estilo a las entradas en la página del tema.. .. . .446 . .. .. . .. .. .. .. .. .. . .. ..
Ejercicio 20-1: Otras Formas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Ejercicio 20-2: Blog con estilo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Implementación del registro de aprendizaje. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Hacer una cuenta de Heroku. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Instalación de la CLI de Heroku. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448

xxiv Contenido en detalle

MachineTranslatedbyGoogle

Instalación de paquetes necesarios.. .. . .448 .. .. .. .. .. ... .. .. .. .. .. . .. ..


Creando un archivo requirements.txt. ... .. .448 .. .. .. .. ... .. .. .. .. .. . .. ..
Especificación del tiempo de ejecución de Python.. .. ... 449
.. .. .. .. ... .. .. .. .. .. . .. ..
Modificando settings.py para Heroku. . . .450 . .. .. .. .. ... .. .. .. .. .. . .. ..
Elaboración de un Procfile para Iniciar Procesos. . .. ..450
. .. .. ... .. .. .. .. .. . .. ..
Uso de Git para rastrear los archivos del proyecto. . .. .. 450
. .. .. ... .. .. .. .. .. . .. ..
Empujando a Heroku. .. .. 452 .. .. .. .. . .. .. .. .. .. ... .. .. .. .. .. . .. ..
Configuración de la base de datos en Heroku. .. .. . .454 . .. .. ... .. .. .. .. .. . .. ..
Refinando el despliegue de Heroku. . .. 454 .. .. .. .. .. ... .. .. .. .. .. . .. ..
Asegurar el proyecto en vivo. . . .. .456 .. . .. .. .. .. .. ... .. .. .. .. .. . .. ..
Confirmar y empujar cambios. . . 457 . . . . . . . . . . . . . .. .. .. .. .. . .. ..
Configuración de variables de entorno en Heroku. .. .. . .458 . ... .. .. .. .. .. . .. ..
Creación de páginas de error personalizadas. . . . . . . . . . . . . . . . . .. .. .. .. .. . .. . . . . 458
Desarrollo en curso . . . . 461. . . . . . . . . . . . . . . . . . . . .. .. .. .. .. . .. ..
La configuración SECRET_KEY . .. .. . .461 . . .. .. .. .. .. ... .. .. .. .. .. . .. ..
Eliminación de un proyecto en Heroku.. .. . .461 .. .. .. .. .. ... .. .. .. .. .. . .. ..
Ejercicio 20-3: Blog en vivo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Ejercicio 20-4: Más 404 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Ejercicio 20-5: Registro de aprendizaje ampliado. . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463

Epílogo 465

UN
Instalación y solución de problemas 467

Pitón en Windows. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 467


Encontrar el intérprete de Python. . . . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 467
Agregar Python a su variable de ruta. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 468
Reinstalando Python. . . . . . . . . . . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 469
Pitón en macOS. . .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 469
Instalación de Homebrew. . . . . . . . . . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 469
Instalando Phyton. . . . . . . . . . . . . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 470
Python es Linux. . .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 470

Palabras clave de Python y funciones integradas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471


Palabras clave de Python.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Funciones integradas de Python. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

B
Editores de texto e IDE 473

Personalización de la configuración de Sublime Text. ... .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 474


Conversión de tabulaciones en espacios. . . . . . . . . . . . .. .. . .. .. .. .. .. .. . .. .. . . 474
Configuración del indicador de longitud de línea. . . . . . . . .. .. . .. .. .. .. .. .. . .. .. . . 474
Sangría y eliminación de sangría de bloques de código. . . .. .. . .. .. .. .. .. .. . .. .. . . 474
Comentando bloques de código. .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 475
Guardar su configuración. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 475
Otras personalizaciones. . . . . . . . . . . . . . . .. .. . .. .. .. .. .. .. . .. .. . . 475
Otros editores de texto e IDE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
INACTIVO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Geany. .
Emacs y Vim. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476

Contenido en detalle xxv

MachineTranslatedbyGoogle

átomo . . . . . . . . . . . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
Código de estudio visual. . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
PyCharm. . . . . . . . . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
Cuadernos Jupyter. . .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 477

C
Obteniendo ayuda 479
Primeros pasos...............
pasos.............................
............................
...................
..... ...... 479
. .
Vuelve a intentarlo . . . . 480. . . . . . . . . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Tomar un descanso .. . . .480 .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Consulte los recursos de este libro. . . . 480 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Búsqueda en línea. . .. 481. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Desbordamiento de pila ... . .. 481 .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
La documentación oficial de Python. . . . 481 .. .. .. .. . .. .. .. .. .. .. . .. ..
Documentación de la Biblioteca Oficial. .. ....482 .. .. .. .. . .. .. .. .. .. .. . .. ..
r/aprenderpython.. .. . .482 .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Publicaciones
Publicacio . . . .. 482
nes de blog. . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Internet Relay Chat . . . . .482. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Crear una cuenta de IRC. . . 482 .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Canales para unirse. .. .. .483 .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..

Flojo . . Cultura
. . . . . IRC. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. . . 483
. . . .. .. 483
discordia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484

D
Uso de Git para el control de versiones 485
. .. .. .. . .. .. .. .. .. . .. .. .. .. ..
Instalando Git. . . ..486 . .. .. .. .. .. .. . .. ..
Instalación de Git en Windows. .. .. 486 .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Instalación de Git en macOS.. .. . .486 . .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Instalación de Git en Linux. . .. .. 486 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Configurando Git. . . .. 486.. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Realización de un proyecto........................
proyecto......................................
..........................
............ .. 486
.. .. .. . .. .. .. .. .. . .. .. .. .. ..
Ignorar archivos. . .. .. 487 . .. .. .. .. .. .. . .. ..

Inicializar un Repositorio. . . .487. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..


. .
Comprobación del estado. . . 487. . . . . . .
. . .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Adición de archivos al repositorio. . .. 488. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Haciendo un compromiso. .. .. . .488. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Comprobación del registro. . .. . .. .. ..
. .. .. 489 .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
El Segundo Compromiso.. .. . .489 . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Revertir un cambio ..............
............................
............................
............................
....................
...... 490
49 0
Comprobación de confirmaciones anteriores. . . 491. . . . . . . . . . . . . .. .. . .. .. .. .. .. .. . .. ..
Borrando el Repositorio. . . 493.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..

Índice 495
xxvi Contenido en detalle

MachineTranslatedbyGoogle

Prefacio

la segunda edición

La respuesta a la primera edición de Python Crash Course ha sido abrumadoramente


positiva. Se han impreso más de 500.000 copias, incluidas traducciones en ocho idiomas.
He recibido cartas y correos electrónicos de lectores de hasta 10 años, así como de jubilados

que quieren aprender a programar en su tiempo libre.


Python Crash Course se está utilizando en escuelas intermedias y secundarias, y también
en clases universitarias. Los estudiantes a los que se les asignan libros de texto más
avanzados utilizan Python Crash Course como texto complementario para sus clases y
consideran que es un complemento valioso. La gente lo está utilizando para mejorar sus
habilidades
habilidades en el trabajo y para empezar a trabajar en sus propios proyectos paralelos. En
resumen, la gente está usando el libro para toda la gama de propósitos que esperaba que hicieran.
La oportunidad de escribir una segunda edición de Python Crash Course ha
sido completamente agradable. Aunque Python es un lenguaje maduro, continúa
evolucionando
evolucionando como lo hacen todos los lenguajes. Mi objetivo al revisar el libro era
hacerlo más ágil y sencillo. Ya no hay ninguna razón para aprender Python 2, por lo que
esta edición se enfoca solo en Python 3. Muchos paquetes de Python se han vuelto más
fáciles de instalar, por lo
l o que las instrucciones de configuración e instalación son más
sencillas. Agregué algunos temas de los que me di cuenta que los lectores se beneficiarían
y actualicé algunas secciones para reflejar formas nuevas y más simples de hacer las
cosas en Python. También he aclarado algunas secciones donde ciertos detalles de la

MachineTranslatedbyGoogle

lenguaje no fueron presentados con tanta precisión como podrían haber sido. Todos los
proyectos se han actualizado por completo utilizando bibliotecas populares y bien mantenidas
que puede usar con confianza para crear sus propios proyectos.
El siguiente es un resumen de los cambios específicos que se han realizado en la segunda
edición:

•En el Capítulo 1, las instrucciones para instalar Python se han simplificado

para los usuarios de todos los principales sistemas operativos. Ahora recomiendo el editor
de texto Sublime Text, que es popular entre los programadores principiantes y profesionales
y funciona bien en todos los sistemas operativos.
•El Capítulo 2 incluye una descripción más precisa de cómo se
implementado en Python. Las variables se describen como etiquetas para valores, lo que
conduce a una mejor comprensión de cómo se comportan las variables en Python. El libro
l ibro
ahora usa f-strings, introducido en Python 3.6. Esta es una forma mucho más simple de
usar valores de variables en cadenas. El uso de guiones bajos para representar números
grandes, como 1_000_000, también se introdujo en Python 3.6 y se incluye en esta edición.
La asignación múltiple de variables se introdujo previamente en uno de los proyectos, y esa
descripción se ha generalizado y trasladado al Capítulo 2 para el beneficio de todos
t odos los
lectores.

Finalmente, en este capítulo se incluye una convención clara para representar valores
constantes en Python.

•En el Capítulo 6, presento el método get() para recuperar valores de un diccionario, que puede
devolver un valor predeterminado si no existe una clave.

•El proyecto Alien Invasion (Capítulos 12-14) ahora se basa completamente en clases.
El juego en sí es una clase, más que una serie de funciones.
Esto simplifica enormemente la estructura general del juego, reduciendo enormemente
el número de llamadas a funciones y parámetros requeridos. Los lectores familiarizados
con la primera edición apreciarán la simplicidad que proporciona este nuevo enfoque
basado en clases. Pygame ahora se puede instalar en una línea en todos los sistemas,
y los lectores tienen la opción de ejecutar el juego en modo de pantalla completa o en
modo de ventana.

•En los proyectos de visualización de datos, las instrucciones de instalación de Matplotlib


Matplotli b
son más sencillas para todos los sistemas operativos. Las visualizaciones con
Matplotlib utilizan la función subplots() , que será más fácil de desarrollar a medida que
aprenda a crear visualizaciones más complejas.
El proyecto Rolling Dice en el Capítulo 15 utiliza Plotly, una biblioteca
bibli oteca de visualización
bien mantenida que presenta una sintaxis limpia y una salida hermosa y totalmente
personalizable.
•En el Capítulo 16, el proyecto meteorológico se basa en datos de la NOAA, que deberían ser
más estables durante los próximos años que el sitio utilizado
utili zado en la primera edición. El
proyecto de mapeo se enfoca en la actividad sísmica global; al final
f inal de este proyecto,
tendrá una visualización impresionante que muestra los límites de las placas tectónicas de
la Tierra a través de un enfoque en las ubicaciones de todos los terremotos durante un
período de tiempo determinado. Aprenderá a trazar cualquier conjunto de datos que
involucre puntos geográficos.
• El Capítulo 17 utiliza
util iza Plotly para visualizar la actividad relacionada
rel acionada con Python en
proyectos de código abierto en GitHub.

xviii Prefacio a la segunda edición

MachineTranslatedbyGoogle

•El proyecto de Registro de aprendizaje (Capítulos 18ÿ20) está construido usando la última
versión de Django y diseñado con la última versión de Bootstrap. El proceso de
implementación del proyecto en Heroku se ha simplificado utilizando el paquete django-
heroku y utiliza variables de entorno en lugar de modificar los archivos settings.py . Este
es un enfoque más simple y es más consistente con la forma en que los programadores
profesionales implementan proyectos modernos de Django.
Dj ango.

• El Apéndice A se actualizó por completo para recomendar las mejores prácticas actuales.
ticios en la instalación de Python. El Apéndice B incluye instrucciones detalladas para
configurar Sublime Text y breves descripciones de la mayoría de los principales editores
de texto e IDE en uso actual. El Apéndice C dirige a los lectores a recursos en línea más
nuevos y populares para obtener ayuda, y el Apéndice D continúa ofreciendo un mini curso
intensivo sobre el uso de Git para el control de versiones.

•El índice se ha actualizado completamente para permitirle usar Python Crash Course
como referencia para todos sus futuros proyectos de Python.

¡Gracias por leer el Curso acelerado de Python! Si tiene algún comentario o pregunta, no
dude en ponerse en contacto.
Prefacio a la segunda edición xxix

MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

Expresiones de gratitud

Este libro no hubiera sido posible sin el maravilloso y extremadamente profesional personal
de No Starch Press. Bill Pollock me invitó a escribir un libro introductorio y agradezco
profundamente esa oferta original.
Tyler Ortman me ayudó a dar forma a mi forma de pensar en las primeras etapas de la redacción.
Los comentarios iniciales de Liz Chadwick y Leslie Shen sobre cada capítulo fueron invaluables,
y Anne Marie Walker ayudó a aclarar muchas partes del libro. Riley Hoffman respondió todas las
preguntas que tenía sobre el proceso de ensamblar un libro completo y pacientemente convirtió
mi trabajo en un hermoso producto terminado.

Me gustaría agradecer a Kenneth Love, el revisor técnico de Python Crash Course. Conocí a
Kenneth en PyCon un año y su entusiasmo por el lenguaje y la comunidad de Python ha sido una
fuente constante de inspiración profesional desde entonces. Kenneth fue más allá de la simple
verificación de hechos y revisó el libro con el objetivo de ayudar a los programadores principiantes a
desarrollar una comprensión sólida del lenguaje Python y la programación en general. Dicho esto,
cualquier inexactitud que quede es completamente mía.

Me gustaría agradecer a mi padre por introducirme a la programación a una edad temprana


y por no tener miedo de que rompiera su equipo. Me gustaría agradecer a mi esposa, Erin, por
apoyarme y animarme a escribir este libro, y me gustaría agradecer a mi hijo, Ever, cuya curiosidad
me inspira todos los días.

MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

Introducción

Todo programador tiene una historia sobre


cómo aprendió a escribir su primer programa.
Empecé a programar de niño cuando mi padre
trabajaba para Digital Equipment Corporation, una de
las empresas pioneras de la era informática moderna. Escribí mi
primer programa en un kit de computadora que mi papá había
ensamblado en nuestro sótano. La computadora consistía en nada
más que una placa base desnuda conectada a un teclado sin
estuche, y su monitor era un tubo
t ubo de rayos catódicos desnudo. Mi
programa inicial era un simple juego de adivinanzas de números,
que se parecía a esto:

¡Estoy pensando en un número! Intenta adivinar el número en el que estoy pensando: 25


¡Demasiado baja! Adivina otra vez: 50

¡Demasiado alto! Adivina otra vez: 42


¡Eso es todo! ¿Te gustaría volver a jugar? (sí/no) no
¡Gracias por jugar!

MachineTranslatedbyGoogle

Siempre recordaré lo satisfecho


satisfecho que me sentía al ver a mi familia jugar un juego
que creé y que funcionó como yo pretendía.

Esa primera experiencia tuvo un impacto duradero. Hay verdadera satisfacción en


construir algo con un propósito, algo que solucione un problema.
El software que escribo ahora satisface una necesidad más importante que los esfuerzos de
mi infancia, pero la sensación de satisfacción que obtengo al crear un programa que funciona
sigue siendo prácticamente la misma.

¿Para quién es este libro?


El objetivo de este libro es ponerlo al día con Python lo más rápido posible para que pueda
crear programas que funcionen (juegos, visualizaciones de datos y aplicaciones web) mientras
desarrolla una base en programación que le servirá bien para el resto de su vida. su vida.
Python Crash Course está escrito para personas de cualquier edad que nunca antes han
programado en Python o que nunca han programado en absoluto. Este libro es para aquellos
que quieren aprender los conceptos básicos de la programación rápidamente para poder
concentrarse
concentrarse en proyectos interesantes, y para aquellos a quienes les gusta probar su
comprensión de nuevos conceptos resolviendo problemas significativos. Python Crash Course
también es perfecto para profesores de secundaria y preparatoria que desean ofrecer a sus
alumnos una introducción a la programación basada en proyectos. Si está tomando una clase
universitaria y desea una introducción a Python más amigable que el texto que se le asignó,
este libro también podría facilitar su clase.

¿Qué puedes esperar aprender?


El propósito de este libro es convertirte en un buen programador en general y en un buen
programador de Python en particular. Aprenderá eficientemente y adoptará buenos hábitos
mientras le brindo una base sólida en conceptos generales de programación. Después de
trabajar en Python Crash Course, debería estar listo para pasar a técnicas de Python más
avanzadas, y su próximo lenguaje de programación será aún más fácil de comprender.

En la primera parte de este libro, aprenderá los conceptos básicos de programación que
necesita conocer para escribir programas en Python. Estos conceptos son los mismos que
aprendería al comenzar en casi cualquier lenguaje de programación.
Aprenderá sobre diferentes tipos de datos y las formas en que puede almacenar datos en listas
y diccionarios dentro de sus programas. Aprenderá a crear colecciones de datos y a trabajar con
esas colecciones de manera eficiente. Aprenderá
Aprenderá a usar bucles while e instrucciones if para
probar ciertas condiciones, de modo que pueda ejecutar secciones específicas de código
mientras esas condiciones sean verdaderas y ejecutar otras secciones cuando no lo sean, una
técnica que lo ayuda enormemente a automatizar procesos.

Aprenderá a aceptar la entrada de los usuarios para hacer que sus programas sean
interactivos y mantenerlos en ejecución mientras el usuario esté activo.
Explorará cómo escribir funciones para hacer que partes de su programa sean reutilizables,
de modo que solo tenga que escribir bloques de código que realicen ciertas acciones una vez
y luego usar ese código tantas veces como desee. A continuación, extenderá

xxxv Introducción

MachineTranslatedbyGoogle

este concepto a un comportamiento más complicado con las clases, haciendo que los programas
relativamente simples respondan a una variedad de situaciones. Aprenderá a escribir programas que
manejen correctamente
correctamente los errores comunes. Despué
Después
s de trabajar con cada uno de estos conceptos
básicos, escribirá algunos programas breves que resuelven algunos problemas bien definidos.
Finalmente, dará su primer paso hacia la programación intermedia aprendiend
aprendiendo
o cómo escribir pruebas
para su código para que pueda desarrollar sus programas aún más sin preocuparse por la introducción
de errores. Toda la información de la Parte I lo preparará para emprender proyectos más grandes y

complejos.
En la Parte II, aplicará lo que aprendió en la Parte I a tres proyectos. Puede hacer cualquiera
cualquiera o
todos estos proyectos en el orden que mejor le convenga. En el primer proyecto (Capítulos 12–14),
creará un juego de disparos al estilo de Space Invaders llamado Alien Invasion, que consiste en niveles
de dificultad creciente. Una vez que haya completado este proyecto, debería estar bien encaminado
para poder desarrollar sus propios juegos 2D.

El segundo proyecto (capítulos 15 a 17) lo introduce a la visualización de datos. Los científicos


de datos tienen como objetivo dar sentido a la gran cantidad de información disponible para ellos a

través de una variedad de técnicas de visualización. Trabajará con conjuntos de datos que genera a
través del código, conjuntos de datos que descarga de fuentes en línea y conjuntos de datos que sus
programas descargan automáticam
automáticamente.
ente.

Una vez que haya completado este proyecto, podrá escribir programas que examinen grandes
conjuntos de datos y hagan representaciones visuales de esa información almacenada.

En el tercer proyecto (Capítulos 18–20), construirá una pequeña aplicación web llamada Registro
de aprendizaje. Este proyecto le permite llevar un diario de ideas y conceptos que ha aprendido sobre
un tema específico. Podrá mantener registros separados para diferentes temas y permitir que otros
creen una cuenta y comiencen sus propios diarios. También aprenderá cómo implementar su proyecto
para que cualquiera pueda acceder a él en línea desde cualquier lugar.

Recursos en línea
Puede encontrar todos los recursos complementarios para el libro en línea en https://
nostarch.com/pythoncrashco
nostarch.com/ urse2e/ o http:// ehmatthes.g
pythoncrashcourse2e/ ithub.io/ pcc_2e/. Estos recursos incluyen:
ehmatthes.github.io/

Instrucciones de configuración Estas instrucciones son idénticas a las que se encuentran en


el libro, pero incluyen enlaces activos en los que puede hacer clic para todas las piezas diferentes.
Si tiene problemas de configuración, consulte este recurso.

Actualizaciones Python, como todos los lenguajes, está en constante evolución. Mantengo un
conjunto completo de actualizaciones, por lo que si algo no funciona, consulte aquí para ver si las
instrucciones han cambiado.

Soluciones a los ejercicios Debe pasar bastante tiempo por su cuenta intentando los ejercicios
de las secciones “Pruébelo usted mismo”. Pero si está atascado y no puede progresar, las
soluciones para la mayoría de los ejercicios están en línea.
Hojas de trucos También hay en línea un juego completo de hojas de trucos descargables para
una referencia rápida a los conceptos principales.

Introducción xxxv

MachineTranslatedbyGoogle

¿Por qué Python?


Todos los años considero si continuar usando Python o pasar a un lenguaje diferente, tal
vez uno que sea más nuevo en el mundo de la programación. Pero sigo enfocándome en
Python por muchas razones. Python es un lenguaje increíblemente eficiente:
eficiente: sus programas
harán más en menos líneas de código de lo que requerirían muchos otros
otros lenguajes. La
sintaxis de Python también lo ayudará a escribir código "limpio". Su código será fácil de

leer, fácil de depurar y fácil de ampliar y desarrollar en comparación con otros lenguajes.

La gente usa Python para muchos propósitos: crear juegos, crear aplicaciones web,
resolver problemas comerciales
comerciales y desarrollar herramientas
herramientas internas en todo tipo de
empresas interesantes.
interesantes. Python también se usa mucho en los campos científicos para la
investigación académica y el trabajo aplicado.
Una de las razones más importantes por las que sigo usando Python es por la
comunidad de Python, que incluye un grupo de personas increíblemente diverso y
acogedor. La comunidad es esencial para los programadores
programadores porque la programació
programación
n no
es una actividad solitaria. La mayoría de nosotros, incluso los programadores más
experimentados,
experimentados, necesitamos pedir consejo a otros que ya hayan resuelto problemas
similares. Tener una comunidad bien conectada y de apoyo es fundament
fundamental
al para ayudarlo
a resolver problemas, y la comunidad de Python brinda un apoyo total a las personas como
usted que están aprendiendo Python como su primer lenguaje de programación.

Python es un gran lenguaje para aprender, ¡así que comencemos!


xxxvi Introducción

MachineTranslatedbyGoogle

Parte I
Lo esencial

La Parte I de este libro le enseña los conceptos básicos


que necesitará para escribir programas en Python. Muchos
de estos conceptos son comunes a todos los lenguajes de
programación, por lo que te serán útiles a lo largo de tu vida
como programador.
En el Capítulo 1 , instalará Python en su computadora y ejecutará su primera
programa, que imprime el mensaje Hello world! a la pantalla
En el Capítulo 2 aprenderá a almacenar información en variables y trabajar
con texto y valores numéricos.

Los capítulos 3 y 4 introducen las listas. Las listas pueden almacenar tanta
información como desee en una variable, lo que le permite trabajar con esos datos de manera eficiente.
Podrá trabajar con cientos, miles e incluso millones de valores en solo unas pocas líneas de
código.
En el Capítulo 5 , usará declaraciones if para escribir código que responda de una
manera si ciertas condiciones son verdaderas y responda de una manera diferente si esas
condiciones no son verdaderas.
El Capítulo 6 le muestra cómo usar los diccionarios de Python, que le permiten
hacer conexiones entre diferentes piezas de información. Al igual que las listas, los
diccionarios pueden contener toda la información que necesite almacenar.
En el Capítulo 7 , aprenderá a aceptar las entradas de los usuarios para que sus
programas sean interactivos. También aprenderá sobre los bucles while , que ejecutan
bloques de código repetidamente siempre que se cumplan ciertas condiciones.
En el Capítulo 8 , escribirá funciones, que se denominan bloques de código
que realizan una tarea específica y se pueden ejecutar siempre que los necesite.

MachineTranslatedbyGoogle

El Capítulo 9 presenta clases, que le permiten modelar objetos del mundo


real, como perros, gatos, personas, automóviles, cohetes y mucho más, para que su
código pueda representar cualquier cosa real o abstracta.
El Capítulo 10 le muestra cómo trabajar con archivos y manejar errores para que
sus programas no se bloqueen inesperadamente. Almacenará los datos antes de que
se cierre el programa y volverá a leer los datos cuando el programa se ejecute de nuevo.
Aprenderá sobre las excepciones de Python, que le permiten anticipar errores y hacer
que sus programas manejen esos errores con gracia.
En el Capítulo 11 aprenderá a escribir pruebas para su código para verificar
que sus programas funcionen de la manera que desea. Como resultado, podrá expandir
sus programas sin preocuparse por introducir nuevos errores.
Probar tu código es una de las primeras habilidades que te ayudarán en la transición de
programador principiante a intermedio.
2 Parte I

MachineTranslatedbyGoogle

1
Empezando

En este capítulo, ejecutará su primer programa


Python, hello_world.py. Primero, deberá verificar si
una versión reciente de Python
está instalado en su computadora; si no es así, lo
instalará. También instalará un editor de texto para trabajar con

sus programas Python. Los editores de texto reconocen el código


de Python y resaltan secciones a medida que escribe, lo
l o que
facilita la comprensión de la estructura de su código.

Configuración de su entorno de programación


Python difiere ligeramente en diferentes sistemas operativos, por lo que deberá tener en

cuenta algunas consideraciones. En las siguientes secciones, nos aseguraremos de que


Python esté configurado correctamente en su sistema.
MachineTranslatedbyGoogle

Versiones de Python

Cada lenguaje de programación evoluciona a medida que surgen nuevas ideas y


tecnologías, y los desarrolladores de Python continuamente han hecho que el
lenguaje sea más versátil y poderoso. Al momento de escribir este artículo, la última
versión es Python 3.7, pero todo en este libro debe ejecutarse en Python 3.6 o posterior.
En esta sección, averiguaremos si Python ya está instalado en su sistema y si necesita

instalar una versión más nueva. El Apéndice A también contiene una guía completa para
instalar la última versión de Python en cada uno de los principales sistemas operativos.

Algunos proyectos antiguos de Python todavía usan Python 2, pero debe usar
Python 3. Si Python 2 está instalado en su sistema, probablemente
probablemente esté allí para admitir
algunos programas más antiguos que su sistema necesita. Dejaremos esta instalación
como está y nos aseguraremos de que tenga una versión más reciente con la que trabajar.

Ejecución de fragmentos de código Python

Puede ejecutar el intérprete de Python en una ventana de terminal, lo que le permite probar
fragmentos de código de Python sin tener que guardar y ejecutar un programa completo.
A lo largo de este libro, verá fragmentos de código que se ven así:

ÿ >>> print("¡Hola, intérprete de Python!")


¡Hola intérprete de Python!

El indicador >>> indica que debe usar la ventana de terminal, y el texto en negrita
es el código que debe escribir y luego ejecutar presionand
presionando
o Intro. La mayoría de los
ejemplos en el libro son programas pequeños e independientes que ejecutará desde su
editor de texto en lugar de la terminal, porque escribirá la mayor parte de su código en el
editor de texto. Pero a veces los conceptos básicos se mostrarán en una serie de fragmentos
ejecutados a través de una sesión de terminal de Python para demostrar conceptos
particulares de manera más eficiente. Cuando ve tres corchetes angulares en una lista de
código ÿ, está viendo el código y la salida de una sesión de terminal. Intentaremos
Intentaremos codificar el
intérprete en su sistema en un momento.

¡También usaremos un editor de texto para crear un programa simple llamado


Hello World! que se ha convertido en un elemento básico para aprender a programar. Hay
una larga tradición en el mundo de la programació
programación
n que imprimir un Hello world! mensaje a la
pantalla ya que su primer programa en un nuevo idioma le traerá buena suerte. Un programa
tan simple tiene un propósito muy real. Si se ejecuta correctamente
correctamente en su sistema, cualquier
programa de Python que escriba debería funcionar también.

Acerca del editor de texto sublime

Sublime Text es un editor de texto simple que se puede instalar en todos los sistemas
operativos modernos.
modernos. Sublime Text le permite ejecutar casi todos sus programas

directamente
directamente desde el editor en lugar de a través de una terminal. Su código se ejecuta en
una sesión de terminal incrustada en la ventana de Sublime Text, lo que facilita ver el
resultado.

4 Capítulo 1

MachineTranslatedbyGoogle

Sublime Text es un editor para principiantes, pero muchos programadores profesionales


también lo usan. Si se siente cómodo usándolo mientras aprende Python, puede continuar
usándolo a medida que avanza hacia proyectos más grandes y complicados. Sublime Text
tiene una política de licencias muy liberal: puedes usar el editor de forma gratuita todo el
tiempo que quieras, pero los desarrolladores te piden que compres una licencia si te gusta y
quieres seguir usándola.
El Apéndice B proporciona información sobre otros editores de texto. Si tiene curiosidad
acerca de las otras opciones, es posible que desee hojear ese apéndice en este punto. Si
desea comenzar a programar rápidamente, puede usar Sublime Text para comenzar y
considerar otros editores una vez que haya adquirido algo de experiencia como programador.
En este capítulo, lo guiaré a través de la instalación de Sublime Text en su sistema operativo.

Python en diferentes sistemas operativos


Python es un lenguaje de programación multiplataforma, lo que significa que se ejecuta en
todos los principales sistemas operativos. Cualquier programa de Python que escriba debe
ejecutarse en cualquier computadora moderna que tenga Python instalado. Sin embargo, los
métodos para configurar Python en diferentes sistemas operativos varían ligeramente.
En esta sección, aprenderá cómo configurar Python en su sistema. lo harás
primero verifique si una versión reciente de Python está instalada en su sistema e instálela
si no es así. Luego instalará Sublime Text. Estos son los únicos dos pasos que son diferentes
para cada sistema operativo.
En las secciones siguientes, ejecutará Hello World! programar y solucionar
cualquier problema que no haya funcionado. Lo guiaré a través de este proceso para cada
sistema operativo, por lo que tendrá un entorno de programación de Python fácil de usar
para principiantes.

Pitón en Windows
Windows no siempre viene con Python, por lo que probablemente deba instalarlo y luego
instalar Sublime Text.

Instalación de Python

Primero, verifique si Python está instalado en su sistema. Abra una ventana de comandos
ingresando comando en el menú Inicio o manteniendo presionada la tecla Mayús mientras
hace clic con el botón derecho en su escritorio y seleccionando Abrir ventana de comandos
aquí en el menú. En la ventana de la terminal, ingrese python en minúsculas. Si recibe un
aviso de Python (>>>) en respuesta, Python está instalado en su sistema. Si ve un mensaje
de error que le dice que python no es un comando reconocido, Python no está instalado.

En ese caso, o si ve una versión de Python anterior a Python 3.6, debe descargar un
instalador de Python para Windows. Ir a https:// python

.org/ y coloque el cursor sobre el enlace Descargas . Debería ver un botón para
descargar la última versión de Python. Haga clic en el botón, que debería comenzar a
descargar automáticamente el instalador correcto para su sistema. Después

Empezando 5

MachineTranslatedbyGoogle

ha descargado el archivo, ejecute el instalador. Asegúrese de seleccionar la opción Add


Python to PATH, lo que facilitará la configuración correcta de su sistema. La Figura 1-1 muestra
esta opción seleccionada.

Figura 1-1: asegúrese de seleccionar la casilla de verificación etiquetada Add Python to PATH.

Ejecutar Python en una sesión de terminal

Abra una ventana de comando e ingrese python en minúsculas. Debería ver un indicador de
Python (>>>), lo que significa que Windows ha encontrado la versión de Python que acaba de
instalar.

C:\> pitón
Python 3.7.2 (v3.7.2:9a3ffc0492, 23 de diciembre de 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] en
win32
Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.

>>>

N ota Si no ve este resultado o algo


a lgo similar, consulte las instrucciones de configuración más detalladas.
ciones en el Apéndice A.

Ingrese la siguiente línea en su sesión de Python y asegúrese de ver


el intérprete de salida Hello Python!

>>> print("¡Hola, intérprete de Python!")


¡Hola intérprete de Python!
>>>

Cada vez que desee ejecutar un fragmento de código de Python, abra una ventana de
comandos e inicie una sesión de terminal de Python. Para cerrar la sesión de terminal, presione ctrl-
Z y luego presione enter, o ingrese el comando exit().

6 Capítulo 1

MachineTranslatedbyGoogle

Instalación de texto sublime

Puede descargar un instalador para Sublime Text en https:


https://
// sublimetext.c
sublimetext.com/.
om/.
Haga clic en el enlace de descarga y busque un instalador de Windows. Después de descargar
el instalador, ejecútelo y acepte todos sus valores predeterminados.

Python en macOS
Python ya está instalado en la mayoría de los sistemas macOS, pero lo más probable es que
sea una versión desactualizada que no querrá aprender. En esta sección, instalará la última
versión de Python y luego instalará Sublime Text y se asegurará de que esté configurado
correctamente.

Comprobando si Python 3 está instalado

Abra una ventana de terminal yendo a Aplicaciones4Utilidades4Terminal.


También puede presionar la barra espaciadora z, escribir terminal y luego presionar Intro. Para
ver qué versión de Python está instalada, ingrese python con una p minúscula ; esto también
inicia el intérprete de Python dentro de la terminal, lo que le permite ingresar comandos de Python.
Debería ver un resultado que le indica qué versión de Python está instalada en su sistema y un
>>> aviso donde puede comenzar a ingresar comandos de Python, como este:

$ pitón
Python 2.7.15 (predeterminado, 17 de agosto de 2018, 22:39:05)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
(cl ang-902.0.39.2)] en darwin
Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.
>>>

Este resultado indica que Python 2.7.15 es actualmente la versión predeterminada


instalado en esta computadora. Una vez que haya visto este resultado, presione ctrl-D o
ingrese exit() para salir del indicador de Python y regresar al indicador de terminal.
Para verificar si tiene Python 3 instalado, ingrese el comando
pitón3. Probablemente reciba un mensaje de error, lo que significa que no tiene instalada ninguna versión
de Python 3. Si el resultado muestra que tiene instalado Python 3.6 o una versión posterior, puede pasar
directamente a "Ejecución de Python en una sesión de terminal" en la página 8. Si Python 3 no está
instalado de manera predeterminada, deberá instalarlo manualmente. Tenga en cuenta que cada vez
v ez que
vea el comando python en este libro, debe usar el comando python3 en su lugar para asegurarse de que está
usando Python 3, no Python 2; difieren lo suficiente como para que tenga problemas al intentar ejecutar el
código de este libro con Python 2.

Si ve alguna versión anterior a Python 3.6, siga las instrucciones en la siguiente sección
para instalar la última versión.

Instalación de la última versión de Python

Puede encontrar un instalador de Python para su sistema en https:


https:// python.org/.. Pase el cursor
// python.org/
sobre el enlace Descargar y debería ver un botón para descargar la última versión de Python.
Haga clic en el botón, que debería comenzar automáticamente

Primeros pasos 7

MachineTranslatedbyGoogle

descargando el instalador correcto para su sistema. Después de que se descargue el archivo, ejecute
el instalador.

Cuando haya terminado, ingrese lo siguiente en un indicador de terminal:

$ python3 --versión
Pitón 3.7.2

Debería ver un resultado similar a este, en cuyo caso, está listo para probar
Python. Cada vez que vea el comando python, asegúrese de usar python3.

Ejecutar Python en una sesión de terminal

Ahora puede intentar ejecutar fragmentos de código de Python abriendo una terminal y escribiendo
python3. Ingrese la siguiente línea en la sesión de terminal:

>>> print("¡Hola, intérprete de Python!")


¡Hola intérprete de Python!
>>>

Su mensaje debe imprimirse directamente en la ventana de terminal actual.


Recuerda que puedes cerrar el intérprete de Python presionando ctrl-D o ingresando el comando
exit().

Instalación de texto sublime

Para instalar el editor de Sublime Text, debe descargar el instalador enhttps:// sublimetext.com/.
sublimetext.com/.
Haga clic en el enlace Descargar y busque un instalador para macOS. Después de que se descargue
el instalador, ábralo y luego arrastre el ícono de Sublime Text a su carpeta deAplicaciones .

pitón es linux
Los sistemas Linux están diseñados para la programación, por lo que Python ya está instalado en la
mayoría de las computadoras con Linux. Las personas que escriben y mantienen Linux esperan que
usted haga su propia programación en algún momento y lo alientan a hacerlo. Por esta razón, hay muy
poco que instalar y solo unas pocas configuraciones que cambiar para comenzar a programar.

Comprobación de su versión de

Python Abra una ventana de terminal ejecutando la aplicación Terminal en su sistema (en
Ubuntu, puede presionar ctrl-alt-T). Para averiguar qué versión de Python está instalada, ingrese
python3 con una p minúscula . Cuando se instala Python, este comando inicia el intérprete de
Python. Debería ver una salida que indica qué versión de Python está instalada y un aviso >>>
donde puede comenzar a ingresar comandos de Python, como este:
$ pitón3
Python 3.7.2 (predeterminado, 27 de diciembre de 2018, 04:01:51)
[CCG 7.3.0] en Linux

8 Capítulo 1

MachineTranslatedbyGoogle

Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.
>>>

Este resultado indica que Python 3.7.2 es actualmente la versión predeterminada de Python
ha ya visto este resultado, presione ctrl-D o ingrese exit()
instalada en esta computadora. Cuando haya
para salir del indicador de Python y regresar a un indicador de terminal. Cada vez que vea el comando
python en este libro, ingrese python3

en cambio.
Necesitará Python 3.6 o posterior para ejecutar el
e l código de este libro. Si la versión de
Python instalada en su sistema es anterior a Python 3.6, consulte el Apéndice A para instalar la
última versión.

Ejecutar Python en una sesión de terminal

Puede intentar ejecutar fragmentos de código de


d e Python abriendo una terminal e ingresando
python3, como lo hizo al verificar su versión. Haga esto nuevamente, y cuando
cuand o tenga Python
ejecutándose, ingrese la siguiente línea en la sesión de terminal:

>>> print("¡Hola, intérprete de Python!")


¡Hola intérprete de Python!
>>>

El mensaje debe imprimirse directamente en la ventana de terminal actual.


Recuerda que puedes cerrar el intérprete de Python presionando ctrl-D o ingresando el comando
exit().

Instalación de texto sublime

En Linux, puede instalar Sublime Text desde el Centro de software de Ubuntu.


Haga clic en el icono del software de Ubuntu en su menú y busque Sublime Text. Haga clic
para instalarlo y luego ejecútelo.

Ejecución de un programa Hello World

Con una versión reciente de Python y Sublime Text instalada, está casi listo para ejecutar su primer
programa de Python escrito en un editor de texto. Pero antes de hacerlo, debe asegurarse de que
Sublime Text esté configurado para usar la versión correcta de Python en
e n su sistema. Entonces
escribirás el Hello World! programe y ejecútelo.

Configuración de Sublime Text para usar la versión correcta de Python

Si el comando python en su sistema ejecuta Python 3,


3 , no necesitará configurar nada y puede
pued e
pasar a la siguiente sección. Si usas el python3

comando, deberá configurar Sublime Text para usar la versión correcta de Python cuando ejecute sus
programas.
Primeros pasos 9

MachineTranslatedbyGoogle

Haga clic en el icono de Sublime Text para iniciarlo, o busque Sublime Text en la barra de
búsqueda de su sistema y luego inícielo. Vaya a Herramient
HerramientasÿSistema
asÿSistema de compilación4
New Build System, que abrirá un nuevo archivo de configuración para usted. Elimine lo que ve e
ingrese lo siguiente:

Python3 {
.sublime-construir "cmd": ["python3", "-u", "$archivo"],

Este código le dice a Sublime Text que use el comando python3 de su sistema cuando
ejecute sus archivos de programa de Python. Guarde el archivo como Python3.sublime-build en
el directorio predeterminado que Sublime Text abre cuando elige Guardar.

Ejecutando hola_mundo.py

Antes de escribir su primer programa, cree una carpeta llamada python_work en algún lugar de
su sistema para sus proyectos. Es mejor usar letras minúsculas y guiones bajos para los espacios
en los nombres de archivos y carpetas, porque Python usa estas convenciones de nomenclatura.

Abra Sublime Text y guarde un archivo Python vacío (File4Save As)


llamado hello_world.py en su carpeta python_work . La extensión .py le dice a Sublime
Text que el código en su archivo está escrito en Python, lo que le indica cómo ejecutar el
programa y resaltar el texto de una manera útil.
Una vez que haya guardado su archivo, ingrese la siguiente línea en el editor de texto:

hola_mundo.py print("¡Hola, mundo de Python!")

Si el comando python funciona en su sistema, puede ejecutar su programa seleccionando


ToolsÿBuild en el menú o presionando ctrl-B (zB en macOS). Si tuvo que configurar Sublime
Text en la sección anterior, seleccione ToolsÿBuild System y luego seleccione Python 3. A
partir de ahora podrá seleccionar ToolsÿBuild o simplemente presione ctrl-B (o zB) para ejecutar
sus programas. .

Debería aparecer una pantalla de terminal en la parte inferior de la ganancia de Sublime Text
dow, mostrando el siguiente resultado:

¡Hola mundo Python!


[Terminado en 0.1s]

Si no ve este resultado, es posible que algo haya fallado en el programa. Verifique cada
carácter en la línea que ingresó. ¿Has escrito con mayúsculas por accidente? ¿Olvidaste una o
ambas comillas o paréntesis? Los lenguajes de programación esperan una sintaxis muy
específica y, si no la proporciona, obtendrá errores. Si no puede ejecutar el programa, consulte
las sugerencias en la siguiente sección.
10 Capítulo 1

MachineTranslatedbyGoogle

Solución de problemas
Si no puede ejecutar hello_world.py , aquí hay algunos remedios que puede probar que también
son buenas soluciones generales para cualquier problema de programación:

•Cuando un programa contiene un error significativo, Python muestra un rastro


atrás, que es un informe de error. Python revisa el archivo e intenta identificar el problema.
Compruebe el rastreo; podría darle una pista sobre qué problema impide que se ejecute el
programa.

•Aléjese de su computadora, tome un breve descanso y vuelva a intentarlo.


Recuerde que la sintaxis es muy importante en la programación, por lo que incluso la falta
de dos puntos, las comillas que no coinciden o los paréntesis que no coinciden pueden impedir
que un programa se ejecute correctamente. Vuelva a leer las partes relevantes de este capítulo,
revise su código e intente encontrar el error.

•Empezar de nuevo. Probablemente no necesite desinstalar ningún software, pero podría tener sentido
eliminar su archivo hello_world.py y volver a crearlo desde cero.

•Pídale a otra persona que siga los pasos de este capítulo, en su computadora o en una diferente, y
observe lo que hacen con cuidado. Es posible que te hayas saltado un pequeño paso que
alguien más haya atrapado.
•Encuentre a alguien que conozca Python y pídale que lo ayude a configurarlo.
Si pregunta, es posible que descubra que inesperadamente conoce a alguien que usa Python.

•Las instrucciones de configuración de este capítulo también están disponibles a través del sitio
web complementario del libro en https:// nostarch.com/ pythoncrashcourse2e/.
La versión en línea de estas instrucciones podría funcionar mejor para usted porque
simplemente puede cortar y pegar el código.

•Pide ayuda en línea. El Apéndice C proporciona una serie de recursos, como foros y sitios de chat en
vivo, donde puede solicitar soluciones a personas que ya han trabajado en el problema al que se
enfrenta actualmente.

No te preocupes por molestar a los programadores experimentados. Todos los programadores


se han quedado atascados en algún momento, y la mayoría de los programadores están felices de
ayudarlo a configurar su sistema correctamente. Siempre que pueda indicar claramente lo que está
tratando de hacer, lo que ya ha intentado y los resultados que está obteniendo, es muy probable
que alguien pueda ayudarlo. Como se mencionó en la Introducción, la comunidad de Python es muy
amigable y da la bienvenida a los principiantes.

Python debería funcionar bien en cualquier computadora moderna. Los problemas de


configuración temprana pueden ser frustrantes, pero vale la pena solucionarlos. Una vez que recibes hola
_world.py en ejecución, puede comenzar a aprender Python y su trabajo de programación se volverá
más interesante y satisfactorio.
Empezando 11

MachineTranslatedbyGoogle

Ejecutar programas de Python desde una terminal


La mayoría de los programas que escriba en su editor de texto los ejecutará directamente
desde el editor. Pero a veces es útil ejecutar programas desde una terminal. Por ejemplo, es
posible que desee ejecutar un programa existente sin abrirlo para editarlo.

Puede hacer esto en cualquier sistema con Python instalado si sabe cómo acceder al

directorio donde se almacena el archivo del programa. Para probar esto, asegúrese de haber
guardado el archivo hello_world.py en la carpeta python_work de su escritorio.

en ventanas
Puede usar el comando de terminal cd, para cambiar de directorio, para navegar a través de
su sistema de archivos en una ventana de comandos. El comando dir, para directorio, le
muestra todos los archivos que existen en el directorio actual.
Abra una nueva ventana de terminal e ingrese los siguientes comandos para ejecutar
hello_world.py:

ÿ C:\> cd Escritorio\pytho
Escritorio\python_work
n_work
ÿ C:\Escritorio\python_work>
C:\Escritorio\python_work> directorio

hola_mundo.py
ÿ C:\Escritorio\python_work>
C:\Escritorio\python_work> python hello_world.py
¡Hola mundo Python!

En ÿ, usa el comando cd para navegar a la carpeta python_work , que se encuentra en


la carpeta Escritorio . A continuación, utilice el comando dir para asegurarse de que hello_world.py
esté en esta carpeta ÿ. Luego ejecuta el archivo usando el comando python hello_world.py ÿ.

La mayoría de sus programas funcionarán bien directamente desde su editor. Pero como
su trabajo se vuelve más complejo, querrá ejecutar algunos de sus programas desde una
terminal.

En macOS y Linux
Ejecutar un programa de Python desde una sesión de terminal es lo mismo en Linux y macOS.
Puede usar el comando de terminal cd, para cambiar de directorio, para navegar a través de su
sistema de archivos en una sesión de terminal. El comando ls, para lista, le muestra todos los
archivos no ocultos que existen en el directorio actual.
Abra una nueva ventana de terminal e ingrese los siguientes comandos para ejecutar
hello_world.py:

ÿ ~$ cd Escritorio/python_work/
Escritorio/python_work/
ÿ ~/Escritorio/python_work$ ls
hola_mundo.py
ÿ ~/Desktop/python_work$ python hello_world.py ¡Hola,
mundo de Python!
12 Capítulo 1

MachineTranslatedbyGoogle

En ÿ, usa el comando cd para navegar a la carpeta python_work , que se


encuentra en la carpeta Escritorio . Luego, usa el comando ls para asegurarte de que
hello_world.py esté en esta carpeta ÿ. Luego ejecuta el archivo usando el comando
python hello_world.py ÿ.
Es así de simple. Simplemente use el comando python (o python3) para ejecutar
programas de Python.

Inténtalo tú mismo

Los ejercicios de este capítulo son de naturaleza exploratoria


exploratoria.. A partir del Capítulo 2, los
desafíos que resolverás se basarán en lo que hayas aprendido.

1-1. python.org: explore la página de inicio de Python (https://python.


(https://python.org/)
org/) para
encontrar temas que le interesen. A medida que se familiarice con Python, las diferentes
partes del sitio le resultarán más útiles.

1-2. Errores tipográficos de Hello World: Abra el archivo hello_world.py que acaba de
crear. Haga un error tipográfico en algún lugar de la línea y vuelva a ejecutar el programa.
¿Se puede hacer un error tipográfico que genera un error? ¿Puedes entender el mensaje

de error? ¿Puedes hacer un error tipográfico que no genere un error? ¿Por qué crees que no hizo
¿un error?

1-3. Habilidades infinitas: si tuviera infinitas


i nfinitas habilidades de programación, ¿qué construiría?
Estás a punto de aprender a programar. Si tiene un objetivo final en mente, tendrá un uso
inmediato para sus nuevas habilidades; ahora es un buen momento para redactar
descripciones de lo que desea crear. Es un buen hábito mantener un cuaderno de “ideas” al
que pueda consultar cada vez que desee comenzar un nuevo proyecto. Tómese unos minutos
ahora para describir tres programas que desea crear.

Resumen
En este capítulo, aprendió un poco sobre Python en general e instaló
i nstaló Python en su sistema
si aún no estaba allí. También instaló un editor de texto para facilitar la escritura de código
Python. Ejecutó fragmentos
fragmentos de código de Python en una sesión de terminal y ejecutó su
primer programa, hello_world.py. Probablemente también aprendiste un poco sobre la
solución de problemas.
En el próximo capítulo, aprenderá sobre los diferentes tipos de datos con los que
puede trabajar en sus programas de Python, y también usará variables.
Primeros pasos 13

MachineTranslatedbyGoogle
MachineTranslatedbyGoogle

2
V ariablesarena
Tipos de datos simples

En este capítulo aprenderá sobre los


diferentes tipos de datos con los que puede
trabajar en sus programas de Python. También
aprenderá a usar variables para representar datos en su
programas

Qué sucede realmente cuando ejecutas hello_world.py


Echemos un vistazo más de cerca a lo que hace Python cuando ejecuta hello_world.py.
Resulta que Python hace una buena cantidad de trabajo, incluso cuando ejecuta un
programa simple:

hola_mundo.py print("¡Hola, mundo de Python!")

Cuando ejecute este código, debería ver este resultado:


¡Hola mundo Python!

MachineTranslatedbyGoogle

Cuando ejecuta el archivo hello_world.py, la terminación .py indica que el


archivo es un programa de Python. Luego, su editor ejecuta el archivo a través del
intérprete de Python, que lee el programa y determina qué significa cada palabra en el
programa. Por ejemplo, cuando el intérprete ve la palabra impresa seguida de paréntesis,
imprime en la pantalla lo que está dentro de los paréntesis.

A medida que escribe sus programas, su editor resalta diferentes partes de su


programa de diferentes maneras. Por ejemplo, reconoce que print() es el nombre de
una función y muestra esa palabra en un color. Reconoce que "¡Hola, mundo de
Python!" no es código de Python y muestra esa frase en un color diferente. Esta
característica se llama resaltado de sintaxis y es bastante útil cuando comienza a escribir
sus propios programas.

Variables
Intentemos usar una variable en hello_world.py. Agregue una nueva línea al principio del
archivo y modifique la segunda línea:

hola_mundo.py mensaje = "¡Hola, mundo de Python!"


imprimir (mensaje)

Ejecute este programa para ver qué sucede. Debería ver el mismo resultado que vio
anteriormente:

¡Hola mundo Python!

Hemos agregado una variable llamada mensaje. Cada variable está conectada a un
value, que es la información asociada a esa variable. En este caso, el valor es "Hello
Python world!" texto.
Agregar una variable hace un poco más de trabajo para el intérprete de Python.
Cuando procesa la primera línea, asocia el mensaje variable con "¡Hola, mundo de

Python!" texto. Cuando llega a la segunda línea, imprime el valor asociado con el
mensaje en la pantalla.
Ampliemos este programa modificando hello_world.py para imprimir un segundo
mensaje. Agregue una línea en blanco a hello_world.py y luego agregue dos nuevas
líneas de código:

mensaje = "¡Hola, mundo de Python!"


imprimir (mensaje)

mensaje = "¡Hola, mundo del Curso intensivo de Python!"


imprimir (mensaje)

Ahora, cuando ejecute hello_world.py, debería ver dos líneas de salida:

¡Hola mundo Python!


¡Hola, mundo del Curso intensivo de Python!

16 Capítulo 2

MachineTranslatedbyGoogle

Puede cambiar el valor de una variable en su programa en cualquier momento, y Python


siempre realizará un seguimiento de su valor actual.

Nombrar y usar variables


Cuando usa variables en Python, debe cumplir con algunas reglas y pautas. Romper algunas de
estas reglas provocará errores; otras líneas de guía solo lo ayudan a escribir código que es más fácil

de leer y comprender. Asegúrese de tener en cuenta las siguientes reglas variables:

•Los nombres de las variables solo pueden contener letras, números y guiones bajos.
Pueden comenzar con una letra o un guión bajo, pero no con un número.
Por ejemplo, puede llamar a una variable mensaje_1 pero no a 1_mensaje.

•No se permiten espacios en los nombres de las variables, pero se pueden usar guiones bajos para
separar palabras en los nombres de las variables. Por ejemplo, mensaje_saludo
funciona, pero el mensaje de saludo causará errores.

•Evite usar palabras clave de Python y nombres de funciones como nombres de variables; es
decir, no use palabras que Python haya reservado para un propósito programático particular,
como la palabra print. (Consulte “Palabras clave y funciones integradas de Python” en la

página 471).
•Los nombres de las variables deben ser breves pero descriptivos. Por ejemplo, el nombre es
mejor que n, nombre_estudiante es mejor que s_n y longitud_nombre es mejor que
longitud_nombre_de_personas.

•Tenga cuidado al usar la letra minúscula l y la letra mayúscula O


porque podrían confundirse con los números 1 y 0.

Puede tomar algo de práctica aprender a crear buenos nombres de variables, especialmente
a medida que sus programas se vuelven más interesantes y complicados. A medida que escriba
más programas y comience a leer el código de otras personas, mejorará en la creación de nombres
significativos.

N ota Las variables de Python que está utilizando en este punto deben estar en minúsculas. No obtendrá
errores si usa letras mayúsculas, pero las letras mayúsculas en los nombres de variables tienen
significados especiales que discutiremos en capítulos posteriores.

Evitar errores de nombre al usar variables


Todo programador comete errores, y la mayoría comete errores todos los días.
Aunque los buenos programadores pueden crear errores, también saben cómo responder a esos
errores de manera eficiente. Veamos un error que es probable que cometa al principio y
aprendamos cómo solucionarlo.
Escribiremos algún código que genere un error a propósito. Introducir el
siguiente código, incluido el mensaje de palabra mal escrito que se muestra en negrita:

mensaje = "¡Hola, lector del Curso acelerado de Python!"


imprimir (mensaje)

Variables y tipos de datos simples 17

MachineTranslatedbyGoogle

Cuando ocurre un error en su programa, el intérprete de Python hace todo lo posible


para ayudarlo a descubrir dónde está el problema. El intérprete proporciona un rastreo
cuando un programa no puede ejecutarse correctamente. Un rastreo es un registro de dónde
el intérprete tuvo problemas al intentar ejecutar su código.
Este es un ejemplo del rastreo que proporciona Python después de haber escrito mal
accidentalmente el nombre de una variable:

Rastreo (última llamada más reciente): ÿ Archivo


"hello_world.py", línea 2, en <módulo> ÿ imprimir (mensaje) ÿ
NameError: el nombre 'mensaje' no está definido

El resultado en ÿ informa que se produjo un error en la línea 2 del archivo


hello_world.py. El intérprete muestra esta línea ÿ para ayudarnos a detectar el error
rápidamente y nos dice qué tipo de error encontró ÿ. En este caso encontró un error de
nombre e informa que la variable que se está imprimiendo, mensaje, no ha sido definida.
Python no puede identificar el nombre de variable proporcionado. Un error de nombre
generalmente significa que olvidamos establecer el valor de una variable antes de usarla o
que cometimos un error de ortografía al ingresar el nombre de la variable.
Por supuesto, en este ejemplo omitimos la letra s en el mensaje de nombre de variable
en la segunda línea. El intérprete de Python no revisa la ortografía de su código, pero se
asegura de que los nombres de las variables se escriban de forma coherente. Por ejemplo,
observe lo que sucede cuando también deletreamos mensaje incorrectamente en otro lugar
del código:

mensaje = "¡Hola, lector del Curso acelerado de Python!"


imprimir (mensaje)

¡En este caso, el programa se ejecuta con éxito!

¡Hola, lector del Curso acelerado de Python!

Los lenguajes de programación son estrictos, pero ignoran la buena y la mala


ortografía. Como resultado, no es necesario tener en cuenta las reglas gramaticales y
ortográficas del inglés cuando intenta crear nombres de variables y escribir código.
Muchos errores de programación son simples errores tipográficos de un solo
carácter en una línea de un programa. Si pasa mucho tiempo buscando uno de estos errores,
sepa que está en buena compañía. Muchos programadores experimentados y talentosos
pasan horas buscando este tipo de pequeños errores. Trate de reírse de eso y siga adelante,
sabiendo que sucederá con frecuencia a lo largo de su vida como programador.

Las variables son etiquetas

Las variables a menudo se describen como cuadros en los que puede almacenar valores.
Esta idea puede ser útil las primeras veces que use una variable, pero no es una forma
precisa de describir cómo se representan internamente las variables en Python. Es mucho
mejor pensar en las variables como etiquetas que puede asignar a los valores. También
puede decir que una variable hace referencia a un determinado valor.

18 Capítulo 2

MachineTranslatedbyGoogle

Esta distinción probablemente no importará mucho en sus programas iniciales,


pero vale la pena aprender más temprano que tarde. En algún momento, verá un
comportamiento
comportamiento inesperado de una variable y una comprensión precisa de cómo funcionan
las variables lo ayudará a identificar lo que sucede en su código.

N ota La mejor manera de comprender los nuevos conceptos de programación es intentar usarlos en sus
programas. Si te quedas atascado mientras trabajas en un ejercicio de este libro, intenta hacer

otra cosa por un tiempo. Si todavía está atascado, revise la parte relevante de ese capítulo. Si
aún necesita ayuda, consulte las sugerencias en el Apéndice C.

Inténtalo tú mismo

Escriba un programa separado para realizar cada uno de estos ejercicios. Guarde
cada programa con un nombre de archivo que siga las convenciones estándar de
Python, usando letras minúsculas y guiones bajos, como simple_message.py y simple
_mensajes.py.

2-1. Mensaje simple: asigne un mensaje a una variable y luego imprima ese
mensaje.

2-2. Mensajes simples: asigne un mensaje a una variable e imprima ese mensaje.
Luego cambie el valor de la variable a un nuevo mensaje e imprima el nuevo mensaje.

Instrumentos de cuerda

Debido a que la mayoría de los programas definen y recopilan algún tipo de datos, y luego
hacen algo útil con ellos, es útil clasificar diferentes tipos de datos. El primer tipo de datos que
veremos es la cadena. Las cadenas son bastante simples a primera vista, pero puede usarlas
de muchas maneras diferentes.
Una cadena es una serie de caracteres. Cualquier cosa dentro de comillas se considera
una cadena en Python, y puede usar comillas simples o dobles alrededor de sus cadenas
de esta manera:

"Esto es una cadena".


'Esto también es una cadena.'

Esta flexibilidad le permite usar comillas y apóstrofes dentro de sus cadenas:

'Le dije a mi amigo: "¡Python es mi lenguaje favorito!"'


"El lenguaje 'Python' lleva el nombre de Monty Python, no de la serpiente".
"Una de las fortalezas de Python es su comunidad diversa y solidaria".
Exploremos algunas de las formas en que puede usar cadenas.

Variables y tipos de datos simples 19

MachineTranslatedbyGoogle

Cambio de mayúsculas y minúsculas en una cadena con métodos

Una de las tareas más simples que puede hacer con cadenas es cambiar el caso de las
palabras en una cadena. Mire el siguiente código e intente determinar qué está
sucediendo:

nombre.py nombre = "ada lovelace"

imprimir (nombre. título ())

Guarde este archivo como name.py y luego ejecútelo. Debería ver esta salida:

ada lovelace

En este ejemplo, el nombre de la variable hace referencia a la cadena en


minúsculas "ada lovelace". El método title() aparece después de la variable en la llllamada
amada print() .
Un método es una acción que Python puede realizar en un dato. El punto (.) después del
nombre en name.title() le dice a Python que haga que el método title() actúe sobre el
nombre de la variable. Cada método va seguido de un conjunto de paréntesis, porque los
métodos a menudo necesitan información adicional para hacer su trabajo. Esa información
se proporciona entre paréntesis. La función title() no necesita información adicional, por lo
que sus paréntesis están vacíos.
El método title() cambia cada palabra al caso del título, donde cada palabra comienza con una letra mayúscula.

Esto es útil porque a menudo querrá pensar en un nombre como una pieza de información. Por ejemplo, es posible que

desee que su programa reconozca los valores de entrada Ada, ADA y ada como el mismo nombre y los muestre todos

como Ada.

Varios otros métodos útiles están disponibles para tratar el caso también. Por
ejemplo, puede cambiar una cadena a letras mayúsculas o minúsculas como esta:

nombre = "Ada Lovelace"

imprimir (nombre. superior ())


imprimir (nombre. inferior ())

Esto mostrará lo siguiente:

ADA LOVELACE
ada lovelace

El método lower() es particularmente útil para almacenar datos. Muchas veces no


querrá confiar en las mayúsculas que proporcionan sus usuarios, por lo que convertirá
las cadenas a minúsculas antes de almacenarlas. Luego, cuando desee mostrar la
información, utilizará el caso que tenga más sentido para cada cadena.
20 Capítulo 2

MachineTranslatedbyGoogle

Uso de variables en cadenas

En algunas situaciones, querrá usar el valor de una variable dentro de una cadena. Por
ejemplo, es posible que desee que dos variables representen un nombre y un apellido
respectivamente, y luego desee combinar esos valores para mostrar el nombre completo
de alguien:

nombre_completo.py nombre = "ada"


last_name = "enlace de amor"
ÿ nombre_completo = f"{nombre} {apellido}"
imprimir (nombre_completo)
(nombre_completo)

Para insertar el valor de una variable en una cadena, coloque la letra f


inmediatamente antes de las comillas de apertura ÿ. Coloque llaves alrededor del nombre
o nombres de cualquier variable que desee usar dentro de la cadena. Python reemplazará
cada variable con su valor cuando se muestre la cadena.
Estas cadenas se llaman cadenas f. La f es para formato, porque Python
formatea la cadena reemplazando el nombre de cualquier variable entre llaves con su
valor. La salida del código anterior es:

ada lovelace

Puedes hacer mucho con f-strings. Por ejemplo, puede usar f-strings para
redactar mensajes completos usando la información asociada con una variable, como
se muestra aquí:

nombre = "ada"
last_name = "enlace de amor"
nombre_completo = f"{nombre} {apellido}"
ÿ print(f"Hola, {nombre_completo.título()}!")

El nombre completo se usa en una oración que saluda al usuario ÿ, y el método


title() cambia el nombre a mayúsculas y minúsculas. Este código devuelve un saludo
simple pero con un formato agradable:

¡Hola, Ada Lovelace!

También puede usar f-strings para redactar un mensaje y luego asignar el mensaje
completo a una variable:

nombre = "ada"
last_name = "enlace de amor"
nombre_completo = f"{nombre} {apellido}"
ÿ mensaje = f"Hola, {nombre_completo.título()}!"
ÿ imprimir (mensaje)

Este código muestra el mensaje ¡Hola, Ada Lovelace! también, pero al asignar
el mensaje a una variable ÿ hacemos que la llamada final a print() sea mucho más
simple ÿ.

Variables y tipos de datos simples 21

MachineTranslatedbyGoogle

N ota F-strings se introdujeron por primera vez en Python 3.6. Si está utilizando Python 3.5 o anterior,
necesitará usar el método format() en lugar de esta sintaxis f . Para usar format(), enumere las variables que
desea usar en la cadena dentro de los paréntesis que siguen al formato.
Se hace referencia a cada variable mediante un conjunto de llaves; las llaves se rellenarán con los valores
enumerados entre paréntesis en el orden proporcionado:

nombre_completo = "{} {}".formato(nombre, apellido)

Adición de espacios en blanco a cadenas con tabulaciones o saltos de línea

En programación, los espacios en blanco se refieren a cualquier carácter que no se imprima, como
espacios, tabulaciones y símbolos de final de línea. Puede usar espacios en blanco para organizar su salida
para que sea más fácil de leer para los usuarios.
Para agregar una tabulación a su texto, use la combinación de caracteres \t como se muestra en ÿ:

>>> imprimir("Pitón")
Python
ÿ >>> imprimir("\tPython")
Pitón

Para agregar una nueva línea en una cadena, use la combinación de caracteres \n:

>>> print("Idiomas:\nPython\nC\nJavaScript")
Idiomas:
Pitón
C

JavaScript

También puede combinar tabulaciones y saltos de línea en una sola cadena. La cadena "\n\t" le dice a
Python que se mueva a una nueva línea y comience la siguiente línea con una tabulación.
El siguiente ejemplo muestra cómo puede usar una cadena de una línea para generar cuatro líneas de salida:

>>> print("Idiomas:\n\tPython\n\tC\n\tJavaScript")
Idiomas:
Pitón
C

JavaScript

Las líneas nuevas y los tabuladores serán muy útiles en l os próximos dos capítulos cuando
comience a producir muchas líneas de salida a partir de unas pocas líneas de código.

Eliminación de espacios en blanco

Los espacios en blanco adicionales pueden ser confusos en sus programas. Para los programadores ,
python y python se parecen bastante. Pero para un programa, son dos cadenas diferentes. Python detecta
el espacio adicional en 'python' y lo considera significativo a menos que le indique lo contrario.

22 Capítulo 2

MachineTranslatedbyGoogle

Es importante pensar en los espacios en blanco, porque a menudo querrá comparar dos
cadenas para determinar si son iguales. Por ejemplo, una instancia importante podría implicar verificar
los nombres de usuario de las personas cuando inician sesión en un sitio web. Los espacios en blanco
adicionales también pueden ser confusos en situaciones mucho más simples. Afortunadamente,
Python facilita la eliminación de espacios en blanco superfluos de los datos que ingresan las personas.

Python puede buscar espacios en blanco adicionales en los lados derecho e izquierdo de
una cadena. Para asegurarse de que no haya espacios en blanco en el extremo derecho de una
cadena, utilice el método rstrip() .

ÿ >>> idioma_favorito = 'python' ÿ >>>


idioma_favorito ' python' ÿ >>>
idioma_favorito.rstrip ()

'pitón'
ÿ >>> idioma_favorito
'pitón'

El valor asociado con favorite_language en ÿ contiene un espacio en blanco adicional al final


de la cadena. Cuando le pide a Python este valor en una sesión de terminal, puede ver el espacio
al final del valor ÿ. Cuando el método rstrip() actúa sobre la variable favorite_language en ÿ, se
elimina este espacio extra. Sin embargo, solo se elimina temporalmente. Si vuelve a solicitar el valor
de favorite_language , puede ver que la cadena se ve igual que cuando se ingresó, incluido el espacio
en blanco adicional ÿ.

Para eliminar el espacio en blanco de la cadena de forma permanente, debe asociar el


valor eliminado con el nombre de la variable:

>>> idioma_favorito = 'python ' ÿ


>>> idioma_favorito = idioma_favorito.rstrip()
>>> lenguaje_favorito
'python'

Para quitar el espacio en blanco de la cadena, elimine el espacio en blanco del lado
derecho de la cadena y luego asocie este nuevo valor con la variable original, como se muestra en
ÿ. Cambiar el valor de una variable se hace a menudo en programación. Así es como se puede
actualizar el valor de una variable a medida que se ejecuta un programa o en respuesta a la entrada
del usuario.
También puede eliminar los espacios en blanco del lado izquierdo de una cadena usando el
método lstrip() , o desde ambos lados a la vez usando strip():
' '
ÿ >>> idioma_favorito = python ÿ >>>
idioma_favorito.rstrip ()
' python'
ÿ >>> idioma_favorito.lstrip ()
'python'
ÿ >>> idioma_favorito.strip ()
'pitón'

Variables y tipos de datos simples


si mples 23

MachineTranslatedbyGoogle

En este ejemplo, comenzamos con un valor que tiene espacios en blanco al principio y
al final ÿ. Luego eliminamos el espacio adicional del lado
l ado derecho en ÿ, del lado izquierdo en
ÿ y de ambos lados en ÿ. Experimentar con estas funciones de eliminación puede ayudarlo a
familiarizarse con la manipulación de cadenas. En el mundo real, estas funciones de eliminación
se utilizan con mayor frecuencia para limpiar la entrada del usuario antes de que se almacene
en un programa.

Evitar errores de sintaxis con cadenas

Un tipo de error que puede ver con cierta regularidad es un error de sintaxis.
Se produce un error de sintaxis cuando Python no reconoce una sección de su programa
como código de Python válido. Por ejemplo, si usa un apóstrofo entre comillas simples,
generará un error. Esto sucede porque Python interpreta todo lo que se encuentra entre la
primera comilla simple y el apóstrofe como una cadena. Luego intenta interpretar el resto del
texto como código Python, que
provoca errores.

Aquí se explica cómo usar comillas simples y dobles correctamente. Guarde este programa
como apostrophe.py y luego ejecútelo:

apostrofe.py mensaje = "Una de las fortalezas de Python es su comunidad diversa". imprimir


(mensaje)

El apóstrofe aparece dentro de un conjunto de comillas dobles, por lo que el intérprete


de Python no tiene problemas para leer la cadena correctamente:

Una de las fortalezas de Python es su comunidad diversa.

Sin embargo, si usa comillas simples, Python no puede identificar dónde está la cadena.
debería terminar:

mensaje = 'Una de las fortalezas de Python es su comunidad diversa.'


imprimir (mensaje)

Verá el siguiente resultado:

Archivo "apostrophe.py", línea 1


mensaje = 'Una de las fortalezas de Python es su comunidad diversa.'
^ÿ
Error de sintaxis: sintaxis invalida

En la salida puede ver que el error ocurre en ÿ justo después de la


segunda comilla simple. Este error de sintaxis indica que el intérprete no reconoce algo
en el código como código de Python válido. Los errores pueden provenir de una variedad de
fuentes, y señalaré algunos comunes a medida que surjan. Es posible que vea errores de
sintaxis a menudo a medida que aprende a escribir el código de Python adecuado. Los

errores de sintaxis también son el tipo de error menos específico, por lo que pueden ser difíciles
y frustrantes de identificar y corregir. Si se queda atascado en un error particularmente
persistente, consulte las sugerencias en el Apéndice C.

24 Capítulo 2

MachineTranslatedbyGoogle

N ota La función de resaltado de sintaxis de su editor debería ayudarlo a detectar algunos errores de
sintaxis rápidamente mientras escribe sus programas. Si ve el código Python resaltado
como si fuera inglés o inglés resaltado como si fuera código Python, es probable que tenga
una comilla que no coincida en algún lugar de su archivo.

Inténtalo tú mismo

Guarde cada uno de los siguientes ejercicios como un archivo separado con un nombre como

nombre_casos.py. Si se atasca, tómese un descanso o consulte las sugerencias en el Apéndice C.

2-3. Mensaje personal: use una variable para representar el nombre de una persona e imprima un mensaje

para esa persona. Su mensaje debe ser simple, como: "Hola Eric, ¿te gustaría aprender algo de Python hoy?"

2-4. Casos de nombres: use una variable para representar el nombre de una persona y luego imprima el

nombre de esa persona en minúsculas, mayúsculas y mayúsculas y minúsculas.

2-5. Cita famosa: encuentra una cita de una persona famosa que admires. Imprima la cita y el nombre de

su autor. Su salida debe ser similar a la siguiente, incluidas las comillas:

Albert Einstein dijo una vez: “Una persona que nunca cometió un error nunca

intentó nada nuevo”.

2-6. Cita famosa 2: repite el ejercicio 2-5, pero esta vez, representa el nombre de la persona

famosa usando una variable llamada persona_famosa. Luego, redacte su mensaje y represéntelo con una

nueva variable llamada mensaje. Imprime tu mensaje.

2-7. Eliminación de nombres: use una variable para representar el nombre de una persona e incluya algunos

caracteres de espacio en blanco al principio y al final del nombre. Asegúrese de usar cada combinación de

caracteres, "\t" y "\n", al menos una vez.

Imprima el nombre una vez, de modo que se muestre el espacio en blanco alrededor del nombre.

Luego imprima el nombre usando cada una de las tres funciones de eliminación,
lstrip(), rstrip() y strip().

Números
Los números se utilizan con bastante frecuencia en la programación para llevar la puntuación
en los juegos, representar datos en visualizaciones, almacenar información en aplicaciones
web, etc. Python trata los números de varias maneras diferentes, dependiendo de cómo se
usen. Primero veamos cómo Python maneja los números enteros, porque son los más simples

para trabajar.
Variables y tipos de datos simples 25

MachineTranslatedbyGoogle

enteros
Puede sumar (+), restar (-), multiplicar (*) y dividir (/) enteros en Python.

>>> 2 + 3

5 >>> 3 - 2

1 >>> 2 3
* 6 >>>
3/2
1.5

En una sesión de terminal, Python simplemente devuelve el resultado de la operación.


Python usa dos símbolos de multiplicación para representar exponentes:

>>> 3 ** 2

9 >>> 3 ** 3

27 >>> 10 ** 6

1000000

Python también admite el orden de las operaciones, por lo que puede usar varias
operaciones en una expresión. También puede usar paréntesis para modificar el orden de
las operaciones para que Python pueda evaluar su expresión en el orden que especifique.
Por ejemplo:

>>> 2 + 3*4
14
>>> (2 + 3) * 4
20

El espaciado en estos ejemplos no tiene efecto sobre cómo Python evalúa las
expresiones; simplemente lo ayuda a detectar más rápidamente las operaciones que tienen
prioridad cuando está leyendo el código.

flotadores

Python llama flotante a cualquier número con un punto decimal . Este término se usa en
la mayoría de los lenguajes de programación y se refiere al hecho de que un punto decimal
puede aparecer en cualquier posición de un número. Cada lenguaje de programación debe
diseñarse cuidadosamente para administrar correctamente los números decimales, de
modo que los números se comporten adecuadamente sin importar dónde aparezca el punto
decimal.
26 Capítulo 2

MachineTranslatedbyGoogle

En su mayor parte, puede usar decimales sin preocuparse por cómo se comportan.
Simplemente ingrese
ingrese los números que desea usar, y lo más probable es que Python haga lo que
espera:

>>> 0,1 + 0,1


0.2
>>> 0,2 + 0,2

0,4
>>> 2 * 0,1
0,2
>>> 2 * 0,2
0.4

Pero tenga en cuenta que a veces puede obtener un número arbitrario de deci
mal lugares en su respuesta:

>>> 0,2 + 0,1


0.30000000000000004 *
0.1 >>> 3
0.30000000000000004

Esto sucede en todos los idiomas y es de poca importancia. Python intenta encontrar una
manera de representar el resultado con la mayor precisión posible, lo que a veces es difícil dada la
forma en que las computadoras tienen que representar números internamente. Simplemente ignore
los lugares decimales adicionales por ahora; aprenderá formas de lidiar con los lugares adicionales
cuando lo necesite en los proyectos de la Parte II.

Enteros y Flotantes
Cuando divide dos números, incluso si son números enteros que dan como resultado un número
entero, siempre obtendrá un flotante:

>>> 4/2
2.0

Si mezcla un número entero y un flotante en cualquier otra operación, también obtendrá


un flotante:

>>> 1 + 2,0
3.0
>>> 2* 6,0 3.0

>>> 3.0 ** 2
9.0

Python utiliza por defecto un flotante en cualquier operación que utilice un flotante, incluso si el
la salida es un número entero.
Variables y tipos de datos simples 27

MachineTranslatedbyGoogle

Guiones bajos en números


Cuando escribe números largos, puede agrupar dígitos usando guiones bajos para que los
números grandes sean más legibles:

>>> universo_eda
universo_edad
d = 14_000_000_00
14_000_000_000
0

Cuando imprime un número que se definió usando guiones bajos, Python imprime solo
los dígitos:

>>> imprimir(universo_edad)
14000000000

Python ignora los guiones bajos al almacenar este tipo de valores. Incluso
si no agrupa los dígitos de tres en tres, el valor no se verá afectado.
Para Python, 1000 es lo mismo que 1_000, que es lo mismo que 10_00. Esta función
funciona para números enteros y flotantes, pero solo está disponible en Python 3.6 y
versiones posteriores.

Asignación Múltiple
Puede asignar valores a más de una variable usando una sola línea.
Esto puede ayudar a acortar sus programas y hacerlos más fáciles de leer; utilizará esta
técnica con mayor frecuencia al inicializar un conjunto de números.
Por ejemplo, así es como puede inicializar las variables x, y y z
a cero:

>>> x, y, z = 0, 0, 0

Debe separar los nombres de las variables con comas y hacer lo mismo con los
valores, y Python asignará cada valor a su variable posicionada respectivamente. Siempre
que el número de valores coincida con el número de variables, Python los emparejará
correctamente.

constantes
Una constante es como una variable cuyo valor permanece igual a lo largo de la vida de un
programa. Python no tiene tipos constantes incorporados, pero los programadores de Python
usan todas las letras mayúsculas para indicar que una variable debe tratarse como una
constante y nunca cambiarse:

MAX_CONEXIONES = 5000

Cuando desee tratar una variable como una constante en su código, haga que el nombre
de la variable esté en mayúsculas.
28 Capítulo 2

MachineTranslatedbyGoogle

Inténtalo tú mismo

2-8. Número ocho: escriba operaciones de suma, resta, multiplicación y división que den
como resultado el número 8. Asegúrese de encerrar sus operaciones en las llamadas print()
para ver los resultados. Debes crear cuatro líneas que se vean así:

imprimir (5 + 3)

Su salida debería ser simplemente cuatro líneas con el número 8 apareciendo una vez
en cada línea.

2-9. Número favorito: use una variable para representar su número favorito. Luego, usando
esa variable, cree un mensaje que revele su número favorito. Imprime
I mprime ese mensaje.

Comentarios
Los comentarios son una característica extremadamente útil en la mayoría de los
lenguajes de programación. Todo lo que ha escrito en sus programas hasta ahora es código de Python.
A medida que sus programas se vuelven más largos y complicados, debe agregar notas dentro
de sus programas que describan su enfoque general del problema que está resolviendo. Un
comentario le permite escribir notas en inglés dentro de sus programas.

¿Cómo se escriben los comentarios?

En Python, la marca hash (#) indica un comentario. El intérprete de Python ignora todo lo que
sigue a una marca hash en su código. Por ejemplo:

comentario.py # Di hola a todos.


print("¡Hola, gente de Python!")

Python ignora la primera línea y ejecuta la segunda línea.

¡Hola gente de Python!

¿Qué tipo de comentarios debe escribir?

La razón principal para escribir comentarios es explicar qué se supone que debe hacer su código
y cómo lo está haciendo funcionar. Cuando estás en medio de un proyecto, entiendes cómo
encajan todas las piezas. Pero cuando regresa a un proyecto después de un tiempo fuera,
probablemente lo haya olvidado.
probablemente lo haya olvidado.

Variables y tipos de datos simples 29

MachineTranslatedbyGoogle

algunos de los detalles. Siempre puede estudiar su código por un tiempo y descubrir
cómo se suponía que debían funcionar los segmentos, pero escribir buenos comentarios
puede ahorrarle tiempo al resumir su enfoque general en un inglés claro.
Si desea convertirse en un programador profesional o colaborar con otros
programadores, debe escribir comentarios significativos. Hoy en día, la mayor parte del
software se escribe en colaboración, ya sea por un grupo de empleados de una empresa
o por un grupo de personas que trabajan juntas en un proyecto de código abierto.
Los programadores expertos esperan ver comentarios en el código, por lo que es mejor
comenzar a agregar comentarios descriptivos a sus programas ahora. Escribir comentarios
claros y concisos en su código es uno de los hábitos más beneficiosos que puede formar
como nuevo programador.
Cuando esté determinando si escribir un comentario, pregúntese si
tenías que considerar varios enfoques antes de encontrar una forma razonable de
hacer que algo funcionara; si es así, escribe un comentario sobre tu solución. Es mucho
más fácil eliminar comentarios adicionales más adelante que regresar y escribir comentarios
para un programa escasamente comentado. De ahora en adelante, usaré comentarios en
ejemplos a lo largo de este libro para ayudar a explicar secciones de código.

Inténtalo tú mismo

2-10. Agregar comentarios: elija dos de los programas que ha escrito y agregue al
menos un comentario a cada uno. Si no tiene nada específico que escribir porque sus
programas son demasiado simples en este punto, simplemente agregue su nombre y la
fecha actual en la parte superior de cada archivo de programa. Luego escribe una oración
que describa lo que hace el programa.

El Zen de Python
Los programadores experimentados de Python lo alentarán a evitar la complejidad y apuntar a la
simplicidad siempre que sea posible. La filosofía de la comunidad de Python está contenida en “The
Zen of Python” de Tim Peters. Puede acceder a este breve conjunto de principios para escribir un
buen código de Python ingresando import this
en su intérprete. No reproduciré todo el "Zen de Python" aquí, pero compartiré algunas líneas
para ayudarlo a comprender por qué deberían ser importantes para usted como programador
principiante de Python.

>>> import this El


zen de Python, de Tim Peters Lo bello es
mejor que lo feo.
Los programadores de Python aceptan la idea de que el código puede ser hermoso
y elegante. En la programación, las personas resuelven problemas. Los programadores
siempre han respetado las soluciones bien diseñadas, eficientes e incluso hermosas para

30 Capítulo 2

MachineTranslatedbyGoogle

problemas. A medida que aprenda más sobre Python y lo use para escribir más código,
alguien podría mirar por encima de su hombro un día y decir: "¡Guau, ese es un código hermoso!"

Lo simple es mejor que lo complejo.

Si tiene que elegir entre una solución simple y una compleja, y ambas
trabajo, use la solución simple. Su código será más fácil de mantener y será más fácil para
usted y para otros desarrollar ese código más adelante.

Complejo es mejor que complicado.

La vida real es complicada y, a veces, una solución simple a un problema es


inalcanzable. En ese caso, use la solución más simple que funcione.

La legibilidad cuenta.

Incluso cuando su código sea complejo, trate de hacerlo legible. Cuando estas
trabajando en un proyecto que involucra una codificación compleja, concéntrese en escribir
comentarios informativos para ese código.

Debe haber una, y preferiblemente


preferiblemente solo una, forma obvia de hacerlo.

Si se le pide a dos programadores de Python que resuelvan el mismo problema, deberían


encontrar soluciones bastante compatibles.
compatibles. Esto no quiere decir que no haya espacio para la
creatividad en la programación. ¡De lo contrario! Pero gran parte de la programación consiste
en utilizar enfoques pequeños y comunes para situaciones simples dentro de un proyecto más
grande y creativo. Los aspectos prácticos de sus programas deberían tener sentido para otros
programadores de Python.

Ahora es mejor que nunca.

Podrías pasar el resto de tu vida aprendiendo todas las complejidades de Python


y de la programación en general, pero nunca completarías ningún proyecto. No intente
escribir un código perfecto; escriba código que funcione y luego decida si mejorar su código
para ese proyecto o pasar a algo nuevo.
A medida que continúe con el próximo capítulo y comience a profundizar en temas
más complicados, intente tener en cuenta esta filosofía de simplicidad y claridad.
Los programadores experimentados
experimentados respetarán más su código y estarán felices de brindarle
comentarios y colaborar con usted en proyectos interesantes.

Inténtalo tú mismo
2-11. Zen of Python: Ingrese importar esto en una sesión de terminal de Python
y hojee los principios adicionales.

Variables y tipos de datos simples 31

MachineTranslatedbyGoogle

Resumen
En este capítulo aprendiste a trabajar con variables. Aprendió a usar nombres de variables
descriptivos y cómo resolver errores de nombre y errores de sintaxis cuando surgen.
Aprendió qué son las cadenas y cómo mostrarlas en minúsculas, mayúsculas y título.
Comenzó a usar espacios en blanco para organizar la salida ordenadamente y aprendió a
eliminar los espacios en blanco innecesarios de diferentes partes de una cadena. Comenzó
a trabajar con números enteros y flotantes, y aprendió algunas de las formas en que puede
trabajar con datos numéricos. También aprendió a escribir comentarios explicativos para
que su código sea más fácil de leer para usted y para otros. Finalmente, lee sobre la
filosofía de mantener su código lo más simple posible, siempre que sea posible.

En el Capítulo 3, aprenderá a almacenar colecciones de información en


estructuras de datos llamadas listas. Aprenderá a trabajar a través de una lista,
manipulando cualquier información en esa lista.
32 Capítulo 2

MachineTranslatedbyGoogle

3
Introducción a las listas

En este capítulo y el siguiente, aprenderá qué


son las listas y cómo empezar a trabajar con los
elementos de una lista. Las listas le permiten almacenar
conjuntos de información en un solo lugar, ya sea que
tenga solo unos pocos elementos o millones de elementos. Las
listas son una de las características más poderosas de Python,
fácilmente accesibles para los nuevos programadores, y unen
muchos conceptos importantes en la programación.

¿Qué es una lista?


Una lista es una colección de elementos en un orden particular. Puede hacer
una lista que incluya las letras del alfabeto, los dígitos del 0 al 9 o los nombres
de todas las personas de su familia. Puedes poner lo que quieras en una lista, y

MachineTranslatedbyGoogle

los elementos de su lista no tienen que estar relacionados de ninguna manera en particular. Debido
a que una lista generalmente contiene más de un elemento, es una buena idea hacer que el nombre
de su lista sea plural, como letras, dígitos o nombres.
En Python, los corchetes ([]) indican una lista y los elementos individuales
individuales de la lista están
separados por comas. Aquí hay un ejemplo simple de una lista que contiene algunos tipos de
bicicletas:

bicicletas.py bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


'specialized']
imprimir (bicicletas)

Si le pide a Python que imprima una lista, Python devuelve su representación del
lista, incluidos los corchetes:

['trek', 'cannondale', 'redline', 'especializado']


'especializado']

Debido a que este no es el resultado que desea que vean sus usuarios, aprendamos cómo
para acceder a los elementos individuales de una lista.

Acceso a elementos en una lista

Las listas son colecciones ordenadas, por lo que puede acceder a cualquier elemento de
una lista diciéndole a Python la posición o el índice del elemento deseado. Para acceder a un
elemento de una lista, escriba el nombre de la lista seguido del índice del elemento entre
corchetes.
Por ejemplo, saquemos la primera bicicleta de la lista bicicletas:

bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


'specialized']
u imprime(bicicletas[0])
imprime(bicicletas[0])

La sintaxis para esto se muestra en u. Cuando pedimos un solo artículo de un


list, Python devuelve solo ese elemento sin corchetes:

emigrar

Este es el resultado que desea que vean sus usuarios: una salida limpia y con un formato
ordenado.
También puede usar los métodos de cadena del Capítulo 2 en cualquier elemento de esta
lista. Por ejemplo, puede formatear el elemento 'trek' de forma más clara usando el método title() :

bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


'specialized']
imprimir (bicicletas [0]. título ())

Este ejemplo produce el mismo resultado


r esultado que el ejemplo anterior, excepto que 'Trek'
está en mayúsculas.
34 Capítulo 3

MachineTranslatedbyGoogle

Las posiciones de índice comienzan en 0, no en 1

Python considera que el primer elemento de una lista está en la posición 0, no en la posición 1.
Esto es cierto para la mayoría de los lenguajes de programación, y la razón tiene que ver con cómo
se implementan las operaciones de lista en un nivel inferior. Si recibe resultados inesperados,
determine si está haciendo una comparación simple
error.

El segundo elemento de una lista tiene un índice de 1. Usando este sistema de conteo,
puede obtener cualquier elemento que desee de una lista restando uno de su posición en la lista.
Por ejemplo, para acceder al cuarto elemento de una lista, solicita el elemento en el índice 3.

Lo siguiente pregunta por las bicicletas en el índice 1 y el índice 3:

bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


imprimir(bicicletas[1])
imprimir(bicicletas[3])

Este código devuelve la segunda y cuarta bicicleta de la lista:

cannondale

especializado

Python tiene una sintaxis especial para acceder al último elemento de una lista. por preguntar
Al buscar el elemento en el índice -1, Python siempre devuelve el último elemento de la lista:

bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


imprimir(bicicletas[-1])

Este código devuelve el valor 'especializado'. Esta sintaxis es bastante útil, porque a
menudo querrá acceder a los últimos elementos de una lista sin saber exactamente cuánto
tiempo tiene la lista. Esta convención se extiende también a otros valores de índice negativos. El
índice -2 devuelve el segundo elemento desde el final de la lista, el índice -3 devuelve el tercer
elemento desde el final y así sucesivamente.

Uso de valores individuales de una lista

Puede utilizar valores individuales de una lista como lo haría con cualquier otra variable. Por
ejemplo, puede usar f-strings para crear un mensaje basado en un valor de una lista.

Intentemos sacar la primera bicicleta de la lista y componer un mensaje usando ese valor.

bicicletas = ['trek', 'cannondale', 'redline', 'specialized']


u message = f"Mi primera bicicleta fue una {bicicletas[0].t
{bicicletas[0].title()}."
itle()}."

imprimir (mensaje)
Introducción a las listas 35

MachineTranslatedbyGoogle

En u, construimos una oración usando el valor en bicicletas[0] y lo asignamos a la


variable mensaje. El resultado es una oración simple sobre la primera bicicleta en la
lista:

Mi primera bicicleta fue una Trek.

Inténtalo tú mismo

Pruebe estos programas breves para obtener experiencia de primera mano con las listas de Python.
Es posible que desee crear una nueva carpeta para los ejercicios de cada capítulo para
mantenerlos organizados.

3-1. Nombres: almacene los nombres de algunos de sus amigos en una lista llamada nombres. Imprima
el nombre de cada persona accediendo a cada elemento de la lista, uno a la vez.

3-2. Saludos: Comience con la lista que usó en el Ejercicio 3-1, pero en lugar de solo imprimir el
nombre de cada persona, imprima un mensaje para ellos. El texto de cada mensaje debe ser el
mismo, pero cada mensaje debe estar personalizado con el nombre de la persona.

3-3. Su propia lista: Piense en su medio de transporte favorito, como una motocicleta o un
automóvil, y haga una lista que almacene varios ejemplos. Use su lista para imprimir una serie de
afirmaciones sobre estos elementos, como "Me gustaría tener una motocicleta Honda".

Cambio, adición y eliminación de elementos


La mayoría de las listas que cree serán dinámicas, lo que significa que creará una

lista y luego agregará y eliminará elementos de ella a medida que su programa sigue
su curso. Por ejemplo, puede crear un juego en el que un jugador tenga que disparar a
los extraterrestres desde el cielo. Puede almacenar el conjunto inicial de alienígenas en
una lista y luego eliminar un alienígena de la lista cada vez que uno es derribado. Cada
vez que aparece un nuevo extraterrestre en la pantalla, lo agregas a la lista. Tu lista de
alienígenas aumentará y disminuirá en longitud a lo largo del juego.

Modificación de elementos en una lista


La sintaxis para modificar un elemento es similar a la sintaxis para acceder a un
elemento en una lista. Para cambiar un elemento, use el nombre de la lista seguido del
índice del elemento que desea cambiar y luego proporcione el nuevo valor que desea que
tenga ese elemento.
36 Capítulo 3

MachineTranslatedbyGoogle

Por ejemplo, supongamos que tenemos una lista de motocicletas y el primer elemento en
la lista es 'honda'. ¿Cómo cambiaríamos el valor de este primer artículo?

motos.py u motos = ['honda', 'yamaha', 'suzuki']


imprimir (motos)

v motos[0] = 'ducati'
imprimir (motos)
El código en u define la lista original, con 'honda' como primer elemento.
El código en v cambia el valor del primer elemento a 'ducati'. El resultado muestra que el
primer elemento se ha cambiado y el resto de la lista permanece igual:

['honda','yamaha','suzuki']
['ducati', 'yamaha', 'suzuki']

Puede cambiar el valor de cualquier elemento de una lista, no solo del primero.

Adición de elementos a una lista

Es posible que desee agregar un nuevo elemento a una lista por muchas razones. Por
ejemplo, es posible que desee hacer que aparezcan nuevos extraterrestres en un juego,
agregar nuevos datos a una visualización o agregar nuevos usuarios registrados a un sitio web
que ha creado. Python proporciona varias formas de agregar nuevos datos a las listas existentes.

Agregar elementos al final de una lista

La forma más sencilla de agregar un nuevo elemento a una lista es agregar el elemento a la lista.
Cuando agrega un elemento a una lista, el nuevo elemento se agrega al final de la lista. Usando la
misma lista que teníamos en el ejemplo anterior, agregaremos el nuevo elemento 'ducati' al final de
la lista:

motos = ['honda', 'yamaha', 'suzuki']


imprimir (motos)

u motocicletas.append('ducati')
imprimir (motos)

El método append() en u agrega 'ducati' al final de la lista sin


afectando a cualquiera de los otros elementos de la lista:

['honda','yamaha','suzuki']
['honda', 'yamaha', 'suzuki', 'ducati']
Introducción a las listas 37

MachineTranslatedbyGoogle

El método append() facilita la creación dinámica de listas. Por ejemplo, puede


comenzar con una lista vacía y luego agregar elementos a la lista mediante una serie de
llamadas append() . Usando una lista vacía, agreguemos los elementos 'honda', 'yamaha' y
'suzuki' a la lista:

motos = []

motocicletas.append('honda')
motocicletas.append('yamaha')
motocicletas.append('suzuki')

imprimir (motos)

La lista resultante tiene exactamente el mismo aspecto que las listas de los ejemplos
anteriores:

['honda','yamaha','suzuki']

La creación de listas de esta manera es muy común, porque a menudo no sabrá los
datos que sus usuarios desean almacenar en un programa hasta después de que el programa
se esté ejecutando. Para que sus usuarios tengan el control, comience definiendo una lista
vacía que contendrá los valores de los usuarios. Luego agregue cada nuevo valor proporcionado
a la lista que acaba de crear.

Insertar elementos en una lista

Puede agregar un nuevo elemento en cualquier posición de su lista usando insert()


método. Para ello, especifique el índice del nuevo elemento y el valor del nuevo elemento.

motos = ['honda', 'yamaha', 'suzuki']

u motocicletas.insertar(0, 'ducati')
imprimir (motos)

En este ejemplo, el código en u inserta el valor 'ducati' al principio de la lista. El método


insert() abre un espacio en la posición 0 y almacena el valor 'ducati' en esa ubicación. Esta
operación desplaza todos los demás valores de la lista una posición a la derecha:

['ducati', 'honda', 'yamaha', 'suzuki']

Eliminación de elementos de una lista

A menudo, deseará eliminar un elemento o un conjunto de elementos de una lista. Por


ejemplo, cuando un jugador dispara a un alienígena desde el cielo, lo más probable es que
quieras eliminarlo de la lista de alienígenas activos. O cuando un usuario

38 Capítulo 3

MachineTranslatedbyGoogle

decide cancelar su cuenta en una aplicación web que usted creó, querrá eliminar a
ese usuario de la lista de usuarios activos. Puede eliminar un elemento según su
posición en la lista o según su valor.

Eliminación de un elemento mediante la instrucción del

Si conoce la posición del elemento que desea eliminar de una lista, puede usar la
instrucción del .

motos = ['honda', 'yamaha', 'suzuki']


print(motos)

u del motos[0]
print(motos)

El código en u usa del para eliminar el primer elemento, 'honda', de la lista de


motocicletas:

['honda','yamaha','suzuki']
['yamaha', 'suzuki']

Puede eliminar un elemento de cualquier posición en una lista utilizando la


instrucción del si conoce su índice. Por ejemplo, aquí se explica cómo eliminar el
segundo elemento, 'yamaha', de la lista:

motos = ['honda', 'yamaha', 'suzuki']


imprimir (motos)

del motos[1]
print(motos)

La segunda motocicleta se elimina de la lista:

['honda','yamaha','suzuki']
['honda', 'suzuki']

En ambos ejemplos, ya no puede acceder al valor que se eliminó de la lista después


de usar la instrucción del .

Eliminación de un elemento mediante el método pop()

A veces querrá usar el valor de un elemento después de eliminarlo de una lista. Por
ejemplo, es posible que desee obtener la posición x e y de un alienígena que acaba de
ser derribado, para poder dibujar una explosión en esa posición. En una aplicación web,
es posible que desee eliminar un usuario de una lista de miembros activos y luego
agregar ese usuario a una lista de miembros inactivos.
El método pop() elimina el último elemento de una lista, pero le permite trabajar
con ese elemento después de eliminarlo. El término pop proviene de pensar en una
lista como una pila de elementos y sacar un elemento de la parte superior de la pila.
En esta analogía, la parte superior de una pila corresponde al final de una lista.

Introducción a las listas 39

MachineTranslatedbyGoogle

Saquemos una motocicleta de la lista de motocicletas:

u motos = ['honda', 'yamaha', 'suzuki']


imprimir (motos)

v motocicleta_reventada = motocicletas.pop() w
print(motocicletas)

x imprimir (motocicleta reventada


reventada))

Comenzamos definiendo e imprimiendo la lista de motocicletas en u. En v hacemos estallar


un valor de la lista y almacenar ese valor en la variable popped_motorcycle.
popped_motorcycle.
Imprimimos la lista en w para mostrar que se ha eliminado un valor de la lista.
Luego imprimimos el valor extraído en x para demostrar que todavía tenemos acceso al valor
que se eliminó.
El resultado muestra que el valor 'suzuki' se eliminó del final de
la lista y ahora está asignado a la variable popped_motorcycle:

['honda','yamaha','suzuki']
['honda','yamaha']
suzuki

¿Cómo podría ser útil este método pop() ? Imagina que las motos de la lista están
almacenadas en orden cronológico según cuando las tuvimos. Si este es el caso, podemos
usar el método pop() para imprimir una declaración sobre la última motocicleta que compramos:

motos = ['honda', 'yamaha', 'suzuki']

última_propiedad = motocicletas.pop
motocicletas.pop()
()
print(f"La última motocicleta que tuve fue
f ue una {última_propiedad.título()}").

El resultado es una oración simple sobre la motocicleta más reciente que tuvimos:

La última motocicleta que tuve fue una Suzuki.

Reventar elementos desde cualquier posición en una lista

Puede usar pop() para eliminar un elemento de cualquier posición en una lista al incluir el índice
del elemento que desea eliminar entre paréntesis.

motos = ['honda', 'yamaha', 'suzuki']

u primera_propiedad = motocicletas.pop(0)
motocicletas.pop(0)
v print(f"La primera motocicleta que tuve fue una {primera_propiedad.título()}"
{primera_propiedad.título()}").
).
40 Capítulo 3

MachineTranslatedbyGoogle

Comenzamos por mostrar la primera motocicleta en la lista en u, y luego


imprimimos un mensaje sobre esa motocicleta en v. El resultado es una oración
simple que describe la primera motocicleta que tuve:

La primera motocicleta que tuve fue una Honda.

Recuerde que cada vez que usa pop(), el elemento con el que trabaja ya no
se almacena en la lista.
Si no está seguro si usar la declaración del o el método pop() , aquí hay una
manera simple de decidir: cuando desee eliminar un elemento de una lista y no
usar ese elemento de ninguna manera, use la declaración del ; si desea usar un
elemento a medida que lo elimina, use el método pop() .

Eliminación de un artículo por valor

A veces no sabrá la posición del valor que desea eliminar de una lista. Si solo
conoce el valor del elemento que desea eliminar, puede usar el método remove() .

Por ejemplo, supongamos que queremos eliminar el valor 'ducati' de la lista de

motocicletas.
motos = ['honda', 'yamaha', 'suzuki', 'ducati'] print(motos)

u motos.remove('ducati')
motos.remove('ducati')
imprimir (motos)

El código en u le dice a Python que averigüe dónde aparece 'ducati' en la


lista y elimine ese elemento:

['honda', 'yamaha', 'suzuki', 'ducati'] ['honda',


'yamaha', 'suzuki']

También puede usar el método remove() para trabajar con un valor que se
está eliminando de una lista. Eliminemos el valor 'ducati' e imprimamos un motivo
para eliminarlo de la lista:

u motos = ['honda', 'yamaha', 'suzuki', 'ducati']


imprimir (motos)

v demasiado_caro = 'ducati'
w motocicletas.r
motocicletas.remove(demasi
emove(demasiado_caro)
ado_caro)
imprimir (motos)
x print(f"\nA {demasiado_caro.title()} es demasiado caro para mí.")

Después de definir la lista en u, asignamos el valor 'ducati' a una variable


llamada demasiado_caro v. Luego usamos esta variable para decirle a Python qué
valor eliminar de la lista en w. En x se ha eliminado el valor 'ducati'

Introducción a las listas 41

MachineTranslatedbyGoogle

de la lista, pero todavía se puede acceder a través de la variable too_caro, lo que nos
permite imprimir una declaración sobre por qué eliminamos 'ducati' de la lista de
motocicletas:

['honda', 'yamaha', 'suzuki', 'ducati'] ['honda', 'yamaha',


'suzuki']

Una Ducati es demasiado cara para mí.

N ota El método remove() elimina solo la primera aparición del valor que especifique. Si existe la
posibilidad de que el valor aparezca más de una vez en la lista, deberá usar un bucle para
asegurarse de que se eliminen todas las apariciones del valor. Aprenderá a hacer esto en
el Capítulo 7.

Inténtalo tú mismo

Los siguientes ejercicios son un poco más complejos que los del Capítulo 2, pero le brindan la
oportunidad de usar listas en todas las formas descritas.

3-4. Lista de invitados: Si pudieras invitar a alguien, vivo o fallecido, a cenar, ¿a quién invitarías?
Haz una lista que incluya al menos tres personas a las que te gustaría invitar a cenar. Luego use
su lista para imprimir un mensaje para cada persona, invitándolos a cenar.

3-5. Cambiar la lista de invitados: acaba de enterarse de que uno de sus invitados no puede asistir
a la cena, por lo que debe enviar un nuevo conjunto de invitaciones. Tendrás que pensar en alguien
más a quien invitar.

•Comience con su programa del Ejercicio 3-4. Agregue una llamada print() al final de su programa
que indique el nombre del invitado que no puede asistir.

•Modifica tu lista, reemplazando el nombre del invitado que no puede asistir con el nombre de la
nueva persona que estás invitando.

•Imprima un segundo conjunto de mensajes de invitación, uno para cada persona que todavía está
en tu lista

3-6. Más invitados: Acabas de encontrar una mesa de comedor más grande, por lo que ahora hay
más espacio disponible. Piense en tres invitados más para invitar a cenar.

•Comience con su programa del Ejercicio 3-4 o del Ejercicio 3-5. Agregar una impresión ()
llame al final de su programa para informar a las personas que encontró una mesa más grande
para la cena.

•Utilice insert() para agregar un nuevo invitado al comienzo de su lista.

•Utilice insert() para agregar un nuevo invitado al medio de su lista.


•Utilice append() para agregar un nuevo invitado al final de su lista.

•Imprima un nuevo conjunto de mensajes de invitación, uno para cada persona en su lista.

42 Capítulo 3

MachineTranslatedbyGoogle

3-7. La lista de invitados se reduce: acaba de enterarse de que su nueva mesa no llegará
a tiempo para la cena y solo tiene espacio para dos invitados.

•Comience con su programa del Ejercicio 3-6. Agrega una nueva línea que imprima un
mensaje diciendo que solo puedes invitar a dos personas a cenar.

•Utilice pop() para eliminar invitados de su lista de uno en uno hasta que solo queden dos.
los nombres permanecen en su lista. Cada vez que seleccione un nombre de su lista,
imprima un mensaje para esa persona haciéndole saber que lamenta no poder invitarla
a cenar.

•Imprima un mensaje para cada una de las dos personas que todavía están en su l ista, haciéndoles
saber que todavía están i nvitados.

•Utilice del para eliminar los dos últimos nombres de su lista, de modo que tenga una lista vacía.
Imprima su lista para asegurarse de que realmente tiene una lista vacía al final de su
programa.

Organizar una lista


A menudo, sus listas se crearán en un orden impredecible, porque no siempre puede
controlar el orden en que los usuarios proporcionan sus datos. Aunque esto es inevitable
en la mayoría de las circunstancias, con frecuencia querrá presentar su información en un
orden particular. Algunas veces querrá conservar el orden original de su lista y otras veces
querrá cambiar el orden original. Python proporciona varias formas diferentes de organizar
sus listas, según la situación.

Ordenar una lista de forma permanente con el método sort()

El método sort() de Python hace que sea relativamente fácil ordenar una lista. Imagina
que tenemos una lista de autos y queremos cambiar el orden de la lista para
almacenarlos alfabéticamente. Para simplificar la tarea, supongamos que todos los
valores de la lista están en minúsculas.

autos.py coches = ['bmw','audi','toyota','subaru']


['bmw','audi','toyota','subaru']
u coches.sort()
imprimir (coches)

El método sort() , que se muestra en u, cambia el orden de la lista de forma


permanente. Los autos ahora están en orden alfabético y nunca podremos volver al
orden original:
[ audi , bmw , subaru , toyota ]

Introducción a las listas 43

MachineTranslatedbyGoogle

También puede ordenar esta lista en orden alfabético inverso pasando el


argumento reverse=True al método sort() . El siguiente ejemplo ordena la lista de
autos en orden alfabético inverso:

coches = ['bmw','audi','toyota','subaru']
autos.sort(reverse=True)
imprimir (coches)

Nuevamente, el orden de la lista cambia permanentemente:

['toyota','subaru','bmw','audi']

Ordenar una lista temporalmente con la función sorted()


Para mantener el orden original de una lista pero presentarla ordenada, puede usar la
función sorted() . La función sorted() le permite mostrar su lista en un orden particular
pero no afecta el orden real de la lista.
Probemos esta función en la lista de autos.

coches = ['bmw','audi','toyota','subaru']

u print("Esta es la lista original:")


imprimir (coches)

v print("\nEsta es la lista ordenada:")


imprimir (ordenado (coches))

w print("\nAquí está de nuevo la lista original:")


imprimir (coches)

Primero imprimimos la lista en su orden original en u y luego en orden alfabético


en v. Después de mostrar la lista en el nuevo orden, mostramos que la lista todavía

está almacenada en su orden original en w.


Aquí está la lista original:
['bmw', 'audi', 'toyota', 'subaru']

Aquí está la lista


ordenada: ['audi', 'bmw', 'subaru', 'toyota']

x Aquí está la lista original de nuevo:


['bmw','audi','toyota','subaru']

Observe que la lista aún existe en su orden original en x después de sorted()


se ha utilizado la función. La función sorted() también puede aceptar un reverse=True
argumento si desea mostrar una lista en orden alfabético inverso.
44 Capítulo 3

MachineTranslatedbyGoogle

N ota Ordenar una lista alfabéticamente es un poco más complicado cuando todos los valores no están en
minúsculas. Hay varias formas de interpretar las letras mayúsculas al determinar un orden de
clasificación, y especificar el orden exacto puede ser más complejo de lo que queremos tratar en este
momento. Sin embargo, la mayoría de los enfoques de clasificación se basarán directamente en lo
que aprendió en esta sección.

Imprimir una lista en orden inverso

Para invertir el orden original de una lista, puede utilizar el método reverse() .
Si originalmente almacenáramos la lista de autos en orden cronológico según cuando los
poseíamos, podríamos reorganizar fácilmente la lista en orden cronológico inverso:

coches = ['bmw','audi','toyota','suba
['bmw','audi','toyota','subaru']
ru']
imprimir (coches)

coches.reverse()
imprimir (coches)

Tenga en cuenta que reverse() no ordena alfabéticamente hacia atrás; simplemente


invierte el orden de la lista:

['bmw','audi','toyota','subaru']
['subaru','toyota','audi','bmw']

El método reverse() cambia el orden de una lista de forma permanente, pero puede
volver al orden original en cualquier momento aplicando reverse() a la misma lista por
segunda vez.

Encontrar la longitud de una lista

Puede encontrar rápidamente la longitud de una lista usando la función len() . La lista de este
ejemplo tiene cuatro elementos, por lo que su longitud es 4:

>>> coches = ['bmw','audi','toyota','su


['bmw','audi','toyota','subaru']
baru']
>>> len(coches)
4

Encontrará len() útil cuando necesite identificar la cantidad de extraterrestres


que aún deben ser derribados en un juego, determinar la cantidad de datos que debe
administrar en una visualización o averiguar la cantidad de usuarios registrados en un
sitio web, entre otras tareas.

N ota Python cuenta los elementos de una lista que comienzan con uno, por lo que no debería encontrarse con
ningún error de uno en uno al determinar la longitud de una lista.

Introducción a las listas 45

MachineTranslatedbyGoogle

Inténtalo tú mismo

3-8. Ver el mundo: piensa en al menos cinco lugares del mundo que te gustaría visitar.
visitar.

•Almacenar las ubicaciones en una lista. Asegúrese de que la lista no esté en orden alfabético.

•Imprima su lista en su orden original. No se preocupe por imprimir la lista ordenadamente, simplemente

imprímala como una lista de Python sin formato.

•Use sorted() para imprimir su lista en orden alfabético sin modificar el


lista real.

•Muestre que su lista todavía está en su orden original imprimiéndola.

•Use sorted() para imprimir su lista en orden alfabético inverso sin cambiar el orden de la lista
original.

•Muestre que su lista todavía está en su orden original imprimiéndola de nuevo.

•Utilice reverse() para cambiar el orden de su lista. Imprima la lista para mostrar que su orden
ha cambiado.

•Use reverse() para cambiar el orden de su lista nuevamente. Imprima la lista para mostrar
que ha vuelto a su orden original.

•Use sort() para cambiar su lista para que se almacene en orden alfabético. Imprima la lista
para mostrar que su orden ha sido cambiado.

•Use sort() para cambiar su lista para que se almacene en orden alfabético inverso.
Imprima la lista para mostrar que su orden ha cambiado.

3-9. Invitados a cenar: Trabajando con uno de los programas de los Ejercicios 3-4 a 3-7
(página 42), use len() para imprimir un mensaje que indique el número de personas que
está invitando a cenar.

3-10. Cada función: piensa en algo que podrías almacenar en una lista. Por ejemplo, podría
hacer una lista de montañas, ríos, países, ciudades, idiomas o cualquier otra cosa que desee.
Escriba un programa que cree una lista que contenga estos elementos y luego use cada
función presentada en este capítulo al menos una vez.

Evitar errores de índice al trabajar con listas


Es común ver un tipo de error cuando se trabaja con listas por primera
vez. Supongamos que tiene una lista con tres elementos y solicita el
cuarto elemento:

motos.py motos = ['honda',


[ 'honda', 'yamaha'
'yamaha',, 'suzuki'] print(motos
print(motos[3])
[3])
46 Capítulo 3

MachineTranslatedbyGoogle

Este ejemplo da como resultado un error de índice:

Rastreo (llamadas recientes más última):


Archivo "motocicletas.py", línea 2, en <módulo>
imprimir(motos[3])
IndexError: índice de lista fuera de rango

Python intenta proporcionarle el elemento en el índice


ín dice 3. Pero cuando busca en la lista,
ningún elemento en motocicletas tiene un índice de 3. Debido a la naturaleza de la indexación en
las listas, este error es típico. La gente piensa que el tercer elemento es el elemento número 3,
porque comienzan a contar en 1. Pero en Python, el tercer elemento es el número 2, porque comienza
a indexarse en 0.
Un error de índice significa que Python no puede encontrar un elemento en el índice que
solicitó. Si ocurre un error de índice en su programa, intente ajustar el índice que está solicitando en
uno. Luego ejecute el programa nuevamente para ver si los resultados
son correctos

Tenga en cuenta que siempre que quiera acceder al último elemento de una lista, use el
índice -1. Esto siempre funcionará, incluso si su lista ha cambiado de tamaño desde la última vez
que accedió a ella:

motos = ['honda', 'yamaha', 'suzuki']


imprimir(motos[-1])

El índice -1 siempre devuelve el último elemento de una lista, en este caso el valor
'suzuki':

'suzuki'

La única vez que este enfoque


en foque causará un error es cuando solicita el último elemento de una
lista vacía:

motos = []

print(motos[-1])

No hay elementos en las motocicletas, por lo que Python devuelve otro error de índice:

Rastreo (última llamada más reciente):


Archivo "motorcyles.py", línea 3, en <módulo>
imprimir(motos[-1])
IndexError: índice de lista fuera de rango

N ota Si se produce un error de índice y no sabe cómo resolverlo, intente imprimir su lista o simplemente imprima
la longitud de su lista. Su lista puede verse muy diferente de lo que pensaba, especialmente si su
programa la ha administrado dinámicamente.
Ver la lista real, o la cantidad exacta de elementos en su lista, puede ayudarlo a resolver tales errores
lógicos.

Introducción a las listas 47

MachineTranslatedbyGoogle

Inténtalo tú mismo

3-11. Error intencional:si aún no ha recibido un error de índice en uno de


sus programas, intente que suceda. Cambie un índice en uno de sus
programas para producir un error de índice. Asegúrese de corregir el error

antes de cerrar el programa.

Resumen
En este capítulo aprendió qué son las listas y cómo trabajar con los elementos
individuales de una lista. Aprendió cómo definir una lista y cómo agregar y eliminar
elementos. Aprendió a ordenar listas de forma permanente y temporal con fines de
visualización.. También aprendió cómo encontrar la longitud de una lista y cómo evitar
visualización
errores de índice cuando trabaja con listas.
En el Capítulo 4, aprenderá cómo trabajar con elementos en una lista de
manera más eficiente. Al recorrer cada elemento de una lista con solo unas pocas
líneas de código, podrá trabajar de manera eficiente, incluso cuando su lista contenga
miles o millones de elementos.
48 Capítulo 3

MachineTranslatedbyGoogle

4
Trabajar con listas

En el Capítulo 3 aprendió cómo hacer una lista simple y

aprendió a trabajar con los elementos individuales en una lista.

en este capitulo

Más adelante aprenderá a recorrer una lista completa utilizando solo

unas pocas líneas de código, independientemente


independientemente de la longitud de la lista. El
bucle le permite realizar la misma acción, o conjunto de acciones, con cada
elemento de una lista. Como resultado, podrá trabajar de manera eficiente con
listas de cualquier longitud, incluidas aquellas con miles o incluso millones de elementos.

Bucle a través de una lista completa


A menudo querrá recorrer todas las entradas de una lista, realizando la misma
tarea con cada elemento. Por ejemplo, en un juego, es posible que desee mover
todos los elementos de la pantalla en la misma cantidad, o en una lista de
números, es posible que desee realizar la misma operación estadística en cada
elemento. O tal vez desee mostrar cada título de una lista de artículos en un sitio
web. Cuando desee realizar la misma acción con todos los elementos de una lista,
puede utilizar el bucle for de Python.

MachineTranslatedbyGoogle

Digamos que tenemos una lista de nombres de magos y queremos imprimir


cada nombre en la lista. Podríamos hacer esto recuperando cada nombre de la lista
individualmente, pero este enfoque podría causar varios problemas. Por un lado,
sería repetitivo hacer esto con una larga lista de nombres. Además, tendríamos que
cambiar nuestro código cada vez que cambiara la longitud de la lista. Un bucle for
evita ambos problemas al permitir que Python los administre internamente.
Usemos un ciclo for para imprimir cada nombre en una lista de magos:

magos.py u magos = ['alice', 'david', 'carolina'] v for mago in


magos: w print(mago)

Comenzamos definiendo una lista en u, tal como lo hicimos en el Capítulo 3.


En v, definimos un bucle for . Esta línea le dice a Python que extraiga un nombre
de la lista de magos y lo asocie con la variable mago. En w le decimos a Python que
imprima el nombre que acaba de ser asignado al mago. Python luego repite las líneas
v y w, una vez para cada nombre en la lista. Puede ser útil leer este código como
"Para cada mago en la lista de magos, escriba el nombre del mago". El resultado es
una copia impresa simple de cada nombre en la lista:

alicia
david
carolina

Una mirada más cercana al bucle

El concepto de bucle es importante porque es una de las formas más comunes en


que una computadora automatiza tareas repetitivas. Por ejemplo, en un ciclo simple
como el que usamos en magicians.py, Python inicialmente lee la primera línea del ciclo:

para mago en magos:

Esta línea le dice a Python que recupere el primer valor de la lista de magos
y asociarlo con la variable mago. Este primer valor es 'alicia'. Python luego lee la
siguiente línea:

imprimir (mago)

Python imprime el valor actual de magician, que sigue siendo 'alicia'. Porque
la lista contiene más valores, Python vuelve a la primera línea del bucle:

para mago en magos:

Python recupera el siguiente nombre en la lista, 'david', y lo asocia


valor con la variable mago. Python luego ejecuta la línea:

imprimir (mago)

50 Capítulo 4

MachineTranslatedbyGoogle

Python vuelve a imprimir el valor actual de magician , que ahora es 'david'.


Python repite todo el bucle una vez más con el último valor de la lista, 'carolina'.
Como no hay más valores en la lista, Python pasa a la siguiente línea del programa.
En este caso, nada viene después del bucle for , por lo que el programa simplemente
finaliza.
Cuando utilice bucles por primera vez, tenga en cuenta que el conjunto de pasos se
repite una vez para cada elemento de la lista, sin importar cuántos elementos haya en la
lista. Si tiene un millón de elementos en su lista, Python repite estos pasos un millón de
veces y, por lo general, muy rápido.
También tenga en cuenta al escribir sus propios bucles for que puede elegir
cualquier nombre que desee para la variable temporal que se asociará con cada valor
en la lista. Sin embargo, es útil elegir un nombre significativo que represente un solo
elemento de la lista. Por ejemplo, esta es una buena forma de iniciar un ciclo for para
obtener una lista de gatos, una lista de perros y una lista general de elementos:

para gato en gatos:


para perro en perros:
para el artículo en list_of_items:

Estas convenciones de nomenclatura pueden ayudarlo a seguir la acción que se


realiza en cada elemento dentro de un bucle for . El uso de nombres singulares y
plurales puede ayudarlo a identificar si una sección de código funciona con un solo
elemento de la lista o con la lista completa.

Hacer más trabajo dentro de un bucle for

Puede hacer casi cualquier cosa con cada elemento en un bucle for . Construyamos
sobre el ejemplo anterior imprimiendo un mensaje a cada mago, diciéndoles que
realizaron un gran truco:

magos.py magos = ['alicia', 'david', 'carolina'] para mago en


magos: u print(f"{mago.título()}, ¡fue un gran truco!")

La única diferencia en este código está en u donde redactamos un mensaje para


cada mago, comenzando con el nombre de ese mago. La primera vez que pasa por el
bucle, el valor de magician es 'alice', por lo que Python inicia el primer mensaje con el
nombre 'Alice'. La segunda vez a través del mensaje comenzará con 'David', y la tercera
vez a través del mensaje comenzará con 'Carolina'.
La salida muestra un mensaje personalizado para cada mago en la lista:

¡Alice, ese fue un gran truco!


¡David, ese fue un gran truco!
Carolina, ese fue un gran truco!
También puede escribir tantas líneas de código como desee en el bucle for .
Cada línea con sangría que sigue a la línea para mago en magos se considera
dentro del bucle, y cada línea con sangría se ejecuta una vez para cada uno .

Trabajar con listas 51

MachineTranslatedbyGoogle

valor en la lista. Por lo tanto, puede hacer todo el trabajo que desee con cada valor de la
lista.
Agreguemos una segunda línea a nuestro mensaje, diciéndole a cada mago que estamos
esperando su próximo truco:

magos = ['alicia', 'david', 'carolina'] por mago


en magos:
print(f"{mago.título(
print(f"{mago.título()},
)}, ¡fue un gran truco!") u print(f"No
puedo esperar a ver tu próximo truco, {mago.título()}.\n")
{mago.título()}.\n")

Debido a que hemos aplicado sangría a ambas llamadas a print(), cada línea se ejecutará
una vez por cada mago de la lista. La nueva línea ("\n") en la segunda impresión()
call u inserta una línea en blanco después de cada pasada por el bucle. Esto crea un conjunto
de mensajes que están perfectamente agrupados para cada persona en la lista:

¡Alice, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, Alice.

¡David, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, David.

Carolina, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, Carolina.

Puede usar tantas líneas como desee en sus bucles for . En la práctica, a menudo le
resultará útil realizar varias operaciones diferentes con cada elemento de una lista cuando utilice
un bucle for .

Hacer algo después de un bucle for


¿Qué sucede una vez que un ciclo for ha terminado de ejecutarse? Por lo general, querrá
resumir un bloque de salida o pasar a otro trabajo que su programa debe realizar.

Cualquier línea de código después del bucle for que no esté sangrada se ejecuta una vez
sin repetición. Escribamos un agradecimiento al grupo de magos en su conjunto,
agradeciéndoles por ofrecer un excelente espectáculo. Para mostrar este mensaje de grupo
después de que se hayan impreso todos los mensajes individuales, colocamos el mensaje de
agradecimiento después del bucle for sin sangría:

magos = ['alicia', 'david', 'carolina'] por mago


en magos:
print(f"{mago.title()},
print(f"{mago.title()}, ¡fue un gran truco!")
print(f"No puedo esperar a ver tu próximo truco, {mago.título()}.\n")
{mago.título()}.\n")

u print("Gracias a todos. ¡Fue un gran espectáculo de magia!")


52 Capítulo 4

MachineTranslatedbyGoogle

Las dos primeras llamadas a print() se repiten una vez para cada mago en el
lista, como viste antes. Sin embargo, debido a que la línea en u no tiene sangría, se
imprime solo una vez:

¡Alice, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, Alice.

¡David, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, David.

Carolina, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, Carolina.

Gracias a todos. ¡Ese fue un gran espectáculo de magia!

Cuando esté procesando datos usando un bucle for , encontrará que esta es una
buena manera de resumir una operación que se realizó en un conjunto de datos completo.
Por ejemplo, puede usar un bucle for para inicializar un juego ejecutando una lista de
caracteres y mostrando cada carácter en la pantalla.
Luego, puede escribir código adicional después de este ciclo que muestra un botón
Reproducir ahora después de que todos los caracteres se hayan dibujado en la pantalla.

Evitar errores de sangría


Python utiliza la sangría para determinar cómo se relaciona una línea o un grupo de líneas
con el resto del programa. En los ejemplos anteriores, las líneas que imprimían mensajes
a magos individuales formaban parte del ciclo for porque estaban sangradas. El uso de
sangría de Python hace que el código sea muy fácil de leer.
Básicamente, utiliza espacios en blanco para forzarte a escribir código con un formato
limpio y una estructura visual clara. En los programas de Python más largos, notará
bloques de código sangrados en algunos niveles diferentes. Estos niveles de sangría lo
ayudan a obtener una idea general de la organización general del programa.
A medida que comience a escribir código que se base en una sangría adecuada,
deberá estar atento a algunos errores de sangría comunes. Por ejemplo, las personas
a veces sangran líneas de código que no necesitan sangría u olvidan sangrar líneas
que necesitan sangría. Ver ejemplos de estos errores ahora lo ayudará a evitarlos en
el futuro y corregirlos cuando aparezcan en sus propios programas.

Examinemos algunos de los errores de sangría más comunes.

Olvidarse de sangrar
Siempre aplique sangría a la línea después de la
l a instrucción for en un bucle. Si lo olvida,
Python le recordará:
magos.py magos = ['alicia', 'david', 'carolina'] for mago en
magos: u print(mago)

Trabajar con listas 53

MachineTranslatedbyGoogle

La llamada a print() u debería estar sangrada, pero no lo está. Cuando Python


espera un bloque sangrado y no lo encuentra, le permite saber con qué línea tuvo un
problema.

Archivo "magos.py", línea 3


print(mago)
^

Error Tabulación: Se esperaba un bloque tabulado

Por lo general, puede resolver este tipo de error de sangría sangrando el


línea o líneas inmediatamente después de la instrucción for .

Olvidarse de sangrar líneas adicionales


A veces, su bucle se ejecutará sin errores, pero no producirá el resultado esperado. Esto
puede suceder cuando intenta realizar varias tareas en un bucle y olvida sangrar algunas
de sus líneas.
Por ejemplo, esto es lo que sucede cuando nos olvidamos de sangrar la segunda línea
en el ciclo que le dice a cada mago que estamos esperando su próximo truco:

magos = ['alicia', 'david', 'carolina']


para mago en magos:
print(f"{mago.title()},
print(f"{mago.title()}, ¡fue un gran truco!")
u print(f"No puedo esperar a ver tu próximo truco, {mago.título()}.\n")
{mago.título()}.\n")

Se supone que la llamada a print() u está sangrada, pero como Python encuentra al
menos una línea sangrada después de la instrucción for , no informa de un error. Como
resultado, la primera llamada print() se ejecuta una vez para cada nombre de la lista porque
está sangrado. La segunda llamada de print() no tiene sangría, por lo que se ejecuta solo una
vez después de que el ciclo haya terminado de ejecutarse. Debido a que el valor final asociado
con el mago es 'carolina', ella es la única que recibe el mensaje "esperando con ansias el
próximo truco":

¡Alice, ese fue un gran truco!


¡David, ese fue un gran truco!
Carolina, ese fue un gran truco!
No puedo esperar a ver tu próximo truco, Carolina.

Este es un error lógico. La sintaxis es código Python válido, pero el código no produce el
resultado deseado porque ocurre un problema en su lógica. Si espera ver una determinada
acción repetida una vez para cada elemento de una lista y se ejecuta solo una vez, determine
si necesita sangrar simplemente una línea o un grupo de líneas.
54 Capítulo 4

MachineTranslatedbyGoogle

sangría innecesariamente

Si sangra accidentalmente una línea que no necesita sangría, Python le informa sobre la
sangría inesperada:

hello_world.py mensaje = "¡Hola, mundo de Python!"


imprimes (mensaje)

No necesitamos sangrar la llamada print() u, porque no es parte de un ciclo;


c iclo; por lo
tanto, Python informa ese error:

Archivo "hello_world.py", línea 2


imprimir (mensaje)
^

IndentationError: sangría inesperada

Puede evitar errores de sangría inesperados sangrando solo cuando tenga una razón
específica para hacerlo. En los programas que está escribiendo en este momento, las únicas
líneas que debe sangrar son las acciones que desea repetir para cada elemento en un bucle
for .

Sangría innecesariamente después del bucle

Si sangra accidentalmente el código que debería ejecutarse después de que finalice un bucle,
ese código se repetirá una vez para cada elemento de la lista. A veces, esto hace que Python
informe de un error, pero a menudo resultará en un error lógico.
Por ejemplo, veamos qué sucede cuando accidentalmente sangramos la línea que
agradeció a los magos como grupo por ofrecer un buen espectáculo:

magos.py magos = ['alicia', 'david', 'carolina'] por mago en


magos:
print(f"{mago.title()}, ¡fue un gran truco!")
print(f"No puedo esperar a ver tu próximo truco, {mago.título()}.
{mago.título()}.\n")
\n")

u print("¡Gracias a todos, fue un gran espectáculo de magia!")

Debido a que la línea en u está sangrada, se imprime una vez para cada persona en la
lista, como se muestra aquí:

¡Alice, ese fue un gran truco!


No puedo esperar a ver tu próximo truco, Alice.

¡Gracias a todos, fue un gran espectáculo de magia!


¡David, ese fue un gran truco!
No puedo esperar a ver tu próximo truco, David.

¡Gracias a todos, fue un gran espectáculo de magia!


Carolina, ese fue un gran truco!
No puedo esperar a ver tu próximo truco, Carolina.

¡Gracias a todos, fue un gran espectáculo de magia!

Trabajar con listas 55

MachineTranslatedbyGoogle

Este es otro error lógico, similar al de “Olvidarse de sangrar


Líneas adicionales” en la página 54. Debido a que Python no sabe lo que está tratando de
lograr con su código, ejecutará todo el código que esté escrito en una sintaxis válida. Si una
acción se repite muchas veces cuando debería ejecutarse solo una vez, probablemente necesite
eliminar la sangría del código para esa acción.

Olvidando el Colón
Los dos puntos al final de una instrucción for le dicen a Python que interprete la siguiente
línea como el comienzo de un ciclo.

magos = ['alicia', 'david', 'carolina'] u de mago en


magos
imprimir (mago)

Si olvida accidentalmente los dos puntos, como se muestra en u, obtendrá un error de


sintaxis porque Python no sabe lo que está tratando de hacer. Aunque este es un error fácil
de solucionar, no siempre es un error fácil de encontrar. Te sorprendería la cantidad de
tiempo que dedican los programadores a buscar errores de un solo carácter como este. Dichos
errores son difíciles de encontrar porque a menudo solo vemos lo que esperamos ver.

Inténtalo tú mismo

4-1. Pizzas: Piensa en al menos tres tipos de tu pizza favorita. Almacene estos
nombres de pizza en una lista y luego use un ciclo for para imprimir el nombre de cada pizza.

•Modifica tu ciclo for para imprimir una oración usando el nombre de la pizza
en lugar de imprimir solo el nombre de la pizza. Para cada pizza, debe tener una
línea de salida que contenga una declaración simple como Me gusta la pizza de
pepperoni.

•Agregue una línea al final de su programa, fuera del bucle for , que indique
cuánto te gusta la pizza. El resultado debe constar de tres o más líneas sobre los
tipos de pizza que te gustan y luego una oración adicional, como ¡Me encanta la
pizza!

4-2. Animales: Piensa en al menos tres animales diferentes que tengan una característica
común. Guarde los nombres de estos animales en una lista y luego use un ciclo for para
imprimir el nombre de cada animal.

•Modifique su programa para imprimir una declaración sobre cada animal, como Un
perro sería una gran mascota.

•Agregue una línea al final de su programa indicando lo que estos animales tienen en
común. Podría escribir una oración como ¡Cualquiera de estos animales sería una
gran mascota!

56 Capítulo 4

MachineTranslatedbyGoogle

Hacer listas numéricas


Existen muchas razones para almacenar un conjunto de números. Por ejemplo, deberá realizar
un seguimiento de las posiciones de cada personaje en un juego, y es posible que también desee
realizar un seguimiento de las puntuaciones más altas de un jugador. En las visualizaciones de datos,
casi siempre trabajará con conjuntos de números, como temperaturas, distancias, tamaños de
población o valores de latitud y longitud, entre otros tipos de conjuntos numéricos.

Las listas son ideales para almacenar conjuntos de números, y Python proporciona una
variedad de herramientas para ayudarlo a trabajar de manera eficiente con listas de números. Una
vez que comprenda cómo usar estas herramientas de manera efectiva, su código funcionará bien
incluso cuando sus listas contengan millones de elementos.

Uso de la función range()


La función range() de Python facilita la generación de una serie de números.
Por ejemplo, puede usar la función range() para imprimir una serie de números como este:

primero
para valor en rango (1, 5):
_numeros.py imprimir (valor)

Aunque parece que este código debería imprimir los números del 1 al 5, no imprime el número 5:

1
2
3
4

En este ejemplo, range() imprime solo los números del 1 al 4. Este es otro resultado del
comportamiento de desactivación por uno que verá a menudo en los lenguajes de programación.
La función range() hace que Python comience a contar en el primer valor que le proporcione y se
detenga cuando alcance el segundo valor que proporcione.
Debido a que se detiene en ese segundo valor, la salida nunca contiene el valor final, que
habría sido 5 en este caso.

Para imprimir los números del 1 al 5, usaría el rango (1, 6):

para el valor en el rango (1, 6):


imprimir (valor)

Esta vez, la salida comienza en 1 y termina en 5:

1
2
3
4
5

Trabajar con listas 57

MachineTranslatedbyGoogle

Si su resultado es diferente de lo que espera cuando usa range(), intente ajustar


su valor final en 1.
También puede pasar range() solo un argumento, y comenzará la secuencia
de números en 0. Por ejemplo, range(6) devolvería los números del 0 al 5.

Usando range() para hacer una lista de números


Si desea hacer una lista
l ista de números, puede convertir los resultados de range()
directamente en una lista usando la función list() . Cuando envuelve list() alrededor de una
llamada a la función range() , la salida será una lista de números.
En el ejemplo de la sección anterior, simplemente imprimimos una serie de
números. Podemos usar list() para convertir ese mismo conjunto de números en una lista:

numeros = lista(rango(1, 6))


imprimir (números)

Y este es el resultado:

[1, 2, 3, 4, 5]

También podemos usar la función range() para decirle a Python que omita números
en un rango determinado. Si pasa un tercer argumento a range(), Python usa ese valor
como un tamaño de paso al generar números.
Por ejemplo, así es como enumerar los números pares entre 1 y 10:

numeros_pares.py numeros_pares = lista(rango(2, 11, 2))


print(numeros_pares)

En este ejemplo, la función range() comienza con el valor 2 y luego suma 2 a ese
valor. Suma 2 repetidamente hasta que alcanza o pasa el valor final, 11, y produce este
resultado:

[2, 4, 6, 8, 10]

Puedes crear casi cualquier conjunto de números que quieras usando el rango ()
función. Por ejemplo, considere cómo podría hacer una lista de los primeros 10
números cuadrados (es decir, el cuadrado de cada número entero del 1 al 10). En Python,
dos asteriscos (**) representan exponentes. Así es como podrías poner los primeros 10
números cuadrados en una lista:

cuadrados.py u cuadrados = []
v para valor en rango (1, 11):
w cuadrado = valor ** 2
x cuadrados.append(cuadrado)
y imprimir (cuadrados)

Empezamos con una lista vacía llamada cuadrados u. En v, le decimos a Python que
recorra cada valor del 1 al 10 usando la función range() . Dentro del bucle,

58 Capítulo 4

MachineTranslatedbyGoogle

el valor actual se eleva a la segunda potencia y se asigna al cuadrado de la variable w.


En x, cada nuevo valor de cuadrado se agrega a la lista de cuadrados.
Finalmente, cuando el ciclo ha terminado de ejecutarse, se imprime la lista de cuadrados y:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Para escribir este código de manera más concisa, omita la variable temporal cuadrado
y agregue cada nuevo valor directamente a la lista:

cuadrados = []
para el valor en el rango (1,11):
u cuadrados.app
cuadrados.append(valor**2)
end(valor**2)

imprimir (cuadrados)

El código en u hace el mismo trabajo que las líneas en w y x en squares.py.


Cada valor en el bucle se eleva a la segunda potencia y luego se agrega inmediatamente a
la lista de cuadrados.
Puede usar cualquiera de estos dos enfoques cuando esté haciendo listas más
complejas. A veces, usar una variable temporal hace que su código sea más fácil de leer;
otras veces hace que el código sea innecesariamente largo. Concéntrese primero en escribir
código que entienda claramente, que haga lo que usted quiere que haga.
Luego busque enfoques más eficientes mientras revisa su código.

Estadísticas simples con una lista de números

Algunas funciones de Python son útiles cuando se trabaja con listas de números. Por ejemplo,
puede encontrar fácilmente el mínimo, el máximo y la suma de una lista de números:

>>> dígitos = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]


>>> min(digitos)
0
>>> max(digitos)
9
>>> suma(digitos)
45

N ota Los ejemplos en esta sección usan listas cortas de números para encajar fácilmente en el
página. Funcionarían igual de bien si su lista contuviera un millón o más de números.

Lista de comprensiones

El enfoque descrito anteriormente para generar los cuadrados de la lista consistía en utilizar
tres o cuatro líneas de código. Una lista de comprensión le permite generar esta misma lista
en una sola línea de código. Una lista por comprensión combina el bucle for y la creación de
nuevos elementos en una sola línea, y agrega automáticamente cada elemento nuevo. Las
listas de comprensión no siempre se presentan a los principiantes, pero las he incluido aquí
porque lo más probable es que las vea tan pronto como empiece a mirar el código de otras
personas.

Trabajar con listas 59

MachineTranslatedbyGoogle

El siguiente ejemplo construye la misma lista de números cuadrados que viste


antes pero usa una lista de comprensión:

cuadrados.py cuadrados = [valor**2 para valor en rango (1, 11)]


imprimir (cuadrados)

Para usar esta sintaxis, comience con un nombre descriptivo para la lista, como
cuadrados. A continuación, abra un conjunto de corchetes y defina la expresión de los
valores que desea almacenar en la nueva lista. En este ejemplo, la expresión es valor**2,
lo que eleva el valor a la segunda potencia. Luego, escriba un ciclo for para generar los
números que desea introducir en la expresión y cierre los corchetes. El bucle for en este
ejemplo es for value in range(1, 11), que introduce los valores del 1 al 10 en la expresión
value**2. Tenga en cuenta que no se utilizan dos puntos al final de la instrucción for .

El resultado es la misma lista de números cuadrados que viste antes:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Se necesita práctica para escribir sus propias listas de comprensión, pero encontrará
vale la pena una vez que te sientas cómodo creando listas ordinarias.
Cuando esté escribiendo tres o cuatro líneas de código para generar listas y comience
a sentirse repetitivo, considere escribir sus propias comprensiones de listas.

Inténtalo tú mismo

4-3. Contar hasta veinte: use un bucle for para imprimir los números del 1 al 20, inclusive.

4-4. Un millón: haga una lista de los números del uno al millón y luego use un ciclo for para imprimir

los números. (Si la salida tarda demasiado, deténgala presionando ctrl-C o cerrando la ventana de
salida).

4-5. Suma de un millón: haga una lista de los números del uno al millón y luego use min() y max()
para asegurarse de que su lista realmente comience en uno y termine en un millón. Además, use la
función sum() para ver qué tan rápido Python puede agregar un millón de números.

4-6. Números impares: use el tercer argumento de la función range() para hacer una lista de los
números impares del 1 al 20. Use un bucle for para imprimir cada número.

4-7. Threes: Haga una lista de los múltiplos de 3 de 3 a 30. Use un ciclo for para imprimir los
números en su lista.

4-8. Cubos: Un número elevado a la tercera potencia se llama cubo. Por ejemplo, el cubo de 2 se
escribe como 2**3 en Python. Haga una lista de los primeros 10 cubos (es decir, el cubo de cada
número entero del 1 al 10) y use un ciclo for para imprimir el valor de cada cubo.
4-9. Comprensión de cubos: use una lista de comprensión para generar una lista de los primeros
10 cubos.

60 Capítulo 4

MachineTranslatedbyGoogle

Trabajar con parte de una lista


En el Capítulo 3 aprendió cómo acceder a elementos individua
individuales
les en una lista, y en este capítulo
ha estado aprendiendo cómo trabajar con todos los elementos en una lista.
También puede trabajar con un grupo específico de elementos en una lista, que Python llama
segmento.

Cortar una lista


Para hacer un corte, especifica el índice del primer y último elemento con el que desea
trabajar. Al igual que con la función range() , Python detiene un elemento antes del segundo
índice que especifique. Para generar los tres primeros elementos de una lista, solicitaría los
l os
índices 0 a 3, que devolverían los elementos 0, 1 y 2.

El siguiente ejemplo involucra una lista de jugadores en un equipo:

jugadores.py jugadores = ['charles', 'martina',


'martina', 'michael', 'florencia',
'florencia', 'eli']
u print(jugadores[0:3])

El código en u imprime una parte de esta lista, que incluye solo los tres primeros
jugadores. La
La salida conse
conserva
rva la estructu
estructura
ra de la lista e incluy
incluye
e los tres primero
primeros
s jugadores de
la lista:

['charles', 'martina', 'miguel']

Puede generar cualquier subconjunto


subconjunto de una lista. Por ejemplo, si quiere los elementos
segundo, tercero y cuarto de una lista, comenzaría el segmento en el índice 1 y terminaría en el
índice 4:

jugadores = ['charles', ''martina',


martina', 'michael', 'florencia',
'florencia', 'eli']
imprimir (jugadores [1: 4])

Esta vez el segmento comienza con 'martina' y termina con 'florence':

['martina', 'miguel', 'florencia']

Si omite el primer índice en un segmento, Python inicia automáticamente su


rebanada al principio de la lista:

jugadores = ['charles', 'martina',


'martina', 'michael', 'florencia',
'florencia', 'eli']
imprimir (jugadores [: 4])

Sin un índice inicial, Python comienza al principio de la lista:

['charles', 'martina', 'miguel', 'florencia']


Trabajar con listas 61

MachineTranslatedbyGoogle

Una sintaxis similar funciona si desea un segmento que incluya el final de una lista.
Por ejemplo, si desea todos los elementos desde el tercer elemento hasta el último elemento,
puede comenzar con el índice 2 y omitir el segundo índice:

jugadores = ['['charles',
charles', 'martina',
'martina', 'michael', 'florencia', 'eli']
'eli']
imprimir (jugadores [2:])

Python devuelve todos los elementos desde el tercer elemento hasta el final de la lista:

['miguel', 'florencia', 'eli']

Esta sintaxis le permite generar todos los elementos desde cualquier punto de su lista
hasta el final, independientemente de la longitud de la lista. Recuerde que un índice
negativo devuelve un elemento a cierta distancia del final de una lista; por lo tanto, puede
generar cualquier segmento desde el final de una lista. Por ejemplo, si queremos dar salida
a los últimos tres jugadores de la lista, podemos usar el segmento players[-3:]:

jugadores = ['['charles',
charles', 'martina',
'martina', 'michael', 'florencia', 'eli']
'eli']

imprimir (jugadores [-3:])

Esto imprime los nombres de los últimos tres jugadores y continuaría funcionando a
medida que la lista de jugadores cambia de tamaño.

N ota Puede incluir un tercer valor entre paréntesis que indique un sector. Si se incluye un tercer
valor, esto le dice a Python cuántos elementos omitir entre elementos en el rango
especificado.

Bucle a través de una rebanada

Puede usar un segmento en un bucle for si desea recorrer un subconjunto de los


elementos de una lista. En el siguiente ejemplo, recorremos los primeros tres jugadores e
imprimimos sus nombres como parte de una lista simple:

jugadores = ['charles',
['charles', 'martina',
'martina', 'michael', 'florencia', 'eli']
'eli']

print("Estos son los tres primeros jugadores de mi equipo:")


u para jugador en jugadores[:3]:
imprimir (jugador.título())
(jugador.título())

En lugar de recorrer la lista completa de jugadores en u, Python realiza un bucle


solo a través de los tres primeros nombres:

Aquí están los tres primeros jugadores de mi equipo:


Charles
martina
Miguel

Las rebanadas son muy útiles en varias situaciones. Por ejemplo, cuando estás
Al crear un juego, puede agregar la puntuación final de un jugador a una lista cada vez que

62 Capítulo 4

MachineTranslatedbyGoogle

el jugador termina de jugar. A continuación, puede obtener las tres puntuaciones más altas de un
jugador ordenando la lista en orden decreciente y tomando una porción que incluya solo las tres
primeras puntuaciones. Cuando trabaja con datos, puede usar segmentos para procesar sus datos
en fragmentos de un tamaño específico. O bien, cuando está creando una aplicación web, puede
usar segmentos para mostrar información en una serie de páginas con una cantidad adecuada de
información en cada página.

Copiar una lista


A menudo, deseará comenzar con una lista existente y crear una lista completamente nueva basada
en la primera. Exploremos cómo funciona copiar una lista y examinemos una situación en la que
copiar una lista es útil.
Para copiar una lista, puede crear un segmento que incluya la lista original completa omitiendo
el primer índice y el segundo índice ([:]). Esto le dice a Python que haga una porción que comience
en el primer elemento y termine en el último, produciendo una copia de la lista completa.

Por ejemplo, imagina que tenemos una lista de nuestras comidas favoritas y queremos hacer
una lista separada de las comidas que le gustan a un amigo. A este amigo le gusta todo lo que hay
en nuestra lista hasta ahora, así que podemos crear su lista copiando la nuestra:

comidas.py u my_foods = ['pizza', 'falafel', 'pastel de zanahoria']


v friend_foods = my_foods[:]

print("Mis comidas favoritas son:")


imprimir (mis_alimentos)

print("\nLas comidas favoritas de mi amigo son:")


imprimir (friend_foods)

En u hacemos una lista de los alimentos que nos gustan llamada my_foods. En v
hacemos una nueva lista llamada friend_foods. Hacemos una copia de my_foods solicitando
una porción de my_foods sin especificar ningún índice y almacenamos la copia en friend_foods.
Cuando imprimimos cada lista, vemos que ambas contienen los mismos alimentos:

Mis comidas favoritas


son: ['pizza', 'falafel', 'carrot cake']

Las comidas favoritas de mi amigo


son: ['pizza', 'falafel', 'carrot cake']

Para demostrar que en realidad tenemos dos listas separadas, agregaremos un nuevo
alimento a cada lista y mostraremos que cada lista realiza un seguimiento de los alimentos favoritos
de la persona adecuada:

my_foods = ['pizza', 'falafel', 'carrot cake'] u friend_foods


my_foods[:]

v my_foods.append('cannoli')
w friend_foods.append('helado')

Trabajar con listas 63

MachineTranslatedbyGoogle

print("Mis comidas favoritas son:")


imprimir (mis_alimentos)

print("\nLas comidas favoritas de mi amigo son:")


imprimir (friend_foods)

En u copiamos los elementos originales en my_foods a la nueva lista friend_foods, como


hicimos en el ejemplo anterior. A continuación, agregamos un nuevo alimento a cada lista: en v
agregamos 'cannoli' a my_foods, y en w agregamos 'helado' a friend_foods. Luego imprimimos las
dos listas para ver si cada uno de estos alimentos está en la lista adecuada.

Mis comidas favoritas son:


x ['pizza', 'falafel', 'carrot cake', 'cannoli']

Las comidas favoritas de mi amiga


son: y ['pizza', 'falafel', 'carrot cake', 'helado']

El resultado en x muestra que 'cannoli' ahora aparece en nuestra lista de comidas favoritas
pero 'helado' no. En y podemos ver que 'helado' ahora aparece en la lista de nuestros amigos
pero 'cannoli' no. Si simplemente hubiéramos establecido friend_foods
igual a my_foods, no produciríamos dos listas separadas. Por ejemplo, esto es lo que sucede
cuando intenta copiar una lista sin usar una división:

my_foods = ['pizza', 'falafel', 'pastel de zanahoria']

# Esto no funciona:
u friend_foods = mis_alimentos

my_foods.append('cannoli')
friend_foods.append('helado')

print("Mis comidas favoritas son:")


imprimir (mis_alimentos)

print("\nLas comidas favoritas de mi amigo son:")


imprimir (friend_foods)

En lugar de almacenar una copia de my_foods en friend_foods en ti , configuramos friend


_alimentos igual a mis_alimentos. Esta sintaxis en realidad le dice a Python que asocie
la nueva variable friend_foods con la lista que ya está asociada con my_foods, por lo que
ahora ambas variables apuntan a la misma lista. Como resultado, cuando agregamos 'cannoli'
a my_foods, también aparecerá en friend_foods. Del mismo modo , 'helado' aparecerá en
ambas listas, aunque parece que se agrega solo a friend_foods.

El resultado muestra que ambas listas son iguales ahora, que no es lo que queríamos:
Mis comidas favoritas son:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'helado']

64 Capítulo 4

MachineTranslatedbyGoogle

Las comidas favoritas de mi amigo son: ['pizza',


'falafel', 'carrot cake', 'cannoli', 'helado']

N ota No se preocupe por los detalles de este ejemplo por ahora. Básicamente, si estás tratando de
trabaja con una copia de una lista y observa un comportamiento inesperado, asegúrese de copiar la
lista mediante un segmento, como hicimos en el primer ejemplo.

Inténtalo tú mismo

4-10. Rebanadas: usando uno de los programas que escribió en este capítulo, agregue varias líneas al
final del programa que hagan lo siguiente:

•Imprimir el mensaje Los tres primeros elementos de la lista son:. Luego use una r ebanada para

imprima los tres primeros elementos de la lista de ese programa.

•Imprima el mensaje Los tres elementos de la mitad de la lista son:. Usa una rebanada para

imprima tres elementos del medio de la lista.

•Imprimir el mensaje Los últimos tres elementos de la lista son:. Uti lice una rebanada para imprimir el
los tres últimos elementos de la lista.

4-11. Mis pizzas, tus pizzas: comienza con tu programa del ejercicio 4-1 (página 56). Haga una
copia de la lista de pizzas y ll ámela friend_pizzas.

Luego, haz lo siguiente:

•Añadir una nueva pizza a la lista ori ginal.

•Añadir una pizza diferente a la li sta friend_pizzas.

• Demuestra que tienes dos listas separadas. Imprime el mensaje Mi favorito

pizzas are:, y luego use un bucle for para imprimir la primera lista. Imprima el mensaje Las pizzas

favoritas de mi amigo son: y luego use un bucle for para imprimir la segunda lista. Asegúrese de que

cada pizza nueva se almacene en la lista adecuada.

4-12. Más bucles: todas las versiones de foods.py en esta sección han evitado el uso de bucles al
imprimir para ahorrar espacio. Elija una versión de foods.py y escriba dos bucles for para imprimir cada

lista de alimentos.

tuplas
Las listas funcionan bien para almacenar colecciones de elementos que pueden cambiar a lo largo
de la vida de un programa. La capacidad de modificar listas es particularmente importante cuando
trabaja con una lista de usuarios en un sitio web o una lista de personajes en un juego. Sin embargo, a
veces querrá crear una lista de elementos que no se pueden cambiar. Las tuplas te permiten hacer
precisamente eso. Python se refiere a valores que no pueden cambiar como inmutables, y una lista
inmutable se llama tupla.

Trabajar con listas 65

MachineTranslatedbyGoogle

Definición de una tupla

Una tupla se parece a una lista, excepto que usa paréntesis en lugar de corchetes. Una vez
que define una tupla, puede acceder a elementos individuales utilizando el índice de cada
elemento, tal como lo haría con una lista.
Por ejemplo, si tenemos un rectángulo que siempre debe tener un tamaño determinado,
podemos asegurarnos de que su tamaño no cambie poniendo las dimensiones en una tupla:

dimensiones.py u dimensiones = (200, 50)


v imprimir (dimensiones [0])
imprimir (dimensiones [1])

Definimos las dimensiones de la tupla en u, usando paréntesis en lugar de cuadrados


soportes. En v imprimimos cada elemento en la tupla individualmente, usando la misma sintaxis
que hemos estado usando para acceder a los elementos en una lista:

200
50

Veamos qué sucede si intentamos cambiar uno de los elementos en las dimensiones de la tupla:

dimensiones = (200, 50)


u dimensiones[0] = 250

El código en u intenta cambiar el valor de la primera dimensión, pero Python devuelve


un error de tipo. Básicamente, debido a que estamos tratando de alterar una tupla, lo que no se
puede hacer con ese tipo de objeto, Python nos dice que no podemos asignar un nuevo valor a un
elemento en una tupla:

Rastreo (llamadas recientes más última):


Archivo "dimensions.py", línea 2, en <módulo>
dimensiones[0] = 250
TypeError: el objeto 'tupla' no admite la asignación de elementos

Esto es beneficioso porque queremos que Python genere un error cuando una línea de código
intente cambiar las dimensiones del rectángulo.

Nota Las tuplas se definen técnicamente por la presencia de una coma; los paréntesis los
hacen parecer más ordenados y legibles. Si desea definir una tupla con un
elemento, debe incluir una coma final:

mi_t = (3,)
A menudo no tiene sentido construir una tupla con un elemento, pero esto puede suceder
cuando las tuplas se generan automáticamente.

66 Capítulo 4

MachineTranslatedbyGoogle

Recorriendo todos los valores en una tupla

Puede recorrer todos los valores en una tupla usando un bucle for , tal como lo hizo
con una lista:

dimensiones = (200, 50)


para dimensión en dimensiones:

imprimir (dimensión)

Python devuelve todos los elementos de la tupla, tal como lo haría con una lista:

200
50

Escribiendo sobre una Tupla

Aunque no puede modificar una tupla, puede asignar un nuevo valor a una variable que
representa una tupla. Entonces, si quisiéramos cambiar nuestras dimensiones, podríamos
redefinir la tupla completa:

u dimensiones = (200, 50)


imprimir("Dimensiones originales:")
para dimensión en dimensiones:
imprimir (dimensión)

v dimensiones = (400, 100)


w print("\nDimensiones modificadas:")
para dimensión en dimensiones:
imprimir (dimensión)

Las líneas que comienzan en u definen la tupla original e imprimen las


dimensiones iniciales. En v, asociamos una nueva tupla con las dimensiones variables.
Luego imprimimos las nuevas dimensiones en w. Python no genera ningún error esta
vez, porque la reasignación de una variable es válida:

Dimensiones originales: 200

50

Dimensiones modificadas:
400
100

En comparación con las listas, las tuplas son estructuras de datos simples. Úselos
cuando desee almacenar un conjunto de valores que no deben cambiarse a lo largo de
la vida de un programa.

Trabajar con listas 67

MachineTranslatedbyGoogle

Inténtalo tú mismo

4-13. Buffet: Un restaurante estilo buffet ofrece solo cinco alimentos básicos. Piense en cinco
alimentos simples y guárdelos en una tupla.

•Utilice un bucle for para imprimir cada comida que ofrece el restaurante.

•Intente modificar uno de los elementos y asegúrese de que Python rechace el


cambio.

•El restaurante cambia su menú, reemplazando dos de los artículos con alimentos diferentes.
Agregue una línea que reescriba la tupla y luego use un ciclo for para imprimir cada uno
de los elementos en el menú revisado.

Estilo de su código

Ahora que está escribiendo programas más largos, vale la pena conocer ideas sobre cómo
diseñar su código. Tómese el tiempo para hacer que su código sea lo más fácil de leer
posible. Escribir código fácil de leer lo ayuda a realizar un seguimiento de lo que están
haciendo sus programas y también ayuda a otros a comprender su código.
Los programadores de Python acordaron una serie de convenciones de estilo
para garantizar que el código de todos esté estructurado más o menos de la misma manera.
Una vez que haya aprendido a escribir código Python limpio, debería poder comprender
la estructura general del código Python de cualquier otra persona, siempre que siga las
mismas pautas. Si espera convertirse en un programador profesional en algún momento,
debe comenzar a seguir estas pautas lo antes posible para desarrollar buenos hábitos.

La guía de estilo
Cuando alguien quiere hacer un cambio en el lenguaje Python, escribe una propuesta de
mejora de Python (PEP). Uno de los PEP más antiguos es PEP 8, que instruye a los
programadores de Python sobre cómo diseñar su código. PEP 8 es bastante largo, pero
gran parte se relaciona con estructuras de codificación más complejas que las que has
visto hasta ahora.
La guía de estilo de Python se escribió con el entendimiento de que el código se lee
con más frecuencia de lo que se escribe. Escribirá su código una vez y luego comenzará
a leerlo cuando comience la depuración. Cuando agrega características a un programa,
pasará más tiempo leyendo su código. Cuando comparte su código con otros
programadores, también lo leerán.
Dada la elección entre escribir código que sea más fácil de escribir o código que
sea más fácil de leer, los programadores de Python casi siempre lo alentarán a escribir
código que sea más fácil de leer. Las siguientes pautas lo ayudarán a escribir un código
claro desde el principio.

68 Capítulo 4

MachineTranslatedbyGoogle

Sangría
PEP 8 recomienda utilizar cuatro espacios por nivel de sangría. El uso de cuatro espacios mejora la
legibilidad y deja espacio para varios niveles de sangría en cada línea.

En un documento de procesamiento de texto, las personas a menudo usan tabulaciones en


lugar de espacios para sangrar. Esto funciona bien para documentos de procesamiento de texto, pero
el intérprete de Python se confunde cuando las pestañas se mezclan con espacios. Cada editor de
texto proporciona una configuración que le permite usar la tecla de tabulación pero luego convierte cada
tabulación a un número determinado de espacios. Definitivamente debe usar su tecla de tabulación ,
pero también asegúrese de que su editor esté configurado para insertar espacios en lugar de tabulaciones
en su documento.
Mezclar tabulaciones y espacios en su archivo puede causar problemas que son muy difíciles
de diagnosticar. Si cree que tiene una combinación de tabulaciones y espacios, puede convertir
todas las tabulaciones de un archivo en espacios en la mayoría de los editores.

Longitud de la línea

Muchos programadores de Python recomiendan que cada línea tenga menos de 80 caracteres.
Históricamente, esta directriz se desarrolló porque la mayoría de las computadoras podían incluir solo
79 caracteres en una sola línea en una ventana de terminal.
Actualmente, las personas pueden colocar líneas mucho más largas en sus pantallas, pero existen
otras razones para adherirse a la longitud de línea estándar de 79 caracteres. Los programadores
profesionales a menudo tienen varios archivos abiertos en la misma pantalla, y usar la longitud de línea
estándar les permite ver líneas completas en dos o tres archivos que están abiertos uno al lado del otro
en la pantalla. PEP 8 también recomienda que limite todos sus comentarios a 72 caracteres por línea,
porque algunas de las herramientas que generan documentación automática para proyectos más grandes
agregan caracteres de formato al comienzo de cada línea comentada.

Las pautas de PEP 8 para la longitud de la línea no son inamovibles y algunos equipos
prefieren un límite de 99 caracteres. No se preocupe demasiado por la longitud de línea en su código
mientras aprende, pero tenga en cuenta que las personas que trabajan en colaboración casi siempre
siguen las pautas de PEP 8. La mayoría de los editores le permiten configurar una señal visual,
generalmente una línea vertical en su pantalla, que le muestra dónde están estos límites.

N ota El Apéndice B le muestra cómo configurar su editor de texto para que siempre inserte cuatro espacios
cada vez que presione la tecla de tabulación y muestre una guía vertical para ayudarlo a seguir el
límite de 79 caracteres.

Líneas en blanco

Para agrupar partes de su programa visualmente, use líneas en blanco. Debe usar líneas en blanco
para organizar sus archivos, pero no lo haga en exceso. Siguiendo los ejemplos proporcionados en
este libro, debe lograr el equilibrio adecuado. Por ejemplo, si tiene cinco líneas de código que crean una
lista y luego otras tres líneas que hacen algo con esa lista, es apropiado colocar una línea en blanco entre
las dos secciones. Sin embargo, no debe colocar tres o cuatro líneas en blanco entre las dos secciones.

Trabajar con listas 69

MachineTranslatedbyGoogle

Las líneas en blanco no afectarán la forma en que se ejecuta su código, pero


afectarán la legibilidad de su código. El intérprete de Python usa sangría horizontal para
interpretar el significado de su código, pero ignora el espacio vertical.

Otras pautas de estilo


PEP 8 tiene muchas recomendaciones de estilo adicionales, pero la mayoría de las líneas
guía se refieren a programas más complejos que los que está escribiendo en este momento.
A medida que aprenda estructuras de Python más complejas, compartiré las partes relevantes
de las pautas de PEP 8.

Inténtalo tú mismo

4-14. PEP 8: consulte la guía de estilo original de PEP 8 en https://python.org/


dev/peps/pep-0008/. No usará mucho ahora, pero podría ser interesante hojearlo.

4-15. Revisión de código: Elija tres de los programas que ha escrito en este capítulo y modifique
cada uno para cumplir con PEP 8:

•Utilice cuatro espacios para cada nivel de sangría. Configure su editor de texto para insertar
cuatro espacios cada vez que presione tabulador, si aún no lo ha hecho (consulte el
Apéndice B para obtener instrucciones sobre cómo hacerlo).

•Utilice menos de 80 caracteres en cada línea y configure su editor para mostrar un


guía vertical en la posición del carácter 80.

•No utilice líneas en blanco en exceso en sus archivos de programa.

Resumen
En este capítulo aprendió cómo trabajar eficientemente con los elementos de una lista.
Aprendió cómo trabajar en una lista usando un bucle for , cómo Python usa la sangría para
estructurar un programa y cómo evitar algunos errores de sangría comunes. Aprendiste a
hacer listas numéricas simples, así como algunas operaciones que puedes realizar en listas
numéricas. Aprendió cómo dividir una lista para trabajar con un subconjunto de elementos y
cómo copiar listas correctamente usando una división. También aprendió sobre las tuplas,
que brindan un grado de protección a un conjunto de valores que no deberían cambiar, y
cómo diseñar su código cada vez más complejo para que sea fácil de leer.

En el Capítulo 5, aprenderá a responder apropiadame


apropiadamente
nte a diferentes condiciones
usando sentencias if . Aprenderá a encadenar conjuntos relativamente complejos de
pruebas condicionales para responder adecuadamente al tipo exacto de situación o
información que está buscando. También aprenderá a usar if
declaraciones mientras recorre una lista para realizar acciones específicas con elementos
seleccionados de una lista.

70 Capítulo 4

MachineTranslatedbyGoogle

5
si declaración s

La programación a menudo implica examinar


un conjunto de condiciones y decidir qué
acción tomar en función de esas condiciones.
La declaración if de Python le permite examinar el
estado actual de un programa y responder adecuadamente
a ese estado.
En este capítulo, aprenderá a escribir pruebas condicionales, que le permiten
verificar cualquier condición de interés. Aprenderá a escribir declaraciones if simples y
aprenderá a crear una serie más compleja de declaraciones if para identificar cuándo
están presentes las condiciones exactas que desea. Luego, aplicará este concepto a
las listas, de modo que podrá escribir un bucle for que maneje la mayoría de los
elementos de una lista de una manera, pero que maneje ciertos elementos con valores
específicos de otra manera.
MachineTranslatedbyGoogle

Un ejemplo sencillo
El siguiente breve ejemplo muestra cómo las pruebas le permiten responder correctamente a
situaciones especiales. Imagina que tienes una lista de autos y quieres imprimir el nombre de
cada auto. Los nombres de los automóviles son nombres propios, por lo que los nombres de
la mayoría de los automóviles deben escribirse en mayúsculas y minúsculas. Sin embargo, el
valor 'bmw' debe imprimirse en mayúsculas. El siguiente código recorre una lista de nombres
de automóviles y busca el valor 'bmw'. Cada vez que el valor es 'bmw', se imprime en mayúsculas
en lugar de en mayúsculas y minúsculas:

autos.py coches = ['audi','bmw','subaru','toyota']


,'toyota']

para coche en coches:


u si coche == 'bmw':

imprimir (coche. superior ())


demás:

imprimir (coche.título())

El bucle de este ejemplo comprueba primero


primero si el valor actual de car es 'bmw' u.
Si es así, el valor se imprime en mayúsculas
mayúsculas.. Si el valor del automóvil es diferente a 'bmw', se
imprime en mayúsculas y minúsculas:

Audi
BMW

subaru

Toyota

Este ejemplo combina varios de los conceptos que aprenderá en este capítulo.
Comencemos mirando los tipos de pruebas que puede usar para examinar las condiciones
en su programa.

Pruebas Condicionales

En el corazón de cada declaración if hay una expresión que se puede evaluar como verdadera
o falsa y se llama prueba condicional. Python usa los valores True y False para decidir si se
debe ejecutar el código en una declaración if . Si una prueba condicional se evalúa como True,
Python ejecuta el código que sigue al if
if
declaración. Si la prueba se evalúa como Falso, Python ignora el código que sigue a la
instrucción if .

Comprobación de la igualdad

La mayoría de las pruebas condicionales comparan el valor actual de una variable con un valor
específico de interés. La prueba condicional más simple verifica si el valor de una variable es
igual al valor de interés:

u >>> coche = 'bmw'


en >>> coche == 'bmw'
Verdadero

72 Capítulo 5

MachineTranslatedbyGoogle

La línea en u establece el valor del automóvil en 'bmw' usando un solo signo igual,
como ya ha visto muchas veces. La línea en v verifica si el valor del automóvil es 'bmw'
usando un signo igual doble (==). Este operador de igualdad devuelve True si los valores
del lado izquierdo y derecho del operador coinciden y False si no coinciden. Los valores de
este ejemplo coinciden, por lo que Python devuelve True.

Cuando el valor del automóvil es diferente a 'bmw', esta prueba devuelve


Falso:

u >>> coche = 'audi'


en >>> coche == 'bmw'
Falso

Un solo signo igual es realmente una declaración; podrías leer el código en ti


como "Establecer el valor del coche igual a 'audi'". Por otro lado, un doble signo igual, como el que
está en v, hace una pregunta: "¿Es el valor del automóvil igual a 'bmw'?"
La mayoría de los lenguajes de programación usan signos iguales de esta manera.

Ignorar el caso al verificar la igualdad


La prueba de igualdad distingue entre mayúsculas y minúsculas en Python. Por ejemplo, dos
valores con diferente capitalización no se consideran iguales:

>>> coche = 'Audi'


>>> coche == 'audi'
Falso

Si el caso importa, este comportamie


comportamiento
nto es ventajoso. Pero si el caso no importa y en su
lugar solo desea probar el valor de una variable, puede convertir el valor de la variable a
minúsculas antes de hacer la comparación:

>>> coche = 'Audi'


>>> coche.inferior() == 'audi'
Verdadero

Esta prueba devolvería True sin importar cómo esté formateado el valor 'Audi' porque
la prueba ahora no distingue entre mayúsculas y minúsculas. La función lower() no cambia el
valor que se almacenó originalmente en car, por lo que puede hacer este tipo de comparación
sin afectar la variable original:

u >>> coche = 'Audi'


v >>> auto.inferior() == 'audi'
Verdadero

w >>> coche
'Audi'
En u asignamos la cadena en mayúscula 'Audi' a la variable coche. en v
convertimos el valor de car a minúsculas y comparamos el valor en minúsculas

Si declaraciones 73

MachineTranslatedbyGoogle

a la cadena 'audi'. Las dos cadenas coinciden, por lo que Python devuelve True. en w
podemos ver que el valor almacenado en car no se ha visto afectado por lower()
método.
Los sitios web imponen ciertas reglas para los datos que los usuarios ingresan de
una manera similar a esta. Por ejemplo, un sitio podría usar una prueba condicional como
esta para asegurarse de que cada usuario tenga un nombre de usuario realmente único, no

solo una variación de las mayúsculas del nombre de usuario de otra persona. Cuando alguien
envía un nuevo nombre de usuario, ese nuevo nombre de usuario se convierte a minúsculas y
se compara con las versiones en minúsculas de todos los nombres de usuario existentes.
Durante esta verificación, un nombre de usuario como 'John' será rechazado si hay alguna variación de 'john'
Esta en uso.

Comprobación de la desigualdad

Cuando desee determinar si dos valores no son iguales, puede combinar un signo de
exclamación y un signo igual (!=).
(!=). El signo de exclamación representa no, como lo
hace en muchos lenguajes de programación.
Usemos otra instrucción if para examinar cómo usar el operador de desigualdad.
Guardaremos un ingrediente de pizza solicitado en una variable y luego imprimiremos un
mensaje si la persona no pidió anchoas:

toppings.py request_topping = 'champiñones'

u si se solicita_topping != 'anchoas':
'anchoas':
print("¡Sujeta las anchoas!")

La línea en u compara el valor de request_topping con el valor 'anchoas'. Si


estos dos valores no coinciden, Python devuelve True y ejecuta el código que sigue a
la instrucción if . Si los dos valores coinciden, Python devuelve False y no ejecuta el
código que sigue a la instrucción if .
Debido a que el valor de request_topping no es 'anchoas', el print()
se ejecuta la función:

Aguante las anchoas!

La mayoría de las expresiones condicionales que escriba probarán la igualdad, pero


a veces le resultará más eficiente probar la desigualdad.

Comparaciones numéricas

Probar valores numéricos es bastante sencillo. Por ejemplo, el siguiente código verifica
si una persona tiene 18 años:

>>> edad = 18
>>> edad == 18
Verdadero

74 Capítulo 5

MachineTranslatedbyGoogle

También puedes probar para ver si dos números no son iguales. por ejemplo, el
siguiente código imprime un mensaje si la respuesta dada no es correcta:

respuesta = 17
número_mágico.py
u si responde != 42:
print("Esa no es la respuesta correcta. Inténtalo de nuevo!")

La prueba condicional en u pasa, porque el valor de la respuesta (17) no es


igual a 42. Debido a que la prueba pasa, se ejecuta el bloque de código sangrado:

Esa no es la respuesta correcta. ¡Inténtalo de nuevo!

También puede incluir varias comparaciones matemáticas en sus declaraciones condicionales,


como menor que, menor o igual que, mayor que y mayor o igual que:

>>> edad = 19
>>> edad < 21
Verdadero

>>> edad <= 21


Verdadero

>>> edad > 21


Falso
>>> edad >= 21
Falso

Cada comparación matemática se puede usar como parte de una declaración if , que puede
ayudarlo a detectar las condiciones exactas de interés.

Comprobación
Comprobación de múltiples condiciones

Es posible que desee verificar varias condiciones al mismo tiempo. Por ejemplo, a veces es posible

que necesite que dos condiciones sean Verdaderas para realizar una acción. Otras veces puede estar
satisfecho con que solo una condición sea Verdadera. Las palabras clave and y or pueden ayudarlo en
estas situaciones.

Uso de y para verificar múltiples condiciones

Para verificar si dos condiciones son ambas Verdaderas simultáneamente, use la palabra clave y
para combinar las dos pruebas condicionales; si pasa cada prueba, la expresión general se evalúa
como verdadera. Si alguna de las pruebas falla o si ambas pruebas fallan, la expresión se evalúa
como Falso.
Por ejemplo, puede verificar si dos personas tienen más de 21 años usando la siguiente prueba:
u >>> edad_0 = 22
>>> edad_1 = 18
v >>> edad_0 >= 21 y edad_1 >= 21
Falso

Si declaraciones 75

MachineTranslatedbyGoogle

w >>> edad_1 = 22
>>> edad_0 >= 21 y edad_1 >= 21
Verdadero

En u definimos dos edades, edad_0 y edad_1. En v verificamos si ambas edades tienen 21


años o más. La prueba de la izquierda pasa, pero la prueba de la derecha falla, po
porr lo que la expresión
condicional general se evalúa como Falsa. En w cambiamos age_1
a 22. El valor de age_1 ahora es mayor que 21, por lo que ambas pruebas individuales pasan, lo que
hace que la expresión condicional general se evalúe como True.
Para mejorar la legibilidad, puede usar paréntesis alrededor de las pruebas individuales, pero
no son obligatorios. Si usa paréntesis, su prueba se vería así:

(edad_0 >= 21) y (edad_1 >= 21)

Usar o para comprobar varias condiciones

La palabra clave o le permite verificar múltiples condiciones también, pero pasa cuando pasa

una o ambas pruebas individuales. Una expresión o falla solo cuando ambas pruebas individuales
fallan.
Consideremos dos edades nuevamente, pero esta vez buscaremos que solo una persona
tenga más de 21 años:

u >>> edad_0 = 22
>>> edad_1 = 18
v >>> edad_0 >= 21 o edad_1 >= 21

Verdadero w >>>
edad_0 = 18 >>> edad_0 >= 21 o edad_1 >= 21
Falso

Comenzamos con dos variables de edad nuevamente en u. Porque la prueba para


p ara age_0 en v
pasa, la expresión general se evalúa como True. Luego bajamos age_0 a 18. En la prueba en w,
ambas pruebas ahora fallan y la expresión general se evalúa como Falsa.

Comprobar si un valor está en una lista


A veces es importante comprobar si una lista contiene un determinado valor antes de realizar una
acción. Por ejemplo, es posible que desee verificar si ya existe un nuevo nombre de usuario en una
lista de nombres de usuario actuales antes de completar el registro de alguien en un sitio web. En
un proyecto de mapeo, es posible que desee verificar si una ubicación enviada ya existe en una
u na lista
de ubicaciones conocidas.

Para saber si un valor en particular ya está en una lista, use la tecla


palabra . Consideremos un código que podría escribir para una pizzería. Haremos una lista de
ingredientes que un cliente ha solicitado para una pizza y luego verificaremos si ciertos
ingredientes están en la lista.

76 Capítulo 5

MachineTranslatedbyGoogle

>>> Request_toppings = ['champiñones', 'cebollas', 'piña']


u >>> 'champiñones' en los ingredientes solicitados
Verdadero

v >>> 'pepperoni' en los ingredientes solicitados


Falso

En u y v, la palabra clave in le dice a P


Python
ython que verifique la existencia de 'champiñones' y
'pepperoni' en la lista de ingredientes solicitados. Esta técnica es bastante poderosa porque
puede crear una lista de valores esenciales y luego verificar fácilmente si el valor que está
probando coincide con uno de los valores de la lista.

Comprobar si un valor no está en una lista

Otras veces, es importante saber si un valor no aparece en una lista. Puede utilizar la palabra
clave no en esta situación. Por ejemplo, considere una lista de usuarios que tienen prohibido
comentar en un foro. Puede verificar si un usuario ha sido prohibido antes de permitir que esa
persona envíe un comentario:

baneados baneados_usuarios = ['andrew', 'carolina', 'david']


_usuarios.py usuario = 'marie'

u si el usuario no está en usuarios prohibidos:


print(f"{user.title()}, puede publicar una respuesta si lo desea").

La línea en u se lee bastante claramente. Si el valor


v alor del usuario no está en la lista
banned_users, Python devuelve True y ejecuta la línea con sangría.
El usuario 'marie' no está en la lista de usuarios prohibidos, por lo que ve un mensaje
invitándola a publicar una respuesta:

Marie, puedes publicar una respuesta si lo deseas.

Expresiones booleanas

A medida que aprenda más sobre programación, escuchará el término expresión booleana
en algún momento. Una expresión booleana es solo otro nombre para una prueba condicional. Un
valor booleano es verdadero o falso, al igual que el valor de una expresión condicional después
de haberla evaluado.
Los valores booleanos a menudo se usan para realizar un seguimiento de ciertas condiciones,
como si un juego se está ejecutando o si un usuario puede editar cierto contenido en un sitio web:

juego_activo = Verdadero
Verdadero
can_edit = Falso

Los valores booleanos proporcionan una forma eficiente de rastrear el estado de un programa
o una condición particular que es importante en su programa.

Si declaraciones 77
declaraciones

MachineTranslatedbyGoogle

Inténtalo tú mismo

5-1. Pruebas condicionales: Escribe una serie de pruebas condicionales. Imprima una declaración

que describa cada prueba y su predicción para los resultados de cada prueba. Su código debería ser
algo como esto:

coche = 'subaru'
print("¿Es auto == 'subaru'? Predigo Verdadero.")
imprimir (coche == 'subaru')

print("\nEs auto == 'audi'? Predigo Falso.")


imprimir (coche == 'audi')

•Observe detenidamente sus resultados y asegúrese de comprender por qué cada línea
se evalúa como Verdadero o Falso.

•Crear al menos diez pruebas. Haga que al menos cinco pruebas se evalúen como Verdadero y
otras cinco pruebas se evalúan como Falso.

5-2. Más pruebas condicionales: no tiene que limitar el número de pruebas que crea a diez. Si
desea probar más comparaciones, escriba más pruebas y agréguelas a conditional_tests.py. Tenga
al menos un resultado verdadero y uno falso para cada uno de los siguientes:

•Pruebas de igualdad y desigualdad con cadenas

•Pruebas usando el método lower()

• Pruebas numéricas que involucran igualdad y desigualdad, mayor que y menor que, mayor

que o igual a, y menor que o igual a

•Pruebas usando la palabra clave y y la palabra clave o

•Comprobar si un elemento está en una lista

•Comprobar si un elemento no está en una lista

si declaraciones
declaraciones

Cuando comprenda las pruebas condicionales, puede comenzar a escribir sentencias if .


Existen varios tipos diferentes de declaraciones if , y su elección de cuál usar depende
de la cantidad de condiciones que necesita probar. Viste varios ejemplos de
declaraciones if en la discusión sobre pruebas condicionales, pero ahora profundicemos
en el tema.

Declaraciones
Declaraciones if simples
El tipo más simple de instrucción if tiene una prueba y una acción:

si prueba_condicional:
hacer algo

78 Capítulo 5

MachineTranslatedbyGoogle

Puede poner cualquier prueba condicional en la primera línea y casi cualquier


acción en el bloque sangrado que sigue a la prueba. Si la prueba condicional se evalúa
como True, Python ejecuta el código que sigue a la instrucción if .
Si la prueba se evalúa como Falso, Python ignora el código que sigue al if
declaración.

Digamos que tenemos una variable que representa la edad de una persona y queremos

saber si esa persona tiene la edad suficiente para votar. El siguiente código prueba si la
persona puede votar:

votando.py edad = 19
u si edad >= 18:
v print("¡Tienes la edad suficiente para votar!")

En u, Python comprueba si el valor de la edad es mayor que o


igual a 18. Lo es, por lo que Python ejecuta la llamada print() sangrada en v:

¡Tienes la edad suficiente para votar!

La sangría juega el mismo papel en las sentencias if que en los bucles for .
Todas las líneas sangradas después de una declaración if se ejecutarán si la prueba pasa,
y todo el bloque de líneas sangradas se ignorará si la prueba no pasa.

Puede tener tantas líneas de código como desee en el bloque que sigue a la
instrucción if . Agreguemos otra línea de salida si la persona tiene la edad suficiente para
votar, preguntando si la persona ya se ha registrado para votar:

edad = 19
si edad >= 18:
print("¡Tienes la edad suficiente para votar!")
print("¿Ya se registró para votar?")

La prueba condicional pasa, y ambas llamadas print() están sangradas, por lo que se
imprimen ambas líneas:

¡Tienes la edad suficiente para votar!


¿Ya te registraste para votar?

Si el valor de la edad es inferior a 18, este programa no produciría resultados.

Declaraciones
Declaraciones if-else

A menudo, deseará realizar una acción cuando pase una prueba condicional y una acción
diferente en todos los demás casos. La sintaxis if-else de Python lo hace posible.
Un bloque if-else es similar a una declaración if simple , pero la declaración else le permite
definir una acción o un conjunto de acciones que se ejecutan cuando falla la prueba
condicional.

Si declaraciones 79

MachineTranslatedbyGoogle

Mostraremos el mismo mensaje que teníamos anteriormente si la persona es mayor


suficiente para votar, pero esta vez agregaremos un mensaje para cualquiera que no tenga la edad
suficiente para votar:

edad = 17
u si edad >= 18:
print("¡Tienes la edad suficiente para votar!")
print("¿Ya se registró para votar?")
v más:
print("Lo siento, eres demasiado joven para votar")
print("¡Por favor regístrese para votar tan pronto como cumpla 18 años!")

Si la prueba condicional en u pasa, el primer bloque de print() sangrado


se ejecutan las llamadas. Si la prueba se evalúa como Falso, se ejecuta el bloque else en v. Debido a
que la edad es menor de 18 años esta vez, la prueba condicional falla y se ejecuta el código en el bloque
else :

Lo siento, eres demasiado joven para votar.


¡Por favor regístrese para votar tan pronto como cumpla 18 años!

Este código funciona porque solo tiene dos situaciones posibles para evaluar: una persona tiene
la edad suficiente para votar o no tiene la edad suficiente para votar. El si-más
La estructura funciona bien en situaciones en las que desea que Python siempre ejecute una de dos
acciones posibles. En una cadena if-else simple como esta, siempre se ejecutará una de las dos acciones.

La cadena if-elif-else

A menudo, deberá probar más de dos situaciones posibles y, para evaluarlas, puede usar la sintaxis if-elif-
else de Python. Python ejecuta solo un bloque en una cadena if-elif-
if-elif-else
else . Ejecuta cada prueba condicional
en orden hasta que pasa una. Cuando pasa una prueba, se ejecuta el código que sigue a esa prueba y

Python omite el resto de las pruebas.

Muchas situaciones del mundo real involucran más de dos condiciones posibles.
Por ejemplo, considere un parque de diversiones que cobra diferentes tarifas para diferentes grupos de
edad:

•La entrada para cualquier persona menor de 4 años es gratuita.

•La entrada para cualquier persona entre las edades de 4 y 18 años es de $25.

•La entrada para cualquier persona mayor de 18 años es de $40.

¿Cómo podemos usar una declaración if para determinar la tasa de admisión de una persona?
El siguiente código prueba el grupo de edad de una persona y luego imprime un mensaje de precio de
admisión:
edad de diversión = 12
_parque.py
u si edad < 4:
print("El costo de su entrada es $0.")

80 Capítulo 5

MachineTranslatedbyGoogle

v elif edad < 18:


print("El costo de su entrada es de $25.")
en otro:
print("El costo de su entrada es de $40.")

La prueba if at u prueba si una persona tiene menos de 4 años. Si pasa la prueba, se


imprime un mensaje apropiado y Python omite el resto de las pruebas. La línea elif en v es
realmente otra prueba if , que se ejecuta solo si la prueba anterior falló. En este punto de la
cadena, sabemos que la persona tiene al menos 4 años porque la primera prueba falló. Si la
persona es menor de 18 años, se imprime un mensaje apropiado y Python omite el bloque
else . Si tanto el si
y las pruebas elif fallan, Python ejecuta el código en el bloque else en w.
En este ejemplo, la prueba en u se evalúa como Falso, por lo que su bloque de código
no se ejecuta. Sin embargo, la segunda prueba se evalúa como Verdadero (12 es menor
que 18) por lo que se ejecuta su código. El resultado es una oración, informando al usuario
del costo de la entrada:

Su costo de admisión es de $25.

Cualquier edad mayor de 17 años haría que las dos primeras pruebas fallaran. En
estas situaciones, se ejecutaría el bloque else y el precio de admisión sería de $40.

En lugar de imprimir el precio de la entrada dentro del bloque if-elif


if-elif-else
-else ,
sería más conciso establecer solo el precio dentro de la cadena if-elif-else y luego tener
una simple llamada print() que se ejecute después de que se haya evaluado la cadena:

edad = 12

si edad < 4:
tu precio = 0
edad < 18:
v precio = 25
demás:

w precio = 40

x print(f"El costo de su entrada es ${precio}").

Las líneas en u, v y w establecen el valor del precio según la edad de la persona, como
en el ejemplo anterior. Después de que la cadena if-elif-else establece el precio, una llamada
print() separada sin sangría ÿ usa este valor para mostrar un mensaje que informa el precio de
admisión de la persona.
Este código produce el mismo resultado que el ejemplo anterior, pero el propósito de
la cadena if-elif-else es más limitado. En lugar de determinar un precio y mostrar un mensaje,
simplemente determina el precio de admisión.
Además de ser más eficiente, este código revisado es más fácil de modificar que el enfoque
original. Para cambiar el texto del mensaje de salida, necesitaría cambiar solo una llamada
print() en lugar de tres llamadas print() separadas .

si declaraciones 81

MachineTranslatedbyGoogle

Uso de múltiples bloques elif


Puede usar tantos bloques elif en su código como desee. Por ejemplo, si el parque de diversiones
implementara un descuento para personas mayores, podría agregar una prueba condicional más al
código para determinar si alguien calificó para el descuento para personas mayores. Digamos que
cualquier persona mayor de 65 años paga la mitad de la entrada regular, o $20:

edad = 12

si edad < 4:
precio = 0
edad < 18:
precio = 25
u elif edad < 65:
precio = 40
v más:
precio = 20

print(f"El costo de su entrada es ${precio}").

La mayor parte de este código no ha cambiado. El segundo bloque elif en u ahora comprueba
para asegurarse de que una persona tenga menos de 65 años antes de asignarle la tarifa de
admisión total de $40. Observe que el valor asignado en el bloque else en v
debe cambiarse a $ 20, porque las únicas edades que llegan a este bloque son las personas de 65
años o más.

Omitir el bloque else


Python no requiere un bloque else al final de una cadena if-elif . Algunas veces un bloque else es
útil; a veces es más claro usar una declaración elif adicional que capte la condición específica de
interés:

edad = 12

si edad < 4:
precio = 0
edad < 18:
precio = 25
edad < 65:
precio = 40
u elif edad >= 65:
precio = 20

print(f"El costo de su entrada es ${precio}").


El bloque extra elif en u asigna un precio de $20 cuando la persona tiene 65 años o más,
que es un poco más claro que el bloque general else . Con este cambio, cada bloque de código
debe pasar una prueba específica para poder ejecutarse.

82 Capítulo 5

MachineTranslatedbyGoogle

El bloque else es una declaración general. Coincide con cualquier condición


que no haya coincidido con una prueba if o elif específica , y que a veces
v eces puede incluir
datos no válidos o incluso maliciosos. Si tiene una condición final específica que está
probando, considere usar un bloque elif final y omita el bloque else . Como resultado,
obtendrá una mayor confianza en que su código
c ódigo se ejecutará solo en las condiciones
correctas.

Prueba de múltiples condiciones

La cadena if-elif-else es poderosa, pero solo es apropiada para usar cuando solo
necesita pasar una prueba. Tan pronto como Python encuentra una prueba que pasa,
salta el resto de las pruebas. Este comportamiento es beneficioso porque es eficiente
y le permite probar una condición específica.
Sin embargo, a veces es importante verificar todas las condiciones de interés.
En este caso, debe usar una serie de declaraciones if simples sin bloques elif o else .
Esta técnica tiene sentido cuando más de una condición puede ser Verdadera y desea
actuar en cada condición que sea Verdadera.
Reconsideremos el ejemplo de la pizzería. Si alguien pide dos ingredientes
pizza, deberá asegurarse de incluir ambos ingredientes en su pizza:

toppings.py u request_toppings = ['champiñones', 'queso extra']

v si 'champiñones' en los ingredientes solicitados:


print("Añadiendo champiñones")
w si 'pepperoni' en los ingredientes solicitados:
print("Añadiendo pepperoni")
x si 'queso extra' en los ingredientes solicitados:
print("Añadiendo queso extra")

print("\nTerminé de hacer tu pizza!")

Comenzamos en u con una lista que contiene los ingredientes solicitados. el si


declaración en v comprueba si la persona pidió champiñones en su pizza. Si es así, se imprime
un mensaje que confirma ese topping. La prueba para pepperoni en w es otra declaración if
simple , no un elif o bien
declaración, por lo que esta prueba se ejecuta independientemente de si la prueba
anterior pasó o no. El código en x verifica si se solicitó queso adicional
independientemente
independientemen te de los resultados de las dos primeras pruebas. Estas tres pruebas
independientes se ejecutan cada vez que se ejecuta este programa.
Debido a que se evalúan todas las condiciones de este ejemplo, se agregan
champiñones y queso adicional a la pizza:

Adición de champiñones.
Agregar queso extra.
¡Terminaste de hacer tu pizza!

Si declaraciones 83

MachineTranslatedbyGoogle

Este código no funcionaría correctamente si usáramos un bloque if-elif-else


if-elif-else ,
porque el código dejaría de ejecutarse después de que solo pasara una prueba. Así es como
se vería:

request_toppings = ['champiñones', 'queso extra']

si 'champiñones' en los ingredien


ingredientes
tes solicitados:
print("Añadiendo champiñones")
elif 'pepperoni' en los ingredientes solicitados:
print("Añadiendo pepperoni")
elif 'queso extra' en los ingrediente
ingredientes
s solicitados:
print("Añadiendo queso extra")

print("\nTerminé de hacer tu pizza!")


print("\nTerminé

La prueba de 'hongos' es la primera prueba que se pasa, por lo que se agregan hongos
a la pizza Sin embargo, los valores 'extra cheese' y 'pepperoni' nunca se verifican, porque
Python no ejecuta ninguna prueba más allá de la primera prueba que pasa en una
cadena if-elif-else . Se agregará el primer aderezo del cliente, pero se perderán todos los
demás aderezos:

Adición de champiñones.

¡Terminaste de hacer tu pizza!

En resumen, si desea que solo se ejecute un bloque de código, use un if-elif


otra cadena. Si necesita ejecutar más de un bloque de código, use una serie de declaraciones if

independientes .

Inténtalo tú mismo

5-3. Alien Colors #1:


Imagina que un alienígena acaba de ser derribado en un juego.
Cree una variable llamada alien_color y asígnele un valor de 'verde', 'amarillo' o ''rojo'.
rojo'.

•Escribe un enunciado if para comprobar si el color del extraterrestre es verde. Si es así, imprime
un mensaje de que el jugador acaba de ganar 5 puntos.

•Escriba una versión de este programa que pase la prueba if y otra que falle. (La versión que falla
no tendrá salida).

5-4. Alien Colors #2: Elija un color para un alienígena como lo hizo en el Ejercicio 5-3, y escriba
una cadena if-else .

•Si el color del alienígena es verde, imprime una declaración de que el jugador acaba de ganar
5 puntos por dispararle al alienígena.
•Si el color del alienígena no es verde, imprima una declaración de que el jugador acaba de ganar
10 puntos.

•Escriba una versión de este programa que ejecute el bloque if y otra que ejecute el bloque else .

84 Capítulo 5

MachineTranslatedbyGoogle

5-5. Alien Colors #3: Convierte tu cadena if-else del Ejercicio 5-4 en una cadena if-elif else .

•Si el alienígena es verde, imprime un mensaje de que el jugador ganó 5 puntos.

•Si el alienígena es amarillo, imprime un mensaje de que el jugador ganó 10 puntos.

•Si el alienígena es rojo, imprime un mensaje de que el jugador ganó 15 puntos.

•Escriba tres versiones de este programa, asegurándose de que cada mensaje se imprima para el extranjero

de color apropiado.

5-6. Etapas de la vida: escriba una cadena if-elif-else que determine la etapa de la vida de una

persona. Establezca un valor para la variable edad y luego:

•Si la persona tiene menos de 2 años, imprima un mensaje de que la persona es

un bebé.

•Si la persona tiene por lo menos 2 años pero menos de 4, imprima un mensaje que

la persona es un niño pequeño.

•Si la persona tiene al menos 4 años pero menos de 13, imprima un mensaje de que la persona es un

niño.
•Si la persona tiene por lo menos 13 años pero menos de 20, imprima un mensaje que

la persona es un adolescente.

•Si la persona tiene al menos 20 años pero menos de 65, i mprima un mensaje que la persona es un adulto.

•Si la persona tiene 65 años o más, imprima un mensaje que indique que la persona es un
mayor.

5-7. Fruta favorita: haga una lista de sus frutas favoritas y luego escriba una serie de declaraciones if

independientes
independientes que verifiquen ciertas frutas en su lista.

•Haz una lista de tus tres frutas favoritas y llámala frutas_favoritas.


•Escriba cinco enunciados
enunciados if . Cada uno debe verificar si un determinado tipo de fruta está en su lista. Si la

fruta está en su lista, el bloque if debe imprimir una declaración, como ¡Realmente le gustan los

plátanos!

Uso de sentencias if con listas


Puedes hacer un trabajo interesante cuando combinas listas y sentencias if .
Puede buscar valores especiales que deben tratarse de manera diferente a otros
valores en la lista. Puede administrar las condiciones cambiantes de manera
eficiente, como la disponibilidad de ciertos artículos en un restaurante durante un
turno. También puede comenzar a probar que su código funciona como espera en
todas las situaciones posibles.

si declaraciones 85

MachineTranslatedbyGoogle

Comprobación de artículos especiales

Este capítulo comenzó con un ejemplo simple que mostraba cómo manejar un valor
especial como 'bmw', que necesitaba imprimirse en un formato diferente al de otros
valores en la lista. Ahora que tiene una comprensión básica de las pruebas condicionales
condicionales
y las declaraciones if , echemos un vistazo más de cerca a cómo puede observar
valores especiales en una lista y manejar esos valores de manera adecuada.
adecuada.
Sigamos con el ejemplo de la pizzería. La pizzería muestra un mensaje cada vez
que se agrega un aderezo a su pizza, mientras se prepara. El código para esta acción
se puede escribir de manera muy eficiente haciendo una lista de ingredientes que el
cliente ha solicitado y usando un bucle para anunciar cada ingrediente a medida que
se agrega a la pizza:

toppings.py request_toppings = ['champiñones', 'pimientos verdes', 'queso extra']

para los ingredientes_solicitados en los ingredientes_solicitados:


print(f"Agregando {requested_topping}.")

print("\nTerminé de hacer tu pizza!")

El resultado es sencillo porque este código es solo un bucle for simple:

Adición de champiñones.
Agregar pimientos verdes.
Agregar queso extra.

¡Terminaste de hacer tu pizza!

Pero, ¿y si la pizzería se queda sin pimientos verdes? Una declaración si


dentro del ciclo for puede manejar esta situación apropiadamente:

request_toppings = ['champiñones', 'pimientos verdes', 'queso extra']

para los ingredientes_solicitados en los ingredientes_solicitados:


u if request_topping == 'pimientos verdes':
print("Lo siento, no tenemos pimientos verdes en este momento.")
v más:
print(f"Agregando {requested_topping}.")

print("\nTerminé de hacer tu pizza!")

Esta vez revisamos cada artículo solicitado antes de agregarlo a la pizza.


El código en u verifica si la persona solicitó pimientos verdes. Si es así, mostramos un
mensaje informándoles por qué no pueden tener pimientos verdes.
El bloque else en v asegura que todos los demás ingredientes se agregarán a la
pizza.

86 Capítulo 5

MachineTranslatedbyGoogle

El resultado muestra que cada aderezo solicitado se maneja de manera adecuada.

Adición de champiñones.
Lo sentimos, no tenemos pimientos verdes en este momento.
Agregar queso extra.

¡Terminaste de hacer tu pizza!

Comprobar que una lista no está vacía

Hemos hecho una suposición simple sobre cada lista con la que hemos trabajado hasta ahora;
hemos asumido que cada lista tiene al menos un elemento en ella. Pronto permitiremos que los

usuarios proporcionen la información que está almacenada en una lista, por lo que no podremos
asumir que una lista tiene elementos cada vez que se ejecuta un bucle. En esta situación, es útil
comprobar si una lista está vacía antes de ejecutar un bucle for .
Como ejemplo, verifiquemos si la lista de ingredientes solicitados está vacía antes de
construir la pizza. Si la lista está vacía, le preguntaremos al usuario y nos aseguraremos de que
quiera una pizza normal. Si la lista no está vacía, construiremos la pizza tal como lo hicimos en los
ejemplos anteriores:

has pedido_ingredientes = []

v si se solicitan_topping
solicitan_toppings:
s:
para los ingredientes_solicitados en los ingredientes_solicitados:
print(f"Agregando {requested_toppin
{requested_topping}.")
g}.")
print("\nTerminé
print("\nTerminé de hacer tu pizza!")
en otro:
print("¿Estás seguro de que quieres una pizza normal?")

Esta vez comenzamos con una lista vacía de ingredientes solicitados en u.


En lugar de saltar directamente a un bucle for , hacemos una comprobación rápida en v. Cuando se
usa el nombre de una lista en una sentencia if , Python devuelve True si la lista contiene al menos
un elemento; una lista vacía se evalúa como Falso. Si se solicita_ingredientes
pasa la prueba condicional, ejecutamos el mismo bucle for que usamos en el ejemplo anterior. Si la
prueba condicional falla, imprimimos un mensaje preguntando al cliente si realmente quiere una pizza
sencilla sin ingredientes w.
La lista está vacía en este caso, por lo que el resultado pregunta si el usuario realmente quiere
una pizza simple:

¿Estás seguro de que quieres una pizza normal?

Si la lista no está vacía, la salida mostrará cada ingrediente solicitado


se añade a la pizza.
si declaraciones 87

MachineTranslatedbyGoogle

Uso de listas múltiples


La gente pedirá casi cualquier cosa, especialmente cuando se trata de ingredientes para pizza. ¿Qué
pasa si un cliente realmente quiere papa
papas
s fritas en su pizza? Puede usar listas y declaraciones
declaraciones if para
asegurarse de que su entrada tenga sentido antes de actuar en consecuencia.

Esté atento a las solicitudes de ingredientes inusuales antes de preparar una pizza.
El siguiente ejemplo define dos listas. La primera es una lista de tops disponible
disponibles
s en la pizzería y la
segunda es la lista de toppings que ha solicitado el usuario. Esta vez, cada elemento de los ingredientes
solicitados se compara con la lista de ingredientes
ingredientes disponibles antes de agregarlo a la pizza:

u available_toppings = ['champiñones', 'aceitunas', 'pimientos verdes',


'pepperoni', 'piña', 'queso extra']

v request_toppings = ['champiñones', 'papas fritas', 'queso extra']

w para los ingredientes solicitados en los ingredientes solicitados:


x si se solicita_topping en available_toppings:
print(f"Agregando {requested_topping}.")
y más:
print(f"Lo sentimos, no tenemos {requested_topping}").

print("\nTerminé de hacer tu pizza!")

En u definimos una lista de ingredientes disponibles en esta pizzería. Tenga en cuenta que esto
podría ser una tupla si la pizzería tiene una selección estable de ingredientes. En v, hacemos una lista de
toppings que ha pedido un cliente. Tenga en cuenta la solicitud inusual, 'papas fritas'. En w recorremos la
lista de ingredien
ingredientes
tes solicitados.
Dentro del ciclo, primero verificamos si cada ingrediente solicitado está realmente en la lista de
ingredientes
ingredientes disponibles x. Si es así, añadimos ese topping a la pizza.
Si el ingrediente solicitado no está en la lista de ingredientes disponibles, el bloque else ejecutará y. El
bloque else imprime un mensaje que le dice al usuario qué ingredientes no están disponibles.

Esta sintaxis de código produce resultados limpios e informativos:

Adición de champiñones.
Lo siento, no tenemos papas fritas.
Agregar queso extra.

¡Terminaste de hacer tu pizza!

¡En solo unas pocas líneas de código, hemos manejado una situación del mundo real de manera
bastante efectiva!
88 Capítulo 5

MachineTranslatedbyGoogle

Inténtalo tú mismo

5-8. Hola administrador: haga una lista de cinco o más nombres de usuario, incluido el nombre
"administrador". Imagine que está escribiendo un código que imprimirá un saludo para cada usuario

después de que inicie sesión en un sitio web. Recorra la lista e imprima un saludo para cada usuario:

•Si el nombre de usuario es 'admin', imprima un saludo especial, como Hello admin,

¿Le gustaría ver un informe de estado?

• De lo contrario, imprima un saludo genérico, como Hola Jaden, gracias por iniciar sesión nuevamente.

5-9. Sin usuarios: agregue una prueba if a hello_admin.py para asegurarse de que la lista de usuarios no
esté vacía.

•Si la li sta está vacía, imprima el mensaje ¡Necesita


¡Necesitamos
mos encontrar algunos usuarios!

•Elimine todos los nombres de usuario de su lista y asegúrese de que se imprima el mensaje correcto.

5-10. Comprobación de nombres de usuario: haga lo siguiente para crear un programa que simule cómo

los sitios web se aseguran de que todos tengan un nombre de usuario único.

•Haga una lista de cinco o más nombres de usuario llamados current_users.

•Haga otra lista de cinco nombres de usuario llamada new_users. Asegúrese de que uno o dos de los

nuevos nombres de usuario también estén en la lista de usuarios_actuales .

•Recorra la lista new_users para ver si ya se ha utilizado cada nuevo nombre de usuario. Si es así,

imprima un mensaje que indique que la persona deberá ingresar un nuevo nombre de usuario. Si

no se ha utilizado un nombre de usuario, imprima un mensaje que diga que el nombre de usuario
está disponible.

•Asegúrese de que su comparación no distinga entre mayúsculas y minúsculas. Si se ha utilizado 'Juan' ,

No se debe aceptar 'JOHN' . (Para hacer esto, deberá hacer una copia de current_users que

contenga las versiones en minúsculas de todos los usuarios existentes).

5-11. Números ordinales: Los números ordinales indican su posición en una lista, como 1º o 2º. La
mayoría de los números ordinales terminan en th, excepto 1, 2 y 3.

•Guarde los números del 1 al 9 en una lista.

• Recorra la lista.

•Use una cadena if-elif-else dentro del ciclo para imprimir el final ordinal apropiado para cada número. Su

salida debe decir "1st 2nd 3rd 4th 5th 6th 7th 8th 9th", y cada resultado debe estar en una línea

separada.
Si declaraciones 89

MachineTranslatedbyGoogle

Diseñar sus declaraciones if


En cada ejemplo de este capítulo, ha visto buenos hábitos de estilo. La única recomendación que proporciona PEP 8
para diseñar pruebas condicionales es usar un solo espacio alrededor de los operadores de comparación, como ==,
>=, <=. Por ejemplo:

si edad < 4:

es mejor que:

si la edad <4:

Dicho espacio no afecta la forma en que Python interpreta su código; es solo


hace que su código sea más fácil de leer para usted y para otros.

Inténtalo tú mismo

5-12. Aplicar estilo a las sentencias if : revise los programas que escribió en este capítulo y asegúrese de
aplicar el estilo adecuado a sus pruebas condicionales.

5-13. Tus ideas: en este punto, eres un programador más capaz que cuando comenzaste este libro.

Ahora que tiene una mejor idea de cómo se modelan las situaciones del mundo real en los programas,
es posible que esté pensando en algunos problemas que podría resolver con sus propios programas.
Registre cualquier idea nueva que tenga sobre problemas que podría querer resolver a medida que sus

habilidades de programación continúan mejorando. Considere los juegos que quizás desee escribir, los
conjuntos de datos que quizás desee explorar y las aplicaciones web que le gustaría crear.

Resumen
En este capítulo, aprendió a escribir pruebas condicionales, que siempre se evalúan como
Verdadero o Falso. Aprendiste a escribir sentencias if simples , if-else
cadenas y cadenas if-elif-else . Comenzó a usar estas estructuras para identificar condiciones
particulares que necesitaba probar y saber cuándo se cumplieron esas condiciones en sus
programas. Aprendió a manejar ciertos elementos en una lista de manera diferente a todos los
demás elementos mientras continúa utilizando la eficiencia de un bucle for . También revisó las
recomendaciones de estilo de Python para asegurarse de que sus programas cada vez más
complejos sigan siendo relativamente fáciles de leer y comprender.
En el Capítulo 6 aprenderá sobre los diccionarios de Python. Un diccionario es similar a

una lista, pero le permite conectar piezas de información. Aprenderá a construir diccionarios,
recorrerlos y usarlos en combinación con listas y sentencias if . Aprender sobre diccionarios le
permitirá modelar una variedad aún más amplia de situaciones del mundo real.

90 Capítulo 5

MachineTranslatedbyGoogle

6
Diccionarios

En este capítulo, aprenderá a usar los diccionarios


de Python, que le permiten conectar piezas de

información relacionada. lo harás


aprenda a acceder a la información una vez que esté

en un diccionario y cómo modificar esa información.


Debido a que los diccionarios pueden almacenar una cantidad

casi ilimitada de información, le mostraré cómo recorrer los datos


en un diccionario. Además, aprenderá a anidar diccionarios dentro
de listas, listas dentro de diccionarios e incluso diccionarios dentro de
otros diccionarios.
Comprender los diccionarios le permite modelar una variedad de situaciones del mundo real.
objetos con mayor precisión. Podrá crear un diccionario que represente a una persona y

luego almacenar toda la información que desee sobre esa persona. Puede almacenar su
nombre, edad, ubicación, profesión y cualquier otro aspecto de una persona que pueda describir.
Podrá almacenar dos tipos de

MachineTranslatedbyGoogle

información que se puede unir, como una lista de palabras y sus significados, una lista de nombres
de personas y sus números favoritos, una lista de montañas y sus elevaciones, etc.

Un diccionario simple
Considere un juego con extraterrestres que pueden tener diferentes colores y valores de puntos.
Este diccionario simple almacena información sobre un extraterrestre en particular:

alien.py alien_0 = {'color': 'verde', 'puntos': 5}

imprimir (alien_0['color'])
(alien_0['color'])
imprimir(alien_0['puntos'])

El diccionario alien_0 almacena el color y el valor en puntos del alienígena. El último


dos líneas acceden y muestran esa información, como se muestra aquí:

verde
5

Como ocurre con la mayoría de los nuevos conceptos de programación, el uso de


diccionarios requiere práctica. Una vez que haya trabajado un poco con los diccionarios, pronto
verá la eficacia con la que pueden modelar situaciones del mundo real.

Trabajar con diccionarios


Un diccionario en Python es una colección de pares clave-valor. Cada clave está conectada a un
valor y puede usar una clave para acceder al valor asociado con esa clave.
El valor de una clave puede ser un número, una cadena, una lista o incluso otro diccionario.
De hecho, puede usar cualquier objeto que pueda crear en Python como un valor en un diccionario.

En Python, un diccionario está entre llaves, {}, con una serie de claves
pares de valores dentro de las llaves, como se muestra en el ejemplo anterior:

alien_0 = {'color': 'verde', 'puntos': 5}

Un par clave-valor es un conjunto de valores asociados entre sí. Cuando proporciona una
clave, Python devuelve el valor asociado con esa clave. Cada clave está conectada a su valor por
dos puntos, y los pares clave-valor individuales están separados por comas. Puede almacenar
tantos pares clave-valor como desee en un diccionario.

El diccionario más simple tiene exactamente un par clave-valor, como se muestra en esta
versión modificada del diccionario alien_0 :

alien_0 = {'color': 'verde'}

92 Capítulo 6

MachineTranslatedbyGoogle

Este diccionario almacena una pieza de información sobre alien_0, a saber, el


color del alienígena. La cadena 'color' es una clave en este diccionario y su valor
asociado es 'verde'.

Acceso a valores en un diccionario

Para obtener el valor asociado con una clave, ingrese el nombre del diccionario y luego
coloque la clave dentro de un conjunto de corchetes, como se muestra aquí:

alien.py alien_0 = {'color': 'verde'}


imprimir (alien_0['color'])
(alien_0['color'])

Esto devuelve el valor asociado con la clave 'color' del diccionario alien_0:

verde

Puede tener un número ilimitado de pares clave-valor en un diccionario.


Por ejemplo, aquí está el diccionario alien_0 original con dos pares clave-valor:

alien_0 = {'color': 'verde', 'puntos': 5}

Ahora puede acceder al color o al valor en puntos de alien_0. Si un jugador derriba


a este alienígena, puedes buscar cuántos puntos debería ganar usando un código como
este:

alien_0 = {'color': 'verde', 'puntos': 5}

u nuevos_puntos = alien_0['puntos']
alien_0['puntos']
v print(f"¡Acabas de ganar {nuevos_puntos} puntos!")

Una vez que se ha definido el diccionario, el código en u extrae el valor


asociado con los 'puntos' clave del diccionario.
dicci onario. Este valor se asigna luego a la
variable new_points. La línea en v imprime una declaración sobre cuántos puntos acaba
de ganar el jugador:

¡Acabas de ganar 5 puntos!

Si ejecuta este código cada vez que se derriba a un alienígena, se recuperará el


valor en puntos del alienígena.

Adición de nuevos pares clave-valor

Los diccionarios son estructuras dinámicas y puede agregar nuevos pares clave-valor a
un diccionario en cualquier momento. Por ejemplo, para agregar un nuevo par clave-
valor, daría el nombre del diccionario seguido de la nueva clave entre corchetes junto
con el nuevo valor.
Agreguemos dos nuevos elementos de información al diccionario alien_0 : las
coordenadas x e y del alienígena, que nos ayudarán a mostrar el alienígena en un

Diccionarios 93

MachineTranslatedbyGoogle

posición particular en la pantalla. Coloquemos al extraterrestre en el borde izquierdo de la


pantalla, 25 píxeles por debajo de la parte superior. Debido a que las coordenadas de la pantalla
generalmente comienzan en la esquina superior izquierda de la pantalla, colocaremos el
extraterrestre en el borde izquierdo de la pantalla configurando
configurando la coordenada x en 0 y 25 píxeles
desde la parte superior configurando su coordenada y en positivo 25, como se muestra aquí:

alien.py alien_0 = {'color': 'verde', 'puntos': 5}


imprimir (alien_0)

u alien_0['x_position'] = 0
v alien_0['posición_y'] = 25
imprimir (alien_0)

Comenzamos definiendo el mismo diccionario con el que hemos estado trabajando.


Luego imprimimos este diccionario, mostrando una instantánea de su información. en ti
agregamos un nuevo par clave-valor al diccionario: clave 'x_position' y valor 0.
Hacemos lo mismo para la clave 'y_position' en v. Cuando imprimimos el diccionario modificado,
vemos los dos pares clave-valor adicionales
adicionales::

{'color': 'verde', 'puntos': 5}


{'color': 'verde', 'puntos': 5, 'posición_y': 25, 'posición_x': 0}

La versión final del diccionario contiene cuatro pares clave-valor. Los dos originales
especifican el color y el valor del punto, y dos más especifican la posición del alienígena.

N ota A partir de Python 3.7, los diccionarios conservan el orden en que fueron definidos. Cuando imprima un
diccionario o recorra sus elementos, verá los elementos en el mismo orden en que se agregaron
al diccionario.

Comenzando con un diccionario vacío

A veces es conveniente, o incluso necesario, comenzar con un diccionario vacío y luego agregarle
cada elemento nuevo. Para comenzar a llenar un diccionario vacío, defina un diccionario con un
conjunto vacío de llaves y luego agregue cada par clave-valor en su propia línea. Por ejemplo, aquí
se explica cómo construir el diccionario alien_0 usando este enfoque:

alien.py extranjero_0 = {}

alien_0['color'] = 'verde'
alien_0['puntos'] = 5
imprimir (alien_0)

Aquí definimos un diccionario alien_0 vacío y luego le agregamos color y valores de


puntos. El resultado es el diccionario que hemos estado usando en ejemplos anteriores:

{'color': 'verde', 'puntos': 5}

94 Capítulo 6

MachineTranslatedbyGoogle

Por lo general, utilizará diccionarios vacíos al almacenar datos proporcionados por el usuario
en un diccionario o cuando escribe código que genera una gran cantidad de pares clave-valor
automáticamente.

Modificación de valores en un

diccionario Para modificar un valor en un diccionario, ingrese el nombre del diccionario con la
clave entre corchetes y luego el nuevo valor que desea asociar con esa clave. Por ejemplo,
considere un extraterrestre que cambia de verde a amarillo a medida que avanza el juego:

alien.py alien_0 = {'color': 'verde'}


print(f"El extraterrestre es {alien_0['color']}").

alien_0['color'] = 'amarillo'
print(f"El extraterrestre ahora es {alien_0['color']}").

Primero definimos un diccionario para alien_0 que contiene solo el color del alienígena;
luego cambiamos el valor asociado a la clave 'color' a 'amarillo'.

El resultado muestra que el alienígena ha cambiado de verde a amarillo:

El extraterrestre es verde.
El alienígena ahora es amarillo.

Para un ejemplo más interesante, sigamos la posición de un extraterrestre que


puede moverse a diferentes velocidades. Guardaremos un valor que represente la velocidad
actual del alienígena y luego lo usaremos para determinar qué tan lejos a la derecha debe
moverse el alienígena:

alien_0 = {'posición_x': 0, 'posición_y': 25, 'velocidad': 'media'}


print(f"Posición original: {alien_0['x_position']}")

# Mueve al alienígena a la derecha.


# Determine qué tan lejos mover al alienígena en función de su velocidad actual.
u if alien_0['velocidad'] == 'lento':
incremento_x = 1
elif alien_0['velocidad'] == 'medio':
incremento_x = 2
demás:
# Este debe ser un extraterrestre rapido.
incremento_x = 3

# La nueva posición es la posición anterior más el incremento.


v alien_0['x_position'] = alien_0['x_position'] + x_increment
print(f"Nueva posición: {alien_0['x_position']}")

Comenzamos definiendo
definiendo un extraterrestre con una posición x inicial y una posición y , y
una velocidad de 'media'. Hemos omitido el color y los valores de puntos para el

Diccionarios 95

MachineTranslatedbyGoogle

En aras de la simplicidad, pero este ejemplo funcionaría de la misma manera si también


incluyeras esos pares clave-valor. También imprimimos el valor original de x_position para
ver cuánto se mueve el alienígena hacia la
l a derecha.
En u, una cadena if-elif-else determina cuánto debe moverse el alienígena hacia la
derecha y asigna este valor a la variable x_increment. Si la velocidad del alienígena es 'lenta',
se mueve una unidad hacia la derecha; si la velocidad es 'media', se mueve dos unidades a la
derecha; y si es 'rápido', se mueve tres unidades a la derecha. Una vez que se ha calculado el
incremento, se suma al valor de x_position en v, y el resultado se almacena en x_position del
diccionario.
Debido a que este es un alienígena de velocidad media, su posición se desplaza dos unidades a la
derecha:

Posición x original: 0
Nueva posición x: 2

Esta técnica es genial: al cambiar un valor en el diccionario del alienígena, puedes


cambiar el comportamiento general del alienígena. Por ejemplo, para convertir este
extraterrestre
extraterrestre de velocidad media en un extraterrest
extraterrestre
re rápido, agregaría la línea:

alien_0['velocidad'] = 'rápido'

El bloque if-elif-
i f-elif-else
else asignaría un valor mayor a x_increment
la próxima vez que se ejecute el código.

Eliminación de pares clave-valor

Cuando ya no necesite una parte de la información almacenada en un diccionario, puede


usar la instrucción del para eliminar por completo un par clave-valor.
Todo lo que necesita es el nombre del diccionario y la clave que desea
retirar.

Por ejemplo, eliminemos la clave 'puntos' del diccionario alien_0 junto con su valor:

alien.py alien_0 = {'color': 'verde', 'puntos': 5}


imprimir (alien_0)

u del alien_0['puntos']
imprimir (alien_0)

La línea en u le dice a Python que elimine los 'puntos' clave del diccionario alien_0 y
que también elimine el valor asociado con esa clave. El resultado muestra que los 'puntos'
clave y su valor de 5 se eliminan del diccionario, pero el resto del diccionario no se ve
afectado:
{'color': 'verde', 'puntos': 5}
{'color verde'}

N ota Tenga en cuenta que el par clave-valor eliminado se elimina de forma permanente.

96 Capítulo 6

MachineTranslatedbyGoogle

Un diccionario de objetos similares

El ejemplo anterior implicó almacenar diferentes tipos de información sobre un objeto, un


extraterrestre en un juego. También puede usar un diccionario para almacenar un tipo de
información sobre muchos objetos. Por ejemplo, supongamos que desea encuestar a varias
personas y preguntarles cuál es su lenguaje de programación favorito. Un diccionario es útil para
almacenar los resultados de una encuesta simple, como esta:

idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}

Como puede ver, hemos dividido un diccionario más grande en varias líneas. Cada
key es el nombre de una persona que respondió a la encuesta, y cada valor es su elección
de idioma. Cuando sepa que necesitará más de una línea para definir un diccionario, presione
Intro después de la llave de apertura. Luego, sangra la línea siguiente un nivel (cuatro
espacios) y escribe el primer par clave-valor, seguido de una coma. A partir de este momento,
cuando presione Intro, su editor de texto debería sangrar automáticamente todos los pares clave-
valor subsiguientes para que coincidan con el primer par clave-valor.

Una vez que haya terminado de definir el diccionario, agregue una llave de cierre en una
nueva línea después del último par clave-valor y sangre un nivel para que se alinee con las
claves del diccionario. También es una buena práctica incluir una coma después del último par
clave-valor, de modo que esté listo para agregar un nuevo par clave-valor en la línea siguiente.

N ota La mayoría de los editores tienen alguna funcionalidad que lo ayuda a formatear listas extendidas y dic.
cionarios de manera similar a este ejemplo. También hay disponibles otras formas aceptables
de formatear diccionarios largos, por lo que es posible que vea un formato ligeramente diferente
en su editor o en otras fuentes.

Para usar este diccionario, dado el nombre de una persona que realizó la encuesta,
puede buscar fácilmente su idioma favorito:

favorito idiomas_favoritos = {
_idiomas.py 'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}
u idioma = idiomas_favoritos[ sarah
sarah ].title()
print(f"El idioma favorito de Sarah es {idioma}").

Para ver qué idioma eligió Sarah, solicitamos el valor en:

idiomas_favoritos['sarah']

Diccionarios 97

MachineTranslatedbyGoogle

Usamos esta sintaxis para extraer el idioma favorito de Sarah del diccionario en u y
asignarlo a la variable idioma. Crear una nueva variable aquí hace que la llamada print() sea
mucho más limpia . El resultado muestra el idioma favorito de Sarah:

El idioma favorito de Sarah es C.

Podría usar esta misma sintaxis con cualquier individuo representado en el diccionario.

Usando get() para acceder a los valores

El uso de claves entre corchetes para recuperar el valor que le interesa de un diccionario
puede causar un problema potencial: si la clave que solicita no existe, obtendrá un error.

Veamos qué sucede cuando pides el valor en puntos de un extraterrestre que no tiene
establecido un valor en puntos:

alien_no_points.py alien_0 = {'color': 'verde', 'velocidad': 'lento'}


imprimir(alien_0['puntos'])

Esto da como resultado un rastreo, que muestra un KeyError:

Rastreo (llamadas recientes más última):


Archivo "alien_no_points.py", línea 2, en <módulo>
imprimir(alien_0['puntos'])
KeyError: 'puntos'

Aprenderá más sobre cómo manejar errores como este en general en el Capítulo 10.
Para los diccionarios, específicamente, puede usar el método get() para establecer un valor
predeterminado que se devolverá si la clave solicitada no existe.
El método get() requiere una clave como primer argumento. Como segundo argumento
opcional, puede pasar el valor que se devolverá si la clave no
existir:

alien_0 = {'color': 'verde', 'velocidad': 'lento'}

point_value = alien_0.get('puntos', 'Sin valor de puntos asignado.')


imprimir (punto_valor)

Si los 'puntos' clave existen en el diccionario, obtendrá el valor correspondiente. Si no es


así, obtiene el valor predeterminado. En este caso, los puntos no existen y recibimos un mensaje
limpio en lugar de un error:
No se asigna ningún valor en puntos.

Si existe la posibilidad de que la clave que está solicitando no exista, considere


utilizando el método get() en lugar de la notación de corchetes.

98 Capítulo 6

MachineTranslatedbyGoogle

N ota Si omite el segundo argumento en la llamada a get() y la clave no existe, Python devolverá el
valor Ninguno. El valor especial Ninguno significa que "no existe ningún valor".
Esto no es un error: es un valor especial destinado a indicar la ausencia de un valor.
Verá más usos para Ninguno en el Capítulo 8.

Inténtalo tú mismo

6-1. Persona: use un diccionario para almacenar información sobre una persona que conoce.
Almacene su nombre, apellido, edad y la ciudad en la que vive. Debe
tener claves como nombre , apellido, edad y ciudad. Imprima cada pieza
de información almacenada en su diccionario.
6-2. Números favoritos: use un diccionario para almacenar los números favoritos de las personas.
Piensa en cinco nombres y utilízalos como claves en tu diccionario. Piense en un número favorito para
cada persona y guárdelo como un valor en su diccionario. Escriba el nombre de cada persona y su
número favorito. Para divertirse aún más, haga una encuesta a algunos amigos y obtenga algunos
datos reales para su programa.

6-3. Glosario: se puede usar un diccionario de Python para modelar un diccionario real.
Sin embargo, para evitar confusiones, llamémoslo glosario.

•Piense en cinco palabras de programación que haya aprendido en los capítulos anteriores.
Utilice estas palabras como claves en su glosario y almacene sus significados como valores.

•Imprima cada palabra y su significado como una salida con un formato ordenado. podrías
imprima la palabra seguida de dos puntos y luego su significado, o imprima la palabra en una
línea y luego imprima su significado con sangría en una segunda línea. Utilice el carácter de
nueva línea (\n) para insertar una línea en blanco entre cada par de palabra y significado en su
salida.

Bucle a través de un diccionario


Un solo diccionario de Python puede contener solo unos pocos pares clave-valor o millones
de pares. Debido a que un diccionario puede contener grandes cantidades de datos, Python le
permite recorrer un diccionario. Los diccionarios se pueden utilizar para almacenar información
de diversas formas; por lo tanto, existen varias formas diferentes de recorrerlos. Puede recorrer
todos los pares clave-valor de un diccionario, sus claves o sus valores.
Bucle a través de todos los pares clave-valor

Antes de explorar los diferentes enfoques de los bucles, consideremos un nuevo diccionario
diseñado para almacenar información sobre un usuario en un sitio web. Él

Diccionarios 99

MachineTranslatedbyGoogle

El siguiente diccionario almacenaría el nombre de usuario, el nombre y el apellido de


una persona:

usuario_0 = {
'usuario': 'efermi',
'primero': 'enrico',
'último': 'fermi',
}

Puede acceder a cualquier información individual sobre user_0 en función de lo


que ya aprendió en este capítulo. Pero, ¿y si quisieras ver todo lo almacenado en el
diccionario de este usuario? Para hacerlo, puede recorrer el diccionario usando un bucle
for :

usuario.py usuario_0 = {
'usuario': 'efermi',
'primero': 'enrico',
'último': 'fermi',
}

u para clave, valor en user_0.items():


v print(f"\nClave: {clave}")
w imprimir(f"Valor: {valor}")

Como se muestra en u, para escribir un bucle for para un diccionario, crea nombres
para las dos variables que contendrán la clave y el valor en cada par clave-valor.
Puede elegir los nombres que desee para estas dos variables. Este código funcionaría
igual de bien si hubiera usado abreviaturas para los nombres de las variables, como esta:

para k, v en user_0.items()

La segunda mitad de la instrucción for en u incluye el nombre del diccionario


seguido del método items(), que devuelve una lista de pares clave-valor. El bucle for luego
asigna cada uno de estos pares a las dos variables provistas. En el ejemplo anterior,
usamos las variables para imprimir cada clave v, seguida del valor asociado w. El "\n" en la
primera llamada print() asegura que se inserte una línea en blanco antes de cada par clave-
valor en la salida:

Clave: última
valor: fermi

Clave: primero
Valor: Enrique
Clave: nombre de usuario

Valor: efermi

100 Capítulo 6

MachineTranslatedbyGoogle

Recorrer todos los pares clave-valor funciona particularmente bien para la dicción.
arios como el ejemplo de favorite_languages.py en la página 97, que almacena el
mismo tipo de información para muchas claves diferentes. Si recorre el diccionario de
idiomas_favoritos , obtiene el nombre de cada persona en el diccionario y su lenguaje
de programación favorito. Debido a que las claves siempre se refieren al nombre de una
persona y el valor siempre es un idioma, usaremos las variables nombre e idioma en el
bucle en lugar de clave y valor. Esto hará que sea más fácil seguir lo que sucede dentro
del ciclo:

favorito idiomas_favoritos = {
idiomas_favoritos
_idiomas.py 'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}

u para nombre, idioma en favoritos_idiomas.elementos():


favoritos_idiomas.elementos():
v print(f"{nombre.título()} El idioma favorito de {idioma.título()}.")
{idioma.título()}.")

El código en u le dice a Python que recorra cada par clave-valor en el diccionario.


A medida que avanza en cada par, la clave se asigna al nombre de la variable y el valor
se asigna al idioma de la variable. Estos nombres descriptivos hacen que sea mucho
más fácil ver lo que está haciendo la llamada print() en v.
Ahora, en solo unas pocas líneas de código, podemos mostrar toda la información
de la encuesta:

El lenguaje favorito de Jen es Python.


El idioma favorito de Sarah es C.
El idioma favorito de Edward es Ruby.
El lenguaje favorito de Phil es Python.

Este tipo de bucle funcionaría igual de bien si nuestro diccionario almacenara los

resultados de encuestar a mil o incluso a un millón de personas.

Recorriendo todas las claves de un diccionario

El método keys() es útil cuando no necesita trabajar con todos los valores en un
diccionario. Recorramos el diccionario de idiomas favoritos e imprimamos los nombres
de todos los que respondieron la encuesta:

idiomas_favoritos = {
idiomas_favoritos
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
phil : pitón
}

u para el nombre en favoritos_idiomas.keys():


imprimir (nombre. título ())

Diccionarios 101

MachineTranslatedbyGoogle

La línea en u le dice a Python que extraiga todas las claves del diccionario
idiomas_favoritos y las asigne una a la vez al nombre de la variable. El resultado muestra
los nombres de todos los que respondieron la encuesta:

Sólo
Sara
Eduardo
phil

Recorrer las teclas es en realidad el comportamiento predeterminado cuando se recorre


un diccionario, por lo que este código tendría exactamente el mismo resultado si
escribió . . .

para nombre en idiomas_favoritos:

en vez de . ..

para el nombre en favoritos_idiomas.keys():

Puede optar por usar el método keys() explícitamente si hace que su código sea más fácil
de leer, o puede omitirlo si lo desea.
Puede acceder al valor asociado con cualquier clave que le interese dentro del bucle
utilizando la clave actual. Imprimamos un mensaje para un par de amigos sobre los idiomas
que eligieron. Recorreremos los nombres en el diccionario como lo hicimos anteriormente,
pero cuando el nombre coincida con uno de nuestros amigos, mostraremos un mensaje sobre
su idioma favorito:

idiomas_favoritos
idiomas_favoritos = {
--recorte--

amigos = ['phil', 'sarah']


para el nombre en favoritos_idiomas.keys():
imprimir (nombre.
(nombre. título ())

v si nombre en amigos:
en idioma = idiomas_favoritos[nomb
idiomas_favoritos[nombre].título()
re].título()
print(f"\t{nombre.título()},
print(f"\t{nombre.título()}, ¡veo que amas {idioma}!")

En u hacemos una lista de amigos a los que queremos imprimir un mensaje. En el interior
el bucle, imprimimos el nombre de cada persona. Luego en v verificamos si el nombre
con el que estamos trabajando está en la lista de amigos. Si es así, determinamos el
idioma favorito de la persona utilizando el nombre del diccionario y el valor actual de
nombre como clave w. Luego imprimimos un saludo especial, que incluye una referencia al
idioma de su elección.
El nombre de todos está impreso, pero nuestros amigos reciben un mensaje especial:

Hola Jen.
Hola Sarah.
¡Sarah, veo que amas a C!
Hola Eduardo.

102 Capítulo 6

MachineTranslatedbyGoogle

hola phil
¡Phil, veo que te encanta Python!

También puede usar el método keys() para averiguar si se encuestó a una persona en
particular. Esta vez, averigüemos si Erin participó en la encuesta:

idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}

u si 'erin' no está en favorite_languages.keys():


print("Erin, ¡haz nuestra encuesta!")

El método keys() no es solo para bucles: en realidad devuelve una lista de todos
las teclas, y la línea en u simplemente verifica si 'erin' está en esta lista. Como no lo es,
se imprime un mensaje invitándola a participar en la encuesta:

¡Erin, por favor toma nuestra encuesta!

Recorriendo las teclas de un diccionario en un orden particular

A partir de Python 3.7, recorrer un diccionario devuelve los elementos en el mismo orden en
que se insertaron. A veces, sin embargo, querrá recorrer un diccionario en un orden diferente.

Una forma de hacer esto es ordenar las claves a medida que se devuelven en el bucle for .
Puede usar la función sorted() para obtener una copia de las claves en orden:

idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}

para el nombre ordenado (favorite_lan


(favorite_languages.keys(
guages.keys()):)):
print(f"{nombre.título()},
print(f"{nombre.título()}, gracias por participar en la encuesta").

Esta declaración for es como otras declaraciones for excepto que hemos
envuelto la función sorted() alrededor del método dictionary.keys() . Esto le dice a Python
que enumere todas las claves en el diccionario
di ccionario y ordene esa lista antes de recorrerla. El
resultado muestra a todos los que respondieron la encuesta, con los nombres mostrados en
orden:

Edward, gracias por participar en la encuesta.


Jen, gracias por participar en la encuesta.
Phil, gracias por participar en la encuesta.
Sara, gracias por participar en la encuesta.

Diccionarios 103

MachineTranslatedbyGoogle

Recorriendo todos los valores en un diccionario

Si está interesado principalmente en los valores que contiene un diccionario, puede usar
el método de valores () para devolver una lista de valores sin ninguna clave.
Por ejemplo, digamos que simplemente queremos una lista de todos los idiomas elegidos
en nuestra encuesta de idiomas de programación sin el nombre de la persona que eligió cada
idioma:

idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}

print("Se han mencionado los siguientes idiomas:")


para idioma en favoritos_idiomas.valores():
favoritos_idiomas.valores():
imprimir(idioma.título())

La declaración for aquí extrae cada valor del diccionario y lo asigna a la variable idioma.
Cuando se imprimen estos valores, obtenemos una lista de todos los idiomas elegidos:

Se han mencionado los siguientes idiomas:


Pitón
C

Pitón
Rubí

Este enfoque extrae todos los valores del diccionario sin verificar
para repeticiones. Eso podría funcionar bien con una pequeña cantidad de valores, pero en
una encuesta con una gran cantidad de encuestados, esto daría como resultado una lista muy
repetitiva. Para ver cada idioma elegido sin repetición, podemos usar un conjunto.
Un conjunto es una colección en la que cada elemento debe ser único:

idiomas_favoritos = {
--recorte--
}

print("Se han mencionado los siguientes idiomas:")


u para idioma en conjunto (favorite_languages.values()):
(favorite_languages.values()):
imprimir(idioma.título())

Cuando ajusta set() alrededor de una lista que contiene elementos duplicados, Python
identifica los elementos únicos en la lista y crea un conjunto a partir de esos elementos. en ti
usamos set() para extraer los idiomas únicos en favorite_languages.values().

El resultado es una lista no repetitiva de idiomas que se han mencionado


por personas que tomaron la encuesta:

Se han mencionado los siguientes idiomas:


Pitón

104 Capítulo 6

MachineTranslatedbyGoogle

Rubí

A medida que continúe aprendiendo sobre Python, a menudo encontrará una característica integrada
del lenguaje que lo ayudará a hacer exactamente lo que desea con sus datos.

N ota Puede construir un conjunto directamente usando llaves y separando los elementos con comas:

>>> idiomas = {'python', 'ruby', 'python', 'c'}


>>> idiomas
{'rubí', 'pitón', 'c'

Es fácil confundir conjuntos con diccionarios porque ambos están entre llaves.
Cuando ve llaves pero no pares clave-valor, probablemente esté viendo un conjunto. A diferencia de las
listas y los diccionarios, los conjuntos no conservan elementos en ningún orden específico.

Inténtalo tú mismo

6-4. Glosario 2: ahora que sabe cómo recorrer un diccionario, limpie el código del ejercicio
6-3 (página 99) reemplazando su serie de print()
llamadas con un bucle que recorre las claves y los valores del diccionario. Cuando
esté seguro de que su ciclo funciona, agregue cinco términos más de Python a su glosario.
Cuando vuelva a ejecutar su programa, estas nuevas palabras y significados deberían
incluirse automáticamente en la salida.

6-5. Ríos: haga un diccionario que contenga tres ríos principales y el país por el que
pasa cada río. Un par clave-valor podría ser 'nilo': 'egipto'.

•Use un bucle para imprimir una oración sobre cada río, como El Nilo atraviesa Egipto.

•Utilice un bucle para imprimir el nombre de cada río incluido en el diccionario.

•Utilice un bucle para imprimir el nombre de cada país incluido en el diccionario.

6-6. Sondeo: use el código en favorite_language


favorite_languages.py
s.py (página 97).

•Haga una lista de las personas que deberían participar en la encuesta de idiomas favoritos.
Incluye algunos nombres que ya estén en el diccionario y otros que no.

• Recorra la lista de personas que deberían realizar la encuesta. Si ya han realizado


la encuesta, imprima un mensaje agradeciéndoles por responder.
r esponder.
Si aún no han realizado la encuesta, imprima un mensaje invitándoles a realizar la
encuesta.
Diccionarios 105

MachineTranslatedbyGoogle

Anidamiento

A veces querrá almacenar varios diccionarios en una lista o una lista de elementos como valor
en un diccionario. Esto se llama anidamiento. Puede anidar diccionarios dentro de una lista, una
lista de elementos dentro de un diccionario o incluso un diccionario dentro de otro diccionario. El
anidamiento es una característica poderosa, como lo demostrarán los siguientes ejemplos.

Una lista de diccionarios

El diccionario alien_0 contiene una variedad de información sobre un extraterrestre, pero no


tiene espacio para almacenar información sobre un segundo extraterrestre, y mucho menos una
pantalla llena de extraterrestres. ¿Cómo puedes manejar una flota de extraterrestres? Una forma
es hacer una lista de extraterrestres en la que cada extraterrestre sea un diccionario de información
sobre ese extraterrestre. Por ejemplo, el siguiente código crea una lista de tres extraterrestres:

extraterrestres.py alien_0 = {'color': 'verde', 'puntos': 5}


alien_1 = {'color': 'amarillo', 'puntos': 10}
alien_2 = {'color': 'rojo', 'puntos': 15}

u alienígenas = [alien_0, alien_1, alien_2]

para alienígena en alienígenas:

imprimir (extranjero)

Primero creamos tres diccionarios, cada uno representando un extraterrestre diferente.


En u almacenamos cada uno de estos diccionarios en una lista llamada extranjeros. Finalmente,
recorremos la lista e imprimimos cada extraterrestre:

{'color': 'verde', 'puntos': 5} {'color': 'amarillo',


'puntos': 10} {'color': 'rojo', 'puntos': 15}

Un ejemplo más realista involucraría a más de tres alienígenas con un código que genera
automáticamente cada alienígena. En el siguiente ejemplo, usamos range() para crear una flota
de 30 alienígenas:

# Haga una lista vacía para almacenar extraterrestres.


extraterrestres = []

# Haz 30 alienígenas verdes.


u para alien_number en el rango (30):
v new_alien = {'color': 'verde', 'puntos': 5, 'velocidad': 'lento'}
w alienígenas.append(nuevo_
alienígenas.append(nuevo_alienígena)
alienígena)
# Muestra los primeros 5 alienígenas.

x para extranjero en extranjeros [: 5]:


imprimir (extranjero)
imprimir("...")

# Muestra cuántos extraterrestres se han creado.


y print(f"Número total de extranjeros: {len(extranjeros)}")

106 Capítulo 6

MachineTranslatedbyGoogle

Este ejemplo comienza con una lista vacía para contener todos los alienígenas que se
crearán. En u range() devuelve una serie de números, que solo le dice a Python cuántas veces
queremos que se repita el bucle. Cada vez que se ejecuta el bucle, creamos un nuevo alienígena
v y luego agregamos cada nuevo alienígena a la lista de alienígenas w. En x usamos un segmento
para imprimir los primeros cinco alienígenas, y luego en y imprimimos la longitud de la lista para
demostrar que en realidad hemos generado la flota completa de 30 alienígenas:

{'velocidad':': 'lento', 'color': 'verde', 'puntos': 5} {'velocidad'


{'velocidad {'velocidad':: 'lento',
'color': 'verde', 'puntos': 5} {'velocidad' : 'lento', 'color': 'verde',
'puntos': 5} {'velocidad': 'lento', 'color': 'verde', 'puntos': 5} {'velocidad
{'velocidad':':
'lento' , 'color': 'verde', 'puntos': 5}

...

Número total de extranjeros: 30

Todos estos alienígenas tienen las mismas características, pero Python considera a
cada uno un objeto separado, lo que nos permite modificar cada alienígena individualmente.

¿Cómo podrías trabajar con un grupo de extraterrestres como este? Imagina que un aspecto
de un juego tiene algunos extraterrestres que cambian de color y se mueven más rápido a medida
que avanza el juego. Cuando sea el momento de cambiar los colores, podemos usar un bucle for y
una instrucción if para cambiar el color de los alienígenas.
alienígenas. Por ejemplo, para cambiar los tres primeros
extraterrestres a extraterrestres amarillos de velocidad media que valen 10 puntos cada uno,
extraterrestres
podríamos hacer esto:

# Haga una lista vacía para almacenar extraterrestres.


extraterrestres = []

# Haz 30 alienígenas verdes.


para alien_number en rango (30):

new_alien = {'color': 'verde', 'puntos': 5, 'velocidad'


'velocidad':: 'lento'}
alienígenas.append(nuevo_alienígena)

para extranjero en extranjeros[:3]:


if alien['color'] == 'verde':
extranjero['color']
extranjero['color'] = 'amarillo'
extranjero['velocidad']
extranjero['velocidad'] = 'medio'
extranjero['puntos']
extranjero['puntos'] = 10

# Muestra los primeros 5 alienígenas.


para extranjero en extranjeros[:5]:
imprimir (extranjero)
imprimir( ... )

Debido a que queremos modificar los primeros tres alienígenas, recorremos


recorremos un segmento
que incluye solo los primeros tres alienígenas. Todos los extraterrestres
extraterrestres son verdes ahora, pero ese
no será siempre el caso, por lo que escribimos una declaración if para asegurarnos

Diccionarios 107

MachineTranslatedbyGoogle

solo estamos modificando alienígenas verdes. Si el alienígena es verde, cambiamos el color


a 'amarillo', la velocidad a 'media' y el valor de puntos a 10, como se muestra en el siguiente
resultado:

{'velocidad': 'medio', 'color': 'amarillo', 'puntos': 10} {'velocidad':


'medio', 'color': 'amarillo', 'puntos': 10} {'velocidad' : 'medio', 'color':

'amarillo', 'puntos': 10} {'velocidad': 'lento', 'color': 'verde', 'puntos':


5} {'velocidad': 'lento' , 'color': 'verde', 'puntos': 5}

...

Puede expandir este ciclo agregando un bloque elif que convierte a los alienígenas
amarillos en rojos, que se mueven rápidamente, con un valor de 15 puntos cada uno. Sin
volver a mostrar todo el programa, ese ciclo se vería así:

para extranjero en extranjeros[0:3]:


if alien['color'] == 'verde':
extranjero['color'] = 'amarillo'
extranjero['velocidad'] = 'medio'
extranjero['puntos'] = 10
elif alien['color'] == 'amarillo':
extranjero['color'] = 'rojo'
extranjero['velocidad']
extranjero['velocidad'] = 'rápido'
extranjero['puntos'] = 15

Es común almacenar varios diccionarios en una lista cuando cada dic


tionary contiene muchos tipos de información sobre un objeto. Por ejemplo, puede crear un
diccionario para cada usuario en un sitio web, como hicimos en user.py
en la página 100 y almacene los diccionarios individuales en una lista llamada usuarios.
Todos los diccionarios de la lista deben tener una estructura idéntica para que pueda
recorrer la lista y trabajar con cada objeto de diccionario de la misma manera.

Una lista en un diccionario

En lugar de poner un diccionario dentro de una lista, a veces es útil poner una lista
dentro de un diccionario. Por ejemplo, considere cómo podría describir una pizza que
alguien está ordenando. Si tuviera que usar solo una lista, todo lo que realmente podría
almacenar es una lista de los ingredientes de la pizza. Con un diccionario, una lista de
los mejores pings puede ser solo un aspecto de la pizza que estás describiendo.
En el siguiente ejemplo, se almacenan dos tipos de información para cada
pizza: un tipo de corteza y una lista de ingredientes. La lista de toppings es un valor
asociado a la clave 'toppings'. Para utilizar los elementos de la lista, le damos el nombre
del diccionario y la tecla 'toppings', como haríamos con cualquier valor del diccionario. En
lugar de devolver un solo valor, obtenemos una lista de ingredientes:

pizza.py # Almacene información sobre una pizza que se está ordenando.


en pizza = {
'corteza': 'gruesa',
'coberturas': ['champiñones', 'queso extra'],
}

108 Capítulo 6

MachineTranslatedbyGoogle

# Resume el pedido.
"
v print(f"Pediste una pizza de {pizza['crust']}-crust "con los
siguientes ingredientes:")

w para aderezo en pizza['toppings']:


imprimir("\t" + cobertura)

Comenzamos en u con un diccionario que contiene información sobre


una pizza que se ha pedido. Una clave en el diccionario es 'crust', y el valor
asociado es la cadena 'thick'. La siguiente clave, 'ingredientes', tiene una lista
como valor que almacena todos los ingredientes solicitados. En v resumimos el
pedido antes de construir la pizza. Cuando necesite dividir una línea
l ínea larga en
una llamada print() , elija un punto apropiado en el que dividir la línea que se
está imprimiendo y finalice la línea con comillas. Aplique sangría a la línea
siguiente, agregue una comilla de apertura y continúe la l a cadena. Python
combinará automáticamente todas las cadenas que encuentre dentro de los
paréntesis. Para imprimir los toppings, escribimos un bucle for w. Para acceder
a la lista de ingredientes, usamos la tecla 'toppings' y Python toma la lista
li sta de
ingredientes del diccionario.
El siguiente resultado resume la pizza que planeamos construir:

Pediste una pizza de masa gruesa con los siguientes ingredientes:


champiñones
extra queso

Puede anidar una lista dentro de un diccionario cada vez que desee
asociar más de un valor con una sola clave en un diccionario. En el ejemplo
anterior de los lenguajes de programación favoritos, si tuviéramos que
almacenar las respuestas de cada persona en una lista, las personas podrían
elegir más de un lenguaje favorito. Cuando recorremos el diccionario, el valor
asociado con cada persona sería una lista de idiomas en lugar de un solo idioma.
Dentro del bucle for del diccionario
di ccionario , usamos otro bucle for para recorrer la
lista de idiomas asociados con cada persona:

favorito u idiomas_favoritos = {
_idiomas.py 'jen': ['pitón', 'rubí'],
'sara': ['c'],
'eduardo': ['rubí', 'ir'],
'phil': ['pitón', 'haskell'],
}

v para nombre, idiomas en favoritos_idiomas.elementos():


Los idiomas favoritos de print(f"\n{name.title()} son:")
w para idioma en idiomas:
imprimir(f"\t{idioma.título()}")

Como puede ver en u, el valor asociado con cada nombre ahora es


una lista. Note que algunas personas tienen un idioma favorito y otras tienen

Diccionarios 109

MachineTranslatedbyGoogle

múltiples favoritos. Cuando recorremos el diccionario en v, usamos el nombre de la


variable languages para contener cada valor del diccionario, porque sabemos que cada
valor será una lista. Dentro del bucle del diccionario principal, usamos otro bucle for w
para recorrer la lista de idiomas favoritos de cada persona.
Ahora cada persona puede enumerar tantos idiomas favoritos como quiera:

Los idiomas favoritos de Jen son:


Pitón
Rubí

Los idiomas favoritos de Sarah son:


C

Los idiomas favoritos de Phil son:


Pitón
Haskell

Los idiomas favoritos de Edward son:


Rubí
Vamos

Para refinar aún más este programa, puede incluir una sentencia if al
comienzo del ciclo for del diccionario para ver si cada persona tiene más de un
idioma favorito examinando el valor de len(idiomas). Si una persona tiene más de
un favorito, el resultado sería el mismo. Si la persona solo tiene un idioma favorito,
puede cambiar la redacción para reflejar eso. Por ejemplo, podría decir que el idioma
favorito de Sarah es C.

N ota No debe anidar listas y diccionarios demasiado profundamente. Si está anidando elementos mucho más
profundamente que lo que ve en los ejemplos anteriores o está trabajando con el código de otra
persona con niveles significativos de anidamiento, lo más probable es que exista una forma más
sencilla de resolver el problema.

Un diccionario en un diccionario

Puede anidar un diccionario dentro de otro diccionario, pero su código puede


complicarse rápidamente cuando lo hace. Por ejemplo, si tiene varios usuarios para
un sitio web, cada uno con un nombre de usuario único, puede usar los nombres de
usuario como claves en un diccionario. A continuación, puede almacenar información
sobre cada usuario mediante el uso de un diccionario como el valor asociado con su
nombre de usuario. En la siguiente lista, almacenamos tres datos sobre cada usuario:
su nombre, apellido y ubicación. Accederemos a esta información recorriendo los
nombres de usuario y el diccionario de información asociado con cada nombre de
usuario:

muchos_usuarios.py usuarios = {
'aeinstein': {
'primero': 'alberto',

110 Capítulo 6

MachineTranslatedbyGoogle

'último': 'einstein',
'ubicación': 'princeton',
},

'mcurio': {
'primero': 'marie',
'último': 'curio',
'ubicación': 'parís',
},

u para nombre de usuario, user_info en users.items():


v print(f"\nNombre de usuario: {nombre de usuario}")
w nombre_completo = f"{información_usuario['primero']}
f"{información_usuario['primero']} {información_usuario['último']}"
{información_usuario['último']}"
ubicación = info_usuario['ubicación']

x print(f"\tNombre completo: {nombre_completo.título()}")


print(f"\tUbicación: {ubicación.título()}")

Primero definimos un diccionario llamado usuarios con dos claves: una para los
nombres de usuario 'aeinstein' y 'mcurie'. El valor asociado con cada clave es un
diccionario que incluye el nombre, el apellido y la ubicación de cada usuario. en ti
recorremos el diccionario de usuarios . Python asigna cada clave a la variable nombre
de usuario, y el diccionario asociado con cada nombre de usuario se asigna a la variable
user_info. Una vez dentro del bucle del diccionario principal, imprimimos el nombre de
usuario en v.
En w comenzamos a acceder al diccionario interno. La variable user_info, que
contiene el diccionario de información del usuario, tiene tres claves: 'primero', 'último'
y 'ubicación'. Usamos cada clave para generar un nombre completo y una ubicación
bien formateados para cada persona, y luego imprimimos un resumen de lo que
sabemos sobre cada usuario x:

Nombre de usuario: einstein


Nombre completo: Albert Einstein
Ubicación: Princeton

Nombre de usuario: mcurie


Nombre completo: Marie Curie
Ubicación: París

Observe que la estructura del diccionario de cada usuario es idéntica. Aunque


Python no lo requiere, esta estructura facilita el trabajo con los diccionarios anidados.
Si el diccionario de cada usuario tuviera claves diferentes, el código dentro del ciclo
for sería más complicado.

Diccionarios 111

MachineTranslatedbyGoogle

Inténtalo tú mismo

6-7. Gente: comience con el programa que escribió para el ejercicio 6-1 (página 99).
Cree dos nuevos diccionarios que representen a diferentes personas y almacene los tres

diccionarios en una lista llamada personas. Recorra su lista de personas. Mientras recorre
la lista, imprima todo lo que sabe sobre cada persona.

6-8. Mascotas: haga varios diccionarios, donde cada diccionario represente una mascota
diferente. En cada diccionario, incluya el tipo de animal y el nombre del dueño.
Guarde estos diccionarios en una lista llamada mascotas. A continuación, recorra su lista y,
mientras lo hace, imprima todo lo que sepa sobre cada mascota.

6-9. Lugares favoritos: haga un diccionario llamado lugares_favoritos. Piense en tres


nombres para usar como claves en el diccionario y almacene de uno a tres lugares favoritos
para cada persona. Para hacer este ejercicio un poco más interesante, pídales a algunos
amigos que mencionen algunos de sus lugares favoritos. Recorre el diccionario e imprime el
nombre de cada persona y sus lugares favoritos.

6-10. Números favoritos: Modifique su programa del Ejercicio 6-2 (página 99) para que
cada persona pueda tener más de un número favorito. Luego escriba el nombre de cada
persona junto con sus números favoritos.

6-11. Ciudades: Haz un diccionario llamado ciudades. Usa los nombres de tres ciudades
como claves en tu diccionario. Cree un diccionario de información sobre cada ciudad e incluya
el país en el que se encuentra la ciudad, su población aproximada y un dato sobre esa ciudad.
Las claves para el diccionario de cada ciudad deben ser algo como país, población y hecho.
Imprime el nombre de cada ciudad y toda la información que tengas guardada sobre ella.

6-12. Extensiones: ahora estamos trabajando con ejemplos que son lo suficientemente
complejos como para que puedan extenderse de varias maneras. Utilice uno de los programas
de ejemplo de este capítulo y amplíelo agregando nuevas claves y valores, cambiando el
contexto del programa o mejorando el formato de la salida.

Resumen
En este capítulo aprendió cómo definir un diccionario y cómo trabajar con la
información almacenada en un diccionario. Aprendió cómo acceder y modificar
elementos individuales
individuales en un diccionario y cómo recorrer toda la información en un
diccionario. Aprendió a recorrer los pares clave-valor de un diccionario, sus claves y
sus valores. También aprendió cómo anidar varios diccionarios en una lista, anidar
listas en un diccionario y anidar un diccionario dentro de un diccionario.

En el próximo capítulo aprenderá sobre los bucles while y cómo aceptar


entradas de personas que están usando sus programas. Este será un capítulo
emocionante, porque aprenderá a hacer que todos sus programas sean
interactivos: podrán responder a las entradas del usuario.

112 Capítulo 6

MachineTranslatedbyGoogle

7
Entrada de usuario y bucles mientras

La mayoría de los programas están escritos para resolver el problema de

un usuario final. Para hacerlo, generalmente necesita obtener cierta

información del usuario. Para un ejemplo simple, digamos que alguien quiere

saber si tiene la edad suficiente para votar. Si escribe un programa para responder

a esta pregunta, necesita saber la edad del usuario antes de poder dar una respuesta. El
programa deberá pedirle al usuario que ingrese, o ingrese, su edad; una vez que el programa
tiene esta entrada, puede compararla con la edad de votación para determinar si el usuario
tiene la edad suficiente y luego informar el resultado.

En este capítulo, aprenderá cómo aceptar la entrada del usuario para que su programa
pueda trabajar con ella. Cuando su programa necesite un nombre, podrá pedirle al usuario
un nombre. Cuando su programa necesite una lista de nombres, podrá solicitar al usuario
una serie de nombres. Para ello, utilizará la función input() .

También aprenderá cómo hacer que los programas sigan ejecutándose todo el tiempo
que los usuarios quieran, para que puedan ingresar toda la información que necesiten;
entonces, su programa puede trabajar con esa información. Utilizará el ciclo while de Python
para mantener los programas en ejecución siempre que se cumplan ciertas condiciones.

MachineTranslatedbyGoogle

Con la capacidad de trabajar con la entrada del usuario y la capacidad de controlar cuánto
tiempo se ejecutan sus programas, podrá escribir programas totalmente interactivos.

Cómo funciona la función input()


La función input() pausa su programa y espera a que el usuario ingrese algún texto. Una vez que
Python recibe la entrada del usuario, asigna esa entrada a una variable para que sea conveniente
para usted trabajar con ella.
Por ejemplo, el siguiente programa le pide al usuario que ingrese algún texto, luego muestra
ese mensaje al usuario:

loro.py mensaje = entrada ("Dime algo y te lo repetiré:")


imprimir (mensaje)

La función input() toma un argumento: el mensaje o las instrucciones que queremos mostrar al
usuario para que sepa qué hacer. En este ejemplo, cuando Python ejecuta la primera línea, el usuario
ve el mensaje Dime algo y te lo repetiré: . El programa espera mientras el usuario ingresa su respuesta
y continúa después de que el usuario presiona enter. La respuesta se asigna al mensaje variable, luego
print (mensaje) muestra la entrada al usuario:

Dime algo y te lo repetiré: ¡Hola a todos!


¡Hola a todos!

N ota Sublime Text y muchos otros editores no ejecutan programas que solicitan al usuario que ingrese información.
Puede usar estos editores para escribir programas que soliciten una entrada, pero deberá ejecutar estos
programas desde una terminal. Consulte “Ejecución de programas de Python desde una terminal” en la
página 12.

Escribir indicaciones claras


Cada vez que utilice la función input() , debe incluir un aviso claro y fácil de seguir que le diga al
usuario exactamente qué tipo de información está buscando. Cualquier declaración que le diga al
usuario qué ingresar debería funcionar. Por ejemplo:

saludador.py nombre = entrada ("Por favor ingrese su nombre:")


print(f"\nHola, {nombre}!")

Agregue un espacio al final de sus indicaciones (después de los dos puntos en el ejemplo
anterior) para separar la indicación de la respuesta del usuario y dejarle claro a su usuario dónde
ingresar su texto. Por ejemplo:

Por favor, introduzca su nombre: Eric


¡Hola, Eric!

114 Capítulo 7

MachineTranslatedbyGoogle

A veces, querrá escribir un aviso que sea más largo que una línea.
Por ejemplo, es posible que desee decirle al usuario por qué está solicitando cierta entrada.
Puede asignar su aviso a una variable y pasar esa variable a la función input() . Esto le permite
construir su solicitud en varias líneas, luego escribir una declaración de entrada () limpia .

saludador.py prompt = "Si nos dice quién es, podemos personalizar los mensajes que ve".
"
prompt += "\n¿Cuál es tu nombre?

nombre = entrada (solicitud)


print(f"\nHola, {nombre}!")

Este ejemplo muestra una forma de construir una cadena de varias líneas. la primera línea
asigna la primera parte del mensaje a la variable prompt. En la segunda línea, el operador +=
toma la cadena que se asignó a prompt y agrega la nueva cadena al final.

El mensaje ahora ocupa dos líneas, nuevamente con un espacio después del signo de interrogación
para mayor claridad:

Si nos dices quién eres, podemos personalizar los mensajes que ves.
¿Cuál es tu primer nombre? eric

¡Hola, Eric!

Uso de int() para aceptar entradas numéricas

Cuando usa la función input() , Python interpreta todo lo que el usuario ingresa como una
cadena. Considere la siguiente sesión de interpretación, que solicita la edad del usuario:

>>> edad = entrada ("¿Cuántos años tienes?")

¿Cuantos años tienes? 21


>>> edad
'21'

El usuario ingresa el número 21, pero cuando le preguntamos a Python por el valor de la
edad, devuelve '21', la representación de cadena del valor numérico ingresado.
Sabemos que Python interpretó la entrada como una cadena porque el número ahora está entre
comillas. Si todo lo que quiere hacer es imprimir la entrada, esto funciona bien. Pero si intenta usar
la entrada como un número, obtendrá un error:

>>> edad = entrada ("¿Cuántos años tienes?")


¿Cuantos años tienes? 21
tu >>> edad >= 18

Rastreo (llamadas recientes más última):


Archivo "<stdin>", línea 1, en <módulo> v
TypeError: tipos no ordenados: str() >= int()

Entrada de usuario y bucles while 115

MachineTranslatedbyGoogle

Cuando intenta usar la entrada para hacer una comparación numérica u, Python
produce un error porque no puede comparar una cadena con un número entero: la
cadena '21' asignada a la edad no se puede comparar con el valor numérico 18 v .
Podemos resolver este problema usando la función int() , que le dice a Python
que trate la entrada como un valor numérico. La función int() convierte una
representación de cadena de un número en una representación numérica, como se
muestra aquí:

>>> edad = entrada ("¿Cuántos años tienes?")


¿Cuantos años tienes? 21
u >>> edad = int(edad)
>>> edad >= 18
Verdadero

En este ejemplo, cuando ingresamos 21 en el indicador, Python interpreta el número


como una cadena, pero luego el valor se convierte en una representación numérica
mediante int() u. Ahora Python puede ejecutar la prueba condicional: compara la edad
(que ahora representa el valor numérico 21) y 18 para ver si la edad es mayor o igual a
18. Esta prueba se evalúa como Verdadero.
¿Cómo se usa la función int() en un programa real? Considere un programa que
determina si las personas son lo suficientemente altas como para subirse a una
montaña rusa:

montaña rusa.py altura = entrada ("¿Qué altura tienes, en pulgadas?")


altura = int(altura)

si altura >= 48:


print("\nEres lo suficientemente alto para montar!")
demás:

print("\nPodrás montar cuando seas un poco mayor.")

El programa puede comparar la altura con 48 porque altura = int(altura)


convierte el valor de entrada en una representación numérica antes de realizar la
comparación. Si el número ingresado es mayor o igual a 48, le decimos al usuario que
es lo suficientemente alto:

¿Cuánto mides, en pulgadas? 71

¡Eres lo suficientemente alto para montar!

Cuando usa entradas numéricas para hacer cálculos y comparaciones,


asegúrese de convertir primero el valor de entrada a una representación numérica.
El operador de módulo

Una herramienta útil para trabajar con información numérica es el operador módulo (%),
que divide un número entre otro número y devuelve el resto:

>>> 4 % 3
1

116 Capítulo 7

MachineTranslatedbyGoogle

>>> 5 % 3

2 >>> 6 % 3

0 >>> 7 % 3
1

El operador módulo no te dice cuántas veces cabe un número en otro; simplemente te


dice cuál es el resto.
Cuando un número es divisible por otro número, el resto es 0, por lo que el operador
módulo siempre devuelve 0. Puedes usar este hecho para determinar si un número es par o
impar:

par_o_impar.py
par_o_impar.py número = entrada("Ingresa un número y te diré si es par o impar: ")
numero = int(numero)

si número % 2 == 0:
print(f"\nEl número {número} es par.")
demás:

print(f"\nEl número {número} es impar.")

Los números pares siempre son divisibles por dos, por lo que si el módulo de un número
y dos es cero (aquí, si número % 2 == 0) el número es par. De lo contrario, es raro.

Introduce un número y te diré si es par o impar: 42

El número 42 es par.

Inténtalo tú mismo

7-1. Coche de alquiler: escriba un programa que le pregunte al usuario qué tipo de coche de
alquiler le gustaría. Imprima un mensaje sobre ese automóvil, como "Déjame ver si puedo
encontrarte un Subaru".

7-2. Asientos en el restaurante: escriba un programa que le pregunte al usuario cuántas


personas hay en su grupo de cena. Si la respuesta es más de ocho, imprima un mensaje
diciendo que tendrán que esperar por una mesa. De lo contrario, informe que su mesa está lista.

7-3. Múltiplos de diez: solicite al usuario un número y luego informe si el número es un


múltiplo de 10 o no.
Entrada de usuario y bucles while 117

MachineTranslatedbyGoogle

Introducción a los bucles while

El bucle for toma una colección de elementos y ejecuta un bloque de código una vez para cada
elemento de la colección. Por el contrario, el bucle while se ejecuta mientras una determinada
condición sea verdadera.

El ciclo while en acción


Puede usar un bucle while para contar una serie de números. Por ejemplo, el siguiente ciclo
while cuenta de 1 a 5:

contando.py número_actual = 1
mientras número_actual <= 5:
imprimir (número_actual)
número_actual += 1

En la primera línea, empezamos a contar desde 1 asignando número_actual


el valor 1. El ciclo while se configura para seguir ejecutándose siempre que el valor de número_actual
sea menor o igual a 5. El código dentro del ciclo imprime el valor de número_actual y luego agrega 1 a

ese valor con número_actual


+= 1. (El operador += es una abreviatura de número_actual = número_actual + 1).
Python repite el bucle siempre que la condición número_actual <= 5 sea verdadera. Como
1 es menor que 5, Python imprime 1 y luego suma 1, haciendo el número actual 2. Como 2 es
menor que 5, Python imprime 2
y vuelve a sumar 1, haciendo que el número actual sea 3, y así sucesivamente. Una vez que el
valor de current_number es mayor que 5, el ciclo deja de ejecutarse y el programa finaliza:

1
2
3
4

Es muy probable que los programas que usa todos los días contengan bucles while . Por
ejemplo, un juego necesita un bucle while para seguir ejecutándose todo el tiempo que desee
seguir jugando y, por lo tanto, puede dejar de ejecutarse tan pronto como le pida que lo abandone.
Los programas no serían divertidos de usar si dejaran de ejecutarse antes de que se lo indiquemos
o continuaran ejecutándose incluso después de que quisiéramos salir, por lo que los bucles while
son muy útiles.

Permitir que el usuario elija cuándo salir


Podemos hacer que el programa parrot.py se ejecute todo el tiempo que el usuario desee colocando
la mayor parte del programa dentro de un ciclo while . Definiremos un valor de salida y luego
mantendremos el programa ejecutándose mientras el usuario no haya ingresado el valor de salida:

loro.py u prompt = "\nDime algo y te lo repetiré:"


"
prompt += "\nIngrese 'salir' para finalizar el programa.

118 Capítulo 7

MachineTranslatedbyGoogle

""
v mensaje =
w while mensaje != 'salir':
mensaje = entrada (solicitud)
imprimir (mensaje)

En u, definimos un aviso que le dice al usuario sus dos opciones: ingresar un mensaje o

ingresar el valor de salida (en este caso, 'salir'). Luego configuramo


configuramos
s un mensaje variable v para
realizar un seguimiento de cualquier valor que ingrese el usuario. Definimos el mensaje como una
cadena vacía, "", por lo que Python tiene algo que verificar la primera vez que llega a la línea
while . La primera vez que se ejecuta el programa y Python llega a la declaración while , necesita
comparar el valor del mensaje con 'quit', pero aún no se ha ingresado ninguna entrada del usuario.
Si Python no tiene nada que comparar, no podrá continuar ejecutando el programa. Para resolver
este problema, nos aseguramos de darle al mensaje un valor inicial. Aunque es solo una cadena
vacía, tendrá sentido para Python y le permitirá realizar la comparación que hace que el ciclo
while funcione. Este bucle while w se ejecuta siempre que el valor del mensaje no sea 'salir'.

La primera vez que pasa por el bucle, el mensaje es solo una cadena vacía, por lo que Python
entra en el bucle. En mensaje = entrada (solicitud), Python muestra la solicitud y espera a que
el usuario ingrese su entrada. Todo lo que ingresan se asigna a un mensaje y se imprime;
luego, Python reevalúa la condición en el while
declaración. Siempre que el usuario no haya ingresado la palabra 'salir', el aviso se muestra
nuevamente y Python espera más información. Cuando el usuario finalmente ingresa 'salir', Python
deja de ejecutar el ciclo while y el programa finaliza:

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. ¡Hola a todos!
¡Hola a todos!

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. Hola de nuevo.

Hola de nuevo.

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. dejar
dejar

Este programa funciona bien, excepto que imprime la palabra 'salir' como si fuera un
mensaje real. Una simple prueba if soluciona esto:

prompt = "\nDime algo y te lo repetiré:"


"
prompt += "\nIngrese 'salir' para finalizar el programa.
""
mensaje
= while mensaje != 'salir':
mensaje = entrada (solicitud)

si el mensaje! = 'salir':
imprimir (mensaje)

Entrada de usuario y bucles while 119

MachineTranslatedbyGoogle

Ahora el programa realiza una comprobación rápida antes de mostrar el mensaje.


y solo imprime el mensaje si no coincide con el valor de salida:

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. ¡Hola a todos!
¡Hola a todos!

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. Hola de nuevo.
Hola de nuevo.

Dime algo y te lo repetiré: Ingresa 'quit' para finalizar el


programa. dejar

usando una bandera

En el ejemplo anterior, hicimos que el programa realizara ciertas tareas mientras una condición
determinada era verdadera. Pero, ¿qué pasa con los programas más complicados en los que
muchos eventos diferentes pueden hacer que el programa deje de ejecutarse?
Por ejemplo, en un juego, varios eventos diferentes pueden terminar el juego.
Cuando el jugador se queda sin barcos, se acaba el tiempo o las ciudades que se suponía
que debían proteger son destruidas, el juego debería terminar. Debe terminar si ocurre
cualquiera de estos eventos. Si pueden ocurrir muchos eventos posibles para detener el
programa, trate de probar todas estas condiciones en un momento
declaración se vuelve complicada y difícil.
Para un programa que debe ejecutarse solo mientras muchas condiciones sean verdaderas,
puede definir una variable que determine si todo el programa está activo o no. Esta variable,
llamada bandera, actúa como una señal para el programa. Podemos escribir nuestros programas
para que se ejecuten mientras el indicador está establecido en Verdadero y dejar de ejecutarse
cuando cualquiera de varios eventos establece el valor del indicador en Falso. Como resultado,
nuestra declaración while general necesita verificar solo una condición: si la bandera es

actualmente True o no. Luego, todas nuestras otras pruebas (para ver si ha ocurrido un evento
que debería establecer el indicador en Falso) se pueden organizar ordenadamente en el resto del
programa.
Agreguemos una bandera a parrot.py de la sección anterior. Este indicador, al que
llamaremos activo (aunque puede llamarlo como quiera), controlará si el programa debe
continuar ejecutándose o no:

prompt = "\nDime algo y te lo repetiré:"


"
prompt += "\nIngrese 'salir' para finalizar el programa.

u activo = Verdadero
v mientras está activo:
mensaje = entrada (solicitud)

w si el mensaje == 'salir':
activo = Falso
x más:
imprimir (mensaje)

120 Capítulo 7

MachineTranslatedbyGoogle

Establecemos la variable active en True u para que el programa comience en un estado


activo. Hacerlo simplifica la instrucción while porque no se realiza ninguna comparación en la
instrucción while en sí; la lógica se cuida en otras partes del programa. Mientras la variable activa
siga siendo True, el bucle seguirá ejecutándose v.

En la instrucción if dentro del ciclo while , verificamos el valor del mensaje


una vez que el usuario ingresa su entrada. Si el usuario ingresa 'salir' w, activamos
a False, y el bucle while se detiene. Si el usuario ingresa algo que no sea 'salir' x, imprimimos
su entrada como un mensaje.
Este programa tiene el mismo resultado que el ejemplo anterior donde colocamos la prueba
condicional directamente en la instrucción while . Pero ahora que tenemos un indicador para
indicar si el programa general está en un estado activo, sería fácil agregar más pruebas (como
declaraciones elif ) para eventos que deberían causar que active se convierta en False. Esto es
útil en programas complicados como juegos en los que puede haber muchos eventos que deberían
hacer que el programa deje de ejecutarse. Cuando cualquiera de estos eventos hace que la
bandera activa se vuelva Falso, el bucle principal del juego se cerrará, se puede mostrar un
mensaje de Game Over y se le puede dar al jugador la opción de volver a jugar.

Usar pausa para salir de un bucle

Para salir de un ciclo while inmediatamente sin ejecutar ningún código restante en el ciclo,
independientemente de los resultados de cualquier prueba condicional, use la instrucción break .
La instrucción break dirige el flujo de su programa; puede usarlo para controlar qué líneas de
código se ejecutan y cuáles no, de modo que el programa solo ejecute el código que desee, cuando
lo desee.
Por ejemplo, considere un programa que pregunta al usuario sobre los lugares que ha visitado.
visitado. Podemos detener el ciclo while en este programa llamando a break tan pronto como el
usuario ingrese el valor 'quit' :

ciudades.py prompt = "\nIngrese el nombre de una ciudad que haya visitado:"

indicador += "\n(Ingrese 'salir' cuando haya terminado.) "

u mientras es cierto:

ciudad = entrada (mensaje)

if ciudad == 'salir':
romper
demás:

print(f"¡Me encantaría ir a {ciudad.título()}!")

Un ciclo que comienza con while True u se ejecutará para siempre a menos que llegue a
una declaración de interrupción . El ciclo en este programa continúa pidiéndole al usuario que
ingrese los nombres de las ciudades en las que ha estado hasta que ingresa 'salir'. Cuando

ingresan 'quit', se ejecuta la instrucción break , lo que hace que Python salga del ciclo:

Ingrese el nombre de una ciudad que haya visitado: (Ingrese 'salir'


cuando haya terminado). Nueva York
¡Me encantaría ir a Nueva York!

Entrada de usuario y bucles while 121

MachineTranslatedbyGoogle

Ingrese el nombre de una ciudad que haya visitado: (Ingrese


'salir' cuando haya terminado). San Francisco ¡Me encantaría ir a
San Francisco!

Ingrese el nombre de una ciudad que haya visitado: (Ingrese


'salir' cuando haya terminado). salir

N ota Puede utilizar la sentencia break en cualquiera de los bucles de Python. Por ejemplo, podrías usar
break para salir de un bucle for que está trabajando a través de una lista o un diccionario.

Uso de continuar en un bucle

En lugar de salir de un bucle por completo sin ejecutar el resto de su código, puede usar la
instrucción continuar para volver al principio del bucle en función del resultado de una prueba
condicional. Por ejemplo, considere un ciclo que cuenta del 1 al 10 pero imprime solo los
números impares en ese rango:

contando.py número_actual = 0
mientras número_actual < 10:
u numero_actual += 1
si numero_actual % 2 == 0:
Seguir

imprimir (número_actu
(número_actual)
al)

Primero establecemos current_number en 0. Debido a que es menor que 10,


Python ingresa al ciclo while . Una vez dentro del bucle, incrementamos el conteo en 1
en u, por lo que el número_actual es 1. La declaración if luego verifica el módulo del
número_actual y 2. Si el módulo es 0 (lo que significa que el número_actual es divisible
por 2), la instrucción continuar dice Python para ignorar el resto del bucle y volver al
principio. Si el número actual no es divisible por 2, se ejecuta el resto del bucle y Python

imprime el número actual:

1
3

Evitar bucles infinitos


Cada bucle while necesita una forma de dejar de ejecutarse para que no continúe
ejecutándose para siempre. Por ejemplo, este ciclo de conteo debería contar del 1 al 5:

contando.py X=1
mientras que x <= 5:

imprimir (x)
X+=1

122 Capítulo 7

MachineTranslatedbyGoogle

Pero si accidentalmente omite la línea x += 1 (como se muestra a continuación), el ciclo se


ejecutará para siempre:

# ¡Este ciclo se ejecuta para siempre!


X=1
mientras que x <= 5:

imprimir (x)

Ahora el valor de x comenzará en 1 pero nunca cambiará. Como resultado, la prueba


condicional x <= 5 siempre se evaluará como True y el bucle while se ejecutará para siempre,
imprimiendo una serie de 1, como este:

1
1
1
1
--recorte--

Cada programador escribe accidentalmente un ciclo while infinito desde el tiempo

al tiempo, especialmente cuando los bucles de un programa tienen condiciones de salida sutiles.
Si su programa se atasca en un ciclo infinito, presione ctrl-C o simplemente cierre la ventana de
terminal que muestra la salida de su programa.
Para evitar escribir bucles infinitos, pruebe cada bucle while y asegúrese de que el bucle se
detenga cuando lo espere. Si desea que su programa finalice cuando el usuario ingrese un cierto
valor de entrada, ejecute el programa e ingrese ese valor. Si el programa no finaliza, analice la
forma en que su programa maneja el valor que debería causar la salida del bucle. Asegúrese de
que al menos una parte del programa pueda hacer que la condición del ciclo sea Falsa o que llegue
a una declaración de interrupción .

N ota Sublime Text y algunos otros editores tienen una ventana de salida incrustada. Esto
puede dificultar la detención de un bucle infinito y es posible que deba cerrar el editor
para finalizar el bucle. Intente hacer clic en el área de salida del editor antes de
presionar ctrl-C, y debería poder cancelar un bucle infinito.

Inténtalo tú mismo

7-4. Ingredientes para pizza: escriba un ciclo que solicite al usuario que ingrese una serie de
ingredientes para pizza hasta que ingrese un valor de 'salir'
' salir' . A medida que ingresen cada
ingrediente, imprima un mensaje que diga que agregará ese ingrediente a su pizza.
7-5. Boletos de cine: un cine cobra diferentes precios de boletos según la edad de la
persona. Si una persona es menor de 3 años, la entrada es gratuita; si son entre 3 y 12, el

boleto cuesta $10; y si son mayores de 12 años, el boleto cuesta $15. Escriba un ciclo en el
que pregunte a los usuarios su edad y luego dígales el costo de su boleto de cine.

(continuado)

Entrada de usuario y bucles while 123

MachineTranslatedbyGoogle

7-6. Tres salidas: Escriba diferentes versiones del Ejercicio 7-4 o del Ejercicio 7-5 que hagan cada

uno de los siguientes al menos una vez:

•Utilice una prueba condicional en la instrucción while para detener el ciclo.

•Utilice una variable activa para controlar cuánto tiempo se ejecuta el bucle.

•Utilice una declaración de interrupción para salir del ciclo cuando el usuario ingrese un valor de 'salir' .

7-7. Infinito: escriba un ciclo que nunca termine y ejecútelo. (Para finalizar el ciclo, presione ctrl-C
o cierre la ventana que muestra la salida).

Usar un bucle while con listas y diccionarios


Hasta ahora, hemos trabajado con solo una parte de la información del usuario a la vez.
Recibimos la entrada del usuario y luego imprimimos la entrada o una respuesta.

La próxima vez que pasemos por el ciclo while , recibiremos otro valor de entrada y
responderemos a eso. Pero para realizar un seguimiento de muchos usuarios y piezas de
información, necesitaremos usar listas y diccionarios con nuestros bucles while .
Un bucle for es efectivo para recorrer una lista, pero no debe modificar
una lista dentro de un bucle for porque Python tendrá problemas para realizar un seguimiento
de los elementos de la lista. Para modificar una lista mientras trabaja en ella, use un bucle while .
El uso de bucles while con listas y diccionarios le permite recopilar, almacenar y organizar
muchas entradas para examinarlas e informar sobre ellas más adelante.

Mover elementos de una lista a otra


Considere una lista de usuarios recién registrados pero no verificados de un sitio web.
Después de verificar estos usuarios, ¿cómo podemos moverlos a una lista separada de usuarios

confirmados? Una forma sería usar un bucle while para extraer usuarios de la lista de usuarios
no confirmados mientras los verificamos y luego los agregamos a una lista separada de usuarios
confirmados. Así es como se vería ese código:

confirmado # Comience con los usuarios que deben verificarse, # y una lista
_usuarios.py vacía para retener a los usuarios confirmados.
u usuarios_no confirmados = ['alicia', 'brian', 'candace']
usuarios_confirmados = []

# Verifique cada usuario hasta que no haya más usuarios sin confirmar.
# Mueva cada usuario verificado a la lista de usuarios confirmados.
v mientras usuarios_no_confirmados:
w usuario_actual = usuarios_no confirmados.pop()

print(f"Verificando usuario: {current_user.title()}")


x usuarios_confirmados.append(usuario_actual)

124 Capítulo 7

MachineTranslatedbyGoogle

# Mostrar todos los usuarios confirmados.


print("\nLos siguientes usuarios han sido confirmados:")
para usuario_confirmado en usuarios_confirmados:
imprimir (usuario_confirmado.título())

Comenzamos con una lista de usuarios no confirmados en u (Alice, Brian y

Candace) y una lista vacía para contener usuarios confirmados. El ciclo while en v
se ejecuta siempre que la lista unconfirmed_users no esté vacía. Dentro de este ciclo, la
función pop() en w elimina a los usuarios no verificados uno a la vez desde el final de
unconfirmed_users. Aquí, porque Candace es la última en unconfirmed_users
lista, su nombre será el primero en ser eliminado, asignado a usuario_actual y agregado a
la lista de usuarios_confirmados en x. El siguiente es Brian, luego Alice.
Simulamos la confirmación de cada usuario imprimiendo un mensaje de verificación
y luego agregándolos a la lista de usuarios confirmados. A medida que se reduce la lista
de usuarios no confirmados, crece la lista de usuarios confirmados. Cuando la lista de
usuarios no confirmados está vacía, el bucle se detiene y se imprime la lista de usuarios
confirmados:

Verificando usuario: Candace


Verificando usuario: Brian
Verificando usuario: Alicia

Los siguientes usuarios han sido confirmados:


Candace
Brian
Alicia

Eliminación de todas las instancias de valores específicos de una lista

En el Capítulo 3 usamos remove() para eliminar un valor específico de una lista. La


función remove() funcionó porque el valor que nos interesaba solo aparecía una vez en la

lista. Pero, ¿qué sucede si desea eliminar todas las instancias de un valor de una lista?

Digamos que tiene una lista de mascotas con el valor 'gato' repetido varias veces. Para
eliminar todas las instancias de ese valor, puede ejecutar un ciclo while hasta que 'gato' ya
no esté en la lista, como se muestra aquí:

mascotas.py mascotas = ['perro', 'gato', 'perro', 'pez dorado', 'gato', 'conejo', 'gato']
imprimir (mascotas)

mientras que 'gato' en mascotas:


mascotas.remove('gato')
imprimir (mascotas)

Comenzamos con una lista que contiene varias instancias de 'gato'. Después de
imprimir la lista, Python ingresa al ciclo while porque encuentra el valor 'gato' en la lista

Entrada de usuario y bucles while 125

MachineTranslatedbyGoogle

al menos una vez. Una vez dentro del ciclo, Python elimina la primera instancia de 'gato',
regresa a la línea while y luego vuelve a ingresar al ciclo cuando encuentra que 'gato'
todavía está en la lista. Elimina cada instancia de 'gato' hasta que el valor ya no está en
la lista, momento en el que Python sale del ciclo e imprime la lista nuevamente:

['perro', 'gato', 'perro', 'pez dorado', 'gato', 'conejo', 'gato'] ['perro', 'perro', 'pez
dorado', 'conejo']

Llenar un diccionario con entrada de usuario

Puede solicitar tanta entrada como necesite en cada paso a través de un tiempo
círculo. Hagamos un programa de sondeo en el que cada paso por el bucle solicite
el nombre y la respuesta del participante. Guardaremos los datos que recopilamos
en un diccionario, porque queremos conectar cada respuesta con un usuario en
particular:

montaña respuestas = {}
_encuesta.py

# Establecer una bandera para indicar que el sondeo está activo.


sondeo_activo = Verdadero

mientras sondeo_activo:
# Solicitar el nombre y la respuesta de la persona.
u nombre = input("\n¿Cuál es tu nombre?")
respuesta = entrada ("¿Qué montaña te gustaría escalar algún día?")

# Guarda la respuesta en el diccionario.


v respuestas[nombre] = respuesta

# Averigüe si alguien más va a realizar la encuesta.


w repetir = entrada ("¿Le gustaría dejar que otra persona responda? (sí/no)")
si repite == 'no':
polling_active = Falso

# El sondeo está completo. Mostrar los resultados.


print("\n--- Resultados de la encuesta ---")
x para nombre, respuesta en answers.items():
print(f"{nombre} quisiera escalar {respuesta}.")

El programa primero define un diccionario vacío (respuestas) y establece un


indicador (polling_active) para indicar que el sondeo está activo. Siempre que
polling_active sea True, Python ejecutará el código en el bucle while .
Dentro del bucle, se le solicita al usuario que ingrese su nombre y una montaña
que le gustaría escalar. Esa información se almacena en el diccionario de respuestas
v, y se le pregunta al usuario si desea o no mantener activa la encuesta w.
Si ingresan sí, el programa ingresa nuevamente al ciclo while . Si ingresan no, el
indicador polling_active se establece en False, el bucle while deja de ejecutarse y el
bloque de código final en x muestra los resultados de la encuesta.

126 Capítulo 7

MachineTranslatedbyGoogle

Si ejecuta este programa e ingresa respuestas de muestra, debería ver un


resultado como este:

¿Cómo te llamas? eric


¿Qué montaña te gustaría escalar algún día? Denali
¿Te gustaría dejar que otra persona responda? (sí/no) sí

¿Cómo te llamas? lynn


¿Qué montaña te gustaría escalar algún día? Pulgar del diablo ¿Te gustaría
dejar que otra persona responda? (sí/no) no

--- Resultados de la
encuesta --- A Lynn le gustaría escalar Devil's Thumb.
A Eric le gustaría escalar el Denali.

Inténtalo tú mismo

7-8. Deli: haga una lista llamada sandwich_orders y llénela con los nombres de varios
sándwiches. Luego haz una lista vacía llamada emparedados_terminados. Recorra la
lista de pedidos de sándwiches e imprima un mensaje para cada pedido, como Hice su
sándwich de atún. A medida que se prepara cada sándwich, muévalo a la lista de
sándwiches terminados. Después de que se hayan hecho todos los sándwiches, imprima
un mensaje que enumere cada sándwich que se preparó.

7-9. Sin Pastrami: Usando la lista sandwich_orders del Ejercicio 7-8, asegúrese de que
el sándwich 'pastrami' aparezca en la lista al menos tres veces. Agregue código cerca
del comienzo de su programa para imprimir un mensaje que diga que la charcutería se
quedó sin pastrami, y luego use un ciclo while para eliminar todas las apariciones
a pariciones de
'pastrami' de sandwich_orders. Asegúrese de que ningún sándwich de pastrami termine
en sándwiches terminados.

7-10. Vacaciones de ensueño: escriba un programa que haga encuestas a los usuarios sobre
las vacaciones de sus sueños. Escribe un mensaje similar a Si pudieras visitar un lugar en el
mundo, ¿a dónde irías? Incluya un bloque de código que imprima los resultados de la encuesta.

Resumen
En este capítulo, aprendió a usar input() para permitir que los usuarios
proporcionen su propia información en sus programas. Aprendió a trabajar con
entrada de texto y numérica y cómo usar bucles while para hacer que sus programas
se ejecuten tanto tiempo como los usuarios lo deseen. Viste varias formas de controlar
el flujo de un ciclo while configurando un indicador activo , usando la instrucción break y

Entrada de usuario y bucles while 127

MachineTranslatedbyGoogle

utilizando la instrucción continuar . Aprendió cómo usar un ciclo while para mover
elementos de una lista a otra y cómo eliminar todas las instancias de un valor de una
lista. También aprendió cómo se pueden usar los bucles while con los diccionarios .
En el Capítulo 8 aprenderá acerca de las funciones. Las funciones le permiten romper
sus programas en partes pequeñas, cada una de las cuales hace un trabajo específico.
Puede llamar a una función tantas veces como desee y puede almacenar sus funciones
en archivos separados. Mediante el uso de funciones, podrá escribir un código más
eficiente que sea más fácil de solucionar y mantener y que se pueda reutilizar en muchos
programas diferentes.
128 Capítulo 7

MachineTranslatedbyGoogle

8
Funciones

En este capítulo, aprenderá a escribir


funciones, que son bloques de código con nombre

que están diseñados para realizar un trabajo específico.


Cuando desea realizar una tarea particular que ha
definido en una función, llama a la función responsable de la
misma. Si necesita realizar esa tarea
varias veces a lo largo de su programa, no necesita escribir todo el código para la
misma tarea una y otra vez; simplemente llama a la función dedicada a manejar esa
tarea, y la llamada le dice a Python que ejecute el código dentro de la función. Descubrirá
que el uso de funciones hace que sus programas sean más fáciles de escribir, leer,
probar y corregir.
En este capítulo también aprenderá formas de pasar información a las funciones.

Aprenderá a escribir
otras funciones ciertaspara
diseñadas funciones cuyo
procesar trabajo
datos principal
y devolver unesvalor
mostrar información
o conjunto de y
valores. Finalmente, aprenderá a almacenar funciones en archivos separados llamados
módulos para ayudar a organizar sus archivos de programa principales.

MachineTranslatedbyGoogle

Definición de una función

Aquí hay una función simple llamada greeting_user() que imprime un saludo:

saludador.py def saludo_usu


saludo_usuario():
ario():
v """Mostrar un saludo simple."""

w imprime("¡Hola!")
x saludo_usu
saludo_usuario()
ario()

Este ejemplo muestra la estructura más simple de una función. la línea en ti


usa la palabra clave def para informar a Python que está definiendo una función. Esta es la definición
de la función, que le dice a Python el nombre de la función y, si corresponde, qué tipo de información
necesita la función para hacer su trabajo. Los paréntesis contienen esa información. En este caso, el
nombre de la función es greeting_user() y no necesita información para hacer su trabajo, por lo que
sus paréntesis están vacíos. (Aún así, los paréntesis son obligatorios). Finalmente, la definición
termina en dos puntos.

Cualquier línea sangrada que siga a def greeting_user(): constituye el cuerpo de la función.
El texto en v es un comentario llamado docstring, que describe lo que hace la función. Las cadenas
de documentos están encerradas entre comillas triples, que Python busca cuando genera
documentación para las funciones en sus programas.

La línea print("¡Hola!") ÿ es la única línea de código real en el cuerpo


de esta función, entonces greeting_user() solo tiene un trabajo: print("¡Hola!").
Cuando quiera usar esta función, llámela. Una llamada de función le dice a Python que
ejecute el código en la función. Para llamar a una función, escribe el nombre de la función,
seguido de cualquier información necesaria entre paréntesis, como se muestra en x. Debido a que
no se necesita información aquí, llamar a nuestra función es tan simple como ingresar
greeting_user(). Como era de esperar, imprime ¡Hola!:

¡Hola!

Pasar información a una función


Modificada ligeramente, la función greeting_user() no solo puede decirle al usuario ¡Hola!
sino también saludarlos por su nombre. Para que la función haga esto, ingrese el nombre de usuario
entre paréntesis de la definición de la función en def greeting_user(). Al agregar el nombre de
usuario aquí, permite que la función acepte cualquier valor de nombre de usuario que especifique.
La función ahora espera que proporcione un valor para el nombre de usuario cada vez que la llame.
Cuando llamas a greeting_user(), puedes pasarle un nombre, como 'jesse', entre paréntesis:
def saludo_usuario(nombre de usuario):
"""Mostrar un saludo simple."""
print(f"Hola, {nombre de usuario.título()}!")
usuario.título()}!")

saludar_usuario('jesse')

130 Capítulo 8

MachineTranslatedbyGoogle

Ingresar a greeting_user('jesse') llama a greeting_user() y le da a la función el


información que necesita para ejecutar la llamada print() . La función acepta el nombre
que le pasó y muestra el saludo para ese nombre:

¡Hola, Jesse!

Del mismo modo, al ingresar greeting_user('sarah') llama a greeting_user(), pasa 'sarah',


e imprime ¡Hola, Sarah! Puede llamar a greeting_user() tantas veces como desee y
pasarle cualquier nombre que desee para producir un resultado predecible cada vez.

Argumentos y Parámetros
En la función de saludo_usuario() anterior , definimos saludo_usuario() para requerir un
valor para la variable nombre de usuario. Una vez que llamamos a la función y le dimos
la información (el nombre de una persona), imprimió el saludo correcto.
El nombre de usuario variable en la definición de greeting_user() es un ejemplo de
un parámetro, una información que la función necesita para hacer su trabajo. El valor
'jesse' en greeting_user('jesse') es un ejemplo de un argumento. Un argumento es una
pieza de información que se pasa de una llamada de función a una función.
Cuando llamamos a la función, colocamos el valor con el que queremos que trabaje la función entre
paréntesis. En este caso, el argumento 'jesse' se pasó a la función greeting_user() y el valor se
asignó al parámetro nombre de usuario.

Nota La gente a veces habla de argumentos y parámetros indistintamente. No se sorprenda si


ve las variables en una definición de función referidas como argumentos o las variables
en una llamada de función referidas como parámetros.

Inténtalo tú mismo

8-1. Mensaje: Escriba una función llamada mostrar_mensaje() que imprima una
oración que diga a todos lo que está aprendiendo en este capítulo. Llame a la
función y asegúrese de que el mensaje se muestre correctamente.

8-2. Libro Favorito: Escriba una función llamada libro_favorito() que acepte un
parámetro, título. La función debe imprimir un mensaje, como Uno de mis libros
favoritos es Alicia en el país de las maravillas. Llame a la función, asegurándose de
incluir el título de un libro como argumento en la llamada a la función.
pasar argumentos
Debido a que una definición de función puede tener múltiples parámetros, una llamada
de función puede necesitar múltiples argumentos. Puede pasar argumentos a sus
funciones de varias maneras. Puede usar argumentos posicionales, que deben estar en

Funciones 131

MachineTranslatedbyGoogle

el mismo orden en que se escribieron los parámetros; argumentos de palabras clave, donde
cada argumento consta de un nombre de variable y un valor; y listas y diccionarios de
valores. Veamos cada uno de estos a su vez.

Argumentos posicionales

Cuando llama a una función, Python debe hacer coincidir cada argumento en la llamada a
la función con un parámetro en la definición de la función. La forma más sencilla de hacerlo
se basa en el orden de los argumentos proporcionados. Los valores emparejados de esta
manera se denominan argumentos posicionales.
Para ver cómo funciona esto, considere una función que muestre información sobre
mascotas. La función nos dice qué tipo de animal es cada mascota y el nombre de la
mascota, como se muestra aquí:

mascotas.py u def describe_mascota(t


describe_mascota(tipo_animal,
ipo_animal, nombre_mascota):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal_type} es {pet_name.title()}").

v describe_mascota('hámster', 'harry')

La definición muestra que esta función necesita un tipo de animal y el


nombre del animal u. Cuando llamamos a describe_pet(), necesitamos proporcionar un
tipo de animal y un nombre, en ese orden. Por ejemplo, en la llamada de función, el
argumento 'hamster' se asigna al parámetro animal_type y el argumento 'harry' se asigna
al parámetro pet_name v. En el cuerpo de la función, estos dos parámetros se utilizan para
mostrar información sobre la mascota. siendo descrito.

El resultado describe a un hámster llamado Harry:

tengo un hamster
Mi hámster se llama Harry.

Llamadas de función múltiple

Puede llamar a una función tantas veces como sea necesario. Describir una segunda mascota diferente
requiere solo una llamada más a describe_pet():

def describe_mascot
describe_mascota(tipo_animal,
a(tipo_animal, nombre_mascota):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal type} es {pet name.title()}").
describe_mascota('hámster',
describe_mascota('hámster', 'harry')

describe_pet('perro', 'willie')

En esta segunda llamada de función, pasamos describe_mascota()


describe_mascota() los argumentos 'perro'
y 'willie'. Al igual que con el conjunto anterior de argumentos que usamos, Python hace coincidir 'perro'
con el parámetro tipo_animal y 'willie' con el parámetro nombre_mascota.

132 Capítulo 8

MachineTranslatedbyGoogle

Como antes, la función hace su trabajo, pero esta vez imprime valores para un perro
llamado Willie. Ahora tenemos un hámster llamado Harry y un perro llamado Willie:

tengo un hamster
Mi hámster se llama Harry.

Tengo un perro.
El nombre de mi perro es Willie.

Llamar a una función varias veces es una forma muy eficiente de trabajar. El código
que describe una mascota se escribe una vez en la función. Luego, cada vez que desee
describir una nueva mascota, llame a la función con la información de la nueva mascota.
Incluso si el código para describir una mascota se expandiera a diez líneas, aún podría
describir una nueva mascota en una sola línea llamando a la función nuevamente.

Puede usar tantos argumentos posicionales como necesite en sus funciones. Python
trabaja a través de los argumentos que proporciona al llamar a la función y hace coincidir
cada uno con el parámetro correspondiente en la definición de la función.

Importancia del orden en los argumentos posicionales

Puede obtener resultados inesperados si mezcla el orden de los argumentos en una llamada
de función cuando usa argumentos posicionales:
posicionales:

def describe_mascota(t
describe_mascota(tipo_animal,
ipo_animal, nombre_mascota):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal_type} es {pet_name.title()}"
{pet_name.title()}").
).

describe_mascota('harry',
describe_mascota('harry', 'hamster')

En esta llamada de función enumeramos primero el nombre y segundo el tipo de animal.


Debido a que el argumento 'harry' aparece primero esta vez, ese valor se asigna al parámetro
animal_type. Asimismo,
Asimismo, 'hamster' se asigna a pet_name. Ahora tenemos un “harry” llamado
“Hamster”:

yo tengo un harry
Mi Harry se llama Hamster.

Si obtiene resultados divertidos como este, asegúrese de que el orden de los


argumentos en su llamada a la función coincida con el orden de los parámetros en la definición
de la función.

Argumentos
Argumentos de palabras clave

Un argumento de palabra clave es un par de nombre y valor que pasa a una función.
Asocias directamente el nombre y el valor dentro del argumento, así que cuando pasas el
argumento a la función, no hay confusión (no terminarás

Funciones 133

MachineTranslatedbyGoogle

con un Harry llamado Hamster). Los argumentos de palabras clave lo liberan de tener que
preocuparse por ordenar correctamente sus argumentos
a rgumentos en la llamada a la función
fun ción y aclaran el rol de
cada valor en la llamada a la función.
Reescribamos pets.py usando argumentos de palabras clave para llamar a describe_pet():

def describe_mascot
describe_mascota(tipo_animal,
a(tipo_animal, nombre_mascota):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal_type} es {pet_name.title()}").

describe_pet(animal_type='hamster',
describe_pet(animal_type='hamster', pet_name='harry')

La función describe_pet() no ha cambiado. Pero cuando llamamos a la función, le decimos


explícitamente a Python con qué parámetro debe coincidir cada argumento. Cuando Python lee la
llamada a la función, sabe asignar el argumento 'hamster' al parámetro animal_type y el argumento
'harry'
a pet_name. El resultado muestra correctamente que tenemos un hámster llamado Harry.

El orden de los argumentos de las palabras clave no importa porque Python sabe
dónde debe ir cada valor. Las siguientes dos llamadas de función son equivalentes:

describe_pet(animal_type='hamster',
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry',
describe_pet(pet_name='harry', animal_type='hams
animal_type='hamster')
ter')

N ota Cuando utilice argumentos de palabras clave, asegúrese de utilizar los nombres exactos de los parámetros
pa rámetros
en la definición de la función.

Valores predeterminados

Al escribir una función, puede definir un valor predeterminado para cada parámetro.
Si se proporciona un argumento para un parámetro en la llamada a la función, Python usa el valor del
argumento. Si no, utiliza el valor predeterminado del parámetro. Entonces, cuando define un valor
predeterminado para un parámetro, puede excluir el argumento correspondiente que normalmente
escribiría en la llamada a la función. El uso de valores predeterminados puede simplificar sus llamadas
a funciones y aclarar las formas en que se usan normalmente sus funciones.

Por ejemplo, si observa que la mayoría de las llamadas a describe_pet() se utilizan para
describir perros, puede establecer el valor predeterminado de animal_type en 'perro'. Ahora
cualquiera que llame a describe_pet() para un perro puede omitir esa información:
def describe_mascot
describe_mascota(nombre_mascota,
a(nombre_mascota, tipo_animal='perro'):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal_type} es {pet_name.title()}").

describe_pet(pet_name='willie')

134 Capítulo 8

MachineTranslatedbyGoogle

Cambiamos
Cambiamos la definición de describe_pet() para incluir un valor predeterminado, 'perro', para
animal_type.
animal_type. Ahora, cuando se llama a la función sin animal_type
especificado, Python sabe usar el valor 'perro' para este parámetro:

Tengo un perro.
El nombre de mi perro es Willie.

Tenga en cuenta que se tuvo que cambiar el orden de los parámetros en la definición de la
función. Debido a que el valor predeterminado hace innecesario especificar un tipo de animal como
argumento, el único argumento que queda en la llamada de función es el nombre de la mascota. Python
todavía interpreta esto como un argumento posicional,
posicional, por lo que si se llama a la función solo con el
nombre de una mascota, ese argumento coincidirá con el primer parámetro enumerado en la definición
de la función. Esta es la razón por la que el primer parámetro debe ser pet_name.
pet_name.

La forma más sencilla de usar esta función ahora es proporcionar solo la información de un perro.
nombre en la llamada de función:

describe_mascota('willie')

Esta llamada de función tendría el mismo resultado que el ejemplo anterior.


El único argumento proporcionado
proporcionado es 'willie', por lo que se compara con el primer parámetro de la
definición, pet_name. Debido a que no se proporciona ningún argumento para animal_type, Python usa
el valor predetermina
predeterminado
do 'perro'.
Para describir un animal que no sea un perro, podría usar una llamada de función como esta:

describe_pet(pet_name=
describe_pet(pet_name='harry',
'harry', animal_type
animal_type='hamster')
='hamster')

Debido a que se proporciona un argumento explícito para animal_type , Python


ignorar el valor predeterminad
predeterminado
o del parámetro.

N ota Cuando utiliza valores predeterminados, cualquier parámetro con un valor predeterminado debe aparecer
después de todos los parámetros que no tienen valores predeterminados. Esto le permite a Python
continuar interpretando correctamente los argumentos posicionales.

Llamadas a funciones equivalentes

Debido a que los argumentos posicionale


posicionales,
s, los argumento
argumentos
s de palabras clave y los valores predeterminados
se pueden usar juntos, a menudo tendrá varias formas equivalentes de llamar a una función. Considere la
siguiente definición para describe_pet() con un valor predeterminado
predeterminado provisto:
def describe_mascota(nombre
describe_mascota(nombre_mascota,
_mascota, tipo_animal=
tipo_animal='perro'):
'perro'):

Con esta definición, siempre se debe proporcionar un argumento para pet_name, y este valor se
puede proporcionar usando la palabra clave posicional o

Funciones 135

MachineTranslatedbyGoogle

formato. Si el animal que se describe no es un perro, se debe incluir un


argumento para animal_type en la llamada, y este argumento también se puede
especificar usando el formato posicional o de palabra clave.
Todas las siguientes llamadas funcionarían para esta función:

# Un perro llamado Willie.


describe_mascota('willie')
describe_pet(pet_name='willie')

# Un hamster llamado Harry.


describe_mascota('harry',
describe_mascota('harry', 'hamster')
describe_pet(pet_name='harry',
describe_pet(pet_name='harry', animal_type='hams
animal_type='hamster')
ter')
describe_pet(animal_type='hamster',
describe_pet(animal_type='hamster', pet_name='harry')

Cada una de estas llamadas de función tendría el mismo resultado que los ejemplos
anteriores.

N ota Realmente no importa qué estilo de llamada utilice. Siempre que sus llamadas de función produzcan
la salida que desea, simplemente use el estilo que le resulte más ffácil
ácil de entender.

Evitar errores de argumento

Cuando comience a usar funciones, no se sorprenda si encuentra errores sobre


argumentos no coincidentes. Los argumentos no coincidentes ocurren cuando
proporciona menos o más argumentos de los que necesita una función para hacer su trabajo.
Por ejemplo, esto es lo que sucede si tratamos de llamar a describe_pet() sin
argumentos:

def describe_mascot
describe_mascota(tipo_animal,
a(tipo_animal, nombre_mascota):
"""Mostrar información sobre una mascota."""
print(f"\nTengo un {animal_type}").
print(f"El nombre de mi {animal_type} es {pet_name.title()}").

describir_mascota()

Python reconoce que falta algo de información en la función


llamada, y el rastreo nos dice que:

Rastreo (última llamada más reciente): u


Archivo "pets.py", línea 6, en <módulo>
v describe_pet() w
TypeError: describe_pet() faltan 2 argumentos posicionales requeridos: 'animal_
tipo y nombre_mascota

En u, el rastreo nos dice la ubicación del problema, lo que nos permite


mire hacia atrás y vea que algo salió mal en nuestra llamada de función. en v
la llamada a la función infractora se escribe para que la veamos. En w el rastreo

136 Capítulo 8

MachineTranslatedbyGoogle

nos dice que a la llamada le faltan dos argumentos e informa los nombres de los argumentos
que faltan. Si esta función estuviera en un archivo separado, probablemente podríamos
reescribir la llamada correctamente sin tener que abrir ese archivo y leer el código de la
función.
Python es útil porque lee el código de la función por nosotros y nos dice
los nombres de los argumentos que necesitamos proporcionar. Esta es otra motivación
para darle a sus variables y funciones nombres descriptivos. Si lo hace, los mensajes de
error de Python serán más útiles para usted y cualquier otra persona que pueda usar su
código.
Si proporciona demasiados argumentos, debería obtener un seguimiento similar
que pueda ayudarlo a hacer coincidir correctamente su llamada de función con la
definición de función.

Inténtalo tú mismo

8-3. Camiseta: Escribe una función llamada make_shirt() que acepte una talla y el texto de un

mensaje que debería estar impreso en la camiseta. La función debe imprimir una oración que resuma
el tamaño de la camisa y el mensaje impreso en ella.

Llame a la función una vez usando argumentos posicionales para hacer una camisa. Llame a la
función por segunda vez usando argumentos de palabras clave.

8-4. Camisas grandes: modifique la función make_shirt() para que las camisas sean grandes por
defecto con un mensaje que diga Me encanta Python. Haga una camisa grande y una camisa mediana
con el mensaje predeterminado, y una camisa de cualquier tamaño con un mensaje diferente.

mensaje.

8-5. Ciudades: Escribe una función llamada describe_city() que acepte el nombre de una ciudad y su
país. La función debe imprimir una oración simple, como Reykjavik está en Islandia. Asigne al
parámetro para el país un valor predeterminado.

Llame a su función para tres ciudades diferentes, al menos una de las cuales no se encuentra en el

país predeterminado.

Valores devueltos
Una función no siempre tiene que mostrar su salida directamente. En su lugar, puede
procesar algunos datos y luego devolver un valor o un conjunto de valores. El valor que
devuelve la función se llama valor de retorno. La declaración de retorno toma un valor
desde dentro de una función y lo envía de vuelta a la línea que llamó a la función.
Los valores devueltos le permiten mover gran parte del trabajo duro de su programa a
funciones, lo que puede simplificar el cuerpo de su programa.

Funciones 137

MachineTranslatedbyGoogle

Devolver un valor simple


Veamos una función que toma un nombre y apellido, y devuelve un nombre completo con un formato limpio:

formateado u def get_formatted_name(nombre, apellido):

_nombre.py """Retorna un nombre completo, con un formato ordenado."""


v nombre_completo = f"{nombre} {apellido}"
w devuelve nombre_completo.título()
nombre_completo.título()

x músico = get_formatted_name('jimi',
get_formatted_name('jimi', 'hendrix')
imprimir (músico)

La definición de get_formatted_name() toma como parámetros un primero y un último


tu nombre La función combina estos dos nombres, agrega un espacio entre ellos y asigna el resultado a
nombre_completo v. El valor de nombre_completo se convierte en mayúsculas y minúsculas y luego se
devuelve a la línea de llamada en w.
Cuando llama a una función que devuelve un valor, debe proporcionar una variable a la que se le
pueda asignar el valor devuelto. En este caso, el valor devuelto se asigna a la variable músico en x. El

resultado muestra un nombre perfectamente formateado formado por las partes del nombre de una persona:

Jimi Hendrix

Esto puede parecer mucho trabajo para obtener un nombre bien formateado cuando
Podríamos haber escrito simplemente:

imprimir("Jimi Hendrix")

Pero cuando considera trabajar con un programa grande que necesita almacenar muchos
nombres y apellidos por separado, funciones como get_formatted_name()
volverse muy útil. Usted almacena el nombre y el apellido por separado y luego llama a esta función cada
vez que desea mostrar un nombre completo.

Hacer un argumento opcional


A veces tiene sentido hacer que un argumento sea opcional para que las personas que usan la función
puedan optar por proporcionar información adicional solo si así lo desean. Puede usar valores
predeterminados para hacer que un argumento sea opcional.
Por ejemplo, digamos que queremos expandir get_formatted_name() para manejar también los
segundos nombres. Un primer intento de incluir segundos nombres podría verse así:
def get_formatted_name(nombre, segundo nombre, apellido):
"""Retorna un nombre completo, con un formato ordenado."""
nombre_completo = f"{primer_nombre} {segundo_nombre} {apellido}"
devolver nombre_comp
nombre_completo.título()
leto.título()

músico = get_forma
get_formatted_name
tted_name('john',
('john', 'lee', 'hooker')
imprimir (músico)

138 Capítulo 8

MachineTranslatedbyGoogle

Esta función funciona cuando se le asigna un nombre, un segundo nombre y un


apellido. La función toma las tres partes de un nombre y luego construye una cadena a partir
de ellas. La función agrega espacios cuando corresponde y convierte el nombre completo en
mayúsculas y minúsculas:

John Lee Hooker

Pero los segundos nombres no siempre son necesarios, y esta función, tal como está
escrita, no funcionaría si intentara llamarla solo con un nombre y un apellido.
Para hacer que el segundo nombre sea opcional, podemos darle al argumento segundo_nombre
segundo_nombre
un valor predeterminado vacío e ignorar el argumento a menos que el usuario proporcione un
valor. Para hacer que get_formatted_name() funcione sin un segundo nombre, establecemos el
valor predeterminado de middle_name
middle_name en una cadena vacía y lo movemos al final de la llista
ista de
parámetros:

u def get_formatted_name(first_name, last_name, second_name=''):


"""Retorna un nombre completo, con un formato ordenado."""
v si segundo_nombre:
nombre_completo = f"{primer_nombre} {segundo_nombre} {apellido}"
en otro:
nombre_completo = f"{nombre} {apellido}"
devolver nombre_com
nombre_completo.título()
pleto.título()

músico = get_formatted_name('jimi', 'hendrix')


imprimir (músico)

x músico = get_formatted_name('john', 'hooker', 'lee')


imprimir (músico)

En este ejemplo, el nombre se construye a partir de tres partes posibles. Debido a que
siempre hay un nombre y un apellido, estos parámetros se enumeran primero en la definición
de la función. El segundo nombre es opcional, por lo que aparece en último lugar en la

definición y su valor predeterminado es una cadena vacía u.


En el cuerpo de la función, verificamos si se ha proporcionado un segundo nombre.
Python interpreta las cadenas no vacías como True, por lo que si middle_name se evalúa como
True si hay un argumento de segundo nombre en la llamada a la
l a función. v. Si se proporciona
un segundo nombre, el primer nombre, el segundo nombre y el apellido se combinan para
formar un nombre completo. . Luego, este nombre se cambia a mayúsculas y minúsculas y se
devuelve a la línea de llamada de función, donde se asigna a la variable músico y se imprime.
Si no se proporciona un segundo nombre, la cadena vacía falla en la prueba if y el bloque else
ejecuta w. El nombre completo se crea con solo un nombre y un apellido, y el nombre formateado
se devuelve a la línea de llamada donde se asigna al músico y se imprime.
Llamar a esta función con un nombre y apellido es sencillo. Si

estamos usando un segundo nombre, sin embargo, debemos asegurarnos de que el


segundo nombre sea el último argumento pasado para que Python coincida correctamente
con los argumentos posicionales x.

Funciones 139

MachineTranslatedbyGoogle

Esta versión modificada de nuestra función funciona para personas con solo una primera
y apellido, y también funciona para personas que tienen un segundo nombre:

Jimi Hendrix
John Lee Hooker

Los valores opcionales permiten que las funciones manejen una amplia gama de casos de
uso mientras permiten que las llamadas a funciones sean lo más simples posible.

Devolver un diccionario

Una función puede devolver cualquier tipo de valor que necesite, incluidas estructuras de datos más
complicadas, como listas y diccionarios. Por ejemplo, la siguiente función toma partes de un nombre y
devuelve un diccionario que representa a una persona:

persona.py def build_person(nombre, apellido):


"""Retornar un diccionario de información sobre una persona."""
u persona = {'primero': nombre, 'apellido': apellido}
v devolver persona

músico = build_person('jimi', 'hendrix')


w imprimir (músico)

La función build_person() toma un nombre y apellido, y coloca estos valores en un diccionario


en u. El valor de first_name se almacena con la clave 'first', y el valor de last_name se almacena
con la clave 'last'. Todo el diccionario que representa a la persona se devuelve en v. El valor de retorno
se imprime en w con las dos piezas originales de información textual ahora almacenadas en un
diccionario:

{'primero': 'jimi', 'último': 'hendrix'}

Esta función toma información textual simple y la coloca en una estructura de datos más
significativa que le permite trabajar con la información más allá de simplemente imprimirla. Las
cadenas 'jimi' y 'hendrix' ahora están etiquetadas como nombre y apellido. Puede extender fácilmente
esta función para aceptar valores opcionales como un segundo nombre, una edad, una ocupación o
cualquier otra información que desee almacenar sobre una persona. Por ejemplo, el siguiente cambio
también le permite almacenar la edad de una persona:

def build_person(nombre, apellido, edad=Ninguno):


"""Retornar un diccionario de información sobre una persona."""
persona = {'primero': nombre, 'apellido': apellido}
si la edad:
persona['edad'] = edad
persona de regreso

músico = build_person('jimi', 'hendrix', edad=27)


imprimir (músico)

140 Capítulo 8

MachineTranslatedbyGoogle

Agregamos un nuevo parámetro opcional edad a la definición de la función y asignamos


al parámetro el valor especial Ninguno, que se usa cuando una variable no tiene un valor
específico asignado. Puede pensar en Ninguno como un valor de marcador de posición. En las
pruebas condicionales, Ninguno se evalúa como Falso. Si la llamada a la función incluye un valor
para la edad, ese valor se almacena en el diccionario. Esta función siempre almacena el nombre
de una persona, pero también se puede modificar para almacenar cualquier otra información que
desee sobre una persona.

Usar una función con un ciclo while

Puede usar funciones con todas las estructuras de Python que ha aprendido hasta ahora. Por ejemplo,
usemos la función get_formatted_name() con un tiempo
bucle para saludar a los usuarios de manera más formal. Aquí hay un primer intento de saludar a
las personas usando su nombre y apellido:

saludador.py def get_formatted_name(nombre, apellido):


"""Retorna un nombre completo, con un formato ordenado."""
nombre_completo
nombre_completo = f"{nombre} {apellido}"
devolver nombre_com
nombre_completo.título()
pleto.título()

# ¡Este es un bucle infinito!


mientras que es cierto:

u print("\nPor favor dime tu nombre:")


f_name = input("Nombre: ")
l_name = input("Apellido: ")

formatted_name = get_formatted_name(f_name, l_name)


print(f"\nHola, {nombre_fo
{nombre_formateado}!
rmateado}!")
")

Para este ejemplo, usamos una versión simple de get_formatted_name() que no involucra
segundos nombres. El ciclo while le pide al usuario que ingrese su nombre, y le solicitamos su
nombre y apellido por separado u.

Pero hay un problema con este bucle while : no hemos definido una condición de salida.
¿Dónde coloca una condición de salida cuando solicita una serie de entradas? Queremos que el
usuario pueda salir lo más fácilmente posible, por lo que cada mensaje debe ofrecer una forma de
salir. La instrucción break ofrece una forma sencilla de salir del bucle en cualquiera de las
indicaciones:

def get_formatted_name(nombre, apellido):


"""Retorna un nombre completo, con un formato ordenado."""
nombre_com
nombre_completo
pleto = f"{nombre} {apellido}"
devolver nombre_com
nombre_completo.título()
pleto.título()
mientras que es cierto:

print("\nPor favor dime tu nombre:")


print("(ingrese 'q' en cualquier momento para salir)")

f_name = input("Nombre: ")


si f_nombre == 'q':
romper

Funciones 141

MachineTranslatedbyGoogle

l_name = input("Apellido: ")


si l_nombre == 'q':
romper

formatted_name = get_formatted_name(f_name, l_name)


print(f"\nHola, {nombre_formateado}!")

Agregamos un mensaje que informa al usuario cómo salir y luego salimos del bucle si el
usuario ingresa el valor de salida en cualquiera de las indicaciones.
Ahora el programa seguirá saludando a las personas hasta que alguien ingrese 'q'
para cualquier nombre:

Por favor, dígame su nombre:


(ingrese 'q' en cualquier momento para salir)
Nombre: eric
Apellido: Mathes

¡Hola, Eric Mathes!

Por favor, dígame su nombre:


(ingrese 'q' en cualquier momento para salir)
Nombre: q

Inténtalo tú mismo

8-6. Nombres de ciudades: escriba una función llamada city_country() que tome el nombre
de una ciudad y su país. La función debería devolver una cadena con el formato siguiente:

"Santiago, Chile"

Llame a su función con al menos tres pares de ciudades y países e imprima los
valores que se devuelven.

8-7. Álbum: escriba una función llamada make_album() que cree un diccionario que
describa un álbum de música. La función debe tomar el nombre de un artista y el título de
un álbum, y debe devolver un diccionario que contenga estos dos datos. Utilice la función
para crear tres diccionarios que representen diferentes álbumes. Imprima cada valor
devuelto para mostrar que los diccionarios están almacenando la información del álbum
correctamente.
Use Ninguno para agregar un parámetro opcional a make_album() que le permita
almacenar la cantidad de canciones en un álbum. Si la línea de llamada incluye un valor para
el número de canciones, agregue ese valor al diccionario del álbum. Realice al menos una
nueva llamada de función que incluya la cantidad de canciones en un álbum.

8-8. Álbumes de usuario: comience con su programa del ejercicio 8-7. escribe un rato
bucle que permite a los usuarios ingresar el artista y el título de un álbum. Una vez que
tenga esa información, llame a make_album() con la entrada del usuario e imprima el
diccionario que se crea. Asegúrese de incluir un valor de salida en el ciclo while .

142 Capítulo 8

MachineTranslatedbyGoogle

Pasar una lista

A menudo le resultará útil pasar una lista a una función, ya sea una lista de nombres,
números u objetos más complejos, como diccionarios. Cuando pasa una lista a una función,
la función obtiene acceso directo al contenido de la lista. Usemos funciones para que trabajar
con listas sea más eficiente.
Digamos que tenemos una lista de usuarios y queremos imprimir un saludo para
cada uno. El siguiente ejemplo envía una lista de nombres a una función llamada
greeting_users(),
greeting_users(), que saluda a cada persona en la lista individualmente:
individualmente:

saludar_usuarios.py def saludo_usuarios(nombres):


"""Imprime un saludo sencillo para cada usuario de la lista."""
para nombre en nombres:
msg = f"Hola, {nombre.título()}!"
imprimir (mensaje)

u nombres de usuario = ['hannah', 'ty', 'margot']


saludar_usuarios(nombres de usuario)

Definimos greeting_users() para que espere una lista de nombres, que asigna a los
nombres de los parámetros. La función recorre la lista que recibe e imprime un saludo para
cada usuario. En u definimos una lista de usuarios y luego pasamos la lista de nombres de
usuario a greeting_users() en nuestra llamada de función:

¡Hola Hannah!
¡Hola, Ty!
¡Hola, Margot!

Esta es la salida que queríamos. Cada usuario ve un saludo personalizado


personalizado y
puede llamar a la función en cualquier momento que desee saludar a un grupo específico
de usuarios.

Modificar una lista en una función

Cuando pasa una lista a una función, la función puede modificar la lista. Cualquier cambio
realizado en la lista dentro del cuerpo de la función es permanente, lo que le permite trabajar
de manera eficiente incluso cuando se trata de grandes cantidades de datos.
Considere una empresa que crea modelos impresos en 3D de diseños que envían
los usuarios. Los diseños que deben imprimirse se almacenan en una lista y, después de
imprimirse, se mueven a una lista separada. El siguiente código hace esto sin usar funciones:
# Comience con algunos diseños que deben imprimirse.
unprinted_designs = ['carcasa del teléfono', 'colgante de robot', 'dodecaedro']
imprimiendo _modelos.py
modelos_completados = []

# Simule la impresión de cada diseño, hasta que no quede ninguno.


# Mueva cada diseño a complete_models después de la impresión.
mientras que unprinted_designs:
diseño_actual = diseños_no_impresos.pop()

Funciones 143

MachineTranslatedbyGoogle

print(f"Modelo de impresión: {diseño_actual}")


modelos_completados.append(d
modelos_completados.append(diseño_actual)
iseño_actual)

# Mostrar todos los modelos completados.


print("\nSe han impreso los siguientes modelos:")
para modelo_completado en modelos_completa
modelos_completados:
dos:
imprimir (modelo_completado)
(modelo_completado)

Este programa comienza con una lista de diseños que deben imprimirse y una
lista vacía llamada complete_models a la que se moverá cada diseño después de que
se haya impreso. Mientras los diseños permanezcan en unprinted_designs, mientras
loop simula la impresión de cada diseño eliminando un diseño del final de la lista,
almacenándolo en current_design y mostrando un mensaje de que se está imprimiendo
el diseño actual. Luego agrega el diseño a la lista de modelos completos. Cuando el
bucle termina de ejecutarse, se muestra una lista de los diseños que se han impreso:

Modelo de impresión: dodecaedro


Modelo de impresión: robot colgante

Modelo de impresión: caja del teléfono

Se han impreso los siguientes modelos: caja del


teléfono con colgante de robot dodecaedro

Podemos reorganizar este código escribiendo dos funciones, cada una de las
cuales hace un trabajo específico. La mayor parte del código no cambiará;
simplemente lo estamos estructurando con más cuidado. La primera función se
encargará de imprimir los diseños, y la segunda resumirá las impresiones que se han realizado:

u def print_models(unprinted_designs, complete_models):


"""

Simule la impresión de cada diseño, hasta que no quede ninguno.


Mueva cada diseño a complete_models después de la impresión.
"""

mientras que unprinted_d


unprinted_designs:
esigns:
diseño_actual = diseños_no_impre
diseños_no_impresos.pop()
sos.pop()
print(f"Modelo de impresión: {diseño_actual}")
modelos_completados.append(d
modelos_completados.append(diseño_actual)
iseño_actual)

v def mostrar_modelos_
mostrar_modelos_completos(modelos_co
completos(modelos_completos):
mpletos):
"""Mostrar todos los modelos que se imprimieron."""
print("\nSe han impreso los siguientes modelos:")
para modelo_completado en modelos_completa
modelos_completados:
dos:
imprimir (modelo_completado)
(modelo_completado)

unprinted_designs
unprinted_designs = ['carcasa del teléfono', 'colgante de robot', 'dodecaedro']
modelos_completados
modelos_completados = []

imprimir_modelos (diseños_no_impre
(diseños_no_impresos,
sos, modelos_completa
modelos_completados)
dos)
mostrar_modelos_completados(modelos
mostrar_modelos_completados(modelos_completados)
_completados)

144 Capítulo 8

MachineTranslatedbyGoogle

En u definimos la función print_models() con dos parámetros: una lista de diseños


que deben imprimirse y una lista de modelos terminados. Dadas estas dos listas, la
función simula la impresión de cada diseño al vaciar la lista de diseños no impresos y
llenar la lista de modelos completos. En v definimos la función show_completed_models()
con un parámetro: la lista de modelos completados. Dada esta lista,
show_completed_models()
show_completed_mode ls() muestra el nombre de cada modelo que se imprimió.

Este programa tiene la misma salida que la versión sin funciones, pero el código
está mucho más organizado. El código que hace la mayor parte del trabajo se ha movido
a dos funciones separadas, lo que hace que la parte principal del programa sea más fácil
de entender. Mire el cuerpo del programa para ver cuánto más fácil es entender lo que
está haciendo este programa:

unprinted_designs
unprinted_designs = ['carcasa del teléfono', 'colgante de robot', 'dodecaedro']
modelos_completados
modelos_completados = []

imprimir_modelos (diseños_no_impre
(diseños_no_impresos,
sos, modelos_completa
modelos_completados)
dos)
mostrar_modelos_completados(modelo
mostrar_modelos_completados(modelos_completados)
s_completados)

Configuramos una lista de diseños sin imprimir y una lista vacía que contendrá
c ontendrá los
modelos completos. Luego, como ya hemos definido nuestras dos funciones, todo lo que
tenemos que hacer es llamarlas y pasarles los argumentos correctos. Llamamos a
print_models() y le pasamos las dos listas que necesita; como se esperaba, print_models()
simula la impresión de los diseños. Luego llamamos a show_completed_models() y le
pasamos la lista de modelos completados para que pueda informar los modelos que
se han impreso. Los nombres de funciones descriptivos permiten que otros lean este
código y lo entiendan, incluso sin comentarios.
Este programa es más fácil de ampliar y mantener que la versión sin funciones.
Si necesitamos imprimir más diseños más adelante, simplemente podemos llamar a
print_models() nuevamente. Si nos damos cuenta de que el código de impresión debe
modificarse, podemos cambiar el código una vez y nuestros cambios se realizarán en
todas partes donde se llame a la función. Esta técnica es más eficiente que tener que
actualizar el código por separado en varios lugares del programa.
Este ejemplo también demuestra la idea de que cada función debe tener un
trabajo específico. La primera función imprime cada diseño y la segunda muestra los
modelos completos. Esto es más beneficioso que usar una función para hacer ambos
trabajos. Si está escribiendo una función y nota que la función está realizando
demasiadas tareas diferentes, intente dividir el código en dos funciones.
Recuerde que siempre puede llamar a una función desde otra función, lo que puede
ser útil al dividir una tarea compleja en una serie de pasos.
Evitar que una función modifique una lista
A veces querrá evitar que una función modifique una lista. Por ejemplo, suponga
que comienza con una lista de diseños sin imprimir y escribe una función para
moverlos a una lista de modelos completos, como en el ejemplo anterior. Puede
decidir que, aunque haya impreso todos los diseños, desea conservar la lista original
de diseños no impresos para sus registros.

Funciones 145

MachineTranslatedbyGoogle

Pero debido a que movió todos los nombres de diseño fuera de unprinted_designs, la
lista ahora está vacía y la lista vacía es la única versión que tiene; el original se ha ido.
En este caso, puede solucionar este problema pasando a la función una copia de la lista,
no el original. Cualquier cambio que la función haga en la lista afectará solo a la copia,
dejando intacta la lista original.
Puede enviar una copia de una lista a una función como esta:

nombre_función(nombre_lista[:])

La notación de división [:] hace una copia de la lista para enviarla a la función.
Si no quisiéramos vaciar la lista de diseños no impresos en print_models.py , podríamos
llamar a print_models() así:

imprimir_modelos(diseños_no_imp
imprimir_modelos(diseños_no_impresos[:],
resos[:], modelos_co
modelos_completados)
mpletados)

La función print_models() puede hacer su trabajo porque todavía recibe el


nombres de todos los diseños no impresos. Pero esta vez usa una copia de la lista
original de diseños no impresos, no la lista actual de diseños no impresos . La lista

complete_models se llenará con los nombres de los modelos impresos como lo hacía
antes, pero la lista original de diseños no impresos no se verá afectada por la función.

Aunque puede conservar el contenido de una lista pasando una copia a sus
funciones, debe pasar la lista original a funciones a menos que tenga una razón específica
para pasar una copia. Es más eficiente que una función trabaje con una lista existente
para evitar usar el tiempo y la memoria necesarios para hacer una copia separada,
especialmente cuando trabaja con listas grandes.

Inténtalo tú mismo

8-9. Mensajes: haga una lista que contenga una serie de mensajes de texto cortos. Pase la lista
a una función llamada show_messages(), que imprime cada mensaje de texto.

8-10. Envío de mensajes: comience con una copia de su programa del ejercicio 8-9.
Escriba una función llamada enviar_mensajes() que imprima cada mensaje de texto y mueva
cada mensaje a una nueva lista llamada mensajes_enviados a medida que se imprime.
Después de llamar a la función, imprima ambas listas para asegurarse de que los mensajes se
movieron correctament
correctamente.
e.

8-11. Mensajes archivados: comience con su trabajo del ejercicio 8-10. Llame a la función
send_messages()
send_messages() con una copia de la llista
ista de mensajes. Después de llamar a la función, imprima
ambas listas para mostrar que la lista original ha conservado sus mensajes.

146 Capítulo 8

MachineTranslatedbyGoogle

Pasar un número arbitrario de argumentos


A veces, no sabrá de antemano cuántos argumentos
argumentos debe aceptar una función.
Afortunadamente,
Afortunadamente, Python permite que una función recopile un número arbitrario de
argumentos de la declaración de llamada.
Por ejemplo, considere una función que construye una pizza. Necesita aceptar una
cantidad de ingredientes, pero no se puede saber de antemano cuántos ingredientes
ingredientes querrá
una persona. La función del siguiente ejemplo tiene un parámetro, *toppings, pero este
parámetro recopila tantos argumentos como proporciona la línea de llamada:

pizza.py def hacer_pizza(*ingredientes):


"""Imprimir la lista de toppings que se han solicitado."""
imprimir (coberturas)

hacer_pizza('pepperoni')
make_pizza('champiñones', 'pimientos verdes', 'queso extra')

El asterisco en el nombre del parámetro *toppings le dice a Python que haga una
vaciar la tupla llamada toppings y empaquetar cualquier valor que reciba en esta tupla.
La llamada a print() en el cuerpo de la función produce una salida que muestra que Python
puede manejar una llamada de función con un valor y una llamada con tres valores. Trata
las diferentes llamadas de manera similar. Tenga en cuenta que Python empaqueta los
argumentos en una tupla, incluso si la función recibe solo un valor:

('pepperoni',)
('champiñones', 'pimientos verdes', 'queso extra')

Ahora podemos reemplazar la llamada print() con un bucle que se ejecuta a través del
lista de ingredientes y describe la pizza que se pide:

def hacer_pizza(*ingredientes):
"""Resume la pizza que estamos a punto de hacer."""
print("\nPreparando una pizza con los siguientes ingredientes:")
para cubrir en coberturas:
imprimir(f"- {topping}")

hacer_pizza('pepperoni')
make_pizza('champiñones', 'pimientos verdes', 'queso extra')

La función responde apropiadamente,


apropiadamente, ya sea que reciba un valor o
tres valores:
Hacer una pizza con los siguientes ingredientes: - pepperoni

Elaboración de una pizza con los siguientes ingredientes: -


champiñones
- pimientos verdes
- queso extra

Funciones 147

MachineTranslatedbyGoogle

Esta sintaxis funciona sin importar cuántos argumentos reciba la función.

Mezclar argumentos posicionales y arbitrarios

Si desea que una función acepte varios tipos diferentes de argumentos, el parámetro que acepta
un número arbitrario de argumentos debe colocarse en último lugar en la definición de la función.
Python primero hace coincidir los argumentos posicionales y de palabras clave y luego recopila los
argumentos restantes en el parámetro final.

Por ejemplo, si la función necesita tomar un tamaño para la pizza, ese


El parámetro debe ir antes del parámetro *toppings:

def make_pizza(size, *toppings):


"""Resumir la pizza que estamos a punto de hacer."""
print(f"\nHacer una pizza de {tamaño} pulgadas con los siguientes ingredientes:") para
agregar ingredientes: print(f"- {topping}")

make_pizza(16, 'pepperoni')
make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')

En la definición de la función, Python asigna el primer valor que recibe al tamaño del
parámetro. Todos los demás valores que vienen después se almacenan en las coberturas de tupla.
Las llamadas de función incluyen un argumento para el tamaño primero, seguido de tantos
ingredientes como sea necesario.
Ahora cada pizza tiene un tamaño y una cantidad de ingredientes, y cada información se
imprime en el lugar adecuado, mostrando el tamaño primero y los ingredientes después:

Hacer una pizza de 16 pulgadas con los siguientes ingredientes:


- pepperoni

Hacer una pizza de 12 pulgadas con los siguientes ingredientes:


- champiñones
- pimientos verdes
- queso extra

N ota A menudo verá el nombre de parámetro genérico *args, que recopila información posicional arbitraria .
argumentos como este.
Uso de argumentos de palabras clave arbitrarias

A veces querrá aceptar un número arbitrario de argumentos, pero no sabrá de antemano qué tipo de
información se pasará a la función. En este caso, puede escribir funciones que acepten tantos pares
clave-valor como proporcione la declaración de llamada. Un ejemplo implica la creación de perfiles de
usuario: sabe que obtendrá información sobre un usuario, pero no está seguro de qué tipo de
información recibirá. La función build_profile() en el

148 Capítulo 8

MachineTranslatedbyGoogle

El siguiente ejemplo siempre incluye un nombre y un apellido, pero también acepta


un número arbitrario de argumentos de palabras clave:

perfil_usuario.py def build_prof


build_profile(primero,
ile(primero, último, **información
**información_usuario):
_usuario):
"""Crear un diccionario que contenga todo lo que sabemos sobre un usuario."""
u user_info['first_name'] = primero
user_info['last_name'] = último
devolver información_de_usuario

perfil_usuario
perfil_usuario = build_pro
build_profile('alberto
file('alberto',', 'einstein',
ubicación='princeton',
campo='física')
imprimir (perfil_usu
(perfil_usuario)
ario)

La definición de build_profile() espera un nombre y apellido, y luego le permite


al usuario pasar tantos pares de nombre-valor como quiera. Los asteriscos dobles
antes del parámetro **user_info hacen que Python cree un diccionario vacío llamado
user_info y empaquete cualquier par de nombre-valor
nombre-valor que reciba en este diccionario.
Dentro de la función, puede acceder a los pares de valores clave en user_info tal

como lo haría con cualquier diccionario.


En el cuerpo de build_profile(), agregamos el nombre y apellido al diccionario
user_info porque siempre recibiremos estas dos piezas de información del usuario
u, y aún no se han colocado en el diccionario. Luego devolvemos el diccionario
user_info a la línea de llamada de función.
Llamamos a build_profile(), pasándole el nombre de pila 'albert', el apellido 'einstein' y
los dos pares clave-valor location='princeton' y field='physics'. Asignamos el perfil devuelto a
user_profile e imprimimos user_profile:

{'ubicación': 'princeton', 'campo': 'física',


'nombre': 'alberto', 'apellido': 'einstein'}

El diccionario devuelto contiene el nombre y apellido del usuario y,


en este caso, la ubicación y el campo de estudio también. La función funcionaría
sin importar cuántos pares clave-valor adicionales se proporcionen en la llamada a
la función.
Puede mezclar valores posicionales, de palabra clave y arbitrarios de muchas
maneras diferentes al escribir sus propias funciones. Es útil saber que existen todos
estos tipos de argumentos porque los verá con
c on frecuencia cuando comience a leer
el código de otras personas. Se necesita práctica para aprender a usar los diferentes
tipos correctamente y saber cuándo usar cada tipo. Por ahora, recuerde usar el
enfoque más simple que haga el trabajo. A medida que progrese, aprenderá a usar el
enfoque más eficiente cada vez.

N ota A menudo verá el nombre del parámetro **kwargs utilizado para recopilar argumentos de palabras clave
no específicos.

Funciones 149

MachineTranslatedbyGoogle

Inténtalo tú mismo

8-12. Sándwiches: escriba una función que acepte una lista de artículos que una persona quiere en
un sándwich. La función debe tener un parámetro que recopile tantos elementos como proporcione la
llamada a la función, y debe imprimir un resumen del sándwich que se está ordenando. Llame a la
función tres veces, usando un número diferente de argumentos cada vez.

8-13. Perfil de usuario: Comience con una copia de user_profile.py de la página 149. Cree un perfil
de usted mismo llamando a build_profile(), usando su nombre y apellido y otros tres pares clave-
valor que lo describan.

8-14. Coches: escriba una función que almacene información sobre un coche en un diccionario.

La función siempre debe recibir un fabricante y un nombre de modelo. Entonces debería aceptar un
número arbitrario de argumentos de palabras clave. Llame a la función con la información requerida
y otros dos pares de nombre y valor, como un color o una característica opcional. Su función debería
funcionar para una llamada como esta:

coche = make_car('subaru',
make_car('subaru', 'outback', color='blue', tow_package=True)
Imprima el diccionario que se devuelve para asegurarse de que toda la información se
almacenó correctamente.

Almacenamiento
Almacenamiento de sus funciones en módulos

Una ventaja de las funciones es la forma en que separan los bloques de código de su programa
principal. Al usar nombres descriptivos para sus funciones, su programa principal será mucho más
fácil de seguir. Puede ir un paso más allá almacenando sus funciones en un archivo separado
llamado módulo y luego importando
ese módulo en su programa principal. Una declaración de importación le dice a Python que haga
que el código en un módulo esté disponible en el archivo de programa que se está ejecutando actualmente.
Almacenar sus funciones en un archivo separado le permite ocultar los detalles del código de su
programa y enfocarse en su lógica de nivel superior. También le permite reutilizar funciones en muchos
programas diferentes. Cuando almacena sus funciones en archivos separados, puede compartir esos
archivos con otros programadores sin tener que compartir todo su programa. Saber cómo importar
funciones también le permite usar bibliotecas de funciones que otros programadores han escrito.
Hay varias formas de importar un módulo y le mostraré cada una de ellas brevemente.

Importación de un módulo completo

Para comenzar a importar funciones, primero debemos crear un módulo. un modulo


es un archivo que termina en .py que contiene el código que desea importar a su

150 Capítulo 8

MachineTranslatedbyGoogle

programa. Hagamos un módulo que contenga la función make_pizza(). Para hacer este
módulo, eliminaremos todo del archivo pizza.py excepto la función make_pizza():

pizza.py def make_pizza(tamaño, *ingredientes):


"""Resume la pizza que estamos a punto de hacer."""
print(f"\nPreparando una pizza de {tamaño} pulgadas con los siguientes ingredientes:")
ingredientes:")
para cubrir en coberturas:
imprimir(f"- {topping}")

Ahora crearemos un archivo separado llamado making_pizzas.py en el mismo


directorio que pizza.py. Este archivo importa el módulo que acabamos de crear y luego
realiza dos llamadas a make_pizza():

haciendo importar pizza


_pizzas.py
u pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')

Cuando Python lee este archivo, la línea import pizza le dice a Python que abra
el archivo pizza.py y copie todas las funciones de este en este programa. En realidad,
no ve el código que se copia entre archivos porque Python copia el código detrás de
escena justo antes de que se ejecute el programa. Todo lo que necesita saber es que
cualquier función definida en pizza.py ahora estará disponible en making_pizzas.py.

Para llamar a una función desde un módulo importado, ingresa el nombre del
módulo que importaste, pizza, seguido del nombre de la función, make_pizza(),
separados por un punto u. Este código produce el mismo resultado que el programa
original que no importó un módulo:

Hacer una pizza de 16 pulgadas con los siguientes ingredientes:


- pepperoni

Hacer una pizza de 12 pulgadas con los siguientes ingredientes:


- champiñones
- pimientos verdes
- queso extra

Este primer enfoque de importación, en el que simplemente escribe import


seguido del nombre del módulo, hace que todas las funciones del módulo estén
disponibles en su programa. Si usa este tipo de declaración de importación para importar
un módulo completo llamado module_name.py, cada función en el módulo está disponible
a través de la siguiente sintaxis:

nombre_módulo.nombre_función()

Funciones 151

MachineTranslatedbyGoogle

Importación de funciones específicas

También puede importar una función específica de un módulo. Aquí está la sintaxis
general para este enfoque:

from nombre_módulo import nombre_función

Puede importar tantas funciones como desee de un módulo separando el nombre


de cada función con una coma:

from nombre_módulo importar función_0 , función_1 , función_2

El ejemplo de making_pizzas.py se vería así si queremos importar


solo la función que vamos a usar:

de pizza importar hacer_pizza

hacer_pizza(16, 'pepperoni')
make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')

Con esta sintaxis, no necesita usar la notación de puntos cuando llama a una
función. Debido a que importamos explícitamente
explícitamente la función make_pizza() en la
declaración de importación , podemos llamarla por su nombre cuando usamos la función.

Uso de as para dar un alias a una función

Si el nombre de una función que está importando puede entrar en conflicto con
un nombre existente en su programa o si el nombre de la función es largo, puede
usar un alias corto y único, un nombre alternativo similar a un apodo para la función.
Le dará a la función este apodo especial cuando importe la función.

Aquí le damos a la función make_pizza() un alias, mp(), importando


hacer_pizza como mp. La palabra clave as cambia el nombre de una función utilizando el alias que
proporciona:

de pizza importar make_pizza como mp

mp (16, 'pepperoni')
mp(12, 'champiñones', 'pimientos verdes', 'queso extra')

La declaración de importación que se muestra aquí cambia el nombre de la función make_pizza() a


mp() en este programa. Cada vez que queramos llamar a make_pizza() , simplemente podemos
escribir mp() en su lugar, y Python ejecutará el código en make_pizza() mientras evita cualquier
confusión con otra función make_pizza() que podría haber escrito en este archivo de programa.

La sintaxis general para proporcionar un alias es:

from nombre_módulo importar nombre_función como fn

152 Capítulo 8

MachineTranslatedbyGoogle

Uso de as para dar un alias a un módulo

También puede proporcionar un alias para un nombre de módulo. Darle a un módulo un


alias corto, como p para pizza, le permite llamar a las funciones del módulo más rápidamente.
Llamar a p.make_pizza() es más conciso
c onciso que llamar a pizza.make_pizza():

importar pizza como p

p.hacer_pizza(16, 'pepperoni')
p.make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')

El módulo pizza recibe el alias p en la declaración de importación , pero todas las


funciones del módulo conservan sus nombres originales. Llamar a las funciones escribiendo
p.make_pizza() no solo es más conciso que escribir pizza.make_pizza(), sino que también
redirige su atención del nombre del módulo y le permite concentrarse en los nombres
descriptivos de sus funciones. Estos nombres de funciones, que le indican claramente lo
que hace cada función, son más importantes para la legibilidad de su código que usar el
nombre completo del módulo.
La sintaxis general para este enfoque es:

importar module_name como mn

Importación de todas las funciones en un módulo

Puede decirle a Python que importe cada función en un módulo usando el operador asterisco
(*) :

*
de la importación de pizzas

hacer_pizza(16, 'pepperoni')
make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')

El asterisco en la declaración de importación le dice a Python que copie todas las


funciones del módulo pizza en este archivo de programa. Debido a que cada función se
importa, puede llamar a cada función por su nombre sin usar la notación de puntos. Sin
embargo, es mejor no usar este enfoque cuando trabaja con módulos más grandes que
no escribió: si el módulo tiene un nombre de función que coincide con un nombre existente
en su proyecto, puede obtener algunos resultados inesperados. Python puede ver varias
funciones o variables con el mismo nombre y, en lugar de importar todas las funciones por
separado, las sobrescribirá.
El mejor enfoque es importar la función o funciones que desee, o importar el módulo
completo y usar la notación de puntos. Esto conduce a un código claro que es fácil de leer
y comprender. Incluyo esta sección para que reconozca declaraciones de importación
como las siguientes cuando las vea en el código de otras personas:

*
de la importación de module_name

Funciones 153

MachineTranslatedbyGoogle

Funciones de estilo
Debe tener en cuenta algunos detalles cuando esté diseñando funciones.
Las funciones deben tener nombres descriptivos, y estos nombres deben usar letras minúsculas
y guiones bajos. Los nombres descriptivos lo ayudan a usted y a otros a comprender lo que su
código está tratando de hacer. Los nombres de los módulos también deben usar estas convenciones.

Cada función debe tener un comentario que explique de manera concisa lo que hace la
función. Este comentario debería aparecer inmediatamente después de la definición de la función
y usar el formato docstring. En una función bien documentada, otros programadores pueden usar la
función leyendo solo la descripción en la cadena de documentación. Deberían poder confiar en que
el código funciona como se describe y, siempre que sepan el nombre de la función, los argumentos
que necesita y el tipo de valor que devuelve, deberían poder usarlo en sus programas.

Si especifica un valor predeterminado para un parámetro, no se deben usar espacios


a cada lado del signo igual:

def nombre_función (parámetro_0, parámetro_1='va


parámetro_1='valor
lor predeterminado ''))

Se debe usar la misma convención para los argumentos de palabras clave en las llamadas a
funciones:

nombre_función(valor_0,
nombre_función(valor_0, parámetro_1='va
parámetro_1='valor')
lor')

PEP 8 (https
(https://
:// www.p
www.python.org/ dev/ peps/pep-0008/) recomienda que limite las líneas de
ython.org/
código a 79 caracteres para que cada línea sea visible en una ventana de editor de tamaño razonable.
Si un conjunto de parámetros hace que la definición de una función tenga más de 79 caracteres,
presione Intro después del paréntesis de apertura en la línea de definición. En la siguiente línea,
presione tabulador dos veces para separar la lista de argumentos del cuerpo de la función, que solo
tendrá una sangría de un nivel.

La mayoría de los editores alinean automáticamente cualquier línea adicional de parámetros para
coincida con la sangría que ha establecido en la primera línea:

def nombre_función (
parámetro_0, parámetro_1, parámetro_2,
parámetro_3, parámetro_4, parámetro_5):
cuerpo funcional...
Si su programa o módulo tiene más de una función, puede separar
califique cada una con dos líneas en blanco para que sea más fácil ver dónde termina una
función y comienza la siguiente.
Todas las declaraciones de importación deben escribirse al principio de un archivo.
La única excepción es si usa comentarios al comienzo de su archivo para describir el programa
general.

154 Capítulo 8

MachineTranslatedbyGoogle

Inténtalo tú mismo

8-15. Modelos de impresión: coloque las funciones para el ejemplo modelos_impresión.py en un


archivo separado llamado funciones_impresión.py. Escriba una declaración de importación en la
parte superior de printing_models.py y modifique el archivo para usar las funciones importadas.

8-16. Importaciones: utilizando un programa que escribió que tiene una función, almacene esa
función en un archivo separado. Importe la función a su archivo de programa principal y llame a la
función utilizando cada uno de estos enfoques:

importar module_name
from nombre_módulo import nombre_función
from nombre_módulo importar nombre_función como fn
importar module_name como mn
*
de la importación de module_name

8-17. Funciones de diseño: elija tres programas cualquiera que haya escrito para este capítulo y
asegúrese de que sigan las pautas de diseño descritas en esta sección.

Resumen
En este capítulo aprendiste a escribir funciones y pasar argumentos para que tus
funciones tengan acceso a la información que necesitan para hacer su trabajo. Aprendió a
usar argumentos posicionales y de palabras clave, y a aceptar un número arbitrario de
argumentos. Viste funciones que muestran resultados y funciones que devuelven valores.
Aprendió a usar funciones con listas, diccionarios, declaraciones if y bucles while . También
vio cómo almacenar sus funciones en archivos separados llamados módulos, por lo que
sus archivos de programa serán más simples y fáciles de entender. Finalmente, aprendió a
diseñar sus funciones para que sus programas continúen bien estructurados y sean tan
fáciles de leer como sea posible para usted y otros.

Uno de sus objetivos como programador debe ser escribir código simple que haga lo
que usted quiere, y las funciones lo ayudarán a hacerlo. Le permiten escribir bloques de
código y dejarlos solos una vez que sabe que funcionan. Cuando sabe que una función
hace su trabajo correctamente, puede confiar en que seguirá funcionando y pasará a su
siguiente tarea de codificación.
Las funciones le permiten escribir código una vez y luego reutilizar ese código
tantas veces como desee. Cuando necesite ejecutar el código en una función, todo lo
que necesita hacer es escribir una llamada de una línea y la función hace su trabajo.
Cuando necesite modificar el comportamiento de una función, solo tiene que modificar

un bloque de código y su cambio surtirá efecto en todos los lugares donde haya realizado
una llamada a esa función.
El uso de funciones hace que sus programas sean más fáciles de leer, y los buenos
nombres de funciones resumen lo que hace cada parte de un programa. Leer una serie de
llamadas a funciones le da una idea mucho más rápida de lo que hace un programa que
leer una larga serie de bloques de código.

Funciones 155

MachineTranslatedbyGoogle

Las funciones también hacen que su código sea más fácil de probar y depurar. cuando el bulto
del trabajo de su programa lo realiza un conjunto de funciones, cada una de las cuales tiene un
trabajo específico, es mucho más fácil probar y mantener el código que ha escrito.
Puede escribir un programa separado que llame a cada función y pruebe si cada función funciona
en todas las situaciones que pueda encontrar. Cuando haga esto, puede estar seguro de que sus
funciones funcionarán correctamente cada vez que las llame.

En el Capítulo 9 aprenderá a escribir clases. Las clases combinan funciones y


datos en un paquete ordenado que se puede utilizar de manera flexible y eficiente.
156 Capítulo 8

MachineTranslatedbyGoogle

9
Clases

La programación orientada a objetos es


uno de los enfoques más efectivos para
escribir software. En la programación
programación orientada a objetos,
escriba clases que representen cosas y
situaciones del mundo real, y cree objetos basados en
estas clases. Cuando escribes una clase, defines el
comportamiento general que puede tener toda una categoría de objeto
Cuando crea objetos individuales de la clase, cada objeto se equipa automáticamente
con el comportamiento general; luego puede darle a cada objeto las características únicas
que desee. Se sorprenderá de lo bien que se pueden modelar situaciones del mundo real
con la programación orientada a objetos.
Crear un objeto a partir de una clase se denomina creación de instancias y se trabaja
con instancias de una clase. En este capítulo, escribirá clases y creará instancias de esas
clases. Especificará el tipo de información que se puede almacenar en las instancias y
definirá las acciones que se pueden realizar con estas instancias.
También escribirá clases que amplían la funcionalidad de las clases existentes, por lo que

MachineTranslatedbyGoogle

clases similares pueden compartir código de manera eficiente. Almacenará sus clases en módulos
e importará clases escritas por otros programadores en sus propios archivos de programa.

Comprender la programación orientada a objetos te ayudará a ver el mundo como lo hace


un programador. Lo ayudará a conocer realmente su código, no solo lo que sucede línea por
línea, sino también los conceptos más importantes detrás de él.
Conocer la lógica detrás de las clases lo entrenará para pensar lógicamente para que pueda escribir
programas que aborden de manera efectiva casi cualquier problema que encuentre.
Las clases también te facilitan la vida a ti y a los demás programadores
programadores con los que trabajarás a
medida que te enfrentas a desafíos cada vez más complejos. Cuando usted y otros programadores
escriban código basado en el mismo tipo de lógica, podrán entender el trabajo de los demás. Sus
programas tendrán sentido para muchos colaboradores, lo que permitirá que todos logren más.

Crear y usar una clase


Puedes modelar casi cualquier cosa usando clases. Comencemos escribiendo una clase simple, Perro,

que represente un perro, no un perro en particular, sino cualquier perro.


¿Qué sabemos sobre la mayoría de los perros domésticos? Bueno, todos tienen un nombre y una edad.
También sabemos que la mayoría de los perros se sientan y dan vueltas. Esas dos piezas de
información (nombre y edad) y esos dos comportamiento
comportamientos
s (sentarse y darse la vuelta) irán en nuestra
clase de perros porque son comunes a la mayoría de los perros. Esta clase le dirá a Python cómo
hacer un objeto que represente a un perro. Después de escribir nuestra clase, la usaremos para crear
instancias individuales, cada una de las cuales representa un perro específico.

Crear la clase de perro


Cada instancia creada a partir de la clase Perro almacenará un nombre y una edad, y le daremos a
cada perro la capacidad de sentarse() y darse la vuelta():

dog.py u clase Perro:


v """Un simple intento de modelar un perro."""

w def __init__(yo, nombre, edad):


"""Inicialice los atributos de nombre y edad."""
X self.nombre = nombre
self.edad = edad

y def sentarse(auto):
Simule un perro sentado en respuesta a una orden .
print(f"{self.name} ahora está sentado.")

def roll_over(auto):
"""Simule darse la vuelta en respuesta a un comando."""
print(f"{self.name} volcado!")

Hay mucho que notar aquí, pero no te preocupes. Verá esta estructura a lo largo de este
capítulo y tendrá mucho tiempo para acostumbrarse a ella. en ti nosotros

158 Capítulo 9

MachineTranslatedbyGoogle

definir una clase llamada Perro. Por convención, los nombres en mayúsculas se refieren
a clases en Python. No hay paréntesis en la definición de la clase porque estamos creando
esta clase desde cero. En v escribimos una cadena de documentación que describe lo que
hace esta clase.

El método __init__()
Una función que es parte de una clase es un método. Todo lo que aprendió sobre las
funciones también se aplica a los métodos; la única diferencia práctica por ahora es la forma
en que llamaremos a los métodos. El método __init__() en w es un método especial que
Python ejecuta automáticamente cada vez que creamos una nueva instancia basada en la
clase Perro . Este método tiene dos guiones bajos iniciales y dos guiones bajos finales, una
convención que ayuda a evitar que los nombres de métodos predeterminados de Python
entren en conflicto con los nombres de sus métodos. Asegúrese de usar dos guiones bajos
a cada lado de __init__(). Si usa solo uno en cada lado, el método no se llamará
automáticamente cuando use su clase, lo que puede generar errores que son difíciles de
identificar.
Definimos el método __init__() para que tenga tres parámetros: self, name y age. El

parámetro self es obligatorio en la definición del método y debe aparecer antes que los
demás parámetros. Debe incluirse en la definición porque cuando Python llame a este
método más adelante (para crear una instancia de Dog), la llamada al método pasará
automáticamente el argumento self . Cada llamada de método asociada con una instancia
pasa automáticamente a self, que es una referencia a la instancia misma; le da a la instancia
individual acceso a los atributos y métodos de la clase. Cuando creamos una instancia de
Dog, Python llamará al método __init__() de la clase Dog . Pasaremos Dog()

un nombre y una edad como argumentos; self se pasa automáticamente, por lo que no
necesitamos pasarlo. Siempre que queramos crear una instancia de la clase Perro ,
proporcionaremos valores solo para los dos últimos parámetros, nombre y edad.
Las dos variables definidas en x tienen cada una el prefijo self. Cualquier variable con
el prefijo self está disponible para todos los métodos de la clase, y también podremos
acceder a estas variables a través de cualquier instancia creada a partir de la clase.
La línea self.name = name toma el valor asociado con el nombre del parámetro
y lo asigna al nombre de la variable , que luego se adjunta a la instancia que se está
creando. El mismo proceso ocurre con self.edad = edad. Las variables a las que se puede
acceder a través de instancias como esta se denominan atributos.
La clase Dog tiene otros dos métodos definidos: sit() y roll_over() y.
Debido a que estos métodos no necesitan información adicional para ejecutarse, solo los
definimos para que tengan un parámetro, self. Las instancias que creemos más tarde
tendrán acceso a estos métodos. En otras palabras, podrán sentarse y darse la vuelta. Por
ahora, sit() y roll_over() no hacen mucho. Simplemente imprimen un mensaje que dice que
el perro está sentado o volteándose. Pero el concepto se puede extender a situaciones
realistas: si esta clase fuera parte de un juego de computadora real, estos métodos
contendrían un código para hacer que un perro animado se siente y se dé la vuelta. Si esta
clase se escribió para controlar un robot, estos métodos dirigirían los movimientos que hacen
que un perro robótico se siente y se dé la vuelta.

Clases 159

MachineTranslatedbyGoogle

Crear una instancia de una clase


Piense en una clase como un conjunto de instrucciones sobre cómo crear una instancia. La clase Dog es un

conjunto de instrucciones que le dice a Python cómo crear instancias individuales que representen perros específicos.

Hagamos una instancia que represente a un perro específico:

perro de clase:
--recorte--

u mi_perro = Perro('Willie', 6)

v print(f"El nombre de mi perro es {mi_perro.nombre}").


w print(f"Mi perro tiene {mi_perro.edad} años")

La clase Dog que estamos usando aquí es la que acabamos de escribir en el ejemplo anterior. En u le decimos
a Python que cree un perro cuyo nombre sea 'Willie' y cuya edad sea 6. Cuando Python lee esta línea, llama al

método __init__() en Dog con los argumentos 'Willie' y 6. El método __init__() crea una instancia que representa a
este perro en particular y establece los atributos de nombre y edad usando l os valores que proporcionamos. Python

luego devuelve una instancia que representa a este perro. Asignamos esa instancia a la variable mi_perro. La convención
de nomenclatura es útil aquí: generalmente podemos suponer que un nombre en mayúsculas como Perro

se refiere a una clase, y un nombre en minúsculas como my_dog se refiere a una única instancia creada a partir de una
clase.

Accediendo a los Atributos

Para acceder a los atributos de una instancia, utiliza la notación de puntos. En v accedemos al valor del nombre del
atributo de mi_perro escribiendo:

mi_perro.nombre

La notación de puntos se usa a menudo en Python. Esta sintaxis demuestra cómo Python encuentra el
valor de un atributo. Aquí Python mira la instancia my_dog
y luego encuentra el nombre del atributo asociado con my_dog. Este es el mismo atributo al que se hace referencia

como self.name en la clase Dog. En w usamos el mismo enfoque para trabajar con el atributo edad.

El resultado es un resumen de lo que sabemos sobre my_dog:

El nombre de mi perro es Willie.


Mi perro tiene 6 años.

Métodos de llamada

Después de crear una instancia de la clase Dog, podemos usar la notación de puntos para llamar a cualquier método

definido en Dog. Hagamos que nuestro perro se siente y se dé la vuelta:

perro de clase:
--recorte--

160 Capítulo 9

MachineTranslatedbyGoogle

mi_perro = Perro('Willie', 6)
mi_perro.sentarse()
mi_perro.roll_over()

Para llamar a un método, proporcione el nombre de la instancia (en este caso, mi_perro)
y el método al que desea llamar, separados por un punto. Cuando Python lee my_dog.sit(),
busca el método sit() en la clase Dog y ejecuta ese código. Python interpreta la línea
my_dog.roll_over() de la misma manera.
my_dog.roll_over()
Ahora Willie hace lo que le decimos:

Willie ahora está sentado.


¡Willie se dio la vuelta!

Esta sintaxis es bastante útil. Cuando a los atributos y métodos se les han dado nombres
descriptivos apropiados como nombre, edad, sit() y roll_over(), podemos inferir fácilmente qué se
supone que debe hacer un bloque de código, incluso uno que nunca hayamos visto antes.

Creación de varias instancias

Puede crear tantas instancias de una clase como necesite. Vamos a crear un segundo perro
llamado tu_perro:

perro de clase:
--recorte--

mi_perro = Perro('Willie', 6)
tu_perro = Perro('Lucy', 3)

print(f"El nombre de mi perro es {mi_perro.nombre}").


print(f"Mi perro tiene {mi_perro.edad} años")
mi_perro.sentarse()

print(f"\nEl nombre de tu perro es {tu_perro.nombre}").


print(f"Tu perro tiene {tu_perro.edad} años").
tu_perro.siéntate()

En este ejemplo, creamos un perro llamado Willie y un perro llamado Lucy.


Cada perro es una instancia separada con su propio conjunto de atributos, capaz de realizar el
mismo conjunto de acciones:

El nombre de mi perro es Willie.


Mi perro tiene 6 años.
Willie ahora está sentado.

Tu perro se llama Lucy.


Tu perro tiene 3 años.
Lucy ahora está sentada.

Incluso si usáramos el mismo nombre y edad para el segundo perro, Python aún crearía
una instancia separada de la clase Perro . Puedes hacer

Clases 161

MachineTranslatedbyGoogle

tantas instancias de una clase como necesite, siempre que asigne a cada instancia
un nombre de variable único o que ocupe un lugar único en una lista o diccionario.

Inténtalo tú mismo

9-1. Restaurante: Haz una clase llamada Restaurante. El método __init__() para Restaurante debe
almacenar dos atributos: un nombre_restaurante y un tipo_cocina .

Haz un método llamado describe_restaurant() que imprima estas dos piezas de información, y un método

llamado open_restaurant()
open_restaurant() que imprima un mensaje que indique que el restaurante está abierto.

Cree una instancia llamada restaurante de su clase. Imprima los dos atributos individualmente

y luego llame a ambos métodos.

9-2. Tres Restaurantes:


Restaurantes: Comience con su clase del Ejercicio 9-1. Cree tres instancias diferentes de la
clase y llame a describe_restaurant()
describe_restaurant() para cada instancia.

9-3. Usuarios: Haz una clase llamada Usuario. Crea dos atributos llamados first_name

y last_name, y luego cree varios otros atributos que normalmente se almacenan en un perfil de usuario.

Cree un método llamado describe_user() que imprima un resumen de la información del usuario. Cree otro

método llamado greeting_user() que imprima un saludo personalizado para el usuario.

Cree varias instancias que representen a diferentes usuarios y llame a ambos métodos
para cada usuario.

Trabajar con clases e instancias


Puede usar clases para representar muchas situaciones del mundo real. Una vez que
escriba una clase, pasará la mayor parte de su tiempo trabajando con instancias creadas
a partir de esa clase. Una de las primeras tareas que querrá hacer es modificar los
atributos asociados con una instancia en particular. Puede modificar los
l os atributos de una
instancia directamente o escribir métodos que actualicen los atributos de formas específicas.

la clase de coche

Escribamos una nueva clase que represente un automóvil. Nuestra clase almacenará
información sobre el tipo de automóvil con el que estamos trabajando y tendrá un
método que resuma esta información:

Coche de clase:
coche.py
"""Un simple intento de representar un coche."""

u def __init__(auto, marca, modelo, año):


"""Inicialice
"""Inicialice los atributos para describir un automóvil".""
automóvil".""
self.hacer = hacer

162 Capítulo 9

MachineTranslatedbyGoogle

self.modelo = modelo
self.año = año

v def get_descriptive_name(self):
get_descriptive_name(self):
"""Retorna un nombre descriptivo con un formato ordenado."""
long_name = f"{self.year} {self.manufacturer} {self.model}"

devuelve nombre_largo.título()
nombre_largo.título()

w mi_auto_nuevo = Auto('audi', 'a4', 2019)


print(my_new_car.get_descriptive_name())

En u en la clase Car , definimos el método __init__() con el self

parámetro primero, tal como lo hicimos antes con nuestra clase Dog . También le damos otros
tres parámetros: marca, modelo y año. El método __init__() toma estos parámetros y los asigna
a los atributos que se asociarán con las instancias creadas a partir de esta clase. Cuando
fabricamos un coche nuevo
instancia, necesitaremos especificar una marca, modelo y año para nuestra instancia.

En v definimos un método llamado get_descriptive_name() que pone el año, la marca y el


modelo de un automóvil en una cadena que describe claramente el automóvil. Esto nos evitará tener
que imprimir el valor de cada atributo individualmente. Para trabajar con los valores de los atributos
en este método, usamos self.make, self.model y self.year.
En w creamos una instancia de la clase Car y la asignamos a la variable my_new_car. Luego llamamos
a get_descriptive_name()
get_descriptive_name() para mostrar qué tipo de automóvil tenemos:

2019 Audi A4

Para hacer la clase más interesante, agregue


agreguemos
mos un atributo que cambie
tiempo extraordinario. Agregaremos
Agregaremos un atributo que almacene el kilometraje total del automóvil.

Establecer un valor predeterminado para un atributo

Cuando se crea una instancia, los atributos se pueden definir sin pasarlos como parámetros.
Estos atributos se pueden definir en __init__()
método, donde se les asigna un valor por defecto.
Agreguemos
Agreguemos un atributo llamado odometer_readin
odometer_reading
g que siempre comienza con un valor de 0.
También agregaremos un método read_odometer() que nos ayuda a leer el odómetro de cada
automóvil:

Coche de clase:
def __init__(auto, marca, modelo, año):
"""Inicialice
"""Inicialice los atributos para describir un automóvil".
automóvil".""
""
self.hacer = hacer
self.modelo = modelo
self.año = año
en self.odometer_reading = 0

def get_descriptive_name(self
get_descriptive_name(self):
):
--recorte--

Clases 163

MachineTranslatedbyGoogle

v def read_odomete
read_odometer(self):
r(self):
"""Imprima una declaración que muestre el kilometraje del automóvil".""
print(f"Este auto tiene {self.odometer_reading} millas").

mi_auto_nuevo = Auto('audi', 'a4', 2019)


print(my_new_car.get_descriptive_name())

mi_auto_nuevo.leer_odómetro()

Esta vez, cuando Python llama al método __init__() para crear una nueva instancia,
almacena los valores de marca, modelo y año como atributos, como lo hizo en el ejemplo anterior.
Luego, Python crea un nuevo atributo llamado odometer_reading
odometer_reading y establece su valor inicial en 0
u. También tenemos un nuevo método llamado read_odometer()
read_odometer() en v que facilita la lectura del
kilometraje de un automóvil.

Nuestro coche arranca con un kilometraje de 0:

2019 Audi A4
Este coche tiene 0 millas en él.

No se venden muchos autos con exactamente 0 millas en el odómetro, por lo que


necesitamos una forma de cambiar el valor de este atributo.

Modificación de valores de atributos

Puede cambiar el valor de un atributo de tres maneras: puede cambiar el valor directamente a través de
una instancia, establecer el valor a través de un método o incrementar el valor (agregarle una cierta
cantidad) a través de un método. Veamos cada uno de estos enfoques.

Modificar el valor de un atributo directamente

La forma más sencilla de modificar el valor de un atributo es acceder al atributo directamente a


través de una instancia. Aquí establecemos la lectura del odómetro a 23 directamente:

Coche de clase:

--recorte--

mi_auto_nuevo = Auto('audi', 'a4', 2019)


print(my_new_car.get_descriptive_name())

u my_new_car.odometer_reading
my_new_car.odometer_reading = 23
mi_auto_nuevo.leer_odómetro()

En u usamos la notación de puntos para acceder al atributo de lectura del odómetro del

automóvil y establecer su valor directamente. Esta línea le dice a Python que tome la instancia
my_new_car,
my_new_ca r, encuentre el atributo odometer_read
odometer_reading
ing asociado con él y establezca el valor de ese
atributo en 23:

2019 Audi A4
Este coche tiene 23 millas en él.

164 Capítulo 9

MachineTranslatedbyGoogle

A veces querrás acceder a atributos directamente como este, pero otras


veces querrá escribir un método que actualice el valor por usted.

Modificar el valor de un atributo a través de un método

Puede ser útil tener métodos que actualicen ciertos atributos por usted.
En lugar de acceder al atributo directamente, pasa el nuevo valor a un método que maneja
la actualización internamente.
Aquí hay un ejemplo que muestra un método llamado update_odometer():

Coche de clase:

--recorte--

u def update_odometer(self,
update_odometer(self, kilometraje):
"""Ajuste la lectura del cuentakilómetros al valor indicado."""
self.odometer_reading = kilometraje

mi_auto_nuevo = Auto('audi', 'a4', 2019)


print(my_new_car.get_descriptive_name())

v my_new_car.update_odome
my_new_car.update_odometer(23)
ter(23)
mi_auto_nuevo.leer_odómetro()

La única modificación a Car es la adición de update_odome


update_odometer()
ter() en u.
Este método toma un valor de kilometraje y lo asigna a self.odometer_reading.
En v, llamamos a update_od
update_odometer()
ometer() y le damos 23 como argumento (correspondiente al parámetro
de kilometraje en la definición del método). Establece la lectura del odómetro en 23 y
read_odometer()
read_odometer() imprime la lectura:

2019 Audi A4
Este coche tiene 23 millas en él.

Podemos extender el método update_odometer() para hacer un trabajo adicional cada


vez que se modifica la lectura del odómetro. Agreguemos un poco de lógica para asegurarnos
de que nadie intente hacer retroceder la lectura del odómetro:

Coche de clase:

--recorte--

def update_odometer(self, kilometraje):


"""

Ajuste la lectura del odómetro al valor dado.


Rechace el cambio si intenta hacer retroceder el odómetro.
"""

en si kilometraje >= self.odometer_reading:


self.odometer_reading = kilometraje
demás:
en print("¡No puedes retroceder un odómetro!")

Ahora update_odometer()
update_odometer() verifica que la nueva lectura tenga sentido antes de modificar el
atributo. Si el nuevo kilometraje, kilometraje, es mayor o igual

Clases 165

MachineTranslatedbyGoogle

al kilometraje existente, self.odometer_reading, puede actualizar la lectura del odómetro al nuevo kilometraje
u. Si el nuevo kilometraje es menor que el kilometraje existente, recibirá una advertencia de que no puede
retroceder un odómetro v.

Incrementar el valor de un atributo a través de un método

A veces querrá incrementar el valor de un atributo en cierta cantidad en lugar de establecer un valor
completamente nuevo. Digamos que compramos un automóvil usado y acumulamos 100 millas entre el
momento en que lo compramos y el momento en que lo registramos.
Aquí hay un método que nos permite pasar esta cantidad incremental y agregar ese valor a la lectura
del odómetro:

Coche de clase:

--recorte--

def update_odometer(self, kilometraje):


--recorte--

u def increment_odometer(self, miles):


"""Agregue la cantidad dada a la lectura del odómetro."""
self.odometer_reading += millas

v my_used_car = Car('subaru', 'outback', 2015)


print(my_used_car.get_descriptive_name())

w my_used_car.update_odome
my_used_car.update_odometer(23_500)
ter(23_500)
mi_coche_usado.leer_odómetro()

x my_used_car.increment_odometer(100)
my_used_car.increment_odometer(100)
mi_coche_usado.leer_odómetro()

El nuevo método increment_odometer() en u toma un número de millas,


y agrega este valor a self.odometer_reading. En v creamos un auto usado, my_used_car. Establecemos
su cuentakilómetros en 23 500 llamando a update_odometer() y pasándole 23_500 en w. En x llamamos
a increment_odometer() y le pasamos 100 para sumar las 100 millas que recorrimos entre comprar el auto y
registrarlo:

2015 Subaru Outback


Este auto tiene 23500 millas.
Este auto tiene 23600 millas.

Puede modificar fácilmente este método para rechazar incrementos negativos para que no
uno usa esta función para hacer retroceder un odómetro.

Nota Puede usar métodos como este para controlar cómo los usuarios de su programa actualizan los valores,

como la lectura del odómetro, pero cualquier persona con acceso al programa puede establecer la lectura del
odómetro en cualquier valor accediendo directamente al atributo. La seguridad eficaz exige una atención
extrema a los detalles además de las comprobaciones básicas como las que se muestran aquí.

166 Capítulo 9

MachineTranslatedbyGoogle

Inténtalo tú mismo

9-4. Número servido: comience con su programa del ejercicio 9-1 (página 162).
Agregue un atributo llamado número_servido con un valor predeterminado de 0. Cree una
instancia llamada restaurante a partir de esta clase. Imprime el número de clientes que ha

servido el restaurante y luego cambia este valor e imprímelo de nuevo.


Agregue un método llamado set_number_served() que le permita establecer la
cantidad de clientes que han sido atendidos. Llame a este método con un nuevo número e

imprima el valor nuevamente.


Agregue un método llamado increment_number_served() que le permita incrementar la
cantidad de clientes que han sido atendidos. Llame a este método con cualquier número que
desee que pueda representar cuántos clientes se atendieron, digamos, en un día hábil.

9-5. Intentos de inicio de sesión: agregue un atributo llamado intentos de inicio de sesión a su usuario

clase del ejercicio 9-3 (página 162). Escriba un método llamado increment_login
_attempts() que incrementa el valor de login_attempts en 1. Escribe otro método

llamado
a 0. reset_login_attempts() que restablece el valor de login_attempts

Crea una instancia de la clase User y llama a increment_login_attempts()


varias veces. Imprima el valor de login_attempts para asegurarse de que se incrementó
correctamente y luego llame a reset_login_attempts().
reset_login_attempts(). Imprima login_attempts nuevamente para
asegurarse de que se restableció a 0.

Herencia
No siempre tienes que empezar desde
d esde cero al escribir una clase. Si la clase que está escribiendo es
una versión especializada de otra clase que escribió, puede usar la herencia. Cuando una clase
hereda de otra, adquiere los atributos
a tributos y métodos de la primera clase. La
L a clase original se llama clase
padre y la nueva clase es la clase hija. La clase secundaria puede heredar cualquiera o todos los
atributos y métodos de su clase principal, pero también es libre de definir sus propios atributos y
métodos nuevos.

El método __init__() para una clase secundaria


Cuando está escribiendo una nueva clase basada en una clase existente, a menudo querrá
llamar al método __init__() desde la clase principal. Esto inicializará todos los atributos que se
definieron en el método principal __init__() y los hará disponibles en la clase secundaria.

Como ejemplo, modelemos un coche eléctrico. Un automóvil eléctrico es solo un tipo


específico de automóvil, por lo que podemos basar nuestra nueva clase ElectricCar en la clase
Car que escribimos anteriormente. Entonces solo tendremos que escribir código para los atributos
y el comportamiento específico de los autos eléctricos.

Clases 167

MachineTranslatedbyGoogle

Comencemos por hacer una versión simple de la clase ElectricCar , que


hace todo lo que hace la clase Car :

electric_car.py u class Car:


"""Un simple intento de representar un coche."""

def __init__(auto, marca, modelo, año):


self.hacer = hacer
self.modelo = modelo
self.año = año
self.odometer_reading = 0

def get_descriptive_name(self):
long_name = f"{self.year} {self.manufacturer} {self.model}"
devuelve nombre_largo.título()

def read_odometer(self):
print(f"Este auto tiene {self.odometer_reading}
{self.odometer_reading} millas").

def update_odometer(self, kilometraje):


si kilometraje >= self.odome
self.odometer_reading
ter_reading::
self.odometer_reading = kilometraje
demás:

print("¡No puedes retroceder un odómetro!")

def increment_
increment_odometer(se
odometer(self,
lf, millas):
self.odometer_readin
self.odometer_reading
g += millas

v clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""

w def __init__(auto, marca, modelo, año):


"""Inicializar atributos de la clase padre."""
X super().__init__(marca, modelo, año)

y my_tesla = ElectricCar('te
ElectricCar('tesla',
sla', 'modelo s', 2019)
imprimir (my_tesla.ge
(my_tesla.get_descripti
t_descriptive_name())
ve_name())

En u comenzamos con Car. Cuando crea una clase secundaria, la clase


principal debe ser parte del archivo actual y debe aparecer antes que la clase
secundaria en el archivo. En v definimos la clase secundaria, ElectricCar. El nombre
de la clase principal debe incluirse entre paréntesis en la definición de una clase secundaria.
El método __init__() en w toma la información requerida para hacer un Car
instancia.
La función super() en x es una función especial que le permite llamar a un
método de la clase principal. Esta línea le dice a Python que llame a __init__()
de Car, que otorga a una instancia de ElectricCar todos los atributos definidos en
ese método. El nombre super proviene de una convención de llamar a la clase padre
superclase y a la clase hija subclase.

168 Capítulo 9

MachineTranslatedbyGoogle

Probamos si la herencia funciona correctamente al intentar crear un automóvil eléctrico con el


mismo tipo de información que proporcionaríamos al fabricar un automóvil normal. En y creamos una
instancia de la clase ElectricCar y la asignamos a my_tesla. Esta línea llama al método __init__()
definido en ElectricCar, que a su vez le dice a Python que llame al método __init__() definido en la clase
padre Car. Proporcionamos los argumentos 'tesla', 'model s' y 2019.

Aparte de __init__(), todavía no hay atributos o métodos que sean particulares de un


automóvil eléctrico. En este punto, solo nos estamos asegurando de que el automóvil eléctrico
tenga los comportamientos de automóvil apropiados:

Modelo S de Tesla 2019

La instancia de ElectricCar funciona como una instancia de Car, así que ahora
puede comenzar definiendo atributos y métodos específicos para los autos eléctricos.

Definición de atributos y métodos para la clase secundaria

Una vez que tenga una clase secundaria que herede de una clase principal, puede agregar

los nuevos atributos y métodos necesarios para diferenciar la clase secundaria de la clase
principal.
Agreguemos un atributo que sea específico para los autos eléctricos (una batería,
por ejemplo) y un método para informar sobre este atributo. Guardaremos el tamaño de la
batería y escribiremos un método que imprima una descripción de la batería:

Coche de clase:

--recorte--

clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""

def __init__(auto, marca, modelo, año):


"""

Inicializar atributos de la clase padre.


A continuación, inicialice los atributos específicos de un coche eléctrico.
"""

super().__init__(marca, modelo, año)


en self.battery_size = 75

v def describe_batería(uno mismo):


"""Imprima una declaración que describa el tamaño de la batería."""
print(f"Este auto tiene una batería de {self.battery_size}-kWh").
my_tesla = ElectricCar('tesla', 'modelo s', 2019)
imprimir (my_tesla.get_descriptive_name())
my_tesla.describe_battery()

En u agregamos un nuevo atributo self.battery_size y establecemos su valor inicial en,


digamos, 75. Este atributo se asociará con todas las instancias creadas a partir de la clase
ElectricCar pero no se asociará con ninguna instancia de Car. Nosotros también
t ambién

Clases 169

MachineTranslatedbyGoogle

agrega un método llamado describe_battery() que imprime información sobre la batería en


v. Cuando llamamos a este método, obtenemos una descripción que es claramente
específica de un automóvil eléctrico:

Tesla Model S 2019


Este automóvil tiene una batería de 75 kWh.

No hay límite en cuánto puede especializarse en la clase ElectricCar .


Puede agregar tantos atributos y métodos como necesite para modelar un automóvil eléctrico
con el grado de precisión que necesite. Un atributo o método que podría pertenecer a
cualquier automóvil, en lugar de uno que sea específico de un automóvil eléctrico, debe
agregarse a la clase Car en lugar de a la clase ElectricCar . Entonces, cualquiera que use la
clase Car también tendrá esa funcionalidad disponible, y la clase ElectricCar solo contendrá
el código para la información y el comportamiento específico de los vehículos eléctricos.

Anulación de métodos de la clase principal

Puede anular cualquier método de la clase principal que no se ajuste a lo que intenta
modelar con la clase secundaria. Para hacer esto, defina un método en la clase secundaria
con el mismo nombre que el método que desea anular en la clase principal. Python ignorará el
método de la clase principal y solo prestará atención al método que defina en la clase
secundaria.
Digamos que la clase Car tenía un método llamado fill_gas_tank(). Este método no
tiene sentido para un vehículo totalmente eléctrico, por lo que es posible que desee anular
este método. Aquí hay una forma de hacerlo:

clase ElectricCar(Coche):
--recorte--

def llenar_tanque_de_gas(auto):
llenar_tanque_de_gas(auto):

"""Los autos eléctricos no tienen tanques de gasolina".""


print("¡Este auto no necesita tanque de gasolina!")

Ahora, si alguien intenta llamar a fill_gas_tank() con un automóvil eléctrico, Python


ignorará el método fill_gas_tank() en Car y ejecutará este código en su lugar. Cuando usa la
herencia, puede hacer que sus clases secundarias conserven lo que necesita y anule todo lo
que no necesite de la clase principal.

Instancias como atributos


Al modelar algo del mundo real en código, es posible que descubra que está agregando más
y más detalles a una clase. Descubrirá que tiene una lista creciente de atributos y métodos
y que sus archivos son cada vez más largos. En estas situaciones, es posible que reconozca

que parte de una clase se puede escribir como una clase separada. Puede dividir su clase
grande en clases más pequeñas que trabajen juntas.

Por ejemplo, si continuamos agregando detalles a la clase ElectricCar , podemos


notar que estamos agregando muchos atributos y métodos específicos para

170 Capítulo 9

MachineTranslatedbyGoogle

la batería del coche. Cuando vemos que esto sucede, podemos detener y mover esos
atributos y métodos a una clase separada llamada Batería. Entonces podemos usar
una instancia de Batería como atributo en la clase ElectricCar :

Coche de clase:

--recorte--

batería de clase u:
"""Un simple intento de modelar una batería para un coche eléctrico."""

v def __init__(self, tamaño_batería=75):


"""Inicialice los atributos de la batería."""
self.battery_size = batería_tamaño

w def describe_batería(uno mismo):


"""Imprima una declaración que describa el tamaño de la batería."""
print(f"Este auto tiene una batería de {self.battery_size}-kWh").

clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""

def __init__(auto, marca, modelo, año):


"""

Inicializar atributos de la clase padre.


A continuación, inicialice los atributos específicos de un coche eléctrico.
"""

super().__init__(marca, modelo, año)


X self.bateria = Bateria()

my_tesla = ElectricCar('tesla', 'modelo s', 2019)

imprimir (my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

En u definimos una nueva clase llamada Batería que no hereda de ninguna


otra clase El método __init__() en v tiene un parámetro, battery_size, además de
self. Este es un parámetro opcional que establece el tamaño de la batería en 75 si
no se proporciona ningún valor. El método describe_battery() también se ha movido
a esta clase w.
En la clase ElectricCar , ahora agregamos un atributo llamado self.battery x.
Esta línea le dice a Python que cree una nueva instancia de Batería
Bat ería (con un tamaño
predeterminado de 75, porque no estamos especificando un valor) y asigne esa
instancia al atributo self.battery. Esto sucederá cada vez que se llame al método
__init__() ; cualquier instancia de ElectricCar ahora tendrá una instancia de Batería
Batería

creada automáticamente.
Creamos un coche eléctrico y lo asignamos a la variable my_tesla. Cuando
queremos describir la batería, necesitamos trabajar con la batería del automóvil.
atributo:

my_tesla.battery.describe_battery()

Clases 171

MachineTranslatedbyGoogle

Esta línea le dice a Python que mire la instancia my_tesla, encuentre su batería
atributo y llame al método describe_battery() que está asociado con la instancia de batería
almacenada en el atributo.
El resultado es idéntico al que vimos anteriormente:

Tesla Model S 2019 Este


automóvil tiene una batería de 75 kWh.

Esto parece mucho trabajo extra, pero ahora podemos describir la batería
con tanto detalle como queramos sin saturar la clase ElectricCar . Agreguemos otro
método a Batería que informe el alcance del automóvil según el tamaño de la batería:

Coche de clase:

--recorte--

batería de clase:
--recorte--

u def get_range(self):
"""Imprime una declaración sobre el alcance que proporciona esta batería."""
si self.battery_size == 75:
rango = 260
elif self.battery_size == 100:
rango = 315

print(f"Este auto puede recorrer alrededor de {rango} millas con una carga completa").

clase ElectricCar(Coche):
--recorte--

my_tesla = ElectricCar(
ElectricCar('tesla',
'tesla', 'modelo s', 2019)
imprimir (my_tesla.get_descriptive_name())
my_tesla.battery.describe
my_tesla.battery.describe_battery()
_battery()
v my_tesla.battery.get_rang
my_tesla.battery.get_range()
e()

El nuevo método get_range() en u realiza un análisis simple. Si la capacidad de la


batería es de 75 kWh, get_range() establece el alcance en 260 millas, y si la capacidad es
de 100 kWh, establece el alcance en 315 millas. Luego informa este valor. Cuando
queramos usar este método, nuevamente tenemos que llamarlo a través del atributo de
batería del automóvil en v.
La salida nos dice la autonomía del coche en función del tamaño de la batería:
La salida nos dice la autonomía del coche en función del tamaño de la batería:

Tesla Model S 2019 Este


automóvil tiene una batería de 75 kWh.
Este coche puede recorrer unas 260 millas con una carga completa.

172 Capítulo 9

MachineTranslatedbyGoogle

Modelado de objetos del mundo real

A medida que comience a modelar cosas más complicadas, como automóviles


eléctricos, se enfrentará a preguntas interesantes. ¿La autonomía de un coche
eléctrico es una propiedad de la batería o del coche? Si solo estamos describiendo
un automóvil, probablemente esté bien mantener la asociación del método get_range() con la batería
clase. Pero si estamos describiendo toda la línea de automóviles de un fabricante,
probablemente queramos mover get_range() a la clase ElectricCar . El método
get_range() aún verificaría el tamaño de la batería antes de determinar el rango, pero
informaría un rango específico para el tipo de automóvil con el que está asociado.
Alternativamente, podríamos mantener la asociación del método get_range() con la
batería pero pasarle un parámetro como car_model. El método get_range() luego
informaría un rango basado en el tamaño de la batería y el modelo de automóvil.
Esto lo lleva a un punto interesante en su crecimiento como programador.
Cuando lucha con preguntas como estas, está pensando en un nivel lógico superior en
lugar de un nivel centrado en la sintaxis. No estás pensando en Python, sino en cómo
representar el mundo real en código. Cuando llegue a este punto, se dará cuenta de que
a menudo no hay enfoques correctos o incorrectos para modelar situaciones del mundo

real. Algunos enfoques son más eficientes que otros, pero se necesita práctica para
encontrar las representaciones más eficientes. Si tu código funciona como quieres, ¡lo
estás haciendo bien! No se desanime si descubre que está fragmentando sus clases y
reescribiéndolas varias veces utilizando diferentes enfoques. En la búsqueda de escribir
código preciso y eficiente, todo el mundo pasa por este proceso.

Inténtalo tú mismo

9-6. Puesto de helados: Un puesto de helados es un tipo específico de restaurante. Escriba una
clase llamada IceCreamStand que herede de la clase Restaurante que escribió en el Ejercicio 9-1

(página 162) o el Ejercicio 9-4 (página 167). Cualquiera de las versiones de la clase funcionará;
simplemente elige el que más te guste. Agregue un atributo llamado sabores que almacene una
lista de sabores de helado. Escribe un método que muestre estos sabores. Cree una instancia de
IceCreamStand
IceCreamStand y llllame
ame a este método.

9-7. Admin: Un administrador es un tipo especial de usuario. Escriba una clase llamada
Admin que herede de la clase Usuario que escribió en el Ejercicio
Ej ercicio 9-3 (página 162) o el
Ejercicio 9-5 (página 167). Agregue un atributo, privilegios, que almacene una lista de cadenas
como "puede agregar una publicación", "puede eliminar una publicación", "puede prohibir a un usuario", etc.
Escriba un método llamado show privileges() que enumere el conjunto de privilegios del
administrador.
administrador. Cree una instancia de Admin y llame a su método.

9-8. Privilegios: Escriba una clase de Privilegios separada . La clase debe tener un atributo,
privilegios, que almacene una lista de cadenas como se describe en el ejercicio 9-7.

Mueva el método show_privileges() a esta clase. Cree una instancia de Privilegios como un
atributo en la clase Admin . Cree una nueva instancia de Admin y use su método para mostrar sus
privilegios.

(continuado)

Clases 173

MachineTranslatedbyGoogle

9-9. Actualización de batería: use la versión final de electric_car.py de esta sección.


Agregue un método a la clase Batería llamado upgrade_battery(). Este método debería
verificar el tamaño de la batería y establecer la capacidad en 100 si aún no lo está.
Haga un automóvil eléctrico con un tamaño de batería predeterminado, llame a get_range()
una vez y luego llame a get_range() una segunda vez después de actualizar la batería. Debería
ver un aumento en el alcance del automóvil.

Importación de clases

A medida que agrega más funcionalidad a sus clases, sus archivos pueden alargarse, incluso
cuando usa la herencia correctamente. De acuerdo con la filosofía general de Python, querrá
mantener sus archivos lo más ordenados posible. Para ayudar, Python le permite almacenar
clases en módulos y luego importar las clases que necesita en su programa principal.

Importación de una sola clase

Vamos a crear un módulo que contenga solo la clase Car . Esto trae a colación un sutil
problema de nomenclatura: ya tenemos un archivo llamado car.py en este capítulo, pero
este módulo debería llamarse car.py porque contiene código que representa un auto.
Resolveremos este problema de nombres almacenando la clase Car en un módulo llamado
car.py, reemplazando el archivo car.py que estábamos usando anteriormente. De ahora en
adelante, cualquier programa que use este módulo necesitará un nombre de archivo más
específico, como my_car.py. Aquí está car.py con solo el código de la clase Car:

car.py u """Una clase que se puede usar para representar un automóvil".""

Coche de clase:

"""Un simple intento de representar un coche."""

def __init__(auto, marca, modelo, año):


"""Inicialice
"""Inicialice los atributos para describir un automóvil"."
automóvil"."""
self.hacer = hacer
self.modelo = modelo
self.año = año
self.odometer_reading
self.odometer_reading = 0
def get_descript
get_descriptive_name(self):
ive_name(self):
"""Retorna un nombre descriptivo con un formato ordenado."""
ordenado."""
long_name = f"{self.year} {self.manufac
{self.manufacturer}
turer} {self.model}"

devuelve nombre_largo
nombre_largo.título()
.título()

def read_odo
read_odometer(self):
meter(self):
"""Imprima una declaración que muestre el kilometraje del automóvil".""
print(f"Este auto tiene {self.odomete
{self.odometer_reading}
r_reading} millas").

174 Capítulo 9

MachineTranslatedbyGoogle

def update_odometer(self, kilometraje):


"""

Ajuste la lectura del odómetro al valor dado.


Rechace el cambio si intenta hacer retroceder el odómetro.
"""

si kilometraje >= self.odometer_reading:


self.odometer_reading = kilometraje
demás:

print("¡No puedes retroceder un odómetro!")

def increment_odometer(self, millas):


"""Agregue la cantidad dada a la lectura del odómetro."""
self.odometer_reading += millas

En u incluimos una cadena de documentación a nivel de módulo que describe brevemente


el contenido de este módulo. Debe escribir una cadena de documentación para cada módulo que
crear.

Ahora creamos un archivo separado llamado my_car.py. Este archivo importará la clase Car
y luego creará una instancia de esa clase:

my_car.py u from car import Car

mi_auto_nuevo = Auto('audi', 'a4', 2019)


print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading = 23
my_new_car.odometer_reading
mi_auto_nuevo.leer_odómetro()

La declaración de importación en u le dice a Python que abra el módulo del automóvil e


importe la clase Car. Ahora podemos usar la clase Car como si estuviera definida en este archivo.
La salida es la misma que vimos antes:

Audi A4 2019
Este auto tiene 23 millas.

Importar clases es una forma efectiva de programar. Imagine cuánto tiempo sería este
archivo de programa si se incluyera toda la clase de automóvil . Cuando, en cambio, mueve la
clase a un módulo e importa el módulo, aún obtiene la misma funcionalidad, pero mantiene su
archivo de programa principal limpio y fácil de leer. También almacena la mayor parte de la lógica
en archivos separados; una vez que sus clases funcionen como desea, puede dejar esos archivos
solos y concentrarse en la lógica de nivel superior de su programa principal.
Almacenamiento de varias clases en un módulo

Puede almacenar tantas clases como necesite en un solo módulo, aunque cada clase en un
módulo debe estar relacionada de alguna manera. Las clases Batería
y ElectricCar ayudan a representar automóviles, así que agréguelos al módulo car.py.

Clases 175

MachineTranslatedbyGoogle

coche.py """Un conjunto de clases que se utiliza para representar automóviles de gasolina y eléctricos".""

Coche de clase:

--recorte--

class Batería:
"""Un simple intento de modelar una batería para un coche eléctrico."""

def __init__(
__init__(self,
self, tamaño_ba
tamaño_batería=70):
tería=70): """Inicializa
los atributos de la batería.""" self.tamaño_batería
self.tamaño_batería =
tamaño_batería

def describe_batería(uno mismo):


"""Imprime una declaración que describa el tamaño de la batería".""
print(f"Este automóvil tiene una batería de {self.battery_size}-kWh").

def get_range(self):
"""Imprime una declaración sobre el alcance que proporciona esta batería.""" if
self.battery_size
self.battery_size == 75: range = 260 elif self.battery_s
self.battery_size
ize == 100: range = 315

print(f"Este auto puede recorrer alrededor de {rango} millas con una carga completa").

clase ElectricCar(Coche):
"""Modela aspectos de un coche, específicos para vehículos eléctricos."""

def __init__(auto, marca, modelo, año):


"""

Inicializar atributos de la clase padre.


A continuación, inicialice los atributos específicos de un coche eléctrico.
"""

super().__init__(marca, modelo, año) self.battery


= Batería()

Ahora podemos crear un nuevo archivo llamado my_electric_car.py,


importar la clase ElectricCar y hacer un auto eléctrico:

mi_electrico de coche de importación ElectricCar


_coche.py
my_tesla = ElectricCar('tesla', 'modelo s', 2019)
print(my_tesla.get_descri
print(my_tesla.get_descriptive_name
ptive_name())
())
my_tesla.battery.describe
my_tesla.battery.describe_battery()
_battery()
my_tesla.battery.get_range()

Esto tiene el mismo resultado que vimos antes, aunque la mayor parte de la lógica
está oculta en un módulo:

Tesla Model S 2019 Este


automóvil tiene una batería de 75 kWh.
Este coche puede recorrer unas 260 millas con una carga completa.

176 Capítulo 9

MachineTranslatedbyGoogle

Importación de varias clases desde un módulo

Puede importar tantas clases como necesite en un archivo de programa. Si queremos hacer un auto
normal y un auto eléctrico en el mismo archivo, necesitamos
necesitamos importar ambas clases, Car y ElectricCar:

my_cars.py u from car import Car, ElectricCar

v mi_escarabajo
mi_escarabajo = Coche('volkswa
Coche('volkswagen',
gen', 'escarabajo', 2019)
imprimir(mi_escarabajo.obten
imprimir(mi_escarabajo.obtener_nombre
er_nombre_descriptivo())
_descriptivo())

w my_tesla = ElectricCar('tesla', 'roadster', 2019)


imprimir (my_tesla.get_descriptive
(my_tesla.get_descriptive_name())
_name())

Importa varias clases de un módulo separando cada clase con una coma u. Una
vez que haya importado las clases necesarias, puede crear tantas instancias de cada
clase como necesite.
En este ejemplo, hacemos un Volkswagen Beetle normal en v y uno eléctrico.
tric Tesla Roadster en w:

Volkswagen Escarabajo 2019


Descapotable Tesla 2019

Importación de un módulo completo

También puede importar un módulo completo y luego acceder a las clases que necesita
usando la notación de puntos. Este enfoque es simple y da como resultado un código que
es fácil de leer. Debido a que cada llamada que crea una instancia de una clase incluye
el nombre del módulo, no tendrá conflictos de nombres con los nombres utilizados en el
archivo actual.
Esto es lo que parece importar todo el módulo del automóvil y luego crear
un coche normal y un coche eléctrico:

my_cars.py u coche de importación

v mi_escarabajo
mi_escarabajo = coche.Coch
coche.Coche('volkswagen
e('volkswagen',', ' escarabajo
escarabajo',', 2019)
imprimir(mi_escarabajo.obten
imprimir(mi_escarabajo.obtener_nombre
er_nombre_descriptivo())
_descriptivo())

w my_tesla = auto.ElectricCar('tesla',
auto.ElectricCar('tesla', 'roadster', 2019)
imprimir (my_tesla.ge
(my_tesla.get_descriptive
t_descriptive_name())
_name())
En u importamos todo el módulo del coche . Luego accedemos a las clases que
necesita a través de la sintaxis module_name.ClassName . En v creamos
nuevamente un Volkswagen Beetle, y en w creamos un Tesla Roadster.

Importación de todas las clases de un módulo

Puede importar cada clase de un módulo usando la siguiente sintaxis:

*
de la importación de module_name

Clases 177

MachineTranslatedbyGoogle

Este método no se recomienda por dos razones. Primero, es útil poder leer las
declaraciones de importación en la parte superior de un archivo y tener una idea clara
de qué clases usa un programa. Con este enfoque, no está claro qué clases está
utilizando del módulo. Este enfoque también puede generar confusión con los nombres
en el archivo. Si importa accidentalmente una clase con el mismo nombre que otra cosa

en su archivo de programa, puede crear errores que son difíciles de diagnosticar.


Muestro esto aquí porque, aunque no es un enfoque recomendado, es probable que lo
vea en el código de otras personas en algún momento.
Si necesita importar muchas clases de un módulo, es mejor importar el módulo
completo y usar la sintaxis module_name.ClassName .
No verá todas las clases utilizadas en la parte superior del archivo, pero verá claramente
dónde se utiliza el módulo en el programa. También evitará los posibles conflictos de
nombres que pueden surgir cuando importa cada clase en un módulo.

Importación de un módulo en un módulo

A veces querrá distribuir sus clases en varios módulos para evitar que un archivo
crezca demasiado y evitar almacenar clases no relacionadas en el mismo módulo.
Cuando almacena sus clases en varios módulos, puede encontrar que una clase en un
módulo depende de una clase en otro módulo. Cuando esto sucede, puede importar la
clase requerida al primer módulo.

Por ejemplo, almacenemos la clase Car en un módulo y ElectricCar


y clases de batería en un módulo separado. Haremos un nuevo módulo llamado
electric_car.py, reemplazando el archivo electric_car.py que creamos anteriormente, y
copiaremos solo las clases Battery y ElectricCar en este archivo:

coche_electrico.py """Un conjunto de clases que se pueden utilizar para representar coches eléctricos."""

u de importación de automóviles

batería de clase:
--recorte--

clase ElectricCar(Coche):
--recorte--

La clase ElectricCar necesita acceso a su clase principal Car, por lo que


importamos Car directamente al módulo en u. Si olvidamos esta línea, Python
generará un error cuando intentemos importar el módulo electric_car . También
necesitamos actualizar el módulo Car para que contenga solo la clase Car :

coche.py """Una clase que se puede usar para representar un automóvil".""

Coche de clase:
--recorte--

178 Capítulo 9

MachineTranslatedbyGoogle

Ahora podemos importar desde cada módulo por separado y crear cualquier tipo de
automóvil que necesitemos:

my_cars.py u from car import Car


de electric_car importar ElectricCar

mi_escarabajo = Coche('volkswagen', 'escarabajo', 2019)


imprimir(mi_escarabajo.obtener_nombre_descriptivo())

my_tesla = ElectricCar('tesla', 'roadster', 2019)


imprimir (my_tesla.get_descriptive_name())

En u importamos Car desde su módulo y ElectricCar desde su módulo.


Luego creamos un automóvil normal y un automóvil eléctrico. Ambos tipos de coches se
crean correctamente:

Volkswagen Escarabajo 2019


Descapotable Tesla 2019

Uso de alias

Como vio en el Capítulo 8, los alias pueden ser muy útiles al usar módulos para organizar
el código de sus proyectos. También puede usar alias al importar clases.

Como ejemplo, considere un programa en el que desea hacer un montón de autos


eléctricos. Puede volverse tedioso escribir (y leer) ElectricCar una y otra vez. Puede dar a
ElectricCar un alias en la declaración de importación:

de electric_car importar ElectricCar como CE

Ahora puedes usar este alias cuando quieras hacer un auto eléctrico:

mi_tesla = EC('tesla', 'roadster', 2019)

Encontrar su propio flujo de trabajo

Como puede ver, Python le brinda muchas opciones sobre cómo estructurar el código en
un proyecto grande. Es importante conocer todas estas posibilidades para que pueda
determinar las mejores formas de organizar sus proyectos, así como comprender los
proyectos de otras personas.
Cuando esté comenzando, mantenga la estructura de su código simple. Intente
hacer todo en un solo archivo y mueva sus clases a módulos separados una vez que
todo esté funcionando. Si le gusta cómo interactúan los módulos y los archivos, intente

almacenar sus clases en módulos cuando inicie un proyecto. Encuentre un enfoque que le
permita escribir código que funcione y continúe desde allí.

Clases 179

MachineTranslatedbyGoogle

Inténtalo tú mismo

9-10. Restaurante importado: utilizando su última clase de restaurante , guárdela en un módulo.


Cree un archivo separado que importe Restaurant. Cree una instancia de Restaurant y llame a uno de

los métodos de Restaurant para mostrar que la declaración de importación funciona correctamente.

9-11. Administrador importado: Comience con su trabajo del Ejercicio 9-8 (página 173).
Almacene las clases Usuario, Privilegios y Administrador en un módulo. Cree un archivo
separado, cree una instancia de administrador y llame a show_privileges() para mostrar
que todo funciona correctamente.

9-12. Múltiples módulos: almacene la clase de usuario en un módulo y almacene las clases
de privilegios y administración en un módulo separado. En un archivo separado, cree una instancia
de administrador y llame a show_privileges() para mostrar que todo sigue funcionando correctamente.

La biblioteca estándar de Python


La biblioteca estándar de Python es un conjunto de módulos incluidos con cada
instalación de Python. Ahora que tiene una comprensión básica de cómo funcionan las
funciones y las clases, puede comenzar a usar módulos como estos que han escrito
otros programadores. Puede usar cualquier función o clase en la biblioteca estándar al
incluir una declaración de importación simple en la parte superior de su archivo.
Veamos un módulo, aleatorio, que puede ser útil para modelar muchas situaciones del
mundo real.
Una función interesante del módulo aleatorio es randint(). Esta función toma
dos argumentos enteros y devuelve un número entero seleccionado al azar entre (e
incluyendo) esos números.
Aquí se explica cómo generar un número aleatorio entre 1 y 6:

>>> de randint de importación aleatoria


>>> citas (1, 6)
3

Otra función útil es choice(). Esta función toma una lista o tupla y devuelve un
elemento elegido al azar:

>>> de la elección de importación aleatoria


>>> jugadores = ['charles', 'martina', 'michael', 'florencia', 'eli']
>>> first_up = elección(jugadores)
>>> primero_arriba
'florencia'

180 Capítulo 9

MachineTranslatedbyGoogle

El módulo aleatorio no debe usarse al crear aplicaciones relacionadas con la seguridad, pero es lo
suficientemente bueno para muchos proyectos divertidos e interesantes.

Nota También puede descargar módulos de fuentes externas. Verá varios de estos ejemplos en la Parte II, donde
necesitaremos módulos externos para completar cada proyecto.

Inténtalo tú mismo

9-13. Dado: crea una clase de dado con un atributo llamado lados, que tiene un valor
predeterminado de 6. Escribe un método llamado roll_die() que imprima un número aleatorio
entre 1 y el número de lados que tiene el dado. Haz un dado de 6 caras y tíralo 10 veces.

Haz un dado de 10 caras y un dado de 20 caras. Tira cada dado 10 veces.

9-14. Lotería: Haz una lista o tupla que contenga una serie de 10 números y cinco
letras. Seleccione al azar cuatro números o letras de la lista e imprima un mensaje

diciendo que cualquier boleto que coincida con estos cuatro números o letras gana un
premio.

9-15. Análisis de lotería: puede usar un ciclo para ver qué tan difícil puede ser ganar el
tipo de lotería que acaba de modelar. Haz una lista o tupla llamada my_ticket.
Escribe un bucle que siga sacando números hasta que gane tu boleto. Imprima un mensaje
informando cuántas veces tuvo que ejecutarse el ciclo para obtener un boleto ganador.

9-16. Python Module of the Week: un excelente recurso para explorar la biblioteca
estándar de Python es un sitio llamado Python Module of the Week. Vaya a https://
pymotw.com/ y mire la tabla de contenido. Encuentre un módulo que le parezca
interesante y lea sobre él, tal vez comenzando con el aleatorio
módulo.

Clases de estilismo
Vale la pena aclarar algunos problemas de estilo relacionados con las clases, especialmente a medida que sus
programas se vuelven más complicados.
Los nombres de las clases deben escribirse en CamelCase. Para hacer esto, escriba en mayúscula la
primera letra de cada palabra en el nombre y no use guiones bajos. Los nombres de instancias y módulos
deben escribirse en minúsculas con guiones bajos entre palabras.

Cada clase debe tener una cadena de documentación inmediatamente después de la definición de la clase.
nición La cadena de documentación debe ser una breve descripción de lo que hace la clase, y debe seguir las
mismas convenciones de formato que usó para escribir cadenas de documentación en funciones. Cada módulo
también debe tener una cadena de documentación que describa para qué se pueden usar las clases en un módulo.

Puede usar líneas en blanco para organizar el código, pero no las use en exceso. Dentro de una
clase puede usar una línea en blanco entre los métodos y dentro de un módulo puede usar dos líneas en
blanco para separar las clases.

Clases 181

MachineTranslatedbyGoogle

Si necesita importar un módulo de la biblioteca estándar y un módulo que escribió, primero


coloque la declaración de importación para el módulo de la biblioteca estándar. Luego agregue
una línea en blanco y la declaración de importación para el módulo que escribió. En programas
con múltiples declaraciones de importación, esta convención facilita ver de dónde provienen los
diferentes módulos utilizados en el programa.

Resumen
En este capítulo aprendió a escribir sus propias clases. Aprendió cómo almacenar información
en una clase usando atributos y cómo escribir métodos que le den a sus clases el
comportamiento que necesitan. Aprendió a escribir métodos __init__() que crean instancias
de sus clases con exactamente los atributos que desea. Viste cómo modificar los atributos
de una instancia directamente ya través de métodos. Aprendió que la herencia puede
simplificar la creación de clases que están relacionadas entre sí y aprendió a usar instancias
de una clase como atributos en otra clase para mantener cada clase simple.

Viste cómo almacenar clases en módulos e importar clases necesitas


en los archivos donde se usarán pueden mantener sus proyectos organizados. Comenzaste
a aprender sobre la biblioteca estándar de Python y viste un ejemplo basado en el módulo
aleatorio . Finalmente, aprendió a diseñar sus clases usando las convenciones de Python.

En el Capítulo 10, aprenderá a trabajar con archivos para que pueda guardar el trabajo
que ha realizado en un programa y el trabajo que ha permitido que realicen los usuarios.
También aprenderá sobre las excepciones, una clase especial de Python diseñada para
ayudarlo a responder a los errores cuando surjan.
182 Capítulo 9

MachineTranslatedbyGoogle

10
Ficheros y excepciones

Ahora que domina las habilidades básicas que


necesita para escribir programas organizados
que sean fáciles de usar, es hora de pensar en
hacer que sus programas sean aún más relevantes y
utilizables. En este capítulo aprenderá a trabajar con archivos
para que sus programas puedan analizar rápidamente muchos datos.
Aprenderá a manejar los errores para que sus programas no se bloqueen cuando se
encuentren con situaciones inesperadas. Aprenderá sobre las excepciones, que son
objetos especiales que Python crea para administrar los errores que surgen mientras se
ejecuta un programa. También aprenderá sobre el módulo json , que le permite guardar
datos de usuario para que no se pierdan cuando su programa deja de ejecutarse.
Aprender a trabajar con archivos y guardar datos hará que sus programas sean
más fáciles de usar para las personas. Los usuarios podrán elegir qué datos ingresar y
cuándo ingresarlos. Las personas pueden ejecutar
ejecutar su programa, hacer algo de trabajo y
luego cerrar el programa y continuar donde lo dejaron más tarde. Aprender a manejar
excepciones lo ayudará a lidiar con situaciones en las que los archivos no existen y con otros
problemas que pueden hacer que sus programas se bloqueen. Esto hará que sus programas
sean más robustos cuando encuentren datos incorrectos, ya sea

MachineTranslatedbyGoogle

proviene de errores inocentes o de intentos maliciosos de romper sus programas. Con


las habilidades que aprenderá en este capítulo, hará que sus programas sean más
aplicables, utilizables y estables.

Lectura de un archivo
Una increíble cantidad de datos está disponible en archivos de texto. Los archivos de
texto pueden contener datos meteorológicos, datos de tráfico, datos socioeconómicos,
obras literarias y más. Leer desde un archivo es particularmente útil en aplicaciones
de análisis de datos, pero también es aplicable a cualquier situación en la que desee
analizar o modificar información almacenada en un archivo. Por ejemplo, puede
escribir un programa que lea el contenido de un archivo de texto y reescriba el archivo
con un formato que permita que un navegador lo muestre.
Cuando desee trabajar con la información de un archivo de texto, el primer paso es
leer el archivo en la memoria. Puede leer todo el contenido de un archivo o puede
trabajar con el archivo una línea a la vez.

Lectura de un archivo completo

Para comenzar, necesitamos un archivo con unas pocas líneas de texto. Comencemos
con un archivo que contiene pi con 30 decimales, con 10 decimales por línea:

pi_digitos.txt 3.1415926535
8979323846
2643383279

Para probar los siguientes ejemplos usted mismo, puede ingresar estas líneas en
un editor y guardar el archivo como
c omo pi_digits.txt, o puede descargar el archivo de los
recursos del libro a través de https:// nostarch.com/ pythoncrashcourse2e/.
pythoncrashcourse2e/. Guarde el
archivo en el mismo directorio donde almacenará los programas de este capítulo.
Aquí hay un programa que abre este archivo, lo lee e imprime el contenido
del archivo a la pantalla:

lector_de_archivos.py con open('pi_digits.txt') como file_object:


contenidos = objeto_archivo.leer()
imprimir (contenido)

La primera línea de este programa tiene mucho que hacer. Empecemos mirando
la función open() . Para realizar cualquier trabajo con un archivo, incluso solo para
imprimir su contenido, primero debe abrir el archivo para acceder a él. La función
open() necesita un argumento: el nombre del archivo que desea abrir. Python busca
este archivo en el directorio donde está almacenado el programa que se está ejecutando
actualmente. En este ejemplo, file_reader.py se está ejecutando actualmente, por lo que
Python busca pi_digits.txt en el directorio donde está almacenado file_reader.py . el abierto()
La función devuelve un objeto que representa el archivo. Aquí, abra ('pi_digits.txt')
devuelve un objeto que representa pi_digits.txt. Python asigna este objeto a file_object,
con el que trabajaremos más adelante en el programa.

184 Capítulo 10

MachineTranslatedbyGoogle

La palabra clave con cierra el archivo una vez que ya no es necesario acceder a él.
Observe cómo llamamos a open() en este programa pero no a close(). Puede abrir y cerrar
el archivo llamando a open() y close(), pero si un error en su programa impide que se ejecute
el método close() , es posible que el archivo nunca se cierre. Esto puede parecer trivial, pero
los archivos mal cerrados pueden hacer que los datos se pierdan o se dañen. Y si llama a

close() demasiado pronto en su programa, se encontrará tratando de trabajar con un archivo


cerrado (un archivo al que no puede acceder), lo que genera más errores. No siempre es
fácil saber exactamente cuándo debe cerrar un archivo, pero con la estructura que se
muestra aquí, Python lo resolverá por usted. Todo lo que tiene que hacer es abrir el archivo y
trabajar con él como desee, confiando en que Python lo cerrará automáticamente cuando el
bloque with termine de ejecutarse.

Una vez que tenemos un objeto de archivo que representa pi_digits.txt, usamos read()
en la segunda línea de nuestro programa para leer todo el contenido del archivo y
almacenarlo como una cadena larga en contenidos. Cuando imprimimos el valor de los
contenidos, recuperamos el archivo de texto completo:

3.1415926535
8979323846
2643383279

La única diferencia entre esta salida y el archivo original es la línea en blanco


adicional al final de la salida. La línea en blanco aparece porque read() devuelve una cadena
vacía cuando llega al final del archivo; esta cadena vacía se muestra como una línea en
blanco. Si desea eliminar la línea en blanco adicional, puede usar rstrip() en la llamada a
print():

con open('pi_digits.txt') como file_object:


contenidos = objeto_archivo.leer()
imprimir (contenido.rstrip())

Recuerde que el método rstrip() de Python elimina, o elimina, cualquier carácter de


espacio en blanco del lado derecho de una cadena. Ahora la salida coincide exactamente con
el contenido del archivo original:

3.1415926535
8979323846
2643383279
Rutas de archivos

Cuando pasa un nombre de archivo simple como pi_digits.txt a la función open() , Python

busca en el directorio donde está almacenado el archivo que se está ejecutando actualmente
(es decir, su archivo de programa .py ).
A veces, dependiendo de cómo organice su trabajo, el archivo que desea abrir
no estará en el mismo directorio que su archivo de programa.
Por ejemplo, puede almacenar sus archivos de programa en una carpeta llamada

Archivos y excepciones 185

MachineTranslatedbyGoogle

python_trabajo; dentro de python_work, es posible que tenga otra carpeta llamada text_files
para distinguir sus archivos de programa de los archivos de texto que están manipulando.
Aunque text_files está en python_work, solo pasa open()
el nombre de un archivo en text_files no funcionará, porque Python solo buscará en python_work
y se detendrá allí; no continuará y buscará en text_files. Para que Python abra archivos desde un

directorio que no sea aquel donde está almacenado el archivo de su programa, debe proporcionar
una ruta de archivo, que le indica a Python que busque en una ubicación específica de su sistema.

Debido a que text_files está dentro de python_work, puede usar una ruta de archivo relativa para
abrir un archivo desde text_files. Una ruta de archivo relativa le dice a Python que busque una ubicación
determinada en relación con el directorio donde se almacena el archivo del programa que se está
ejecutando actualmente. Por ejemplo, escribirías:

con open('text_files/filename.txt') como file_object:

Esta línea le dice a Python que busque el archivo .txt deseado en la carpeta text_files y
asume que text_files se encuentra dentro de python_work (que es).

N ota Los sistemas Windows usan una barra invertida (\) en lugar de una barra inclinada (/) al mostrar las
rutas de los archivos, pero aún puede usar barras inclinadas en su código.

También puede decirle a Python exactamente dónde está el archivo en su computadora,


independientemente de dónde esté almacenado el programa que se está ejecutando. Esto se
llama una ruta de archivo absoluta. Utiliza una ruta absoluta si una ruta relativa no funciona. Por
ejemplo, si ha colocado archivos de texto en alguna carpeta que no sea python_work, digamos, una
carpeta llamada otros archivos, simplemente pasando open() la ruta 'text_files/ filename.txt' no
funcionará porque Python solo buscará esa ubicación. dentro de python_work. Deberá escribir una
ruta completa para aclarar dónde desea que busque Python.

Las rutas absolutas suelen ser más largas que las rutas relativas, por lo que es útil
asígnelos a una variable y luego pase esa variable a open():

file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
'/home/ ehmatthes/other_files/text_files/filename.txt'
con open(file_path) como file_object:

Usando rutas absolutas, puede leer archivos desde cualquier ubicación en su sistema. Por
ahora es más fácil almacenar archivos en el mismo directorio que sus archivos de programa o en una
carpeta como text_files dentro del directorio que almacena sus archivos de programa.

N ota Si intenta usar barras invertidas en una ruta de archivo, obtendrá un error porque la barra invertida
se usa para escapar de los caracteres en las cadenas. Por ejemplo, en la ruta "C:
\ruta\a\archivo.txt", la secuencia \t se interpreta como una tabulación. Si necesita usar barras
invertidas, puede escapar de cada una en la ruta, así: "C:\\ruta\\a\\archivo.txt".

186 Capítulo 10

MachineTranslatedbyGoogle

Lectura línea por línea


Cuando esté leyendo un archivo, a menudo querrá examinar cada línea del archivo.
Es posible que esté buscando cierta información en el archivo o que desee modificar el texto del
archivo de alguna manera. Por ejemplo, es posible que desee leer un archivo de datos
meteorológicos
meteorológicos y trabajar con cualquier línea que incluya la palabra soleado en la descripción del
tiempo de ese día. En un informe de noticias, puede buscar cualquier línea con la etiqueta
<titular> y volver a escribir esa línea con un tipo específico de formato.

Puede usar un bucle for en el objeto de archivo para examinar cada línea de un archivo
de una en una:

file_reader.py u nombre de archivo = 'pi_digits.txt'

v con open(nombre de archivo) como objeto_archivo:


w para línea en file_object:
imprimir (línea)

En u asignamos el nombre del archivo que estamos leyendo a la variable


nombre del archivo. Esta es una convención común cuando se trabaja con archivos. Debido a que el
nombre de archivo variable no representa el archivo real, es solo una cadena que le dice a Python dónde
encontrar el archivo, puede intercambiar fácilmente 'pi_digits.txt'
para el nombre de otro archivo con el que desea trabajar. Después de llamar a open(), se
asigna un objeto que representa el archivo y su contenido a la variable file_object v. Nuevamente
usamos la sintaxis with para permitir que Python abra y cierre el archivo correctamente. Para
examinar el contenido del archivo, trabajamos en cada línea del archivo haciendo un bucle
sobre el objeto de archivo w.
Cuando imprimimos cada línea, encontramos aún más líneas en blanco:

3.1415926535

8979323846

2643383279

Estas líneas en blanco aparecen porque hay un carácter invisible de nueva línea al final de cada línea
en el archivo de texto. La función de impresión agrega su propia nueva línea cada vez que la llamamos,
l lamamos, por
lo que terminamos con dos caracteres de nueva línea al final de cada línea: uno del archivo y otro de print().
Usando rstrip()
en cada línea de la llamada print() elimina estas líneas en blanco adicionales:

nombre de archivo = 'pi_digits.txt'

con abierto (nombre de archivo) como file_object:


para línea en file_object:
imprimir (línea.rstrip())

Archivos y excepciones 187

MachineTranslatedbyGoogle

Ahora la salida coincide con el contenido del archivo una vez más:

3.1415926535
8979323846
2643383279

Hacer una lista de líneas de un archivo

Cuando usa with, el objeto de archivo devuelto por open() solo está disponible dentro del
bloque with que lo contiene. Si desea conservar el acceso al contenido de un archivo
fuera del bloque with , puede almacenar las líneas del archivo en una lista dentro del
bloque y luego trabajar con esa lista. Puede procesar partes del archivo inmediatamente
y posponer parte del procesamiento para más adelante en el programa.
El siguiente ejemplo almacena las líneas de pi_digits.txt en una lista dentro del
bloque with y luego imprime las líneas fuera del bloque with :

nombre de archivo = 'pi_digits.txt'

con abierto (nombre de archivo) como file_object:


u líneas = file_object.readlines()
file_object.readlines()

v para línea en líneas:


imprimir (línea.rstrip())

En u, el método readlines() toma cada línea del archivo y la almacena en una lista.
Luego, esta lista se asigna a las líneas, con las que podemos continuar trabajando
después de que finalice el bloque with . En v usamos un bucle for simple para imprimir
cada línea de líneas. Dado que cada elemento de las líneas corresponde a cada línea
del archivo, la salida coincide exactamente con el contenido del archivo.

Trabajar con el contenido de un archivo


Después de leer un archivo en la memoria, puede hacer lo que quiera con esos datos,
así que exploremos brevemente los dígitos de pi. Primero, intentaremos construir una
sola cadena que contenga todos los dígitos del archivo sin espacios en blanco:

pi_string.py nombre de archivo = 'pi_digits.txt'

con abierto (nombre de archivo) como file_object:


líneas = objeto_archivo.readlin
objeto_archivo.readlines()
es()

''
u pi_string = v
para línea en líneas:
pi_string += línea.rstrip()

w imprimir (pi_cadena)
imprimir (len (pi_cadena))

188 Capítulo 10

MachineTranslatedbyGoogle

Comenzamos abriendo el archivo y almacenando cada línea de dígitos en una lista, solo
como hicimos en el ejemplo anterior. En u creamos una variable, pi_string, para contener los
dígitos de pi. Luego creamos un ciclo que agrega cada línea de dígitos a pi_string y elimina el
carácter de nueva línea de cada línea v. En w imprimimos esta cadena y también mostramos
su longitud:

3.1415926535 8979323846 2643383279 36

La variable pi_string contiene el espacio en blanco que estaba en el lado izquierdo de


los dígitos en cada línea, pero podemos deshacernos de eso usando strip()
en lugar de rstrip():

--recorte--
para línea en líneas:
pi_string += línea.strip()

imprimir (pi_cadena)
imprimir (len (pi_cadena))

Ahora tenemos una cadena que contiene pi con 30 decimales. La cadena tiene 32
caracteres porque también incluye el 3 inicial y un punto decimal:

3.141592653589793238462643383279
32

N ota Cuando Python lee un archivo de texto, interpreta todo el texto del archivo como una cadena. Si lee
un número y quiere trabajar con ese valor en un contexto numérico, tendrá que convertirlo en
un número entero usando la función int() o convertirlo en un número flotante usando la función
float() .

Archivos grandes: un millón de dígitos

Hasta ahora nos hemos centrado en analizar un archivo de texto que contiene solo tres líneas,
pero el código de estos ejemplos funcionaría igual de bien en archivos mucho más grandes. Si
comenzamos con un archivo de texto que contiene pi hasta 1.000.000 de decimales en lugar
de solo 30, podemos crear una sola cadena que contenga todos estos dígitos.
No necesitamos cambiar nuestro programa en absoluto excepto para pasarle un archivo diferente.
También imprimiremos solo los primeros 50 lugares decimales, para que no tengamos que ver
pasar un millón de dígitos en la terminal:

pi_string.py nombre de archivo = 'pi_million_digits.txt


'pi_million_digits.txt''

con abierto (nombre de archivo) como file_object:


líneas = objeto_archiv
objeto_archivo.readlines()
o.readlines()

Archivos y Excepciones 189

MachineTranslatedbyGoogle

''
pi_string =
para línea en líneas:
pi_string += línea.strip()

imprimir(f"{pi_cadena[:52]}...")

imprimir (len (pi_cadena))


El resultado muestra que, de hecho, tenemos una cadena que contiene pi con 1,000,000 de
decimales:

3.141592653589793238462643383279502884197169399
3.14159265358979323846264338327950288419716939937510...
37510...
1000002

Python no tiene un límite inherente a la cantidad de datos con los que puede trabajar; usted
puede trabajar con tantos datos como la memoria de su sistema pueda manejar.

N ota Para ejecutar este programa (y muchos de los ejemplos que siguen), deberá descargar los recursos
disponibles en https://nostarch.com/pythoncrashcourse2e/.

¿Tu cumpleaños está contenido en Pi?

Siempre he tenido curiosidad por saber si mi cumpleaños aparece en algún lugar de los dígitos de pi.
Usemos el programa que acabamos de escribir para averiguar si el cumpleaños de alguien aparece en
algún lugar del primer millón de dígitos de pi. Podemos hacer esto expresando cada cumpleaños como una
cadena de dígitos y viendo si esa cadena aparece en algún lugar de pi_string:

--recorte--
para línea en líneas:
pi_string += línea.strip()

u cumpleaños = entrada ("Ingrese su cumpleaños, en la forma mmddyy:")


v si cumpleaños en pi_string:
print("¡Tu cumpleaños aparece en el primer millón de dígitos de pi!")
demás:

print("Tu cumpleaños no aparece en el primer millón de dígitos de pi.")

En u solicitamos el cumpleaños del usuario, y luego en v verificamos si ese


la cadena está en pi_string. Vamos a intentarlo:
Ingrese su fecha de nacimiento, en la forma mmddyy:
120372 ¡ Su cumpleaños aparece en el primer millón de dígitos de pi!

¡Mi cumpleaños aparece en los dígitos de pi! Una vez que hayas leído de un
archivo, puede analizar su contenido en casi cualquier forma que pueda imaginar.

190 Capítulo 10

MachineTranslatedbyGoogle

Inténtalo tú mismo

10-1. Aprendiendo Python: abra un archivo en blanco en su editor de texto y escriba unas
pocas líneas que resuman lo que ha aprendido sobre Python hasta ahora. Comience cada

línea con la frase In Python you can. . . . Guarde el archivo como learning_python.txt en el
mismo directorio que sus ejercicios de este capítulo. Escriba un programa que lea el archivo
e imprima lo que escribió tres veces. Imprima el contenido una vez leyendo todo el archivo, una
vez recorriendo el objeto del archivo y una vez almacenando las líneas en una lista y luego
trabajando con ellas fuera del bloque with .

10-2. Aprendiendo C: puede usar el método replace() para reemplazar cualquier palabra en
una cadena con una palabra diferente. Aquí hay un ejemplo rápido que muestra cómo
reemplazar 'perro' con 'gato' en una oración:

>>> mensaje = "Me gustan mucho los perros".


>>> mensaje.reemplaza
mensaje.reemplazar('perro',
r('perro', 'gato')
Me gustan mucho los gatos.

Lea cada línea del archivo que acaba de crear, learning_python.txt, y reemplace la
palabra Python con el nombre de otro idioma, como C. Imprima cada línea modificada en la
pantalla.

Escribir en un archivo

Una de las formas más sencillas de guardar datos es escribirlos en un archivo. Cuando
escribe texto en un archivo, la salida seguirá estando disponible después de cerrar la
terminal que contiene la salida de su programa. Puede examinar la salida después de que

un programa termine de ejecutarse y también puede compartir los archivos de salida con
otros. También puede escribir programas que vuelvan a leer el texto en la memoria y vuelvan
a trabajar con él más tarde.

Escribir en un archivo vacío


Para escribir texto en un archivo, debe llamar a open() con un segundo argumento que le
dice a Python que desea escribir en el archivo. Para ver cómo funciona esto, escribamos un
mensaje simple y almacenémoslo en un archivo en lugar de imprimirlo en la pantalla:
escribe nombre de archivo = 'programación.txt'
_mensaje.py
u con open(nombre de archivo, 'w') como objeto_archivo:
v file_object.write("Me encanta programar")

La llamada a open() en este


e ste ejemplo tiene dos argumentos u. El primer argumento
sigue siendo el nombre del archivo que queremos abrir. El segundo argumento, 'w', le dice
a Python que queremos abrir el archivo en modo de escritura. Puedes abrir un archivo

Archivos y excepciones 191

MachineTranslatedbyGoogle

en modo de lectura ('r'), modo de escritura ('w'), modo de adición ('a') o un modo que le permita
leer y escribir en el archivo ('r+'). Si omite el argumento de modo, Python abre el archivo en modo
de solo lectura de forma predeterminada.
La función open() crea automáticamente el archivo en el que está escribiendo si aún no
existe. Sin embargo, tenga cuidado al abrir un archivo en modo de escritura ('w') porque si el

archivo existe, Python borrará el contenido del archivo antes de devolver el objeto del archivo.

En v usamos el método write() en el objeto de archivo para escribir una cadena en el


archivo. Este programa no tiene salida de terminal, pero si abre el archivo programación.txt,
verá una línea:

programación.txt Me encanta programar.

Este archivo se comporta como cualquier otro archivo en su computadora. Puede abrirlo,
escribir texto nuevo en él, copiarlo,
c opiarlo, pegarlo, etc.

N ota Python solo puede escribir cadenas en un archivo de texto. Si desea almacenar datos numéricos en un
archivo de texto, primero tendrá que convertir los datos a formato de cadena usando la función str() .

Escribir varias líneas


La función write() no agrega líneas nuevas al texto que escribe. Por lo tanto, si escribe más de
una línea sin incluir caracteres de nueva línea, es posible que su archivo no tenga el aspecto
que desea:

nombre de archivo = 'programación.txt'

con open(nombre de archivo, 'w') como objeto_archivo:


file_object.write("Me encanta programar")
file_object.write("Me encanta crear nuevos juegos").

Si abres programación.txt, verás las dos líneas juntas:

Me encanta programar. Me encanta crear nuevos juegos.

Incluir líneas nuevas en tus llamadas a write() hace que cada cadena aparezca en su propia
línea:

nombre de archivo = 'programación.txt'


con open(nombre de archivo, 'w') como objeto_archivo:
file_object.write("Me encanta programar.\n")
file_object.write("Me encanta crear nuevos juegos.\n")

La salida ahora aparece en líneas separadas:

Me encanta la programación.
Me encanta crear nuevos juegos.

192 Capítulo 10

MachineTranslatedbyGoogle

También puede utilizar espacios, caracteres de tabulación y líneas en blanco para dar formato a su
salida, tal como lo ha estado haciendo con la salida basada en terminal.

Agregar a un archivo
Si desea agregar contenido a un archivo en lugar de escribir sobre el contenido existente, puede abrir el
archivo en modo de adición. Cuando abre un archivo en modo de adición, Python no borra el contenido
del archivo antes de devolver el objeto de archivo.
Cualquier línea que escriba en el archivo se agregará al final del archivo. Si el archivo aún no existe,
Python creará un archivo vacío para usted.
Modifiquemos write_message.py agregando algunas nuevas razones por las que nos encanta
programar al archivo de programación existente.txt:

escribe nombre de archivo = 'programación.txt'


_mensaje.py
u con open(filename, 'a') como file_object:
v file_object.write("También me encanta encontrar significado en grandes conjuntos de datos.\
datos.\n")
n")
file_object.write("Me encanta crear aplicaciones que puedan ejecutarse en un nave gador.\
gador.\n")
n")

En u usamos el argumento 'a' para abrir el archivo y agregarlo en lugar de escribir sobre el
archivo existente. En v escribimos dos líneas nuevas, que se agregan a programación.txt:

programación.txt Me encanta programar.


Me encanta crear nuevos juegos.
También me encanta encontrar significado en grandes conjuntos de datos.
Me encanta crear aplicaciones que puedan ejecutarse en un navegador.

Terminamos con el contenido original del archivo, seguido del nuevo contenido que acabamos
de agregar.

Inténtalo tú mismo

10-3. Invitado: escriba un programa que solicite al usuario su nombre. Cuando respondan, escribe su nombre

en un archivo llamado guest.txt.

10-4. Libro de invitados: escriba un bucle while que solicite a los usuarios su nombre. Cuando ingresen su

nombre, imprima un saludo en la pantalla y agregue una línea que registre su visita en un archivo llamado
guest_book.txt. Asegúrese de que cada entrada aparezca en una nueva línea en el archivo.

10-5. Encuesta de programación: escriba un ciclo while que pregunte a las personas por qué les gusta

programar. Cada vez que alguien ingrese un motivo, agregue su motivo a un archivo que almacena todas

las respuestas.

Archivos y Excepciones 193

MachineTranslatedbyGoogle

Excepciones

Python usa objetos especiales llamados excepciones para administrar los errores que
surgen durante la ejecución de un programa. Cada vez que ocurre un error que hace
que Python no esté seguro de qué hacer a continuación, crea un objeto de excepción.

Si escribe código que maneja la excepción, el programa continuará ejecutándose. Si no


maneja la excepción, el programa se detendrá y mostrará un seguimiento, que incluye
un informe de la excepción que se generó.
Las excepciones se manejan con bloques try-except . Un bloque try-except le
pide a Python que haga algo, pero también
t ambién le dice a Python qué hacer si surge una
excepción. Cuando usa bloques try-except , sus programas continuarán ejecutándose
incluso si las cosas comienzan a salir mal. En lugar de rastreos, que pueden resultar
confusos para los usuarios, los usuarios verán mensajes de error amigables que usted
escribe.

Manejo de la excepción ZeroDivisionError

Veamos un error simple que hace que Python genere una excepción. Probablemente
sepa que es imposible dividir un número por cero, pero pidamos a Python que lo
haga de todos modos:

división imprimir (5/0)


_calculadora.py
_calculadora.py
Por supuesto, Python no puede hacer esto, por lo que obtenemos un seguimiento:

Rastreo (llamadas recientes más última):


Archivo "division_calculator.py",
"division_calculator.py", línea 1, en <módulo> print(5/0) u
ZeroDivisionError: división por cero

El error informado en u en el rastreo, ZeroDivisionError, es una excepción .


objeto de ción. Python crea este tipo de objeto en respuesta a una situación en la
que no puede hacer lo que le pedimos. Cuando esto sucede, Python detiene el
programa y nos dice el tipo de excepción que se generó. Podemos utilizar esta
información para modificar nuestro programa. Le diremos a Python qué hacer cuando
ocurra este tipo de excepción; así, si vuelve a pasar, estamos preparados.

Uso de bloques try-except


Cuando crea que puede ocurrir un error, puede escribir un bloque try-except
try-except para
manejar la excepción que podría generarse. Le dices a Python que intente ejecutar
algún código y le dices qué hacer si el código resulta en un tipo particular de excepción.

Así es como se ve un bloque try-except para manejar la excepción


ZeroDivisionError :

tratar:
imprimir (5/0)
excepto ZeroDivisionError:
print("¡No puedes dividir por cero!")

194 Capítulo 10

MachineTranslatedbyGoogle

Ponemos print(5/0), la línea que causó el error, dentro de un bloque de prueba . Si el


código en un bloque de prueba funciona, Python salta el bloque de excepción . Si el código en el
bloque de prueba genera un error, Python busca un bloque de excepción cuyo error coincida con
el que se generó y ejecuta el código en ese bloque.
En este ejemplo, el código en el bloque de prueba produce un ZeroDivisionError, por lo

que Python busca un bloque de excepción que le indique cómo responder. Luego, Python
ejecuta el código en ese bloque y el usuario ve un mensaje de error amigable en lugar de un
rastreo:

¡No puedes dividir por cero!

Si hubiera más código seguido del bloque try-except , el programa continuaría ejecutándose
porque le dijimos a Python cómo manejar el error. Veamos un ejemplo en el que detectar un error
puede permitir que un programa continúe ejecutándose.

Uso de excepciones para evitar bloqueos

El manejo correcto de los errores es especialmente importante cuando el programa tiene más
trabajo que hacer después de que ocurre el error. Esto sucede a menudo en programas que
solicitan a los usuarios que ingresen información. Si el programa responde adecuadamente a
una entrada no válida, puede solicitar una entrada más válida en lugar de bloquearse.
Vamos a crear una calculadora simple que solo haga divisiones:

división print("Dame dos numeros y los dividire")


_calculadora.py print("Ingrese 'q' para salir.")

mientras que es cierto:

u primer_número = entrada("\nPrimer número: ")


si primer_número == 'q':
romper
v segundo_numero = entrada("Segundo numero: ")
si segundo_número == 'q':
romper
w respuesta = int(primer_número) / int(segundo_número)
imprimir (respuesta)

Este programa solicita al usuario que ingrese un primer_número u y, si el usuario no


ingresa q para salir, un segundo_número v. Luego dividimos estos dos números para obtener
una respuesta w. Este programa no hace nada para manejar los errores, por lo que pedirle
que divida por cero hace que se bloquee:
Dame dos números y los dividiré.
Introduzca 'q' para salir.

Primer número: 5
Segundo número: 0
Rastreo (llamadas recientes más última):
Archivo "division_calculator.py", línea 9, en <módulo> respuesta =
int(primer_número) / int(segundo_número)
i nt(segundo_número)
ZeroDivisionError: división por cero

Archivos y excepciones 195

MachineTranslatedbyGoogle

Es malo que el programa se bloquee, pero tampoco es una buena idea permitir
que los usuarios vean los rastreos. Los usuarios no técnicos se sentirán confundidos
por ellos y, en un entorno malicioso, los atacantes aprenderán más de lo que usted
quiere que sepan a partir de un rastreo. Por ejemplo, sabrán el nombre de su archivo
de programa y verán una parte de su código
c ódigo que no funciona correctamente. Un atacante
habilidoso a veces puede usar esta información para determinar qué tipo de ataques
usar contra su código.

El otro bloque
Podemos hacer que este programa sea más resistente a errores envolviendo la línea
que podría producir errores en un bloque try-except . El error se produce en la línea
que realiza la división, por lo que allí colocaremos el bloque try-except .
Este ejemplo también incluye un bloque else . Cualquier código que dependa del intento .
la ejecución exitosa del bloque va en el bloque else :

--recorte--
mientras que es cierto:

--recorte--
si segundo_número == 'q':
romper
Inténtalo tu:
respuesta = int(primer_número) / int(segundo_número)
v excepto ZeroDivisionError:
print("¡No puedes dividir por 0!")
en otro:
imprimir (respuesta)

Le pedimos a Python que intente completar la operación de división en un intento .


bloque u, que incluye solo el código que podría causar un error. Cualquier código
que dependa del éxito del bloque try se agrega al bloque else .

En este caso, si la operación de división es exitosa, usamos el bloque else para


imprimir el resultado w.
El bloque de excepción le dice a Python cómo responder cuando un ZeroDivisionError
surge v. Si el bloque try no tiene éxito debido a un error de división por cero,
imprimimos un mensaje amigable que le dice al usuario cómo evitar este tipo de
error. El programa continúa ejecutándose y el usuario nunca ve un rastro:
Dame dos números y los dividiré.
Introduzca 'q' para salir.

Primer número: 5
Segundo número: 0

¡No puedes dividir por 0!

196 Capítulo 10

MachineTranslatedbyGoogle

Primer número: 5
Segundo número: 2
2.5

primer número: q

El bloque try-except-else funciona así: Python intenta ejecutar el código en el bloque


try . El único código que debe ir en un bloque de prueba es el código que puede provocar
que se genere una excepción. A veces tendrá código adicional que debería ejecutarse
solo si el bloque de prueba fue exitoso; este código va en el bloque else . El bloque de
excepción le dice a Python qué hacer en caso de que surja una determinada excepción
cuando intente ejecutar el código en el bloque de prueba .
Al anticipar las posibles fuentes de errores, puede escribir programas robustos
que continúan ejecutándose incluso cuando encuentran datos no válidos y faltan recursos.
Su código será resistente a errores de usuarios inocentes y ataques maliciosos.

Manejo de la excepción FileNotFoundError


Un problema común cuando se trabaja con archivos es el manejo de archivos que faltan.
El archivo que está buscando puede estar en una ubicación diferente, el nombre del archivo
puede estar mal escrito o el archivo puede no existir en absoluto. Puede manejar todas
estas situaciones de una manera sencilla con un bloque de prueba excepto .
Intentemos leer un archivo que no existe. El siguiente programa intenta leer el
contenido de Alicia en el país de las maravillas, pero no he guardado el archivo alice.txt
en el mismo directorio que alice.py:

alice.py nombre de archivo = 'alicia.txt'

con abierto (nombre de archivo, codificación = 'utf-8') como f:


contenido = f.leer()

Hay dos cambios aquí. Uno es el uso de la variable f para representar el objeto de
archivo, que es una convención común. El segundo es el uso del argumento de codificación .
Este argumento es necesario cuando la codificación predeterminada de su sistema no coincide
con la codificación del archivo que se está leyendo.
Python no puede leer un archivo que falta, por lo que genera una excepción:

Rastreo (llamadas recientes más última):


Archivo alice.py , línea 3, en <módulo>
con abierto (nombre de archivo, codificación = ' utf-8') como f:
FileNotFoundError: [Errno 2] No existe tal archivo o directorio: 'alice.txt'

La última línea del rastreo informa un FileNotFoundError: esta es la excepción que


Python crea cuando no puede encontrar el archivo que está tratando de abrir.

Archivos y excepciones 197

MachineTranslatedbyGoogle

En este ejemplo, la función open() produce el error, así que para manejarlo, el bloque try
comenzará con la línea que contiene open():

nombre de archivo = 'alicia.txt'

tratar:
con abierto (nombre de archivo, codificación = ' utf-8') como f:
contenido = f.leer()
excepto FileNotFoundError:
print(f"Lo siento, el archivo {nombre de archivo} no existe").

En este ejemplo, el código en el bloque try produce un FileNotFoundError,


entonces Python busca un bloque de excepción que coincida con ese error. Luego, Python
ejecuta el código en ese bloque y el resultado es un mensaje de error amigable en lugar
de un rastreo:

Lo sentimos, el archivo alice.txt no existe.

El programa no tiene nada más que hacer si el archivo no existe, por lo que el código
de manejo de errores no agrega mucho a este programa. Construyamos sobre este ejemplo
y veamos cómo el manejo de excepciones puede ayudar cuando trabaja con más de un
archivo.

Analizando texto
Puede analizar archivos de texto que contengan libros completos. Muchas obras clásicas de
la literatura están disponibles como archivos de texto simples porque son de dominio público.
Los textos utilizados en esta sección provienen del Proyecto Gutenberg (http:// gutenberg
.org/). Project Gutenberg mantiene una colección de obras literarias que están disponibles
en el dominio público y es un gran recurso si está interesado en trabajar con textos literarios
en sus proyectos de programación.

Extraigamos el texto de Alicia en el país de las maravillas e intentemos contar el número


de palabras del texto. Usaremos el método de cadena split(), que puede construir una lista de
palabras a partir de una cadena. Esto es lo que hace split() con una cadena que contiene solo
el título "Alicia en el país de las maravillas":

>>> título = "Alicia en el País de las


Maravillas" >>> título.split()
['Alicia en el país de las Maravillas']
El método split() separa una cadena en partes siempre que encuentra un espacio y
almacena todas las partes de la cadena en una lista. El resultado es una lista de palabras
de la cadena, aunque también pueden aparecer algunos signos de puntuación con algunas
de las palabras. Para contar el número de palabras en Alicia en el país de las maravillas,
usaremos split() en todo el texto. Luego contaremos los elementos de la lista para tener una
idea aproximada de la cantidad de palabras en el texto:

nombre de archivo = 'alicia.txt'

tratar:

198 Capítulo 10

MachineTranslatedbyGoogle

con abierto (nombre de archivo, codificación = 'utf-8') como f:


contenido = f.leer()
excepto FileNotFoundError:
print(f"Lo siento, el archivo {nombre de archivo} no existe").
demás:

# Cuente el número aproximado de palabras en el archivo.


u palabras = contenidos.split()
v num_palabras = len(palabras)
w print(f"El archivo {fil ename} tiene aproximadamente {num_words} palabras").

Moví el archivo alice.txt al directorio correcto, por lo que el bloque de prueba funcionará
esta vez. En u, tomamos el contenido de la cadena, que ahora contiene el texto completo de
Alicia en el país de las maravillas como una cadena larga, y usamos split()
método para producir una lista de todas las palabras en el libro. Cuando usamos len() en esta
lista para examinar su longitud, obtenemos una buena aproximación del número de palabras en
la cadena original v. En w imprimimos una declaración que informa cuántas palabras se
encontraron en el archivo. Este código se coloca en el bloque else porque funcionará solo si el
código en el bloque try se ejecutó con éxito por completo. El resultado nos dice cuántas palabras
hay en alice.txt:

El archivo alice.txt tiene alrededor de 29465 palabras.

El conteo es un poco alto porque la información adicional es provista por el


editor en el archivo de texto
t exto utilizado aquí, pero es una buena aproximación de lla
a longitud
de Alicia en el País de las Maravillas.

Trabajar con varios archivos


Agreguemos más libros para analizar. Pero antes de hacerlo, pasemos la mayor parte de
este programa a una función llamada contar_palabras(). Al hacerlo, será más fácil ejecutar el
análisis de varios libros:

word_count.py def count_words(nombre de archivo):


u """Cuenta el número aproximado de palabras en un archivo."""
tratar:
con abierto (nombre de archivo, codificación = 'utf-8') como f:
contenidos = f.read() excepto
FileNotFoundError:
print(f"Lo siento, el archivo {nombre de archivo} no existe").
demás:
palabras = contenido.split()
num_palabras = len(palabras)
print(f"El archivo {filename} tiene aproximadamente {num_words} palabras").

nombre de archivo = 'alicia.txt'

contar_palabras(nombre de archivo)

La mayor parte de este código no ha cambiado. Simplemente lo sangramos y lo


movimos al cuerpo de count_words(). Es un buen hábito mantener los comentarios actualizados
cuando está modificando un programa, así que cambiamos el comentario a una cadena de
documentos y lo reformulamos ligeramente.

Archivos y Excepciones 199

MachineTranslatedbyGoogle

Ahora podemos escribir un ciclo simple para contar las palabras en cualquier texto que
queramos analizar. Hacemos esto almacenando los nombres de los archivos que queremos
analizar en una lista y luego llamamos a count_words() para cada archivo en la lista. Intentaremos
contar las palabras de Alicia en el país de las maravillas, Siddhartha, Moby Dick y Mujercitas, que
están disponibles en el dominio público. He dejado intencionalmente siddhartha.txt fuera del

directorio que contiene word_count.py, para que podamos ver qué tan bien nuestro programa
maneja un archivo faltante:

def contar_palabras(nombre de archivo):


--recorte--

nombres de archivo = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt


'moby_dick.txt',', 'little_women.txt']
para nombre de archivo en nombres de archivo:

contar_palabras(nombre de archivo)

El archivo siddhartha.txt faltante no tiene efecto en el resto de la ejecución del programa:

El archivo alice.txt tiene alrededor de 29465 palabras.


Lo sentimos, el archivo siddhartha.txt no existe.
El archivo moby_dick.txt tiene alrededor de 215830 palabras.
El archivo little_women.txt tiene alrededor de 189079 palabras.

El uso del bloque try-except en este ejemplo proporciona dos ventajas significativas.
Evitamos que nuestros usuarios vean un rastreo y dejamos que el programa continúe analizando
los textos que puede encontrar. Si no detectamos el FileNotFoundError que generó
siddhartha.txtt , el usuario vería un rastreo completo y el programa dejaría de ejecutarse después
siddhartha.tx
de intentar analizar Siddhartha. Nunca analizaría Moby Dick o Mujercitas.

fallando en silencio

En el ejemplo anterior, informamos a nuestros usuarios que uno de los archivos no estaba
disponible. Pero no necesita informar cada excepción que detecte.
A veces querrá que el programa falle silenciosame
silenciosamente
nte cuando ocurra una excepción y continúe
como si nada hubiera pasado. Para hacer que un programa falle silenciosamente, escribes un
bloque de prueba como de costumbre, pero le dices explícitamente a Python que no haga nada en
el bloque de excepción . Python tiene una declaración de paso que le dice que no haga nada en un bloque:
def contar_palabras(nombre de archivo):
"""Cuenta el número aproximado de palabras en un archivo."""
tratar:
--recorte--
excepto FileNotFound
FileNotFoundError:
Error:
en aprobar
demás:

--recorte--

nombres de archivo = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt',


'moby_dick.txt', 'little_women.txt']
para nombre de archivo en nombres de archivo:

contar_palabras(nombre de archivo)

200 Capítulo 10

MachineTranslatedbyGoogle

La única diferencia entre este listado y el anterior es la declaración de aprobación en u. Ahora,


cuando se genera un FileNotFoundError , se ejecuta el código en el bloque excepto , pero no sucede
nada. No se produce ningún rastreo y no hay ningún resultado en respuesta al error que se generó.
Los usuarios ven los recuentos de palabras para cada archivo que existe, pero no ven ninguna
indicación de que no se encontró un archivo:

El archivo alice.txt tiene alrededor de 29465 palabras.


El archivo moby_dick.txt tiene alrededor de 215830 palabras.
El archivo little_women.txt tiene alrededor de 189079 palabras.

La instrucción de paso también actúa como marcador de posición. Es un recordatorio de que eres
elegir no hacer nada en un punto específico de la ejecución de su programa y que es posible que
desee hacer algo allí más tarde. Por ejemplo, en este programa podríamos decidir escribir cualquier
nombre de archivo que falte en un archivo llamado archivos_faltantes.txt. Nuestros usuarios no verían
este archivo, pero podríamos leerlo y solucionar cualquier texto que falte.

Decidir qué errores informar


¿Cómo sabe cuándo informar un error a sus usuarios y cuándo fallar en silencio? Si los usuarios
saben qué textos se supone que deben analizarse, podrían apreciar un mensaje que les informe por qué
no se analizaron algunos textos. Si los usuarios esperan ver algunos resultados pero no saben qué libros
deben analizarse, es posible que no necesiten saber que algunos textos no estaban disponibles. Dar a
los usuarios información que no están buscando puede disminuir la usabilidad de su programa. Las
estructuras de manejo de errores de Python le brindan un control detallado sobre cuánto compartir con
los usuarios cuando las cosas salen mal; depende de usted decidir cuánta información compartir.

El código bien escrito y debidamente probado no es muy propenso a errores internos, como
errores de sintaxis o lógicos. Pero cada vez que su programa depende de algo externo, como la
entrada del usuario, la existencia de un archivo o la disponibilidad de una conexión de red, existe la
posibilidad de que se genere una excepción. Un poco de experiencia lo ayudará a saber dónde incluir
bloques de manejo de excepciones en su programa y cuánto informar a los usuarios sobre los errores
que surjan.
Inténtalo tú mismo

10-6. Adición: un problema común cuando se solicita una entrada numérica ocurre
cuando las personas proporcionan texto en lugar de números. Cuando intente convertir la

entrada a un int, obtendrá un ValueError. Escriba un programa que solicite dos números.
Súmalos e imprime el resultado. Detecte el ValueError si alguno de los valores de entrada
no es un número e imprima un mensaje de error amistoso. Pruebe su programa ingresando
dos números y luego ingresando algún texto en lugar de un número.

(continuado)

Archivos y Excepciones 201

MachineTranslatedbyGoogle

10-7. Calculadora de sumas: Envuelva su código del Ejercicio 10-6 en un ciclo while para que el
usuario pueda continuar ingresando números incluso si comete un error e ingresa texto en lugar de
un número.

10-8. Perros y gatos: haga dos archivos, cats.txt y dogs.txt. Guarde al menos tres nombres de
gatos en el primer archivo y tres nombres de perros en el segundo archivo. Escriba un programa
que intente leer estos archivos e imprima el contenido del archivo en la pantalla. Envuelva su código
en un bloque try-except para detectar el error FileNotFound e imprima un mensaje amigable si falta
un archivo. Mueva uno de los archivos a una ubicación diferente en su sistema y asegúrese de que
el código en el bloque excepto se ejecute correctamente.

10-9. Gatos y perros silenciosos: modifique su bloque de excepción en el ejercicio 10-8 para
fallar silenciosamente si falta algún archivo.

10-10. Palabras comunes: Visite Project Gutenberg (https://gutenberg.org/) y encuentre


algunos textos que le gustaría analizar. Descargue los archivos de texto de estos trabajos o copie
el texto sin formato de su navegador a un archivo de texto en su computadora.

Puede usar el método count() para averiguar cuántas veces aparece una palabra o frase
en una cadena. Por ejemplo, el siguiente código cuenta el número de veces que aparece 'fila' en una
cadena:

>>> linea = "Rema, rema, rema tu bote" >>>


linea.count('fila')
2

>>> linea.inferior().cuenta('fila')
3

Tenga en cuenta que convertir la cadena a minúsculas usando lower() atrapa


todas las apariciones de la palabra que está buscando, independientemente de su formato.

Escriba un programa que lea los archivos que encontró en el Proyecto Gutenberg y determine
cuántas veces aparece la palabra 'el' en cada texto. Esta será una aproximación porque también
contará palabras como 'entonces' y 'allí'.
Intente contar 'el ', con un espacio en la cadena, y vea cuánto más baja su
cuenta es.
Almacenamiento
Almacenamiento de datos

Muchos de sus programas le pedirán a los usuarios que ingresen ciertos tipos de información.

Puede permitir que los usuarios almacenen preferenc


preferencias
ias en un juego o proporcionen datos
para una visualización. Cualquiera que sea el enfoque de su programa, almacena
almacenará
rá la
información que los usuarios proporcionen en estructuras de datos como listas y diccionarios.
Cuando los usuarios cierran un programa, casi siempre querrá guardar la información que
ingresaron. Una forma sencilla de hacer esto consiste en almacenar sus datos utilizando el
módulo json .

202 Capítulo 10

MachineTranslatedbyGoogle

El módulo json le permite volcar estructuras de datos simples de Python en un archivo y cargar los datos
de ese archivo la próxima vez que se ejecute el programa. También puede usar json para compartir datos
entre diferentes programas de Python. Aún mejor, el formato de datos JSON no es específico de Python, por
lo que puede compartir los datos que almacena en formato JSON con personas que trabajan en muchos otros
lenguajes de programación. Es un formato útil y portátil, y es fácil de aprender.

N ota El formato JSON (Notación de objetos de JavaScript) se desarrolló originalmente para JavaScript.
Sin embargo, desde entonces se ha convertido en un formato común utilizado por muchos lenguajes,
incluido Python.

Usando json.dump() y json.load()


Escribamos un programa corto que almacene un conjunto de números y otro programa que vuelva a leer
estos números en la memoria. El primer programa utilizará json.dump() para almacenar el conjunto de
números y el segundo programa utilizará json.load().

La función json.dump() toma dos argumentos: un dato para almacenar y un objeto de archivo
que puede usar para almacenar los datos. Así es como puede usar json.dump() para almacenar una lista
de números:

número de importación json


_escritor.py
números = [2, 3, 5, 7, 11, 13]

u nombre de archivo = 'números.json'


v con abierto (nombre de archivo, 'w') como f:
w json.dump(números, f)

Primero importamos el módulo json y luego creamos una lista de números para trabajar. En u
elegimos un nombre de archivo en el que almacenar la lista de números.

Es habitual utilizar la extensión de archivo .json para indicar que los datos del archivo se almacenan en
formato JSON. Luego abrimos el archivo en modo de escritura, lo que le permite a json escribir los datos en
el archivo v. En w usamos json.dump()
función para almacenar los números de la lista en el archivo numbers.json.
Este programa no tiene salida, pero abramos el archivo number.json y
Míralo. Los datos se almacenan en un formato que se parece a Python:

[2, 3, 5, 7, 11, 13]


Ahora escribiremos un programa que use json.load() para volver a leer la lista en la memoria:

número de importación json


_lector.py
u nombre de archivo = 'números.json'
v con abierto (nombre de archivo) como f:
w números = json.load(f)

imprimir (números)

Archivos y Excepciones 203

MachineTranslatedbyGoogle

En u nos aseguramos de leer del mismo archivo en el que escribimos. Esta vez
cuando abrimos el archivo, lo abrimos en modo lectura porque Python solo necesita leer del archivo v. En
w usamos la función json.load() para cargar la información almacenada en numbers.json, y la asignamos
al numeros variables
Finalmente imprimimos la lista de números recuperada y vemos que es la misma lista creada en

number_writer.py:

[2, 3, 5, 7, 11, 13]

Esta es una forma sencilla de compartir datos entre dos programas.

Guardar y leer datos generados por el usuario


Guardar datos con json es útil cuando trabaja con datos generados por el usuario, porque si no
almacena la información de su usuario de alguna manera, la perderá cuando el programa deje de
ejecutarse. Veamos un ejemplo en el que le pedimos al usuario su nombre la primera vez que ejecuta un
programa y luego recordamos su nombre cuando ejecuta el programa nuevamente.

Comencemos almacenando el nombre del usuario:

recuerda importar json


_me.py
u nombre de usuario = entrada ("¿Cuál es tu nombre?")

nombre de archivo = 'nombre de usuario.json'


con abierto (nombre de archivo, 'w') como f:
v json.dump(nombre de usuario, f)
w print(f"¡Te recordaremos cuando regreses, {nombre de usuario}!")

En u solicitamos un nombre de usuario para almacenar. Luego, usamos json.dump(),


pasándole un nombre de usuario y un objeto de archivo, para almacenar el nombre de usuario en un archivo v.

Luego imprimimos un mensaje informando al usuario que hemos almacenado su información w:

¿Cómo te llamas? eric


¡Te recordaremos cuando vuelvas, Eric!

Ahora escribamos un nuevo programa que salude a un usuario cuyo nombre ya ha sido
almacenado:
saludar_usuario.py importar json

nombre de archivo = 'nombre de usuario.json'

con abierto (nombre de archivo) como f:


u nombre de usuario = json.load(f)
v print(f"¡Bienvenido de nuevo, {nombre de usuario}!")

204 Capítulo 10

MachineTranslatedbyGoogle

En u usamos json.load() para leer la información almacena


almacenada
da en username.json
y asígnelo a la variable nombre de usuario. Ahora que hemos recuperado el nombre de usuario,
podemos darle la bienvenida v:

¡Bienvenido de nuevo, Erick!

Necesitamos
Necesitamos combinar estos dos programas en un solo archivo. Cuando alguien
ejecuta Remember_me.py, queremos recuperar su nombre de usuario de la memoria si es posible;
por lo tanto, comenzaremos con un bloque de prueba que intenta recuperar el nombre de usuario. Si
el archivo nombreusuario.json no existe, tendremos el aviso de bloque de excepción para un nombre
de usuario y lo almacenaremos en nombreusuario.json para la próxima vez:

recuerda importar json


_me.py
# Cargue el nombre de usuario, si se ha almacenado previamente.
# De lo contrario, solicite el nombre de usuario y guárdelo.
nombre de archivo = 'nombre de usuario.json'

tratar:

u con abierto (nombre de archivo) como f:


en nombre de usuario = json.load(f)
w excepto FileNotFoundError:
x nombre de usuario = entrada ("¿Cuál es tu nombre?")
y con abierto (nombre de archivo, 'w') como f:
json.dump(nombre
json.dump(nombre de usuario,
usuario, f)
print(f"¡Te recordaremos cuando regreses, {nombre de usuario}!")
demás:

print(f"¡Bienvenido
print(f"¡Bienvenido de nuevo, {nombre de usuario}!")

No hay código nuevo aquí; los bloques de código de los dos últimos ejemplos se combinan en
un solo archivo. En u intentamos abrir el archivo username.json.
Si este archivo existe, volvemos a leer el nombre de usuario en la memoria v e imprimimos un
mensaje de bienvenida al usuario en el bloque else . Si esta es la primera vez que el usuario ejecuta
el programa, el nombre de usuario.json no existirá y aparecerá un FileNotFoundError
ocurrirá w. Python pasará al bloque excepto donde le pediremos al usuario que ingrese su nombre de
usuario x. Luego usamos json.dump() para almacenar el nombre de usuario e imprimir un saludo y.

Cualquiera que sea el bloque que se ejecuta, el resultado es un nombre de usuario y un apropiado
saludo. Si esta es la primera vez que se ejecuta el programa, esta es la salida:
¿Cómo te llamas? eric

¡Te recordaremos cuando vuelvas, Eric!

De lo contrario:

¡Bienvenido de nuevo, Erick!

Este es el resultado que ve si el programa ya se ejecutó al menos una vez.

Archivos y excepciones 205

MachineTranslatedbyGoogle

refactorización

A menudo, llegará a un punto en el que su código funcionará, pero reconocerá que puede
mejorar el código si lo divide en una serie de funciones que tienen tareas específicas. Este
proceso se llama refactorización. La refactorización hace que su código sea más limpio, más
fácil de entender y más fácil de extender.
Podemos refactorizar Remember_me.py moviendo la mayor parte de su lógica a una o
más funciones. El enfoque de Remember_me.py es saludar al usuario, así que vamos a mover
todo nuestro código existente a una función llamada greeting_user():

recuerda importar json


_me.py
def saludo_usuario(
saludo_usuario():
):
u """Saluda al usuario por su nombre."""
nombre de archivo = 'nombre de usuario.json'

tratar:
con abierto (nombre de archivo) como f:
nombre de usuario = json.load(f)
excepto FileNotFoundErr
FileNotFoundError:
or:

nombre de usuario = entrada ("¿Cuál es tu nombre?")


con abierto (nombre de archivo, 'w') como f:
json.dump(nomb
json.dump(nombre
re de usuario, f)
print(f"¡Te recordaremos cuando regreses, {nombre de usuario}!")
demás:

print(f"¡Bienvenido
print(f"¡Bienvenido de nuevo, {nombre de usuario}!")

saludar_usuario()

Debido a que estamos usando una función ahora, actualizamos los comentarios con
una cadena de documentación que refleja cómo funciona actualmente el programa u. Este
archivo es un poco más limpio, pero la función greeting_user() hace más que solo saludar al
usuario: también recupera un nombre de usuario almacenado, si existe, y solicita un nuevo
nombre de usuario si no existe.
Refactoricemos greeting_user()
greeting_user() para que no haga tantas tareas diferentes.
Comenzaremos moviendo el código para recuperar un nombre de usuario almacenado a una
función separada:

importar json

def get_stored_user
get_stored_username():
name():
u Obtener nombre de usuario almacenado si está disponible.
nombre de archivo = 'nombre de usuario.json'

tratar:
con abierto (nombre de archivo) como f:
nombre de usuario = json.load(f)
excepto FileNotFoundErr
FileNotFoundError:
or:
en volver Ninguno
demás:
devolver nombre de usuario

206 Capítulo 10

MachineTranslatedbyGoogle

def saludo_usuario():
"""Saluda al usuario por su nombre."""
nombre de usuario = get_stored_username()
w si nombre de usuario:

print(f"¡Bienvenido de nuevo, {nombre de usuario}!")


demás:

nombre de usuario = entrada ("¿Cuál es tu nombre?")


nombre de archivo = 'nombre de usuario.json'
con abierto (nombre de archivo, 'w') como f:
json.dump(nombre de usuario,
usuario, f)
print(f"¡Te recordaremos cuando regreses, {nombre de usuario}!")

saludar_usuario()

La nueva función get_stored_username() tiene un propósito claro, como se


indica en la cadena de documentación en u. Esta función recupera un nombre de
usuario almacenado y devuelve el nombre de usuario si encuentra uno. Si el archivo
nombreusuario.json no existe, la función devuelve Ninguno v. Esta es una buena
práctica: una función debe devolver el valor que espera o Ninguno. Esto nos permite
realizar una prueba simple con el valor de retorno de la función. En w imprimimos
un mensaje de bienvenida para el usuario si el intento de recuperar un nombre de
usuario fue exitoso y, si no es así, solicitamos un nuevo nombre de usuario.
Deberíamos factorizar un bloque más de código fuera de greeting_user().
Si el nombre de usuario no existe, debemos mover el código que solicita un
nuevo nombre de usuario a una función dedicada a ese propósito:

importar json

def get_stored_username():
"""Obtener nombre de usuario almacenado si está disponible."""

--recorte--

def obtener_nuevo_n
obtener_nuevo_nombre_de_usuario(
ombre_de_usuario():
):
"""Solicitar un nuevo nombre de usuario."""
nombre de usuario = entrada ("¿Cuál es tu nombre?")
nombre de archivo = 'nombre de usuario.json'

con abierto (nombre de archivo, 'w') como f:


json.dump(nombre de usuario,
usuario, f)
devolver nombre de usuario

def saludo_usuario():
"""Saluda al usuario por su nombre."""
nombre de usuario = get_stored_username()
si nombre de usuario:

print(f"¡Bienvenido de nuevo, {nombre de usuario}!")


demás:

nombre de usuario = get_new_username()


print(f"¡Te recordaremos cuando regreses, {nombre de usuario}!")

saludar_usuario()

Archivos y Excepciones 207

MachineTranslatedbyGoogle

Cada función en esta versión final de Remember_me.py tiene un propósito único


y claro. Llamamos a greeting_user(), y esa función imprime un mensaje apropiado: da
la bienvenida a un usuario existente o saluda a un nuevo usuario. Lo hace llamando a
get_stored_username(), que es responsable solo de recuperar un nombre de usuario
almacenado, si existe. Finalmente, greeting_user() llama a get_new_username()
si es necesario, que se encarga únicamente de obtener un nuevo nombre de usuario
y almacenarlo. Esta compartimentación del trabajo es una parte esencial de la escritura
de un código claro que será fácil de mantener y ampliar.

Inténtalo tú mismo

10-11. Número favorito: escriba un programa que solicite el número favorito del usuario. Use
json.dump() para almacenar este número en un archivo.
archivo. Escriba un programa separado que lea
este valor e imprima el mensaje, “¡Sé su número favorito! Su _____."

10-12. Número favorito recordado:


combine los dos programas del ejercicio 10-11 en un
solo archivo. Si el número ya está almacenado, informe el número favorito al usuario. De lo
contrario, solicite el número favorito del usuario y guárdelo en un archivo. Ejecute el programa dos
veces para ver si funciona.

10-13. Verificar usuario: la lista final de Remember_me.py asume que el usuario ya ingresó su
nombre de usuario o que el programa se está ejecutando por primera vez. Deberíamos modificarlo
en caso de que el usuario actual no sea la última persona que usó el programa.

Antes de imprimir un mensaje de bienvenida en greeting_user(), pregunte al usuario si este


es el nombre de usuario correcto. Si no es así, llame a get_new_username() para obtener el correcto
nombre de usuario.

Resumen
En este capítulo, aprendió a trabajar con archivos. Aprendió a leer un archivo completo
a la vez ya leer el contenido de un archivo una línea a la vez. Aprendió a escribir en un
archivo y agregar texto al final de un archivo. Lea acerca de las excepciones y cómo
manejar las excepciones que probablemente verá en sus programas. Finalmente,
aprendió cómo almacenar estructuras de datos de Python para que pueda guardar la
información que proporcionan sus usuarios, evitando que tengan que empezar de
nuevo cada vez que ejecutan un programa.
En el Capítulo 11, aprenderá formas eficientes de probar su código. Esto ayudará
confía en que el código que desarrolla es correcto y lo ayudará a identificar los errores
que se introducen a medida que continúa desarrollando los programas que ha escrito.

208 Capítulo 10

MachineTranslatedbyGoogle

11
Probar su código

Cuando escribe una función o una clase, también puede escribir

pruebas para ese código. Las pruebas demuestran que su código

funciona como se supone que debe hacerlo en respuesta a todos los

tipos de entrada para los que está diseñado. Cuando escribe pruebas, puede

estar seguro de que su código funcionará correctamente a medida que más personas

comiencen a usar sus programas. También podrá probar código nuevo a medida que
lo agrega para asegurarse de que sus cambios no rompan el comportamiento existente
de su programa. Todos los programadores cometen errores, por lo que todos los
programadores deben probar su código con frecuencia, detectando problemas antes
de que los usuarios los encuentren.

En este capítulo, aprenderá a probar su código usando herramientas en el


módulo unittest de Python. Aprenderá a crear un caso de prueba y comprobará
que un conjunto de entradas da como resultado la salida que desea. Verá cómo se
ve una prueba que pasa y cómo se ve una prueba que falla, y aprenderá cómo una
prueba que falla puede ayudarlo a mejorar su código. Aprenderá a probar funciones
y clases, y comenzará a comprender cuántas pruebas escribir para un proyecto.

MachineTranslatedbyGoogle

Probar una función


Para aprender acerca de las pruebas, necesitamos código para probar. Aquí hay una función
simple que toma un nombre y apellido, y devuelve un nombre completo con un formato limpio:

nombre
_function.py def get_formatted_name(nombre,
"""Generar apellido):
un nombre completo bien formateado."""
formateado."""
nombre_completo = f"{primero} {último}"
devolver nombre_completo.título()

La función get_formatted_name() combina el nombre y apellido con un espacio en el


medio para completar un nombre completo, y luego escribe en mayúsculas y devuelve el
nombre completo. Para verificar que get_formatted_name() funciona, hagamos un programa
que use esta función. El programa names.py permite a los usuarios ingresar un nombre y
apellido, y ver un nombre completo con un formato limpio:

nombres.py from name_function import get_formatted_name

print("Ingrese 'q' en cualquier momento para salir.")


mientras que es cierto:

primero = entrada("\nPor favor, dame un nombre: ")


si primero == 'q':
romper
apellido = entrada ("Por favor, dame un apellido:")
si ultimo == 'q':
romper

formatted_name = get_formatted_name (primero, último)


print(f"\tNombre bien formateado: {formatted_name}.")

Este programa importa get_formatted_name() desde name_function.py. Él


el usuario puede ingresar una serie de nombres y apellidos, y ver los nombres completos con
formato que se generan:

Introduzca 'q' en cualquier momento para salir.

Por favor, dame un nombre: janis


Por favor dame un apellido: joplin
Nombre cuidadosamente formateado: Janis Joplin.
Por favor, dame un nombre: bob
Por favor dame un apellido: dylan
Nombre cuidadosamente formateado: Bob Dylan.

Por favor dame un nombre: q

Podemos ver que los nombres generados aquí son correctos. Pero digamos que queremos
modificar get_formatted_name() para que también pueda manejar segundos nombres.
Mientras lo hacemos, queremos asegurarnos de no romper la forma en que la función maneja
los nombres que solo tienen un nombre y un apellido. Podríamos probar nuestro código
ejecutando names.py e ingresando un nombre como Janis Joplin cada vez que modificamos
get_formatted_name(), pero eso sería tedioso. Afortunadamente,

210 Capítulo 11

MachineTranslatedbyGoogle

Python proporciona una forma eficiente de automatizar la prueba de la salida de una función.
Si automatizamos la prueba de get_formatted_name(), siempre podemos estar seguros de que la
función funcionará cuando se le den los tipos de nombres para los que hemos escrito pruebas.

Pruebas unitarias y casos de prueba

El módulo unittest de la biblioteca estándar de Python proporciona herramientas para probar su


código. Una prueba unitaria verifica que un aspecto específico del comportamiento de una función
es correcto. Un caso de prueba es una colección de pruebas unitarias que juntas prueban que una
función se comporta como se supone que debe hacerlo, dentro de la gama completa de situaciones
que espera que maneje. Un buen caso de prueba considera todos los posibles tipos de entrada
que una función podría recibir e incluye pruebas para representar cada una de estas situaciones.
Un caso de prueba con cobertura completa incluye una gama completa de pruebas unitarias que
cubren todas las formas posibles en que puede usar una función. Lograr una cobertura completa
en un proyecto grande puede ser desalentador. A menudo es lo suficientemente bueno escribir
pruebas para los comportamientos críticos de su código y luego apuntar a una cobertura completa
solo si el proyecto comienza a tener un uso generalizado.

Una prueba de aprobación

La sintaxis para configurar un caso de prueba requiere algo de tiempo para acostumbrarse,
pero una vez que haya configurado el caso de prueba, es sencillo agregar más pruebas unitarias
para sus funciones. Para escribir un caso de prueba para una función, importe el módulo unittest y
la función que desea probar. Luego crea una clase que herede de unittest.TestCase y escribe una
serie de métodos para probar diferentes aspectos del comportamiento de tu función.

Aquí hay un caso de prueba con un método que verifica que la función

get_formatted_name() funciona correctamente cuando se le da un nombre y apellido:

prueba unitaria de importación

nombre_prueba_función.py
from name_function import get_formatted_na
get_formatted_name
me

en la clase NamesTestCase (unittest.TestCas


(unittest.TestCase):
e):
"""Pruebas para 'name_functio
'name_function.py'."""
n.py'."""

def test_first_last_name(self):
test_first_last_name(self):
"""¿Funcionan nombres como 'Janis Joplin'?"""
nombre_formateado
nombre_formateado = obtener_nombre_fo
obtener_nombre_formateado('janis
rmateado('janis',', 'joplin')
volvo self.assertEqual(formatted_nam
self.assertEqual(formatted_name,
e, 'Janis Joplin')

ÿ si __nombre__ == '__principal__':
unittest.principal()

Primero, importamos unittest y la función que queremos probar, get_formatted


_nombre(). En u creamos una clase llamada NaNamesTestCa
mesTestCase,
se, que contendrá una serie de prueba
pruebas
s
unitarias para get_formatted_name(). Puede nombrar la clase como desee, pero es mejor llamarla
de alguna manera relacionada con la función que está a punto de probar y usar la palabra Prueba
en el nombre de la clase. Esta clase debe heredar de la clase unittest.TestCase para que Python

sepa cómo ejecutar las pruebas que escribe.

Probando su código 211

MachineTranslatedbyGoogle

NamesTestCase contiene un solo método que prueba un aspecto de


get_formatted_name(). Llamamos a este método test_first_last_name() porque estamos
verificando que los nombres con solo un nombre y apellido tengan el formato correcto.
Cualquier método que comience con test_ se ejecutará automáticamente cuando ejecutemos
test_name_function.py. Dentro de este método de prueba, llamamos a la función que queremos
probar. En este ejemplo llamamos a get_formatted_name()
get_formatted_name() con los argumentos 'janis' y 'joplin', y
asignamos el resultado a formatted_name v.
En w usamos una de las características más útiles de unittest : un método de afirmación .
Los métodos de afirmación verifican que un resultado que recibió coincida con el resultado
que esperaba recibir. En este caso, debido a que sabemos que se supone que
get_formatted_name() devuelve un nombre completo en mayúsculas y correctamente espaciado,
esperamos
esperamos que el valor de formatted_name sea Janis Joplin. Para verificar si esto es cierto,
usamos el método assertEqual() de unittest y le pasamos formatted_name
formatted_name y 'Janis Joplin'. La línea

self.assertEqual(formatted_name,
self.assertEqual(formatted_name, 'Janis Joplin')

dice: “Compare el valor en formatted_name con la cadena 'Janis Joplin'. Si son iguales a lo

esperado, bien. Pero si no coinciden, ¡avísame!”.


Vamos a ejecutar este archivo directamente, pero es importante tener en cuenta que
muchos marcos de prueba importan sus archivos de prueba antes de ejecutarlos. Cuando
se importa un archivo, el intérprete ejecuta el archivo a medida que se importa. el si
El bloque en ÿ busca una variable especial, __nombre__, que se establece cuando se
ejecuta el programa. Si este archivo se ejecuta como el programa principal, el valor de
__name__
__name__ se establec
establece
e en '__main_
'__main__'.
_'. En este caso
caso,, llamamos a un
unittest.main(),
ittest.main(), que e
ejecuta
jecuta
el caso de prueba. Cuando un marco de prueba importa este archivo, el valor de __name__ no
será '__main__' y este bloque no se ejecutará.
Cuando ejecutamos test_name_function.py, obtenemos el siguiente resultado:

.
-------------------------------------------------- --------------------

Ejecutó 1 prueba en 0.000s

DE ACUERDO

El punto en la primera línea de salida nos dice que pasó una sola prueba.
La siguiente línea nos dice que Python ejecutó una prueba y tardó menos de 0,001
segundos
segundo s en ejecutarse. El OK final nos dice que todas las pruebas unitarias en el caso
de prueba pasaron.
Esta salida indica que la función get_formatted_name() siempre funcionará para nombres
que tengan nombre y apellido a menos que modifiquemos la función. Cuando modificamos
get_formatted_name(), podemos ejecutar esta prueba nuevamente. Si pasa el caso de prueba,
sabemos que la función seguirá funcionando para nombres como Janis Joplin.

Una prueba fallida

¿Cómo se ve una prueba fallida? Modifiquemos get_formatted_name() para que pueda manejar
segundos nombres, pero lo haremos de una manera que rompa la función para nombres con
solo un nombre y apellido, como Janis Joplin.

212 Capítulo 11

MachineTranslatedbyGoogle

Aquí hay una nueva versión de get_formatted_name() que requiere un argumento de segundo
nombre:

nombre def get_formatted_name(primero, medio, último):


_function.py """Generar un nombre completo bien formateado."""

nombre_completo = f"{primero} {medio} {último}"


devolver nombre_com
nombre_completo.título()
pleto.título()

Esta versión debería funcionar para personas con segundo nombre, pero cuando probamos
lo, vemos que hemos roto la función para las personas con sólo un nombre y apellido. Esta vez,
ejecutar el archivo test_name_function.py da este resultado:

en mi
================================================== ====================

v ERROR: test_first_last_name (__main__.NamesTestCase)


-------------------------------------------------- --------------------

w Rastreo (última llamada más reciente): Archivo


"test_name_function.py",
"test_name_function.py", línea 8, en test_first_last_name
nombre_formateado
nombre_formateado = obtener_nombre_formateado('janis',
obtener_nombre_formateado('janis', 'joplin')
TypeError: get_formatted_name() falta 1 argumento posicional requerido: 'último'

-------------------------------------------------- --------------------

x Realizó 1 prueba en 0.000s

y FALLIDO (errores=1)

Hay mucha información aquí porque es posible que necesite saber mucho cuando falla una
prueba. El primer elemento de la salida es un solo E u, que nos dice que una prueba unitaria en
el caso de prueba resultó en un error. A continuación,
continuación, vemos que test_first_last_name() en
NamesTestCase causó un error v. Saber qué prueba falló es fundamental cuando su caso de
prueba contiene muchas pruebas unitarias.
En w vemos un rastreo estándar, que informa que la llamada de función
get_formatted_name('janis
get_formatted_name('janis',', 'joplin') ya no funciona porque falta un argumento posicional requerido.

También vemos que se ejecutó una prueba unitaria x. Finalmente, vemos un mensaje
adicional que indica que el caso de prueba general falló y que ocurrió un error al ejecutar el caso
de prueba y. Esta información aparece al final de la salida para que la vea de inmediato; no
necesita desplazarse
desplazarse hacia arriba a través de una larga lista de resultados para averiguar cuántas
pruebas fallaron.
Responder a una prueba fallida

¿Qué haces cuando falla una prueba? Suponiendo que está comprobando las condiciones
correctas, una prueba satisfactoria significa que la función se está comportando correctamen
correctamente
te y
una prueba fallida significa que hay un error en el nuevo código que escribió. Entonces, cuando
una prueba falla, no cambie la prueba. En su lugar, corrija el código que provocó que la prueba fallara.
Examine los cambios que acaba de realizar en la función y descubra cómo esos cambios
rompieron el comportamiento deseado.
En este caso, get_formatted_name() solía requerir solo dos parámetros: un nombre y un
apellido. Ahora requiere un primer nombre, segundo nombre y

Probar su código 213

MachineTranslatedbyGoogle

apellido. La adición de ese parámetro de segundo nombre obligatorio rompió el comportamiento


deseado de get_formatted_name(). La mejor opción aquí es hacer que el segundo nombre
sea opcional. Una vez que lo hagamos, nuestra prueba para nombres como Janis Joplin
debería pasar nuevamente, y también deberíamos poder aceptar segundos nombres.
Modifiquemos get_formatted_name() para que los segundos nombres sean opcionales y luego
ejecutemos el caso de prueba nuevamente. Si pasa, nos aseguraremos de que la función
maneje los segundos nombres correctamente.
Para que los segundos nombres sean opcionales, movemos el parámetro medio al
final de la lista de parámetros en la definición de la función y asígnele un valor
predeterminado vacío. También agregamos una prueba if que genera el nombre completo
correctamente, dependiendo de si se proporciona o no un segundo nombre:

nombre def get_formatted_name(n


get_formatted_name(nombre,
ombre, apellido, medio=''):
_function.py
_function.py """Generar un nombre completo bien formateado."""
si medio:
nombre_completo
nombre_completo = f"{primero} {medio} {último}"
demás:

nombre_completo
nombre_completo = f"{primero} {último}"

devolver nombre_comp
nombre_completo.título()
leto.título()

En esta nueva versión de get_formatted_name(), el segundo nombre es opcional.


Si se pasa un segundo nombre a la
l a función, el nombre completo contendrá un nombre, un
segundo nombre y un apellido. De lo contrario, el nombre completo constará solo de un
nombre y apellido. Ahora la función debería funcionar para ambos tipos de nombres.
Para averiguar si la función
f unción aún funciona para nombres como Janis Joplin, ejecutemos
test_name_function.py nuevamente :

.
-------------------------------------------------- --------------------

Ejecutó 1 prueba en 0.000s

DE ACUERDO

El caso de prueba pasa ahora. Esto es ideal; significa que la función vuelve a funcionar
para nombres como Janis Joplin sin que tengamos que probar la función manualmente.
Arreglar nuestra función fue fácil porque la prueba fallida nos ayudó a identificar el nuevo
código que rompía el comportamiento existente.
Adición de nuevas pruebas

Ahora que sabemos que get_formatted_name() funciona nuevamente para nombres simples,
escribamos una segunda prueba para las personas que incluyen un segundo nombre.
Hacemos esto agregando otro método a la clase
cl ase NamesTestCase:

--recorte--
nombre_prueba_función.py
clase NombresTe
NombresTestCase
stCase (unittest.Test
(unittest.TestCase):
Case):
"""Pruebas para 'name_functio
'name_function.py'."""
n.py'."""

def test_first_last
test_first_last_name(self):
_name(self):
--recorte--

214 Capítulo 11

MachineTranslatedbyGoogle

def test_first_last_middle_name(self):
"""¿Funcionan nombres como 'Wolfgang Amadeus Mozart'?"""
en formatted_name = get_formatted_name(
'wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')

si __nombre__ == '__principal__':
unittest.principal()

Llamamos a este nuevo método test_first_last_middle_name().


test_first_last_middle_name(). El nombre del método debe
comenzar con test_ para que el método se ejecute automáticamente cuando ejecutamos
test_name_function.py. Nombramos el método para dejar claro qué comportamiento de
get_formatted_name()
get_formatted_name() estamos probando. Como resultado, si la prueba falla, sabemos de inmediato qué
tipo de nombres se ven afectados. Está bien tener nombres de métodos largos en sus clases de
TestCase . Deben ser descriptivos para que pueda entender el resultado cuando fallan las pruebas y,
dado que Python los llama automáticamente, nunca tendrá que escribir código que llame a estos métodos.

Para probar la función, llamamos a get_formatted_name() con un nombre, segundo y segundo


nombre u, y luego usamos assertEqual() para verificar que el nombre completo devuelto coincida con
el nombre completo (primero, segundo y último) que esperamos .
Cuando ejecutamos test_name_function.py nuevamente, ambas pruebas pasan:

..
-------------------------------------------------- --------------------

Realizó 2 pruebas en 0.000s

DE ACUERDO

¡Estupendo! Ahora sabemos que la función aún funciona para nombres como Janis

Joplin, y podemos estar seguros de que también funcionará para nombres como Wolfgang
Amadeus Mozart .

Inténtalo tú mismo

11-1. Ciudad, País: Escriba una función que acepte dos parámetros: un nombre de
ciudad y un nombre de país. La función debe devolver una única cadena con el formato
Ciudad, País, como Santiago, Chile. Almacene la función en un módulo llamado
city_functions.py.
Cree un archivo llamado test_cities.py que pruebe la función que acaba de
escribir (recuerde que necesita importar unittest y la función que desea probar).
Escriba un método llamado test_city_country() para verificar que llamar a su función con
valores como 'santiago' y 'chile' da como resultado la cadena correcta. Ejecute
test_cities.py y asegúrese de que test_city_country() pase.
(continuado)

Probar su código 215

MachineTranslatedbyGoogle

11-2. Población: modifique su función para que requiera un tercer parámetro, la población. Ahora

debería devolver una sola cadena de la forma Ciudad, País – población xxx, como Santiago, Chile – población

5000000. Ejecutar prueba

_cities.py de nuevo.
nuevo. Asegúrate de que test_ci
test_city_country()
ty_country() falle esta vez.
Modifique la función para que el parámetro de población sea opcional. Ejecutar prueba

_cities.py nuevamente,
nuevamente, y asegúrese de que tes
test_city_country()
t_city_country() vuelva a pasar.
pasar.

Escriba una segunda prueba llamada test_city_country_population() que verifique que puede llamar

a su función con los valores 'santiago', 'chile' y 'population=5000000'.


'population=5000000'. Vuelva a ejecutar test_cities.py y

asegúrese de que pase esta nueva prueba.

Probar una clase


En la primera parte de este capítulo, escribió pruebas para una sola función. Ahora
escribirá pruebas para una clase. Utilizará clases en muchos de sus propios programas, por
lo que es útil poder probar que sus clases funcionan correctamente. Si tiene exámenes
aprobados para una clase en la que está trabajando, puede estar seguro de que las mejoras
que realice en la clase no romperán accidentalmente su comportamiento actual.

Una variedad de métodos de afirmación

Python proporciona una serie de métodos de afirmación en la clase unittest.TestCase .


Como se mencionó anteriormente, los métodos de afirmación prueban si una condición que
cree que es verdadera en un punto específico de su código es realmente verdadera. Si la
condición es verdadera como se esperaba, se confirma su suposición sobre cómo se
comporta esa parte de su programa; puede estar seguro de que no existen errores. Si la

condición que supone que es verdadera en realidad no lo es, Python genera una excepción.
La tabla 11-1 describe seis métodos de afirmación comúnmente utilizados. Con
estos métodos, puede verificar que los valores devueltos sean iguales o no iguales a los
valores esperados, que los valores sean verdaderos o falsos, y que los valores estén o no
en una lista determinada. Puede usar estos métodos solo en una clase que hereda de unittest
.TestCase, así que veamos cómo podemos usar uno de estos métodos en el contexto de
probar una clase real.
Tabla 11-1: Métodos de afirmación disponibles desde el módulo unittest

Método Usar

afirmarIgual(a, b) Verifique que a == b

afirmarNoEqual(a, b) Verifica que a != b


afirmarVerdadero(x) Verifique que x sea Verdadero

afirmarFalso(x) Verifica que x es Falso

afirmarEn(elemento, lista) Verifique que el artículo esté en la lista

afirmarNoEn(elemento, lista) Verifique que el artículo no esté en la lista

216 Capítulo 11

MachineTranslatedbyGoogle

Una clase para probar

Probar una clase es similar a probar una función: gran parte de su trabajo consiste en
probar el comportamiento de los métodos de la clase. Pero hay algunas diferencias,
así que escribamos una clase para probar. Considere una clase que ayude a administrar

encuestas anónimas:
encuesta.py clase Encuesta anónima:
"""Recopilar respuestas anónimas a una pregunta de encuesta."""

u def __init__(uno mismo, pregunta):


"""Guarde una pregunta y prepárese para almacenar respuestas."""
self.pregunta = pregunta
auto.respuestas = []

v def mostrar_pregunta(auto):
"""Mostrar la pregunta de la encuesta."""
imprimir(auto.pregunta)

w def store_response(self, new_response):


"""Almacenar una única respuesta a la encuesta."""
self.responses.append(nueva_respuesta)

x def mostrar_resultados(uno mismo):


"""Mostrar todas las respuestas que se han dado."""
imprimir("Resultados
imprimir("Resultados de la encuesta:")
para respuesta en self.responses:
imprimir(f"- {respuest
{respuesta}")
a}")

Esta clase comienza con una pregunta de encuesta que usted proporciona e incluye una lista vacía para
almacenar las respuestas. La clase tiene métodos para imprimir la pregunta de la encuesta v, agregar una
nueva respuesta a la lista de respuestas w e imprimir todas las respuestas almacenadas en la lista x. Para crear
una instancia de esta clase, todo lo que tiene que proporcionar es una pregunta. Una vez que tenga una
instancia que represente una encuesta en particular, muestre la pregunta de la encuesta con show_question(),
almacene una respuesta usando store_response() y muestre los resultados con show_results().

Para mostrar que la clase EncuestaAnónima funciona, escribamos un programa


que use la clase:

idioma desde la importación de encuestas AnonymousSurvey


_encuesta.py
_encuesta.py
# Definir una pregunta y hacer una encuesta.
pregunta = "¿Qué idioma aprendiste a hablar primero?"
my_survey = AnonymousSurvey(pregunta)

# Muestra la pregunta y almacena las respuestas a la pregunta.


mi_encuesta.mostrar_pregunta()
print("Ingrese 'q' en cualquier momento para salir.\n")
mientras que es cierto:

respuesta = entrada ("Idioma:")


si respuesta == 'q':
romper
my_survey.store_response(respuesta)

Probar su código 217

MachineTranslatedbyGoogle

# Mostrar los resultados de la encuesta.


print("\n¡Gracias a todos los que participaron en la encuesta!")
mi_encuesta.mostrar_resultados()

Este programa define una pregunta ("¿Qué idioma aprendiste a hablar primero?")
prim ero?") y
crea un objeto AnonymousSurvey con esa pregunta. El programa llama a show_question()
para mostrar la pregunta y luego solicita respuestas.
r espuestas. Cada respuesta se almacena a medida que
se recibe. Cuando se han ingresado todas las respuestas (el usuario ingresa q para salir),
show_results() imprime los resultados de la encuesta:

¿Qué idioma aprendiste a hablar primero?


Introduzca 'q' en cualquier momento para salir.

Idioma: Inglés
Idioma: Español
Idioma: Inglés

Idioma: mandarín
Idioma: q

¡Gracias a todos los que participaron en la encuesta!


Resultados de la
encuesta: - Inglés -
Español - Inglés

- mandarín

Esta clase funciona para una simple encuesta anónima. Pero digamos que queremos
mejorar AnonymousSurvey y el módulo en el que se encuentra, encuesta. Podríamos permitir que
cada usuario ingrese más de una respuesta. Podríamos escribir un método para enumerar solo
respuestas únicas y para informar cuántas veces se dio cada respuesta.
Podríamos escribir otra clase para gestionar encuestas no anónimas.
Implementar tales cambios correría el riesgo de afectar el comportamiento actual.
de la clase EncuestaAnónima. Por ejemplo, es posible que al intentar
i ntentar permitir que cada
usuario ingrese varias respuestas, accidentalmente podamos cambiar la forma en que se
manejan las respuestas individuales. Para asegurarnos de no interrumpir el comportamiento
existente a medida que desarrollamos este módulo, podemos escribir pruebas para la clase.
Prueba de la clase AnonymousSurvey
Escribamos una prueba que verifique un aspecto del comportamiento de AnonymousSurvey .
Escribiremos una prueba para verificar que una sola respuesta
r espuesta a la pregunta de la encuesta
se almacene correctamente. Usaremos el método assertIn() para verificar que la respuesta esté
en la lista de respuestas después de que se haya almacenado:

prueba
prueba unitaria de importación

_encuesta.py
_encuesta.py desde la importación de encuestas AnonymousSurvey

u class TestAnonymousSurvey(unittest.TestCase):
"""Pruebas para la clase AnonymousSurvey"""

218 Capítulo 11

MachineTranslatedbyGoogle

v def test_store_single_response(auto):
"""Prueba que una sola respuesta se almacena correctamente."""
pregunta = "¿Qué idioma aprendiste a hablar primero?"
en my_survey = AnonymousSurvey(pregunta)
my_survey.store_response('Inglés')
X self.assertIn('Inglés', mi_encuesta.respuestas)

si __nombre__ == '__principal__':
unittest.principal()

Comenzamos importando el módulo unittest y la clase que queremos probar,


AnonymousSurvey. Llamamos a nuestro caso de prueba TestAnonymousSurvey, que
nuevamente hereda de unittest.TestCase u. El primer método de prueba verificará que
cuando almacenamos una respuesta a la pregunta de la encuesta, la respuesta termina
en la lista de respuestas de la encuesta. Un buen nombre descriptivo para este método es
test_store_single_response() v. Si esta prueba falla, sabremos por el nombre del método
que se muestra en el resultado de la prueba fallida que hubo un problema al almacenar
una sola respuesta a la encuesta.

Para probar el comportamiento de una clase, necesitamos crear una instancia de


la clase. En w creamos una instancia llamada my_survey con la pregunta "¿Qué idioma
aprendiste a hablar por primera vez?" Almacenamos una sola respuesta, en inglés,
usando el método store_response() . Luego verificamos que la respuesta se almacenó
correctamente afirmando que el inglés está en la lista my_survey.responses x.
Cuando ejecutamos test_survey.py, la prueba pasa:

.
-------------------------------------------------- --------------------

Ejecutó 1 prueba en 0.001 s

DE ACUERDO

Esto es bueno, pero una encuesta es útil solo si genera más de una respuesta.
Verifiquemos que tres respuestas se pueden almacenar correctamente. Para hacer esto,
agregamos otro método a TestAnonymousSurvey:

prueba unitaria de importación

desde la importación de encuestas AnonymousSurvey

clase TestAnonymousSurvey(unittest.TestCase):
"""Pruebas para la clase AnonymousSurvey"""

def test_store_single_response(auto):
--recorte--

def test_store_tres_respuestas(uno mismo):


"""Pruebe que tres respuestas individuales se almacenan correctamente."""
pregunta = "¿Qué idioma aprendiste a hablar primero?"
my_survey = AnonymousSurvey(pregunta)
en respuestas = ['Inglés', 'Español', 'Mandarín']
para respuesta en respuestas:
my_survey.store_response(respuesta)

en para respuesta en respuestas:


Probar su código 219

MachineTranslatedbyGoogle

self.assertIn(respuesta,
self.assertIn(respuesta, mi_encuesta.res
mi_encuesta.respuestas)
puestas)

si __nombre__ == '__principal__':
unittest.principal()

Llamamos al nuevo método test_store_three_responses(). Creamos un objeto de encuesta


tal como lo hicimos en test_store_single_response(). Definimos una lista que contiene tres
respuestas diferentes u, y luego llamamos a store_response()
para cada una de estas respuestas. Una vez que se han almacenado las respuestas, escribimos otro
ciclo y afirmamos que cada respuesta ahora está en my_survey.responses v.
Cuando volvemos a ejecutar test_survey.py , ambas pruebas (para una sola respuesta y
para tres respuestas) pasar:

..
-------------------------------------------------- --------------------

Realizó 2 pruebas en 0.000s

DE ACUERDO

Esto funciona perfectamente. Sin embargo, estas pruebas son un poco repetitivas, por lo que
use otra característica de unittest para hacerlos más eficientes.

El método de configuración ()

En test_survey.py creamos una nueva instancia de AnonymousSurvey en cada método de prueba


y creamos nuevas respuestas en cada método. El unittest.TestCase
class tiene un método setUp() que le permite crear estos objetos una vez y luego usarlos
u sarlos en cada
uno de sus métodos de prueba. Cuando incluyes un setUp()
en una clase TestCase , Python ejecuta el método setUp() antes de ejecutar cada método que
comienza con test_. Todos los objetos creados en el método setUp() estarán disponibles en cada
método de prueba que escriba.
Usemos setUp() para crear una instancia de encuesta y un conjunto de respuestas que se
pueden usar en test_store_single_response() y test_store_tres_responses():

prueba unitaria de importación

desde la importación de encuestas AnonymousSurvey

clase TestAnonymous
TestAnonymousSurvey(unittest.
Survey(unittest.TestCase):
TestCase):
"""Pruebas para la clase EncuestaAnónima."""
def configurar(auto):
"""

Cree una encuesta y un conjunto de respuestas para usar en todos los métodos de prueba.
"""

pregunta = "¿Qué idioma aprendiste a hablar primero?"


self.my_survey
self.my_survey = AnonymousSurvey
AnonymousSurvey(pregunta)
(pregunta)
ultravioleta
self.responses = ['Inglés', 'Español', 'Mandarín']

def test_store_si
test_store_single_response(auto):
ngle_response(auto):
"""Prueba que una sola respuesta se almacena correctamente.
correctamente."""
"""
self.my_survey.store_response(s
self.my_survey.store_response(self.responses[0
elf.responses[0])
])
self.assertIn(self.responses[0]
self.assertIn(self.responses[0],, self.my_surv
self.my_survey.responses)
ey.responses)

220 Capítulo 11

MachineTranslatedbyGoogle

def test_store_tres_respuestas(uno mismo):


"""Pruebe que tres respuestas individuales se almacenan correctamente."""
para respuesta en self.responses:
self.my_survey.store_response(respuesta)
para respuesta en self.responses:
self.assertIn(respuesta, self.my_survey.responses)

si __nombre__ == '__principal__':
unittest.principal()

El método setUp() hace dos cosas: crea una instancia de encuesta u y crea una lista de
respuestas v. Cada una de estas tiene el prefijo self, por lo que pueden usarse en cualquier parte de
la clase. Esto simplifica los dos métodos de prueba, porque ninguno tiene que hacer una instancia de
encuesta o una respuesta.
El método test_store_single_response() verifica que la primera respuesta en self.responses—
self.responses—
self.responses[0]—se
self.responses[0]—se puede almacenar correctamente y test_store
_tres_respuestas() verifica que las tres respuestas
respuestas en self.responses se puedan almacenar
correctamente.

Cuando ejecutamos test_survey.py nuevamente, ambas pruebas aún pasan. Estas pruebas serían
particularmente útiles cuando se intente expandir AnonymousSurvey para manejar múltiples respuestas
para cada persona. Después de modificar el código para aceptar varias respuestas, puede ejecutar estas
pruebas y asegurarse de que no haya afectado la capacidad de almacenar una sola respuesta o una serie
de respuestas individuales.
Cuando estás probando tus propias clases, el método setUp() puede hacer que tus métodos
de prueba sean más fáciles de escribir. Crea un conjunto de instancias y atributos en setUp() y luego
usa estas instancias en todos sus métodos de prueba. Esto es mucho más fácil que crear un nuevo
conjunto de instancias y atributos en cada método de prueba.

N ota Cuando se ejecuta un caso de prueba, Python imprime un carácter para cada prueba unitaria tal como está.
terminado. Una prueba que pasa imprime un punto, una prueba que da como resultado un error imprime
una E y una prueba que da como resultado una aserción fallida imprime una F. Es por eso que verá una
cantidad diferente de puntos y caracteres en la primera línea de salida cuando ejecuta sus casos de prueba.
Si un caso de prueba tarda mucho en ejecutarse porque contiene muchas pruebas unitarias, puede
ver estos resultados para tener una idea de cuántas pruebas están pasando.
Inténtalo tú mismo

11-3. Empleado: Escribe una clase llamada Empleado. El método __init__() debe tomar
un nombre, un apellido y un salario anual, y almacenar cada uno de estos como atributos.
Escriba un método llamado give_raise() que agregue $5,000 al salario anual de manera

predeterminada, pero que también acepte una cantidad de aumento diferente.


Escriba un caso de prueba para Empleado. Escriba dos métodos de prueba, test_give_default
_raise() y test_give_custom_raise(). Utilice el método setUp() para no tener que crear una nueva
instancia de empleado en cada método de prueba. Ejecute su caso de prueba y asegúrese de que
ambas pruebas pasen.

Probando su código 221

MachineTranslatedbyGoogle

Resumen
En este capítulo aprendió a escribir pruebas para funciones y clases usando
herramientas en el módulo unittest . Aprendió a escribir una clase que hereda de
unittest.TestCase, y aprendió a escribir métodos de prueba que verifican comportamientos

específicos que deben exhibir sus funciones y clases. Aprendió a usar el método setUp()
para crear de manera eficiente instancias y atributos de sus clases que se pueden usar en
todos los métodos de prueba para una clase.
Las pruebas son un tema importante que muchos principiantes no aprenden. No
tienes que escribir pruebas para todos los proyectos simples que intentas como principiante.
Pero tan pronto como comience a trabajar en proyectos que impliquen un esfuerzo de
desarrollo significativo, debe probar los comportamientos críticos de sus funciones y clases.
Estará más seguro de que el nuevo trabajo en su proyecto no romperá las partes que
funcionan, y esto le dará la libertad de realizar mejoras en su código. Si accidentalmente
interrumpe la funcionalidad existente, lo sabrá de inmediato, por lo que aún puede
solucionar el problema fácilmente. Responder a una prueba fallida que ejecutó es mucho
más fácil que responder a un informe de error de un usuario descontento.

Otros programadores respetan más tus proyectos si incluyes algunas pruebas iniciales.
Se sentirán más cómodos experimentando con su código y estarán más dispuestos a
trabajar con usted en proyectos. Si desea contribuir a un proyecto en el que están trabajando
otros programadores, se espera que demuestre que su código pasa las pruebas existentes
y, por lo general, se espera que escriba pruebas para el nuevo comportamiento que
introduzca en el proyecto.
Experimente con las pruebas para familiarizarse con el proceso de probar su
código. Escriba pruebas para los comportamientos más críticos de sus funciones y clases,
pero no apunte a una cobertura completa en los primeros proyectos a menos que tenga
una razón específica para hacerlo.

También podría gustarte