Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2.8. Entrada
El programa de la sección anterior funciona bien, pero es muy limitado, ya que sólo funciona con un valor para
total_secs. ¿Qué pasaría si quisiéramos reescribir el programa para que fuera más general? Una cosa que
podríamos hacer es permitir al usuario introducir cualquier valor que desee para el número de segundos. El programa
podría entonces imprimir el resultado apropiado para ese valor inicial.
Para ello, necesitamos una forma de obtener la entrada del usuario. Por suerte, en Python hay una función
incorporada para realizar esta tarea. Como es de esperar, se llama input.
La función de entrada permite que el usuario proporcione una cadena de instrucciones. Cuando se evalúa la función,
se muestra el prompt. El usuario del programa puede introducir el nombre y pulsar return. Cuando esto sucede, el
texto que se ha introducido se devuelve desde la función de entrada, y en este caso se asigna a la variable n. Asegúrese
de ejecutar este ejemplo varias veces y pruebe algunos nombres diferentes en el cuadro de entrada que aparece.
Es muy importante tener en cuenta que la función de entrada devuelve un valor de cadena. Incluso si le pides al
usuario que introduzca su edad, obtendrás una cadena como "17". Sería tu trabajo, como programador, convertir esa
cadena en un int o un float, usando las funciones de conversión de int o float que vimos antes.
Para modificar nuestro programa anterior, añadiremos una sentencia de entrada que permita al usuario introducir el
número de segundos. Luego convertiremos esa cadena a un número entero. A partir de ahí el proceso es el mismo que
antes. Para completar el ejemplo, imprimiremos una salida apropiada.
La variable str_seconds hará referencia a la cadena introducida por el usuario. Como dijimos
anteriormente, aunque esta cadena sea 7684, sigue siendo una cadena y no un número. Para convertirla en un
número entero, utilizamos la función int. El resultado se denomina total_secs. Ahora, cada vez que ejecute el
programa, puede introducir un nuevo valor para el número de segundos a convertir.
Compruebe su comprensión
A. <class 'str'>
B. <class 'int'>
C. <class 18>
D. 18
data-8-5: Haga clic en todas las variables de tipo `int` en el código siguiente
data-8-6: Haga clic en todas las variables de tipo `str` en el código siguiente
1.Los paréntesis tienen la mayor precedencia y pueden utilizarse para forzar que una expresión se evalúe en el orden
que se desee. Como las expresiones entre paréntesis se evalúan primero, 2 * (3-1) es 4, y (1+1)**(5-2)
es 8. También puedes usar paréntesis para hacer que una expresión sea más fácil de leer, como en (minuto *
100) / 60, aunque no cambie el resultado.
2.La exponenciación tiene la siguiente precedencia, por lo que 2**1+1 es 3 y no 4, y 3*1**3 es 3 y no 27.
¿Puedes explicar por qué?
3.La multiplicación y los dos operadores de división tienen la misma precedencia, que es mayor que la suma y la
resta, que también tienen la misma precedencia. Así, 2*3-1 da 5 en lugar de 4, y 5-2*2 es 1, no 6.
4.Los operadores con la misma precedencia (excepto **) se evalúan de izquierda a derecha. En álgebra decimos que
son asociativos a la izquierda. Así, en la expresión 6-3+2, primero se realiza la resta, obteniendo 3. A continuación,
sumamos 2 para obtener el resultado 5. Si las operaciones se hubieran evaluado de derecha a izquierda, el resultado
habría sido 6-(3+2), que es 1.
Nota
Una excepción a la regla asociativa de izquierda a derecha es el operador de exponenciación **. Un consejo útil es
utilizar siempre paréntesis para forzar exactamente el orden que se desea cuando hay exponenciación:
Vea la tabla de precedencia de operadores para todos los operadores introducidos en este libro. También verás muchos
operadores no matemáticos de Python próximos.
Compruebe su comprensión
16 - 2 * 5 // 3 + 1
A. 14
B. 24
C. 3
D. 13.667
2 ** 2 ** 3 * 3
A. 768
B. 128
C. 12
D. 256
2.10. Reasignación
Como hemos mencionado anteriormente, es legal hacer más de una asignación a la misma variable. Una nueva
asignación hace que una variable existente se refiera a un nuevo valor (y deje de referirse al valor anterior).
La primera vez que se imprime bruce, su valor es 5, y la segunda vez, su valor es 7. La sentencia de
asignación cambia el valor (el objeto) al que se refiere bruce.
Es importante tener en cuenta que en matemáticas, una declaración de igualdad es siempre verdadera.
Si a es igual a b ahora, entonces a siempre será igual a b. En Python, una
sentencia de asignación puede hacer que dos variables se refieran al mismo objeto y por lo tanto tengan
el mismo valor. Parece que son iguales. Sin embargo, debido a la posibilidad de reasignación, no tienen
por qué permanecer así:
a=5
b = a # después de ejecutar esta línea, a y b son ahora iguales
print(a, b)
a = 3 # después de ejecutar esta línea, a y b ya no son iguales
print(a, b)
La línea 4 cambia el valor de a pero no cambia el valor de b, por lo que ya no son iguales. Tendremos mucho más
que decir sobre la igualdad en un capítulo posterior.
2.10.1. Desarrollar su modelo mental de Cómo
evalúa Python
Es importante empezar a desarrollar un buen modelo mental de los pasos que sigue Python cuando evalúa una
sentencia de asignación. En una sentencia de asignación, Python primero evalúa el código a la derecha del operador de
asignación. Luego le da un nombre a lo que sea. La (muy corta) visualización de abajo muestra lo que sucede.
a = 5
b = a
a=5
b=a
Nota
En algunos lenguajes de programación, se utiliza un símbolo diferente para la asignación, como <- o :=.
La intención es que esto ayude a evitar confusiones. Python eligió utilizar los símbolos = para la
asignación , y == para la igualdad. Esta es una opción popular que también se encuentra en lenguajes
x = 15
y=x
x = 22
A. x is 15 and y is 15
B. x is 22 and y is 22
C. x is 15 and y is 22
D. x is 22 and y is 15
2.11. Actualización de variables
Una de las formas más comunes de reasignación es una actualización en la que el nuevo valor de la variable depende
del anterior. Por ejemplo,
x=x+1
Esto significa obtener el valor actual de x, añadir uno, y luego actualizar x con el nuevo valor. El nuevo valor de x es
el antiguo valor de x más 1. Aunque esta sentencia de asignación puede parecer un poco extraña, recuerde que la
ejecución de la asignación es un proceso de dos pasos. Primero, evalúa la expresión del lado derecho. Segundo, que el
nombre de la variable del lado izquierdo se refiera a este nuevo objeto resultante. El hecho de que x aparezca en
ambos lados no importa. La semántica de la sentencia de asignación asegura que no hay confusión en cuanto al
resultado. El visualizador lo deja muy claro.
x = 6 # inicializar x
print(x)
x = x + 1 # actualizar x
print(x)
Si intentas actualizar una variable que no existe, obtendrás un error porque Python evalúa la expresión del lado
derecho del operador de asignación antes de asignar el valor resultante al nombre de la izquierda. Antes de actualizar
una variable, hay que inicializarla, normalmente con una simple asignación. En el ejemplo anterior, x se
inicializó a 6.
Actualizar una variable añadiendo 1 se llama incremento; restar 1 se llama decremento. A veces, los programadores
también hablan de "bumping" de una variable, que significa lo mismo que incrementarla en 1.
Temas avanzados
Tema 1: Python más allá del navegador. Esta es una suave introducción al uso de Python desde la línea de
comandos. Cubriremos esto más adelante, pero si tienes curiosidad por saber cómo es Python fuera de
este eBook, puedes echar un vistazo aquí. También hay instrucciones para instalar Python en tu
ordenador aquí.
Tema 2: Dive Into Python 3, este es un libro de texto online de Mark Pilgrim. Si ya tienes algo de
experiencia en programación, este libro te lleva a lo más profundo con ambos pies.
Compruebe su comprensión
x = 12
x=x-1
print(x)
A. 12
B. -1
C. 11
D. Nada. Se produce un error porque x nunca puede ser igual a x - 1.
x = 12
x=x-3
x=x+5
x=x+1
print(x)
A. 12
B. 9
C. 15
D. Nada. Se produce un error porque x no puede utilizarse tantas veces en las sentencias de
asignación.
2.12. Glosario
declaración de asignación
Declaración que asigna un valor a un nombre (variable). A la izquierda del operador de asignación, =, hay
un nombre. A la derecha del token de asignación hay una expresión que es evaluada por el intérprete de Python
y luego asignada al nombre. La diferencia entre los lados izquierdo y derecho de la sentencia de asignación es a
menudo confusa para los nuevos programadores. En la siguiente asignación:
n=n+1
n juega un papel muy diferente a cada lado del =. A la derecha es un valor y forma parte de la expresión que
será evaluada por el intérprete de Python antes de asignarla al nombre de la izquierda.
ficha de asignación
= es el token de asignación de Python, que no debe confundirse con el operador matemático de comparación
que utiliza el mismo símbolo.
clase
comentario
Información en un programa que está destinada a otros programadores (o a cualquiera que lea el código fuente)
y que no tiene ningún efecto sobre la ejecución del programa.
tipo de datos
Un conjunto de valores. El tipo de un valor determina cómo puede utilizarse en las expresiones. Hasta ahora,
los tipos que has visto son enteros (int), números de punto flotante (float) y cadenas (str).
decremento
Disminuye en 1.
evaluar
Simplificar una expresión realizando las operaciones para obtener un único valor.
expresión
Una combinación de operadores y operandos (variables y valores) que representa un único valor de resultado.
Las expresiones se evalúan para obtener ese resultado.
float
Un tipo de datos de Python que almacena números de punto flotante. Los números de punto flotante se
almacenan internamente en dos partes: una base y un exponente. Cuando se imprimen en el formato estándar,
parecen números decimales. Tenga cuidado con los errores de redondeo cuando utilice números
flotantes, y recuerde que sólo son valores aproximados.
incrementar
Inicializar una variable es darle un valor inicial. Como en Python las variables no existen hasta que se les
asignan valores, se inicializan cuando se crean. En otros lenguajes de programación esto no es así, y las
variables pueden ser creadas sin ser inicializadas, en cuyo caso tienen valores por defecto o basura.
int
Un tipo de datos de Python que contiene números enteros positivos y negativos.
división de enteros
Operación que divide un número entero entre otro y da como resultado un número entero. La división de
enteros produce sólo el número entero de veces que el numerador es divisible por el denominador y descarta
cualquier resto.
palabra clave
Una palabra reservada que es utilizada por el compilador para analizar el programa; no se pueden utilizar
palabras clave como if, def y while como nombres de variables.
operador de módulo
También llamado operador del resto o operador del resto de enteros. Da el resto después de realizar la división
de enteros.
objeto
También conocido como objeto de datos (o valor de datos). Las cosas fundamentales que los programas están
diseñados para manipular (o que los programadores piden que hagan cosas por ellos).
operando
operador
Símbolo especial que representa un cálculo simple como la suma, la multiplicación o la concatenación de
cadenas.
cadena de preguntas
Se utiliza durante la entrada interactiva para proporcionar al usuario pistas sobre el tipo de valor que debe
introducir.
diagrama de referencia
Imagen que muestra una variable con una flecha que señala el valor (objeto) al que se refiere la variable. Véase
también instantánea de estado.
reglas de precedencia
Conjunto de reglas que rigen el orden de evaluación de las expresiones que incluyen varios operadores y
operandos.
instantánea del estado
Representación gráfica de un conjunto de variables y de los valores a los que se refieren, tomados en un
instante determinado de la ejecución del programa.
declaración
Una instrucción que el intérprete de Python puede ejecutar. Hasta ahora sólo hemos visto la sentencia
assignment, pero pronto conoceremos la sentencia import y la sentencia for.
str
valor
Un número o una cadena (u otras cosas que se nombrarán más adelante) que puede almacenarse en una variable
o calcularse en una expresión.
variable
nombre de la variable
Un nombre dado a una variable. Los nombres de las variables en Python consisten en una secuencia de letras
(a..z, A..Z, y _) y dígitos (0..9) que comienza con una letra. En las mejores prácticas de programación, los
nombres de las variables deben ser elegidos de manera que describan su uso en el programa, haciendo que el
programa se auto documente.
La programación es una cosa extraña en cierto modo. He aquí la razón. Como programadores, pasamos el 99% de
nuestro tiempo intentando que nuestro programa funcione. Nos esforzamos, nos estresamos, pasamos horas de
frustración intentando que nuestro programa se ejecute correctamente. Luego, cuando conseguimos que funcione, lo
celebramos, lo entregamos y pasamos a la siguiente tarea o trabajo de programación. Pero aquí está el secreto, cuando
tienes éxito, eres feliz, tu cerebro libera un poco de química que te hace sentir bien. Tienes que organizar tu
programación de manera que tengas muchos pequeños éxitos. Resulta que a tu cerebro no le importa mucho si has
escrito con éxito "hello world" o una transformada rápida de Fourier (créeme, es difícil), pero sigues obteniendo esa
pequeña liberación que te hace feliz. Cuando te sientes feliz quieres seguir adelante y resolver el siguiente pequeño
problema. Esencialmente te estoy diciendo una vez más, empieza con algo pequeño, haz algo pequeño que funcione, y
luego añádelo.
La técnica de empezar poco a poco y seguir mejorando es la base del desarrollo ágil de software.
print(current_time)
print(wait_time)
Hasta aquí todo bien. Ahora vamos a dar el siguiente paso. Tenemos que averiguar cuál será el tiempo después de
esperar el número de horas de wait_time. Una solución razonable es simplemente sumar wait_time a
current_time e imprimir el resultado. Así que vamos a intentar eso.
current_time = input("What is the current time (in hours 0 - 23)?")
wait_time = input("How many hours do you want to wait")
print(current_time)
print(wait_time)
Hmm, cuando ejecutas este ejemplo ves que ha ocurrido algo inesperado. No te darías cuenta de que se trata de un
error si no supieras primero lo que se supone que debe hacer el programa.
debug-2-3: ¿Cuál de las siguientes opciones describe mejor lo que está mal en el ejemplo anterior?
Entonces, ¿qué hacemos con el problema? Tendremos que convertir tanto current_time como wait_time
a int. A estas alturas del desarrollo de la programación, puede ser una buena idea incluir el tipo de la variable en el
propio nombre de la misma. Así que veamos otra iteración del programa que hace eso, y la conversión a entero.
current_time_int = int(current_time_str) Ah
wait_time_int = int(wait_time_str) ora
final_time_int = current_time_int + wait_time_int
,
print(final_time_int)
esto es mucho mejor, y de hecho, dependiendo de las horas que haya elegido, puede ser exactamente correcto. Si has
introducido 8 para hora_actual y 5 para tiempo_de_espera, entonces 13 es correcto.
Pero si introdujo 17 (5 pm) para current_time y 9 para wait_time entonces el resultado de 26
no es correcto.
Esto ilustra un aspecto importante de las pruebas: es importante probar el código con una serie de entradas. Es
especialmente importante probar su código en condiciones límite. Para este problema en particular, debe probar su
programa con current_time de 0, 23, y algunos valores entre ellos. Deberías probar tu wait_time
para 0, y algunos valores mayores. ¿Qué pasa con los números negativos? Los números negativos no tienen sentido, y
ya que no tenemos las herramientas para decirle al usuario cuando algo está mal, no nos preocuparemos por eso
todavía.
Así que para tener en cuenta esos números mayores que 23, necesitamos un último paso: utilizar el operador de
módulo.
current_time_int = int(current_time_str)
wait_time_int = int(wait_time_str)
final_answer = final_time_int % 24
Por
supuesto, incluso en esta sencilla progresión, hay otras formas en las que podrías haberte desviado. Veremos algunas
de ellas y cómo se pueden rastrear en la siguiente sección.
3.3. Consejos iniciales para la
depuración
Depurar un programa es una forma de pensar diferente a la de escribir un programa. El proceso de depuración es
mucho más parecido al de un detective. He aquí algunas reglas para empezar a pensar en la depuración.
1. ¡Todo el mundo es sospechoso (excepto Python)! Es común que los programadores principiantes culpen a Python,
pero ese debería ser su último recurso. Recuerda que Python ha sido utilizado para resolver problemas de nivel CS1
millones de veces por millones de otros programadores. Por lo tanto, Python probablemente no es el problema.
2. Encontrar pistas. Este es el mayor trabajo del detective y en este momento hay dos tipos importantes de pistas que
debes entender.
Mensajes de error
Imprimir declaraciones
current_time_int = int(current_time_str)
wait_time_int = int(wait_time_int)
¿Puedes ver lo que está mal, simplemente mirando el código? Puede que sí, puede que no. Nuestro cerebro tiende a
ver lo que creemos que está ahí, así que a veces es muy difícil encontrar el problema sólo mirando el código.
Especialmente cuando se trata de nuestro propio código y estamos seguros de que lo hemos hecho todo bien.
current_time_int = int(current_time_str)
wait_time_int = int(wait_time_int)
Nota
Las descripciones de errores que ve en activecode pueden ser diferentes (¡y más comprensibles!) que en un
intérprete de Python normal. El intérprete en activecode está limitado en muchos aspectos, pero está pensado
A. No se puede utilizar una variable tanto en el lado izquierdo como en el derecho de una sentencia de
asignación.
Al escribir y utilizar este libro durante los últimos años hemos recogido muchas estadísticas sobre los programas de
este libro. Aquí hay algunas estadísticas sobre los mensajes de error para el ejercicio que hemos estado viendo.
TimeLimitError: 44 0.48%
Message Number Percent
IndentationError: 28 0.31%
AttributeError: 27 0.30%
ImportError: 16 0.18%
IndexError: 6 0.07%
Casi el 90% de los mensajes de error encontrados para este problema son ParseError, TypeError, NameError o
ValueError. Veremos estos errores en tres etapas:
3.4.1. ParseError
Los errores de análisis ocurren cuando se comete un error en la sintaxis de su programa. Los errores de sintaxis son
como cometer errores gramaticales al escribir. Si no usas puntos y comas en tu escritura, estás dificultando que otros
lectores entiendan lo que estás tratando de decir. Del mismo modo, Python tiene ciertas reglas gramaticales que deben
seguirse o de lo contrario Python no puede entender lo que estás tratando de decir.
Normalmente, los ParseErrors pueden deberse a la falta de caracteres de puntuación, como paréntesis, comillas o
comas. Recuerda que en Python las comas se utilizan para separar los parámetros de las funciones. Los paréntesis
deben estar equilibrados, o de lo contrario Python piensa que estás tratando de incluir todo lo que sigue como un
parámetro a alguna función.
Aquí hay un par de ejemplos de errores de análisis en el programa de ejemplo que hemos estado utilizando. A ver si
puedes averiguar la causa de los mismos.
current_time_int = int(current_time_str)
wait_time_int = int(wait_time_str)
Encontrar pistas ¿Cómo puede ayudarse a sí mismo a encontrar estos problemas? Un truco que puede ser muy
valioso en esta situación es simplemente empezar comentando el número de línea que está marcado como error. Si
comentas la línea cuatro, el mensaje de error pasa a apuntar a la línea 5. Ahora te preguntarás, ¿realmente soy tan malo
que tengo dos líneas seguidas con errores? Tal vez, así que llevado al extremo, podrías comentar todas las líneas
restantes del programa. Ahora el mensaje de error cambia a TokenError: EOF in multi-line
statement Esta es una forma muy técnica de decir que Python llegó al final del archivo (EOF) mientras todavía
estaba buscando algo. En este caso un paréntesis derecho.
current_time_int = int(current_time_str)
wait_time_int = int(wait_time_str)
Encontrar pistas Si sigue el mismo consejo que para el último problema, comentando la línea uno, obtendrá
inmediatamente un mensaje de error diferente. Aquí es donde tienes que tener mucho cuidado y no entrar en pánico.
El mensaje de error que se obtiene ahora es NameError: el nombre 'current_time_str' no
está definido en la línea 4. Podrías estar muy tentado a pensar que esto está de alguna manera
relacionado con el problema anterior e inmediatamente concluir que hay algo mal con el nombre de la variable
current_time_str pero si reflexionas un minuto verás que al comentar la línea uno has causado un nuevo
error no relacionado. Es decir, has comentado la creación del nombre current_time_str. Así que, por
supuesto, cuando quieras convertirlo en un int obtendrás el error NameError. Sí, esto puede ser confuso, pero se
hará mucho más fácil con la experiencia. También es importante mantener la calma, y evaluar cada nueva pista
cuidadosamente para no perder el tiempo persiguiendo problemas que realmente no existen.
Descomente la línea 1 y volverá al ParseError. Otra vía es eliminar una posible fuente de error. En lugar de comentar
toda la línea, puede intentar asignar current_time_str a un valor constante. Por ejemplo, puede hacer que la
línea uno se vea así: current_time_str = "10" #input("¿Cuál es la "hora actual" (en
horas 0-23)?"). Ahora has asignado a current_time_str la cadena 10, y has comentado la
sentencia input. ¡Y ahora el programa funciona! Así que concluyes que el problema debe tener algo que ver con la
función de entrada.
3.4.2. TypeError
Los errores de tipo se producen cuando se intenta combinar dos objetos que no son compatibles. Por ejemplo, se
intenta sumar un entero y una cadena. Por lo general, los errores de tipo pueden aislarse en las líneas que utilizan
operadores matemáticos, y normalmente el número de línea dado por el mensaje de error es una indicación precisa de
la línea.
Este es un ejemplo de un error de tipo creado por un alumno polaco. Vea si puede encontrar y corregir el error.
a = input('wpisz godzine')
x = input('wpisz liczbe godzin')
int(x)
int(a)
h = x // 24
s = x % 24
print (h, s)
a=a+s
print ('godzina teraz', a)
Encontrar pistas Una cosa que puede ayudarte en esta situación es imprimir los valores y los tipos de las variables
involucradas en la sentencia que está causando el error. Puedes intentar añadir una sentencia print después de la línea
4 print(x, type(x)) Verás que al menos hemos confirmado que x es de tipo string. Ahora tienes que
empezar a trabajar hacia atrás en el programa. Tienes que preguntarte, ¿dónde se utiliza x en el programa? x se utiliza
en las líneas 2, 3, y por supuesto 5 y 6 (donde estamos obteniendo un error). Así que tal vez mueva la declaración de
impresión para estar después de la línea 2 y de nuevo después de la 3. La línea 3 es donde se espera que el valor de x
se cambie a un entero. ¿Podría la línea 4 estar cambiando misteriosamente x de nuevo a una cadena? No es muy
probable. Así que el valor y el tipo de x es el que se espera después de la línea 2, pero no después de la línea 3. Esto le
ayuda a aislar el problema en la línea 3. De hecho, si empleas una de nuestras técnicas anteriores de comentar la línea
3, verás que esto no tiene ningún impacto en el error, y es una gran pista de que la línea 3, tal y como está escrita
actualmente, es inútil.
Encontrar pistas Con los errores de nombre una de las mejores cosas que puedes hacer es utilizar el editor, o la
función de búsqueda del navegador. A menudo, si busca la palabra exacta en el mensaje de error, sucederá una de estas
dos cosas:
1. La palabra que buscas aparecerá sólo una vez en tu código, también es probable que esté a la derecha de una sentencia
de asignación, o como parámetro de una función. Esto debería confirmarle que tiene un error tipográfico en alguna
parte. Si el nombre en cuestión es lo que pensabas que debía ser, entonces probablemente tienes un error tipográfico
en el lado izquierdo de una sentencia de asignación en una línea antes de que aparezca el mensaje de error. Empieza a
mirar hacia atrás en tus sentencias de asignación. En algunos casos es muy bueno dejar visibles todas las cadenas
resaltadas de la función de búsqueda, ya que le ayudarán a encontrar rápidamente una línea en la que podría haber
esperado que su variable estuviera resaltada.
2. La segunda cosa que puede suceder es que usted estará mirando directamente a una línea en la que esperaba que la
búsqueda encontrara la cadena en cuestión, pero no estará resaltada. La mayoría de las veces será el error tipográfico
justo ahí.
3.4.4. ValueError
Los errores de valor se producen cuando se pasa un parámetro a una función y la función espera ciertas limitaciones
en los valores, y el valor pasado no es compatible. Podemos ilustrar esto con este programa en particular de dos
maneras diferentes.
Los ValueErrors no siempre son causados por un error de entrada del usuario, pero en este programa ese es el caso.
Volveremos a ver los ValueErrors cuando lleguemos a programas más complicados. Por ahora vale la pena repetir que
necesitas mantener un registro de las restricciones necesarias para tus variables, y entender lo que tu función está
esperando. Puedes hacer esto escribiendo comentarios en tu código, o nombrando tus variables de manera que te
recuerden su forma correcta.
3.5. Resumen
Asegúrate de que te tomas el tiempo necesario para entender los mensajes de error. Pueden ayudarte mucho.
Las sentencias print son tus amigas. Utilízalas para ayudarte a descubrir lo que realmente ocurre en tu código.
Trabaje hacia atrás desde el error. Muchas veces un mensaje de error es causado por algo que ha sucedido antes en el
programa. Recuerda siempre que python evalúa un programa de arriba a abajo.