Desarrolla Juegos en Python Part 2
Desarrolla Juegos en Python Part 2
Capítulo 4
ADIVINA EL NÚMERO
Temas Tratados En Este Capítulo:
• Sentencias import
• Módulos
• Sentencias while
• Condiciones
• Bloques
• Booleanos
• Operadores de comparación
• La diferencia entre = y ==
• Sentencias if
• La palabra reservada break
• Las funciones str(), int() y float()
• La función random.randint()
En este capítulo crearás el juego “Adivina el Número”. La computadora pensará un número
aleatorio entre 1 y 20, y te pedirá que intentes adivinarlo. La computadora te dirá si cada intento
es muy alto o muy bajo. Tú ganas si adivinas el número en seis intentos o menos.
Este es un buen juego para codificar ya que usa números aleatorios y bucles, y recibe entradas del
usuario en un programa corto. Aprenderás cómo convertir valores a diferentes tipos de datos, y
por qué es necesario hacer esto. Dado que este programa es un juego, nos referiremos al usuario
como el jugador. Pero llamarlo “usuario” también sería correcto.
Alberto
10
Tu estimación es muy alta.
Intenta adivinar.
2
Capítulo 4 – Adivina el Número 27
4
¡Buen trabajo, Alberto! ¡Has adivinado mi número en 3 intentos!
Si obtienes errores luego de copiar este código, compáralo con el código del libro usando la
herramienta diff online en http://invpy.com/es/diff/adivinaElNúmero.
adivinaElNúmero.py
# Este es el juego de adivinar el número.
import random
intentosRealizados = 0
10. print('Bueno, ' + miNombre + ', estoy pensando en un número entre 1 y 20.')
11.
13. print('Intenta adivinar.') # Hay cuatro espacios delante de print.
estimación = input()
14.
15. estimación = int(estimación)
intentosRealizados = intentosRealizados + 1
16.
17.
19.
Capítulo 4 – Adivina el Número 28
21.
if estimación > número:
22.
print('Tu estimación es muy alta.')
23.
24.
25. if estimación == número:
28. if estimación == número:
29. intentosRealizados = str(intentosRealizados)
30. print('¡Buen trabajo, ' + miNombre + '! ¡Has adivinado mi número en ' +
intentosRealizados + ' intentos!')
31.
32.
33. if estimación != número:
número = str(número)
34. print('Pues no. El número que estaba pensando era ' + número)
Sentencias import
La primera línea es un comentario. Recuerda que Python ignorará todo lo que esté precedido por
el signo #. Esto sólo nos indica qué es lo que hace el programa.
La segunda línea es una sentencia import. Recuerda, las sentencias son instrucciones que realizan
alguna acción, pero no son evaluadas a un valor como las expresiones. Ya has visto sentencias
antes: las sentencias de asignación almacenan un valor en una variable.
Aunque Python incluye muchas funciones integradas, algunas funciones existen en programas
separados llamados módulos. Puedes usar estas funciones importando sus módulos en tu
programa con una sentencia import.
La línea 2 importa el módulo llamado random de modo que el programa pueda llamar a
random.randint(). Esta función generará un número aleatorio para que el usuario adivine.
4. intentosRealizados = 0
La línea 4 crea una nueva variable llamada intentosRealizados. Guardaremos en esta variable
el número de veces que el jugador ha intentado adivinar el número. Ya que el jugador no ha
realizado ningún intento a esta altura del programa, guardaremos aquí el entero 0.
7. miNombre = input()
Las líneas 6 y 7 son iguales a las líneas en el programa Hola Mundo que viste en el Capítulo 3.
Los programadores a menudo reutilizan código de sus otros programas para ahorrarse trabajo.
La línea 6 es una llamada a la función print(). Recuerda que una función es como un mini-
programa dentro de tu programa. Cuando tu programa llama a una función, ejecuta este mini-
programa. El código dentro de la función print() muestra en la pantalla la cadena que ha
recibido como argumento.
La Función random.randint()
La línea 9 llama a una nueva función denominada randint() y guarda el valor que ésta devuelve
en la variable número. Recuerda, las llamadas a funciones pueden ser parte de expresiones, ya que
son evaluadas a un valor.
La función randint() es parte del módulo random, por lo que debes colocar random. delante de
ella (¡no olvides colocar el punto!) para decirle a Python que la función randint() está en el
módulo random.
Sólo por un momento, vuelve a la consola interactiva y escribe import random para importar el
módulo random. Luego escribe random.randint(1, 20) para ver a qué se evalúa la llamada a la
función. Devolverá un entero entre 1 y 20. Repite el código nuevamente y la llamada a la función
probablemente devolverá un entero diferente. La función randint() devuelve un entero aleatorio
cada vez, de la misma forma en que tirando un dado obtendrías un número aleatorio cada vez:
12
Capítulo 4 – Adivina el Número 30
Usa la función randint() cuando quieras agregar aleatoriedad a tus juegos. Y vas a usar
aleatoriedad en muchos juegos. (Piensa en la cantidad de juegos de mesa que utilizan dados.)
También puedes probar diferentes intervalos de números cambiando los argumentos. Por
ejemplo, escribe random.randint(1, 4) para obtener sólo enteros entre 1 y 4 (incluyendo 1 y
4). O prueba random.randint(1000, 2000) para obtener enteros entre 1000 y 2000.
Por ejemplo, escribe lo siguiente en la consola interactiva. Los resultados que obtienes cuando
llamas a la función random.randint() serán seguramente diferentes (después de todo es
aleatorio).
>>> random.randint(1, 4)
1294
Puedes cambiar ligeramente el código fuente del juego para hacer que el programa se comporte
de forma diferente. Prueba cambiar las líneas 9 y 10 de:
…a lo siguiente:
Y ahora la computadora pensará en un entero comprendido entre 1 y 100 en lugar de entre 1 y 20.
Cambiar la línea 9 cambiará el intervalo del número aleatorio, pero recuerda cambiar también la
línea 10 para que el juego le diga al jugador el nuevo rango en lugar del viejo.
Capítulo 4 – Adivina el Número 31
Recibiendo al Jugador
10. print('Bueno, ' + miNombre + ', estoy pensando en un número entre 1 y 20.')
En la línea 10 la función print() recibe al jugador llamándolo por su nombre, y le dice que la
computadora está pensando un número aleatorio.
Puede parecer que hay más de un argumento cadena en la línea 10, pero observa la línea con
cuidado. El signo suma concatena las tres cadenas de modo que son evaluadas a una única
cadena. Y esa única cadena es el argumento que se pasa a la función print(). Si miras
detenidamente, verás que las comas están dentro de las comillas, por lo que son parte de las
cadenas y no un separador.
Bucles
12. while intentosRealizados < 6:
La línea 12 es una sentencia while (mientras), que indica el comienzo de un bucle while. Los
bucles te permiten ejecuta código una y otra vez. Sin embargo, necesitas aprender algunos otros
conceptos antes de aprender acerca de los bucles. Estos conceptos son bloques, booleanos,
operadores de comparación, condiciones, y la sentencia while.
Bloques
Varias líneas de código pueden ser agrupadas en un bloque. Un bloque consiste en líneas de
código que comparten mínima indentación posible. Puedes ver dónde comienza y termina un
bloque de código mirando el número de espacios antes de las líneas. Esto se llama la indentación
de la línea.
en la Figura 4-1. Este bloque continuará hasta una línea sin espacios (la indentación original antes
de que comenzara el bloque). Las líneas vacías son ignoradas.
La línea 20 tiene una indentación de ocho espacios. Ocho espacios es más que cuatro espacios, lo
que comienza un nuevo bloque. Este bloque se señala con (2) en la Figura 4-1. Este bloque se
encuentra dentro de otro bloque.
La línea 22 sólo tiene cuatro espacios. Al ver que la indentación se ha reducido, sabes que el
bloque ha terminado. La línea 20 es la única línea del bloque. La línea 22 está en el mismo bloque
que las otras líneas con cuatro espacios.
La línea 23 incrementa la indentación a ocho espacios, de modo que otra vez comienza un nuevo
bloque. Es el que tiene la etiqueta (3) en la Figura 4-1.
Para recapitular, la línea 12 no está en ningún bloque. Las líneas 13 a 23 pertenecen al mismo
bloque (marcado como bloque 1). La línea 20 está en un bloque dentro de un bloque marcado con
(2). Y la línea 23 es la única línea en otro bloque dentro de un bloque marcado con (3).
Por ejemplo:
Los tipos de datos que han sido introducidos hasta ahora son enteros, floats, cadenas, y ahora
bools.
Operadores de Comparación
La línea 12 tiene una sentencia while:
La expresión que sigue a la palabra reservada while (la parte intentosRealizados < 6)
contiene dos valores (el valor en la variable intentosRealizados, y el valor entero 6)
conectados por un operador (el símbolo <, llamado el símbolo “menor que”). El símbolo <
se llama un operador de comparación.
Los operadores de comparación comparan dos valores y se evalúan a un valor Booleano True o
False. En la Tabla 4-1 se muestra una lista de todos los operadores de comparación.
Ya has leído acerca de los operadores matemáticos +, -, *, y /. Como cualquier operador, los
operadores de comparación se combinan con valores ara formar expresiones tales como
intentosRealizados < 6.
Condiciones
Una condición es una expresión que combina dos valores con un operador de comparación (tal
como < o >) y se evalúa a un valor Booleano. Una condición es sólo otro nombre para una
expresión que se evalúa a True o False. Las condiciones se usan en sentencias while (y en
algunas otras situaciones, explicadas más adelante.)
Capítulo 4 – Adivina el Número 34
intentosRealizados < 6
0 < 6
Experimentando True
con Booleans, Operadores de Comparación y Condiciones
Escribe las siguientes expresiones en la consola interactiva para ver sus resultados Booleanos:
>>> 0 < 6
True
>>> 6 < 0
>>> 50 < 10
False
>>> 10 < 11
True
>>> 10 < 10
False
La condición 0 < 6 devuelve el valor Booleano True porque el número 0 es menor que el
número 6. Pero como 6 no es menor que 0, la condición 6 < 0 se evalúa a False. 50 no es
menor que 10, luego 50 < 10 es False. 10 es menor que 11, entonces 10 < 11 es True.
Observa que 10 < 10 se evalúa a False porque el número 10 no es más pequeño que el número
10. Son exactamente del mismo tamaño. Si Alicia fuera igual de alta que Berto, no dirías que
Alicia es más alta que Berto o que Alicia más baja que Berto. Ambas afirmaciones serían falsas.
>>> 10 == 10
True
>>> 10 == 11
False
>>> 11 == 10
False
Capítulo 4 – Adivina el Número 35
>>> 10 != 10
False
>>> 10 != 11
True
Sólo recuerda que el operador de comparación “igual a” (==) está compuesto por dos caracteres,
igual que el operador de comparación “diferente a” ( !=) que también está compuesto por dos
caracteres.
Cadenas y valores enteros no pueden ser iguales. Por ejemplo, prueba escribiendo lo siguiente en
la consola interactiva:
>>> 42 == 'Hola'
False
>>> 42 != '42'
True
Creabdo Bucles con sentencias while
La sentencia while (mientras) indica el comienzo de un bucle. Los bucles pueden ejecutar el
mismo código repetidas veces. Cuando la ejecución llega hasta una sentencia while, evalúa la
condición junto a la palabra reservada while. Si la condición se evalúa a True, la ejecución se
mueve dentro del bloque while. (En tu programa, el bloque while comienza en la línea 13.) Si la
condición se evalúa a False, la ejecución se mueve hasta debajo del bloque while. (En “Adivina
el Número”, la primera línea luego del bloque while es la línea 28.)
Una sentencia while siempre incluye dos punos (el signo :) después de la condición.
Capítulo 4 – Adivina el Número 36
Así es como funciona el bucle. Mientras que la condición sea True, el programa sigue ejecutando
el código dentro del bloque while en forma repetida hasta la primera vez que la condición sea
False. Piensa en la sentencia while como decir, “mientras esta condición sea verdadera, sigue
iterando a través del código en este bloque”.
El Jugador Adivina
Las líneas 13 a 17 piden al jugador que adivine cuál es el númeo secreto y le permiten formular
su intento. Este número se almacena en una variable llamada estimación.
En la línea 15, llamas a una función llamada int(). La función int() toma un argumento y
devuelve un valor entero de ese argumento. Prueba escribir lo siguiente en la consola interactiva:
>>> int('42')
42
>>> 3 + int('2')
5
La llamada a int('42') devolverá el valor entero 42. La llamada int(42) hará lo mismo (a
pesar de que no tiene mucho sentido obtener la forma de valor entero de un valor que ya es
entero). Sin embargo, aunque la función int() acepta cadenas, no puedes pasarle cualquier
cadena. Pasarle 'cuarenta-y-dos' a int() resultará en un error. La cadena que recibe int()
debe estar compuesta por números.
>>> int('cuarenta-y-dos')
Traceback (most recent call last):
3 + int('2')
3 + 2
5
Recuerda, la función input() devuelve una cadena de texto que el jugador ha escrito. Si el
jugador escribe 5, la función input() devolverá el valor de cadena '5', no el valor entero 5.
Python no puede usar los operadores de comparación < y > para comparar una cadena y un valor
entero:
Capítulo 4 – Adivina el Número 38
4 < '5'
El float(), str(), y bool() funciona de manera similar se volverá float, str, y las versiones de
Boole de los argumentos que se pasan a ellos:
>>> float('42')
42.0
>>> float(42)
42.0
>>> str(42)
'42'
>>> str(42.0)
'42.0'
>>> str(False)
'False'
>>> bool('')
False
Incrementando las Variables
>>> bool('cualquier cadena no vacía')
True
Una vez que el jugador ha realizado un intento, el número de intentos debería incrementarse en
uno.
Capítulo 4 – Adivina el Número 39
En la primera iteración del bucle, intentosRealizados tiene el valor 0. Python tomará este
valor y le sumará 1. 0 + 1 se evalúa a 1, el cual se almacena como nuevo valor de
intentosRealizados. Piensa en la línea 17 como diciendo, “la variable intentosRealizados
debería ser uno más que lo que es ahora”.
Sumarle uno al valor entero o float de una variable es lo que se llama incrementar la variable.
Restarle uno al valor entero o float de una variable es decrementar la variable.
Sentencias if
19. if estimación < número:
20. print('Tu estimación es muy baja.') # Hay ocho espacios delante de
print.
La sentencia if funciona casi igual que una sentencia while. Pero a diferencia del bloque while,
la ejecución no vuelve atrás hasta la sentencia if cuando termina de ejecutarse el bloque if.
Simplemente continúa en la línea siguiente. En otras palabras, las sentencias if no generan un
bucle. Mira la Figura 4-3 para ver una comparación de las dos sentencias.
La línea 22 comprueba si la estimación del jugador es mayor que el entero aleatorio. Si esta
condición es True, entonces la llamada a la función print() indica al jugador que su estimación
es demasiado alta.
Una sentencia break indica a la ejecución que salga inmediatamente del bucle while y se mueva
a la primera línea a continuación del mismo. (Las sentencias break no se molestan en volver a
revisar la condición del bucle while, sólo salen del bucle instantaneamente.)
La sentencia break es simplemente la palabra reservada break en sí misma, sin condición o dos
puntos.
La línea 28 no tiene indentación, lo que significa que el bloque while ha terminado y esta es la
primera línea luego del mismo. La ejecución ha abandonado el bloque while, sea porque la
condición de la sentencia while era False (cuando el jugador se quedó sin intentos) o porque se
ejecutó la sentencia break (cuando el jugador adivina el número correctamente).
Capítulo 4 – Adivina el Número 41
La línea 32 usa el operador comparación != para comprobar si el último intento del jugador no es
igual al número secreto. Si esta condición se evalúa a True, la ejecución se mueve dentro del
bloque if de la línea 33.
Las líneas 33 y 34 están dentro del bloque if, y sólo se ejecutan si la condición de la línea 32 es
True.
34. print('Pues no. El número que estaba pensando era ' + número)
En este bloque, el programa indica al jugador cuál era el número secreto que no ha podido
adivinar correctamente. Esto requiere concatenar cadenas, pero número almacena un valor entero.
La línea 33 reemplazará número con una forma cadena, de modo que pueda ser concatenada con
la cadena 'Pues no. El número que estaba pensando era ' de la línea 34.
Puedes cambiar la dificultad del juego modificando el número de intentos que el jugador recibe.
Para dar al jugador sólo cuatro intentos, cambia esta línea::
Resumen
“¿Qué tipo de instrucciones?” Hay sólo unos pocos tipos diferentes de instrucciones, de verdad.
1. Expresiones. Las expresiones son valores conectados por operadores. Todas las
expresiones son evaluadas a un único valor, así como 2 + 2 se evalúa a 4 o 'Hola' + '
' + 'Mundo' se evalúa a 'Hola Mundo'. Cuando las expresiones están al lado de las
palabras reservadas if y while, pueden recibir también el nombre de condiciones.
2. Sentencias de asignación. Las sentencias de asignación almacenan valores en variables
para que puedas recordar los valores más adelante en el programa.
3. Sentencias de control de flujo if, while, y break. Las sentencias de control de flujo
pueden hacer que el flujo omita instrucciones, genere un bucle sobre un bloque de
Capítulo 4 – Adivina el Número 43
instrucciones o salga del bucle en el que se encuentra. Las llamadas a funciones también
cambian el flujo de ejecución moviéndose al comienzo de una función.
4. Las funciones print() e input(). Estas funciones muestran texto en la pantalla y
reciben texto del teclado. Esto se llama E/S (o en inglés I/O), porque tiene que ver con las
Entradas y Salidas del programa.
Y eso es todo, sólo estas cuatro cosas. Por supuesto, hay muchos detalles acerca de estos cuatro
tipos de instrucciones. En este libro aprenderás acerca de nuevos tipos de datos y operadores,
nuevas sentencias de controlo de flujo, y muchas otras funciones que vienen con Python.
También hay diferentes tipos de E/S tales como entradas provistas por el ratón o salidas de sonido
y gráficos en lugar de sólo texto.
En cuanto a la persona que usa tus programas, sólo se preocupa acerca del último tipo, E/S. El
usuario escribe con el teclado y luego ve cosas en la pantalla u oye sonidos de los altavoces. Pero
para que la computadora pueda saber qué imágenes mostrar y qué sonidos reproducir, necesita un
programa, y los programas son sólo un manojo de instrucciones que tú, el programador, has
escrito.
Capítulo 5 – Chistes 43
Capítulo 5
CHISTES
Temas Tratados En Este Capítulo:
• Caracteres de escape
• Utilizando comillas simples y comillas dobles para las cadenas.
• Utilizando el argumento palabra clave final (end) de print() para evitar nuevas lineas
Aprovechar print() al Máximo
La mayoría de los juegos en este libro tendrán un texto simple de entrada y salida. La entrada es
escrita por el usuario desde el teclado e introducida a la computadora. La salida es el texto
mostrado en la pantalla. En Python, la función print() se puede usar para mostrar salidas de
texto en la pantalla. Pero hay más para aprender sobre cómo funcionan las cadenas y el print()
en Python.
¡Un monopatín!
¿Porqué vuelan los pájaros pa'l sur?
Si obtienes errores después de escribir este código, compáralo con el código del libro con la
herramienta diff en línea en http://invpy.com/es/diff/chistes.
chistes.py
1. print('¿Qué sale de la cruza entre un mono y un pato?')
2. input()
3. print('¡Un monopatín!')
4. print()
5. print('¿Porqué vuelan los pájaros pa\'l sur?')
6. input()
7. print('¡Porque caminando tardarían muchísimo!')
8. print()
9. print('¿En qué se parecen una familia, un bombero y un barco?')
10. input()
11. print("No sé... ¿en qué se parecen?")
12. input()
13. print('En que el bombero y el barco tienen casco.')
14. input()
15. print('¿Y la familia?', end='')
16. print(' -Bien, gracias.')
Las líneas de la 1 a la 4 tienen tres llamadas a la función print(). No quieres que el jugador lea
de inmediato el remate del chiste, así que hay una llamada a la función print() después del
primer print(). El jugador puede leer la primera línea, presionar INTRO, y entonces leer el
remate del chiste.
El usuario todavía puede escribir una cadena y pulsar INTRO, pero esta cadena devuelta no está
siendo almacenada en ninguna variable. El programa tan solo lo olvidará y se moverá a la
siguiente línea de código.
La última llamada a la función print() no tiene argumento de cadena. Esto le indica al programa
que solamente escriba una línea en blanco. Las líneas en blanco pueden ser útiles para evitar que
el texto quede unido.
Capítulo 5 – Chistes 45
Caracteres de Escape
5. print('¿Porqué vuelan los pájaros pa\'l sur?')
6. input()
7. print('¡Porque caminando tardarían muchísimo!')
8. print()
En el primer print() de arriba, ha una barra invertida justo antes de la comillas simple (esto es,
el apóstrofo). Nota que \ es una barra inversa, y / es una barra inclinada. Esta barra inversa
indica que la letra que está a su derecha es una caracter de escape. Un caracter de escape te
permite imprimir caracteres que son difíciles de introducir en el código fuente. En esta llamada a
print() el caracter de escape es una comilla simple.
El caracter de escape comilla simple está allí porque de otra manera Python pensaría que la
comilla indica el final de la cadena. Pero esta comilla necesita formar parte de la cadena. La
comilla simple de escape le indica a Python que la comilla simple es literalmente una parte de la
cadena en lugar de indicar el final del valor de la cadena.
Esto es porque la "t" en "turquesa" fue vista como un caracter de escape debido a que estaba
después de una barra inversa. El caracter de escape t simula la pulsación de la tecla TAB de tu
teclado. Hay caracteres de escape para que las cadenas puedan tener caracteres que no se pueden
escribir.
Pero no puedes mexzclar las comillas. Esta línea devolverá un error si intentas utilizarla:
Me gusta utilizar las comillas simples, así no tengo que pulsar la tecla shift (mayúsculas) para
escribirlas. Es más fácil de escribir, y a Python le da igual de cualquier manera.
Del mismo modo en que necesitas el caracter de escape \' para obtener una comilla simple en
una cadena rodeada de comillas simples, se necesita un caracter de escape \" para imprimir una
comilla doble en una cadena rodeada de comillas dobles. Por ejemplo, mira estas dos líneas:
>>> print("Él dijo, \"No puedo creer que lo dejaste llevarse el carro pa'l
pueblo\"")
Él dijo, "No puedo creer que lo dejaste llevarse el carro pa'l pueblo"
En las cadenas de comillas simples no necesitas escapar las comillas dobles, y en las cadenas de
comillas dobles no necesitas escapar las comillas simples. El intérprete de Python tiene
inteligencia suficiente para saber que si una cadena comienza con un tipo de comillas, el otro tipo
de comillas no significa que la cadena está terminada.
Capítulo 5 – Chistes 47
¿Te diste cuenta del segundo parámetro en el print de la línea 15?. Normalmente, print() añade
un salto de línea al final de la cadena que imprime. Por esta razón, una función print() en
blanco tan solo imprimirá una nueva línea. Pero la función print() tiene la opción de un
segundo parámetro (que tiene nombre “end” (fin)).
La cadena en blanco dada se llama argumento de palabra clave. El parámetro final tiene un
nombre específico, y para pasar un argumento a ese parámetro en particular necesitamos utilizar
la sintáxis end=.
Pasando una cadena en blanco usando end, la función print() no añadirá un salto de linea al
final de la cadena, en lugar de esto añadirá una cadena en blanco. Por esta razón ' -Bien,
gracias.' aparece junto a la línea anterior, en lugar de sobre una nueva línea. No hubo salto de
línea después de la cadena '¿Y la familia?'.
Resumen
Este capítulo explora las diferentes formas en las que se puede utilizar la función print(). Los
caracteres de escape se utilizan para los caracteres que son difíciles o imposibles de escribir en
código usando el teclado. Los caracteres de escape se escriben en las cadenas comienzando con
una barra inversa \ seguida de una sola letra para el carácter de escape. Por ejemplo, \n sería un
salto de línea. Para incluir una barra invertida en una cadena, deberás utilizar el carácter de escape
\\.
La función print() añade automáticamente un carácter de salto de línea al final de la cadena que
se pasa para imprimr en pantalla. La mayor parte del tiempo, es un atajo útil. Pero a veces no
quieres un carácter de salto de línea al final. Para cambiar esto, puedes pasar el argumento de
palabra clave end con una cadena en blanco. Por ejemplo, para imprimir “spam” en la pantalla sin
un carácter de salto de línea, podrías hacer el llamado print('spam', end='').
Al añadir este nivel de control sobre el texto que mostraremos en la pantalla, puedes tener formas
más flexibles para hacerlo.
Capítulo 5 – Chistes 48
Capítulo 6
REINO DE DRAGONES
Temas Tratados En Este Capítulo:
• La función time.sleep()
• Creando nuestras propias funciones con la palabra reservada def
• La palabra reservada return
• Los operadores Booleanos and, or y not
• Tablas de verdad
• Entorno de variables (Global y Local)
• Parámetros y Argumentos
• Diagramas de Flujo
Las Funciones
Ya hemos usado dos funciones en nuestros programas anteriores: input() y print(). En los
programas anteriores, hemos llamado a estas funciones para ejecutar el código dentro de ellas. En
este capítulo, escribiremos nuestras propias funciones para que sean llamadas por programas. Una
función es como un mini-programa dentro de nuestro programa.
El juego que crearemos para presentar las funciones se llama "Reino de Dragones", y permite al
jugador elegir entre dos cuevas, en una de las cuales encontrará un tesoro y en la otra su
perdición.
Abre una nueva ventana del editor de archivos haciendo clic en el menú File (Archivo) ► New
Window (Nueva Ventana). En la ventana vacía que aparece escribe el código fuente y guárdalo
como dragón.py. Luego ejecuta el programa pulsando F5.
Capítulo 6 – Reino de Dragones 49
Te aproximas a la cueva...
Es oscura y espeluznante...
¡Un gran dragon aparece súbitamente frente a tí! Abre sus fauces y...
no
¡NOTA IMPORTANTE! Los programas de este libro sólo podrán ejecutarse
sobre Python 3, no Python 2. Al iniciar la ventana IDLE, dirá algo como “Python
3.4.2” en la parte superior. Si tienes Python 2 instalado, es posible instalar
también Python 3 a la vez. Para descargar Python 3, dirígete a
https://python.org/download/.
Si obtienes errores luego de copiar este código, compáralo con el código del libro usando la
herramienta diff online en http://invpy.com/es/diff/dragón.
dragón.py
import random
import time
def mostrarIntroducción():
5. print('Estás en una tierra llena de dragones. Frente a tí')
print('hay dos cuevas. En una de ellas, el dragón es generoso y')
6.
print('amigable y compartirá su tesoro contigo. El otro dragón')
7.
print('es codicioso y está hambriento, y te devorará inmediatamente.')
8.
9. def elegirCueva():
11.
12. cueva = ''
13. while cueva != '1' and cueva != '2':
18.
19. def explorarCueva(cuevaElegida):
20. print('Te aproximas a la cueva...')
time.sleep(2)
21.
22. print('Es oscura y espeluznante...')
time.sleep(2)
23.
24. print()
y...') time.sleep(2)
25.
26.
cuevaAmigable = random.randint(1, 2)
27.
28.
if cuevaElegida == str(cuevaAmigable):
29. print('¡Te regala su tesoro!')
30.
35. jugarDeNuevo = 'sí'
36. while jugarDeNuevo == 'sí' or jugarDeNuevo == 's':
37.
38. mostrarIntroducción()
39.
númeroDeCueva = elegirCueva()
40.
41.
explorarCueva(númeroDeCueva)
42.
43.
1. import random
2. import time
Sentencias def
4. def mostrarIntroducción():
5. print('Estás en una tierra llena de dragones. Frente a tí')
print('hay dos cuevas. En una de ellas, el dragón es generoso y')
6.
print('amigable y compartirá su tesoro contigo. El otro dragón')
7.
print('es codicioso y está hambriento, y te devorará inmediatamente.')
8.
La línea 4 es una sentencia def. La sentencia def crea, es decir, una nueva función que puede ser
llamada más adelante en el programa. Luego de haber definido esta función, puedes llamarla de
la misma forma en que llamas a otras funciones. Cuando llamas a esta función, el código dentro
del bloque def se ejecuta.
La Figura 6-1 muestra las partes de una sentencia def. Comienza con la palabra reservada def
seguida por un nombre de función con paréntesis y luego dos puntos. El bloque a continuación de
la sentencia def se llama el bloque def.
Recuerda, la sentencia def no ejecuta el código. Sólo define qué código se ejecutará cuando
llames a la función. Cuando la ejecución llega a una sentencia def, omite lo que sigue hasta la
primera línea a continuación del bloque def.
38. mostrarIntroducción()
Entonces todas las llamadas a print() se ejecutan, y se muestra la introducción “Estás en una
tierra llena de dragones...”.
Capítulo 6 – Reino de Dragones 52
decirAdios()
def decirAdios():
print('¡Adios!')
def sayGoodbye():
print('Goodbye!')
sayGoodbye()
La línea 11 define otra función llamada elegirCueva(). El código de esta función pregunta al
jugador a qué cueva quiere entrar, 1 ó 2.
Esta función necesita asegurar que el jugador haya respondido 1 ó 2, y no otra cosa. Un bucle
aquí seguirá preguntando al jugador hasta que escriba alguna de estas dos respuestas válidas. Esto
se llama validación de entrada.
La línea 12 crea una nueva variable llamada cueva y guarda en ella una cadena vacía. Luego un
bucle while comienza en la línea 13. La condición contiene un nuevo operador que no has visto
Capítulo 6 – Reino de Dragones 53
antes llamado and (y). Igual que los signos - o * son operadores matemáticos y los signos == o !=
son operadores de comparación, el operador and es un operador Booleano.
Operadores Booleanos
La lógica Booleana se ocupa de enunciados que son verdaderas ( True) o falsos (False ). Los
operadores Booleanos comparan dos valores Booleanos y se evalúan a un único valor Booleano.
Piensa en este enunciado, “Los gatos tienen bigotes y los perros tienen colas.” “Los gatos tienen
bigotes” es verdadero y “los perros tienen colas” también es verdadero, luego el enunciado
completo “Los gatos tienen bigotes y los perros tienen colas” es verdadero.
Pero el enunciado “Los gatos tienen bigotes y los perros tienen alas” sería falso. Incluso si “los
gatos tienen bigotes” es verdadero, los perros no tienen alas, luego “los perros tienen alas” es
falso. En lógica Booleana, los enunciados sólo pueden ser completamente verdaderos o
completamente falsos. Debido a la conjunción “y”, el enunciado completo es verdadero sólo si
ambas partes son verdaderas. Si una o ambas partes son falsas, entonces el enunciado completo
es falso.
Prueba escribir las siguientes expresiones con el operador and en la consola interactiva:
El operador not sólo actúa sobre un valor, en lugar de combinar dos valores. El operador not (no)
se evalúa al valor Booleano opuesto. La expresión not True se evaluará a False y not False se
evaluará a True.
Si alguna vez te olvidas cóno funcionan los operadores Booleanos, puedes mirar estas tablas de
verdad:
La condición tiene dos partes conectadas por el operador Booleano and. La condición es True
sólo si ambas partes son True.
La primera vez que se comprueba la condición de la sentencia while, cueva está definida como
la cadena vacía, ''. La cadena vacía no es igual a la cadena '1', luego el lado izquierdo se evalúa
a True. La cadena vacía tampoco es igual a la cadena '2', por lo que el lado derecho se evalúa a
True.
Entonces la condición se transforma en True and True. Como ambos valores Booleanos son
True, la condición finalmente se evalúa a True. Luego la ejecución del programa entra al bloque
while.
▼ cueva != '2':
and
▼
while True
and cueva != '2':
while True
▼
Capítulo 6 – Reino de Dragones 56
while ▼
La línea 14 pregunta al jugador qué cueva quiere elegir. La línea 15 permite al jugador escribir la
respuesta y pulsar INTRO. Esta respuesta es almacenada en cueva. Después de ejecutar este
código, la ejecución vuelve a la parte superior de la sentencia while y vuelve a comprobar la
condición.
Si el jugador ha ingresado 1 ó 2, entonces cueva será '1' or '2' (ya que input() siempre
devuelve cadenas). Esto hace que la condición sea False, y la ejecución del programa continuará
debajo del bucle while. Por ejemplo, si el usuario escribiese '1' la evaluación se vería así:
Pero si el jugador hubiese escrito 3 o 4 o HOLA, esa respuesta habría sido inválida. La condición
seguiría siendo True y entrando al bloque while para preguntar de nuevo al jugador. El programa
simplemente continúa preguntando hasta que el jugador responda 1 or 2. Esto garantiza que
cuando la ejecución continúe avanzando la variable cueva contendrá una respuesta válida.
Retorno de Valores
17. return cueva
Esta es una sentencia return, la cual sólo aparece dentro de bloques def. ¿Recuerdas como la
función input() devuelve un valor de cadena que el jugador ha ingresado? La función
Capítulo 6 – Reino de Dragones 57
Una vez ejecutada la sentencia return, la ejecución del programa sale inmediatamente del bloque
def. (Esto es como cuando la sentencia break hace que la ejecución salga de un bloque while.)
La ejecución del programa vuelve a la línea que contiene la llamada a la función. La llamada a la
función será entonces evaluada al valor de retorno.
Cuando elegirCueva() es llamada más adelante por el programa en la línea 40, el valor
de retorno es almacenado en la variable númeroDeCueva. El bucle while garantiza que
elegirCueva() devolverá sólo '1' o '2' como valor de retorno.
Cuando la ejecución está dentro de una función, no puedes modificar las variables fuera de la
función, incluidas variables de otras funciones. Esto es porque esas variables existen en un
“entorno” diferente. todas las variables existen en el entorno global o en el entorno local de la
llamada a una función.
El entorno exterior a todas las funciones se llama entorno global. El entorno dentro de una
función (por la duración de una llamada específica a la función) se llama entorno local.
El programa entero tiene un solo entorno global. Las variables definidas en el entorno global
puede ser leídas fuera y dentro de las funciones, pero sólo pueden ser modificadas fuera de todas
las funciones. Las variables creadas en la llamada a una función sólo pueden ser leídas o
modificadas durante esa llamada a la función.
Puedes leer el valor de las variables globales desde el entorno local, pero intentar modificar una
variable global desde el entorno local no funcionará. Lo que Python hace en ese caso es crear una
variable local con el mismo nombre que la variable global. Sería posible, por ejemplo, tener una
Capítulo 6 – Reino de Dragones 58
variable local llamada spam al mismo tienpo que existe una variable global llamada spam. Python
las considerará dos variables distintas.
Mira el siguiente ejemplo para ver qué pasa cuando intentas modificar una variable global desde
dentro de un entorno local. Los comentarios explican qué es lo que está ocurriendo:
def bacon():
spam = 99
# función:
print(spam) # 99
bacon() # Llamaeste
Al ser ejecutado, a código
la función bacon():
mostrará las siguientes salidas:
# La variable global no fue cambiada en bacon():
42
print(spam) # 42
99
42
Dónde se crea una variables determina en qué entorno se encuentra. Cuando el programa Reino
de Dragones ejecuta por primera vez la línea:
...la variable cueva se crea dentro de la función elegirCueva(). Esto significa que es creada en el
entorno local de la función elegirCueva(). Será olvidada cuando elegirCueva() finalice, y será
recreada si elegirCueva() es llamada por segunda vez. El valor de una variable local no es
recordado entre una llamada a una función local y otra.
Parámetros
19. def explorarCueva(cuevaElegida):
Capítulo 6 – Reino de Dragones 59
Recuerda cómo para algunas llamadas a funciones como str() o randint(), pasarías un
argumento entre paréntesis:
>>> str(5)
'5'
Por ejemplo, aquí hay un pequeño programa que demuestra cómo se define una función con un
parámetro:
sayHello('Alicia')
sayHello('Berto')
spam = 'Carolina'
sayHello(spam)
Si ejecutas este programa, verás algo así:
Cuando llamas a decirHola(), el argumento se asigna al parámetro nombre. Los parámetros son
simplemente variables locales ordinarias. Como todas las variables locales, los valores en los
parámetros serán olvidados cuando la llamada a la función retorne.
El módulo time tiene una función llamada sleep() que pone al programa en pausa. La línea 21
pasa el valor entero 2 de modo que time.sleep() pondrá al programa en pausa por 2 segundos.
Aquí el código imprime algo más de texto y espera por otros 2 segundos. Estas pequeñas pausas
agregan suspenso al juego, en lugar de mostrar todo el texto a la vez. En el programa Chistes del
capítulo anterior, has llamado a la función input() para poner el juego en pausa hasta que el
jugador pulsara la tecla INTRO. Aquí, el jugador no tiene que hacer nada excepto esperar un par de
segundos.
24. print('¡Un gran dragon aparece súbitamente frente a tí! Abre sus fauces
y...')
25. print()
26. time.sleep(2)
if int(cuevaElegida) == cuevaAmigable:
32. else:
La línea 32 es una sentencia else (si no). La palabra reservada else siempre viene a continuación
del bloque if. El bloque else se ejecuta si la condición de la sentencia if fue False. Piensa en esto
como la forma del programa de decir, “Si esta condición es verdadera entonces ejecuta el bloque
if, en caso contrario ejecuta el bloque else.”
Recuerda colocar los dos puntos (el signo : ) luego de la palabra reservada else.
La línea 35 es la primera línea que no es una sentencia def ni pertenece a un bloque def. Esta
línea es donde la parte principal del programa comienza. Las sentencias def anteriores sólo
definen las funciones, pero sin ejecutarlas.
Las líneas 35 y 36 configuran un bucle que contiene al resto del juego. Al final del juego, el
jugador puede escribir si desea jugar de nuevo. Si es así, la ejecución vuelve a entrar al bucle
while para ejecutar todo el juego otra vez. En caso contrario, la condición de la sentencia while
será False y la ejecución continuará hasta el final del programa y terminará.
La primera vez que la ejecución llega a esta sentencia while, la línea 35 ha acabado de asignar
'sí' a la variable jugarDeNuevo. Esto significa que la condición será True. De esta forma se
garantiza que la ejecución entrará al bucle al menos una vez.
38. mostrarIntroducción()
La línea 40 también llama a una función que tú has definido. Recuerda que la función
elegirCueva() permite al jugador elegir la cueva a la que desea entrar. Cuando se ejecuta
return cueva en la línea 17, la ejecución del programa vuelve a la línea 40, y la llamada a
elegirCueva() se evalúa al valor de retorno. Este valor de retorno es almacenado en una nueva
variable llamada númeroDeCueva. Entonces la ejecución del programa continúa en la línea 42.
42. explorarCueva(númeroDeCueva)
Sin importar si el jugador gana o pierde, se le pregunta si quiere jugar de nuevo. La variable
jugarDeNuevo almacena lo que haya ingresado el jugador. La línea 45 es la última línea del
bloque while, de modo que el programa vuelve a la línea 36 para comprobar la condición del
bucle while: jugarDeNuevo == 'sí' or jugarDeNuevo == 's'
Si el jugador ingresa la cadena 'sí' o 's', la ejecución entrará nuevamente al bucle en la línea
38.
Si el jugador ingresa 'no' o 'n', o una tontería como 'Abraham Lincoln', entonces la condición
será False. La ejecución del programa continúa a la línea a continuación del bloque while. Pero
dado que no hay más líneas después del bloque while, el programa termina.
Una cosa a tener en cuenta: la cadena 'SÍ' no es igual a la cadena 'sí'. Si el jugador ingresa la
cadena 'SÍ', entonces la condición de la sentencia while se evaluará a False y el programa
terminará igualmente. Otros programas más adelante en este libro te mostrarán cómo evitar este
problema.
¡Acabas de completar tu segundo juego! En Reino de Dragones, has usado mucho de cuanto
aprendiste en el juego “Adivina el Número” y has aprendido unos cuantos trucos nuevos. Si no
Capítulo 6 – Reino de Dragones 63
entendiste algunos de los conceptos en este programa, recorre cada línea del código fuente otra
vez e intenta modificar el código fuente viendo cómo cambia el programa.
En el siguiente capítulo no crearás un juego, pero aprenderás cómo usar una funcionalidad de
IDLE llamada depurador.
Diseñando el Programa
Reino de Dragones es un juego simple. El resto de los juegos en este libro serán un poco más
complicados. A veces ayuda escribir en papel todo lo que quieres que tu juego o programa haga
antes de comenzar a escribir el código. Esto se llama “diseñar el programa”.
Por ejemplo, puede ayudar dibujar un diagrama de flujo. Un diagrama de flujo es una ilustración
que muestra cada posible acción que puede ocurrir en el juego, y qué acciones llevan a qué otras
acciones. La Figura 6-2 es un diagrama de flujo para Reino de Dragones.
Para ver qué pasa en el juego, coloca tu dedo sobre el recuadro “Inicio”. Luego sigue una flecha
desde ese recuadro hasta otro recuadro. Tu dedo es como la ejecución del programa. El programa
termina cuando tu dedo llega al recuadro “Fin”.
Resumen
En el juego “Reino de Dragones”, has creado tus propias funciones. Las funciones son un mini-
programa dentro de tu programa. El código dentro de la función se ejecuta cuando la función es
llamada. Al descomponer tu código en funciones, puedes organizar tu código en secciones más
pequeñas y fáciles de entender.
Los argumentos son valores pasados al código de la función cuando la función es llamada. La
propia llamada a la función se evalúa al valor de retorno.
Capítulo 6 – Reino de Dragones 64
Los entornos de variables pueden parecer complicados, pero son útiles para
organizar funciones como fragmentos de código separados del resto del
programa. Dado que cada función tiene su propio entorno local, puedes estar
seguro de que el código en una función no ocasionará errores en otras
funciones.
Las funciones son tan útiles que casi todos los programas las usan. Entendiendo
cómo funcionan las funciones, podemos ahorrarnos escribir muchas líneas de
código y hacer que los errores sean más fáciles de arreglar.