Python Curso Crash
Python Curso Crash
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
“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
“¡Aprender Python con Python Crash Course fue una experiencia extremadamente
positiva! Una gran elección si eres nuevo en Python.”
—Mikke empieza a programar
"Contiene literalmente todo lo que necesita saber sobre Python y aún más".
—FireBearStudio.com
Machine Translated by Google
Machine Translated by Google
pitón
Curso intensivo
2da edición
Una práctica , Proyecto basado
Introducción a la Programación
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. 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.
Contenidos breves
Agradecimientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii
Parte I: Fundamentos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Capítulo 5: Sentencias if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Capítulo 6: Diccionarios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Epílogo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
índice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
x Contenido breve
Machine Translated by Google
Contenidos en detalle
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
2
Variables y tipos de datos simples 15
.. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. ..
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
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
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. . . . . . . . . . . . . . .. .. .. .. .. . .. .. ..
7
Entrada de usuario y bucles while 113
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
. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Valores predeterminados . . .. . 134
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
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 función con un bucle while. . 141. . . . . . . . . . . . . . . . . . . . . . . . .. ..
Ejercicio 8-6: Nombres de ciudades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 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
9
Clases 157
10
Archivos y excepciones 183
11
Probando tu código 209
12
Un barco que dispara balas 227
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
Disparando a los extraterrestres. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. . .. .. . . 268
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 de la velocidad. . . . . . . . . . . . . .. .. .. .. . .. .. .. .. .. .. . .. .. . . 287
xx Contenido en detalle
Machine Translated by Google
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 .. .. .. .. .. . .. .. .. .. .. .. . .. ..
Definición de colores personalizados. . . . .. 314
. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
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
Tirar dados con Plotly. .. . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 323
Instalación de Plotly. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 324
Creación de la clase de troquel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . 324
Tirar el dado. . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 325
dieciséis
17
Trabajar con API 359
18
Primeros pasos con Django 379
.. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. ..
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
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
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Implementación del registro de aprendizaje. .
Epílogo 465
UN
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
Geany. . . . . . . . . . . . . . . . . . . . . . . . . . .. .. . .. .. .. .. .. .. . .. .. . . 476
Emacs y Vim. . . .. .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
átomo . . . . . . . . . . . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
Código de estudio visual. . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
PyCharm. . . . . . . . . . . .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 476
Cuadernos Jupyter. . .. .. .. .. . .. .. .. .. .. . .. .. .. .. .. .. . .. .. . . 477
C
Obteniendo ayuda 479
D
Uso de Git para el control de versiones 485
Índice 495
Prefacio
la segunda edición
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:
•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.
• 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.
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.
Introducción
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á 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 los errores comunes. Despué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 aprendiendo 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 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.
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áticamente.
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/ pythoncrashcourse2e/ o http:// ehmatthes.github.io/ pcc_2e/. Estos recursos incluyen:
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
La gente usa Python para muchos propósitos: crear juegos, crear aplicaciones web,
resolver problemas comerciales y desarrollar herramientas internas en todo tipo de
empresas 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 porque la programación no
es una actividad solitaria. La mayoría de nosotros, incluso los programadores más
experimentados, necesitamos pedir consejo a otros que ya hayan resuelto problemas
similares. Tener una comunidad bien conectada y de apoyo es fundamental 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.
xxxvi Introducción
Machine Translated by Google
Parte I
Lo esencial
2 Parte I
Machine Translated by Google
1
Empezando
Versiones de Python
Algunos proyectos antiguos de Python todavía usan Python 2, pero debe usar
Python 3. Si Python 2 está instalado en su sistema, 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.
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í:
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 presionando 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 codificar el
intérprete en su sistema en un momento.
Sublime Text es un editor de texto simple que se puede instalar en todos los sistemas
operativos modernos. Sublime Text le permite ejecutar casi todos sus programas
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
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
Figura 1-1: asegúrese de seleccionar la casilla de verificación etiquetada Add Python to PATH.
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 similar, consulte las instrucciones de configuración más detalladas.
ciones en el Apéndice A.
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
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.
$ 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)] en darwin
Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.
>>>
Si ve alguna versión anterior a Python 3.6, siga las instrucciones en la siguiente sección
para instalar la última versión.
Puede encontrar un instalador de Python para su sistema en https:// python.org/. Pase el cursor
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.
$ 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.
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:
Para instalar el editor de Sublime Text, debe descargar el instalador en https:// 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 de Aplicaciones .
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
instalada en esta computadora. Cuando haya visto este resultado, presione ctrl-D o ingrese exit()
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 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.
Puede intentar ejecutar fragmentos de código de Python abriendo una terminal e ingresando
python3, como lo hizo al verificar su versión. Haga esto nuevamente, y cuando tenga Python
ejecutándose, ingrese la siguiente línea en la sesión de terminal:
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 su sistema. Entonces
escribirás el Hello World! programe y ejecútelo.
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 Herramientasÿ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.
Debería aparecer una pantalla de terminal en la parte inferior de la ganancia de Sublime Text
dow, mostrando el siguiente resultado:
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:
•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.
•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.
Empezando 11
Machine Translated by Google
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\python_work
ÿ C:\Escritorio\python_work> directorio
hola_mundo.py
ÿ C:\Escritorio\python_work> python hello_world.py
¡Hola mundo Python!
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$ ls
hola_mundo.py
ÿ ~/Desktop/python_work$ python hello_world.py ¡Hola,
mundo de Python!
12 Capítulo 1
Machine Translated by Google
Inténtalo tú mismo
Los ejercicios de este capítulo son de naturaleza exploratoria. A partir del Capítulo 2, los
desafíos que resolverás se basarán en lo que hayas aprendido.
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?
Resumen
En este capítulo, aprendió un poco sobre Python en general e instaló 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 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
Variables
Intentemos usar una variable en hello_world.py. Agregue una nueva línea al principio del
archivo y modifique la segunda línea:
Ejecute este programa para ver qué sucede. Debería ver el mismo resultado que vio
anteriormente:
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:
16 Capítulo 2
Machine Translated by Google
•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.
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.
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
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:
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:
Guarde este archivo como name.py y luego ejecútelo. Debería ver esta salida:
ada lovelace
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:
ADA LOVELACE
ada lovelace
20 Capítulo 2
Machine Translated by Google
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()}!")
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 ÿ.
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:
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 los próximos dos capítulos cuando
comience a producir muchas líneas de salida a partir de unas pocas líneas de código.
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() .
'pitón'
ÿ >>> idioma_favorito
'pitón'
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'
En este ejemplo, comenzamos con un valor que tiene espacios en blanco al principio y
al final ÿ. Luego eliminamos el espacio adicional del lado 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.
Aquí se explica cómo usar comillas simples y dobles correctamente. Guarde este programa
como apostrophe.py y luego ejecútelo:
Sin embargo, si usa comillas simples, Python no puede identificar dónde está la cadena.
debería terminar:
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.
enteros
Puede sumar (+), restar (-), multiplicar (*) y dividir (/) enteros en Python.
>>> 2 + 3
5 >>> 3 - 2
1 >>> 2 3
* 6 >>>
3/2
1.5
>>> 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 los números que desea usar, y lo más probable es que Python haga lo que
espera:
Pero tenga en cuenta que a veces puede obtener un número arbitrario de deci
mal lugares en su respuesta:
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
>>> 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.
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 ese mensaje.
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:
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.
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.
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!"
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.
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.
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.
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.
32 Capítulo 2
Machine Translated by Google
3
Introducción a las listas
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 de la lista están
separados por comas. Aquí hay un ejemplo simple de una lista que contiene algunos tipos de
bicicletas:
Si le pide a Python que imprima una lista, Python devuelve su representación del
lista, incluidos los corchetes:
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.
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() :
Este ejemplo produce el mismo resultado que el ejemplo anterior, excepto que 'Trek'
está en mayúsculas.
34 Capítulo 3
Machine Translated by Google
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.
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:
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.
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.
imprimir (mensaje)
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".
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?
v motos[0] = 'ducati'
imprimir (motos)
['honda','yamaha','suzuki']
['ducati', 'yamaha', 'suzuki']
Puede cambiar el valor de cualquier elemento de una lista, no solo del primero.
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.
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:
u motocicletas.append('ducati')
imprimir (motos)
['honda','yamaha','suzuki']
['honda', 'yamaha', 'suzuki', 'ducati']
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.
u motocicletas.insertar(0, 'ducati')
imprimir (motos)
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.
Si conoce la posición del elemento que desea eliminar de una lista, puede usar la
instrucción del .
u del motos[0]
print(motos)
['honda','yamaha','suzuki']
['yamaha', 'suzuki']
del motos[1]
print(motos)
['honda','yamaha','suzuki']
['honda', 'suzuki']
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.
v motocicleta_reventada = motocicletas.pop() w
print(motocicletas)
x imprimir (motocicleta reventada)
['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:
última_propiedad = motocicletas.pop()
print(f"La última motocicleta que tuve fue una {última_propiedad.título()}").
El resultado es una oración simple sobre la motocicleta más reciente que tuvimos:
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.
u primera_propiedad = motocicletas.pop(0)
v print(f"La primera motocicleta que tuve fue una {primera_propiedad.título()}").
40 Capítulo 3
Machine Translated by Google
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() .
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() .
u motos.remove('ducati')
imprimir (motos)
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:
v demasiado_caro = 'ducati'
w motocicletas.remove(demasiado_caro)
imprimir (motos)
x print(f"\nA {demasiado_caro.title()} es demasiado caro para mí.")
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:
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.
•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 lista, haciéndoles
saber que todavía están invitados.
•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.
['audi','bmw','subaru','toyota']
coches = ['bmw','audi','toyota','subaru']
autos.sort(reverse=True)
imprimir (coches)
['toyota','subaru','bmw','audi']
coches = ['bmw','audi','toyota','subaru']
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.
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','subaru']
imprimir (coches)
coches.reverse()
imprimir (coches)
['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.
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:
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.
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
•Use sorted() para imprimir su lista en orden alfabético inverso sin cambiar el orden de la lista
original.
•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.
46 Capítulo 3
Machine Translated by Google
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:
El índice -1 siempre devuelve el último elemento de una lista, en este caso el valor
'suzuki':
'suzuki'
La única vez que este enfoque 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:
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.
Inténtalo tú mismo
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
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 este capitulo
alicia
david
carolina
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:
imprimir (mago)
50 Capítulo 4
Machine Translated by Google
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:
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 .
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:
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:
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 .
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:
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:
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.
Olvidarse de sangrar
Siempre aplique sangría a la línea después de la instrucción for en un bucle. Si lo olvida,
Python le recordará:
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":
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:
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 .
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:
Debido a que la línea en u está sangrada, se imprime una vez para cada persona en la
lista, como se muestra aquí:
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.
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
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.
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):
1
2
3
4
5
Si desea hacer una lista 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:
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:
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
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.append(valor**2)
imprimir (cuadrados)
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:
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.
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 .
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
El código en u imprime una parte de esta lista, que incluye solo los tres primeros
jugadores. La salida conserva la estructura de la lista e incluye los tres primeros jugadores de
la lista:
Puede generar cualquier 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:
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:
Python devuelve todos los elementos desde el tercer elemento hasta el final de la lista:
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:]:
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.
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.
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:
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:
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:
v my_foods.append('cannoli')
w friend_foods.append('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:
# Esto no funciona:
u friend_foods = mis_alimentos
my_foods.append('cannoli')
friend_foods.append('helado')
El resultado muestra que ambas listas son iguales ahora, que no es lo que queríamos:
64 Capítulo 4
Machine Translated by Google
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 rebanada 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:. Utilice 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:
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.
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:
200
50
Veamos qué sucede si intentamos cambiar uno de los elementos en las dimensiones de la tupla:
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
Puede recorrer todos los valores en una tupla usando un bucle for , tal como lo hizo
con una lista:
Python devuelve todos los elementos de la tupla, tal como lo haría con una lista:
200
50
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:
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.
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.
•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.
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.
Inténtalo tú mismo
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).
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.
70 Capítulo 4
Machine Translated by Google
5
si declaración s
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:
imprimir (coche.título())
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
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:
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.
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:
w >>> coche
'Audi'
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:
u si se solicita_topping != 'anchoas':
print("¡Sujeta las anchoas!")
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!")
>>> edad = 19
>>> edad < 21
Verdadero
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.
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.
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
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 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.
76 Capítulo 5
Machine Translated by Google
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
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
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')
•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 numéricas que involucran igualdad y desigualdad, mayor que y menor que, mayor
que o igual a, y menor que o igual a
si declaraciones
Declaraciones if simples
si prueba_condicional:
hacer algo
78 Capítulo 5
Machine Translated by Google
votando.py edad = 19
u si edad >= 18:
v print("¡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:
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
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!")
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-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
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 entre las edades de 4 y 18 años es de $25.
¿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
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.
edad = 12
si edad < 4:
tu precio = 0
edad < 18:
v precio = 25
demás:
w precio = 40
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
edad = 12
si edad < 4:
precio = 0
edad < 18:
precio = 25
u elif edad < 65:
precio = 40
v más:
precio = 20
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.
edad = 12
si edad < 4:
precio = 0
edad < 18:
precio = 25
edad < 65:
precio = 40
u elif edad >= 65:
precio = 20
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
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:
Adición de champiñones.
Agregar queso extra.
Si declaraciones 83
Machine Translated by Google
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.
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'.
•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 .
•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 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, imprima 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 que verifiquen ciertas frutas en su lista.
fruta está en su lista, el bloque if debe imprimir una declaración, como ¡Realmente le gustan los
plátanos!
si declaraciones 85
Machine Translated by Google
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
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.
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:
Adición de champiñones.
Agregar pimientos verdes.
Agregar queso extra.
86 Capítulo 5
Machine Translated by Google
Adición de champiñones.
Lo sentimos, no tenemos pimientos verdes en este momento.
Agregar queso extra.
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_toppings:
para los ingredientes_solicitados en los ingredientes_solicitados:
print(f"Agregando {requested_topping}.")
print("\nTerminé de hacer tu pizza!")
en otro:
print("¿Estás seguro de que quieres una pizza normal?")
si declaraciones 87
Machine Translated by Google
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 disponibles 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 disponibles antes de agregarlo a la 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 ingredientes solicitados.
Dentro del ciclo, primero verificamos si cada ingrediente solicitado está realmente en la lista de
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.
Adición de champiñones.
Lo siento, no tenemos papas fritas.
Agregar queso extra.
¡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 lista está vacía, imprima el mensaje ¡Necesitamos 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 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.
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.
• 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
si edad < 4:
es mejor que:
si la edad <4:
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.
90 Capítulo 5
Machine Translated by Google
6
Diccionarios
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:
imprimir (alien_0['color'])
imprimir(alien_0['puntos'])
verde
5
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:
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 :
92 Capítulo 6
Machine Translated by Google
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í:
Esto devuelve el valor asociado con la clave 'color' del diccionario alien_0:
verde
u nuevos_puntos = alien_0['puntos']
v print(f"¡Acabas de ganar {nuevos_puntos} puntos!")
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
u alien_0['x_position'] = 0
v alien_0['posición_y'] = 25
imprimir (alien_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.
alien.py extranjero_0 = {}
alien_0['color'] = 'verde'
alien_0['puntos'] = 5
imprimir (alien_0)
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_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.
Diccionarios 95
Machine Translated by Google
Posición x original: 0
Nueva posición x: 2
alien_0['velocidad'] = 'rápido'
Por ejemplo, eliminemos la clave 'puntos' del diccionario alien_0 junto con su valor:
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:
N ota Tenga en cuenta que el par clave-valor eliminado se elimina de forma permanente.
96 Capítulo 6
Machine Translated by Google
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'].title()
print(f"El idioma favorito de Sarah es {idioma}").
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:
Podría usar esta misma sintaxis con cualquier individuo representado en el diccionario.
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:
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:
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.
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
usuario_0 = {
'usuario': 'efermi',
'primero': 'enrico',
'último': 'fermi',
}
usuario.py usuario_0 = {
'usuario': 'efermi',
'primero': 'enrico',
'último': 'fermi',
}
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()
Clave: última
valor: fermi
Clave: primero
Valor: Enrique
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.py 'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}
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.
idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}
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
en vez de . ..
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 = {
--recorte--
}
v si nombre en amigos:
en idioma = idiomas_favoritos[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'
}
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:
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'
}
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 y ordene esa lista antes de recorrerla. El
resultado muestra a todos los que respondieron la encuesta, con los nombres mostrados en
orden:
Diccionarios 103
Machine Translated by Google
idiomas_favoritos = {
'jen': 'pitón',
'sara': 'c',
'eduardo': 'rubí',
'phil': 'pitón'
}
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:
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--
}
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:
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:
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.
•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.
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.
imprimir (extranjero)
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:
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:
...
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. Por ejemplo, para cambiar los tres primeros
extraterrestres a extraterrestres amarillos de velocidad media que valen 10 puntos cada uno,
podríamos hacer esto:
Debido a que queremos modificar los primeros tres alienígenas, recorremos un segmento
que incluye solo los primeros tres alienígenas. Todos los 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
...
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í:
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:
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:")
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 , 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'],
}
Diccionarios 109
Machine Translated by Google
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',
},
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:
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-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 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.
112 Capítulo 6
Machine Translated by Google
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.
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:
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.
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:
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?
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!
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:
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:
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í:
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
si número % 2 == 0:
print(f"\nEl número {número} es par.")
demás:
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.
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".
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.
contando.py número_actual = 1
mientras número_actual <= 5:
imprimir (número_actual)
número_actual += 1
1
2
3
4
5
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.
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 configuramos 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:
Este programa funciona bien, excepto que imprime la palabra 'salir' como si fuera un
mensaje real. Una simple prueba if soluciona esto:
si el mensaje! = 'salir':
imprimir (mensaje)
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:
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
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' :
u mientras es cierto:
ciudad = entrada (mensaje)
if ciudad == 'salir':
romper
demás:
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:
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.
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_actual)
1
3
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
1
1
1
1
--recorte--
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' . 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)
7-6. Tres salidas: Escriba diferentes versiones del Ejercicio 7-4 o del Ejercicio 7-5 que hagan cada
•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).
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()
124 Capítulo 7
Machine Translated by Google
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)
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
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']
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
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?")
126 Capítulo 7
Machine Translated by Google
--- 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 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
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
x saludo_usuario()
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.
¡Hola!
saludar_usuario('jesse')
130 Capítulo 8
Machine Translated by Google
¡Hola, Jesse!
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.
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í:
v describe_mascota('hámster', 'harry')
tengo un hamster
Mi hámster se llama Harry.
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():
describe_mascota('hámster', 'harry')
describe_pet('perro', 'willie')
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.
Puede obtener resultados inesperados si mezcla el orden de los argumentos en una llamada
de función cuando usa argumentos posicionales:
describe_mascota('harry', 'hamster')
yo tengo un harry
Mi Harry se llama Hamster.
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 en la llamada a la funció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():
describe_pet(animal_type='hamster', pet_name='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', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')
N ota Cuando utilice argumentos de palabras clave, asegúrese de utilizar los nombres exactos de los pará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:
describe_pet(pet_name='willie')
134 Capítulo 8
Machine Translated by Google
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, 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.
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')
describe_pet(pet_name='harry', animal_type='hamster')
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.
Debido a que los argumentos posicionales, los argumentos 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 provisto:
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
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 fácil de entender.
describir_mascota()
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
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.
138 Capítulo 8
Machine Translated by Google
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
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 en una cadena vacía y lo movemos al final de la lista de
parámetros:
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 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.
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:
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:
140 Capítulo 8
Machine Translated by Google
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:
Funciones 141
Machine Translated by Google
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:
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
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(), que saluda a cada persona en la lista individualmente:
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!
Funciones 143
Machine Translated by Google
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:
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:
v def mostrar_modelos_completos(modelos_completos):
"""Mostrar todos los modelos que se imprimieron."""
print("\nSe han impreso los siguientes modelos:")
para modelo_completado en modelos_completados:
imprimir (modelo_completado)
144 Capítulo 8
Machine Translated by Google
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:
Configuramos una lista de diseños sin imprimir y una lista vacía que contendrá 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.
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_impresos[:], modelos_completados)
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 correctamente.
8-11. Mensajes archivados: comience con su trabajo del ejercicio 8-10. Llame a la función
send_messages() con una copia de la lista 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
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')
Funciones 147
Machine Translated by Google
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.
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:
N ota A menudo verá el nombre de parámetro genérico *args, que recopila información posicional arbitraria .
argumentos como este.
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
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:
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.
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():
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:
nombre_módulo.nombre_función()
Funciones 151
Machine Translated by Google
También puede importar una función específica de un módulo. Aquí está la sintaxis
general para este enfoque:
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 la función make_pizza() en la
declaración de importación , podemos llamarla por su nombre cuando usamos la 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.
mp (16, 'pepperoni')
mp(12, 'champiñones', 'pimientos verdes', 'queso extra')
152 Capítulo 8
Machine Translated by Google
p.hacer_pizza(16, 'pepperoni')
p.make_pizza(12, 'champiñones', 'pimientos verdes', 'queso extra')
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')
*
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.
Se debe usar la misma convención para los argumentos de palabras clave en las llamadas a
funciones:
nombre_función(valor_0, parámetro_1='valor')
PEP 8 (https:// www.python.org/ dev/ peps/ pep-0008/) recomienda que limite las líneas de
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...
154 Capítulo 8
Machine Translated by Google
Inténtalo tú mismo
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.
156 Capítulo 8
Machine Translated by Google
9
Clases
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.
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
conjunto de instrucciones que le dice a Python cómo crear instancias individuales que representen perros específicos.
perro de clase:
--recorte--
u mi_perro = Perro('Willie', 6)
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 los 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.
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.
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
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.
Ahora Willie hace lo que le decimos:
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.
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)
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() 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: Comience con su clase del Ejercicio 9-1. Cree tres instancias diferentes de la
clase y llame a 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.
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:
162 Capítulo 9
Machine Translated by Google
self.modelo = modelo
self.año = año
v def 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()
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.
2019 Audi A4
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 un atributo llamado odometer_reading 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 get_descriptive_name(self):
--recorte--
Clases 163
Machine Translated by Google
v def read_odometer(self):
"""Imprima una declaración que muestre el kilometraje del automóvil".""
print(f"Este auto tiene {self.odometer_reading} millas").
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 y establece su valor inicial en 0
u. También tenemos un nuevo método llamado read_odometer() en v que facilita la lectura del
kilometraje de un automóvil.
2019 Audi A4
Este coche tiene 0 millas en él.
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.
Coche de clase:
--recorte--
u 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, encuentre el atributo odometer_reading 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
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--
v my_new_car.update_odometer(23)
mi_auto_nuevo.leer_odómetro()
2019 Audi A4
Este coche tiene 23 millas en él.
Coche de clase:
--recorte--
Ahora 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.
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--
w my_used_car.update_odometer(23_500)
mi_coche_usado.leer_odómetro()
x my_used_car.increment_odometer(100)
mi_coche_usado.leer_odómetro()
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
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 reset_login_attempts() que restablece el valor de login_attempts
a 0.
Herencia
No siempre tienes que empezar desde 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 y métodos de la primera clase. La 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.
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.
Clases 167
Machine Translated by Google
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} millas").
v clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""
168 Capítulo 9
Machine Translated by Google
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.
Coche de clase:
--recorte--
clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""
Clases 169
Machine Translated by Google
clase ElectricCar(Coche):
--recorte--
def llenar_tanque_de_gas(auto):
"""Los autos eléctricos no tienen tanques de gasolina".""
print("¡Este auto no necesita tanque de gasolina!")
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.
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."""
clase ElectricCar(Coche):
"""Representan aspectos de un coche, específicos de los vehículos eléctricos."""
imprimir (my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
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:
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--
172 Capítulo 9
Machine Translated by Google
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 y llame 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 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. 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
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.
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:
Coche de clase:
def 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()
def read_odometer(self):
"""Imprima una declaración que muestre el kilometraje del automóvil".""
print(f"Este auto tiene {self.odometer_reading} millas").
174 Capítulo 9
Machine Translated by Google
my_new_car.odometer_reading = 23
mi_auto_nuevo.leer_odómetro()
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.
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 get_range(self):
"""Imprime una declaración sobre el alcance que proporciona esta batería.""" if
self.battery_size == 75: range = 260 elif self.battery_size == 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."""
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_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:
176 Capítulo 9
Machine Translated by Google
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 importar ambas clases, Car y ElectricCar:
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:
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:
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.
*
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.
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.
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--
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:
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.
Ahora puedes usar este alias cuando quieras hacer un auto eléctrico:
Clases 179
Machine Translated by Google
Inténtalo tú mismo
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.
Otra función útil es choice(). Esta función toma una lista o tupla y devuelve un
elemento elegido al azar:
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.
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
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.
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
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.
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 pi_digits.txt, o puede descargar el archivo de los
recursos del libro a través de https:// nostarch.com/ 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:
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
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
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:
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.
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'
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
Puede usar un bucle for en el objeto de archivo para examinar cada línea de un archivo
de una en una:
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, 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:
Ahora la salida coincide con el contenido del archivo una vez más:
3.1415926535
8979323846
2643383279
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 :
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.
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:
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:
--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() .
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 =
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.14159265358979323846264338327950288419716939937510...
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/.
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()
¡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:
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.
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.
Este archivo se comporta como cualquier otro archivo en su computadora. Puede abrirlo,
escribir texto nuevo en él, copiarlo, 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() .
Incluir líneas nuevas en tus llamadas a write() hace que cada cadena aparezca en su propia
línea:
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:
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:
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
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.
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 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.
tratar:
imprimir (5/0)
excepto ZeroDivisionError:
print("¡No puedes dividir por cero!")
194 Capítulo 10
Machine Translated by Google
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.
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:
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)
ZeroDivisionError: división por cero
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 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)
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
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:
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():
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").
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":
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:
tratar:
198 Capítulo 10
Machine Translated by Google
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:
palabras = contenido.split()
num_palabras = len(palabras)
print(f"El archivo {filename} tiene aproximadamente {num_words} palabras").
contar_palabras(nombre de archivo)
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:
contar_palabras(nombre de archivo)
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.txt , el usuario vería un rastreo completo y el programa dejaría de ejecutarse después
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 silenciosamente 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:
--recorte--
contar_palabras(nombre de archivo)
200 Capítulo 10
Machine Translated by Google
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.
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)
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.
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.inferior().cuenta('fila')
3
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 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 preferencias en un juego o proporcionen datos
para una visualización. Cualquiera que sea el enfoque de su programa, almacenará 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.
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:
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:
Ahora escribiremos un programa que use json.load() para volver a leer la lista en la memoria:
imprimir (números)
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:
Ahora escribamos un nuevo programa que salude a un usuario cuyo nombre ya ha sido
almacenado:
204 Capítulo 10
Machine Translated by Google
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:
De lo contrario:
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():
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() 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_username():
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 FileNotFoundError:
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:
saludar_usuario()
importar json
def get_stored_username():
"""Obtener nombre de usuario almacenado si está disponible."""
--recorte--
def obtener_nuevo_nombre_de_usuario():
def saludo_usuario():
"""Saluda al usuario por su nombre."""
nombre de usuario = get_stored_username()
si nombre de usuario:
saludar_usuario()
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. 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.
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
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
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.
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:
def test_first_last_name(self):
"""¿Funcionan nombres como 'Janis Joplin'?"""
nombre_formateado = obtener_nombre_formateado('janis', 'joplin')
volvo self.assertEqual(formatted_name, 'Janis Joplin')
ÿ si __nombre__ == '__principal__':
unittest.principal()
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__ se establece en '__main__'. En este caso, llamamos a unittest.main(), que ejecuta
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:
.
-------------------------------------------------- --------------------
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 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.
¿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:
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
================================================== ====================
-------------------------------------------------- --------------------
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, 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', '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 hacia arriba a través de una larga lista de resultados para averiguar cuántas
pruebas fallaron.
.
-------------------------------------------------- --------------------
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.
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 NamesTestCase:
--recorte--
nombre_prueba_función.py
clase NombresTestCase (unittest.TestCase):
"""Pruebas para 'name_function.py'."""
def test_first_last_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()
..
-------------------------------------------------- --------------------
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)
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
Modifique la función para que el parámetro de población sea opcional. Ejecutar prueba
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'. Vuelva a ejecutar test_cities.py y
Método Usar
216 Capítulo 11
Machine Translated by Google
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:
v def mostrar_pregunta(auto):
"""Mostrar la pregunta de la encuesta."""
imprimir(auto.pregunta)
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().
Este programa define una pregunta ("¿Qué idioma aprendiste a hablar primero?") y
crea un objeto AnonymousSurvey con esa pregunta. El programa llama a show_question()
para mostrar la pregunta y luego solicita respuestas. 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:
Idioma: Inglés
Idioma: Español
Idioma: Inglés
Idioma: mandarín
Idioma: q
- 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 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
prueba unitaria de importación
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()
.
-------------------------------------------------- --------------------
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:
clase TestAnonymousSurvey(unittest.TestCase):
"""Pruebas para la clase AnonymousSurvey"""
def test_store_single_response(auto):
--recorte--
self.assertIn(respuesta, mi_encuesta.respuestas)
si __nombre__ == '__principal__':
unittest.principal()
..
-------------------------------------------------- --------------------
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 ()
clase TestAnonymousSurvey(unittest.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.
"""
def test_store_single_response(auto):
"""Prueba que una sola respuesta se almacena correctamente."""
self.my_survey.store_response(self.responses[0])
self.assertIn(self.responses[0], self.my_survey.responses)
220 Capítulo 11
Machine Translated by Google
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[0]—se puede almacenar correctamente y test_store
_tres_respuestas() verifica que las tres 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.
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.
222 Capítulo 11
Machine Translated by Google
Parte II
Proyectos
Visualización de datos
Aplicaciones
web En el proyecto Aplicaciones web (capítulos 18, 19 y 20), utilizará el paquete Django
para crear una aplicación web sencilla que permita a los usuarios llevar un diario sobre
cualquier número de temas sobre los que hayan estado aprendiendo. Los usuarios crearán
una cuenta con un nombre de usuario y una contraseña, ingresarán un tema y luego harán
entradas sobre lo que están aprendiendo. También aprenderá cómo implementar su
aplicación para que cualquier persona en el mundo pueda acceder a ella.
Después de completar este proyecto, podrá comenzar a crear sus propias aplicaciones
web simples y estará listo para profundizar en recursos más completos sobre la creación
de aplicaciones con Django.
224 Parte II
Machine Translated by Google
Proyecto 1
Invasión alienígena
Machine Translated by Google
Machine Translated by Google
12
Un barco que dispara balas
Mientras crea este juego, también aprenderá a administrar proyectos grandes que
abarcan varios archivos. Refactorizaremos una gran cantidad de código y administraremos el
contenido de los archivos para organizar el proyecto y hacer que el código sea eficiente.
Machine Translated by Google
Tenga en cuenta que Alien Invasion abarca varios archivos diferentes, así que cree un nuevo alien_invasion
carpeta en su sistema. Asegúrese de guardar todos los archivos del proyecto en esta carpeta para que sus
declaraciones de importación funcionen correctamente.
Además, si se siente cómodo usando el control de versiones, es posible que desee usarlo para esto.
proyecto. Si no ha utilizado el control de versiones antes, consulte el Apéndice D para obtener una descripción general.
Planificación de su proyecto
Cuando está construyendo un proyecto grande, es importante preparar un plan antes de
comenzar a escribir código. Su plan lo mantendrá enfocado y hará que sea más probable que complete
el proyecto.
Escribamos una descripción del juego general. Aunque el seguimiento
Aunque esta descripción no cubre todos los detalles de Alien Invasion, proporciona una idea
clara de cómo empezar a construir el juego:
Para la primera fase de desarrollo, crearemos una nave que pueda moverse hacia la derecha y
hacia la izquierda y que dispare balas cuando el jugador presione la barra espaciadora. Después de
configurar este comportamiento, podemos crear los alienígenas y refinar el juego.
Instalando Pygame
Antes de comenzar a programar, instale Pygame. El módulo pip lo ayuda a descargar e instalar
paquetes de Python. Para instalar Pygame, ingrese el siguiente comando en un indicador de terminal:
Este comando le dice a Python que ejecute el módulo pip e instale el pygame
paquete a la instalación de Python del usuario actual. Si utiliza un comando
228 Capítulo 12
Machine Translated by Google
que no sea python para ejecutar programas o iniciar una sesión de terminal, como
python3, su comando se verá así:
Nota Si este comando no funciona en macOS, intente ejecutar el comando nuevamente sin el indicador
--user .
Crearemos una ventana de Pygame vacía creando una clase para representar el juego. En
su editor de texto, cree un nuevo archivo y guárdelo como alien_invasion.py; luego ingresa
lo siguiente:
importar pygame
def run_game(self):
"""Iniciar el bucle principal del juego."""
en mientras que es cierto:
si __nombre__ == '__principal__':
# Cree una instancia de juego y ejecute el juego.
ai = invasión alienígena ()
ai.run_game()
230 Capítulo 12
Machine Translated by Google
def run_game(self):
--recorte--
para evento en pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
Los colores en Pygame se especifican como colores RGB: una mezcla de rojo,
verde y azul. Cada valor de color puede variar de 0 a 255. El valor de color (255, 0, 0) es
rojo, (0, 255, 0) es verde y (0, 0, 255) es azul. Puede mezclar diferentes valores RGB para
crear hasta 16 millones de colores. El valor de color (230, 230, 230) mezcla cantidades iguales
de rojo, azul y verde, lo que produce un color de fondo gris claro. Asignamos este color a
self.bg_color u.
En v, llenamos la pantalla con el color de fondo usando el método fill()
método, que actúa sobre una superficie y toma sólo un argumento: un color.
Cada vez que introducimos una nueva funcionalidad en el juego, normalmente también
creamos algunas configuraciones nuevas. En lugar de agregar configuraciones a lo largo
del código, escribamos un módulo llamado configuración que contenga una clase llamada
Configuración para almacenar todos estos valores en un solo lugar. Este enfoque nos
permite trabajar con un solo objeto de configuración cada vez que necesitamos acceder a una
configuración individual. Esto también facilita la modificación de la apariencia y el
comportamiento del juego a medida que crece nuestro proyecto: para modificar el juego,
simplemente cambiaremos algunos valores en settings.py, que crearemos a continuación, en
lugar de buscar diferentes configuraciones a lo largo del proyecto. .
Cree un nuevo archivo llamado settings.py dentro de su carpeta alien_invasion y agregue
esta clase de configuración inicial :
Para crear una instancia de Configuración en el proyecto y usarla para acceder a nuestro
configuración, necesitamos modificar alien_invasion.py de la siguiente manera:
alien_invasion.py --recorte--
importar pygame
en self.pantalla = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Invasión alienígena")
def run_game(self):
--recorte--
# Vuelva a dibujar la pantalla durante cada pasada por el bucle.
en self.screen.fill(self.settings.bg_color)
Importamos la configuración al archivo principal del programa. Luego creamos una instancia de
Settings y la asignamos a self.settings u, luego de hacer la llamada a pygame.init(). Cuando creamos
una pantalla v, usamos los atributos screen_width y screen_height de self.settings, y luego usamos
self.settings para acceder al color de fondo cuando llenamos la pantalla en w también.
Cuando ejecutes alien_invasion.py ahora, aún no verás ningún cambio, porque todo lo que hemos
hecho es mover la configuración que ya estábamos usando en otro lugar. Ahora estamos listos para
comenzar a agregar nuevos elementos a la pantalla.
232 Capítulo 12
Machine Translated by Google
Para Alien Invasion, puede usar el archivo ship.bmp (Figura 12-1), que está disponible en los
recursos del libro en https:// nostarch.com/ pythoncrashcourse2e/.
El color de fondo del archivo coincide con la configuración que estamos usando en este proyecto.
Cree una carpeta llamada imágenes dentro de su carpeta principal del proyecto alien_invasion .
Guarde el archivo ship.bmp en la carpeta de imágenes .
nave de clase:
"""Una clase para manejar la nave."""
y def blitme(self):
"""Dibuja el barco en su ubicación actual."""
self.screen.blit(self.image, self.rect)
Pygame es eficiente porque te permite tratar todos los elementos del juego como rect
ángulos (rectángulos), incluso si no tienen exactamente la forma de rectángulos. Tratar un elemento
como un rectángulo es eficiente porque los rectángulos son formas geométricas simples. Cuando
Pygame necesita averiguar si dos elementos del juego han chocado, por ejemplo, puede hacerlo
más rápidamente si trata cada objeto como un rectángulo. Este enfoque generalmente funciona lo
suficientemente bien como para que nadie que juegue se dé cuenta de que no estamos trabajando
con la forma exacta de cada elemento del juego. Trataremos el barco y la pantalla como ángulos
rectos en esta clase.
Cuando trabaja con un objeto rect , puede usar las coordenadas x e y de los
bordes superior, inferior, izquierdo y derecho del rectángulo, así como el centro, para
colocar el objeto. Puede establecer cualquiera de estos valores para establecer la
posición actual del rect. Cuando esté centrando un elemento del juego, trabaje con
los atributos center, centerx o centery de un rect. Cuando esté trabajando en un borde
de la pantalla, trabaje con los atributos superior, inferior, izquierdo o derecho .
También hay atributos que combinan estas propiedades, como midbottom, midtop,
midleft y midright. Cuando esté ajustando la ubicación horizontal o vertical del rect,
puede usar los atributos x e y , que son las coordenadas x e y de su esquina
superior izquierda. Estos atributos le evitan tener que hacer cálculos que antes los
desarrolladores de juegos tenían que hacer manualmente, y los usará con frecuencia.
Nota En Pygame, el origen (0, 0) está en la esquina superior izquierda de la pantalla y las coordenadas aumentan
a medida que avanza hacia abajo y hacia la derecha. En una pantalla de 1200 por 800, el origen
está en la esquina superior izquierda y la esquina inferior derecha tiene las coordenadas (1200, 800).
Estas coordenadas se refieren a la ventana del juego, no a la pantalla física.
234 Capítulo 12
Machine Translated by Google
En y, definimos el método blitme() , que dibuja la imagen en la pantalla en la posición especificada por
self.rect.
alien_invasion.py --recorte--
desde ajustes importar Ajustes
desde barco importación Barco
def run_game(self):
--recorte--
# Vuelva a dibujar la pantalla durante cada pasada por el bucle.
self.screen.fill(self.settings.bg_color)
en self.ship.blitme()
Figura 12-2: Invasión alienígena con la nave en la parte inferior central de la pantalla
El método _check_events()
Moveremos el código que administra los eventos a un método separado
llamado _check_events(). Esto simplificará run_game() y aislará el bucle de
gestión de eventos. Aislar el bucle de eventos te permite administrar los eventos
por separado de otros aspectos del juego, como actualizar la pantalla.
Aquí está la clase AlienInvasion con el nuevo método _check_events() , que solo afecta
el código en run_game():
en self._check_events()
236 Capítulo 12
Machine Translated by Google
v def _check_events(auto):
"""Responder a las pulsaciones de teclas y eventos del ratón."""
para evento en pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
El método _update_screen()
Para simplificar aún más run_game(), moveremos el código para actualizar la pantalla a un método
separado llamado _update_screen():
self._check_events()
self._update_screen()
def _check_events(auto):
--recorte--
def _update_screen(auto):
"""Actualice las imágenes en la pantalla y pase a la nueva pantalla."""
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
pygame.display.flip()
Ahora que hemos reestructurado el código para que sea más fácil agregarlo, ¡podemos
trabajar en los aspectos dinámicos del juego!
Inténtalo tú mismo
12-1. Cielo azul: haga una ventana de Pygame con un fondo azul.
12-2. Personaje del juego: encuentre una imagen de mapa de bits de un personaje del juego
que le guste o convierta una imagen en un mapa de bits. Cree una clase que dibuje al personaje
en el centro de la pantalla y haga coincidir el color de fondo de la imagen con el color de fondo
de la pantalla, o viceversa.
pilotando el barco
A continuación, le daremos al jugador la capacidad de mover la nave hacia la derecha y hacia la
izquierda. Escribiremos un código que responda cuando el jugador presione la tecla de flecha derecha o izquierda.
Primero nos concentraremos en el movimiento hacia la derecha y luego aplicaremos los mismos principios
para controlar el movimiento hacia la izquierda. A medida que agreguemos este código, aprenderá cómo
controlar el movimiento de las imágenes en la pantalla y cómo responder a las entradas del usuario.
Cada vez que el jugador presiona una tecla, esa pulsación de tecla se registra en Pygame como un evento.
Cada evento es recogido por el método pygame.event.get() . Necesitamos especificar en nuestro método
_check_events() qué tipo de eventos queremos que el juego verifique. Cada pulsación de tecla se registra como
un evento KEYDOWN .
Cuando Pygame detecta un evento KEYDOWN , debemos verificar si la tecla que se presionó es
una que desencadena una determinada acción. Por ejemplo, si el jugador presiona la tecla de flecha derecha,
queremos aumentar el valor rect.x del barco para mover el barco a la derecha:
Dentro de _check_events() agregamos un bloque elif al bucle de eventos para responder cuando Pygame
detecta un evento KEYDOWN u. Verificamos si la tecla presionada, event.key, es la tecla de flecha derecha v.
La tecla de flecha derecha está representada por pygame.K_RIGHT. Si se presionó la tecla de flecha derecha,
movemos el barco hacia la derecha aumentando el valor de self.ship.rect.x en 1 w.
Cuando ejecute alien_invasion.py ahora, la nave debería moverse un píxel a la derecha cada vez que
presione la tecla de flecha derecha. Eso es un comienzo, pero no es una forma eficiente de controlar la nave.
Mejoremos este control permitiendo el movimiento continuo.
238 Capítulo 12
Machine Translated by Google
# Bandera de movimiento
en self.moving_right = Falso
def blitme(yo):
--recorte--
si evento.key == pygame.K_RIGHT:
self.ship.moving_right = Falso
En u, modificamos cómo responde el juego cuando el jugador presiona la tecla de flecha hacia la
derecha: en lugar de cambiar la posición de la nave directamente, simplemente establecemos moving_right
en True. En v, agregamos un nuevo bloque elif , que responde a eventos KEYUP . Cuando el jugador
suelta la tecla de flecha hacia la derecha (K_RIGHT), establecemos moving_right en False.
A continuación, modificamos el ciclo while en run_game() para que llame a la actualización del barco ()
método en cada paso a través del bucle:
self._check_events()
self.ship.update()
self._update_screen()
La posición del barco se actualizará después de que hayamos verificado los eventos del teclado y
antes de que actualicemos la pantalla. Esto permite que la posición del barco se actualice en respuesta a la
entrada del jugador y garantiza que la posición actualizada se utilizará al dibujar el barco en la pantalla.
Ahora que el barco puede moverse continuamente hacia la derecha, agregar movimiento hacia la izquierda
es sencillo. Nuevamente, modificaremos la clase Ship y el _check
método _eventos() . Aquí están los cambios relevantes a __init__() y update()
en barco:
240 Capítulo 12
Machine Translated by Google
la tecla de flecha derecha siempre tendría prioridad. Hacerlo de esta manera hace que los
movimientos sean más precisos al cambiar de derecha a izquierda cuando el jugador puede
mantener presionadas ambas teclas momentáneamente.
Tenemos que hacer dos ajustes a _check_events():
Actualmente, la nave se mueve un píxel por ciclo a través del bucle while , pero podemos tener
un control más preciso de la velocidad de la nave agregando un atributo ship_speed a la clase
Configuración . Usaremos este atributo para determinar qué tan lejos mover el barco en cada
pasada por el bucle. Aquí está el nuevo atributo en settings.py:
# Configuración de envío
self.ship_speed = 1.5
Usamos valores decimales para la configuración de velocidad para tener un control más
preciso de la velocidad del barco cuando aumentamos el ritmo del juego más adelante.
Sin embargo, los atributos rect como x almacenan solo valores enteros, por lo que debemos realizar
algunas modificaciones en Ship:
# Banderas de movimiento
self.moving_right = Falso
self.moving_left = Falso
def blitme(yo):
--recorte--
Creamos un atributo de configuración para Ship, para que podamos usarlo en update() u.
Debido a que estamos ajustando la posición del barco en fracciones de un píxel, debemos
asignar la posición a una variable que pueda almacenar un valor decimal. Puede usar un valor
decimal para establecer un atributo de rect, pero rect solo conservará la parte entera de ese valor.
Para realizar un seguimiento preciso de la posición del barco, definimos un nuevo atributo self.x
que puede contener valores decimales v.
Usamos la función float() para convertir el valor de self.rect.x a un decimal y asignamos este valor a
self.x.
Ahora, cuando cambiamos la posición del barco en update(), el valor de self.x
se ajusta por la cantidad almacenada en settings.ship_speed w. Después de actualizar self.x ,
usamos el nuevo valor para actualizar self.rect.x, que controla
242 Capítulo 12
Machine Translated by Google
la posición del barco x. Solo la parte entera de self.x se almacenará en self.rect.x, pero está bien para
mostrar la nave.
Ahora podemos cambiar el valor de ship_speed, y cualquier valor mayor que uno hará que el
barco se mueva más rápido. Esto ayudará a que la nave responda lo suficientemente rápido como
para derribar a los alienígenas, y nos permitirá cambiar el ritmo del juego a medida que el jugador
avanza en el juego.
Nota Si está utilizando macOS, es posible que observe que el barco se mueve muy lentamente, incluso con una
configuración de alta velocidad. Puedes solucionar este problema ejecutando el juego en modo de
pantalla completa, que implementaremos en breve.
Este código comprueba la posición del barco antes de cambiar el valor de self.x. El código
self.rect.right devuelve la coordenada x del borde derecho del rect del barco. Si este valor es menor
que el valor devuelto por self.screen
_rect.right, la nave no ha llegado al borde derecho de la pantalla u. Lo mismo ocurre con el borde
izquierdo: si el valor del lado izquierdo del rect es mayor que cero, el barco no ha llegado al borde
izquierdo de la pantalla v. Esto asegura que el barco está dentro de estos límites antes de ajustar el
valor de yo.x.
Cuando ejecute alien_invasion.py ahora, la nave debería dejar de moverse en cualquier
borde de la pantalla. Esto está muy bien; todo lo que hemos hecho es agregar una prueba
condicional en una declaración if , ¡pero se siente como si la nave chocara contra una pared o un
campo de fuerza en cualquiera de los bordes de la pantalla!
Refactorización de _check_events()
El método _check_events() aumentará en longitud a medida que continuamos desarrollando el juego,
así que dividamos _check_events() en dos métodos más: uno que maneja eventos KEYDOWN y otro
que maneja eventos KEYUP :
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(evento)
elif event.type == pygame.KEYUP:
self._check_keyup_events(evento)
Ahora que estamos respondiendo a las pulsaciones de teclas de manera eficiente, podemos
agregar otra forma de salir del juego. Se vuelve tedioso hacer clic en la X en la parte superior de
la ventana del juego para finalizar el juego cada vez que prueba una nueva función, por lo que
agregaremos un atajo de teclado para finalizar el juego cuando el jugador presione Q:
Pygame tiene un modo de pantalla completa que te puede gustar más que ejecutar el juego en una
ventana normal. Algunos juegos se ven mejor en el modo de pantalla completa y los usuarios de
macOS pueden ver un mejor rendimiento en el modo de pantalla completa.
244 Capítulo 12
Machine Translated by Google
Para ejecutar el juego en modo de pantalla completa, realice los siguientes cambios
en __init__():
Nota Asegúrate de poder salir presionando Q antes de ejecutar el juego en modo de pantalla completa; Pygame no ofrece
una forma predeterminada de salir de un juego mientras está en modo de pantalla completa.
Un resumen rápido
En la siguiente sección, agregaremos la capacidad de disparar balas, lo que implica agregar
un nuevo archivo llamado bullet.py y hacer algunas modificaciones a algunos de los archivos
que ya estamos usando. En este momento, tenemos tres archivos que contienen varias clases
y métodos. Para tener claro cómo está organizado el proyecto, revisemos cada uno de estos
archivos antes de agregar más funcionalidades.
alien_invasion.py
El archivo principal, alien_invasion.py, contiene la clase AlienInvasion . Esta clase crea una
serie de atributos importantes que se utilizan a lo largo del juego: la configuración se asigna
a la configuración, la superficie de visualización principal se asigna a la pantalla y también
se crea una instancia de barco en este archivo. El ciclo principal del juego, un ciclo while ,
también se almacena en este módulo. El bucle while llama a _check_events(), ship.update()
y _update_screen().
El método _check_events() detecta eventos relevantes, como presionar y soltar
teclas, y procesa cada uno de estos tipos de eventos a través de los métodos
_check_keydown_events() y _check_keyup_events(). Por ahora,
estos métodos gestionan el movimiento del barco. La clase AlienInvasion también contiene
_update_screen(), que vuelve a dibujar la pantalla en cada pasada por el bucle principal.
El archivo alien_invasion.py es el único archivo que necesitas ejecutar cuando quieres jugar
a Alien Invasion. Los otros archivos, settings.py y ship.py , contienen código que se importa a
este archivo.
configuración.py
El archivo settings.py contiene la clase Settings . Esta clase solo tiene un __init__()
método, que inicializa los atributos que controlan la apariencia del juego y la velocidad del
barco.
nave.py
El archivo ship.py contiene la clase Ship . La clase Ship tiene un __init__()
un método update() para gestionar la posición del barco y un método blitme()
método para dibujar el barco en la pantalla. La imagen del barco se almacena en ship.bmp,
que se encuentra en la carpeta de imágenes .
Inténtalo tú mismo
12-4. Cohete: haz un juego que comience con un cohete en el centro de la pantalla. Permita
que el jugador mueva el cohete hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha con
las cuatro teclas de flecha. Asegúrese de que el cohete nunca se mueva más allá de cualquier borde de la
pantalla.
12-5. Teclas: Cree un archivo Pygame que cree una pantalla vacía. En el bucle de eventos,
imprima el atributo event.key siempre que se detecte un evento pygame.KEYDOWN .
Ejecute el programa y presione varias teclas para ver cómo responde Pygame.
disparar balas
Ahora agreguemos la capacidad de disparar balas. Escribiremos un código que dispare una bala,
que está representada por un pequeño rectángulo, cuando el jugador presione la barra
espaciadora. Las balas viajarán directamente hacia arriba en la pantalla hasta que desaparezcan
de la parte superior de la pantalla.
246 Capítulo 12
Machine Translated by Google
Al final del método __init__() , actualizaremos settings.py para incluir los valores que necesitaremos
para una nueva clase Bullet :
Estos ajustes crean viñetas de color gris oscuro con un ancho de 3 píxeles y un
altura de 15 píxeles. Las balas viajarán un poco más lento que el barco.
Ahora cree un archivo bullet.py para almacenar nuestra clase Bullet . Aquí está la primera parte
de bullet.py:
rect, y el ancho y alto del rect. Inicializamos el rect en (0, 0), pero lo moveremos a la ubicación correcta
en la siguiente línea, porque la posición de la bala depende de la posición del barco. Obtenemos el ancho y el
alto de la viñeta de los valores almacenados en self.settings.
Ahora que tenemos una clase Bullet y las configuraciones necesarias definidas, podemos
escribir código para disparar una bala cada vez que el jugador presione la barra espaciadora.
Crearemos un grupo en AlienInvasion para almacenar todas las balas vivas para que
podamos administrar las balas que ya se han disparado. Este grupo será una instancia de la
clase pygame.sprite.Group , que se comporta como una lista con algunas funciones
adicionales que son útiles al crear juegos. Usaremos este grupo para dibujar viñetas en la
pantalla en cada pasada por el bucle principal y para actualizar la posición de cada viñeta.
248 Capítulo 12
Machine Translated by Google
self._check_events()
self.ship.update()
en self.bullets.update()
self._update_screen()
disparando balas
alien_invasion.py --recorte--
desde barco importación Barco
u de viñeta importar viñeta
def _fire_bullet(auto):
"""Cree una nueva viñeta y agréguela al grupo de viñetas."""
new_bullet = Bullet(self)
wx self.viñetas.añadir(nueva_viñeta)
def _update_screen(auto):
"""Actualice las imágenes en la pantalla y pase a la nueva pantalla."""
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
y para viñeta en self.bullets.sprites():
bala.draw_bullet()
pygame.display.flip()
--recorte--
Por el momento, las viñetas desaparecen cuando llegan a la parte superior, pero solo
porque Pygame no puede dibujarlas sobre la parte superior de la pantalla. Las balas en
realidad siguen existiendo; sus valores de coordenadas y se vuelven cada vez más
negativos. Esto es un problema, porque continúan consumiendo memoria y potencia de
procesamiento.
250 Capítulo 12
Machine Translated by Google
self._check_events()
self.ship.update()
self.bullets.update()
self._update_screen()
Cuando usa un bucle for con una lista (o un grupo en Pygame), Python espera que
la lista mantenga la misma longitud mientras el bucle se esté ejecutando. Debido a que
no podemos eliminar elementos de una lista o grupo dentro de un ciclo for , tenemos que
recorrer una copia del grupo. Usamos el método copy() para configurar el bucle for u, que
nos permite modificar viñetas dentro del bucle. Verificamos cada viñeta para ver si ha
desaparecido de la parte superior de la pantalla en v. Si es así, la eliminamos de las viñetas
w. En x, insertamos una llamada print() para mostrar cuántas viñetas existen actualmente en
el juego y verificamos que se eliminen cuando lleguen a la parte superior de la pantalla.
Esto limita al jugador a tres balas a la vez. Usaremos esta configuración en AlienInvasion para
comprobar cuántas viñetas existen antes de crear una nueva viñeta en _fire_bullet():
El código para _update_bullets() se corta y pega desde run_game(); todo lo que hemos hecho
aquí es aclarar los comentarios.
El ciclo while en run_game() parece simple nuevamente:
Ahora nuestro bucle principal contiene solo un código mínimo, por lo que podemos leer rápidamente
los nombres de los métodos y comprender lo que sucede en el juego. El ciclo principal verifica la
entrada del jugador y luego actualiza la posición del barco y las balas que se han disparado. Luego
usamos las posiciones actualizadas para dibujar una nueva pantalla.
Ejecute alien_invasion.py una vez más y asegúrese de que todavía puede disparar balas sin
errores.
252 Capítulo 12
Machine Translated by Google
Inténtalo tú mismo
12-6. Sideways Shooter: escribe un juego que coloque un barco en el lado izquierdo de la
pantalla y permita al jugador mover el barco hacia arriba y hacia abajo. Haz que la nave
dispare una bala que atraviese la pantalla cuando el jugador presione la barra espaciadora.
Asegúrese de que las viñetas se eliminen una vez que desaparezcan de la pantalla.
Resumen
En este capítulo, aprendiste a hacer un plan para un juego y aprendiste la estructura
básica de un juego escrito en Pygame. Aprendió a establecer un color de fondo y
almacenar configuraciones en una clase separada donde puede ajustarlas más fácilmente.
Viste cómo dibujar una imagen en la pantalla y darle al jugador control sobre el
movimiento de los elementos del juego. Ha creado elementos que se mueven solos,
como balas que vuelan por una pantalla, y ha eliminado objetos que ya no son
necesarios. También aprendió a refactorizar el código en un proyecto de manera
regular para facilitar el desarrollo continuo.
En el Capítulo 13, agregaremos extraterrestres a Alien Invasion. Al final
del capítulo, podrás derribar a los alienígenas, ¡con suerte antes de que lleguen a
tu nave!
13
¡Alienígenas!
confinar a un personaje dentro de las paredes de un laberinto o pasar una pelota entre dos
personajes. Continuaremos trabajando a partir de un plan que revisamos ocasionalmente para
mantener el enfoque de nuestras sesiones de escritura de código.
Antes de comenzar a escribir código nuevo para agregar una flota de extraterrestres a la
pantalla, veamos el proyecto y actualicemos nuestro plan.
•Utilice el espacio alrededor del primer extraterrestre y el tamaño total de la pantalla para
determinar cuántos extraterrestres pueden caber en la pantalla. Escribiremos un bucle para
crear extraterrestres para llenar la parte superior de la pantalla.
•Haz que la flota se mueva hacia los lados y hacia abajo hasta que toda la flota sea derribada,
un alienígena golpee la nave o un alienígena llegue al suelo. Si toda la flota es derribada,
crearemos una nueva flota. Si un extraterrestre golpea la nave o el suelo, destruiremos la
nave y crearemos una nueva flota.
•Limita la cantidad de barcos que el jugador puede usar y finaliza el juego cuando el jugador haya
usado la cantidad asignada de barcos.
Refinaremos este plan a medida que implementemos características, pero esto es suficiente
para empezar.
También debe revisar su código existente cuando comience a trabajar en una nueva serie
de funciones en un proyecto. Debido a que cada nueva fase generalmente hace que un proyecto
sea más complejo, es mejor limpiar cualquier código desordenado o ineficiente. Hemos estado
refactorizando sobre la marcha, por lo que no hay ningún código que necesitemos refactorizar en
este punto.
256 Capítulo 13
Machine Translated by Google
La mayor parte de esta clase es como la clase Barco , excepto por la ubicación de los alienígenas.
en la pantalla. Inicialmente colocamos a cada extraterrestre cerca de la esquina superior izquierda
de la pantalla; agregamos un espacio a la izquierda que es igual al ancho del extraterrestre y un
espacio arriba igual a su altura u para que sea fácil de ver. somos principalmente
¡Alienígenas! 257
Machine Translated by Google
preocupado por la velocidad horizontal de los alienígenas, por lo que rastrearemos la posición
horizontal de cada alienígena con precisión v.
Esta clase Alien no necesita un método para dibujarla en la pantalla; en su lugar, usaremos
un método de grupo de Pygame que dibuja automáticamente todos los elementos de un grupo en
la pantalla.
alien_invasion.py --recorte--
de importación de viñetas Viñeta
de importación alienígena Alien
self._create_fleet()
En este método, creamos una instancia de Alien y luego la agregamos al grupo que albergará
la flota. El extraterrestre se colocará en el área superior izquierda predeterminada de la pantalla, lo
cual es perfecto para el primer extraterrestre.
258 Capítulo 13
Machine Translated by Google
Para que aparezca el extraterrestre, necesitamos llamar al método draw() del grupo en
_update_screen():
pygame.display.flip()
Ahora que el primer extraterrestre aparece correctamente, escribiremos el código para dibujar
toda una flota.
Para dibujar una flota, necesitamos averiguar cuántos alienígenas pueden caber en la pantalla y
cuántas filas de alienígenas pueden caber en la pantalla. Primero calcularemos el espacio horizontal
entre los extraterrestres y crearemos una fila; luego determinaremos el espacio vertical y crearemos
una flota completa.
¡Alienígenas! 259
Machine Translated by Google
Para averiguar cuántos extraterrestres caben en una fila, veamos cuánto espacio horizontal tenemos. El
ancho de la pantalla se almacena en settings.screen_width, pero necesitamos un margen vacío a cada
lado de la pantalla. Haremos que este margen sea del ancho de un extraterrestre. Debido a que tenemos
dos márgenes, el espacio disponible para los extraterrestres es el ancho de la pantalla menos dos anchos
extraterrestres:
N ota Un gran aspecto de los cálculos en la programación es que no tienes que estar seguro
tus fórmulas son correctas cuando las escribes por primera vez. Puedes probarlos y ver si funcionan. En
el peor de los casos, tendrás una pantalla abarrotada de extraterrestres o con muy pocos extraterrestres.
Luego puede revisar sus cálculos en función de lo que ve en la pantalla.
Estamos listos para generar una fila completa de alienígenas. Debido a que nuestro código para hacer
un solo extraterrestre funciona, reescribiremos _create_fleet() para hacer una fila completa de
extraterrestres:
260 Capítulo 13
Machine Translated by Google
La primera fila está desplazada hacia la izquierda, lo que en realidad es bueno para el juego.
La razón es que queremos que la flota se mueva hacia la derecha hasta que toque el borde
de la pantalla, luego baje un poco, luego se mueva hacia la izquierda y así sucesivamente. Al igual
que el juego clásico Space Invaders, este movimiento es más interesante que hacer que la flota
caiga hacia abajo. Continuaremos este movimiento hasta que todos los alienígenas sean derribados
o hasta que un alienígena golpee la nave o la parte inferior de la pantalla.
¡Alienígenas! 261
Machine Translated by Google
N ota Según el ancho de pantalla que haya elegido, la alineación de la primera fila de alienígenas
puede verse ligeramente diferente en su sistema.
Refactorización de _create_fleet()
Si el código que hemos escrito hasta ahora fuera todo lo que necesitamos para crear una flota,
probablemente dejaríamos _create_fleet() como está. Pero tenemos más trabajo por hacer, así
que vamos a limpiar un poco el método. Agregaremos un nuevo método auxiliar, _create_alien(),
y lo llamaremos desde _create_fleet():
Adición de filas
Para terminar la flota, determinaremos la cantidad de filas que caben en la pantalla y luego
repetiremos el ciclo para crear los alienígenas en una fila hasta que tengamos la cantidad correcta
de filas. Para determinar el número de filas, encontramos el espacio vertical disponible restando la
altura alienígena desde la parte superior, la altura del barco desde la parte inferior y dos alturas
alienígenas desde la parte inferior de la pantalla:
262 Capítulo 13
Machine Translated by Google
Ahora que sabemos cuántas filas caben en una flota, podemos repetir el código para
crear una fila:
Necesitamos el ancho y el alto de un alien, por lo que en u usamos el atributo size, que
contiene una tupla con el ancho y el alto de un objeto rect . Para calcular el número de filas que
caben en la pantalla, escribimos nuestro disponible
Cálculo de _space_y justo después del cálculo de available_space_x v. El cálculo está entre
paréntesis para que el resultado se pueda dividir en dos líneas, lo que resulta en líneas de 79
caracteres o menos, como se recomienda.
Para crear varias filas, usamos dos bucles anidados: uno exterior y otro interior w. El
bucle interior crea los alienígenas en una fila. El bucle exterior cuenta desde 0 hasta el número
de filas que queremos; Python usa el código para hacer una sola fila y lo repite número_filas
veces.
Para anidar los bucles, escriba el nuevo bucle for y sangre el código que desea repetir. (La
mayoría de los editores de texto facilitan la sangría y la eliminación de la sangría de bloques de
código, pero para obtener ayuda, consulte el Apéndice B). Ahora, cuando llamamos a
_create_alien(), incluimos un argumento para el número de fila para que cada fila se pueda
colocar más abajo en la pantalla.
La definición de _create_alien() necesita un parámetro para contener el número de fila.
Dentro de _create_alien(), cambiamos el valor de la coordenada y de un extraterrestre cuando
no está en la primera fila x comenzando con la altura de un extraterrestre para crear un espacio
vacío en la parte superior de la pantalla. Cada fila comienza dos alturas alienígenas debajo
¡Alienígenas! 263
Machine Translated by Google
la fila anterior, entonces multiplicamos la altura del alienígena por dos y luego por el número de la
fila. El número de la primera fila es 0, por lo que la ubicación vertical de la primera fila no cambia.
Todas las filas subsiguientes se colocan más abajo en la pantalla.
Cuando ejecutes el juego ahora, deberías ver una flota completa de alienígenas, como
se muestra en la Figura 13-4.
Inténtalo tú mismo
13-1. Estrellas: Encuentra una imagen de una estrella. Haz que aparezca una cuadrícula de estrellas en la pantalla.
13-2. Mejores estrellas: puedes hacer un patrón de estrellas más realista introduciendo la aleatoriedad
cuando colocas cada estrella. Recuerda que puedes obtener un número aleatorio como este:
Este código devuelve un número entero aleatorio entre ÿ10 y 10. Usando su código
264 Capítulo 13
Machine Translated by Google
Ahora hagamos que la flota de alienígenas se mueva hacia la derecha a través de la pantalla hasta que
toque el borde, y luego hagamos que suelte una cantidad determinada y se mueva en la otra dirección.
Continuaremos este movimiento hasta que todos los alienígenas hayan sido derribados, uno choque con la nave
o uno llegue al final de la pantalla. Comencemos haciendo que la flota se mueva hacia la derecha.
Para mover a los alienígenas, usaremos un método update() en alien.py, que llamaremos para cada
alienígena en el grupo de alienígenas. Primero, agregue una configuración para controlar la velocidad de cada
alienígena:
Creamos un parámetro de configuración en __init__() para que podamos acceder a la velocidad del
alienígena en update(). Cada vez que actualizamos la posición de un extraterrestre, lo movemos hacia la derecha
en la cantidad almacenada en alien_speed. Hacemos un seguimiento de la posición exacta del extraterrestre con
el atributo self.x , que puede contener valores decimales u. Luego usamos el valor de self.x para actualizar la
¡Alienígenas! 265
Machine Translated by Google
Estamos a punto de escribir código para gestionar el movimiento de la flota, así que
creamos un nuevo método llamado _update_aliens(). Configuramos las posiciones de los
alienígenas para que se actualicen después de que se hayan actualizado las balas, porque
pronto comprobaremos si alguna bala alcanza a algún alienígena.
La ubicación de este método en el módulo no es crítica. Pero para mantener el
código organizado, lo colocaré justo después de _update_bullets() para que coincida con el
orden de las llamadas a métodos en el ciclo while . Aquí está la primera versión de
_update_aliens():
Ahora crearemos la configuración que hará que la flota se mueva hacia abajo en la pantalla y
hacia la izquierda cuando toque el borde derecho de la pantalla. He aquí cómo implementar
este comportamiento:
266 Capítulo 13
Machine Translated by Google
Podemos llamar al nuevo método check_edges() en cualquier alien para ver si está en el
borde izquierdo o derecho. El alien está en el borde derecho si el atributo derecho de su rect
es mayor o igual que el atributo derecho del rect de la pantalla . Está en el borde izquierdo si
su valor izquierdo es menor o igual a 0 u.
Modificamos el método update() para permitir el movimiento hacia la izquierda o
hacia la derecha multiplicando la velocidad del alienígena por el valor de dirección_flota v. Si flota
_direction es 1, el valor de alien_speed se agregará a la posición actual del alienígena,
moviéndolo hacia la derecha; si la dirección_flota es ÿ1, el valor se restará de la posición del
alienígena, moviéndolo hacia la izquierda.
def _change_fleet_direction(self):
"""Deja caer toda la flota y cambia la dirección de la flota".""
para alien en self.aliens.sprites():
en alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1
¡Alienígenas! 267
Machine Translated by Google
self._check_fleet_edges()
self.aliens.update()
Inténtalo tú mismo
13-3. Gotas de lluvia: encuentre una imagen de una gota de lluvia y cree una cuadrícula de gotas de lluvia.
Haz que las gotas de lluvia caigan hacia la parte inferior de la pantalla hasta que desaparezcan.
13-4. Lluvia constante: modifique su código en el ejercicio 13-3 para que cuando una fila de
gotas de lluvia desaparezca de la parte inferior de la pantalla, aparezca una nueva fila en la parte
superior de la pantalla y comience a caer.
Hemos construido nuestra nave y una flota de alienígenas, pero cuando las balas alcanzan a los
alienígenas, simplemente pasan porque no estamos buscando colisiones. En la programación de juegos, las
colisiones ocurren cuando los elementos del juego se superponen. Para hacer que las balas derriben a los
alienígenas, usaremos el método sprite.groupcollide() para buscar colisiones entre miembros de dos grupos.
Queremos saber de inmediato cuándo una bala golpea a un alienígena para que podamos hacer que un
alienígena desaparezca tan pronto como sea alcanzado. Para hacer esto, buscaremos colisiones
inmediatamente después de actualizar la posición de todas las balas.
La función sprite.groupcollide() compara los rectos de cada elemento en un grupo con los rectos de
cada elemento en otro grupo. En este caso, compara el rect de cada bala con el rect de cada alienígena y
devuelve un diccionario que contiene las balas y los alienígenas que han chocado. Cada tecla en el
268 Capítulo 13
Machine Translated by Google
diccionario será una bala, y el valor correspondiente será el alienígena que fue golpeado. (También
usaremos este diccionario cuando implementemos un sistema de puntuación en el Capítulo 14).
El nuevo código que agregamos compara las posiciones de todas las viñetas en self.bullets
y todos los alienígenas en self.aliens, e identifica cualquiera que se superponga.
Cada vez que los rectos de una viñeta y un alienígena se superponen, groupcollide() agrega un par
de valores clave al diccionario que devuelve. Los dos argumentos True le dicen a Pygame que elimine
las balas y los alienígenas que han chocado. (Para hacer una bala de alta potencia que pueda viajar a
la parte superior de la pantalla, destruyendo a todos los extraterrestres en su camino, puede configurar
el primer argumento booleano en Falso y mantener el segundo argumento booleano en Verdadero. El
impacto de los alienígenas desaparecería, pero todas las viñetas permanecerían activas hasta que
desaparecieran de la parte superior de la pantalla).
Cuando ejecutas Alien Invasion ahora, los alienígenas que golpees deberían desaparecer.
La figura 13-5 muestra una flota que ha sido derribada parcialmente.
¡Alienígenas! 269
Machine Translated by Google
Puedes probar muchas características del juego simplemente ejecutándolo. Pero algunas características son
tediosas de probar en la versión normal del juego. Por ejemplo, es mucho trabajo derribar a todos los
extraterrestres en la pantalla varias veces para probar si su código responde correctamente a una flota vacía.
Para probar características particulares, puede cambiar ciertas configuraciones del juego para
enfocarse en un área en particular. Por ejemplo, puede reducir la pantalla para que haya menos alienígenas
para derribar o aumentar la velocidad de la bala y obtener muchas balas a la vez.
Mi cambio favorito para probar Alien Invasion es usar balas realmente anchas que permanecen
activas incluso después de haber golpeado a un alienígena (ver Figura 13-6). ¡ Intenta establecer bullet_width
en 300, o incluso en 3000, para ver qué tan rápido puedes derribar la flota!
Figura 13-6: Las balas extra poderosas hacen que algunos aspectos del juego sean más fáciles de probar.
Cambios como estos te ayudarán a probar el juego de manera más eficiente y posiblemente generen
ideas para otorgar poderes adicionales a los jugadores. Solo recuerde restaurar la configuración a la normalidad
cuando termine de probar una función.
Repoblación de la Flota
Una característica clave de Alien Invasion es que los alienígenas son implacables: cada vez que se destruye la
flota, debería aparecer una nueva flota.
Para hacer que aparezca una nueva flota de alienígenas después de que una flota haya sido destruida,
primero verificamos si el grupo de alienígenas está vacío. Si es así, hacemos una llamada a _create_fleet().
Realizaremos esta verificación al final de _update_bullets(), porque ahí es donde se destruyen los extraterrestres
individuales.
270 Capítulo 13
Machine Translated by Google
En u, verificamos si el grupo de alienígenas está vacío. Un grupo vacío se evalúa como Falso, por
lo que esta es una forma sencilla de verificar si el grupo está vacío.
Si es así, nos deshacemos de las viñetas existentes usando el método empty() , que elimina todos los
sprites restantes de un grupo v. También llamamos a _create
_fleet(), que vuelve a llenar la pantalla con extraterrestres.
Ahora aparece una nueva flota tan pronto como destruyas la flota actual.
El mejor valor para esta configuración depende de la velocidad de su sistema, así que encuentre un
valor que funciona para usted. También puede ajustar otras configuraciones.
Refactorización _update_bullets()
Vamos a refactorizar _update_bullets() para que no haga tantas tareas diferentes.
Moveremos el código para lidiar con colisiones de balas y extraterrestres a un método separado:
self._check_bullet_alien_collisions()
¡Alienígenas! 271
Machine Translated by Google
colisiones = pygame.sprite.groupcollide(
self.bullets, self.aliens, True, True)
si no self.aliens:
# Destruye las balas existentes y crea una nueva flota.
self.bullets.empty()
self._create_fleet()
Inténtalo tú mismo
13-5. Sideways Shooter Parte 2: Hemos recorrido un largo camino desde el ejercicio
12-6, Sideways Shooter. Para este ejercicio, intente desarrollar Sideways Shooter hasta el
mismo punto al que llevamos Alien Invasion. Añade una flota de alienígenas y haz que se
muevan lateralmente hacia la nave. O escriba un código que coloque alienígenas en
posiciones aleatorias a lo largo del lado derecho de la pantalla y luego los envíe hacia la
nave. Además, escriba un código que haga desaparecer a los alienígenas cuando sean golpeados.
Terminar el juego
¿Cuál es la diversión y el desafío en un juego si no puedes perder? Si el jugador no derriba la
flota lo suficientemente rápido, haremos que los alienígenas destruyan la nave cuando hagan
contacto. Al mismo tiempo, limitaremos la cantidad de barcos que un jugador puede usar y
destruiremos el barco cuando un alienígena llegue al final de la pantalla. El juego terminará cuando
el jugador haya usado todas sus naves.
Comenzaremos comprobando las colisiones entre los extraterrestres y la nave para que
podamos responder adecuadamente cuando un extraterrestre la golpee. Comprobaremos si hay
colisiones entre alienígenas y naves inmediatamente después de actualizar la posición de cada
alienígena en AlienInvasion:
272 Capítulo 13
Machine Translated by Google
Ahora tenemos que averiguar qué sucederá exactamente cuando un extraterrestre colisione con la
nave. En lugar de destruir la instancia de la nave y crear una nueva, contaremos cuántas veces la
nave ha sido golpeada mediante el seguimiento de las estadísticas del juego. Las estadísticas de
seguimiento también serán útiles para la puntuación.
Escribamos una nueva clase, GameStats, para realizar un seguimiento de las estadísticas del juego y guardarla
como game_stats.py:
estadísticas_del_juego.py
clase GameStats:
"""Estadísticas de seguimiento de Alien Invasion."""
def reset_stats(auto):
"""Inicializar estadísticas que pueden cambiar durante el juego."""
self.ships_left = self.settings.ship_limit
Crearemos una instancia de GameStats para todo el tiempo que se esté ejecutando Alien
Invasion . Pero necesitaremos restablecer algunas estadísticas cada vez que el jugador comience
un nuevo juego. Para hacer esto, inicializaremos la mayoría de las estadísticas en el reinicio
_stats() en lugar de directamente en __init__(). Llamaremos a este método desde __init__()
para que las estadísticas se establezcan correctamente cuando se crea por primera vez la
instancia de GameStats u. Pero también podremos llamar a reset_stats() cada vez que el
jugador comience un nuevo juego.
¡Alienígenas! 273
Machine Translated by Google
En este momento solo tenemos una estadística, ships_left, cuyo valor será
cambiar a lo largo del juego. El número de barcos con los que comienza el jugador debe
almacenarse en settings.py como ship_limit:
importar pygame
Creamos la instancia después de crear la ventana del juego pero antes de definir otros
elementos del juego, como la nave.
Cuando un extraterrestre golpee la nave, restaremos uno de la cantidad de naves que
quedan, destruiremos todas las balas y alienígenas existentes, crearemos una nueva flota y
reubicaremos la nave en el centro de la pantalla. También pausaremos el juego por un momento
para que el jugador pueda notar la colisión y reagruparse antes de que aparezca una nueva flota.
Pongamos la mayor parte de este código en un nuevo método llamado _ship_hit(). llamaremos
este método de _update_aliens() cuando un extraterrestre golpea la nave:
274 Capítulo 13
Machine Translated by Google
# Decrementar barcos_izquierda.
en self.stats.ships_left -= 1
# Pausa.
X dormir (0.5)
El nuevo método _ship_hit() coordina la respuesta cuando un extraterrestre golpea una nave. Dentro
de _ship_hit(), el número de barcos que quedan se reduce en 1 en u, después de lo cual vaciamos los grupos
alienígenas y balas v.
A continuación, creamos una nueva flota y centramos el barco w. (Agregaremos el método
center_ship() a Enviar en un momento). Luego agregamos una pausa después de que se hayan realizado
las actualizaciones en todos los elementos del juego, pero antes de que se hayan dibujado los cambios en
la pantalla, para que el jugador pueda ver eso. su nave ha sido golpeada x. La llamada sleep() detiene la
ejecución del programa durante medio segundo, el tiempo suficiente para que el jugador vea que el
alienígena ha golpeado la nave. Cuando finaliza la función sleep() , la ejecución del código pasa a
_update_screen()
método, que dibuja la nueva flota en la pantalla.
En _update_aliens(), reemplazamos la llamada print() con una llamada a _ship_hit()
cuando un extraterrestre golpea la nave:
N ota Tenga en cuenta que nunca fabricamos más de un barco; creamos solo una instancia de nave para todo el
juego y la volvemos a actualizar cada vez que la nave ha sido golpeada. La estadística ships_left
nos dirá cuando el jugador se haya quedado sin naves.
Ejecuta el juego, dispara a algunos alienígenas y deja que un alienígena golpee la nave. El juego
debería hacer una pausa y debería aparecer una nueva flota con el barco centrado en la parte inferior de la
pantalla nuevamente.
¡Alienígenas! 275
Machine Translated by Google
¡Juego terminado!
Alien Invasion se siente más completo ahora, pero el juego nunca termina. El valor de ships_left se
vuelve cada vez más negativo. Agreguemos una bandera game_active como un atributo a
GameStats para finalizar el juego cuando el jugador se quede sin barcos.
Estableceremos esta bandera al final del método __init__() en GameStats:
276 Capítulo 13
Machine Translated by Google
self.stats.game_active=Falso
self._check_events()
si self.stats.game_active:
self.ship.update()
self._update_bullets()
self._update_aliens()
self._update_screen()
¡Alienígenas! 277
Machine Translated by Google
Inténtalo tú mismo
Resumen
En este capítulo, aprendiste a agregar una gran cantidad de elementos idénticos a un juego
creando una flota de alienígenas. Usaste bucles anidados para crear una cuadrícula de
elementos e hiciste que un gran conjunto de elementos del juego se movieran llamando al método
update() de cada elemento. Aprendió a controlar la dirección de los objetos en la pantalla ya
responder a situaciones específicas, como cuando la flota llega al borde de la pantalla. Detectaste y
respondiste a las colisiones cuando las balas golpearon a los extraterrestres y los extraterrestres
golpearon la nave. También aprendió cómo realizar un seguimiento de las estadísticas en un juego
y usar una bandera game_active para determinar cuándo termina el juego.
En el siguiente y último capítulo de este proyecto, agregaremos un botón Reproducir para que
el jugador puede elegir cuándo comenzar su primer juego y si jugar de nuevo cuando finaliza el
juego. Aceleraremos el juego cada vez que el jugador derribe a toda la flota y agregaremos un
sistema de puntuación. ¡El resultado final será un juego totalmente jugable!
278 Capítulo 13
Machine Translated by Google
14
Puntuación
Botón de clase:
Primero, importamos el módulo pygame.font , que permite que Pygame represente texto en la
pantalla. El método __init__() toma los parámetros self, el ai_game
280 Capítulo 14
Machine Translated by Google
object y msg, que contiene el texto del botón u. Establecemos las dimensiones del botón en v, y
luego configuramos button_color para colorear el objeto rect del botón de verde brillante y
configuramos text_color para representar el texto en blanco.
En w, preparamos un atributo de fuente para representar texto. El argumento Ninguno le dice
a Pygame que use la fuente predeterminada y 48 especifica el tamaño del texto. Para centrar el
botón en la pantalla, creamos un rect para el botón x y establecemos su atributo central para que
coincida con el de la pantalla.
Pygame trabaja con texto representando la cadena que desea mostrar como
una imagen. En y, llamamos a _prep_msg() para manejar esta representación.
Aquí está el código para _prep_msg():
alien_invasion.py --recorte--
desde game_stats importar GameStats
desde el botón botón de importación
Puntuación 281
Machine Translated by Google
Este código crea una instancia de Button con la etiqueta Reproducir, pero no dibuja el
botón en la pantalla. Llamaremos al método draw_button() del botón en _update_screen ():
pygame.display.flip()
Para que el botón Reproducir sea visible sobre todos los demás elementos de la
pantalla, lo dibujamos después de que se hayan dibujado todos los demás elementos, pero
antes de pasar a una nueva pantalla. Lo incluimos en un bloque if , por lo que el botón solo
aparece cuando el juego está inactivo.
Ahora, cuando ejecute Alien Invasion, debería ver un botón Reproducir en el centro
de la pantalla, como se muestra en la Figura 14-1.
282 Capítulo 14
Machine Translated by Google
Comenzando el juego
Para comenzar un nuevo juego cuando el jugador hace clic en Jugar, agregue el siguiente elif
bloque hasta el final de _check_events() para monitorear los eventos del mouse sobre el botón:
Usamos el método rect collidepoint() para comprobar si el punto del clic del ratón se superpone
a la región definida por el rect u del botón Reproducir. Si es así, establecemos game_active en True,
¡y comienza el juego!
En este punto, deberías poder comenzar y jugar un juego completo. Cuando finaliza el
juego, el valor de game_active debería convertirse en False y el botón Reproducir debería volver
a aparecer.
Restablecer el juego
El código del botón Reproducir que acabamos de escribir funciona la primera vez que el jugador
hace clic en Reproducir. Pero no funciona después de que finaliza el primer juego, porque las
condiciones que causaron el final del juego no se han restablecido.
Para restablecer el juego cada vez que el jugador hace clic en Jugar, debemos restablecer las
estadísticas del juego, eliminar los antiguos alienígenas y las balas, construir una nueva flota y
centrar la nave, como se muestra aquí:
Puntuación 283
Machine Translated by Google
self.bullets.empty()
En u, reiniciamos las estadísticas del juego, lo que le da al jugador tres nuevos barcos.
Luego establecemos game_active en True para que el juego comience tan pronto como el
código de esta función termine de ejecutarse. Vaciamos los alienígenas y las balas .
grupos v, y luego crea una nueva flota y centra el barco w.
Ahora el juego se reiniciará correctamente cada vez que hagas clic en Jugar, permitiéndote
para jugar tantas veces como quieras!
284 Capítulo 14
Machine Translated by Google
self.stats.game_active=Falso
pygame.mouse.set_visible(Verdadero)
Volvemos a hacer visible el cursor tan pronto como el juego se vuelve inactivo, lo que sucede en
_ship_hit(). La atención a detalles como este hace que su juego se vea más profesional y permite que el
jugador se concentre en jugar en lugar de descubrir la interfaz de usuario.
Inténtalo tú mismo
14-1. Presione P para jugar: debido a que Alien Invasion usa la entrada del teclado para
controlar la nave, sería útil comenzar el juego presionando una tecla. Agregue un código que le
permita al jugador presionar P para comenzar. Podría ayudar mover algo de código de _check
_play_button() a un método _start_game() que se puede llamar desde _check_play
_button() y _check_keydown_events().
14-2. Práctica de objetivo: cree un rectángulo en el borde derecho de la pantalla que se
mueva hacia arriba y hacia abajo a un ritmo constante. Luego, haga que aparezca un barco en
el lado izquierdo de la pantalla que el jugador puede mover hacia arriba y hacia abajo mientras
dispara balas al objetivo rectangular en movimiento. Agregue un botón Reproducir que inicie el
juego, y cuando el jugador falle el objetivo tres veces, finalice el juego y haga que vuelva a
aparecer el botón Reproducir. Deje que el jugador reinicie el juego con este botón Reproducir.
Subir de nivel
En nuestro juego actual, una vez que un jugador derriba toda la flota alienígena, el jugador alcanza un
nuevo nivel, pero la dificultad del juego no cambia. Animemos un poco las cosas y hagamos que el
juego sea más desafiante aumentando la velocidad del juego cada vez que un jugador limpia la
pantalla.
Puntuación 285
Machine Translated by Google
durante el reinicio del juego cuando comenzamos un nuevo juego. Aquí está el __init__()
método para settings.py:
# Configuración de envío
self.ship_limit = 3
# Configuración de viñetas
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60, 60, 60
self.bullets_permitido = 3
# Configuración alienígena
self.fleet_drop_speed = 10
en self.initialize_dynamic_settings()
Este método establece los valores iniciales para las velocidades de la nave, la bala y
el alienígena. Aumentaremos estas velocidades a medida que el jugador progrese en el juego
y las restableceremos cada vez que el jugador comience un nuevo juego. Incluimos flota
_dirección en este método para que los alienígenas siempre se muevan justo al comienzo de un nuevo
juego. No necesitamos aumentar el valor de fleet_drop_speed, porque cuando los alienígenas se
mueven más rápido por la pantalla, también bajarán más rápido por la pantalla.
286 Capítulo 14
Machine Translated by Google
Para aumentar la velocidad de la nave, las balas y los alienígenas cada vez
que el jugador alcance un nuevo nivel, escribiremos un nuevo método llamado
Increase_speed():
Para aumentar la velocidad de estos elementos del juego, multiplicamos cada velocidad
configuración por el valor de speedup_scale.
Aumentamos el tempo del juego llamando a added_speed () en _check
_bullet_alien_collisions() cuando el último alienígena de una flota ha sido derribado:
Restablecimiento de la velocidad
Jugar a Alien Invasion debería ser más divertido y desafiante ahora. Cada vez que
limpias la pantalla, el juego debería acelerarse y volverse un poco más difícil. Si el juego se
vuelve demasiado difícil demasiado rápido, disminuya el valor de settings.speedup_scale. O
si el juego no es lo suficientemente desafiante, aumente el valor ligeramente. Encuentra un
punto ideal aumentando la dificultad en un tiempo razonable. El primer par de pantallas
debería ser fácil, las siguientes desafiantes pero factibles, y las siguientes pantallas casi
imposiblemente difíciles.
Puntuación 287
Machine Translated by Google
Inténtalo tú mismo
14-3. Práctica de objetivo desafiante: comience con su trabajo del ejercicio 14-2
(página 285). Haga que el objetivo se mueva más rápido a medida que avanza el juego y
reinicie el objetivo a la velocidad original cuando el jugador haga clic en Reproducir.
14-4. Niveles de dificultad: haga un conjunto de botones para Alien Invasion que le permita
al jugador seleccionar un nivel de dificultad inicial apropiado para el juego. Cada botón debe
asignar los valores apropiados para los atributos en Configuración necesarios para crear
diferentes niveles de dificultad.
Puntuación
Implementemos un sistema de puntuación para rastrear la puntuación del juego en tiempo real y mostrar la
puntuación más alta, el nivel y la cantidad de barcos restantes.
La puntuación es una estadística del juego, por lo que agregaremos un atributo de puntuación a GameStats:
estadísticas_del_juego.py
clase GameStats:
--recorte--
def reset_stats(auto):
"""Inicializar estadísticas que pueden cambiar durante el juego."""
self.ships_left = self.ai_settings.ship_limit
puntuación propia = 0
Para restablecer la puntuación cada vez que comienza un nuevo juego, inicializamos la puntuación en
reset_stats() en lugar de __init__().
Visualización de la partitura
Para mostrar la puntuación en la pantalla, primero creamos una nueva clase, Scoreboard. Por ahora, esta clase solo
mostrará la puntuación actual, pero eventualmente la usaremos para informar la puntuación más alta, el nivel y la
cantidad de barcos restantes también.
Aquí está la primera parte de la clase; guárdelo como scoreboard.py:
marcador de clase:
"""Una clase para reportar información de puntuación."""
288 Capítulo 14
Machine Translated by Google
Para convertir el texto que se mostrará en una imagen, llamamos a prep_score() x, que
definimos aquí:
Hacer un marcador
Para mostrar la puntuación, crearemos una instancia de Scoreboard en AlienInvasion. Primero,
actualicemos las declaraciones de importación :
alien_invasion.py --recorte--
desde game_stats importar GameStats
desde el marcador importar el marcador
--recorte--
Puntuación 289
Machine Translated by Google
pygame.display.set_caption("Invasión alienígena")
290 Capítulo 14
Machine Translated by Google
Para escribir una puntuación en vivo en la pantalla, actualizamos el valor de stats.score cada vez que se golpea
a un alienígena y luego llamamos a prep_score() para actualizar la imagen de la puntuación. Pero primero,
determinemos cuántos puntos obtiene un jugador cada vez que derriba a un alienígena:
# Puntuación
self.puntos_alienígenas = 50
Aumentaremos el valor en puntos de cada alienígena a medida que avanza el juego. Para asegurarnos de
que este valor de punto se restablece cada vez que comienza un nuevo juego, establecemos el valor en
initialize_dynamic_settings().
Actualicemos la puntuación cada vez que derriben a un alienígena en _check_bullet
_colisiones_alienígenas():
si colisiones:
self.stats.score += self.settings.alien_points
self.sb.prep_score()
--recorte--
Restablecimiento de la puntuación
En este momento, solo estamos preparando una nueva partitura después de que un alienígena haya sido
golpeado, lo que funciona durante la mayor parte del juego. Pero todavía vemos el puntaje anterior cuando
comienza un nuevo juego hasta que el primer alienígena es golpeado en el nuevo juego.
Podemos arreglar esto preparando la puntuación al comenzar un nuevo juego:
Puntuación 291
Machine Translated by Google
self.stats.game_active = Verdadero
self.sb.prep_score()
--recorte--
Llamamos a prep_score() después de restablecer las estadísticas del juego al iniciar un nuevo
juego. Esto prepara el marcador con una puntuación de 0.
Tal como está escrito actualmente, nuestro código podría perder la puntuación de algunos
alienígenas. Por ejemplo, si dos balas chocan con alienígenas durante el mismo paso por el bucle
o si hacemos una bala extra ancha para golpear a varios alienígenas, el jugador solo recibirá
puntos por golpear a uno de los alienígenas. Para arreglar esto, refinemos la forma en que se
detectan las colisiones de balas y extraterrestres.
En _check_bullet_alien_collisions(), cualquier bala que choca con un extraterrestre se convierte
en una clave en el diccionario de colisiones . El valor asociado con cada bala es una lista de
alienígenas con los que ha chocado. Recorremos los valores en el diccionario de colisiones para
asegurarnos de otorgar puntos por cada impacto alienígena:
Debido a que el juego se vuelve más difícil cada vez que un jugador alcanza un nuevo nivel, los
extraterrestres en niveles posteriores deberían valer más puntos. Para implementar esta funcionalidad,
agregaremos código para aumentar el valor del punto cuando la velocidad del juego
aumenta:
292 Capítulo 14
Machine Translated by Google
self.initialize_dynamic_settings()
def initialize_dynamic_settings(auto):
--recorte--
def aumentar_velocidad(auto):
"""Aumenta la configuración de velocidad y los valores de puntos alienígenas".""
self.ship_speed *= self.speedup_scale
self.bullet_speed *= self.speedup_scale
self.alien_speed *= self.speedup_scale
Definimos una tasa a la que aumentan los puntos, a la que llamamos score_scale u.
Un pequeño aumento en la velocidad (1.1) hace que el juego sea más desafiante rápidamente.
Pero para ver una diferencia más notable en la puntuación, necesitamos cambiar el valor del punto
alienígena en una cantidad mayor (1,5). Ahora, cuando aumentamos la velocidad del juego, también
aumentamos el valor de puntos de cada golpe v. Usamos la función int() para aumentar el valor de puntos en
números enteros.
Para ver el valor de cada extraterrestre, agregue una llamada print() a la función de aumento_velocidad()
método en Configuración:
El nuevo valor de puntos debería aparecer en la terminal cada vez que alcances un nuevo nivel.
N ota Asegúrese de eliminar la llamada print() después de verificar que el valor del punto está aumentando, o podría afectar el
rendimiento de su juego y distraer al jugador.
Redondeando la puntuación
La mayoría de los juegos de disparos de estilo arcade reportan puntajes como múltiplos de 10, así que
sigamos esa pista con nuestros puntajes. Además, formateemos la partitura para incluir separadores de
coma en números grandes. Haremos este cambio en el marcador:
Puntuación 293
Machine Translated by Google
Puntuaciones altas
Todos los jugadores quieren superar la puntuación más alta de un juego, así que hagamos un seguimiento e informemos
las puntuaciones más altas para darles a los jugadores algo por lo que trabajar. Guardaremos puntuaciones altas en
Estadísticas del juego:
Debido a que la puntuación más alta nunca debe restablecerse, inicializamos high_score en
__init__() en lugar de reset_stats().
294 Capítulo 14
Machine Translated by Google
A continuación, modificaremos el marcador para mostrar la puntuación más alta. Comencemos con el
método __init__() :
La puntuación más alta se mostrará por separado de la puntuación, por lo que necesitamos un
nuevo método, prep_high_score(), para preparar la imagen de puntuación más alta u.
Aquí está el método prep_high_score() :
El método check_high_score() compara la puntuación actual con la puntuación más alta. Si la puntuación
actual es mayor, actualizamos el valor de high_score
y llame a prep_high_score() para actualizar la imagen de la puntuación más alta.
Puntuación 295
Machine Translated by Google
Necesitamos llamar a check_high_score() cada vez que un alienígena es golpeado después de la actualización
ing la puntuación en _check_bullet_alien_collisions():
Figura 14-4: La puntuación más alta se muestra en la parte superior central de la pantalla.
296 Capítulo 14
Machine Translated by Google
auto.puntaje = 0
auto.nivel = 1
Para que Scoreboard muestre el nivel actual, llamamos a un nuevo método, prep
_level(), de __init__():
El método prep_level() crea una imagen a partir del valor almacenado en stats.level u
y establece el atributo derecho de la imagen para que coincida con el atributo derecho de la
puntuación v. Luego establece el atributo superior 10 píxeles debajo de la parte inferior de la
imagen de la puntuación para dejar espacio entre la puntuación y el nivel w.
También necesitamos actualizar show_score():
# Aumentar el nivel.
self.stats.level += 1
self.sb.prep_level()
Puntuación 297
Machine Translated by Google
N ota En algunos juegos clásicos, las puntuaciones tienen etiquetas, como Puntuación, Puntuación alta y Nivel.
Hemos omitido estas etiquetas porque el significado de cada número queda claro una vez que has
jugado el juego. Para incluir estas etiquetas, agréguelas a las cadenas de puntuación justo antes de
las llamadas a font.render() en Scoreboard.
298 Capítulo 14
Machine Translated by Google
la pantalla para representar cuántos barcos quedan, tal como lo hacen muchos juegos de arcade
clásicos.
Primero, necesitamos hacer que Ship herede de Sprite para que podamos crear un grupo de
barcos:
Aquí importamos Sprite, nos aseguramos de que Ship herede de Sprite u, y llamamos a super()
al comienzo de __init__() v.
A continuación, debemos modificar el marcador para crear un grupo de barcos que podamos
mostrar. Aquí están las declaraciones de importación para Scoreboard:
Debido a que estamos haciendo un grupo de barcos, importamos Group and Ship
clases
Aquí está __init__():
Puntuación 299
Machine Translated by Google
El método prep_ships() crea un grupo vacío, self.ships, para contener las instancias de envío u.
Para llenar este grupo, se ejecuta un ciclo una vez por cada barco que el jugador ha dejado v. Dentro del
ciclo, creamos un nuevo barco y establecemos el valor de la coordenada x de cada barco para que los
barcos aparezcan uno al lado del otro con un margen de 10 píxeles en el lado izquierdo del grupo de naves
w. Establecemos el valor de la coordenada y 10 píxeles hacia abajo desde la parte superior de la pantalla
para que los barcos aparezcan en la esquina superior izquierda de la pantalla x. Luego agregamos cada
barco nuevo al grupo de barcos y.
También llamamos a prep_ships() cuando se golpea un barco para actualizar la visualización del barco .
imágenes cuando el jugador pierde un barco:
300 Capítulo 14
Machine Translated by Google
Inténtalo tú mismo
14-5. Puntuación más alta de todos los tiempos: la puntuación más alta se restablece cada
vez que un jugador cierra y reinicia Alien Invasion. Solucione esto escribiendo la puntuación más
alta en un archivo antes de llamar a sys.exit() y leyendo la puntuación más alta al inicializar su
valor en GameStats.
14-6. Refactorización: busque métodos que realicen más de una tarea y refactorícelos para
organizar su código y hacerlo eficiente. Por ejemplo, mueva parte del código en
_check_bullet_alien_collisions(), que inicia un nuevo nivel cuando la flota de alienígenas ha sido
destruida, a una función llamada start_new
_nivel(). Además, mueva las cuatro llamadas de método separadas en el método
__init__() en Scoreboard a un método llamado prep_images() para acortar __init__().
El método prep_images() también podría ayudar a simplificar _check_play_button() o iniciar
_game() si ya ha refactorizado _check_play_button().
nota Antes de intentar refactorizar el proyecto, consulte el Apéndice D para saber cómo
restaurar el proyecto a un estado de funcionamiento si introduce errores durante la
refactorización.
(continuado)
Puntuación 301
Machine Translated by Google
14-7. Expansión del juego: piensa en una forma de expandir Alien Invasion. Por
ejemplo, puede programar a los alienígenas para que disparen balas a la nave o
agregue escudos para que su nave se esconda detrás, que pueden ser destruidos por
balas desde cualquier lado. O use algo como el módulo pygame.mixer para agregar
efectos de sonido, como explosiones y sonidos de disparos.
14-8. Sideways Shooter, versión final: continúa desarrollando Sideways Shooter, usando
todo lo que hemos hecho en este proyecto. Agregue un botón Reproducir, haga que el
juego se acelere en los puntos apropiados y desarrolle un sistema de puntuación. Asegúrese
de refactorizar su código mientras trabaja y busque oportunidades para personalizar el
juego más allá de lo que se muestra en este capítulo.
Resumen
En este capítulo, aprendió cómo implementar un botón Reproducir para comenzar
un nuevo juego, detectar eventos del mouse y ocultar el cursor en juegos activos.
Puede usar lo que ha aprendido para crear otros botones en sus juegos, como un
botón de Ayuda para mostrar instrucciones sobre cómo jugar. También aprendió
cómo modificar la velocidad de un juego a medida que avanza, implementar un
sistema de puntaje progresivo y mostrar información en formas textuales y no textuales.
302 Capítulo 14
Machine Translated by Google
Proyecto 2
Visualización de datos
Machine Translated by Google
Machine Translated by Google
15
Genera nuestros Datos
Instalación de Matplotlib
Para usar Matplotlib para su conjunto inicial de visualizaciones, deberá instalarlo usando pip,
un módulo que descarga e instala paquetes de Python. Ingrese el siguiente comando en un
indicador de terminal:
Este comando le dice a Python que ejecute el módulo pip e instale el paquete
matplotlib en la instalación de Python del usuario actual. Si usa un comando que no sea
python en su sistema para ejecutar programas o iniciar una sesión de terminal, como python3,
su comando se verá así:
N ota Si este comando no funciona en macOS, intente ejecutar el comando nuevamente sin la marca --
user .
Para ver los tipos de visualizaciones que puede realizar con Matplotlib, visite la galería
de muestras en https:// matplotlib.org/ gallery/. Cuando hace clic en una visualización en la
galería, verá el código utilizado para generar el gráfico.
306 Capítulo 15
Machine Translated by Google
ÿ fig, ax = plt.subparcelas()
ax.plot(cuadrados)
plt.mostrar()
Primero importamos el módulo pyplot usando el alias plt para no tener que escribir pyplot
repetidamente. (Verá esta convención a menudo en ejemplos en línea, así que haremos lo
mismo aquí.) El módulo pyplot contiene una serie de funciones que generan gráficos y
diagramas.
Creamos una lista llamada cuadrados para contener los datos que trazaremos. Entonces nosotros
siga otra convención común de Matplotlib llamando a subplots()
función ÿ. Esta función puede generar uno o más gráficos en la misma figura. La variable
fig representa la figura completa o colección de gráficos que se generan. La variable ax
representa una sola parcela en la figura y es la variable que usaremos la mayor parte del
tiempo.
Luego usamos el método plot() , que intentará graficar los datos proporcionados de una
manera significativa. La función plt.show() abre el visor de Matplotlib y muestra el diagrama,
como se muestra en la Figura 15-1. El visor le permite hacer zoom y navegar por el gráfico,
y cuando hace clic en el icono del disco, puede guardar las imágenes del gráfico que desee.
Figura 15-1: Uno de los gráficos más simples que puede hacer en Matplotlib
ÿ ax.tick_params(axis='ambos', labelsize=14)
plt.mostrar()
El parámetro linewidth en ÿ controla el grosor de la línea que genera plot() . El método set_title()
en ÿ establece un título para el gráfico. Los parámetros de tamaño de fuente, que aparecen repetidamente
en todo el código, controlan el tamaño del texto en varios elementos del gráfico.
Los métodos set_xlabel() y set_ylabel() le permiten establecer un título para cada uno de los
ejes ÿ, y el método tick_params() le da estilo a las marcas de verificación ÿ.
Los argumentos que se muestran aquí afectan las marcas de verificación en los ejes x e y (eje = 'ambos')
y establecen el tamaño de fuente de las etiquetas de marca de verificación en 14 (tamaño de etiqueta = 14).
Como puede ver en la Figura 15-2, el gráfico resultante es mucho más fácil de leer.
El tipo de etiqueta es más grande y el gráfico de líneas es más grueso. A menudo vale la pena experimentar
con estos valores para tener una idea de lo que se verá mejor en el gráfico resultante.
308 Capítulo 15
Machine Translated by Google
Corrección de la trama
Pero ahora que podemos leer mejor el gráfico, vemos que los datos no se trazan
correctamente. ¡Observe al final del gráfico que el cuadrado de 4.0 se muestra como 25!
Arreglemos eso.
Cuando le da a plot() una secuencia de números, asume que el primer punto de datos
corresponde a un valor de coordenada x de 0, pero nuestro primer punto corresponde a un
valor de x de 1. Podemos anular el comportamiento predeterminado dando plot () los valores
de entrada y salida utilizados para calcular los cuadrados:
valores_de_entrada = [1, 2, 3, 4, 5]
cuadrados = [1, 4, 9, 16, 25]
--recorte--
Ahora , plot() graficará los datos correctamente porque proporcionamos los valores
de entrada y salida, por lo que no tiene que asumir cómo se generaron los números de
salida. El gráfico resultante, que se muestra en la figura 15-3, es correcto.
Matplotlib tiene varios estilos predefinidos disponibles, con buenas configuraciones iniciales
para colores de fondo, líneas de cuadrícula, anchos de línea, fuentes, tamaños de fuente y más
que harán que sus visualizaciones sean atractivas sin requerir mucha personalización. Para ver
los estilos disponibles en su sistema, ejecute las siguientes líneas en una sesión de terminal:
Para usar cualquiera de estos estilos, agregue una línea de código antes de comenzar a
generar la gráfica:
valores_de_entrada = [1, 2, 3, 4, 5]
cuadrados = [1, 4, 9, 16, 25]
plt.style.use('nacido en el mar')
higo, hacha = plt.subplots()
--recorte--
Este código genera el gráfico que se muestra en la figura 15-4. Hay disponible una
amplia variedad de estilos; Juega con estos estilos para encontrar algunos que te gusten.
A veces, es útil trazar y diseñar puntos individuales en función de ciertas características. Por
ejemplo, puede trazar valores pequeños en un color y valores más grandes en un color
diferente. También podría trazar un gran conjunto de datos con
310 Capítulo 15
Machine Translated by Google
un conjunto de opciones de estilo y luego enfatice puntos individuales al volver a trazarlos con
diferentes opciones.
Para trazar un solo punto, use el método scatter() . Pasar el sencillo (x, y)
valores del punto de interés para scatter() para trazar esos valores:
plt.style.use('seaborn') fig, ax
= plt.subplots() ax.scatter(2, 4)
plt.mostrar()
plt.style.use('seaborn') fig, ax
= plt.subplots() ÿ ax.scatter(2,
4, s=200)
plt.mostrar()
valores_x = [1, 2, 3, 4, 5]
valores_y = [1, 4, 9, 16, 25]
plt.style.use('nacido en el mar')
higo, hacha = plt.subplots()
ax.scatter(valores_x, valores_y, s=100)
--recorte--
La lista x_values contiene los números que se van a elevar al cuadrado y y_values
contiene el cuadrado de cada número. Cuando estas listas se pasan a scatter(),
Matplotlib lee un valor de cada lista a medida que traza cada punto. Los puntos a trazar
son (1, 1), (2, 4), (3, 9), (4, 16) y (5, 25); La figura 15-6 muestra el resultado.
312 Capítulo 15
Machine Translated by Google
plt.style.use('nacido en el mar')
higo, hacha = plt.subplots()
ÿ ax.scatter(valores_x, valores_y, s=10)
--recorte--
plt.mostrar()
Figura 15-7: Python puede trazar 1000 puntos tan fácilmente como traza 5 puntos.
Para cambiar el color de los puntos, pase c a scatter() con el nombre de un color para usar
entre comillas, como se muestra aquí:
También puede definir colores personalizados utilizando el modelo de color RGB. Definir
un color, pase el argumento c una tupla con tres valores decimales (uno para rojo, verde y azul
en ese orden), usando valores entre 0 y 1. Por ejemplo, la siguiente línea crea una gráfica con
puntos de color verde claro:
Los valores cercanos a 0 producen colores oscuros y los valores cercanos a 1 producen
colores más claros.
Un mapa de colores es una serie de colores en un degradado que se mueve desde un color
inicial hasta uno final. Los mapas de colores se utilizan en las visualizaciones para enfatizar un
patrón en los datos. Por ejemplo, puede convertir los valores bajos en un color claro y los valores
altos en un color más oscuro.
El módulo pyplot incluye un conjunto de mapas de colores integrados. Para usar uno de
estos mapas de colores, debe especificar cómo pyplot debe asignar un color a cada punto en
el conjunto de datos. Aquí se explica cómo asignar un color a cada punto en función de su
valor y:
--recorte--
Pasamos la lista de valores y a c, y luego le decimos a pyplot qué mapa de colores usar
usando el argumento cmap . Este código colorea los puntos con valores de y más bajos de azul
claro y los puntos con valores de y más altos de azul oscuro. La figura 15-8 muestra el gráfico
resultante.
N ota Puede ver todos los mapas de colores disponibles en pyplot en https://matplotlib.org/; ir a
Ejemplos, desplácese hacia abajo hasta Color y haga clic en Referencia de mapa de colores.
314 Capítulo 15
Machine Translated by Google
plt.savefig('cuadrados_plot.png', bbox_inches='apretado')
Inténtalo tú mismo
15-1. Cubos: Un número elevado a la tercera potencia es un cubo. Traza los primeros cinco
números cúbicos y luego traza los primeros 5000 números cúbicos.
Paseos aleatorios
En esta sección, usaremos Python para generar datos para una caminata aleatoria y luego
usaremos Matplotlib para crear una representación visualmente atractiva de esos datos. Una
caminata aleatoria es un camino que no tiene una dirección clara pero que está determinado
por una serie de decisiones aleatorias, cada una de las cuales se deja completamente al azar.
Podrías imaginar una caminata aleatoria como el camino que tomaría una hormiga confundida si
diera cada paso en una dirección aleatoria.
para almacenar el número de puntos del recorrido y dos listas para almacenar los valores de las
coordenadas x e y de cada punto del recorrido.
Para tomar decisiones aleatorias, almacenaremos los posibles movimientos en una lista y usaremos
la función choice() , del módulo aleatorio , para decidir qué movimiento hacer cada vez que se da un paso
ÿ. Luego establecemos el número predeterminado de puntos en una caminata en 5000, que es lo
suficientemente grande como para generar algunos patrones interesantes pero lo suficientemente pequeño
como para generar caminatas rápidamente ÿ. Luego, en ÿ, hacemos dos listas para contener los valores de
x e y, y comenzamos cada caminata en el punto (0, 0).
Elegir direcciones
Usaremos el método fill_walk() , como se muestra aquí, para llenar nuestra caminata con puntos y determinar
la dirección de cada paso. Agregue este método a random_walk.py:
316 Capítulo 15
Machine Translated by Google
self.x_values.append(x)
self.y_values.append(y)
En ÿ configuramos un bucle que se ejecuta hasta que la caminata se llena con el correcto
número de puntos. La parte principal del método fill_walk() le dice a Python cómo simular cuatro
decisiones aleatorias: ¿la caminata irá a la derecha o a la izquierda? ¿Hasta dónde llegará en esa
dirección? ¿Subirá o bajará? ¿Hasta dónde llegará en esa dirección?
Usamos choice([1, -1]) para elegir un valor para x_direction, que devuelve
1 para el movimiento a la derecha o ÿ1 para la izquierda ÿ. A continuación, elección ([0, 1, 2, 3, 4])
le dice a Python qué tan lejos debe moverse en esa dirección (x_distance) seleccionando
aleatoriamente un número entero entre 0 y 4. (La inclusión de un 0 nos permite dar pasos a lo largo
del eje y, así como también pasos que tienen movimiento a lo largo de ambos ejes).
En ÿ y ÿ determinamos la longitud de cada paso en las direcciones x e y multiplicando la
dirección del movimiento por la distancia elegida. Un resultado positivo para x_step significa
moverse a la derecha, un resultado negativo significa moverse a la izquierda y 0 significa moverse
verticalmente. Un resultado positivo para y_step significa moverse hacia arriba, negativo significa
moverse hacia abajo y 0 significa moverse horizontalmente. Si el valor de x_step y y_step es 0, el
paseo no va a ninguna parte, así que continuamos el ciclo para ignorar este movimiento ÿ.
Para obtener el siguiente valor de x para la caminata, sumamos el valor en x_step al último
valor almacenado en x_values ÿ y hacemos lo mismo para los valores de y. Cuando tenemos
estos valores, los agregamos a x_values y y_values.
Cada recorrido aleatorio es diferente y es divertido explorar los diversos patrones que se
pueden generar. Una forma de utilizar el código anterior para realizar varios paseos sin tener
que ejecutar el programa varias veces es envolverlo en un ciclo while , como este:
318 Capítulo 15
Machine Translated by Google
Estilo de la caminata
rw_visual.py --recorte--
mientras que es cierto:
Además de colorear los puntos para mostrar su posición a lo largo de la caminata, sería útil ver
dónde comienza y termina cada caminata. Para hacerlo, podemos graficar el primer y el último punto
individualmente después de que se haya graficado la serie principal. Haremos los puntos finales más
grandes y los colorearemos de manera diferente para que se destaquen, como se muestra aquí:
rw_visual.py --recorte--
mientras que es cierto:
--recorte--
ax.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
edgecolors='ninguno', s=15)
plt.mostrar()
--recorte--
320 Capítulo 15
Machine Translated by Google
Para mostrar el punto de partida, trazamos el punto (0, 0) en verde en un tamaño mayor
(s=100) que el resto de los puntos. Para marcar el punto final, trazamos el último valor x e y en
la caminata en rojo con un tamaño de 100. Asegúrese de insertar este código justo antes de la
llamada a plt.show() para que los puntos inicial y final sean dibujado encima de todos los otros
puntos.
Cuando ejecute este código, debería poder detectar exactamente dónde se encuentra cada
caminata comienza y termina. (Si estos puntos finales no se destacan claramente, ajuste su
color y tamaño hasta que lo hagan).
Eliminemos los ejes en este diagrama para que no distraigan la atención del camino de cada
caminata. Para apagar los ejes, use este código:
rw_visual.py --recorte--
mientras que es cierto:
--recorte--
ax.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none',
s = 100)
plt.mostrar()
--recorte--
Para modificar los ejes, usamos los métodos ax.get_xaxis() y ax.get_yaxis() ÿ para
establecer la visibilidad de cada eje en False. A medida que continúe trabajando con
visualizaciones, verá con frecuencia este encadenamiento de métodos.
Ejecute rw_visual.py ahora; deberías ver una serie de gráficos sin ejes.
Aumentemos el número de puntos para darnos más datos con los que trabajar.
Para hacerlo, aumentamos el valor de num_points cuando hacemos un RandomWalk
instancia y ajuste el tamaño de cada punto al dibujar el gráfico, como se muestra aquí:
rw_visual.py --recorte--
mientras que es cierto:
Este ejemplo crea un recorrido aleatorio con 50 000 puntos (para reflejar datos del mundo real) y
traza cada punto con un tamaño s=1. La caminata resultante es tenue y parecida a una nube, como se
muestra en la Figura 15-11. Como puede ver, ¡hemos creado una obra de arte a partir de un diagrama de
dispersión simple!
Experimente con este código para ver cuánto puede aumentar el número de puntos en una
caminata antes de que su sistema comience a ralentizarse significativamente o la trama pierda su
atractivo visual.
Una visualización es mucho más eficaz para comunicar patrones en los datos si encaja bien en la
pantalla. Para que la ventana de trazado se ajuste mejor a su pantalla, ajuste el tamaño de la salida
de Matplotlib, así:
rw_visual.py --recorte--
mientras que es cierto:
Al crear la trama, puede pasar un argumento figsize para establecer el tamaño de la figura. El
parámetro figsize toma una tupla, que le dice a Matplotlib las dimensiones de la ventana de trazado en
pulgadas.
Matplotlib asume que la resolución de su pantalla es de 100 píxeles por pulgada; si este código
no le da un tamaño de gráfico preciso, ajuste los números como
322 Capítulo 15
Machine Translated by Google
Inténtalo tú mismo
x_paso = self.obtener_paso()
y_paso = self.obtener_paso()
qué números es más probable que ocurran al generar un conjunto de datos que represente
el lanzamiento de dados. Luego trazaremos los resultados de una gran cantidad de tiradas
para determinar qué resultados son más probables que otros.
El estudio de tirar los dados se usa a menudo en matemáticas para explicar varios
tipos de análisis de datos. Pero también tiene aplicaciones del mundo real en casinos y
otros escenarios de juego, así como en la forma en que se juegan juegos como Monopoly y
muchos juegos de rol.
Instalación de plotly
Si usó python3 o algo más al instalar Matplotlib, asegúrese de usar el mismo comando
aquí.
Para ver qué tipo de visualizaciones son posibles con Plotly, visite la galería de tipos
de gráficos en https:// plot.ly/ python/. Cada ejemplo incluye código fuente, para que pueda
ver cómo Plotly genera las visualizaciones.
clase morir:
"""Una clase que representa un solo dado."""
El método roll() utiliza la función randint() para devolver un número aleatorio entre 1 y
el número de lados ÿ. Esta función puede devolver el valor inicial (1), el valor final
(num_sides) o cualquier número entero entre los dos.
324 Capítulo 15
Machine Translated by Google
rodar el dado
Antes de crear una visualización basada en la clase Die , tiremos un D6, imprimamos los resultados
y verifiquemos que los resultados parezcan razonables:
# Crea un D6.
ÿ morir = morir()
imprimir (resultados)
En ÿ creamos una instancia de Die con los seis lados predeterminados. En ÿ rodamos
el dado 100 veces y almacena los resultados de cada tirada en la lista de resultados. Aquí hay un
[4, 6, 5, 6, 1, 5, 6, 3, 5, 3, 5, 3, 2, 2, 1, 3, 1, 5, 3, 6, 3, 6, 5, 4,
1, 1, 4, 2, 3, 6, 4, 2, 6, 4, 1, 3, 2, 5, 6, 3, 6, 2, 1, 1, 3, 4, 1, 4,
3, 5, 1, 4, 5, 5, 2, 3, 3, 1, 2, 3, 5, 6, 2, 5, 6, 1, 3, 2, 1, 1, 1, 6,
5, 5, 2, 2, 6, 4, 1, 4, 5, 1, 1, 1, 4, 5, 3, 3, 1, 3, 5, 4, 5, 6, 5, 4,
1, 5, 1, 2]
Una exploración rápida de estos resultados muestra que la clase Die parece estar funcionando.
Vemos los valores 1 y 6, por lo que sabemos que se están devolviendo los valores más pequeños y
más grandes posibles, y como no vemos 0 o 7, sabemos que todos los resultados están en el rango
apropiado. También vemos cada número del 1 al 6, lo que indica que todos los resultados posibles
están representados.
Determinemos exactamente cuántas veces aparece cada número.
die_visual.py --recorte--
# Haga algunas tiradas y almacene los resultados en una lista.
resultados = []
ÿ para roll_num en rango (1000):
resultado = morir.tirar()
resultados.append(resultado)
ÿ frecuencias.append(frecuencia)
imprimir (frecuencias)
Debido a que ya no imprimimos los resultados, podemos aumentar el número de tiradas simuladas
a 1000 ÿ. Para analizar las tiradas, creamos la lista vacía de frecuencias para almacenar el número de
veces que se tira cada valor. Recorremos los valores posibles (del 1 al 6 en este caso) en ÿ, contamos
cuántas veces aparece cada número en los resultados ÿ y luego agregamos este valor a la lista de
frecuencias ÿ. Luego imprimimos esta lista antes de hacer una visualización:
Estos resultados parecen razonables: vemos seis frecuencias, una para cada pos.
número posible cuando lanzas un D6, y vemos que ninguna frecuencia es significativamente más
alta que otra. Ahora vamos a visualizar estos resultados.
Hacer un histograma
Con una lista de frecuencias, podemos hacer un histograma de los resultados. Un histograma es un
gráfico de barras que muestra la frecuencia con la que se producen determinados resultados. Aquí está
el código para crear el histograma:
Para hacer un histograma, necesitamos una barra para cada uno de los posibles resultados.
Los almacenamos en una lista llamada x_values, que comienza en 1 y termina en el número de
lados del dado ÿ. Plotly no acepta los resultados del rango ()
directamente, por lo que necesitamos convertir el rango en una lista explícitamente usando
326 Capítulo 15
Machine Translated by Google
Tenga en cuenta que Plotly ha hecho que el gráfico sea interactivo: desplace
el cursor sobre cualquier barra del gráfico y verá los datos asociados. Esta función
es especialmente útil cuando se trazan varios conjuntos de datos en el mismo gráfico.
Observe también los íconos en la parte superior derecha, que le permiten desplazar y
hacer zoom en la visualización, y guardar su visualización como una imagen.
Después de crear dos instancias de Die, tiramos los dados y calculamos la suma de
los dos dados para cada tirada ÿ. El mayor resultado posible (12) es la suma del mayor
número de ambos dados, que almacenamos en max_result ÿ.
El resultado más pequeño posible (2) es la suma del número más pequeño en ambos dados.
Cuando analizamos los resultados, contamos el número de resultados para cada valor entre 2 y
max_result ÿ. (Podríamos haber usado el rango (2, 13), pero esto funcionaría solo para dos
dados D6. Al modelar situaciones del mundo real, es mejor escribir código que pueda modelar
fácilmente una variedad de situaciones. Este código nos permite simular el lanzamiento un par
de dados con cualquier número de lados).
Al crear el gráfico, incluimos la tecla dtick en x_axis_config
diccionario ÿ. Esta configuración controla el espacio entre las marcas en el eje x. Ahora que
tenemos más barras en el histograma, el valor predeterminado de Plotly
328 Capítulo 15
Machine Translated by Google
la configuración solo etiquetará algunas de las barras. La configuración 'dtick': 1 le dice a Plotly que
etiquete cada marca de verificación. También actualizamos el título del gráfico y también cambiamos
el nombre del archivo de salida.
Después de ejecutar este código, debería ver un gráfico similar al de la Figura 15-13.
Figura 15-13: Resultados simulados de lanzar dos dados de seis caras 1000 veces
Este gráfico muestra los resultados aproximados que es probable que obtenga cuando
tira un par de dados D6. Como puede ver, es menos probable que saque un 2 o un 12 y lo más
probable es que saque un 7. Esto sucede porque hay seis formas de sacar un 7, a saber: 1 y 6, 2
y 5, 3 y 4 , 4 y 3, 5 y 2, o 6 y 1.
Vamos a crear un dado de seis lados y un dado de diez lados, y veamos qué sucede cuando los
lanzamos 50,000 veces:
# Crea un D6 y un D10.
morir_1 = morir()
ÿ dado_2 = Dado(10)
Figura 15-14: Los resultados de lanzar un dado de seis caras y uno de diez caras 50 000 veces
330 Capítulo 15
Machine Translated by Google
Inténtalo tú mismo
15-6. Dos D8: crea una simulación que muestre lo que sucede cuando lanzas dos dados de
ocho caras 1000 veces. Trate de imaginar cómo cree que se verá la visualización antes de
ejecutar la simulación; luego vea si su intuición era correcta.
Aumente gradualmente la cantidad de rollos hasta que comience a ver los límites de las
capacidades de su sistema.
15-7. Tres dados: cuando lanzas tres dados D6, el número más pequeño que puedes lanzar
es 3 y el número más grande es 18. Crea una visualización que muestre lo que sucede cuando
lanzas tres dados D6.
15-8. Multiplicación: cuando lanzas dos dados, generalmente sumas los dos números para
obtener el resultado. Cree una visualización que muestre lo que sucede si multiplica estos
números.
15-9. Comprensiones de matrices: para mayor claridad, los listados en esta sección
usan la forma larga de bucles for . Si se siente cómodo usando listas de comprensión, intente
escribir una comprensión para uno o ambos bucles en cada uno de estos programas.
15-10. Practicar con ambas bibliotecas: intente usar Matplotlib para hacer una visualización
de tirada de dados y use Plotly para hacer la visualización de una caminata aleatoria. (Deberá
consultar la documentación de cada biblioteca para completar este ejercicio).
Resumen
En este capítulo, aprendió a generar conjuntos de datos y crear visualizaciones de
esos datos. Creó gráficos simples con Matplotlib y usó un gráfico de dispersión
para explorar recorridos aleatorios. También creó un histograma con Plotly y usó un
histograma para explorar los resultados de lanzar dados de diferentes tamaños.
Generar sus propios conjuntos de datos con código es una forma interesante
y poderosa de modelar y explorar una amplia variedad de situaciones del mundo
real. A medida que continúe trabajando en los proyectos de visualización de datos
que siguen, esté atento a las situaciones que podría modelar con código. Mire las
visualizaciones que ve en los medios de comunicación y vea si puede identificar
aquellas que se generaron usando métodos similares a los que está aprendiendo en
estos proyectos.
En el Capítulo 16, descargará datos de fuentes en línea y continuará
usar Matplotlib y Plotly para explorar esos datos.
dieciséis
Descarga de datos
Al final de este capítulo, estará preparado para trabajar con diferentes tipos y formatos de
conjuntos de datos, y tendrá una comprensión más profunda de cómo crear visualizaciones
complejas. Poder acceder y visualizar datos en línea de diferentes tipos y formatos es esencial
para trabajar con una amplia variedad de conjuntos de datos del mundo real.
El módulo csv de Python en la biblioteca estándar analiza las líneas en un archivo CSV y nos
permite extraer rápidamente los valores que nos interesan. Comencemos examinando la primera
línea del archivo, que contiene una serie de encabezados para los datos. Estos encabezados nos
dicen qué tipo de información contienen los datos:
Después de importar el módulo csv , asignamos el nombre del archivo con el que estamos
trabajando a filename. Luego abrimos el archivo y asignamos el archivo resultante
334 Capítulo 16
Machine Translated by Google
objeto a f u. A continuación, llamamos a csv.reader() y le pasamos el objeto de archivo como argumento para crear un objeto
El módulo csv contiene una función next() , que devuelve la siguiente línea en el archivo
cuando pasa el objeto del lector. En la lista anterior, llamamos a next() solo una vez para
obtener la primera línea del archivo, que contiene los encabezados de archivo w. Almacenamos
los datos que se devuelven en header_row. Como puede ver, header_row contiene
encabezados significativos relacionados con el clima que nos dicen qué información contiene
cada línea de datos:
sitka_highs.py --recorte--
con abierto (nombre de archivo) como f:
lector = csv.lector(f)
header_row = siguiente (lector)
0 ESTACIÓN
1 NOMBRE
2 FECHA
3 PRCP
4 TAVG
5 TMAX
6 TMIN
Aquí vemos que las fechas y sus altas temperaturas se almacenan en las columnas 2 y
5. Para explorar estos datos, procesaremos cada fila de datos en
sitka_weather_07-2018_simple.csv y extraeremos los valores con los índices 2 y 5.
Ahora que sabemos qué columnas de datos necesitamos, leamos algunos de esos datos.
Primero, leeremos en la temperatura alta de cada día:
sitka_highs.py --recorte--
con abierto (nombre de archivo) como f:
lector = csv.lector(f)
header_row = siguiente (lector)
imprimir (altos)
Hacemos una lista vacía llamada highs u y luego recorremos las filas restantes en el
archivo v. El objeto del lector continúa desde donde lo dejó en el archivo CSV y automáticamente
regresa cada línea siguiendo su posición actual.
Debido a que ya hemos leído la fila del encabezado, el ciclo comenzará en la segunda línea
donde comienzan los datos reales. En cada pasada por el bucle, extraemos los datos del índice
5, que corresponde al encabezado TMAX, y los asignamos a la variable high w. Usamos la
función int() para convertir los datos, que se almacenan como una cadena, a un formato numérico
para que podamos usarlos. Luego agregamos este valor a los máximos.
[62, 58, 70, 70, 67, 59, 58, 62, 66, 59, 56, 63, 65, 58, 56, 59, 64, 60, 60,
61, 65, 65, 63, 59, 64, 65, 68, 66, 64, 67, 65]
Para visualizar los datos de temperatura que tenemos, primero crearemos un gráfico simple de
los máximos diarios usando Matplotlib, como se muestra aquí:
336 Capítulo 16
Machine Translated by Google
plt.mostrar()
Pasamos la lista de máximos a plot() y pasamos c='red' para trazar los puntos en rojo u.
(Graficaremos los máximos en rojo y los mínimos en azul.) Luego especificamos algunos otros
detalles de formato, como el título, el tamaño de fuente y las etiquetas v, que debe reconocer
del Capítulo 15. Porque todavía tenemos que agregue las fechas, no etiquetaremos el eje x, pero
plt.xlabel() modifica el tamaño de fuente para hacer que las etiquetas predeterminadas sean más
legibles w. La figura 16-1 muestra el gráfico resultante: un gráfico lineal simple de las temperaturas
máximas de julio de 2018 en Sitka, Alaska.
Figura 16-1: Un gráfico de líneas que muestra las temperaturas máximas diarias de julio de 2018 en Sitka, Alaska
Agreguemos fechas a nuestro gráfico para que sea más útil. La primera fecha del archivo de
datos meteorológicos se encuentra en la segunda fila del archivo:
Los datos se leerán como una cadena, por lo que necesitamos una forma de
convertir la cadena "2018-07-01" en un objeto que represente esta fecha. Podemos
construir un objeto que represente el 1 de julio de 2018 usando el método strptime() del
módulo datetime . Veamos cómo funciona strptime() en una sesión de terminal:
Primero importamos la clase de fecha y hora del módulo de fecha y hora. Luego
llamamos al método strptime() usando la cadena que contiene la fecha con la que
queremos trabajar como primer argumento. El segundo argumento le dice a Python cómo
se formatea la fecha. En este ejemplo, Python interpreta que '%Y-' significa que la parte de
la cadena antes del primer guión es un año de cuatro dígitos; '%m-' significa que la parte de
la cadena antes del segundo guión es un número que representa el mes; y '%d' significa que
la última parte de la cadena es el día del mes, del 1 al 31.
El método strptime() puede tomar una variedad de argumentos para determinar
cómo interpretar la fecha. La tabla 16-1 muestra algunos de estos argumentos.
Argumento Significado
%UN
Nombre del día de la semana, como lunes
%B
Nombre del mes, como enero
%metro
Mes, como un número (01 a 12)
%d
Día del mes, como un número (01 a 31)
%Y
Año de cuatro dígitos, como 2019
%pag am o pm
%METRO
Minutos (00 a 59)
%S
Segundos (00 a 61)
Trazado de fechas
Ahora podemos mejorar nuestra gráfica de datos de temperatura extrayendo fechas para
los máximos diarios y pasando esos máximos y fechas a plot(), como se muestra aquí:
338 Capítulo 16
Machine Translated by Google
# Dar formato a
la trama. plt.title("Temperaturas máximas diarias, julio de 2018", tamaño de
fuente=24) plt.xlabel('', tamaño de fuente=16) x fig.autofmt_xdate()
plt.mostrar()
Creamos dos listas vacías para almacenar las fechas y temperaturas altas del
archivo u. Luego, convertimos los datos que contienen la información de fecha (fila [2])
en un objeto de fecha y hora v y lo agregamos a las fechas. Pasamos las fechas y los
valores de temperatura máxima a plot() w. La llamada a fig.autofmt_xdate() x dibuja las
etiquetas de fecha en diagonal para evitar que se superpongan. La figura 16-2 muestra
el gráfico mejorado.
Figura 16-2: El gráfico es más significativo ahora que tiene fechas en el eje x.
Con la configuración de nuestro gráfico, agreguemos más datos para obtener una imagen más
completa del clima en Sitka. Copie el archivo sitka_weather_2018_simple.csv, que contiene los datos
meteorológicos de un año completo para Sitka, en la carpeta donde está almacenando los datos para
los programas de este capítulo.
Ahora podemos generar un gráfico para el clima de todo el año:
sitka_highs.py --recorte--
u nombre de archivo = 'datos/sitka_weather_2018_simple.csv'
con abierto (nombre de archivo) como f:
--recorte--
# Dar formato a la trama.
Modificamos el nombre del archivo para usar el nuevo archivo de datos sitka_weather_2018
_simple.csv u, y actualizamos el título de nuestro gráfico para reflejar el cambio en su contenido v.
La figura 16-3 muestra el gráfico resultante.
Podemos hacer que nuestro gráfico informativo sea aún más útil al incluir las bajas temperaturas.
Necesitamos extraer las bajas temperaturas del archivo de datos y luego agregarlas a nuestro gráfico,
como se muestra aquí:
Sitka_highs --recorte--
_lows.py nombre de archivo = 'sitka_weather_2018_simple.csv'
340 Capítulo 16
Machine Translated by Google
# Dar formato a la
trama. x plt.title("Temperaturas máximas y mínimas diarias - 2018", tamaño de fuente=24)
--recorte--
Sitka_highs --recorte--
_lows.py # Grafique las temperaturas altas y bajas.
plt.style.use('nacido en el mar')
higo, hacha = plt.subplots()
u ax.plot(fechas, máximos, c='rojo', alfa=0.5)
ax.plot(fechas, mínimos, c='azul', alfa=0.5)
v plt.fill_ between(fechas, máximos, mínimos, color de cara='azul', alfa=0,1)
--recorte--
Figura 16-5: La región entre los dos conjuntos de datos está sombreada.
El sombreado ayuda a que el rango entre los dos conjuntos de datos sea
inmediatamente evidente.
342 Capítulo 16
Machine Translated by Google
Comprobación de errores
0 ESTACIÓN
1 NOMBRE
2 FECHA
3 PRCP
4 TMAX
5 TMIN
6 TOBOS
en alto = int(fila[4])
bajo = int(fila[5])
fechas.append(fecha_actual)
--recorte--
En u actualizamos los índices para que correspondan a los TMAX y TMIN de este archivo
posiciones.
Cuando ejecutamos el programa, obtenemos un error, como se muestra en la última línea
del siguiente resultado:
''
ValueError: literal no válido para int() con base 10:
El rastreo nos dice que Python no puede procesar la temperatura alta de una de las fechas
porque no puede convertir una cadena vacía ('') en un número entero. En lugar de revisar los
datos y descubrir qué lectura falta, solo manejaremos los casos de datos faltantes directamente.
fechas.append(fecha_actual)
highs.append (alto)
mínimos.append(bajo)
Cada vez que examinamos una fila, tratamos de extraer la fecha y el alto y
baja temperatura u. Si falta algún dato, Python generará un ValueError
y lo manejamos imprimiendo un mensaje de error que incluye la fecha de los datos que faltan v.
Después de imprimir el error, el ciclo continuará procesando la siguiente fila. Si todos los datos de
una fecha se recuperan sin errores, el bloque else
344 Capítulo 16
Machine Translated by Google
se ejecutará y los datos se agregarán a las listas correspondientes w. Debido a que estamos trazando
información para una nueva ubicación, actualizamos el título para incluir la ubicación en el gráfico y usamos
un tamaño de fuente más pequeño para acomodar el título más largo x.
Cuando ejecutes death_valley_highs_lows.py ahora, verás que solo faltan datos en una fecha:
Comparando este gráfico con el gráfico de Sitka, podemos ver que Death Valley
es más cálido en general que el sureste de Alaska, como esperamos. Además, la amplitud de
temperaturas cada día es mayor en el desierto. La altura de la región sombreada deja esto claro.
Muchos conjuntos de datos con los que trabaja tendrán datos faltantes, mal formateados o incorrectos.
Puede usar las herramientas que aprendió en la primera mitad de este libro para manejar estas situaciones. Aquí
usamos un bloque try-except-else para manejar los datos faltantes. A veces usará continuar para omitir algunos
datos o usar remove()
o del para eliminar algunos datos después de haberlos extraído. Utilice cualquier enfoque que funcione,
siempre que el resultado sea una visualización significativa y precisa.
6. En la página siguiente, puede seleccionar los tipos de datos que desea. Puede
descargar un tipo de datos, por ejemplo, centrándose en la temperatura del aire,
o puede descargar todos los datos disponibles de esta estación. Haz tu
opciones y luego haga clic en Continuar.
Los datos que descargue se estructurarán igual que los datos con los que trabajamos
con en esta sección. Puede tener encabezados diferentes a los que vio en esta sección. Pero si sigue
los mismos pasos que usamos aquí, debería poder generar visualizaciones de los datos que le interesan.
Inténtalo tú mismo
16-1. Lluvia de Sitka: Sitka se encuentra en una selva tropical templada, por lo que recibe una
buena cantidad de lluvia. En el archivo de datos sitka_weather_2018_simple.csv hay un encabezado
llamado PRCP, que representa las cantidades de lluvia diarias. Realice una visualización
centrándose en los datos de esta columna. Puede repetir el ejercicio para el Valle de la Muerte si
siente curiosidad por la poca lluvia que cae en un desierto.
16-2. Comparación entre Sitka y el Valle de la Muerte: Las escalas de temperatura en los
gráficos de Sitka y el Valle de la Muerte reflejan los diferentes rangos de datos. Para comparar
con precisión el rango de temperatura en Sitka con el del Valle de la Muerte, necesita escalas
idénticas en el eje y. Cambie la configuración del eje y en uno o ambos gráficos en las Figuras
16-5 y 16-6. Luego haga una comparación directa entre los rangos de temperatura en Sitka y el
Valle de la Muerte (o dos lugares cualquiera que desee comparar).
16-3. San Francisco: ¿Son las temperaturas en San Francisco más como las temperaturas
en Sitka o las temperaturas en el Valle de la Muerte? Descargue algunos datos de San Francisco
y genere un gráfico de temperatura alta-baja para San Francisco para hacer una comparación.
346 Capítulo 16
Machine Translated by Google
16-4. Índices automáticos: en esta sección codificamos los índices correspondientes a las
columnas TMIN y TMAX . Use la fila de encabezado para determinar los índices de estos
valores, de modo que su programa pueda funcionar para Sitka o Death Valley. Use el nombre
de la estación para generar automáticamente un título apropiado para su gráfico también.
16-5. Explorar: genere algunas visualizaciones más que examinen cualquier otro aspecto
meteorológico que le interese para cualquier lugar que le interese.
{"tipo":"FeatureCollection","metadatos":{"generado":1550361461000,...
{"type":"Feature","properties":{"mag":1.2,"place":"11km NNE of Nor...
{"type":"Feature","properties":{"mag":4.3,"place":"69 km al NNO de Ayn...
{"type":"Feature","properties":{"mag":3.6,"place":"126km SSE of Co...
{"type":"Feature","properties":{"mag":2.1,"place":"21 km al NNO de Teh...
{"type":"Feature","properties":{"mag":4,"place":"57 km al suroeste de Kakto...
--recorte--
Este archivo está formateado más para máquinas que para humanos. Pero
podemos ver que el archivo contiene algunos diccionarios, así como información
que nos interesa, como la magnitud y la ubicación de los terremotos.
El módulo json proporciona una variedad de herramientas para explorar y trabajar con datos
JSON. Algunas de estas herramientas nos ayudarán a reformatear el archivo para que podamos
ver los datos sin procesar más fácilmente antes de comenzar a trabajar con ellos mediante
programación.
Comencemos cargando los datos y mostrándolos en un formato que sea más fácil
leer. Este es un archivo de datos largo, por lo que en lugar de imprimirlo, reescribiremos los datos
en un archivo nuevo. Luego podemos abrir ese archivo y desplazarnos hacia adelante y hacia atrás
fácilmente a través de los datos:
v readable_file = 'datos/readable_eq_data.json'
con abierto (archivo_legible, 'w') como f:
w json.dump(all_eq_data, f, sangría=4)
Primero importamos el módulo json para cargar los datos correctamente desde el archivo
y luego almacenamos todo el conjunto de datos en all_eq_data u. El json.load()
La función convierte los datos a un formato con el que Python puede trabajar: en este caso, un
diccionario gigante. En v creamos un archivo para escribir estos mismos datos en un formato más
legible. La función json.dump() toma un objeto de datos JSON y un objeto de archivo, y escribe los
datos en ese archivo w. El argumento indent=4 le dice a dump() que formatee los datos usando una
sangría que coincida con la estructura de los datos.
legible_eq {
_datos.json "tipo": "Colección de funciones",
en "metadatos": {
"generado": 1550361461000,
"url": "https://earthquake.usgs.gov/earthquakes/.../1.0_day.geojson",
"title": "USGS Magnitud 1.0+ Terremotos, día pasado",
"estado": 200,
"api": "1.7.0",
"contar": 158
},
v "características": [
--recorte--
La primera parte del archivo incluye una sección con la clave "metadatos". Este
nos dice cuándo se generó el archivo de datos y dónde podemos encontrar los datos en línea.
También nos da un título legible por humanos y el número de terremotos incluidos en este archivo. En
este período de 24 horas se registraron 158 sismos.
348 Capítulo 16
Machine Translated by Google
Este archivo geoJSON tiene una estructura que resulta útil para los datos basados en la ubicación.
La información se almacena en una lista asociada a las "características" clave v.
Debido a que este archivo contiene datos de terremotos, los datos están en forma de lista donde
cada elemento de la lista corresponde a un solo terremoto. Esta estructura puede parecer confusa,
pero es bastante poderosa. Permite a los geólogos almacenar toda la información que necesitan en un
diccionario sobre cada terremoto y luego juntar todos esos diccionarios en una gran lista.
legible_eq --recorte--
_datos.json {
"tipo": "Característica",
en "propiedades": {
"mag": 0.96,
--recorte--
en "title": "M 1.0 - 8 km al NE de Aguanga, CA"
},
en "geometría": {
"tipo": "Punto",
"coordenadas": [
xy -116.7941667,
33.4863333,
3.22
]
},
"id": "ci37532978"
},
Las "propiedades" clave contienen mucha información sobre cada terremoto u. Estamos
principalmente interesados en la magnitud de cada terremoto, que está asociado con la clave "mag".
También nos interesa el título de cada terremoto, que proporciona un buen resumen de su magnitud y
ubicación v.
La "geometría" clave nos ayuda a entender dónde ocurrió el terremoto w. Necesitaremos
esta información para mapear cada evento. Podemos encontrar la longitud x y la latitud y para cada
terremoto en una lista asociada a las "coordenadas" clave.
Este archivo contiene mucho más anidamiento de lo que usaríamos en el código que escribimos,
así que si parece confuso, no se preocupe: Python manejará la mayor parte de la complejidad. Solo
trabajaremos con uno o dos niveles de anidamiento a la vez. Comenzaremos sacando un diccionario para
cada terremoto que se registró en el período de 24 horas.
N ota Cuando hablamos de ubicaciones, a menudo decimos primero la latitud de la ubicación, seguida de la longitud.
Esta convención probablemente surgió porque los humanos descubrieron la latitud mucho antes de que
desarrolláramos el concepto de longitud. Sin embargo, muchos marcos geoespaciales enumeran primero
la longitud y luego la latitud, porque esto corresponde a la (x, y)
convención que usamos en las representaciones matemáticas. El formato geoJSON sigue la convención
(longitud, latitud), y si usa un marco diferente, es importante saber qué convención sigue ese marco.
Primero, haremos una lista que contenga toda la información sobre cada terremoto que ocurrió.
all_eq_dicts = all_eq_data['características']
imprimir (len (todos_eq_dicts))
Tomamos los datos asociados con las 'características' clave y los almacenamos en all_eq
_dicts. Sabemos que este archivo contiene registros sobre 158 terremotos, y el resultado
verifica que hemos capturado todos los terremotos en el archivo:
158
Extracción de magnitudes
Usando la lista que contiene datos sobre cada terremoto, podemos recorrer esa lista y extraer
cualquier información que queramos. Ahora sacaremos la magnitud de cada terremoto:
eq_explorar --recorte--
_datos.py all_eq_dicts = all_eq_data['características']
tu revistas = []
para eq_dict en all_eq_dicts:
v mag = eq_dict['propiedades']['mag']
revistas.append(mag)
Hacemos una lista vacía para almacenar las magnitudes, y luego recorremos
el diccionario all_eq_dicts u. Dentro de este ciclo, cada terremoto está representado por el diccionario
eq_dict. La magnitud de cada terremoto se almacena en la sección 'propiedades' de este diccionario
bajo la clave 'mag' v. Almacenamos cada magnitud en la variable mag y luego la agregamos a la lista
mags.
Imprimimos las primeras 10 magnitudes, para que podamos ver si estamos obteniendo
los datos correctos:
350 Capítulo 16
Machine Translated by Google
Los datos de ubicación se almacenan bajo la clave "geometría". Dentro del diccionario de
geometría hay una clave de "coordenadas" , y los primeros dos valores en esta lista son la longitud
y la latitud. Así es como extraeremos estos datos:
eq_explorar --recorte--
_datos.py all_eq_dicts = all_eq_data['características']
Con la información que hemos obtenido hasta ahora, podemos construir un mapa del mundo simple.
Aunque todavía no se verá presentable, queremos asegurarnos de que la información se muestre
correctamente antes de centrarnos en cuestiones de estilo y presentación.
Aquí está el mapa inicial:
--recorte--
Figura 16-7: Un mapa simple que muestra dónde ocurrieron todos los terremotos en las últimas 24 horas
Podemos hacer muchas modificaciones para que este mapa sea más significativo
y fácil de leer, así que hagamos algunos de estos cambios.
352 Capítulo 16
Machine Translated by Google
Antes de configurar el gráfico, veamos una forma ligeramente diferente de especificar los
datos para un gráfico de Plotly. En el gráfico actual, la lista de datos se define en una
línea:
Esta es una de las formas más sencillas de definir los datos de un gráfico en Plotly.
Pero no es la mejor manera cuando desea personalizar la presentación.
Aquí hay una forma equivalente de definir los datos para el gráfico actual:
datos = [{
'tipo': 'disperso',
'lon': lons,
'lat': lats,
}]
En este enfoque, toda la información sobre los datos se estructura como pares
clave-valor en un diccionario. Si coloca este código en eq_plot.py, verá el mismo gráfico
que acabamos de generar. Este formato nos permite especificar personalizaciones más
fácilmente que el formato anterior.
Cuando buscamos cómo mejorar el estilo del mapa, debemos centrarnos en los aspectos
de los datos que queremos comunicar más claramente. El mapa actual muestra la
ubicación de cada terremoto, pero no comunica la gravedad de ningún terremoto.
Queremos que los espectadores vean de inmediato dónde ocurren los terremotos más
importantes del mundo.
Para ello, cambiaremos el tamaño de los marcadores en función de la magni
tud de cada terremoto:
Plotly ofrece una gran variedad de personalizaciones que puede realizar en una serie
de datos, cada una de las cuales se puede expresar como un par clave-valor. Aquí estamos
usando la tecla 'marcador' para especificar qué tan grande debe ser cada marcador en el mapa.
Usamos un diccionario anidado como el valor asociado con 'marcador', porque puede
especificar una serie de configuraciones para todos los marcadores en una serie.
Queremos que el tamaño corresponda a la magnitud de cada terremoto. Pero si solo
pasamos la lista de revistas , los marcadores serían demasiado pequeños para ver fácilmente las
diferencias de tamaño. Necesitamos multiplicar la magnitud por un factor de escala para obtener
un tamaño de marcador apropiado. En mi pantalla, un valor de 5 funciona bien; un valor un poco
más pequeño o más grande podría funcionar mejor para su mapa. Usamos una lista de
comprensión, que genera un tamaño de marcador apropiado para cada valor en la lista de revistas v.
Cuando ejecute este código, debería ver un mapa que se parece al
en la figura 16-8. Este es un mapa mucho mejor, pero aún podemos hacer más.
eq_world_map.py --recorte--
u nombre de archivo = 'datos/eq_data_30_day_m1.json'
--recorte--
# Mapa de los terremotos.
datos = [{
--recorte--
354 Capítulo 16
Machine Translated by Google
'marcador': {
'tamaño': [5 * revista para revista en revistas],
'color': revistas,
'escala de colores': 'Viridis',
'escala inversa': Cierto,
vwxy 'barra de colores': {'título': 'Magnitud'},
},
}]
--recorte--
Asegúrese de actualizar el nombre del archivo para usar el conjunto de datos de 30 días u.
Todos los cambios significativos aquí ocurren en el diccionario de 'marcadores' , porque solo
estamos modificando la apariencia de los marcadores. La configuración de 'color' le dice a Plotly
qué valores debe usar para determinar dónde cae cada marcador en la escala de colores v.
Usamos la lista de revistas para determinar el color que se usa.
La configuración de 'escala de colores ' le dice a Plotly qué rango de colores usar: 'Viridis'
es una escala de colores que va del azul oscuro al amarillo brillante y funciona bien para este
conjunto de datos w. Establecemos 'reversescale' en True, porque queremos usar amarillo
brillante para los valores más bajos y azul oscuro para los terremotos x más severos. La
configuración de la 'barra de colores' nos permite controlar la apariencia de la escala de colores
que se muestra en el lateral del mapa. Aquí llamamos a la escala de colores 'Magnitud' para
dejar claro qué representan los colores x.
Cuando ejecute el programa ahora, verá un mapa mucho más atractivo.
En la Figura 16-9, la escala de colores muestra la severidad de los terremotos individuales.
¡Trazar tantos terremotos realmente deja en claro dónde están los límites de las placas
tectónicas!
Figura 16-9: En 30 días de terremotos, el color y el tamaño se utilizan para representar la magnitud
de cada terremoto.
También puede elegir entre una serie de otras escalas de colores. Para ver las escalas de colores
Plotly almacena las escalas de colores en el módulo de colores. Las escalas de colores se definen en
el diccionario PLOTLY_SCALES, y los nombres de las escalas de colores sirven como claves en el
diccionario. Aquí está el resultado que muestra todas las escalas de color disponibles:
grises
YlGnBu
Verduras
--recorte--
Viridis
Siéntase libre de probar estas escalas de colores; recuerda que puedes revertir
cualquiera de estas escalas usando la configuración de escala inversa .
N ota Si imprime el diccionario PLOTLY_SCALES , puede ver cómo se definen las escalas de color.
Cada escala tiene un color inicial y un color final, y algunas escalas también tienen uno o más colores intermedios
definidos. Plotly interpola sombras entre cada uno de estos colores definidos.
Para finalizar este mapa, agregaremos un texto informativo que aparece cuando pasas el cursor sobre el
marcador que representa un terremoto. Además de mostrar la longitud y la latitud, que aparecen de forma
predeterminada, mostraremos la magnitud y también proporcionaremos una descripción de la ubicación
aproximada.
Para realizar este cambio, debemos extraer un poco más de datos del archivo y agregarlos también
al diccionario en datos :
eq_world_map.py --recorte--
umags, lons, lats, hover_texts = [], [], [], []
para eq_dict en all_eq_dicts:
--recorte--
lat = eq_dict['geometría']['coordenadas'][1]
v título = eq_dict['propiedades']['título']
revistas.append(mag)
lons.append(lon)
lats.append(lat)
hover_texts.append(título)
--recorte--
356 Capítulo 16
Machine Translated by Google
Primero creamos una lista llamada hover_texts para almacenar la etiqueta que usaremos
para cada marcador u. La sección de "título" de los datos del terremoto contiene un nombre
descriptivo de la magnitud y ubicación de cada terremoto además de su longitud y latitud. En v
extraemos esta información y la asignamos al título de la variable, y luego la agregamos a la
lista hover_texts.
Cuando incluimos la clave 'texto' en el objeto de datos , Plotly usa este valor
como una etiqueta para cada marcador cuando el espectador se desplaza sobre el
marcador. Cuando pasamos una lista que coincide con el número de marcadores, Plotly
extrae una etiqueta individual para cada marcador que genera w. Cuando ejecuta este
programa, debería poder pasar el cursor sobre cualquier marcador, ver una descripción
de dónde ocurrió ese terremoto y leer su magnitud exacta.
¡Esto es impresionante! En aproximadamente 40 líneas de código, hemos creado
un mapa visualmente atractivo y significativo de la actividad sísmica global que también
ilustra la estructura geológica del planeta. Plotly ofrece una amplia gama de formas en
las que puede personalizar la apariencia y el comportamiento de sus visualizaciones.
Con las numerosas opciones de Plotly, puede crear gráficos y mapas que muestren
exactamente lo que usted desea.
Inténtalo tú mismo
16-6. Refactorización: el ciclo que extrae datos de all_eq_dicts usa variables para
la magnitud, longitud, latitud y título de cada terremoto antes de agregar estos
valores a sus listas apropiadas. Se eligió este enfoque para aclarar cómo extraer
datos de un archivo JSON, pero no es necesario en su código.
En lugar de usar estas variables temporales, extraiga cada valor de eq_dict y
agréguelo a la lista correspondiente en una línea. Hacerlo debería acortar el cuerpo
de este ciclo a solo cuatro líneas.
16-7. Título automatizado: en esta sección, especificamos el título manualmente al
definir my_layout, lo que significa que debemos recordar actualizar el título cada vez
que cambia el archivo de origen. En su lugar, puede usar el título del conjunto de
datos en la parte de metadatos del archivo JSON. Obtenga este valor, asígnelo a una
variable y utilícelo para el título del mapa cuando esté definiendo my_layout.
(continuado)
Resumen
En este capítulo, aprendió a trabajar con conjuntos de datos del mundo real. Procesó
archivos CSV y JSON, y extrajo los datos en los que desea concentrarse. Usando datos
meteorológicos históricos, aprendió más sobre cómo trabajar con Matplotlib, incluido
cómo usar el módulo de fecha y hora y cómo trazar varias series de datos en un gráfico.
Trazó datos geográficos en un mapa mundial en Plotly y también diseñó mapas y gráficos
de Plotly.
A medida que adquiera experiencia trabajando con archivos CSV y JSON, podrá
para procesar casi cualquier dato que desee analizar. Puede descargar la mayoría
de los conjuntos de datos en línea en cualquiera de estos formatos o en ambos. Al
trabajar con estos formatos, también podrá aprender a trabajar con otros formatos de
datos más fácilmente.
En el próximo capítulo, escribirá programas que recopilan automáticamente sus
propios datos de fuentes en línea y luego creará visualizaciones de esos datos. Estas
son habilidades divertidas si quieres programar como pasatiempo y habilidades críticas
si estás interesado en programar profesionalmente.
358 Capítulo 16
Machine Translated by Google
17
En este capítulo, aprenderá a escribir un programa
autónomo que genere un visu
alización basada en los datos que recupera. Su
Una API web es una parte de un sitio web diseñado para interactuar con programas. Esos
programas utilizan direcciones URL muy específicas para solicitar cierta información. Este
tipo de solicitud se denomina llamada API. Los datos solicitados serán devueltos en un
Machine Translated by Google
formato fácil de procesar, como JSON o CSV. La mayoría de las aplicaciones que se basan en
fuentes de datos externas, como las aplicaciones que se integran con sitios de redes sociales, se
basan en llamadas API.
Git y GitHub
Basaremos nuestra visualización en información de GitHub, un sitio que permite a los programadores
colaborar en proyectos de codificación. Usaremos la API de GitHub para solicitar información sobre
los proyectos de Python en el sitio y luego generaremos una visualización interactiva de la popularidad
relativa de estos proyectos usando Plotly.
GitHub (https:// github.com/) toma su nombre de Git, un sistema de control de versiones distribuido.
Git ayuda a las personas a administrar su trabajo en un proyecto, por lo que los cambios realizados por
una persona no interferirán con los cambios que realicen otras personas.
Cuando implementa una nueva función en un proyecto, Git realiza un seguimiento de los cambios
que realiza en cada archivo. Cuando su nuevo código funciona, confirma los cambios que ha
realizado y Git registra el nuevo estado de su proyecto. Si comete un error y desea revertir los
cambios, puede volver fácilmente a cualquier estado de funcionamiento anterior. (Para obtener más
información sobre el control de versiones con Git, consulte el Apéndice D). Los proyectos en GitHub
se almacenan en repositorios que contienen todo lo relacionado con el proyecto: su código,
información sobre sus colaboradores, cualquier problema o informe de error, etc.
Cuando a los usuarios de GitHub les gusta un proyecto, pueden "destacarlo" para mostrar su
apoyo y realizar un seguimiento de los proyectos que podrían querer usar. En este capítulo,
escribiremos un programa para descargar automáticamente información sobre los proyectos de
Python con más estrellas en GitHub y luego crearemos una visualización informativa de estos
proyectos.
la API La API de GitHub le permite solicitar una amplia gama de información a través de llamadas
a la API. Para ver cómo se ve una llamada API, ingrese lo siguiente en la barra de direcciones de
su navegador y presione enter:
https://api.github.com/search/repositories?q=language:python&sort=stars
El signo de interrogación después de los repositorios indica que estamos a punto de pasar
una discusión. La q significa consulta y el signo igual (=) nos permite comenzar a especificar una
consulta (q=). Al usar language:python, indicamos que queremos información solo sobre los
repositorios que tienen Python como idioma principal.
La parte final, &sort=stars, ordena los proyectos por el número de estrellas que se les han otorgado.
360 Capítulo 17
Machine Translated by Google
{
u "recuento_total": 3494012,
v "resultados_incompletos": falso,
w "elementos": [
{
"identificación": 21289110,
"id_nodo": "MDEwOlJlcG9zaXRvcnkyMTI4OTExMA==",
"nombre": "pitón impresionante",
"full_name": "vinta/genial-python",
--recorte--
Solicitudes de instalación
Esta línea le dice a Python que ejecute el módulo pip e instale el paquete
Requests en la instalación de Python del usuario actual. Si usa python3 o un
comando diferente cuando ejecuta programas o instala paquetes, asegúrese de usar
el mismo comando aquí.
N ota Si este comando no funciona en macOS, intente ejecutar el comando nuevamente sin
la marca --user .
Ahora comenzaremos a escribir un programa para emitir automáticamente una llamada a la API y
procesar los resultados mediante la identificación de los proyectos de Python con más estrellas en
GitHub:
N ota Las llamadas simples como esta deberían devolver un conjunto completo de resultados, por lo que
es seguro ignorar el valor asociado con 'incomplete_results'. Pero cuando realiza llamadas
API más complejas, su programa debe verificar este valor.
362 Capítulo 17
Machine Translated by Google
u Teclas: 73
archivo_url
archivado
asignados_url
--recorte--
URL
vigilantes
contador_de_observadores
La API de GitHub devuelve mucha información sobre cada repositorio: hay 73 claves
en repo_dict u. Cuando revise estas claves, tendrá una idea del tipo de información que
puede extraer sobre un proyecto. (La única forma de saber qué información está disponible
a través de una API es leer la documentación o examinar la información a través del código,
como lo estamos haciendo aquí).
Extraigamos los valores de algunas de las claves en repo_dict:
python_repos.py --recorte--
# Explorar información sobre los repositorios.
repo_dicts = respuesta_dict['elementos']
print(f"Repositorios devueltos: {len(repo_dicts)}")
x print(f"Creado: {repo_dict['created_at']}")
y print(f"Actualizado: {repo_dict['updated_at']}")
print(f"Descripción: {repo_dict['descripción']}")
Aquí imprimimos los valores para un número de claves del diccionario del primer
repositorio. En u imprimimos el nombre del proyecto. Un diccionario completo representa
al propietario del proyecto, por lo que en v usamos la clave de propietario para acceder al
diccionario que representa al propietario y luego usamos la clave de inicio de sesión para
obtener el nombre de inicio de sesión del propietario. En w imprimimos cuántas estrellas ha
obtenido el proyecto y la URL del repositorio de GitHub del proyecto. Luego mostramos
cuándo se creó x y cuándo se actualizó por última vez y. Finalmente, imprimimos la
descripción del repositorio; la salida debería ser algo como esto:
Podemos ver que el proyecto de Python con más estrellas en GitHub a partir de este
escrito es awesome-python, su propietario es el usuario vinta, y ha sido protagonizado
por más de 60.000 usuarios de GitHub. Podemos ver la URL del repositorio del proyecto,
su fecha de creación de junio de 2014 y que se actualizó recientemente.
Además, la descripción nos dice que awesome-python contiene una lista de recursos
populares de Python.
python_repos.py --recorte--
# Explorar información sobre los repositorios.
repo_dicts = respuesta_dict['elementos']
print(f"Repositorios devueltos: {len(repo_dicts)}")
364 Capítulo 17
Machine Translated by Google
Nombre: impresionante-python
Dueño: vinta
Estrellas: 61549
Repositorio: https://github.com/vinta/awesome-python
Descripción: una lista seleccionada de increíbles marcos, bibliotecas y software de Python
y recursos
Nombre: system-design-primer
Propietario: donnemartin
Estrellas: 57256
Repositorio: https://github.com/donnemartin/system-design-primer
Descripción: Aprende a diseñar sistemas a gran escala. preparación para el sistema
entrevista de diseño. Incluye tarjetas flash de Anki.
--recorte--
Nombre: patrones-python
Dueño: faif
Estrellas: 19058
Repositorio: https://github.com/faif/python-patterns
Descripción: una colección de patrones de diseño/modismos en Python
Algunos proyectos interesantes aparecen en estos resultados, y podría valer la pena mirar
algunos. Pero no pierda demasiado tiempo, porque en breve crearemos una visualización que
hará que los resultados sean mucho más fáciles de leer.
La mayoría de las API tienen una tasa limitada, lo que significa que hay un límite en la cantidad
de solicitudes que puede realizar en un período de tiempo determinado. Para ver si se está
acercando a los límites de GitHub, ingrese https:// api.github.com/ rate_limit en un navegador web.
Deberías ver una respuesta que comienza así:
{
"recursos": {
"centro": {
"límite": 60,
"restante": 58,
"restablecer": 1550385312
},
u "buscar": {
v "límite": 10,
w "restante": 8,
X "restablecer": 1550381772
},
--recorte--
N ota Muchas API requieren que se registre y obtenga una clave de API para realizar llamadas API. Al
momento de escribir este artículo, GitHub no tiene tal requisito, pero si obtiene una clave API,
sus límites serán mucho más altos.
# Hacer visualización.
x datos = [{
'tipo': 'barra',
'x': nombres_repositorios,
'y': estrellas,
}]
366 Capítulo 17
Machine Translated by Google
y mi_diseño = {
'title': 'Proyectos de Python con más estrellas en GitHub',
'xaxis': {'título': 'Repositorio'},
'yaxis': {'title': 'Estrellas'},
}
Vamos a refinar el estilo del gráfico. Como vio en el Capítulo 16, puede incluir todas las
directivas de estilo como pares clave-valor en los diccionarios data y my_layout .
Los cambios en el objeto de datos afectan a las barras. Aquí hay una versión modificada
del objeto de datos para nuestro gráfico que nos da un color específico y un borde claro para
cada barra:
python_repos --recorte--
_visual.py datos = [{
'tipo': 'barra',
'x': nombres_repositorios,
'y': estrellas,
'marcador': {
'color': 'rgb(60, 100, 150)',
'línea': {'ancho': 1.5, 'color': 'rgb(25, 25, 25)'}
},
'opacidad': 0.6,
}]
--recorte--
Los ajustes de marcador que se muestran aquí afectan el diseño de las barras.
Establecemos un color azul personalizado para las barras y especificamos que se perfilarán
con una línea gris oscuro de 1,5 píxeles de ancho. También establecemos la opacidad de
las barras en 0,6 para suavizar un poco la apariencia del gráfico.
A continuación, modificaremos my_layout:
python_repos --recorte--
_visual.py mi_diseño = {
'title': 'Proyectos de Python con más estrellas en GitHub',
u 'fuente del título': {'tamaño': 28},
v 'ejex':'
'título': 'Repositorio',
'fuente del título': {'tamaño': 24},
'tipo de letra': {'tamaño': 14},
},
en 'yaxis': {
'título': 'Estrellas',
'fuente del título': {'tamaño': 24},
'tipo de letra': {'tamaño': 14},
},
}
--recorte--
Usamos la tecla 'titlefont' para definir el tamaño de fuente del título general del gráfico
u. Dentro del diccionario 'xaxis' , agregamos configuraciones para controlar el tamaño de
fuente del título del eje x ('titlefont') y también de las etiquetas de marca ('tickfont') v.
Debido a que se trata de diccionarios anidados individuales, puede incluir claves para el color
y la familia de fuentes de los títulos de los ejes y las etiquetas de marcas. En w definimos
configuraciones similares para el eje y.
La figura 17-2 muestra el gráfico rediseñado.
368 Capítulo 17
Machine Translated by Google
herramientas personalizada En Plotly, puede pasar el cursor sobre una barra individual para mostrar la
información que representa la barra. Esto se conoce comúnmente como información sobre herramientas y, en
este caso, actualmente muestra la cantidad de estrellas que tiene un proyecto. Vamos a crear una información
sobre herramientas personalizada para mostrar la descripción de cada proyecto, así como el propietario del proyecto.
Necesitamos extraer algunos datos adicionales para generar la información sobre herramientas y
modificar el objeto de datos :
--snip-- #
Resultados del
python_repos_visual.py
proceso. response_dict =
r.json() repo_dicts = response_dict['items']
u repo_names, stars, labels = [], [], [] for repo_dict
en repo_dicts: repo_names.append(repo_dict['name'])
stars.append( repo_dict['recuento de
observadores de estrellas'])
# Hacer visualización.
datos = [{ 'tipo': 'barra', 'x':
nombres_repo, 'y':
estrellas, x 'texto
flotante': etiquetas,
'marcador': {
Primero definimos una nueva lista vacía, etiquetas, para contener el texto que
queremos mostrar para cada proyecto u. En el bucle en el que procesamos los datos,
extraemos el propietario y la descripción de cada proyecto v. Plotly le permite usar código
HTML dentro de elementos de texto, por lo que generamos una cadena para la etiqueta con un
salto de línea (<br />) entre el nombre de usuario del propietario del proyecto y la descripción w.
Luego almacenamos esta etiqueta en las etiquetas de la lista .
En el diccionario de datos , agregamos una entrada con la clave 'hovertext' y asignamos
es la lista que acabamos de crear x. A medida que Plotly crea cada barra, extraerá etiquetas
de esta lista y solo las mostrará cuando el espectador se desplace sobre una barra.
La figura 17-3 muestra el gráfico resultante.
Figura 17-3: Al pasar el cursor sobre una barra, se muestra el propietario y la descripción del proyecto.
Debido a que Plotly le permite usar HTML en elementos de texto, podemos agregar fácilmente
enlaces a un gráfico. Usemos las etiquetas del eje x como una forma de permitir que el
espectador visite la página de inicio de cualquier proyecto en GitHub. Necesitamos extraer las
URL de los datos y usarlas al generar las etiquetas del eje x:
python_repos --recorte--
_visual.py # Resultados del proceso.
respuesta_dict = r.json()
repo_dicts = respuesta_dict['elementos']
370 Capítulo 17
Machine Translated by Google
estrellas.append(repo_dict['stargazers_count'])
--recorte--
# Hacer visualización.
datos = [{
'tipo': 'barra',
x 'x': repo_enlaces,
'y': estrellas,
--recorte--
}]
--recorte--
igual que antes, pero ahora el espectador puede hacer clic en cualquiera de los nombres de
proyectos en la parte inferior del gráfico para visitar la página de inicio de ese proyecto en GitHub.
¡Ahora tenemos una visualización interactiva e informativa de datos recuperados a través de una API!
Para obtener más información sobre la API de GitHub, consulte su documentación en https://
desarrollador.github.com/ v3/. Aquí aprenderá cómo obtener una amplia variedad de
información específica de GitHub. Si tiene una cuenta de GitHub, puede trabajar con sus
propios datos, así como con los datos disponibles públicamente para los repositorios de
otros usuarios.
https://hacker-noticias.firebaseio.com/v0/item/19155826.json
Todo en este programa debería parecerle familiar, porque lo hemos usado todo
en los dos capítulos anteriores. El resultado es un diccionario de información sobre el
artículo con el ID 19155826:
legible_hn {
_datos.json "por": "jimktrains2",
u "descendientes": 220,
"identificación": 19155826,
v "niños": [
19156572,
19158857,
--recorte--
],
"puntuación": 722,
"tiempo": 1550085414,
w "title": "Oportunidad Mars Rover de la NASA concluye una misión de 15 años",
"tipo": "historia",
x "url": "https://www.nytimes.com/.../mars-opportunity-rover-dead.html"
}
372 Capítulo 17
Machine Translated by Google
El diccionario contiene una serie de claves con las que podemos trabajar. La
clave 'descendientes' nos dice el número de comentarios que ha recibido el artículo u. La
clave 'niños' proporciona los ID de todos los comentarios realizados directamente en
respuesta a este envío v. Cada uno de estos comentarios también puede tener sus
propios comentarios, por lo que la cantidad de descendientes que tiene un envío suele
ser mayor que la cantidad de niños. Podemos ver el título del artículo que se está
discutiendo w, y una URL para el artículo que se está discutiendo también x.
La siguiente URL devuelve una lista simple de todos los ID de la parte superior actual
artículos en Hacker News:
https://hacker-news.firebaseio.com/v0/topstories.json
Podemos usar esta llamada para averiguar qué artículos están en la página de
inicio en este momento y luego generar una serie de llamadas API similares a la que
acabamos de examinar. Con este enfoque, podemos imprimir un resumen de todos los
artículos en la portada de Hacker News en este momento:
solicitudes de importación
Título: Pregúntele a HN: ¿Es práctico crear un modelo de cohete controlado por software?
Enlace de discusión: http://news.ycombinator.com/item?id=19180181
Comentarios: 72
374 Capítulo 17
Machine Translated by Google
Usaría un proceso similar para acceder y analizar información con cualquier API.
Con estos datos, puede hacer una visualización que muestre qué envíos han inspirado
las discusiones recientes más activas. Esta es también la base de las aplicaciones
que brindan una experiencia de lectura personalizada para sitios como Hacker News.
Para obtener más información sobre el tipo de información a la que puede acceder a
través de la API de Hacker News, visite la página de documentación en https:// github
.com/ HackerNews/ API/.
Inténtalo tú mismo
Resumen
En este capítulo, aprendió a usar las API para escribir programas independientes que
recopilan automáticamente los datos que necesitan y usan esos datos para crear una
visualización. Usó la API de GitHub para explorar los proyectos de Python con más
estrellas en GitHub y también examinó brevemente la API de Hacker News.
Aprendió a usar el paquete Requests para emitir automáticamente una llamada API a
GitHub y cómo procesar los resultados de esa llamada. También se introdujeron
algunas configuraciones de Plotly que personalizan aún más la apariencia de los
gráficos que genera.
En el próximo capítulo, utilizará Django para crear una aplicación web como
proyecto final.
Proyecto 3
Aplicaciones web
Machine Translated by Google
Machine Translated by Google
18
Primeros pasos con Django
Django puede responder a solicitudes de página y facilitar la lectura y escritura en una base
de datos, administrar usuarios y mucho más. En los Capítulos 19 y 20, refinará el proyecto Registro
de aprendizaje y luego lo implementará en un servidor en vivo para que usted (y sus amigos) puedan
usarlo.
Configuración de un proyecto
Al comenzar un proyecto, primero debe describir el proyecto en una especificación o especificación.
A continuación, configurará un entorno virtual en el que compilar el proyecto.
Una especificación completa detalla los objetivos del proyecto, describe la funcionalidad del
proyecto y analiza su apariencia e interfaz de usuario. Como cualquier buen proyecto o plan de
negocios, una especificación debe mantenerlo enfocado y ayudarlo a mantener su proyecto
encaminado. No escribiremos una especificación completa del proyecto aquí, pero presentaremos
algunos objetivos claros para mantener el proceso de desarrollo enfocado. Aquí está la especificación que usaremos:
Cuando aprende sobre un tema nuevo, llevar un diario de lo que ha aprendido puede ser
útil para rastrear y revisar la información. Una buena aplicación hace que este proceso sea eficiente.
Cree un nuevo directorio para su proyecto llamado learning_log, cambie a ese directorio
en una terminal e ingrese el siguiente código para crear un entorno virtual:
Aquí estamos ejecutando el módulo de entorno virtual venv y usándolo para crear un entorno
virtual llamado ll_env (tenga en cuenta que esto es ll_env con dos L minúsculas , no dos). Si usa
un comando como python3
cuando ejecute programas o instale paquetes, asegúrese de usar ese comando aquí.
380 Capítulo 18
Machine Translated by Google
(ll_env)learning_log$ desactivar
aprendizaje_log$
Instalando Django
Una vez activado el entorno virtual, ingrese lo siguiente para instalar
Django:
Debido a que estamos trabajando en un entorno virtual, que es su propio entorno autónomo,
este comando es el mismo en todos los sistemas. No hay necesidad de usar el indicador --user , y
no hay necesidad de usar comandos más largos, como python -m pip install nombre_paquete.
N ota Django lanza una nueva versión aproximadamente cada ocho meses, por lo que es posible que vea una
versión más nueva cuando instale Django. Lo más probable es que este proyecto funcione como
está escrito aquí, incluso en las versiones más nuevas de Django. Si quiere asegurarse de usar la
misma versión de Django que ve aquí, use el comando pip install django==2.2.*. Esto instalará la
última versión de Django 2.2. Si tiene algún problema relacionado con la versión que está utilizando,
consulte los recursos en línea para el libro en https://nostarch.com/pythoncrashcourse2e/.
N ota No olvide este punto, o puede encontrarse con algunos problemas de configuración cuando implemente
la aplicación. Si olvida el punto, elimine los archivos y carpetas que se crearon (excepto ll_env)
y ejecute el comando nuevamente.
Ejecutar el comando ls (dir en Windows) v muestra que Django ha creado un nuevo directorio
llamado learning_log. También creó un archivo manage.py , que es un programa corto que recibe
comandos y los alimenta a la parte relevante de Django para ejecutarlos. Usaremos estos comandos
para administrar tareas, como trabajar con bases de datos y ejecutar servidores.
382 Capítulo 18
Machine Translated by Google
Cada vez que modificamos una base de datos, decimos que estamos migrando la base de datos.
Emitir el comando de migración por primera vez le dice a Django que se asegure de que la base de datos
coincida con el estado actual del proyecto. La primera vez que ejecutamos este comando en un nuevo
proyecto usando SQLite (más sobre SQLite en un momento), Django creará una nueva base de datos para
nosotros. En u, Django informa que preparará la base de datos para almacenar la información que necesita
para manejar las tareas administrativas y de autenticación.
Ejecutar el comando ls muestra que Django creó otro archivo llamado db.sqlite3 v. SQLite es una base
de datos que se ejecuta en un solo archivo; es ideal para escribir aplicaciones sencillas porque no tendrá que
prestar mucha atención a la gestión de la base de datos.
N ota En un entorno virtual activo, use el comando python para ejecutar manage.py com
mands, incluso si usa algo diferente, como python3, para ejecutar otros programas. En un entorno virtual, el
comando python hace referencia a la versión de Python que creó el entorno virtual.
Ver el proyecto
Asegurémonos de que Django haya configurado el proyecto correctamente. Ingrese el comando
runserver de la siguiente manera para ver el proyecto en su estado actual:
Django debería iniciar un servidor llamado servidor de desarrollo, para que pueda ver el proyecto
en su sistema y ver qué tan bien funciona. Cuando solicita una página ingresando una URL en un
navegador, el servidor Django responde a esa solicitud creando la página adecuada y enviándola al
navegador.
En u, Django verifica para asegurarse de que el proyecto esté configurado correctamente; en v
informa la versión de Django en uso y el nombre del archivo de configuración en uso; y en w informa la
URL donde se está sirviendo el proyecto. La URL http:// 127.0.0.1:8000/ indica que el proyecto está
escuchando solicitudes en el puerto 8000 de su computadora, que se denomina host local. El término host
local se refiere a un servidor que solo procesa solicitudes en su sistema; no permite que nadie más vea las
páginas que está desarrollando.
N ota Si recibe el mensaje de error Ese puerto ya está en uso, dígale a Django que use un
puerto diferente ingresando python manage.py runserver 8001, y luego recorra los números más altos
hasta que encuentre un puerto abierto.
Inténtalo tú mismo
18-1. Nuevos proyectos: para tener una mejor idea de lo que hace Django, cree un
par de proyectos vacíos y observe lo que crea Django. Cree una nueva carpeta con un
nombre simple, como snap_gram o insta_chat (fuera de su directorio learning_log),
navegue hasta esa carpeta en una terminal y cree un entorno virtual.
Instale Django y ejecute el comando django-admin.py startproject snap_gram.
(asegúrese de incluir el punto al final del comando).
Mire los archivos y carpetas que crea este comando y compárelos con el registro
de aprendizaje. Haga esto varias veces hasta que esté familiarizado con lo que crea
Django al iniciar un nuevo proyecto. Luego elimine los directorios del proyecto si lo desea.
384 Capítulo 18
Machine Translated by Google
Definición de modelos
Pensemos en nuestros datos por un momento. Cada usuario deberá crear una serie de
temas en su registro de aprendizaje. Cada entrada que hagan estará vinculada a un tema, y
estas entradas se mostrarán como texto. También necesitaremos almacenar la marca de
tiempo de cada entrada, para que podamos mostrar a los usuarios cuándo hicieron cada
entrada.
Abra el archivo models.py y observe su contenido existente:
Se está importando un módulo llamado modelos y se nos invita a crear nuestros propios
modelos. Un modelo le dice a Django cómo trabajar con los datos que se almacenarán en la
aplicación. En cuanto al código, un modelo es solo una clase; tiene atributos y métodos, como
todas las clases que hemos discutido. Este es el modelo de los temas que almacenarán los
usuarios:
Hemos creado una clase llamada Tema, que hereda de Modelo, una clase principal incluida
en Django que define la funcionalidad básica de un modelo. Agregamos dos atributos a la clase
Topic : text y date_added.
El atributo de texto es un CharField, un dato compuesto por caracteres o texto u. Utiliza
CharField cuando desea almacenar una pequeña cantidad de texto, como un nombre, un título o
una ciudad. Cuando definimos un atributo CharField , debemos decirle a Django cuánto espacio
debe reservar en la base de datos. Aquí le damos una longitud máxima de 200 caracteres, que
debería ser suficiente para contener la mayoría de los nombres de temas.
N ota Para ver los diferentes tipos de campos que puede usar en un modelo, consulte la Referencia de
campo del modelo de Django en https://docs.djangoproject.com/en/2.2/ref/models
/los campos/. No necesitará toda la información en este momento, pero será extremadamente
útil cuando esté desarrollando sus propias aplicaciones.
Le decimos a Django qué atributo usar por defecto cuando muestra información sobre un
tema. Django llama a un método __str__() para mostrar una representación simple de un
modelo. Aquí hemos escrito un método __str__() que devuelve la cadena almacenada en el
atributo de texto w.
Activación de modelos
Para usar nuestros modelos, debemos decirle a Django que incluya nuestra aplicación en el
proyecto general. Abra settings.py (en el directorio learning_log/ learning_log ); verás una sección
que le dice a Django qué aplicaciones están instaladas y funcionan juntas en el proyecto:
configuración.py --recorte--
APLICACIONES_INSTALADAS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.archivos estáticos',
]
--recorte--
Agregue nuestra aplicación a esta lista modificando INSTALLED_APPS para que se vea así:
--recorte--
APLICACIONES_INSTALADAS = [
# Mis aplicaciones
'registro_de_aprendizaje',
'django.contrib.admin',
386 Capítulo 18
Machine Translated by Google
--recorte--
]
--recorte--
El comando makemigrations le dice a Django que descubra cómo modificar la base de datos
para que pueda almacenar los datos asociados con cualquier modelo nuevo que hayamos definido. El
resultado aquí muestra que Django ha creado un archivo de migración llamado 0001_initial.py. Esta
migración creará una tabla para el modelo Tema
en la base de datos
La mayor parte de la salida de este comando es idéntica a la primera vez que emitimos el
comando de migración . La línea que debemos verificar aparece en u, donde Django confirma que la
migración de learning_logs funcionó bien.
Siempre que queramos modificar los datos que maneja Learning Log, seguiremos estos tres pasos:
modificar models.py, llamar a makemigrations en learning_logs y decirle a Django que migre el proyecto.
Django facilita el trabajo con sus modelos a través del sitio de administración. Solo los administradores
del sitio usan el sitio de administración, no los usuarios generales. En esta sección, configuraremos el
sitio de administración y lo usaremos para agregar algunos temas a través del modelo de temas .
Configuración de un superusuario
Django le permite crear un superusuario, un usuario que tiene todos los privilegios disponibles en el
sitio. Los privilegios de un usuario controlan las acciones que el usuario puede realizar.
La configuración de privilegios más restrictiva permite que un usuario solo lea información pública
en el sitio. Los usuarios registrados suelen tener el privilegio de leer sus propios datos privados y
cierta información seleccionada disponible solo para los miembros. Para administrar de manera
efectiva una aplicación web, el propietario del sitio generalmente necesita acceso a toda la
información almacenada en el sitio. Un buen administrador tiene cuidado con la información
confidencial de sus usuarios, porque los usuarios confían mucho en las aplicaciones a las que
acceden.
Para crear un superusuario en Django, ingrese el siguiente comando y
responder a las indicaciones:
w Contraseña:
Contraseña de nuevo):
Superusuario creado con éxito.
(ll_env)registro_de_aprendizaje$
N ota Cierta información confidencial se puede ocultar a los administradores de un sitio. Por ejemplo, Django no
almacena la contraseña que ingresa; en su lugar, almacena una cadena derivada de la contraseña,
llamada hash. Cada vez que ingresa su contraseña, Django procesa su entrada y la compara con el
hash almacenado. Si los dos hashes coinciden, estás autenticado. Al exigir que los hashes coincidan,
si un atacante obtiene acceso a la base de datos de un sitio, podrá leer los hashes almacenados,
pero no las contraseñas. Cuando un sitio está configurado correctamente, es casi imposible obtener
las contraseñas originales de los hashes.
v admin.site.register(Tema)
388 Capítulo 18
Machine Translated by Google
Este código primero importa el modelo que queremos registrar, Tema u. El punto delante
de models le dice a Django que busque models.py en el mismo directorio que admin.py. El código
admin.site.register() le dice a Django que administre nuestro modelo a través del sitio de
administración v.
Ahora use la cuenta de superusuario para acceder al sitio de administración. Ir a http://
localhost:8000/ admin/, e ingrese el nombre de usuario y la contraseña del superusuario que
acaba de crear. Debería ver una pantalla como la de la Figura 18-2.
Esta página le permite agregar nuevos usuarios y grupos, y cambiar los existentes. También
puede trabajar con datos relacionados con el modelo de tema que acabamos de definir.
N ota Si ve un mensaje en su navegador que indica que la página web no está disponible, asegúrese de que
todavía tiene el servidor Django ejecutándose en una ventana de terminal. Si no lo hace, active un
entorno virtual y vuelva a emitir el comando python manage.py runserver. Si tiene problemas para
ver su proyecto en cualquier punto del proceso de desarrollo, cerrar cualquier terminal abierta y
volver a ejecutar el comando runserver es un buen primer paso para solucionar el problema.
Agregar temas
Para que un usuario registre lo que ha estado aprendiendo sobre ajedrez y escalada en roca,
necesitamos definir un modelo para los tipos de entradas que los usuarios pueden hacer en sus
registros de aprendizaje. Cada entrada debe estar asociada con un tema en particular. Esta
relación se denomina relación de muchos a uno, lo que significa que muchas entradas se pueden
asociar con un tema.
Aquí está el código para el modelo Entry . Colóquelo en su archivo models.py :
Metaclase x:
verbose_name_plural = 'entradas'
La clase Entry hereda de la clase Model base de Django , al igual que Topic
lo hiciste. El primer atributo, tema, es una instancia de ForeignKey v. Una clave externa es un
término de base de datos; es una referencia a otro registro en la base de datos. Este es el código
que conecta cada entrada a un tema específico. A cada tema se le asigna una clave, o ID, cuando
se crea. Cuando Django necesita establecer una conexión entre dos datos, utiliza la clave asociada
con cada dato. Usaremos estas conexiones en breve para recuperar todas las entradas asociadas
con un tema determinado. El argumento on_delete=models.CASCADE le dice a Django que cuando
se elimina un tema, todas las entradas asociadas con ese tema también deben eliminarse. Esto se
conoce como eliminación en cascada.
En x anidamos la clase Meta dentro de nuestra clase Entry . La clase Meta contiene
información adicional para administrar un modelo; aquí, nos permite establecer un atributo
especial que le dice a Django que use Entradas cuando necesita referirse a más de una entrada.
Sin esto, Django se referiría a múltiples entradas como Entradas.
El método __str__() le dice a Django qué información mostrar cuando
se refiere a entradas individuales. Debido a que una entrada puede ser un cuerpo largo de
texto, le decimos a Django que muestre solo los primeros 50 caracteres del texto y. También
agregamos puntos suspensivos para aclarar que no siempre mostramos la entrada completa.
390 Capítulo 18
Machine Translated by Google
Debido a que agregamos un nuevo modelo, necesitamos migrar la base de datos nuevamente.
Este proceso se volverá bastante familiar: modifica models.py, ejecuta el comando python
manage.py makemigrations app_name y luego ejecuta el comando python manage.py migrate.
También necesitamos registrar el modelo Entry . Así es como debería verse admin.py ahora:
admin.site.register(Tema)
admin.sitio.registrar(Entrada)
Por supuesto, estas son solo pautas. Será importante saber cuándo seguir
estas pautas y cuándo ignorar estas sugerencias.
Cuando haga clic en Guardar, volverá a la página de administración principal para las
entradas. Aquí, verá el beneficio de usar text[:50] como la representación de cadena para cada
entrada; es mucho más fácil trabajar con varias entradas en la interfaz de administración si solo ve
la primera parte de una entrada en lugar del texto completo de cada entrada.
Haga una segunda entrada para Ajedrez y una entrada para Escalada en roca para que
tengamos algunos datos iniciales. Aquí hay una segunda entrada para Ajedrez:
Estas tres entradas nos darán algo con qué trabajar mientras continuamos
para desarrollar el Registro de aprendizaje.
La concha de Django
Con algunos datos ingresados, podemos examinar esos datos mediante programación a
través de una sesión de terminal interactiva. Este entorno interactivo se denomina shell de
Django y es un excelente entorno para probar y solucionar problemas de su proyecto. Aquí hay
un ejemplo de una sesión de shell interactiva:
392 Capítulo 18
Machine Translated by Google
...
1 ajedrez
2 escalada en roca
>>> t = Tema.objetos.get(id=1)
>>> t.texto
'Ajedrez'
>>> t.fecha_añadida
fechahora.fechahora(2019, 2, 19, 1, 55, 31, 98500, tzinfo=<UTC>)
También podemos mirar las entradas relacionadas con un tema determinado. Anteriormente
definimos el atributo de tema para el modelo de entrada . Era una ForeignKey, una conexión entre cada
entrada y un tema. Django puede usar esta conexión para obtener cada entrada relacionada con un tema
determinado, como este:
u >>> t.entry_set.all()
<QuerySet [<Entrada: La apertura es la primera parte del juego, más o menos...>, <Entrada:
Para obtener datos a través de una relación de clave externa, utilice el nombre en minúsculas
del modelo relacionado seguido de un guión bajo y la palabra conjunto u.
Por ejemplo, suponga que tiene los modelos Pizza y Topping, y Topping está relacionado con Pizza a través
de una clave externa. Si su objeto se llama my_pizza y representa una sola pizza, puede obtener todos los
ingredientes de la pizza usando el código my_pizza
.topping_set.all().
Usaremos este tipo de sintaxis cuando comencemos a codificar las páginas que los usuarios
pueden solicitar. El shell es muy útil para asegurarse de que su código recupere los datos que desea. Si su
código funciona como espera en el shell, puede esperar que funcione correctamente en los archivos dentro
de su proyecto. Si su código genera errores o no recupera los datos que esperaba, es mucho más fácil
solucionar los problemas de su código en el entorno de shell simple que dentro de los archivos que generan
páginas web. No nos referiremos mucho al shell, pero debe continuar usándolo para practicar el trabajo
con la sintaxis de Django para acceder a los datos almacenados en el proyecto.
N ota Cada vez que modifique sus modelos, deberá reiniciar el shell para ver los efectos de esos
cambios. Para salir de una sesión de shell, presione ctrl-D; en Windows, presione ctrl-Z
y luego presione enter.
Inténtalo tú mismo
18-2. Entradas cortas: el método __str__() en el modelo Entry actualmente agrega puntos
suspensivos a cada instancia de Entry cuando Django lo muestra en el sitio de administración o en
el shell. Agregue una instrucción if al método __str__() que agregue puntos suspensivos solo si la
entrada tiene más de 50 caracteres. Use el sitio de administración para agregar una entrada que
tenga menos de 50 caracteres y verifique que no tenga puntos suspensivos cuando se visualice.
18-3. La API de Django: cuando escribe código para acceder a los datos de su proyecto, está
escribiendo una consulta. Lea la documentación para consultar sus datos en https://
docs.djangoproject.com/en/2.2/topics/db/queries/. Gran parte de lo que vea le parecerá nuevo, pero
le resultará muy útil cuando empiece a trabajar en sus propios proyectos.
18-4. Pizzería: Comience un nuevo proyecto llamado pizzería con una aplicación llamada pizzas.
Defina un modelo Pizza con un campo denominado nombre, que contendrá valores de
nombre, como Hawaiian y Meat Lovers. Defina un modelo llamado Cobertura con campos
llamados pizza y nombre. El campo pizza debe ser una clave externa para Pizza, y el nombre
debe poder contener valores como piña, tocino canadiense y
embutido.
Registre ambos modelos con el sitio de administración y use el sitio para ingresar algunos
nombres de pizza y coberturas. Use el shell para explorar los datos que ingresó.
La creación de páginas web con Django consta de tres etapas: definición de URL, escritura de
vistas y escritura de plantillas. Puede hacerlo en cualquier orden, pero en este proyecto siempre
comenzaremos definiendo el patrón de URL. Un patrón de URL describe la forma en que se
presenta la URL. También le dice a Django qué buscar cuando hace coincidir una solicitud del
navegador con la URL de un sitio para que sepa qué página devolver.
Luego, cada URL se asigna a una vista particular: la función de vista recupera y procesa los
datos necesarios para esa página. La función de vista a menudo representa la página utilizando
una plantilla, que contiene la estructura general de la página. Para ver cómo funciona esto,
hagamos la página de inicio para el Registro de aprendizaje.
Definiremos la URL para la página de inicio, escribiremos su función de vista y crearemos una
plantilla simple.
Debido a que todo lo que estamos haciendo es asegurarnos de que el Registro de
aprendizaje funcione como se supone, crearemos una página simple por ahora. Es divertido
diseñar una aplicación web en funcionamiento cuando está completa; una aplicación que se ve
bien pero no funciona bien no tiene sentido. Por ahora, la página de inicio mostrará solo un título
y una breve descripción.
394 Capítulo 18
Machine Translated by Google
Los usuarios solicitan páginas ingresando URL en un navegador y haciendo clic en enlaces, por
lo que debemos decidir qué URL se necesitan. La URL de la página de inicio es la primera: es la
URL base que la gente usa para acceder al proyecto. Por el momento, la URL base, http://
localhost:8000/, devuelve el sitio Django predeterminado que nos permite saber que el proyecto se
configuró correctamente. Cambiaremos esto asignando la URL base a la página de inicio de
Learning Log.
En la carpeta principal del proyecto learning_log , abra el archivo urls.py. Aquí está el código
que deberías ver:
v urlpatrones = [
w ruta('admin/', admin.sitio.urls),
]
Las primeras dos líneas importan un módulo y una función para administrar las URL para
el sitio de administración u. El cuerpo del archivo define la variable urlpatterns v.
En este archivo urls.py , que representa el proyecto como un todo, los urlpatterns
La variable incluye conjuntos de direcciones URL de las aplicaciones del proyecto. El código en w
incluye el módulo admin.site.urls, que define todas las URL que se pueden solicitar desde el sitio
de administración.
Necesitamos incluir las URL para learning_logs, así que agregue lo siguiente:
patrones de URL = [
ruta('admin/', admin.sitio.urls),
u ruta('', include('registro_de_aprendizaje.urls')),
]
w de . importar vistas
x app_name = 'registro_de_aprendizaje'
y patrones de URL = [
# Página de inicio
z ruta('', vistas.índice, nombre='índice'),
]
Para dejar claro en qué urls.py estamos trabajando, agregamos una cadena de documentación
al comienzo del archivo u. Luego importamos la función de ruta , que es necesaria cuando se asignan
URL a vistas v. También importamos el módulo de vistas w; el punto le dice a Python que importe el
módulo views.py desde el mismo directorio que el módulo urls.py actual . La variable app_name ayuda
a Django a distinguir este archivo urls.py de archivos con el mismo nombre en otras aplicaciones
dentro del proyecto x. La variable urlpatterns en este módulo es una lista de páginas individuales que
se pueden solicitar desde la aplicación learning_logs y.
El patrón de URL real es una llamada a la función path() , que toma tres argumentos z. El
primer argumento es una cadena que ayuda a Django a enrutar correctamente la solicitud actual.
Django recibe la URL solicitada e intenta enrutar la solicitud a una vista. Para ello, busca en todos
los patrones de URL que hemos definido para encontrar uno que coincida con la solicitud actual.
Django ignora la URL base del proyecto (http:// localhost:8000/), por lo que la cadena vacía ('') coincide
con la URL base. Cualquier otra URL no coincidirá con este patrón y Django devolverá una página de
error si la URL solicitada no coincide con ningún patrón de URL existente.
El segundo argumento en path() z especifica qué función llamar en views.py. Cuando una
URL solicitada coincide con el patrón que estamos definiendo, Django llama a la función index()
desde views.py (escribiremos esta función de vista en la siguiente sección). El tercer argumento
proporciona el índice de nombres para este patrón de URL para que podamos consultarlo en otras
secciones de código. Siempre que queramos proporcionar un enlace a la página de inicio, usaremos
este nombre en lugar de escribir una URL.
Actualmente, este archivo solo importa la función render() , que genera la respuesta en función
de los datos proporcionados por las vistas. Abra el archivo de vistas y agregue el siguiente código
para la página de inicio:
Cuando una solicitud de URL coincide con el patrón que acabamos de definir, Django busca
para una función llamada index() en el archivo views.py . Django luego pasa el
396 Capítulo 18
Machine Translated by Google
solicitud de objeto a esta función de vista. En este caso, no necesitamos procesar ningún dato para la página,
por lo que el único código en la función es una llamada a render().
La función render() aquí pasa dos argumentos: la solicitud original
objeto y una plantilla que puede usar para construir la página. Escribamos esta plantilla.
<p>El registro de aprendizaje lo ayuda a realizar un seguimiento de su aprendizaje, para cualquier tema que esté
aprendiendo sobre.</p>
Aunque puede parecer un proceso complicado para crear una página, esta separación
entre URL, vistas y plantillas funciona bastante bien.
Le permite pensar en cada aspecto de un proyecto por separado. En proyectos más
grandes, permite que las personas que trabajan en el proyecto se concentren en las áreas
en las que son más fuertes. Por ejemplo, un especialista en bases de datos puede enfocarse
en los modelos, un programador puede enfocarse en el código de vista y un diseñador web
puede enfocarse en las plantillas.
Inténtalo tú mismo
18-5. Planificador de comidas: considere una aplicación que ayude a las personas a planificar sus
comidas durante la semana. Cree una nueva carpeta llamada meal_planner e inicie un nuevo proyecto
de Django dentro de esta carpeta. Luego crea una nueva aplicación llamada Meal_plans. Haga una
página de inicio simple para este proyecto.
18-6. Página de inicio de pizzería: agregue una página de inicio al proyecto de pizzería que
comenzó en el ejercicio 18-4 (página 394).
Herencia de plantilla
Al crear un sitio web, algunos elementos siempre deberán repetirse en cada página. En lugar
de escribir estos elementos directamente en cada página, puede escribir una plantilla base que
contenga los elementos repetidos y luego hacer que cada página herede de la base. Este
enfoque le permite concentrarse en desarrollar los aspectos únicos de cada página y hace que
sea mucho más fácil cambiar la apariencia general del proyecto.
398 Capítulo 18
Machine Translated by Google
La plantilla principal
base.html <p>
u <a href="{% url 'learning_logs:index' %}">Registro de aprendizaje</a>
</p>
La primera parte de este archivo crea un párrafo que contiene el nombre del proyecto,
que también actúa como un enlace a la página de inicio. Para generar un enlace, usamos una
etiqueta de plantilla, que se indica mediante llaves y signos de porcentaje {% %}. Una etiqueta
de plantilla genera información que se mostrará en una página. Nuestra etiqueta de plantilla {%
url 'learning_logs:index' %} genera una URL que coincide con el patrón de URL definido en
learning_logs/ urls.py con el nombre 'index' u. En este ejemplo, learning_logs es el espacio de
nombres y el índice es un patrón de URL con un nombre único en ese espacio de nombres. El
espacio de nombres proviene del valor que asignamos a app_name en el archivo learning_logs/
urls.py .
En una página HTML simple, un enlace está rodeado por la etiqueta de anclaje <a>:
Hacer que la etiqueta de la plantilla genere la URL para nosotros lo hace mucho más fácil
para mantener nuestros enlaces actualizados. Solo necesitamos cambiar el patrón de URL
en urls.py, y Django insertará automáticamente la URL actualizada la próxima vez que se
solicite la página. Cada página de nuestro proyecto heredará de base.html, por lo que a partir
de ahora, cada página tendrá un enlace a la página de inicio.
En v insertamos un par de etiquetas de bloque . Este bloque, denominado contenido, es
un marcador de posición; la plantilla secundaria definirá el tipo de información que va en el
bloque de contenido .
Una plantilla secundaria no tiene que definir cada bloque de su principal, por lo que
puede reservar espacio en las plantillas principales para tantos bloques como desee; la plantilla
secundaria usa solo los que necesita.
N ota En el código de Python, casi siempre usamos cuatro espacios cuando aplicamos sangría. Los archivos de
plantilla tienden a tener más niveles de anidamiento que los archivos de Python, por lo que es común
usar solo dos espacios para cada nivel de sangría. Solo necesitas asegurarte de ser consistente.
La plantilla infantil
Ahora necesitamos reescribir index.html para heredar de base.html. Agregue el siguiente
código a index.html:
<p>El registro de aprendizaje lo ayuda a realizar un seguimiento de su aprendizaje, para cualquier tema sobre
el que esté aprendiendo.</p>
w {% contenido de bloque final %}
Si compara esto con el index.html original, puede ver que hemos reemplazado el título del
Registro de aprendizaje con el código para heredar de una plantilla principal u. Una plantilla secundaria
debe tener una etiqueta {% extends %} en la primera línea para decirle a Django de qué plantilla principal
debe heredar. El archivo base.html
es parte de learning_logs, por lo que incluimos learning_logs en la ruta a la plantilla principal. Esta
línea extrae todo lo contenido en la plantilla base.html y permite que index.html defina lo que va en el
espacio reservado por el bloque de contenido .
N ota En un proyecto grande, es común tener una plantilla principal llamada base.html para
todo el sitio y plantillas principales para cada sección principal del sitio. Todas las plantillas de sección
heredan de base.html, y cada página del sitio hereda de una plantilla de sección. De esta manera,
puede modificar fácilmente la apariencia del sitio como un todo, cualquier sección del sitio o cualquier
página individual. Esta configuración proporciona una manera muy eficiente de trabajar y lo alienta a
actualizar constantemente su sitio a lo largo del tiempo.
La página de temas
Ahora que tenemos un enfoque eficiente para crear páginas, podemos centrarnos en las siguientes dos
páginas: la página de temas generales y la página para mostrar las entradas de un solo tema. La página
de temas mostrará todos los temas que los usuarios han creado y es la primera página que implicará
trabajar con datos.
Primero, definimos la URL para la página de temas. Es común elegir un fragmento de URL simple que
refleje el tipo de información presentada en la página.
400 Capítulo 18
Machine Translated by Google
Usaremos la palabra temas, por lo que la URL http:// localhost:8000/ topics/ devolverá esta página.
Así es como modificamos learning_logs/ urls.py:
en vistas.py.
La vista de temas
Primero importamos el modelo asociado con los datos que necesitamos. La función
topics() necesita un parámetro: el objeto de solicitud que Django recibió del servidor v. En w
consultamos la base de datos solicitando los objetos Topic , ordenados por el atributo date_added .
Almacenamos el conjunto de consultas resultante en temas.
En x definimos un contexto que enviaremos a la plantilla. Un contexto es un diccionario en
el que las claves son nombres que usaremos en la plantilla para acceder a los datos y los
valores son los datos que necesitamos enviar a la plantilla. En este caso, hay un par clave-valor,
que contiene el conjunto de temas que mostraremos en la página. Al crear una página que utiliza
datos, pasamos la variable de contexto a render() , así como el objeto de solicitud y la ruta a la
plantilla y.
La plantilla de temas
La plantilla para la página de temas recibe el diccionario de contexto , por lo que la plantilla
puede usar los datos que proporciona themes() . Crea un archivo llamado themes.html en el
mismo directorio que index.html. Así es como podemos mostrar los temas en la plantilla:
<p>Temas</p>
tu <ul>
v {% para tema en temas %}
<li> {{tema}} </li>
wx {% vacío %}
<li>Todavía no se han agregado temas.</li>
y {% endfor%}
z</ul>
Dentro del bucle, queremos convertir cada tema en un elemento de la lista con viñetas.
lista. Para imprimir una variable en una plantilla, envuelva el nombre de la variable entre
llaves dobles. Las llaves no aparecerán en la página; simplemente le indican a Django que
estamos usando una variable de plantilla. Entonces, el código {{ topic }} en w será
reemplazado por el valor de topic en cada pasada por el ciclo. La etiqueta HTML <li></li>
indica un elemento de lista. Todo lo que se encuentre entre estas etiquetas, dentro de un par
de etiquetas <ul></ul> , aparecerá como un elemento con viñetas en la lista.
En x usamos la etiqueta de plantilla {% vacío %} , que le dice a Django qué hacer si no
hay elementos en la lista. En este caso, imprimimos un mensaje informando al usuario que
aún no se han agregado temas. Las últimas dos líneas cierran el bucle for y y luego cierran
la lista con viñetas z.
402 Capítulo 18
Machine Translated by Google
Ahora necesitamos modificar la plantilla base para incluir un enlace a la página superior de ics.
Agrega el siguiente código a base.html:
base.html <p>
u <a href="{% url 'learning_logs:index' %}">Registro de aprendizaje</a> -
v <a href="{% url 'learning_logs:topics' %}">Temas</a>
</p>
Agregamos un guión después del enlace a la página de inicio u, y luego agregamos un enlace
a la página de temas usando la etiqueta de plantilla {% url %} nuevamente v. Esta línea le dice a Django
que genere un enlace que coincida con el patrón de URL con el nombre ' temas' en learning_logs/ urls.py.
Ahora, cuando actualice la página de inicio en su navegador, verá un vínculo Temas . Cuando
haga clic en el enlace, verá una página similar a la Figura 18-4.
A continuación, debemos crear una página que pueda centrarse en un solo tema, que muestre el nombre del
tema y todas las entradas de ese tema. Definiremos nuevamente un nuevo patrón de URL, escribiremos una
vista y crearemos una plantilla. También modificaremos la página de temas para que cada elemento de la
lista con viñetas se vincule a su página de tema correspondiente.
El patrón de URL para la página del tema es un poco diferente a los patrones de URL anteriores porque
usará el atributo id del tema para indicar qué tema se solicitó. Por ejemplo, si el usuario desea ver la página
de detalles del tema Ajedrez, donde la identificación es 1, la URL será http:// localhost:8000/ topics/ 1/.
Aquí hay un patrón para que coincida con esta URL, que debe colocar en el aprendizaje
_logs/ urls.py:
urls.py --recorte--
patrones de URL = [
--snip-- #
Página de detalles para un solo tema.
ruta('temas/<int:id_tema>/', vistas.tema, nombre='tema'),
]
La vista de tema
La función topic() necesita obtener el tema y todas las entradas asociadas de la base de datos,
como se muestra aquí:
vistas.py --recorte--
u def tema (solicitud, topic_id):
"""Mostrar un solo tema y todas sus entradas."""
v tema = Tema.objetos.get(id=id_tema)
w entradas = topic.entry_set.order_by('-date_added')
x contexto = {'tema': tema, 'entradas': entradas}
y return render(solicitud, 'learning_logs/topic.html', context)
Esta es la primera función de vista que requiere un parámetro que no sea el objeto de
solicitud . La función acepta el valor capturado por la expresión /<int:topic_id>/ y lo almacena en
topic_id u. En v usamos get() para recuperar el tema, tal como lo hicimos en el shell de Django.
En w obtenemos las entradas asociadas con este tema y las ordenamos de acuerdo con la
fecha_añadida. El signo menos delante de date_added ordena los resultados en orden inverso, lo
que mostrará primero las entradas más recientes. Almacenamos el tema y las entradas en el
diccionario de contexto x y enviamos el contexto a la plantilla topic.html y.
N ota Las frases de código en vyw se denominan consultas , porque consultan la base de datos para obtener
información específica. Cuando escribe consultas como estas en sus propios proyectos, es útil
probarlas primero en el shell de Django. Obtendrá comentarios mucho más rápidos en el shell que
escribiendo una vista y una plantilla, y luego verificando los resultados en un navegador.
La plantilla de tema
La plantilla debe mostrar el nombre del tema y las entradas. También debemos informar al
usuario si aún no se han realizado entradas para este tema.
404 Capítulo 18
Machine Translated by Google
<p>Entradas:</p>
v <ul>
w {% para entrada en entradas %}
<li>
xy <p>{{ entrada.fecha_añadida|fecha:'M d, YH:i' }}</p>
<p>{{ entrada.texto|saltos de línea}}</p>
</li>
z {% vacío %}
<li>Todavía no hay entradas para este tema.</li>
{% que antes %}
</ul>
Extendemos base.html, como lo hacemos con todas las páginas del proyecto. A continuación,
mostramos el tema que se está mostrando actualmente, que se almacena en la variable de plantilla
{{ topic }}. La variable topic está disponible porque está incluida en el diccionario de contexto . Luego
comenzamos una lista con viñetas para mostrar cada una de las entradas v y las repasamos como
hicimos con los temas anteriores w.
Cada viñeta enumera dos piezas de información: la marca de tiempo y el texto completo de
cada entrada. Para la marca de tiempo x, mostramos el valor del atributo date_added. En las
plantillas de Django, una línea vertical (|) representa un filtro de plantilla, una función que modifica
el valor en una variable de plantilla.
La fecha del filtro :'M d, YH:i' muestra marcas de tiempo en el formato 1 de enero de 2018 23:00.
La siguiente línea muestra el valor completo del texto en lugar de solo los primeros 50 caracteres de la
entrada. El filtro saltos de línea y garantiza que las entradas de texto largo incluyan saltos de línea en
un formato comprensible para los navegadores en lugar de mostrar un bloque de texto ininterrumpido.
En z usamos la etiqueta de plantilla {% vacío %} para imprimir un mensaje que informa al usuario que no
se han realizado entradas.
Antes de mirar la página del tema en un navegador, debemos modificar la plantilla de temas para que
cada tema se vincule a la página adecuada. Este es el cambio que debe realizar en topics.html:
temas.html --recorte--
{% por tema en temas %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ tema }}</a>
</li>
{% vacío %}
--recorte--
N ota Existe una diferencia sutil pero importante entre topic.id y topic_id. La expresión topic.id
examina un tema y recupera el valor del ID correspondiente. La variable topic_id es una
referencia a esa ID en el código. Si encuentra errores al trabajar con ID, asegúrese de
usar estas expresiones de la manera adecuada.
Figura 18-5: La página de detalles de un solo tema, que muestra todas las entradas de un tema
Inténtalo tú mismo
18-8. Pizzeria Pages: Agregue una página al proyecto Pizzeria del Ejercicio 18-6 (página
398) que muestre los nombres de las pizzas disponibles. Luego vincule cada nombre de pizza
a una página que muestre los ingredientes de la pizza. Asegúrese de utilizar la herencia de
plantillas para crear sus páginas de manera eficiente.
406 Capítulo 18
Machine Translated by Google
Resumen
En este capítulo, aprendió a crear aplicaciones web simples utilizando el marco Django.
Escribió una breve especificación del proyecto, instaló Django en un entorno virtual,
configuró un proyecto y verificó que el proyecto se configuró correctamente. Configuró una
aplicación y definió modelos para representar los datos de su aplicación. Aprendió sobre las
bases de datos y cómo Django lo ayuda a migrar su base de datos después de realizar un
cambio en sus modelos. Creó un superusuario para el sitio de administración y usó el sitio
de administración para ingresar algunos datos iniciales.
También exploró el shell de Django, que le permite trabajar con los datos de su
proyecto en una sesión de terminal. Aprendió a definir direcciones URL, crear funciones de
visualización y escribir plantillas para crear páginas para su sitio. También utilizó la herencia
de plantillas para simplificar la estructura de las plantillas individuales y facilitar la modificación
del sitio a medida que evoluciona el proyecto.
En el Capítulo 19, creará páginas intuitivas y fáciles de usar que permitan a los
usuarios agregar nuevos temas y entradas y editar entradas existentes sin pasar por el
sitio de administración. También agregará un sistema de registro de usuarios, lo que
permitirá a los usuarios crear una cuenta y hacer su propio registro de aprendizaje. Este es
el corazón de una aplicación web: la capacidad de crear algo con lo que cualquier número
de usuarios puede interactuar.
19
Cuentas de usuario
Antes de construir un sistema de autenticación para crear cuentas, primero agregaremos algunas páginas que
permitan a los usuarios ingresar sus propios datos. Daremos a los usuarios la posibilidad de agregar un nuevo
tema, agregar una nueva entrada y editar sus entradas anteriores.
Actualmente, solo un superusuario puede ingresar datos a través del sitio de administración. No queremos
que los usuarios interactúen con el sitio de administración, por lo que usaremos las herramientas de creación
de formularios de Django para crear páginas que permitan a los usuarios ingresar datos.
Comencemos por permitir que los usuarios agreguen un nuevo tema. Agregar una página basada en formularios
funciona de la misma manera que las páginas que ya hemos creado: definimos una URL, escribimos una
función de vista y escribimos una plantilla. La principal diferencia es la adición de un nuevo módulo llamado
formularios.py, que contendrá los formularios.
Cualquier página que permita a un usuario ingresar y enviar información en una página web es un formulario,
incluso si no lo parece. Cuando los usuarios ingresan información, debemos validar que la información
proporcionada es el tipo correcto de datos y no es malicioso, como un código para interrumpir nuestro servidor.
Luego necesitamos procesar y guardar información válida en el lugar apropiado en la base de datos. Django auto
acopla gran parte de este trabajo.
u class TopicForm(formularios.ModelForm):
metaclase:
modelo = Tema
volvo campos = ['texto']
X etiquetas = {'texto': ''}
Tema. En u definimos una clase llamada TopicForm, que hereda de los formularios
.ModelForm.
La versión más simple de ModelForm consiste en una clase Meta anidada que le dice a Django en
qué modelo basar el formulario y qué campos incluir en el formulario. En v construimos un formulario a partir
del modelo Topic e incluimos solo el campo de texto w. El código en x le dice a Django que no genere una
etiqueta para el texto
campo.
410 Capítulo 19
Machine Translated by Google
La URL de una nueva página debe ser breve y descriptiva. Cuando el usuario quiera
agregar un nuevo tema, lo enviaremos a http:// localhost:8000/ new_topic/.
Aquí está el patrón de URL para la página new_topic , que agrega al aprendizaje
_logs/ urls.py:
urls.py --recorte--
patrones de URL = [
--recorte--
# Página para agregar un nuevo tema
ruta('nuevo_tema/', vistas.nuevo_tema, nombre='nuevo_tema'),
]
La función de vista
new_topic() La función new_topic() necesita manejar dos situaciones diferentes:
solicitudes iniciales para la página new_topic (en cuyo caso debería mostrar un
formulario en blanco) y el procesamiento de cualquier dato enviado en el formulario.
Una vez que se procesan los datos de un formulario enviado, es necesario redirigir al usuario a los tema
página:
--recorte--
def nuevo_tema(solicitud):
"""Agregar un nuevo tema."""
u if solicitud.método != 'POST':
# No se enviaron datos; crear un formulario en blanco.
en formulario = TopicForm()
demás:
Los dos tipos principales de solicitud que usará al crear aplicaciones web son las solicitudes
GET y las solicitudes POST. Utiliza solicitudes GET para páginas que solo leen datos del
servidor. Por lo general, utiliza solicitudes POST cuando el usuario necesita enviar información
a través de un formulario. Especificaremos el método POST para procesar todos nuestros
formularios. (Existen algunos otros tipos de solicitudes, pero no las usaremos en este proyecto).
La plantilla new_topic
Ahora crearemos una nueva plantilla llamada new_topic.html para mostrar el formulario que
acabamos de crear.
412 Capítulo 19
Machine Translated by Google
Esta plantilla amplía base.html, por lo que tiene la misma estructura base que el resto de las
páginas del Registro de aprendizaje. En u definimos un formulario HTML.
El argumento de acción le dice al navegador dónde enviar los datos enviados en el formulario; en este
caso, lo enviamos de vuelta a la función de vista new_topic().
El argumento del método le dice al navegador que envíe los datos como una solicitud POST.
Django usa la etiqueta de plantilla {% csrf_token %} v para evitar que los atacantes usen el
formulario para obtener acceso no autorizado al servidor (este tipo de ataque se denomina falsificación
de solicitud entre sitios). En w mostramos el formulario; aquí puedes ver lo simple que Django puede
hacer ciertas tareas, como mostrar un formulario. Solo necesitamos incluir la variable de plantilla
{{ form.as_p }} para que Django cree todos los campos necesarios para mostrar el formulario
automáticamente.
El modificador as_p le dice a Django que represente todos los elementos del formulario en formato
de párrafo, como una forma sencilla de mostrar el formulario de forma ordenada.
Django no crea un botón de envío para formularios, así que definimos uno en x.
<p>Temas</p>
<ul>
--recorte--
</ul>
Ahora que el usuario puede agregar un nuevo tema, también querrá agregar nuevas entradas.
Definiremos nuevamente una URL, escribiremos una función de vista y una plantilla, y
vincularemos a la página. Pero primero, agregaremos otra clase a forms.py.
Necesitamos crear un formulario asociado con el modelo Entry pero esta vez con un poco más
de personalización que TopicForm:
clase TopicForm(formularios.ModelForm):
--recorte--
clase EntryForm(formularios.ModelForm):
metaclase:
modelo = Entrada
campos = ['texto']
etiquetas = {'texto': 'Entrada:'}
ultravioleta
widgets = {'texto': formularios.Textarea(attrs={'cols': 80})}
414 Capítulo 19
Machine Translated by Google
el widget de entrada para el campo 'texto', por lo que el área de texto tendrá 80 columnas de ancho en lugar de las 40
predeterminadas. Esto brinda a los usuarios suficiente espacio para escribir una entrada significativa.
Las nuevas entradas deben estar asociadas con un tema en particular, por lo que debemos incluir un argumento
topic_id en la URL para agregar una nueva entrada. Aquí está la URL, que agrega a learning_logs/ urls.py:
urls.py --recorte--
patrones de URL = [
--recorte--
# Página para agregar una nueva entrada
ruta('nueva_entrada/<int:topic_id>/', vistas.nueva_entrada, nombre='nueva_entrada'),
]
Este patrón de URL coincide con cualquier URL con el formulario http://localhost:
8000/nueva_entrada/id/, donde id es un número que coincide con el ID del tema. El código <int:topic_id>
captura un valor numérico y lo asigna a la variable topic_id. Cuando se solicita una URL que coincida
con este patrón, Django envía la solicitud y el ID del tema a la función de vista new_entry() .
La función de vista para new_entry es muy parecida a la función para agregar un nuevo tema. Agrega el siguiente
código a tu archivo views.py :
--recorte--
def nueva_entrada(solicitud, topic_id):
"""Agregar una nueva entrada para un tema en particular."""
u tema = Tema.objetos.get(id=topic_id)
v if solicitud.método != 'POST':
# No se enviaron datos; crear un formulario en blanco.
en formulario = FormularioEntrada()
demás:
Actualizamos la declaración de importación para incluir el formulario de entrada que acabamos de hacer.
La definición de new_entry() tiene un parámetro topic_id para almacenar el valor que recibe
de la URL. Necesitaremos el tema para representar la página y procesar los datos del
formulario, por lo que usamos topic_id para obtener el objeto de tema correcto en usted.
En v comprobamos si el método de solicitud es POST o GET. El bloque if se
ejecuta si es una solicitud GET y creamos una instancia en blanco de EntryForm w.
La plantilla new_entry
Como puede ver en el siguiente código, la plantilla para new_entry es similar a la plantilla
para new_topic:
Mostramos el tema en la parte superior de la página u, para que el usuario pueda ver
a qué tema está agregando una entrada. El tema también actúa como un enlace a la
página principal de ese tema.
416 Capítulo 19
Machine Translated by Google
El argumento de acción del formulario incluye el valor topic_id en la URL, por lo que la
función de vista puede asociar la nueva entrada con el tema correcto v.
Aparte de eso, esta plantilla se parece a new_topic.html.
<p>Entradas:</p>
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">Agregar nueva entrada</a>
</p>
<ul>
--recorte-
</ul>
Colocamos el enlace para agregar entradas justo antes de mostrar las entradas, porque
agregar una nueva entrada será la acción más común en esta página. La figura 19-2 muestra la
página new_entry . Ahora los usuarios pueden agregar nuevos temas y tantas entradas como deseen
para cada tema. Pruebe la página new_entry agregando algunas entradas a algunos de los temas
que ha creado.
Edición de entradas
Ahora crearemos una página para que los usuarios puedan editar las entradas que agregaron.
La URL edit_entry
La URL de la página debe pasar el ID de la entrada que se va a editar. Aquí está learning_logs/ urls.py:
urls.py --recorte--
patrones de URL = [
--recorte--
# Página para editar una entrada.
ruta('edit_entry/<int:entry_id>/', views.edit_entry, name='edit_entry'),
]
La función de visualización
edit_entry() Cuando la página edit_entry recibe una solicitud GET, la función edit_entry()
La función devuelve un formulario para editar la entrada. Cuando la página recibe una solicitud POST
con texto de entrada revisado, guarda el texto modificado en la base de datos:
if solicitud.método != 'POST':
# Solicitud inicial; prellene el formulario con la entrada actual.
en form = EntryForm(instancia=entrada)
demás:
418 Capítulo 19
Machine Translated by Google
Primero importamos el modelo Entry . En u obtenemos el objeto de entrada que el usuario quiere
editar y el tema asociado con esta entrada. En el bloque if , que se ejecuta para una solicitud GET,
creamos una instancia de EntryForm con el argumento instancia=entrada v. Este argumento le dice a
Django que cree el formulario prellenado con información del objeto de entrada existente. El usuario
verá sus datos existentes y podrá editarlos.
La plantilla edit_entry
<p>Editar entrada:</p>
Ahora necesitamos incluir un enlace a la página edit_entry para cada entrada en la página del
tema:
tema.html --recorte--
{% para entrada en entradas %}
<li>
<p>{{ entrada.fecha_añadida|fecha:'M d, YH:i' }}</p>
<p>{{ entrada.texto|saltos de línea}}</p>
<p>
<a href="{% url 'learning_logs:edit_entry' entry.id %}">Editar entrada</a>
</p>
</li>
--recorte--
Incluimos el enlace de edición después de que se haya mostrado la fecha y el texto de cada
entrada. Usamos la etiqueta de plantilla {% url %} para determinar la URL del patrón de URL con
nombre edit_entry, junto con el atributo ID de la entrada actual en el ciclo (entry.id). El texto del
vínculo Editar entrada aparece después de cada entrada en la página. La Figura 19-3 muestra
cómo se ve la página del tema con estos enlaces.
Figura 19-3: Cada entrada ahora tiene un enlace para editar esa entrada.
Learning Log ahora tiene la mayor parte de la funcionalidad que necesita. Los usuarios
pueden agregar temas y entradas, y leer cualquier conjunto de entradas que deseen. En la
siguiente sección, implementaremos un sistema de registro de usuarios para que cualquiera pueda
crear una cuenta con Learning Log y crear su propio conjunto de temas y entradas.
420 Capítulo 19
Machine Translated by Google
Inténtalo tú mismo
19-1. Blog: Inicie un nuevo proyecto de Django llamado Blog. Crear una aplicación llamada blogs
en el proyecto y un modelo llamado BlogPost. El modelo debe tener campos como título, texto y fecha_añadida.
Cree un superusuario para el proyecto y use el sitio de administración para hacer un par de publicaciones breves.
Cree una página de inicio que muestre todas las publicaciones en orden cronológico.
Crea un formulario para hacer nuevas publicaciones y otro para editar publicaciones existentes.
Comenzaremos creando una nueva aplicación llamada usuarios, usando el comando startapp :
Este comando crea un nuevo directorio llamado usuarios u con una estructura
idéntico a la aplicación learning_logs v.
configuración.py --recorte--
APLICACIONES_INSTALADAS = [
# Mis aplicaciones
'registro_de_aprendizaje',
'usuarios',
--recorte--
]
--recorte--
A continuación, debemos modificar la raíz urls.py para que incluya las URL que escribiremos para la
aplicación de los usuarios :
patrones de URL = [
ruta('admin/', admin.sitio.urls),
ruta('usuarios/', include('usuarios.urls')),
ruta('', include('registro_de_aprendizaje.urls')),
]
Agregamos una línea para incluir el archivo urls.py de los usuarios. Esta línea coincidirá
cualquier URL que comience con la palabra usuarios, como http:// localhost:8000/ users
/ acceso/.
Primero implementaremos una página de inicio de sesión. Usaremos la vista de inicio de sesión
predeterminada que proporciona Django, por lo que el patrón de URL para esta aplicación se ve un poco
diferente. Cree un nuevo archivo urls.py en el directorio learning_log/ users/ y agréguele lo siguiente:
u app_name = 'usuarios'
patrones de URL = [
# Incluir direcciones URL de autenticación predeterminadas.
v ruta('', include('django.contrib.auth.urls')),
]
Importamos la función de ruta y luego importamos la función de inclusión para que podamos
incluir algunas URL de autenticación predeterminadas que ha definido Django.
Estas URL predeterminadas incluyen patrones de URL con nombre, como 'iniciar sesión' y 'cerrar
sesión'. Establecemos la variable app_name en 'usuarios' para que Django pueda distinguir estas
URL de las URL que pertenecen a otras aplicaciones u. Incluso las URL predeterminadas proporcionadas
por Django, cuando se incluyen en el archivo urls.py de la aplicación de los usuarios , serán accesibles
a través del espacio de nombres de los usuarios .
El patrón de la página de inicio de sesión coincide con la URL http:// localhost:8000/ users
/ login/ v. Cuando Django lee esta URL, la palabra usuarios le dice a Django que busque en users/ urls.py,
y login le dice que envíe solicitudes a la vista de inicio de sesión predeterminada de Django .
Cuando el usuario solicita la página de inicio de sesión, Django utilizará una función de vista
predeterminada, pero aún debemos proporcionar una plantilla para la página. El valor por defecto
422 Capítulo 19
Machine Translated by Google
Las vistas de autenticación buscan plantillas dentro de una carpeta llamada registro, por lo que
necesitaremos crear esa carpeta. Dentro del directorio learning_log/ users/ , crea un directorio llamado
templates; dentro de eso, crea otro directorio llamado registro. Aquí está la plantilla login.html , que debe
guardar en learning_log
/ usuarios/ plantillas/ registro:
u {% si formulario.errores%}
<p>Tu nombre de usuario y contraseña no coinciden. Vuelve a intentarlo.</p>
{% terminara si %}
Esta plantilla amplía base.html para garantizar que la página de inicio de sesión tenga
la misma apariencia que el resto del sitio. Tenga en cuenta que una plantilla en una aplicación puede
heredar de una plantilla en otra aplicación.
Si el atributo de errores del formulario está configurado, mostramos un mensaje de error u, informe
indicando que la combinación de nombre de usuario y contraseña no coincide con nada almacenado
en la base de datos.
Queremos que la vista de inicio de sesión procese el formulario, por lo que establecemos el argumento
de acción como la URL de la página de inicio de sesión v. La vista de inicio de sesión envía un formulario a
la plantilla, y depende de nosotros mostrar el formulario y agregar un botón de envío X. en y
incluimos un elemento de formulario oculto, 'siguiente'; el argumento de valor le dice a Django dónde
redirigir al usuario después de que haya iniciado sesión correctamente. En este caso, enviamos al usuario
de vuelta a la página de inicio.
Agreguemos el enlace de inicio de sesión a base.html para que aparezca en todas las páginas. No
queremos que el enlace se muestre cuando el usuario ya haya iniciado sesión, por lo que lo anidamos
dentro de una etiqueta {% if %} :
base.html <p>
<a href="{% url 'learning_logs:index' %}">Registro de aprendizaje</a> - <a href="{% url
'learning_logs:topics' %}">Temas</a> - u {% si usuario.está_autenticado %}
</p>
En el sistema de autenticación de Django, cada plantilla tiene una variable de usuario disponible, que
siempre tiene un conjunto de atributos is_authenticated : el atributo es True si el usuario está conectado y False si
no lo está. Este atributo le permite mostrar un mensaje a los usuarios autenticados y otro a los usuarios no
autenticados.
Ya configuramos una cuenta de usuario, así que iniciemos sesión para ver si la página funciona.
Vaya a http:// localhost:8000/ admin/. Si todavía está conectado como administrador, busque un enlace de cierre de
sesión en el encabezado y haga clic en él.
Cuando haya cerrado la sesión, vaya a http:// localhost:8000/ users/ login/. Debería ver una página de
inicio de sesión similar a la que se muestra en la Figura 19-4. Ingrese el nombre de usuario y la contraseña que
configuró anteriormente, y debería regresar a la página de índice. El encabezado de la página de inicio debe
mostrar un saludo personalizado con su nombre de usuario.
Saliendo de tu cuenta
Ahora debemos proporcionar una forma para que los usuarios cierren sesión. Pondremos un enlace en la base .
.html que cierra la sesión de los usuarios; cuando hagan clic en este enlace, irán a una página que confirma que
se han desconectado.
424 Capítulo 19
Machine Translated by Google
Agregaremos el enlace para cerrar sesión en base.html para que esté disponible en todas
las páginas. Lo incluiremos en la parte {% if user.is_authenticated %} para que solo los usuarios
que ya hayan iniciado sesión puedan verlo:
base.html --recorte-
{% si usuario.está_autenticado%}
Hola, {{ usuario.nombre de usuario }}.
<a href="{% url 'users:logout' %}">Cerrar sesión</a>
{% demás %}
--recorte--
El patrón de URL con nombre predeterminado para cerrar sesión es simplemente 'cerrar sesión'.
Los usuarios querrán saber que cerraron sesión correctamente, por lo que la vista de cierre de
sesión predeterminada muestra la página usando la plantilla loged_out.html, que crearemos
ahora. Aquí hay una página simple que confirma que el usuario ha cerrado la sesión.
Guarde este archivo en templates/ registration, el mismo lugar donde guardó login.html:
Figura 19-5: La página de cierre de sesión confirma que un usuario ha cerrado sesión correctamente.
La página de registro
A continuación, crearemos una página para que los nuevos usuarios puedan registrarse. Usaremos el
UserCreationForm predeterminado de Django pero escribiremos nuestra propia función de vista y plantilla.
La URL de registro
El siguiente código proporciona el patrón de URL para la página de registro, de nuevo en users/ urls.py:
app_name = 'usuarios'
patrones de URL = [
# Incluir direcciones URL de autenticación predeterminadas.
ruta('', include('django.contrib.auth.urls')),
# Página de registro.
ruta('registrar/', vistas.registrar, nombre='registrar'),
]
Importamos el módulo de vistas de los usuarios, que necesitamos porque estamos escribiendo nuestra
propia vista para la página de registro. El patrón de la página de registro coincide con la URL http:// localhost:8000/
users/ register/ y envía solicitudes a la función register() que estamos a punto de escribir.
La función de vista register() debe mostrar un formulario de registro en blanco cuando se solicita la página
de registro por primera vez y luego procesar los formularios de registro completos cuando se envían. Cuando
un registro es exitoso, la función también necesita iniciar sesión en el nuevo usuario. Agrega el siguiente
código a users/ views.py:
si formulario.es_válido():
wx nuevo_usuario = formulario.guardar()
# Inicie sesión como usuario y luego rediríjalo a la página de inicio.
426 Capítulo 19
Machine Translated by Google
Si los datos enviados son válidos, llamamos al método save() del formulario para
guardar el nombre de usuario y el hash de la contraseña en la base de datos x. El guardar ()
El método devuelve el objeto de usuario recién creado, que asignamos a new_user.
Cuando se guarda la información del usuario, iniciamos sesión llamando a login()
función con los objetos request y new_user y, que crea una sesión válida para el nuevo
usuario. Finalmente, redirigimos al usuario a la página de inicio z, donde un saludo
personalizado en el encabezado le indica que su registro fue exitoso.
La plantilla de registro
Ahora cree una plantilla para la página de registro, que será similar a la página de inicio de
sesión. Asegúrese de guardarlo en el mismo directorio que login.html:
<button name="enviar">Registrarse</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</formulario>
Usamos el método as_p nuevamente para que Django muestre todos los campos en el
formulario de manera adecuada, incluidos los mensajes de error si el formulario no se completa
correctamente.
A continuación, agregaremos el código para mostrar el enlace de la página de registro a cualquier usuario que
no haya iniciado sesión actualmente:
base.html --recorte--
{% si usuario.está_autenticado%}
Hola, {{ usuario.nombre de usuario }}.
<a href="{% url 'users:logout' %}">Cerrar sesión</a>
{% demás %}
<a href="{% url 'usuarios:registrar' %}">Registrarse</a> -
<a href="{% url 'users:login' %}">Iniciar sesión</a>
{% terminara si %}
--recorte--
Ahora los usuarios que han iniciado sesión ven un saludo personalizado y un enlace de cierre de sesión.
Los usuarios que no han iniciado sesión ven un enlace de página de registro y un enlace de inicio de sesión.
Pruebe la página de registro creando varias cuentas de usuario con diferentes
nombres de usuario
En la siguiente sección, restringiremos algunas de las páginas para que estén disponibles
solo para usuarios registrados, y nos aseguraremos de que cada tema pertenezca a un usuario específico.
N ota El sistema de registro que hemos configurado permite que cualquiera pueda crear cualquier número de cuentas
para el Registro de aprendizaje. Pero algunos sistemas requieren que los usuarios confirmen su identidad
mediante el envío de un correo electrónico de confirmación al que el usuario debe responder. Al hacerlo, el
sistema genera menos cuentas de spam que el sistema simple que estamos usando aquí. Sin embargo,
cuando está aprendiendo a crear aplicaciones, es perfectamente apropiado practicar con un sistema de
registro de usuarios simple como el que estamos usando.
Inténtalo tú mismo
Los usuarios deberían poder ingresar datos exclusivos para ellos, por lo que crearemos un sistema para averiguar
qué datos pertenecen a qué usuario. Luego, restringiremos el acceso a ciertas páginas para que los usuarios
puedan trabajar solo con sus propios datos.
Modificaremos el modelo de tema para que cada tema pertenezca a un usuario específico.
Esto también se encargará de las entradas, porque cada entrada pertenece a un tema específico.
Comenzaremos restringiendo el acceso a ciertas páginas.
428 Capítulo 19
Machine Translated by Google
Cada tema será propiedad de un usuario, por lo que solo los usuarios registrados pueden solicitar la página
de temas. Agrega el siguiente código a learning_logs/ views.py:
Para que esta redirección funcione, debemos modificar settings.py para que Django sepa dónde
encontrar la página de inicio de sesión. Agregue lo siguiente al final de settings.py:
configuración.py --recorte--
# Mi configuración
LOGIN_URL = 'usuarios: iniciar sesión'
Ahora, cuando un usuario no autenticado solicita una página protegida por el decorador
@login_required , Django enviará al usuario a la URL definida por LOGIN_URL en settings.py.
Puede probar esta configuración cerrando sesión en cualquier cuenta de usuario y yendo a la página
de inicio. Haga clic en el enlace Temas , que debería redirigirlo a la página de inicio de sesión. Luego inicie
sesión en cualquiera de sus cuentas y, desde la página de inicio, haga clic nuevamente en el enlace
Temas . Debería poder acceder a la página de temas.
Django facilita la restricción del acceso a las páginas, pero debe decidir qué páginas
proteger. Lo mejor es pensar primero en qué páginas deben no estar restringidas y luego
restringir todas las demás páginas del proyecto. Puede corregir fácilmente la restricción
excesiva del acceso y es menos peligroso que dejar las páginas confidenciales sin restricciones.
vistas.py --recorte--
@Necesario iniciar sesión
def temas (solicitud):
--recorte--
Intente acceder a cada una de estas páginas mientras está desconectado: será redirigido a
la página de inicio de sesión. Tampoco podrá hacer clic en enlaces a páginas como new_topic.
Pero si ingresa la URL http:// localhost:8000/ new_topic/, será redirigido a la página de inicio de
sesión. Debe restringir el acceso a cualquier URL que sea de acceso público y se relacione con
datos privados del usuario.
430 Capítulo 19
Machine Translated by Google
Cuando migramos la base de datos, Django modificará la base de datos para que pueda almacenar una
conexión entre cada tema y un usuario. Para realizar la migración, Django necesita saber qué usuario asociar
a cada tema existente. El enfoque más simple es comenzar dando todos los temas existentes a un usuario, por
ejemplo, el superusuario. Pero primero necesitamos saber la identificación de ese usuario.
Veamos los ID de todos los usuarios creados hasta ahora. Inicie una sesión de shell de Django y emita
los siguientes comandos:
>>>
En u importamos el modelo de Usuario a la sesión de shell. Luego observamos todos los usuarios que
se han creado hasta ahora v. El resultado muestra tres usuarios: ll_admin, eric y willie.
Ahora que conocemos los ID, podemos migrar la base de datos. Cuando hagamos esto, Python
nos pedirá que conectemos el modelo Topic a un propietario en particular temporalmente o que
agreguemos un valor predeterminado a nuestro archivo models.py para indicarle qué hacer. Elija
la opción 1:
432 Capítulo 19
Machine Translated by Google
N ota Puede simplemente restablecer la base de datos en lugar de migrar, pero perderá todos los datos
existentes. Es una buena práctica aprender a migrar una base de datos manteniendo la integridad
de los datos de los usuarios. Si desea comenzar con una base de datos nueva, emita el comando
python manage.py flush para reconstruir la estructura de la base de datos. Tendrá que crear un
nuevo superusuario y todos sus datos desaparecerán.
Actualmente, si ha iniciado sesión, podrá ver todos los temas, sin importar con qué usuario haya
iniciado sesión. Cambiaremos eso mostrando a los usuarios solo los temas que les pertenecen.
vistas.py --recorte--
@Necesario iniciar sesión
def temas (solicitud):
"""Mostrar todos los temas."""
temas = Tema.objetos.filtro(propietario=solicitud.usuario).order_by('fecha_añadida')
contexto = {'temas': temas}
volver render (solicitud, 'learning_logs/topics.html', contexto)
--recorte-
forma en que se muestran los temas, no necesitamos cambiar la plantilla para la página de temas en
absoluto.
Para ver si esto funciona, inicie sesión como el usuario al que conectó todos los temas
existentes y vaya a la página de temas. Deberías ver todos los temas. Ahora cierre sesión y vuelva
a iniciar sesión como un usuario diferente. La página de temas no debe incluir ningún tema.
Todavía no hemos restringido el acceso a las páginas de temas, por lo que cualquier
usuario registrado podría probar varias URL, como http:// localhost:8000/ topics/ 1/, y
recuperar páginas de temas que coincidan.
Inténtalo tú mismo. Mientras esté conectado como el usuario propietario de todos los
temas, copie la URL o anote el ID en la URL de un tema, y luego cierre sesión y vuelva a
iniciar sesión como un usuario diferente. Introduce la URL de ese tema. Debería poder leer
las entradas, aunque haya iniciado sesión como un usuario diferente.
Arreglaremos esto ahora realizando una verificación antes de recuperar el pedido
entradas en la función de vista topic() :
--recorte--
@Necesario iniciar sesión
def tema (solicitud, topic_id):
"""Mostrar un solo tema y todas sus entradas."""
tema = Tema.objetos.get(id=topic_id)
# Asegúrese de que el tema pertenezca al usuario actual.
v if tema.propietario != solicitud.usuario:
elevar Http404
entradas = topic.entry_set.order_by('-date_added')
contexto = {'tema': tema, 'entradas': entradas}
volver render (solicitud, 'learning_logs/topic.html', contexto)
--recorte--
Una respuesta 404 es una respuesta de error estándar que se devuelve cuando un
recurso solicitado no existe en un servidor. Aquí importamos el Http404
excepción u, que plantearemos si el usuario solicita un tema que no debería ver.
Después de recibir una solicitud de tema, nos aseguramos de que el usuario del tema
coincida con el usuario conectado actualmente antes de mostrar la página. Si el usuario
actual no posee el tema solicitado, lanzamos la excepción Http404 v, y Django devuelve
una página de error 404.
Ahora, si intenta ver las entradas de temas de otro usuario, verá un mensaje de página
no encontrada de Django. En el Capítulo 20, configuraremos el proyecto para que los
usuarios vean una página de error adecuada.
vistas.py --recorte--
@Necesario iniciar sesión
def editar_entrada(solicitud, id_entrada):
"""Editar una entrada existente."""
entrada = Entrada.objetos.get(id=entry_id)
434 Capítulo 19
Machine Translated by Google
tema = entrada.tema
if tema.propietario != solicitud.usuario:
elevar Http404
if solicitud.método != 'POST':
--recorte--
Hay una solución sencilla para este problema, porque tenemos acceso
al usuario actual a través del objeto de solicitud . Agregue el siguiente código, que asocia el
nuevo tema con el usuario actual:
vistas.py --recorte--
@Necesario iniciar sesión
def nuevo_tema(solicitud):
"""Agregar un nuevo tema."""
if solicitud.método != 'POST':
# No se enviaron datos; crear un formulario en blanco.
formulario = TopicForm()
demás:
Cuando llamamos por primera vez a form.save(), pasamos el argumento commit=False porque
necesitamos modificar el nuevo tema antes de guardarlo en la base de datos u. Luego establecemos
el atributo de propietario del nuevo tema para el usuario actual v. Finalmente, llamamos a save()
en la instancia de tema recién definida w. Ahora el tema tiene todos los datos necesarios y se
guardará con éxito.
Debería poder agregar tantos temas nuevos como desee para tantos
diferentes usuarios como quieras. Cada usuario tendrá acceso solo a sus propios datos, ya
sea que esté viendo datos, ingresando datos nuevos o modificando datos antiguos.
Inténtalo tú mismo
19-3. Refactorización: hay dos lugares en views.py donde nos aseguramos de que el usuario asociado
con un tema coincida con el usuario conectado actualmente. Coloque el código para esta verificación en una
función llamada check_topic_owner() y llame a esta función cuando corresponda.
19-4. Protección de new_entry: actualmente, un usuario puede agregar una nueva entrada al registro de
aprendizaje de otro usuario ingresando una URL con la ID de un tema que pertenece a otro usuario. Evite este
ataque comprobando que el usuario actual sea el propietario del tema de la entrada antes de guardar la nueva
entrada.
19-5. Blog protegido: en su proyecto de blog, asegúrese de que cada publicación de blog esté
conectada a un usuario en particular. Asegúrese de que todas las publicaciones sean de acceso público, pero
solo los usuarios registrados pueden agregar publicaciones y editar publicaciones existentes. En la vista que
permite a los usuarios editar sus publicaciones, asegúrese de que el usuario esté editando su propia publicación
Resumen
En este capítulo, aprendió a usar formularios para permitir a los usuarios agregar nuevos
temas y entradas, y editar entradas existentes. Luego aprendió a implementar cuentas de
usuario. Permitió que los usuarios existentes iniciaran y cerraran sesión, y usaron el
UserCreationForm predeterminado de Django para permitir que las personas crearan nuevas cuentas.
Después de crear un sistema simple de autenticación y registro de usuarios, restringió el
acceso a usuarios registrados para ciertas páginas usando @login_required
decorador. Luego atribuyó datos a usuarios específicos a través de una relación de clave
externa. También aprendió a migrar la base de datos cuando la migración requiere que
especifique algunos datos predeterminados.
Finalmente, aprendió cómo asegurarse de que un usuario solo pueda ver los datos que
le pertenecen modificando las funciones de vista. Recuperó los datos apropiados utilizando el
método filter() y comparó al propietario de los datos solicitados con el usuario conectado
actualmente.
Puede que no siempre sea inmediatamente obvio qué datos debe poner a disposición y
qué datos debe proteger, pero esta habilidad vendrá con la práctica. Las decisiones que tomamos
en este capítulo para proteger los datos de nuestros usuarios también ilustran por qué trabajar
con otros es una buena idea al crear un proyecto: tener a otra persona revisando su proyecto
hace que sea más probable que detecte áreas vulnerables.
436 Capítulo 19
Machine Translated by Google
20
Diseñar e implementar una aplicación
Hemos ignorado deliberadamente el estilo hasta ahora para centrarnos primero en la funcionalidad de
Learning Log. Esta es una buena manera de abordar el desarrollo, porque una aplicación solo es útil si
funciona. Por supuesto, una vez que funciona, la apariencia es crítica, por lo que la gente querrá usarlo.
La aplicación django-bootstrap4
Usaremos django-bootstrap4 para integrar Bootstrap en nuestro proyecto. Esta aplicación descarga
los archivos Bootstrap requeridos, los coloca en una ubicación adecuada en su proyecto y hace que las
directivas de estilo estén disponibles en las plantillas de su proyecto.
configuración.py --recorte--
APLICACIONES_INSTALADAS = [
# Mis aplicaciones.
'registro_de_aprendizaje',
'usuarios',
# Aplicaciones de terceros.
'arranque4',
'django.contrib.admin',
--recorte--
Inicie una nueva sección llamada Aplicaciones de terceros para aplicaciones creadas por otros
desarrolladores y agregue 'bootstrap4' a esta sección. Asegúrese de colocar esta sección
después de # Mis aplicaciones pero antes de la sección que contiene las aplicaciones
predeterminadas de Django.
Bootstrap es una gran colección de herramientas de diseño. También tiene varias plantillas que puede
aplicar a su proyecto para crear un estilo general. Es mucho más fácil usar estas plantillas que usar
herramientas de estilo individuales. Para ver las plantillas que ofrece Bootstrap, vaya a https://
getbootstrap.com/, haga clic en Ejemplos y busque la sección Barras de navegación . Usaremos la
plantilla estática Navbar , que proporciona una barra de navegación superior simple y un contenedor para
el contenido de la página.
438 Capítulo 20
Machine Translated by Google
Modificando base.html
Necesitamos modificar la plantilla base.html para acomodar la plantilla de Bootstrap.
Presentaré el nuevo base.html en partes.
El primer cambio que haremos en base.html define los encabezados HTML en el archivo, por
lo que cada vez que se abre una página de registro de aprendizaje, la barra de título del
navegador muestra el nombre del sitio. También agregaremos algunos requisitos para usar
Bootstrap en nuestras plantillas. Elimine todo en base.html y reemplácelo con el siguiente código:
v <!doctype html>
w <html lang="es">
x <cabeza>
<juego de caracteres meta="utf-8">
y <title>Registro de aprendizaje</title>
z {% bootstrap_css%}
{% bootstrap_javascript jquery='completo' %}
{ </cabeza>
base.html --recorte--
</cabeza>
tu <cuerpo>
440 Capítulo 20
Machine Translated by Google
el usuario hace clic en el botón, los elementos de navegación aparecerán en una lista
desplegable. La referencia de colapso hace que la barra de navegación se colapse cuando el
usuario reduce la ventana del navegador o cuando el sitio se muestra en dispositivos móviles
con pantallas pequeñas.
Aquí está la siguiente sección de código que define la barra de navegación:
base.html --recorte--
<span class="navbar-toggler-icon"></botón>
u <div class="collapse navbar-collapse" id="navbarCollapse">
<clase ul = "navbar-nav mr-auto">
vw <li class="elemento-de-navegación">
base.html --recorte--
</ul>
en <ul class="navbar-navml-auto">
en {% si usuario.está_autenticado%}
<li class="elemento de navegación">
en <span class="navbar-text"}">Hola, {{ usuario.nombre de usuario }}.
</li>
<li class="elemento de navegación">
</nav>
El bloque if en v es el mismo bloque condicional que usamos anteriormente para mostrar mensajes
apropiados a los usuarios dependiendo de si han iniciado sesión o no. El bloque es un poco más largo ahora
porque algunas reglas de estilo están dentro de las etiquetas condicionales. En w es un elemento <span> . El
elemento span da estilo a fragmentos de texto, o elementos de una página, que forman parte de una línea más
larga. Mientras que los elementos de división crean su propia división en una página, los elementos de extensión
son continuos dentro de una sección más grande. Esto puede resultar confuso al principio, porque muchas
páginas tienen elementos div profundamente anidados. Aquí, estamos usando el elemento span para aplicar
estilo al texto informativo en la barra de navegación, como el nombre del usuario que inició sesión.
Queremos que esta información se vea diferente a un enlace, para que los usuarios no tengan la tentación
de hacer clic en estos elementos.
En x cerramos el elemento div que contiene las partes de la barra de navegación que colapsarán en
pantallas estrechas, y al final de esta sección cerramos la barra de navegación en general. Si quisiera agregar
más enlaces a la barra de navegación, agregaría otro elemento <li> a cualquiera de los grupos <ul> que
hemos definido en la barra de navegación usando directivas de estilo idénticas a las que ha visto aquí. .
Todavía hay un poco más que debemos agregar a base.html. Necesitamos definir dos bloques que
las páginas individuales pueden usar para colocar el contenido específico de esas páginas.
base.html --recorte--
</nav>
</cuerpo>
</html>
En u abrimos una etiqueta <main> . El elemento principal se utiliza para la parte más significativa del
cuerpo de una página. Aquí asignamos el selector de arranque
442 Capítulo 20
Machine Translated by Google
contenedor, que es una forma sencilla de agrupar elementos en una página. Colocaremos dos
elementos div en este contenedor.
El primer elemento div v contiene un bloque page_header . Usaremos este bloque para
titular la mayoría de las páginas. Para que esta sección se destaque del resto de la página,
colocamos algo de relleno debajo del encabezado. El relleno se refiere al espacio entre el
contenido de un elemento y su borde. El selector pb-2 es una directiva de arranque que
proporciona una cantidad moderada de relleno en la parte inferior del elemento con estilo. Un
margen es el espacio entre el borde de un elemento y otros elementos de la página. Queremos
un borde solo en la parte inferior de la página, por lo que usamos el selector border-bottom, que
proporciona un borde delgado en la parte inferior del bloque page_header .
Para actualizar la página de inicio, usaremos un elemento Bootstrap llamado jumbotron, que es
un cuadro grande que se destaca del resto de la página y puede contener lo que desee. Por lo
general, se usa en las páginas de inicio para contener una breve descripción del proyecto
general y una llamada a la acción que invita al espectador a participar.
tu {% bloque page_header%}
v <div clase="jumbotron">
w <h1 class="display-3">Haga un seguimiento de su aprendizaje.</h1>
Dentro del jumbotron hay tres elementos. El primero es un mensaje breve, Haga un
seguimiento de su aprendizaje, que brinda a los visitantes primerizos una idea de lo que hace
el Registro de aprendizaje. La clase h1 es un encabezado de primer nivel, y el selector display-3
agrega una apariencia más delgada y alta a este encabezado en particular w. En x incluimos un
mensaje más largo que brinda más información sobre lo que el usuario puede hacer con su
registro de aprendizaje.
En lugar de simplemente usar un enlace de texto, creamos un botón en y que invita a los
usuarios a registrar su cuenta de Registro de aprendizaje. Este es el mismo enlace que en el
encabezado, pero el botón se destaca en la página y le muestra al espectador lo que debe hacer
para comenzar a usar el proyecto. Los selectores que ve aquí lo diseñan como un botón grande
que representa una llamada a la acción. El código » es una entidad html que parece dos
corchetes de ángulo recto combinados (>>). En z cerramos el bloque page_header . No estamos
agregando más contenido a esta página, por lo que no necesitamos definir el bloque de contenido
en esta página.
La página de índice ahora se parece a la Figura 20-1 y es una mejora significativa
ment sobre nuestro proyecto sin estilo.
v {% bloque page_header%}
<h2>Inicia sesión en tu cuenta.</h2>
{% endblock page_header%}
444 Capítulo 20
Machine Translated by Google
La etiqueta inserta reglas de estilo Bootstrap en los elementos individuales del formulario a
medida que se representa el formulario. En y, abrimos una etiqueta de plantilla bootstrap4 {%
botones %}, que agrega estilo Bootstrap a los botones.
La Figura 20-2 muestra el formulario de inicio de sesión ahora. La página es mucho más
limpia y tiene un estilo consistente y un propósito claro. Intente iniciar sesión con un nombre de
usuario o contraseña incorrectos; verá que incluso los mensajes de error tienen un estilo
consistente y se integran bien con el sitio en general.
Asegurémonos de que las páginas para ver información también tengan el estilo adecuado,
comenzando con la página de temas:
tu {% bloque page_header%}
<h1>Temas</h1>
{% endblock page_header%}
La página de temas tiene más contenido que la mayoría de las páginas, por lo que necesita un poco
más de trabajo. Usaremos el componente de tarjeta de Bootstrap para que cada entrada se destaque.
Una tarjeta es un div con un conjunto de estilos flexibles y predefinidos que es perfecto para mostrar
las entradas de un tema:
tu {% bloque page_header%}
<h3>{{ tema }}</h3>
{% endblock page_header%}
446 Capítulo 20
Machine Translated by Google
hace que parezca un poco más pequeña que la marca de tiempo x. El segundo elemento es un div
con el selector card-body y, que coloca el texto de la entrada en un cuadro simple en la tarjeta.
Tenga en cuenta que el código de Django para incluir la información en la página no ha cambiado;
solo han cambiado los elementos que afectan la apariencia de la página.
La Figura 20-3 muestra la página del tema con su nueva apariencia. La funcionalidad de
Learning Log no ha cambiado, pero ahora se ve más profesional y atractivo para los usuarios.
N ota Si desea utilizar una plantilla de Bootstrap diferente, siga un proceso similar al que
hemos hecho hasta ahora en este capítulo. Copie la plantilla que desea usar en base.html y
modifique los elementos que contienen contenido real para que la plantilla muestre la información
de su proyecto. Luego use las herramientas de estilo individuales de Bootstrap para diseñar el
contenido de cada página.
Inténtalo tú mismo
20-1. Otras formas: aplicamos los estilos de Bootstrap a la página de inicio de sesión .
Realice cambios similares en el resto de las páginas basadas en formularios, incluidos
new_topic, new_entry, edit_entry y register.
20-2. Blog con estilo: use Bootstrap para diseñar el proyecto de blog que creó en
el Capítulo 19.
Para crear una cuenta, vaya a https:// heroku.com/ y haga clic en uno de los enlaces de
registro. Es gratis crear una cuenta, y Heroku tiene un nivel gratuito que le permite probar sus
proyectos en una implementación en vivo antes de implementarlos correctamente.
Tenga en cuenta que el nivel gratuito de Heroku tiene límites, como la cantidad de aplicaciones que puede implementar y cómo
a menudo, las personas pueden visitar su aplicación. Pero estos límites son lo suficientemente generosos como para permitirle
También deberá instalar tres paquetes que ayuden a servir proyectos de Django en un servidor
en vivo. En un entorno virtual activo, emita los siguientes comandos:
Se requiere el paquete psycopg2 para administrar la base de datos que usa Heroku. El
paquete django-heroku maneja casi toda la configuración que necesita nuestra aplicación para
funcionar correctamente en los servidores de Heroku. Esto incluye administrar la base de datos
y almacenar archivos estáticos en un lugar donde se puedan servir correctamente.
Los archivos estáticos contienen reglas de estilo y archivos JavaScript. El paquete gunicorn
proporciona un servidor capaz de servir aplicaciones en un entorno en vivo.
Heroku necesita saber de qué paquetes depende nuestro proyecto, por lo que usaremos pip
para generar un archivo que los enumere. Nuevamente, desde un entorno virtual activo, emita el
siguiente comando:
448 Capítulo 20
Machine Translated by Google
El comando congelar le dice a pip que escriba los nombres de todos los paquetes
actualmente instalados en el proyecto en el archivo requirements.txt. Abra este archivo
para ver los paquetes y los números de versión instalados en su proyecto:
N ota Si un paquete aparece en su sistema pero el número de versión difiere del que se muestra
aquí, conserve la versión que tiene en su sistema.
A menos que especifique una versión de Python, Heroku utilizará su versión predeterminada
actual de Python. Asegurémonos de que Heroku use la misma versión de Python que
estamos usando. En un entorno virtual activo, emita el comando python
--versión:
En este ejemplo, estoy ejecutando Python 3.7.2. Cree un nuevo archivo llamado
runtime.txt en el mismo directorio que manage.py e ingrese lo siguiente:
tiempo de ejecución.txt
pitón-3.7.2
Este archivo debe contener una línea con su versión de Python especificada en
el formato mostrado; asegúrese de ingresar python en minúsculas, seguido de un guión,
seguido del número de versión de tres partes.
N ota Si recibe un error que informa que el tiempo de ejecución de Python que solicitó no está
disponible, vaya a https://devcenter.heroku.com/categories/language-support/ y busque un
enlace para especificar un tiempo de ejecución de Python. Explore el artículo para encontrar
los tiempos de ejecución disponibles y use el que más se asemeje a su versión de Python.
Ahora necesitamos agregar una sección al final de settings.py para definir algunas configuraciones específicas
para el entorno de Heroku:
configuración.py --recorte--
# Mi configuración
LOGIN_URL = 'usuarios: iniciar sesión'
# Configuración de Heroku.
importar django_heroku
django_heroku.settings(locales())
Aquí importamos el módulo django_heroku y llamamos a la función settings() . Esta función modifica
algunas configuraciones que necesitan valores específicos para el entorno de Heroku.
Un Procfile le dice a Heroku qué procesos debe comenzar para servir adecuadamente al proyecto.
Guarde este archivo de una línea como Procfile, con una P mayúscula y sin extensión de archivo, en el
mismo directorio que manage.py.
Aquí está la línea que va en Procfile:
Esta línea le dice a Heroku que use gunicorn como servidor y que use el conjunto
tings en learning_log/ wsgi.py para iniciar la aplicación. El indicador del archivo de registro le dice
a Heroku los tipos de eventos que debe registrar.
Como se discutió en el Capítulo 17, Git es un programa de control de versiones que le permite tomar una
instantánea del código en su proyecto cada vez que implementa una nueva función con éxito. Si algo sale
mal, puede volver fácilmente a la última instantánea de trabajo de su proyecto; por ejemplo, si
accidentalmente introduce un error mientras trabaja en una nueva función. Cada instantánea se denomina
confirmación.
Con Git, puede intentar implementar nuevas funciones sin preocuparse por romper su proyecto.
Cuando está implementando en un servidor en vivo, debe asegurarse de que está implementando una
versión funcional de su proyecto. Para leer más sobre Git y el control de versiones, consulte el Apéndice
D.
Instalando Git
Es posible que Git ya esté instalado en su sistema. Para saber si Git ya está instalado, abra una nueva
ventana de terminal y emita el comando git
--versión:
450 Capítulo 20
Machine Translated by Google
Si recibe un mensaje de error por algún motivo, consulte las instrucciones de instalación de Git en el
Apéndice D.
Configuración de Git
Git realiza un seguimiento de quién realiza cambios en un proyecto, incluso cuando solo una persona está
trabajando en el proyecto. Para hacer esto, Git necesita saber su nombre de usuario y correo electrónico. Debe
proporcionar su nombre de usuario, pero puede crear un correo electrónico para sus proyectos de práctica:
Si olvida este paso, Git le pedirá esta información cuando realice su primera confirmación.
Ignorar archivos
No necesitamos que Git rastree cada archivo en el proyecto, así que le diremos que ignore algunos archivos.
Cree un archivo llamado .gitignore en la carpeta que contiene manage.py.
Tenga en cuenta que este nombre de archivo comienza con un punto y no tiene extensión de archivo. Aquí
está el código que va en .gitignore:
.gitignore ll_env/
__pycache__/
*.sqlite3
Le decimos a Git que ignore todo el directorio ll_env , porque podemos volver a crear
automáticamente en cualquier momento. Tampoco rastreamos el directorio __pycache__ , que contiene los
archivos .pyc que se crean automáticamente cuando Django ejecuta los archivos .py . No hacemos un
seguimiento de los cambios en la base de datos local, porque es un mal hábito: si alguna vez usa SQLite en
un servidor, puede sobrescribir accidentalmente la base de datos en vivo con su base de datos de prueba
local cuando envía el proyecto al servidor. El asterisco en *.sqlite3 le dice a Git que ignore cualquier archivo
que termine con la extensión .sqlite3.
N ota Si usa macOS, agregue .DS_Store a su archivo .gitignore . Este es un archivo que
almacena información sobre la configuración de carpetas en macOS y no tiene nada que ver con este proyecto.
La mayoría de los sistemas operativos ocultan archivos y carpetas que comienzan con un punto,
como .gitignore. Cuando abre un explorador de archivos o intenta abrir un archivo desde una aplicación como
Sublime Text, no verá este tipo de archivos de forma predeterminada.
Pero como programador, necesitará verlos. Aquí se explica cómo ver los archivos ocultos, según su sistema
operativo:
•En Windows, abra el Explorador de Windows y luego abra una carpeta como Escritorio. Haga clic en la
pestaña Ver y asegúrese de que las extensiones de nombre de archivo y los elementos ocultos
estén marcados.
•En macOS, puede presionar ÿ-shift-. (punto) en cualquier ventana del explorador de archivos para
ver los archivos y carpetas ocultos.
•En sistemas Linux como Ubuntu, puede presionar ctrl-H en cualquier explorador de archivos
para mostrar archivos y carpetas ocultos. Para que esta configuración sea permanente,
abra un explorador de archivos como Nautilus y haga clic en la pestaña de opciones (indicada
por tres líneas). Seleccione la casilla de verificación Mostrar archivos ocultos .
Comprometer el proyecto
Necesitamos inicializar un repositorio Git para Learning Log, agregar todos los archivos
necesarios al repositorio y confirmar el estado inicial del proyecto.
Así es como se hace:
--recorte--
crear modo 100644 usuarios/vistas.py
x (ll_env)learning_log$ estado de git
En maestro de rama
nada que cometer, árbol de trabajo limpio
(ll_env)registro_de_aprendizaje$
Empujando a Heroku
Finalmente estamos listos para llevar el proyecto a Heroku. En un entorno virtual activo, emita los
siguientes comandos:
452 Capítulo 20
Machine Translated by Google
Primero emite el comando de inicio de sesión de heroku , que lo llevará a una página en
su navegador donde puede iniciar sesión en su cuenta de Heroku u. Luego le dices a Heroku
que construya un proyecto vacío v. Heroku genera un nombre compuesto por dos palabras y
un número; puede cambiar esto más adelante. A continuación, emitimos el comando git push
heroku master w, que le dice a Git que envíe la rama maestra del proyecto al repositorio que
acaba de crear Heroku. Luego, Heroku construye el proyecto en sus servidores utilizando
estos archivos. En x está la URL que usaremos para acceder al proyecto en vivo, que
podemos cambiar junto con el nombre del proyecto.
Cuando haya emitido estos comandos, el proyecto se implementará pero no se
configurará por completo. Para verificar que el proceso del servidor se inició correctamente,
use el comando heroku ps :
(ll_env)learning_log$ heroku pd
u Cuota de horas de dinamómetro gratis restante este mes: 450h 44m (81 %)
Uso gratuito de dinamómetro para esta aplicación: 0h 0m (0%)
Para obtener más información sobre la suspensión del dinamómetro y cómo actualizar, consulte:
https://devcenter.heroku.com/articles/dyno-sleeping
v === web (Gratis): gunicorn learning_log.wsgi --log-file - (1)
web.1: hasta 2019/02/19 23:40:12 -0900 (hace ~ 10m)
(ll_env)registro_de_aprendizaje$
El resultado muestra cuánto tiempo más puede estar activo el proyecto en el próximo
mes u. En el momento de escribir este artículo, Heroku permite que las implementaciones
gratuitas estén activas hasta 550 horas en un mes. Si un proyecto excede este límite, se
mostrará una página de error del servidor estándar; personalizaremos esta página de error en
breve. En v vemos que se ha iniciado el proceso definido en Procfile .
Ahora podemos abrir la aplicación en un navegador usando el comando heroku open:
Este comando le evita abrir un navegador e ingresar la URL que le mostró Heroku, pero
esa es otra forma de abrir el sitio. Debería ver la página de inicio de Learning Log, con el estilo
correcto. Sin embargo, aún no puede usar la aplicación porque no hemos configurado la base
de datos.
N ota El proceso de implementación de Heroku cambia de vez en cuando. Si tiene problemas irresolubles,
consulte la documentación de Heroku para obtener ayuda. Vaya a https://devcenter.heroku
.com/, haga clic en Python y busque un enlace para Comenzar con Python o Implementar
aplicaciones de Python y Django en Heroku. Si no entiende lo que ve allí, consulte las
sugerencias en el Apéndice C.
Necesitamos ejecutar la migración una vez para configurar la base de datos en vivo y aplicar todas las
migraciones que generamos durante el desarrollo. Puede ejecutar los comandos de Django y Python
en un proyecto de Heroku usando el comando heroku run.
Aquí se explica cómo ejecutar la migración en la implementación de Heroku:
Puede compartir su enlace de Heroku para permitir que cualquiera use su versión de Registro
de aprendizaje. En la siguiente sección, completaremos algunas tareas más para finalizar el proceso de
implementación y configurarlo para que continúe desarrollando el Registro de aprendizaje.
Ya has visto que podemos ejecutar comandos únicos usando la función heroku run
dominio. Pero también puede ejecutar comandos abriendo una sesión de terminal Bash mientras está
conectado al servidor Heroku usando el comando heroku run bash. Bash es el lenguaje que se ejecuta en
muchos terminales Linux. Usaremos la sesión de terminal de Bash para crear un superusuario para que
podamos acceder al sitio de administración en la aplicación en vivo:
454 Capítulo 20
Machine Translated by Google
Contraseña (nuevamente):
Superusuario creado con éxito. w ~ $ salir salir
(ll_env)registro_de_aprendizaje$
En u ejecutamos ls para ver qué archivos y directorios existen en el servidor, que deberían
ser los mismos archivos que tenemos en nuestro sistema local. Puede navegar por este sistema
de archivos como cualquier otro.
N ota Los usuarios de Windows usarán los mismos comandos que se muestran aquí (como ls en lugar de dir),
porque está ejecutando una terminal Linux a través de una conexión remota.
Lo más probable es que desee que su URL sea más amigable y fácil de recordar que https://
secret-lowlands-82594.herokuapp.com/. Puede cambiar el nombre de la aplicación usando un solo
comando:
Puede usar letras, números y guiones al nombrar su aplicación y llamarla como quiera, siempre
que nadie más haya reclamado el nombre. Esta implementación ahora se encuentra en https:// learning-
log.herokuapp.com/. El proyecto ya no está disponible en la URL anterior; el comando apps:rename
mueve completamente el proyecto a la nueva URL.
N ota Cuando implementa su proyecto usando el servicio gratuito de Heroku, Heroku pone su implementación en
modo de suspensión si no ha recibido ninguna solicitud después de una cierta cantidad de tiempo o si
ha estado demasiado activo para el nivel gratuito. La primera vez que un usuario accede al sitio después
de haber estado inactivo, tardará más en cargarse, pero el servidor responderá a las solicitudes posteriores
con mayor rapidez. Así es como Heroku puede permitirse ofrecer implementaciones gratuitas.
configuración.py --recorte--
# Configuración de Heroku.
importar django_heroku
django_heroku.settings(locales())
si os.environ.get('DEBUG') == 'VERDADERO':
DEPURAR = Verdadero
El método os.environ.get() lee el valor asociado con una variable de entorno específica
en cualquier entorno donde se ejecuta el proyecto. Si la variable que estamos solicitando está
configurada, el método devuelve su valor; si no está configurado, el método devuelve Ninguno.
El uso de variables de entorno para almacenar valores booleanos puede resultar confuso. En
la mayoría de los casos, las variables de entorno se almacenan como cadenas y debe tener
cuidado con esto. Considere este fragmento de una simple sesión de terminal de Python:
>>> bool('Falso')
Verdadero
El valor booleano de la cadena 'False' es True, porque cualquier cadena que no esté
vacía se evalúa como True. Así que usaremos las cadenas 'VERDADERO' y 'FALSO', en
mayúsculas, para aclarar que no estamos almacenando los valores booleanos verdaderos y
falsos reales de Python. Cuando Django lee en la variable de entorno con la clave 'DEBUG'
en Heroku, estableceremos DEBUG en True si el valor es 'TRUE' y False si el valor es 'FALSE'.
456 Capítulo 20
Machine Translated by Google
u (ll_env)learning_log$ git commit -am "Establecer DEBUG basado en variables de entorno". [maestro
3427244] Establecer DEPURACIÓN en función de las variables de entorno. 1 archivo cambiado, 4
inserciones (+) v (ll_env)learning_log$ git status
En maestro de rama
nada que cometer, árbol de trabajo limpio
(ll_env)learning_log$
Ahora podemos establecer el valor que queremos para DEBUG en settings.py a través de Heroku.
El comando heroku config:set establece una variable de entorno para nosotros:
(ll_env)registro_de_aprendizaje$
En el Capítulo 19, configuramos el Registro de aprendizaje para que devuelva un error 404 si el usuario
solicita un tema o una entrada que no le pertenece. Probablemente también haya visto unos 500 errores de
servidor (errores internos) en este punto. Un error 404 generalmente significa que su código Django es
correcto, pero el objeto solicitado no existe; un error 500 generalmente significa que hay un error en el código
que ha escrito, como un error en una función en views.py. Actualmente, Django devuelve la misma página
de error genérica en ambas situaciones. Pero podemos escribir nuestras propias plantillas de página de error
404 y 500 que coincidan con la apariencia general de Learning Log. Estas plantillas deben ir en el directorio
raíz de plantillas.
En la carpeta learning_log más externa , crea una nueva carpeta llamada templates. Luego crea un nuevo
archivo llamado 404.html; la ruta a este archivo debe ser learning_log
/ templates/ 404.html. Aquí está el código para este archivo:
{% bloque page_header%}
<h2>El artículo que solicitaste no está disponible. (404)</h2>
{% endblock page_header%}
458 Capítulo 20
Machine Translated by Google
Esta sencilla plantilla proporciona la información genérica de la página de error 404, pero está
diseñada para que coincida con el resto del sitio.
Crea otro archivo llamado 500.html usando el siguiente código:
{% bloque page_header%}
<h2>Ha habido un error interno. (500)</h2>
{% endblock page_header%}
configuración.py --recorte--
PLANTILLAS = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'plantillas')],
'APP_DIRS': Verdadero,
--recorte--
},
]
--recorte--
Este cambio le dice a Django que busque en el directorio raíz de plantillas las plantillas de la
página de error.
Si desea ver cómo se ven las páginas de error en su sistema antes de enviarlas a Heroku,
primero deberá configurar Debug=False en su configuración local para suprimir las páginas de
depuración predeterminadas de Django. Para hacerlo, realice el siguiente cambio en settings.py
(asegúrese de estar trabajando en la parte de settings.py que se aplica al entorno local, no en la
parte que se aplica a Heroku):
configuración.py --recorte--
# ADVERTENCIA DE SEGURIDAD: ¡no ejecute con la depuración activada en producción!
DEPURAR = Falso
--recorte--
Ahora solicita un tema o entrada que no te pertenezca para ver la página de error 404. Para
probar la página de error 500, solicite un tema o una entrada que no exista. Por ejemplo, la URL
http:// localhost:8000/ topics/ 999/ debería generar un error 500 a menos que ya haya generado 999
temas de ejemplo.
Cuando haya terminado de comprobar las páginas de error, establezca el valor local de
DEBUG de nuevo en True para seguir desarrollando el registro de aprendizaje. (Asegúrese de no
cambiar la forma en que se maneja DEBUG en la sección que administra la configuración en el
entorno de Heroku).
N ota La página de error 500 no mostrará ninguna información sobre el usuario que ha iniciado sesión,
porque Django no envía ninguna información de contexto en la respuesta cuando hay
un error del servidor.
Ahora necesitamos confirmar los cambios en la página de error que acabamos de hacer y
enviarlos a Heroku:
--recorte--
remoto: Verificando la implementación... hecho.
A https://git.heroku.com/learning-log.git d5075a1..4bd3b1c
maestro -> maestro (ll_env)learning_log$
Ahora, cuando aparece una página de error, debe tener el mismo estilo que la
resto del sitio, lo que hace que la experiencia del usuario sea más fluida cuando surgen errores.
En este punto, si un usuario solicita manualmente un tema o entrada que no existe, recibirá un
error de servidor 500. Django intenta renderizar la página inexistente, pero no tiene suficiente
información para hacerlo y el resultado es un error 500.
Esta situación se maneja con mayor precisión como un error 404, y podemos implementar este
comportamiento usando la función de acceso directo de Django get_object_or_404().
Esta función intenta obtener el objeto solicitado de la base de datos, pero si ese objeto no existe,
genera una excepción 404. Importaremos esta función a views.py y la usaremos en lugar de get():
460 Capítulo 20
Machine Translated by Google
Desarrollo en curso
Es posible que desee desarrollar aún más el registro de aprendizaje después de su impulso inicial
a un servidor en vivo o desarrollar sus propios proyectos para implementar. Hay un proceso
bastante consistente para actualizar proyectos.
En primer lugar, realizará los cambios necesarios en su proyecto local. Si sus cambios
dan como resultado nuevos archivos, agregue esos archivos al repositorio de Git usando el
comando git add . (asegúrese de incluir el punto al final del comando).
Cualquier cambio que requiera una migración de la base de datos necesitará este comando,
porque cada migración genera un nuevo archivo de migración.
En segundo lugar, confirme los cambios en su repositorio usando git commit -am "commit
message". Luego envíe sus cambios a Heroku usando el comando git push heroku master. Si
migró su base de datos localmente, también deberá migrar la base de datos activa. Puede
utilizar el comando único heroku run python manage.py migrate o abrir una sesión de terminal
remota con heroku run bash y ejecutar el comando python manage.py migrate.
Luego visite su proyecto en vivo y asegúrese de que los cambios que espera ver hayan tenido
efecto.
Es fácil cometer errores durante este proceso, así que no se sorprenda cuando algo
salga mal. Si el código no funciona, revise lo que ha hecho e intente detectar el error. Si no
puede encontrar el error o no sabe cómo deshacer el error, consulte las sugerencias para
obtener ayuda en el Apéndice C. No se avergüence de pedir ayuda: todos los demás aprendieron
a construir proyectos preguntando. las mismas preguntas que es probable que haga, por lo que
alguien estará encantado de ayudarle. Resolver cada problema que surja lo ayuda a desarrollar
sus habilidades de manera constante hasta que construya proyectos significativos y confiables y
también responda las preguntas de otras personas.
La configuración SECRET_KEY
Django usa el valor de la configuración SECRET_KEY en settings.py para implementar una serie
de protocolos de seguridad. En este proyecto, hemos enviado nuestro archivo de configuración al
repositorio con la configuración SECRET_KEY incluida. Esto está bien para un proyecto de
práctica, pero la configuración SECRET_KEY debe manejarse con más cuidado para un sitio de
producción. Si crea un proyecto que está obteniendo un uso significativo, asegúrese de investigar
cómo manejar su configuración SECRET_KEY de manera más segura.
Es una buena práctica ejecutar el proceso de implementación varias veces con el mismo proyecto
o con una serie de proyectos pequeños para familiarizarse con la implementación. Pero deberá
saber cómo eliminar un proyecto que se ha implementado. Heroku también limita la cantidad de
proyectos que puede alojar de forma gratuita, y no desea saturar su cuenta con proyectos de
práctica.
Inicie sesión en el sitio web de Heroku (https:// heroku.com/); será redirigido a una página
que muestra una lista de sus proyectos. Haga clic en el proyecto que desea eliminar.
Verá una nueva página con información sobre el proyecto. Haga clic en Configuración
enlace y desplácese hacia abajo hasta que vea un enlace para eliminar el proyecto. Esta
acción no se puede revertir, por lo que Heroku le pedirá que confirme la solicitud de
eliminación ingresando manualmente el nombre del proyecto.
Si prefiere trabajar desde una terminal, también puede eliminar un proyecto emitiendo
el comando destroy :
N ota La eliminación de un proyecto en Heroku no afecta a la versión local del proyecto. Si nadie ha
usado su proyecto implementado y solo está practicando el proceso de implementación, es
perfectamente razonable eliminar su proyecto en Heroku y volver a implementarlo.
Inténtalo tú mismo
20-3. Blog en vivo: implemente el proyecto de blog en el que ha estado trabajando en Heroku.
Asegúrese de establecer DEBUG en Falso, para que los usuarios no vean las páginas de
error completas de Django cuando algo sale mal.
20-4. Más 404: la función get_object_or_404() también debe usarse en las vistas new_entry() y
edit_entry() . Realice este cambio, pruébelo ingresando una URL como http://localhost:8000/
new_entry/999/, y verifique que vea un 404
error.
462 Capítulo 20
Machine Translated by Google
Resumen
En este capítulo, aprendió a dar a sus proyectos una apariencia simple pero profesional
utilizando la biblioteca Bootstrap y la aplicación django-bootstrap4.
Al usar Bootstrap, los estilos que elija funcionarán de manera consistente en casi cualquier
dispositivo que la gente use para acceder a su proyecto.
Aprendió sobre las plantillas de Bootstrap y usó la plantilla estática de la barra de navegación
para crear una apariencia simple para el registro de aprendizaje. Usó un tron gigante para hacer
que el mensaje de una página de inicio se destaque y aprendió a diseñar todas las páginas de
un sitio de manera consistente.
En la parte final del proyecto, aprendió cómo implementar un proyecto en los servidores
de Heroku para que cualquiera pueda acceder a él. Creó una cuenta de Heroku e instaló
algunas herramientas que ayudan a administrar el proceso de implementación. Usó Git para enviar
el proyecto de trabajo a un repositorio y luego empujó el repositorio a los servidores de Heroku.
Finalmente, aprendió a comenzar a proteger su aplicación configurando DEBUG=False en el
servidor en vivo.
Ahora que ha terminado el Registro de aprendizaje, puede comenzar a crear su propio
proyectos Comience de manera simple y asegúrese de que el proyecto funcione antes de
agregar complejidad. ¡Disfruta de tu aprendizaje continuo y buena suerte con tus proyectos!
Epílogo
Siempre que sea posible, invite a otras personas a probar sus programas.
Si escribes un juego, deja que otras personas lo jueguen. Si hace una visualización,
muéstresela a los demás y vea si tiene sentido para ellos. Si crea una aplicación web,
impleméntela en línea e invite a otros a probarla. Escuche a sus usuarios e intente
incorporar sus comentarios en sus proyectos; te convertirás en un mejor programador si
lo haces.
Cuando trabaja en sus propios proyectos, se encontrará con problemas que son
desafiantes, o incluso imposibles, de resolver por su cuenta. Siga encontrando formas
de pedir ayuda y encuentre su propio lugar en la comunidad de Python. Únase a un grupo
de usuarios de Python local o explore algunas comunidades de Python en línea. Considere
asistir a una PyCon cerca de usted también.
Debe esforzarse por mantener un equilibrio entre trabajar en proyectos que le
interesen y desarrollar sus habilidades de Python en general. Muchas fuentes de
aprendizaje de Python están disponibles en línea y una gran cantidad de libros de Python
están dirigidas a programadores intermedios. Muchos de estos recursos estarán accesibles
para usted ahora que conoce los conceptos básicos y cómo aplicar sus habilidades.
Trabajar con tutoriales y libros de Python se basará directamente en lo que aprendió aquí
y profundizará su comprensión de la programación en general y de Python en particular.
Luego, cuando vuelva a trabajar en proyectos después de concentrarse en aprender
sobre Python, podrá resolver una variedad más amplia de problemas de manera más
eficiente.
¡Felicitaciones por lo lejos que has llegado y buena suerte con tu aprendizaje
continuo!
466 Epílogo
Machine Translated by Google
UN
Instalación y
Solución de problemas
Pitón en Windows
Las instrucciones del Capítulo 1 le muestran cómo instalar Python usando el
instalador oficial en https:// python.org/. Si no pudo hacer que Python se ejecutara
después de usar el instalador, las instrucciones de solución de problemas en esta sección
deberían ayudarlo a poner en funcionamiento Python.
$ C:\Python37\python --versión
Pitón 3.7.2
C:\Python37
Tenga en cuenta que no incluimos el nombre del archivo python.exe ; eran simplemente
diciéndole al sistema dónde buscarlo.
Cierra la ventana de tu terminal y abre una nueva. Al hacerlo, se cargará la nueva variable
Path en su sesión de terminal. Ahora, cuando ingrese python --version, debería ver la versión de
Python que acaba de agregar a su ruta
variable. Ahora puede iniciar una sesión de terminal de Python simplemente ingresando python
en un símbolo del sistema.
N ota Si utiliza una versión anterior de Windows, es posible que vea un cuadro con la etiqueta Valor de variable
al hacer clic en Editar. Si ve este cuadro, use la tecla de flecha derecha para desplazarse
completamente hacia la derecha. Tenga cuidado de no sobrescribir la variable existente; si lo hace,
haga clic en Cancelar y vuelva a intentarlo. Agregue un punto y coma y la ruta a su archivo
python.exe a la variable existente:
%SystemRoot%\system32\...\System32\WindowsPowerShell\v1.0\;C:\Python37
468 Apéndice A
Machine Translated by Google
Reinstalando Python
Si aún no puede ejecutar Python, a menudo desinstalar Python y volver a ejecutar el
instalador resolverá cualquier problema que haya ocurrido en su primer intento.
Para hacer esto, abra el Panel de control de su sistema y haga clic en Programas y
características. Desplácese hacia abajo hasta que vea la versión de Python que acaba de
instalar y selecciónela. Haga clic en Desinstalar/Cambiar y luego haga clic en Desinstalar
en el cuadro de diálogo que aparece. Luego, vuelva a ejecutar el instalador siguiendo las
instrucciones del Capítulo 1, pero esta vez asegúrese de seleccionar la opción Agregar
Python a la RUTA y cualquier otra configuración que sea relevante para su sistema. Si aún
tiene problemas y no está seguro de dónde obtener ayuda, consulte las sugerencias en el Apéndice C.
Python en macOS
Las instrucciones de instalación en el Capítulo 1 usan el instalador oficial de Python en
https:// python.org/, que le recomiendo que use a menos que tenga una razón específica para
no hacerlo. Otro enfoque usa Homebrew, una herramienta que puede usar para instalar una
variedad de software en macOS. Si ya está usando Homebrew y quiere usarlo para instalar
Python, o si las personas con las que trabaja usan Homebrew y quiere una configuración
similar a la que están usando, puede usar las siguientes instrucciones.
Instalar Homebrew
Homebrew depende de algunas de las herramientas de línea de comandos del paquete Xcode
de Apple, por lo que primero deberá instalar las herramientas de línea de comandos de Xcode.
Abra una terminal y ejecute este comando:
$ xcode-seleccionar --instalar
Haga clic en los cuadros de diálogo de confirmación que aparecen (esto puede llevar
un tiempo, dependiendo de la velocidad de su conexión). A continuación, instale Homebrew
ingresando el siguiente comando:
N ota La -e en este comando le dice a Ruby (el lenguaje de programación en el que está escrito
Homebrew) que ejecute el código que se descarga aquí. Solo debe ejecutar comandos como
este desde fuentes en las que confíe.
$ cerveza doctor
Su sistema está listo para preparar.
Este resultado significa que está listo para usar Homebrew para instalar paquetes en su
sistema.
Instalación de Python
$ python3 --versión
Pitón 3.7.2
ps
Ahora puede iniciar una sesión de terminal de Python con el comando python3.
También puede usar el comando python3 en su editor de texto para que ejecute programas
con la versión de Python que acaba de instalar en lugar de la versión anterior del sistema.
Si necesita ayuda para configurar Sublime Text para usar la versión que acaba de instalar,
consulte las instrucciones en el Capítulo 1.
pitón es linux
Python se incluye de forma predeterminada en casi todos los sistemas Linux. Pero si
la versión predeterminada es anterior a Python 3.6, debe instalar la última versión. Las
siguientes instrucciones deberían funcionar para la mayoría de los sistemas basados en apt.
Usaremos un paquete llamado deadsnakes, que facilita la instalación de múltiples
versiones de Python. Introduzca los siguientes comandos:
$ pitón3.7
>>>
También querrá usar este comando cuando configure su editor de texto y cuando
ejecute programas desde la terminal.
470 Apéndice A
Machine Translated by Google
Cada una de las siguientes palabras clave tiene un significado específico y verá un
error si intenta usar alguna de ellas como nombre de variable.
B
Editores de texto e IDE
Te animo a usar un editor de texto simple mientras aprendes a programar. Los editores de
texto también suponen una carga mucho más ligera para su sistema; por lo tanto, si está trabajando
en una máquina más antigua o con menos recursos, un editor de texto funcionará mejor que un IDE.
Si ya está familiarizado con los IDE o si las personas que lo rodean usan un IDE y desea usar un
entorno similar, pruébelos por todos los medios.
En el Capítulo 1, configuró Sublime Text para usar la versión de Python que desea al ejecutar sus
programas. Ahora lo configuraremos para que realice algunas de las tareas mencionadas al principio
de este apéndice.
Si usa una combinación de tabuladores y espacios en su código, puede causar problemas en sus
programas que son difíciles de diagnosticar. Para evitar esto, puede configurar Sublime Text para
usar siempre espacios para la sangría, incluso cuando presiona la tecla de tabulación . Vaya a
VerÿSangría y asegúrese de que la opción Sangría usando espacios esté seleccionada. Si no es
así, selecciónelo. Además, asegúrese de que el Ancho de la pestaña
se establece en 4 espacios.
La mayoría de los editores le permiten configurar una señal visual, generalmente una línea vertical,
para mostrar dónde deben terminar sus líneas. En la comunidad de Python, la convención es limitar
las líneas a 79 caracteres o menos. Para configurar esta función, seleccione View4Ruler y luego haga
clic en 80. Sublime Text colocará una línea vertical en la marca de 80 caracteres para ayudar a
restringir las líneas de código a una longitud adecuada.
474 Apéndice B
Machine Translated by Google
Guardar su configuración
Algunas de las configuraciones mencionadas solo afectan el archivo actual en el que está trabajando.
Para que su configuración afecte a todos los archivos que abre en Sublime Text, deberá definir
su configuración de usuario. Seleccione Sublime Text4Preferences4Settings y busque el
archivo Preferences.sublime-settings – User. Ingrese lo siguiente en este archivo:
{
"gobernantes": [80],
"traducir_tabs_a_espacios": verdadero
}
Guarde este archivo y la configuración de su regla y pestaña se aplicará a todos los archivos
con los que trabaje en Sublime Text. Si agrega más configuraciones a este archivo, asegúrese de
que cada línea termine con una coma excepto la última línea. Puede ver los archivos de
configuración de otros usuarios en línea y personalizar su editor con la configuración que lo ayude
a trabajar de manera más eficiente.
Otras personalizaciones
Puede personalizar Sublime Text de muchas maneras para ayudarlo a trabajar de manera aún más
eficiente. Mientras explora los menús, esté atento a los atajos de teclado para los elementos de
menú que usa con más frecuencia. Cada vez que usa un atajo de teclado en lugar de alcanzar el
mouse o el panel táctil, se vuelve un poco más eficiente. No intentes aprender todo de golpe; solo
trate de ser eficiente con las acciones que usa con más frecuencia y esté atento a otras funciones que
puedan ayudarlo a desarrollar su propio flujo de trabajo.
INACTIVO
IDLE es un editor de texto que se incluye con Python. Es un poco menos intuitivo para trabajar que
Sublime Text, pero verá referencias a él en otros tutoriales dirigidos a principiantes, por lo que es
posible que desee probarlo.
geany
Geany es un editor de texto simple que le permite ejecutar todos sus programas directamente
desde el editor. Muestra toda su salida en una ventana de terminal, lo que lo ayuda a sentirse
cómodo usando terminales. Geany tiene una interfaz muy simple, pero es lo suficientemente
poderosa como para que un número significativo de programadores experimentados aún la
usen.
Emacs y Vim
Emacs y Vim son dos editores populares preferidos por muchos programadores
experimentados porque están diseñados para usarse de modo que sus manos nunca tengan
que dejar el teclado. Esto hace que escribir, leer y modificar código sea muy eficiente una
vez que aprende cómo funciona el editor. También significa que ambos editores tienen una
curva de aprendizaje bastante pronunciada. Vim está incluido en la mayoría de las máquinas
Linux y macOS, y tanto Emacs como Vim se pueden ejecutar completamente dentro de una
terminal. Por esta razón, a menudo se usan para escribir código en servidores a través de una
sesión de terminal remota.
Los programadores a menudo recomendarán que los pruebes. Pero muchos
los programadores competentes olvidan cuánto están tratando de aprender los nuevos
programadores. Es beneficioso conocer estos editores, pero evite usarlos hasta que se
sienta cómodo trabajando con código en un editor más simple que le permita concentrarse
en aprender a programar en lugar de aprender a usar un editor.
Átomo
Visual Studio Code, también llamado VS Code, es otro editor que actúa más como un IDE.
VS Code admite el uso eficiente de un depurador, tiene soporte de control de versiones
integrado y también ofrece herramientas de finalización de código.
PyCharm
PyCharm es un IDE popular entre los programadores de Python porque fue creado para
funcionar específicamente con Python. La versión completa requiere una suscripción paga, pero
también está disponible una versión gratuita llamada PyCharm Community Edition que muchos
desarrolladores encuentran útil.
476 Apéndice B
Machine Translated by Google
PyCharm presenta un linter, que verifica que su estilo de codificación coincida con las
convenciones comunes de Python y ofrece sugerencias cuando se desvía del formato normal
de Python. También tiene un depurador integrado para ayudarlo a resolver errores de manera
competente y modos que lo ayudan a trabajar de manera eficiente con varias bibliotecas
populares de Python.
Cuadernos Jupyter
Jupyter Notebook es un tipo de herramienta diferente a los editores de texto o IDE
tradicionales, ya que es una aplicación web construida principalmente con bloques; cada
bloque es un bloque de código o un bloque de texto. Los bloques de texto se representan en
Markdown, por lo que puede incluir un formato simple en sus bloques de texto.
Los portátiles Jupyter se desarrollaron para admitir el uso de Python en aplicaciones
científicas, pero desde entonces se han ampliado para volverse útiles en una amplia variedad
de situaciones. En lugar de simplemente escribir comentarios dentro de un archivo .py , puede
escribir texto claro con formato simple, como encabezados, listas con viñetas e hipervínculos
entre secciones de código. Cada bloque de código se puede ejecutar de forma independiente,
lo que le permite probar pequeñas partes de su programa, o puede ejecutar todos los bloques
de código a la vez. Cada bloque de código tiene su propia área de salida y puede activar o
desactivar las áreas de salida según sea necesario.
Jupyter Notebooks puede resultar confuso a veces debido a las interacciones entre
diferentes celdas. Si define una función en una celda, esa función también está disponible
para otras celdas. Esto es beneficioso la mayor parte del tiempo, pero puede resultar
confuso en portátiles más largos y si no comprende completamente cómo funciona el
entorno de Notebook.
Si está realizando algún trabajo científico o centrado en datos en Python, es casi
seguro que verá Jupyter Notebooks en algún momento.
C
Obteniendo ayuda
Primeros pasos
Cuando esté atascado, su primer paso debe ser evaluar su situación. Antes de
pedir ayuda a otra persona, responda claramente las siguientes tres preguntas:
Haga sus respuestas lo más específicas posible. Para la primera pregunta, explícito
afirmaciones como "Estoy tratando de instalar la última versión de Python en mi computadora
portátil con Windows 10" son lo suficientemente detalladas para que otros miembros de la
comunidad de Python puedan ayudarlo. Declaraciones como "Estoy tratando de instalar Python" no
brindan suficiente información para que otros puedan ofrecer mucha ayuda.
Su respuesta a la segunda pregunta debe proporcionar suficientes detalles para que no se
le aconseje que repita lo que ya intentó: "Fui a https://
python.org/ descargas/ e hizo clic en el botón Descargar para mi sistema. Luego ejecuté el instalador”,
es más útil que “Fui al sitio web de Python y descargué algo”.
Para la tercera pregunta, es útil conocer los mensajes de error exactos que
recibido para que pueda buscar una solución en línea o proporcionarlos cuando solicite ayuda.
A veces, solo responder estas tres preguntas antes de pedir ayuda a otros te permite ver algo
que te estás perdiendo y despegarte sin tener que ir más lejos. Los programadores incluso tienen un
nombre para esto: se llama depuración de patitos de goma. La idea es que si explica claramente su
situación a un patito de goma (o cualquier objeto inanimado) y le hace una pregunta específica, a
menudo podrá responder su propia pregunta. Algunas tiendas de programación incluso tienen un pato
de goma real para animar a la gente a "hablar con el pato".
Vuelve a intentarlo
Simplemente volver al principio y volver a intentarlo puede ser suficiente para resolver muchos
problemas. Digamos que está tratando de escribir un ciclo for basado en un ejemplo de este libro.
Es posible que solo te hayas perdido algo simple, como dos puntos al final de la línea for . Repasar
los pasos nuevamente podría ayudarlo a evitar repetir el mismo error.
Tomar un descanso
480 Apéndice C
Machine Translated by Google
Búsqueda en línea
Lo más probable es que alguien más haya tenido el mismo problema que usted tiene y haya
escrito sobre él en línea. Las buenas habilidades de búsqueda y las consultas específicas lo
ayudarán a encontrar los recursos existentes para resolver el problema al que se enfrenta.
Por ejemplo, si tiene dificultades para instalar la última versión de Python en Windows 10,
buscar instalar python windows 10 y limitar los resultados a los recursos del último año podría
llevarlo a una respuesta clara.
Buscar el mensaje de error exacto también puede ser extremadamente útil. Por ejemplo,
supongamos que obtiene el siguiente error cuando intenta iniciar una sesión de terminal de
Python:
> pitón
'python' no se reconoce como un comando interno o externo,
programa operable o archivo por lotes
>
Desbordamiento de pila
r/aprenderpython
Reddit se compone de una serie de subforos llamados subreddits. El subreddit r/
learnpython (https:// reddit.com/ r/ learnpython/) es bastante activo y solidario. Aquí
puedes leer las preguntas de otros y publicar las tuyas.
Publicaciones de blog
Muchos programadores mantienen blogs y comparten publicaciones sobre las partes del
lenguaje con las que están trabajando. Debe hojear los primeros comentarios en una
publicación de blog para ver qué reacciones han tenido otras personas antes de tomar
cualquier consejo. Si no aparecen comentarios, toma la publicación con pinzas. Es posible
que nadie más haya verificado el consejo.
Pegue esta línea en el sitio de IRC con el apodo como el nombre que eligió.
lier y un valor para código_verificación. Ahora estás listo para unirte a un canal.
482 Apéndice C
Machine Translated by Google
Para unirse al canal principal de Python, ingrese /join #python en el cuadro de entrada.
Verá una confirmación de que se unió al canal y alguna información general sobre el
canal.
El canal ##learnpython (con dos hashtags) también suele ser bastante activo. Este
canal está asociado con https:// reddit.com/ r/ learnpython/, por lo que también verá
mensajes sobre publicaciones en r/ learnpython . Es posible que desee unirse al canal
#django si está trabajando en aplicaciones web.
Después de unirse a un canal, puede leer las conversaciones que tienen otras
personas y también hacer sus propias preguntas.
Para obtener ayuda efectiva, debe conocer algunos detalles sobre la cultura de IRC.
Centrarse en las tres preguntas al comienzo de este apéndice definitivamente lo guiará
hacia una solución exitosa. Las personas estarán felices de ayudarlo si puede explicar
con precisión lo que está tratando de hacer, lo que ya ha intentado y los resultados
exactos que está obteniendo. Si necesita compartir código o salida, los miembros de IRC
usan sitios externos creados para este propósito, como https:// bpaste.net/ +python. (Aquí es
donde #python lo envía a compartir código y salida). Esto evita que los canales se inunden
con código y también hace que sea mucho más fácil leer el código que la gente comparte.
Ser paciente siempre hará que la gente esté más dispuesta a ayudarte. Pregunta tu
pregunta de manera concisa y luego espera a que alguien responda. A menudo, las
personas están en medio de muchas conversaciones, pero por lo general alguien se dirigirá
a usted en un tiempo razonable. Si hay pocas personas en el canal, puede llevar un tiempo
obtener una respuesta.
Flojo
Slack es como una reinvención moderna de IRC. A menudo se usa para comunicaciones
internas de la empresa, pero también hay muchos grupos públicos a los que puede
unirse. Si desea consultar los grupos de Python Slack, comience con https://
pyslackers.com/. Haga clic en el enlace de Slack en la parte superior de la página e ingrese su dirección
de correo electrónico para recibir una invitación.
Una vez que esté en el espacio de trabajo de Python Developers, verá una lista de
canales. Haga clic en Canales y luego elija los temas que le interesen.
Es posible que desee comenzar con los canales #learning_python y #django .
Discordia
Discord es otro entorno de chat en línea con una comunidad de Python donde puede
solicitar ayuda y seguir debates relacionados con Python.
Para comprobarlo, diríjase a https:// pythondiscord.com/ y haga clic en Chatear ahora
Enlace. Debería ver una pantalla con una invitación generada automáticamente; haz clic
en Aceptar invitación. Si ya tiene una cuenta de Discord, puede iniciar sesión con su
cuenta existente. Si no tiene una cuenta, ingrese un nombre de usuario y siga las
indicaciones para completar su registro en Discord.
Si es la primera vez que visita Python Discord, deberá aceptar las reglas de
la comunidad antes de participar por completo. Una vez que hayas hecho eso, puedes
unirte a cualquiera de los canales que te interesen. Si está buscando ayuda, asegúrese
de publicar en uno de los canales de ayuda de Python.
484 Apéndice C
Machine Translated by Google
D
Uso de G it para el control de versiones
Instalando Git
Git se ejecuta en todos los sistemas operativos, pero existen diferentes enfoques para instalarlo
en cada sistema. Las siguientes secciones proporcionan instrucciones específicas para cada sistema
operativo.
Configuración de Git
Git realiza un seguimiento de quién realiza cambios en un proyecto, incluso cuando solo una persona
está trabajando en el proyecto. Para hacer esto, Git necesita saber su nombre de usuario y correo
electrónico. Debe proporcionar un nombre de usuario, pero puede inventar una dirección de correo
electrónico falsa:
Si olvida este paso, Git le pedirá esta información cuando realice su primera confirmación.
hacer un proyecto
Hagamos un proyecto para trabajar. Cree una carpeta en algún lugar de su sistema llamada
git_practice. Dentro de la carpeta, haz un programa Python simple:
486 Apéndice D
Machine Translated by Google
Ignorar archivos
Los archivos con la extensión .pyc se generan automáticamente a partir de archivos .py , por lo que no
necesitamos que Git realice un seguimiento de ellos. Estos archivos se almacenan en un directorio
llamado __pycache__. Para decirle a Git que ignore este directorio, crea un archivo especial
llamado .gitignore, con un punto al comienzo del nombre del archivo y sin extensión de archivo, y agrega la
siguiente línea:
.gitignore __pycache__/
Este archivo le dice a Git que ignore cualquier archivo en el directorio __pycache__ . Usando un
El archivo .gitignore mantendrá su proyecto ordenado y será más fácil trabajar con él.
Es posible que deba modificar la configuración de su editor de texto para que muestre los archivos
ocultos para poder abrir .gitignore. Algunos editores están configurados para ignorar los nombres de archivo
que comienzan con un punto.
Inicializar un repositorio
Ahora que tiene un directorio que contiene un archivo de Python y un archivo .gitignore , puede inicializar
un repositorio de Git. Abra una terminal, navegue hasta el git
carpeta _practice y ejecute el siguiente comando:
v Archivos sin
seguimiento: (use "git add <archivo>..." para incluir en lo que se confirmará)
.gitignore
hola_git.py
w no se agregó nada para confirmar, pero hay archivos sin rastrear presentes (use "git add" para rastrear)
git_practice$
En Git, una rama es una versión del proyecto en el que estás trabajando; aquí
puedes ver que estamos en una sucursal llamada master u. Cada vez que verifique el
estado de su proyecto, debería mostrar que está en el maestro de sucursales. Luego verá
que estamos a punto de hacer la confirmación inicial. Una confirmación es una instantánea
del proyecto en un momento determinado.
Git nos informa que los archivos sin rastrear están en el proyecto v, porque aún
no le hemos dicho qué archivos rastrear. Luego, se nos dice que no se agregó nada a la
confirmación actual, pero que hay archivos sin seguimiento que quizás deseemos agregar
al repositorio w.
git_practice$
El comando git agregar. agrega todos los archivos dentro de un proyecto que
aún no están siendo rastreados al repositorio u. No compromete los archivos; simplemente
le dice a Git que comience a prestarles atención. Cuando verificamos el estado del proyecto
ahora, podemos ver que Git reconoce algunos cambios que deben confirmarse v. La
etiqueta nuevo archivo significa que estos archivos se agregaron recientemente al repositorio
w.
Hacer un compromiso
Hagamos el primer commit:
488 Apéndice D
Machine Translated by Google
Emitimos el comando git commit -m "message" u para tomar una instantánea del proyecto.
El indicador -m le dice a Git que registre el mensaje que sigue ("Proyecto iniciado") en el registro
del proyecto. La salida muestra que estamos en el maestro
branch v y que dos archivos han cambiado w.
Cuando verificamos el estado ahora, podemos ver que estamos en el maestro
rama, y tenemos un árbol de trabajo limpio x. Este es el mensaje que desea ver cada
vez que confirma un estado de trabajo de su proyecto. Si recibe un mensaje diferente,
léalo detenidamente; es probable que haya olvidado agregar un archivo antes de
realizar una confirmación.
Proyecto iniciado.
git_practice$
Cada vez que realiza una confirmación, Git genera una ID de referencia única
de 40 caracteres. Registra quién realizó la confirmación, cuándo se realizó y el mensaje
grabado. No siempre necesitará toda esta información, por lo que Git ofrece una opción
para imprimir una versión más simple de las entradas de registro:
El segundo compromiso
Para ver el poder real del control de versiones, necesitamos hacer un cambio en el
proyecto y confirmar ese cambio. Aquí solo agregaremos otra línea a hola
_git.py:
v modificado: hello_git.py
w no se agregaron cambios para confirmar (use "git add" y/o "git commit -a")
git_practice$
Vemos la rama en la que estamos trabajando u, el nombre del archivo que se modificó
v, y que no se han confirmado cambios w. Confirmemos el cambio y verifiquemos el estado
nuevamente:
Hacemos una nueva confirmación, pasando las banderas -am cuando usamos el
comando git commit u. El indicador -a le dice a Git que agregue todos los archivos
modificados en el repositorio a la confirmación actual. (Si crea nuevos archivos entre
confirmaciones, simplemente vuelva a emitir el
archivos
comando
en git
el repositorio).
add . para incluir
El indicador
los nuevos
-m le
dice a Git que registre un mensaje en el registro para este
comprometerse.
Revertir un cambio
Ahora veamos cómo abandonar un cambio y volver al estado de trabajo anterior. Primero,
agrega una nueva línea a hello_git.py:
490 Apéndice D
Machine Translated by Google
no se agregaron cambios para confirmar (use "git add" y/o "git commit -a")
git_practice$
Aunque volver a un estado anterior puede parecer trivial en este proyecto simple,
si estuviéramos trabajando en un proyecto grande con docenas de archivos
modificados, todos los archivos que habían cambiado desde la última confirmación se revertirían.
Esta función es increíblemente útil: puede realizar tantos cambios como desee al
implementar una nueva función y, si no funcionan, puede descartarlos sin afectar el
proyecto. No tiene que recordar esos cambios y deshacerlos manualmente. Git hace
todo eso por ti.
N ota Puede que tenga que actualizar el archivo en su editor para ver la versión anterior.
Si desea crear una nueva rama para retener las confirmaciones que creó, puede hacerlo (ahora
o más tarde) usando -b con el comando de pago nuevamente. Ejemplo:
Este comando lo lleva de vuelta a la rama maestra . A menos que desee trabajar con
algunas funciones más avanzadas de Git, es mejor no realizar ningún cambio en su proyecto
cuando haya verificado una confirmación anterior. Sin embargo, si eres el único que trabaja en
un proyecto y deseas descartar todas las confirmaciones más recientes y volver a un estado
anterior, puedes restablecer el proyecto a una confirmación anterior. Trabajando desde la rama
maestra , ingrese lo siguiente:
492 Apéndice D
Machine Translated by Google
Borrando el Repositorio
A veces estropearás el historial de tu repositorio y no sabrás cómo recuperarlo. Si esto
sucede, primero considere pedir ayuda usando los métodos discutidos en el Apéndice C. Si
no puede arreglarlo y está trabajando en un proyecto en solitario, puede continuar trabajando
con los archivos pero deshacerse del historial del proyecto eliminando el directorio .git . Esto
no afectará el estado actual de ninguno de los archivos, pero eliminará todas las
confirmaciones, por lo que no podrá verificar ningún otro estado del proyecto.
Para hacer esto, abra un explorador de archivos y elimine el repositorio .git o elimínelo
desde la línea de comandos. Luego, deberá comenzar de nuevo con un repositorio nuevo
para comenzar a rastrear sus cambios nuevamente. Así es como se ve todo este proceso
en una sesión de terminal:
.gitignore
hola_git.py
no se agregó nada para confirmar, pero hay archivos sin rastrear presentes (use "git add" para rastrear)
z git_practice$ git agregar.
git_practice$ git commit -m "Volver a empezar". [master
(root-commit) 6baf231] Empezar de nuevo. 2 archivos
cambiados, 4 inserciones (+) modo de creación
100644 .gitignore modo de creación 100644 hello_git.py
{ git_practice$ git status En branch master nada que
confirmar, árbol de trabajo clean git_practice$
494 Apéndice D
Machine Translated by Google
Índice
Marcador, 288–289
Ajustes, 231
Barco, 233–235
finalizando el juego, 276
archivos
alien_invasion.py, 229
UN
bullet.py, 247 button.py,
adición (+), 26 alias, 280 game_stats.py, 273
152 alice.py, 197– scoreboard.py, 288
199 proyecto Alien settings.py, 231 ship.bmp,
Invasion. Véase también extraterrestres 233 inicializando
de Pygame configuraciones dinámicas,
286
comprobando bordes,
266 colisiones, con balas, agregar
268–269, 291–292 niveles, 285–287
colisiones, con barco, 272–275 modificar los ajustes
controlando la dirección de la flota, de velocidad,
266 creando un extraterrestre, 285 restablecer la velocidad,
256 287 planificar, 228
Machine Translated by Google
496 Índice
Machine Translated by Google
Índice 497
Machine Translated by Google
498 Índice
Machine Translated by Google
Y escribir
agregando, 193
temblores. Ver mapeo de
archivos vacíos, 191
terremotos
líneas múltiples, 192
electric_car.py, 168–173
first_numbers.py, 57
electric_car.py module, 178
flags, 120 floats, 26
función enumerate() , 335
foods.py, 63–65 for
variables de entorno, 456 epoch
loops, 49. Ver también
time, 366 eq_explore_data.py,
diccionarios;
348–351 operador de igualdad
(==), 72–73 eq_world_map.py ,
enumera formatted_name.py,
351–357 even_numbers.py, 58
138–140 full_name.py, 21–22
even_or_odd.py, 117 excepciones,
funciones, 129 alias (as), 152
183, 194–202
argumentos, 131–137
palabra clave arbitraria, 148
decidir qué errores informar,
número arbitrario de, 147
201 bloques else ,
evitar errores, 136 palabra
196 fallar silenciosamente,
clave, 133 listas como, 143–
200
146 mezclar posicional y
FileNotFoundError, 197
arbitrario, 148 opcional, 138
manejo, 194 bloques try-
orden de, 133 posicional,
except , 194 uso para
132–133 incorporado,
evitar bloqueos, 195
471 llamadas, 130–137
ZeroDivisionError, 194
llamadas equivalentes, 135–
exponentes (**), 26
136 varias veces, 132
definición, 130 diccionarios,
F
devolución, 140 listas en
favoritos_idiomas.py, 97–98 modificación , 143–145
FileNotFoundError, 197 proteger, 145 módulos, 150–
file_reader.py, 184–188 cierre 155 alias (as), 153 importar todas
de archivos, 185 rutas de las funciones (*), 153 importar
módulos completos, 150 importar
archivo, 185 absoluto, 186
relativo, 186 apertura, 184 funciones específicas, 152
modo agregar, 192 parámetros, valores
modo lectura, 192 modo predeterminados para, 134 pasar
escritura, 192 lectura desde, información a. Ver funciones:
184 –190 archivos valores de retorno de
completos, 184–185 argumentos, 137–142
línea por línea, 187 estilo, 154
hacer una lista de líneas,
188 trabajar con
contenidos, 188 trabajar
con archivos grandes, 189
Índice 499
Machine Translated by Google
GRAMO H
juegos. Ver proyecto Alien Invasion; Hacker News, 372
Pygame Geany, 476 hash mark (#), para comentarios, 29
solicitudes GET, 412 obtener ayuda head, de un archivo HTML, 440 HEAD
Discord, 484 IRC (Internet Relay Chat), (Git), 492 Hello World, 9 hello_git.py,
482–483 documentación oficial de Python, 486–491 hello_world.py, 10, 15–19
481 Heroku, 437. Véase también Django;
Git; Proyecto de registro de aprendizaje
Bash shell, 454 CLI, instalación, 458
configuración de comandos,
458 destruir, 462 iniciar sesión, 453
recursos en línea, 480 r/ abrir, 453 ps, 453 renombrar, 455
learnpython, 482 ejecutar, 454 establecer, 458 bases
depuración de patitos de goma, de datos, configurar, 454 paquete
480 Slack, 483 Stack Overflow, 481 django-heroku , 448
tres preguntas principales, 479 Git, documentación , 453 variables
360, 450 sucursales, 452, 488 de entorno, configuración, 456–
confirmaciones, 360, 450 comprobación, 458 páginas de error,
491–493 creación, 452 , 457, 460, personalizado, 458–460 plan
488, 490, 493 configurar, 451, 486 gratuito, limitaciones de, 448,
HEAD separado, 492 agregar 456 creación de una cuenta, 448
archivos, 452, 460, 488, 493 Procfile, 450 eliminación de
ignorar, 451, 487 HEAD, 492 proyectos, 461 envío a Heroku, 452–
instalar, 450, 486 registrar, verificar, 453, 457 visualización en directo ,
489 repositorios, 360 eliminar, 493 453 Tiempo de ejecución de Python,
inicializar, 452, 487, 493 revertir especificación, 449
cambios, 490 estado, verificar, requisitos.txt, 448–449 protección,
452, 457, 487–493 GitHub, 360 456 settings.py, modificación para,
mayor que (>), 75 mayor que o igual 450, 456, 459 superusuario,
a (>=), 75 greetinger.py, 114, 130–131 creación, 454–455 URL, fácil de usar,
greeting_users.py, 143 paquete 455 archivos ocultos, 451
gunicorn , 448
Índice 500
Machine Translated by Google
hn_article.py, 372 j
hn_submissions.py, 373
Archivos JSON
Elaboración casera, 469
que examinan datos, 347
formato de archivo geoJSON, 349
yo
función json.dump() , 348 función
Índice 501
Machine Translated by Google
linux METRO
Índice 502
Machine Translated by Google
norte
módulos; funciones:
módulos parámetros, 131
operador módulo (%), 116–117, 122 clases de padres, 167. Consulte también
clases: herencia loro.py, 114,
motocicletas.py, 37–42 mountain_poll.py, 126
mpl_squares.py, 306–310 multiplicación (*), 26 118–121 declaración de paso , 200 PEP 8, 68–
my_car.py, 175 my_cars.py, 177–179 70, 90, 154 persona.py, 140–142 mascotas.py,
Índice 503
Machine Translated by Google
Índice 504
Machine Translated by Google
q cadenas f, 21
nuevas líneas, 22
valores para dejar de fumar, 118–120
comillas simples y dobles, 19, 24
tabulaciones, 22 uso de variables, 21
R
espacio en blanco, 22–24 método
random_walk.py, 316–317 strptime() , 338 pautas de estilo, 68–70
paseos aleatorios, 315–323 líneas en blanco, 69
función choice() , 317 puntos
de color, 319 método
fill_walk() , 316 paseos CamelCase, 181
múltiples, generación, 318 trazado, 317 clases, 181
Clase RandomWalk , 316 puntos de inicio funciones, 154
y fin, 320 rango( ) función, 57–59 método sentencias if , 90
readlines() , 188 método read() , 185 sangría, 69 longitud
refactorización, 206–208, 236 recordar_me.py, de línea, 69
204–208 Paquete de solicitudes, 361 valores PEP 8, 68
devueltos, 137 r/learnpython, 482 Texto sublime, 4–10, 474–475
rollercoaster.py, 116 tirando dados, 323–330 comentar el código, 475 configurar,
analizando resultados, 325 Clase de dado , 9 personalizar, 474 sangrar y quitar
324 tamaños diferentes, 329 función randint() , sangría de bloques de código, 474
324 dos dados, 328 depuración de pato de instalar, 7–9 indicador de longitud
goma, 480 rw_visual.py, 317–323 de línea, 474 ejecutar
programas de Python, 9–10 guardar
su configuración, 475 tabuladores y
espacios, 474 restar (-), 26 superclases,
168. Ver también clases: herencia
encuesta.py, 217 errores de sintaxis, 24
resaltado de sintaxis, 16
scatter_squares.py, 311–315
sets, 104 sitka_highs_lows.py, T
Índice 505
Machine Translated by Google
test_name_function.py, 211–215 En
variables, 16–19, 28
constantes, 28 como Zen de Python, 30–31
etiquetas, 18 Error de división cero, 194
asignación múltiple, 28
convenciones de nomenclatura,
17 valores, 16 sistema de
control de versiones, 485.
Consulte
también el entorno virtual de Git (venv),
380 vote.py, 79–80
Índice 506
Machine Translated by Google
Python Crash Course, 2nd Edition está ambientado en New Baskerville, Futura,
Dogma y The Sans Mono Condensed.
Machine Translated by Google
RECURSOS
Visite https:// nostarch.com/ pythoncrashcourse2e/ para obtener recursos, erratas y
más información.
Belt Advice on Deployment, ejemplos de las tarjetas Python withPython Una guía
Scalability, Testing, and More por Flash por eric matthes enero de ilustrada para explorar
julien danjou diciembre de 2018, 2019, 101 tarjetas, $ 27.95 isbn las matemáticas con
240 págs., $34,95 isbn 978-1-59327-878-6 978-1-59327-896-0 a todo color código por peter farrell
enero de 2019, 304 págs., $29,95
isbn 978-1-59327-867-0 a todo color
Proyectos poco prácticos de Python Aprenda robótica con ¡ Mission Python Code
MUNDIAL
MUNDIAL
MEJOR VENDIDO
MEJOR VENDIDO
APRENDER PITÓN —
¡RÁPIDO!
MÁS DE
MÁS DE 500.000
500.000
COPIAS VENDIDAS
COPIAS VENDIDAS
Python Crash Course es la guía más vendida del mundo sobre el • Cree y personalice aplicaciones web e impleméntelas
lenguaje de programación Python. Esta introducción rápida y completa de forma segura en línea