Sei sulla pagina 1di 53

1.

El camino del programa


El objetivo de este libro es enseñarle a pensar como lo hacen los científicos informáticos.
Esta manera de pensar combina algunas de las mejores características de la matemática,
la ingeniería y las ciencias naturales. Como los matemáticos, los científicos informáticos
usan lenguajes formales para denotar ideas (específicamente, cómputos). Como los
ingenieros, ellos diseñan cosas, construyendo sistemas mediante el ensamble de
componentes y evaluando las ventajas y desventajas de cada una de las alternativas de
construcción. Como los científicos, ellos observan el comportamiento de sistemas
complejos, forman hipótesis, y prueban sus predicciones.

La habilidad más importante del científico informático es la resolución de problemas. La


resolución de problemas incluye poder formular problemas, pensar en soluciones de
manera creativa, y expresar soluciones claras y precisas. Como se verá, el proceso de
aprender a programar es la oportunidad perfecta para desarrollar la habilidad de
resolver problemas. Por esa razón este capítulo se llama “El Camino del programa.”

A cierto nivel, usted aprenderá a programar, lo cual es una habilidad muy útil por sí
misma. A otro nivel, usted utilizará la programación para obtener algún resultado. Ese
resultado se verá más claramente durante el proceso.

1.1. El lenguaje de programación Python


El lenguaje de programación que aprenderá es Python. Python es un ejemplo de lenguaje
de alto nivel; otros lenguajes de alto nivel de los que quizá ha oído hablar son C++, PHP
y Java.

Como se puede deducir, además de “lenguajes de alto nivel” también existen lenguajes


de bajo nivel, que también se denominan “lenguajes de máquina” o “lenguajes
ensambladores.” A propósito, las computadoras sólo ejecutan programas escritos en
lenguajes de bajo nivel. Así, los programas escritos en lenguajes de alto nivel tienen que
ser traducidos antes de ser ejecutados. Esta traducción lleva tiempo, lo que es una
pequeña desventaja de los lenguajes de alto nivel.

Aun así, las ventajas son enormes. En primer lugar, la programación en lenguajes de alto
nivel es mucho más fácil; escribir programas en un lenguaje de alto nivel toma menos
tiempo, los programas son más cortos y más fáciles de leer, y es más probable que
estos programas queden correctos. En segundo lugar, los lenguajes de alto nivel
son portables, lo que significa que los programas escritos con estos lenguajes pueden
ser ejecutados en diferentes tipos de computadoras sin modificación alguna o con pocas
modificaciones. Los programas escritos en lenguajes de bajo nivel sólo pueden ser
ejecutados en un tipo de computadora y deben ser reescritos para ser ejecutados en
otra.

Debido a estas ventajas, casi todo programa se escribe en un lenguaje de alto nivel. Los
lenguajes de bajo nivel son sólo usados para unas pocas aplicaciones especiales.

Hay dos tipos de programas que traducen lenguajes de alto nivel a lenguajes de bajo
nivel: intérpretes y compiladores. Un intérprete lee un programa de alto nivel y lo
ejecuta, lo que significa que lleva a cabo lo que indica el programa. Es decir, traduce el
programa poco a poco, leyendo y ejecutando cada comando.

Un compilador lee el programa y lo traduce completo antes de su ejecución. En este


caso, al programa de alto nivel se le llama código fuente, y el programa traducido es
llamado código objeto o programa ejecutable. Una vez que un programa ha sido
compilado, puede ser ejecutado repetidamente sin necesidad de más traducción.

Muchos de los lenguajes modernos usan ambos tipos de programas de traducción. Estos
lenguajes se traducen primero a un lenguaje de bajo nivel, llamado código de bytes, y
después son interpretados por un programa denominado máquina virtual. Aunque
Python usa ambos tipos de programas de traducción, usualmente se le considera un
lenguaje interpretado debido a la manera en que los programadores interactúan con él.

Existen dos maneras de usar el intérprete de Python: en modo de comandos y en modo


de guión. En modo de comandos se escriben sentencias en lenguaje Python en
el intérprete de comandos de Python y éste muestra el resultado inmediatamente:

$ python
Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print 1 + 1
2

La primera línea de este ejemplo es el comando que pone en marcha al intérprete de


Python — en el indicador de comandos de sistemas tipo UNIX. Las tres líneas siguientes
son mensajes del intérprete. La quinta línea comienza con >>>, que es el indicador del
intérprete de comandos de Python para indicar que está listo. Si
escribimos print 1 + 1 el intérprete contestará 2.

Alternativamente, se puede escribir el programa en un archivo y usar el intérprete para


ejecutar el contenido de dicho archivo. El archivo, en este caso, se denomina
archivo guión. Por ejemplo, en un editor de texto se puede crear un archivo con el
nombre primerprograma.py que contenga lo siguiente:
print 1 + 1

Por convención, los archivos que contienen programas de Python tienen nombres que
terminan con .py.

Para ejecutar el programa, se le tiene que indicar al intérprete el nombre del guión:

$ python primerprograma.py
2

Estos ejemplos muestran a Python corriendo desde la línea de comandos de sistemas


tipo Unix. En otros entornos de desarrollo los detalles de la ejecución de programas
diferirán. También, la mayoría de los programas son más interesantes que el
mencionado.

En los ejemplos de este libro se usa tanto el intérprete de Python como los guiones.
Usted será capaz de identificar cualquiera de ellos, puesto que los ejemplos en modo de
comandos siempre empezarán con el indicador del intérprete de comandos de Python
(>>>).

En la realización de pruebas de segmentos cortos de código programado en Python, es


más conveniente trabajar en el modo de comandos porque se obtienen resultados
inmediatos. Piense en esto como un borrador que se utiliza para ayudarle a resolver
problemas. Cualquier segmento de código más allá de unas pocas líneas debe incluirse
en un guión.

1.2. ¿Qué es un programa?


Un programa es una secuencia de instrucciones que especifican cómo ejecutar un
cómputo. El cómputo puede ser algo matemático, como solucionar un sistema de
ecuaciones o determinar las raíces de un polinomio, pero también puede ser un
cómputo simbólico, como buscar y reemplazar el texto de un documento o (aunque
parezca raro) compilar un programa.

Las instrucciones (comandos, órdenes) tienen una apariencia diferente en lenguajes de


programación distintos, pero existen algunas que son básicas, que se presentan en casi
todo lenguaje, y que pueden agruparse en los siguientes conceptos:

entrada
Reciben datos del teclado, de un archivo o de algún otro dispositivo.

salida
Muestran datos en el monitor o los envían a un archivo u otro dispositivo.
matemáticas
Ejecutan operaciones básicas de matemáticas como la adición y la multiplicación.

operación condicional
Prueban la veracidad de alguna condición y ejecutan la secuencia de
instrucciones apropiada.

repetición
Ejecutan alguna acción repetidas veces, usualmente con alguna variación.

Aunque sea difícil de creer, estos conceptos agrupan más o menos todas las
instrucciones que hay en los lenguajes de programación. Todos los programas en
existencia, sin importar su complejidad, son formulados exclusivamente con tales
instrucciones. Así, la programación se puede describir como el proceso de dividir una
tarea amplia y compleja en tareas cada vez más pequeñas hasta que éstas sean lo
suficientemente sencillas como para ser ejecutadas con estas instrucciones básicas.

Quizás esta descripción sea un poco imprecisa, pero volveremos a este tema más
adelante cuando hablemos de algoritmos.

1.3. ¿Qué es la depuración?


La programación es un proceso complejo y, debido a que es realizada por seres
humanos, a veces conlleva la aparición de errores. Por caprichos del destino, estos
errores de programación se denominan bichos (del inglés ‘bugs’) y el proceso de
buscarlos y corregirlos es llamado depuración (del inglés ‘debugging’).

Hay tres tipos de errores que pueden ocurrir en un programa: errores de sintaxis,
errores en tiempo de ejecución y errores semánticos. Es muy útil distinguirlos para
encontrarlos más rápido.

1.4. Errores de sintaxis


Python sólo puede ejecutar un programa si el programa está correcto sintácticamente;
de lo contrario, el proceso falla y devuelve un mensaje de error. La palabra sintaxis se
refiere a la estructura de cualquier programa y a las reglas de esa estructura. Por
ejemplo, en español, la primera letra de toda oración debe ser mayúscula, y el fin de
toda oración debe llevar un punto. esta oración tiene un error de sintaxis. Esta otra
oración también

Para la mayoría de los lectores unos pocos errores de sintaxis no representan un


problema significativo, es por eso que pueden leer la poesía de e. e. cummings sin
proferir algún mensaje de error. Python no es así. Si hay, aunque sea un error de sintaxis
en el programa, Python mostrará un mensaje de error y abortará la ejecución del
programa. Durante las primeras semanas en su carrera de programador empleará
bastante tiempo buscando errores de sintaxis. Sin embargo, conforme vaya adquiriendo
experiencia, no tendrá tantos errores y los encontrará más rápido.

1.5. Errores en tiempo de ejecución


El segundo tipo de error es un error en tiempo de ejecución. Este error aparece sólo
cuando se ejecuta un programa. Estos errores también se llaman excepciones porque
indican que algo excepcional (y malo) ha ocurrido.

Los errores en tiempo de ejecución son raros en los programas simples que veremos en
los primeros capítulos, por lo que pasará un buen tiempo antes de encontrar el primer
error de este tipo.

1.6. Errores semánticos


El tercer tipo de error es el error semántico. Si hay un error semántico en su programa,
el programa será ejecutado sin ningún mensaje de error, pero el resultado no será el
deseado. El programa ejecutará exactamente lo que usted le dijo que ejecutara.

A veces ocurre que el programa escrito no es el programa que se tenía en mente. El


sentido o significado del programa (su valor semántico) no es correcto. Identificar
errores semánticos es difícil porque requiere trabajar al revés: comenzar por los
resultados de salida y tratar de descifrar lo que el programa está realizando.

1.7. Depuración experimental


Una de las técnicas más importantes que usted aprenderá es la depuración. Aunque a
veces es frustrante, la depuración es una de las partes de la programación
intelectualmente más exigentes, desafiantes e interesantes.

La depuración es una actividad parecida a la labor realizada por detectives: se tienen que
estudiar las pistas para inferir los procesos y eventos que han generado los resultados
que se han encontrado.

La depuración es como una ciencia experimental. Una vez que se tiene conciencia de un
error, se modifica el programa y se intenta nuevamente. Si la hipótesis fue la correcta se
pueden predecir los resultados de la modificación y se estará más cerca de un programa
correcto. Si la hipótesis fue errónea tendrá que idearse otra hipótesis. Como dijo
Sherlock Holmes: “Cuando se ha descartado lo imposible, lo que queda, no importa cuán
inverosímil, debe ser la verdad”. (A. Conan Doyle, The Sign of Four)

Para algunas personas, la programación y la depuración son lo mismo: la programación


es el proceso de depurar un programa gradualmente hasta que el programa realice lo
deseado. Esto quiere decir que el programa debe ser, desde el principio, un programa
que funcione y que realice algo; a este programa se le hacen pequeñas modificaciones y
se le depura manteniéndolo siempre funcionando.

Por ejemplo, aunque el sistema operativo Linux contenga miles de líneas de


instrucciones, Linus Torvalds lo comenzó como un programa para explorar el
microprocesador Intel 80386. Según Larry Greenfield, uno de los primeros proyectos de
Linus fue un programa que intercambiaría la impresión de AAAA y BBBB. Este programa
se convirtió en Linux (de The Linux Users’ Guide Versión Beta 1).

En capítulos posteriores se tratará más el tema de la depuración y de otras técnicas de


programación.

1.8. Lenguajes formales y lenguajes naturales


Los Lenguajes naturales son los lenguajes hablados por seres humanos, como el
español, el inglés y el francés. Estos no han sido diseñados artificialmente (aunque se
trate de imponer cierto orden en ellos), pues se han desarrollado naturalmente.

Los Lenguajes formales son diseñados por seres humanos para aplicaciones específicas.


La notación matemática, por ejemplo, es un lenguaje formal, ya que se presta a la
representación de las relaciones entre números y símbolos. Los químicos utilizan un
lenguaje formal para representar la estructura química de las moléculas. Y lo más
importante en programación:

Los Lenguajes de programación son lenguajes formales que han sido desarrollados para
expresar cómputos.

Los lenguajes formales casi siempre tienen reglas sintácticas estrictas. Por
ejemplo, 3+3=6 es una expresión matemática sintácticamente correcta, pero 3=+6$ no lo
es. De la misma manera, H2O es una nomenclatura química sintácticamente correcta,
pero 2Zz`` no lo es.

Existen dos clases de reglas sintácticas: unidades léxicas y estructura. Las unidades


léxicas son los elementos básicos de un lenguaje, como lo son las palabras, los números
y los elementos químicos. Por ejemplo, en 3=+6$, $ no es (hasta donde sabemos) una
unidad matemática aceptada. De manera similar, 2Zz no es formal porque no hay ningún
elemento químico con la abreviación Zz.
La segunda clase de regla sintáctica está relacionada con la estructura de una sentencia;
es decir, con el orden de las unidades léxicas. La estructura de la sentencia 3=+6$ no es
aceptada porque no se puede escribir el símbolo de igualdad seguido del signo de la
adición. Similarmente, las fórmulas moleculares tienen que mostrar el número de
subíndice después del elemento, no antes.

Al leer una oración, sea en un lenguaje natural o una sentencia en un lenguaje formal, se
debe discernir la estructura de la oración. En un lenguaje natural este proceso,
llamado análisis sintáctico, ocurre subconscientemente.

Por ejemplo, cuando se escucha una oración simple como el otro zapato se cayó, se
puede distinguir el predicado (el otro zapato) y el verbo (se cayó). Cuando se ha
analizado la oración sintácticamente, se puede deducir el significado, o la semántica, de
la oración. Si usted sabe lo que es un zapato y el significado de caer, comprenderá el
significado de la oración.

Aunque existen muchas cosas en común entre los lenguajes naturales y los lenguajes
formales — por ejemplo, las unidades léxicas, la estructura, la sintaxis y la semántica —
también existen muchas diferencias:

ambigüedad
Los lenguajes naturales tienen muchísimas ambigüedades que se superan
usando claves contextuales e información adicional. Los Lenguajes formales son
diseñados para estar completamente libres de ambigüedades, tanto como sea
posible, lo que quiere decir que cualquier sentencia tiene sólo un significado sin
importar el contexto en el que se encuentra.

redundancia
Para reducir la ambigüedad y los malentendidos, los lenguajes naturales utilizan
bastante redundancia. Como resultado tienen una abundancia de posibilidades
para expresarse. Los lenguajes formales son menos redundantes y más concisos.

literalidad
Los lenguajes naturales tienen muchas metáforas y frases comunes. El significado
de un dicho, por ejemplo, estiró la pata, es diferente al significado de sus
sustantivos y verbos. En este ejemplo, la oración no tiene nada que ver con un
pie y significa ‘murió’. En los lenguajes formales sólo existe el significado literal.

Los que aprenden a hablar un lenguaje natural —es decir todo el mundo— muchas veces
tienen dificultad en adaptarse a los lenguajes formales. A veces la diferencia entre los
lenguajes formales y los naturales es comparable a la diferencia entre la prosa y la
poesía:
Poesía
Se utiliza la palabra por su cualidad auditiva tanto como por su significado. El
poema, en su totalidad, produce un efecto o reacción emocional. La ambigüedad
no es sólo común sino utilizada a propósito.

Prosa
El significado literal de la palabra es más importante y la estructura contribuye
aún más al significado. La prosa se presta más al análisis que la poesía, pero
todavía contiene ambigüedad.

Programas
El significado de un programa es inequívoco y literal, y es entendido en su
totalidad analizando las unidades léxicas y la estructura.

He aquí unas sugerencias para la lectura de un programa (y de otros lenguajes


formales). Primero, recuerde que los lenguajes formales son mucho más densos que los
lenguajes naturales, y en consecuencia toma más tiempo dominarlos. Además, la
estructura es muy importante, entonces usualmente no es una buena idea leerlo de
arriba a abajo y de izquierda a derecha. En lugar de esto, aprenda a separar las
diferentes partes en su mente, identificar las unidades léxicas e interpretar la estructura.
Finalmente, ponga atención a los detalles. Las fallas de puntuación y la ortografía
afectarán negativamente la ejecución de su programa.

1.9. El primer programa


Tradicionalmente el primer programa en un lenguaje nuevo se llama “¡Hola todo el
mundo!” porque sólo muestra las palabras ¡Hola todo el mundo!. En el lenguaje Python
es así:

print "¡Hola todo el mundo!"

Este es un ejemplo de una sentencia print , la cual no imprime nada en papel, más bien
muestra un valor. En este caso, el resultado es las palabras:

¡Hola todo el mundo!

Las comillas señalan el comienzo y el final del valor; ellas no aparecen en el resultado.
Algunas personas evalúan la calidad de un lenguaje de programación por la simplicidad
del programa ¡Hola todo el mundo!. Si seguimos ese criterio, Python cumple con este
cometido bastante bien.

1.10. Glosario
algoritmo
Un proceso general para resolver una clase completa de problemas.

análisis sintáctico
Escudriñamiento de un programa y realización del análisis de su estructura
sintáctica.

bicho
Un error en un programa.

código de bytes
Un lenguaje intermedio entre el código fuente y el código objeto. Muchos de los
lenguajes modernos traducen el código fuente en código de bytes y después
interpretan el código de bytes mediante un programa denominado máquina
virtual.

código fuente
Un programa escrito en un lenguaje de alto nivel antes de ser compilado.

código objeto
La salida del compilador una vez que el programa ha sido traducido.

compilar
Traducir un programa escrito en un lenguaje de alto nivel a un lenguaje de bajo
nivel de una vez, en preparación para la ejecución posterior.

depuración
El proceso de hallazgo y eliminación de los tres tipos de errores de
programación.

error de sintaxis
Un error estructural que hace que un programa sea imposible de analizar
sintácticamente (e imposible de interpretar).
error en tiempo de ejecución
Un error que no ocurre hasta que el programa ha comenzado su ejecución e
impide que éste continúe.

error semántico

Un error en un programa que hace que se ejecute algo que no era lo deseado.

excepción
Otro nombre para un error en tiempo de ejecución.

guión
Un programa almacenado en un archivo (que usualmente será interpretado).

interpretar
Ejecutar un programa escrito en un lenguaje de alto nivel traduciéndolo línea por
línea.

lenguaje de alto nivel


Un lenguaje de programación como Python que está diseñado para ser fácil de
leer y escribir.

lenguaje de bajo nivel


Un lenguaje de programación que está diseñado para ser fácil de ejecutar para
una computadora; también se le llama lenguaje de máquina o lenguaje
ensamblador.

lenguaje formal
Cualquier lenguaje diseñado que tiene un propósito específico, como la
representación de ideas matemáticas o programas de computadoras; todos los
lenguajes de programación son lenguajes formales.

lenguaje natural
Cualquier lenguaje hablado que evolucionó de forma natural.

portabilidad
La cualidad de un programa que puede ser ejecutado en más de un tipo de
computadora.

programa
Secuencia de instrucciones que especifica a una computadora las acciones y
cálculos que debe realizar.

Programa ejecutable
Otro nombre para el código de objeto que está listo para ser ejecutado.

Resolución de problemas
El proceso de plantear un problema, hallar la solución y expresarla.

semántica
El significado de un programa

Sentencia print
Una instrucción que causa que el intérprete de Python muestre un valor en el
monitor.

sintaxis
La estructura de un programa.

terminal de Python
Interfase interactiva del intérprete de Python. El usuario de la terminal de Python
escribe los comandos en el indicador (>>>), y presiona la tecla Entrar para enviar
inmediatamente estos comandos al intérprete para su procesamiento.

Unidad léxica
Uno de los elementos básicos de la estructura sintáctica de un programa, análogo
a una palabra en un lenguaje natural.

1.11. Ejercicios

1. Escriba en español una oración semánticamente comprensible pero


sintácticamente incorrecta. Escriba otra oración que sea sintácticamente correcta
pero que contenga errores semánticos.

2. Inicie la terminal de Python. Escriba 1 + 2 y luego presione la tecla Entrar.


Python evalúa esta expresión, presenta el resultado, y enseguida muestra otro
indicador. Considerando que el símbolo * es el signo de multiplicación y el doble
símbolo ** es el signo de potenciación, realice ejercicios adicionales escribiendo
diferentes expresiones y observando lo mostrado por el intérprete de Python.
¿Qué sucede si utiliza el signo de división ( /)? ¿Son los resultados obtenidos los
esperados? Explique.

3. Escriba 1 2 y presione la tecla Entrar. Python trata de evaluar esta expresión,


pero no puede, porque la expresión es sintácticamente incorrecta. Así, Python
responde con el siguiente mensaje de error:
File "<stdin>", line 1
1 2
^
SyntaxError: invalid syntax

Muchas veces Python indica la ubicación del error de sintaxis, sin embargo, no
siempre es precisa, por lo que no proporciona suficiente información sobre cuál
es el problema. De esta manera, el mejor antídoto es que usted aprenda la
sintaxis de Python.

En este caso, Python protesta porque no encuentra signo de operación alguno


entre los números.

Escriba tres ejemplos adicionales de cadenas que produzcan mensajes de error


cuando se introducen en el indicador de Python. Explique por qué cada ejemplo
no tiene una sintaxis de Python válida.

4. Escriba print 'hola'. Python ejecuta esta sentencia que muestra las letras h-


o-l-a. Nótese que las comillas simples en los extremos de la cadena no son parte
de la salida mostrada. Ahora escriba print '"hola"' y describa y explique el
resultado.

5. Escriba print queso sin comillas. La salida será algo como esto:

Traceback (most recent call last):


File "<stdin>", line 1, in ?
NameError: name 'queso' is not defined

Este es un error en tiempo de ejecución; específicamente, es un NameError, y


más específicamente, es un error porque el nombre queso no está definido. Si
aún no sabe qué significa esto, lo sabrá pronto.

6. Escriba 'Esta es una prueba...' en el indicador de Python y presione la


tecla Entrar. Observe lo que pasa. Ahora cree un guión de Python con el
nombre prueba1.py que contenga lo siguiente (asegúrese de guardar el archivo
antes de intentar correrlo):

'Este es una prueba...'

¿Qué pasa cuando corre este guión? Ahora cambie el contenido del guión a:

print 'Este es una prueba...'


y córralo de nuevo.

¿Qué pasó esta vez?

Cuando se escribe una <em>expresión</em> en el indicador de Python, ésta


es evaluada y el resultado es mostrado en la línea
siguiente. 'Esta es una prueba...' es una expresión, que se evalúa
con 'Esta es una prueba...' (de la misma manera que 42 se evalúa
con 42). Sin embargo, la evaluación de expresiones en un guión no se envía a la
salida del programa, por lo que es necesario mostrarla explícitamente.

2. Variables, expresiones y sentencias

2.1. Valores y tipos


Un valor es una de las cosas fundamentales que un programa manipula — como una
letra o un número. Los valores que hemos visto hasta ahora son el número 2 (resultado
de la adición de 1 + 1), y "¡Hola todo el mundo!".

Estos valores pertenecen a diferentes tipos: 2 es un entero, y "¡Hola todo el mundo!" es


una cadena , llamada así porque contiene unacadenade letras. Usted (y el intérprete)
puede identificar cadenas porque están encerradas entre comillas.

La sentencia print también trabaja con enteros.

>>> print 4
4

Si no esta seguro del tipo que un valor tiene, el intérprete le puede decir.

>>> type("¡Hola todo el mondo!")


<type 'str'>
>>> type(17)
<type 'int'>

Las cadenas pertenezcan al tipo str y los enteros pertenezcan al tipo int . Los números
con un punto decimal pertenezcan a un tipo llamado float, porque éstos se representan
en un formato denominado punto flotante.

>>> type(3.2)
<type 'float'>

¿Que ocurre con valores como "17" y "3.2"? Parecen números, pero están encerrados
entre comillas como las cadenas.
>>> type("17")
<type 'str'>
>>> type("3.2")
<type 'str'>

Ellos son cadenas.

Cadenas en Python puede ser incluida en cualquiera de los dos comillas simples (') o
comillas dobles ("):

>>> type('Este es una cadena.')


<type 'str'>
>>> type("y este es tambian.")
<typle 'str'>

Cuando usted escribe un número grande podría estar tentado a usar comas para separar
grupos de tres dígitos, como en 1,000,000. Esto no es un número entero válido en
Python, pero sí es aceptado en una sentencia como:

>>> print 1,000,000


1 0 0

Bueno, ¡eso no es lo que esperábamos! Python interpreta a 1,000,000 como una lista de


tres números. Siendo así, recuerde no poner comas en sus números enteros.

2.2. Variables
Una de las características más poderosas en un lenguaje de programación es la
capacidad de manipular variables. Una variable es un nombre que se refiere a un valor.

La sentencia de asignación crea nuevas variables y les da valores:

>>> mensaje = "¿Qué Onda?"


>>> n = 17
>>> pi = 3.14159

Este ejemplo hace tres asignaciones. La primera asigna la cadena "¿Que Onda?" a una


nueva variable denominada mensaje. La segunda le asigna el entero 17 a n, y la tercera le
da el número de punto flotante 3.14159 a pi.

No debe confundirse el operador de asignación, =, con el signo de igualdad (aún y


cuando se usa el mismo símbolo). El operador de asignación enlaza un nombre, en el
lado izquierdo del operador, con un valor en el lado derecho. Esta es la razón por la que
obtendrá un error si escribe:
>>> 17 = n

Una manera común de representar variables en el papel es escribir el nombre de la


variable con una flecha apuntando a su valor. Esta clase de dibujo se
denomina diagrama de estado porque muestra el estado de cada una de las variables
(piense en los valores como el estado mental de las variables). Este diagrama muestra el
resultado de las sentencias de asignación anteriores:

La sentencia print también funciona con variables.

>>> print mensaje


¿Qué Onda?
>>> print n
17
>>> print pi
3.14159

En cada caso el resultado es el valor de la variable. Las variables también tienen tipos;
nuevamente, le podemos preguntar al intérprete cuáles son.

>>> type(mesaje)
<type 'str'>
>>> type(n)
<type 'int'>
>>> type(pi)
<type 'float'>

El tipo de una variable es el tipo del valor al que se refiere.

2.3. Nombres de variables y palabras reservadas


Los programadores generalmente escogen nombres significativos para sus variables —
que especifiquen para qué se usa la variable.

Los nombres de variables pueden ser arbitrariamente largos. Pueden contener letras y


números, pero tienen que empezar con una letra. Aunque es permitido usar letras
mayúsculas, por convención no lo hacemos. Si usted lo hace, recuerde que las letras
mayúsculas importan, Pedro y pedro son variables diferentes.

El carácter subrayado (_) puede aparecer en un nombre. A menudo se usa en nombres


con múltiples palabras, tales como mi_nombre ́ó precio_de_la_porcelana_en_china .

Si usted le da un nombre inválido a una variable obtendrá un error de sintaxis:

>>> 76trombones = "gran desfile"


SyntaxError: invalid syntax
>>> mas$ = 1000000
SyntaxError: invalid syntax
>>> class = "Informática 101"
SyntaxError: invalid syntax

76trombones es inválido porque no empieza con una letra. mas$ es inválido porque


contiene un carácter ilegal, el símbolo $. Pero, ¿que sucede con class?

Resulta que class es una de las palabras reservadas de Python. Las palabras reservadas


definen las reglas del lenguaje y su estructura, y no pueden ser usadas como nombres
de variables.

Python tiene treinta y una palabras reservadas:

and as assert break class continue


def del elif else except exec
finall
for from global if import
y
in is lambda not or pass
print raise return try while with
yield          

Usted puede mantener esta lista a mano. Si el intéprete se queja por alguno de sus
nombres de variables, y usted no sabe por qué, búsquelo en esta lista.

2.4. Sentencias
Una sentencia es una instrucción que el intérprete de Python puede ejecutar. Hemos
visto dos clases de sentencias: la asignación y print.

Cuando usted digita una sentencia en la línea de comandos, Python la ejecuta y


despliega el resultado, si hay alguno. El resultado de la sentencia print es un valor. Las
sentencias de asignación no producen un resultado.

Un guión usualmente contiene una secuencia de sentencias. Si hay más de una, los
resultados aparecen uno a uno a medida que las sentencias se ejecutan.

Por ejemplo, el guión

print 1
x = 2
print x

produce la salida:
1
2

Nuevamente, la sentencia de asignación no produce salida.

2.5. Evaluación de expresiones


Una expresión es una combinación de valores, variables y operadores. Si digita una
expresión en la línea de comandos, el intérprete la evalúa y despliega el resultado:

>>> 1 + 1
2

La evaluación de una expresión produce un valor, esta es la razón por la que las


expresiones pueden aparecer en el lado derecho de las sentencias de asignación. Un
valor, por si mismo, se considera como una expresión, lo mismo ocurre para las
variables.

>>> 17
17
>>> x
2

Aunque es un poco confuso, evaluar una expresión no es lo mismo que mostrar un


valor.

>>> mesaje = "Juan es chido"


>>> mesaje
'Juan es chido'
>>> print mesaje
Juan es chido

Cuando la terminal de Python muestra el valor de una expresión que ha evaluado, usa el
mismo formato que se usaría para introducir un valor. En el caso de las cadenas, esto
implicaría que se incluyen las comillas. Pero la sentencia print despliega el valor de la
expresión que, en este caso, es el contenido de la cadena.

En un guión, una expresión, por sí misma, es una sentencia válida, pero no realiza nada.
El guión

17
3.2
"¡Hola todo el mundo!"
1 + 1
no produce ninguna salida. ¿Como cambiaría el guión de manera que despliegue los
valores de las cuatro expresiones?

2.6. Operadores y operandos


Los operadores son símbolos especiales que representan cómputos como la suma y la
multiplicación. Los valores que el operador usa se denominan operandos.

Los siguientes son expresiones válidas en Python cuyo significado es más o menos claro:

20+32 hour-1 hour*60+minute minute/60 5**2 (5+9)*(15-7)

Los símbolos +, - y /, y los paréntesis para agrupar, significan en Python lo mismo que
en matemáticas. El asterisco (*) es el símbolo para la multiplicación, y ** es el símbolo
para la potenciación.

Cuando el nombre de una variable aparece en la posición de un operando, se reemplaza


por su valor antes de realizar la operación.

La suma, resta, multiplicación y potenciación realizan lo que usted esperaría pero la


división podría sorprenderlo. La siguiente operacion tiene un resultado inesperado:

>>> minuto = 59
>>> minuto/60
0

El valor de minuto es 59, y 59 dividido por 60 es 0.98333, no 0. La razón para esta


discrepancia radica en que Python está realizando división entera.

Cuando los dos operandos son enteros el resultado también debe ser un entero; y, por
convención, la división entera siempre redondea hacia abajo, incluso en casos como éste
donde el siguiente entero está muy cerca.

Una posible solución a este problema consiste en calcular un porcentaje, en lugar de una
fracción:

>>> minuto*100/60
98

De nuevo, el resultado se redondea hacia abajo; pero, al menos ahora, el resultado


estará más aproximado. Otra alternativa es usar la división en punto flotante. En el
capítulo 4 veremos cómo convertir valores enteros y variables a valores de punto
flotante.
2.7. Orden de las operaciones
Cuando hay más de un operador en una expresión, el orden de evaluación depende de
las reglas de precedencia. Python sigue las mismas reglas de precedencia a las que
estamos acostumbrados para sus operadores matemáticos. El acrónimo PPMDAS es útil
para recordar el orden de las operaciones:

1. Los Paréntesis tienen la precedencia más alta y pueden usarse para forzar la


evaluación de una expresión en el orden que usted desee. Ya que las expresiones
en paréntesis se evalúan primero , 2 * (3-1) es 4, y (1+1)**(5-2) es 8. También
puede usar paréntesis para que una expresión quede más legible, como
en (minute * 100) / 60, aunque esto no cambie el resultado.
2. La Potenciación tiene la siguiente precedencia más alta, así que 2**1+1 es 3 y no
4, y 3*1**3 es 3 y no 27.
3. La Multiplicación y División tienen la misma precedencia, que es más alta que la
de la Adición y la Subtracción, que también tienen la misma precedencia. Así
que 2*3-1 da 5 en lugar de 4, y 2/3-1 es -1, no 1 (recuerde que, en división
entera, 2/3=0).
4. Los operadores con la misma precedencia se evalúan de izquierda a derecha. Así
que en la expresión minute*100/60, la multiplicación se hace primero, resultando
5900/60, lo que a su vez da 98. Si las operaciones se hubieran evaluado de
derecha a izquierda, el resultado sería 59*1, que es 59, y no es lo correcto.

2.8. Operaciones sobre cadenas


En general, usted no puede realizar operaciones matemáticas sobre cadenas, incluso si
las cadenas están compuestas por números. Las siguientes operaciones son inválidas
(suponiendo que mensaje tiene el tipo cadena):

mensaje-1 "Hola"/123 mensaje*"Hola" "15"+2

Sin embargo, el operador + funciona con cadenas, aunque no calcula lo que usted


esperaría. Para las cadenas el operador + representa la operación de concatenación, que
significa unir los dos operandos enlazándolos en el orden en que aparecen. Por ejemplo:

bien_cocinado = "pan de nuez y"


fruta = "plátano"
print bien_cocinado + fruta

La salida de este programa es pan de nuez y plátano. El espacio antes de la


palabra plátano es parte de la cadena y sirve para producir el espacio entre las cadenas
concatenadas.
El operador * también funciona con las cadenas; hace una operación de repetición. Por
ejemplo, 'Ja'*3 resulta en 'JaJaJa'. Uno de los operandos tiene que ser una cadena, el
otro tiene que ser un entero.

Estas interpretaciones de + y * tienen sentido por la analogía existente con la suma y la


multiplicación. Así como 4*3 es equivalente a 4+4+4, esperamos que "Ja"*3 sea lo
mismo que "Ja"+"Ja"+"Ja", y lo es. Sin embargo, las operaciones de concatenación y
repetición sobre cadenas tienen una diferencia significativa con las operaciones de suma
y multiplicación. ¿Puede usted pensar en una propiedad que la suma y la multiplicación
tengan y que la concatenación y repetición no?

2.9. Introducción de datos


Existen dos funciones incorporadas en Python para introducir datos desde el teclado:

n = raw_input("Introduzca su nombre por favor: ")


print n
n = input("Introduzca una expresión numérica: ")
print n

Una muestra de la ejecución de este guión sería:

$ python entrada.py
Introduzca su nombre por favor: Arturo, Rey de los británicos
Arturo, Rey de los británicos
Introduzca una expresión numérica: 7 * 3
21

Cada una de estas funciones permite el uso de un indicador que se da entre los


paréntesis de la función.

2.10. Composición
Hasta aquí hemos visto aisladamente los elementos de un programa — variables,
expresiones, y sentencias — sin especificar cómo combinarlos.

Una de las características más útiles de los lenguajes de programación es su capacidad


de tomar pequeños bloques para componer con ellos. Por ejemplo, ya que sabemos
cómo sumar números y cómo mostrarlos; de aquí se desprende que podemos hacer las
dos cosas al mismo tiempo:

>>> print 17 + 3
20
De hecho, la suma tiene que calcularse antes que el mostrado en pantalla, así que las
acciones no están ocurriendo realmente al mismo tiempo. La cuestión es que cualquier
expresión que tenga números, cadenas y variables puede ser usada en una
sentencia print. Usted ya ha visto un ejemplo de esto:

print "Número de minutos desde medianoche: ", hour * 60 + minute

También puede poner expresiones arbitrarias en el lado derecho de una sentencia de


asignación:

percentage = (minuto * 100) / 60

Esta capacidad no parece nada impresionante ahora, pero vamos a ver otros ejemplos en
los que la composición hace posible expresar cálculos complejos organizada y
concisamente.

Advertencia: hay restricciones sobre los lugares en los que se pueden usar las
expresiones. Por ejemplo, el lado izquierdo de una sentencia de asignación tiene que ser
un nombre de variable, no una expresión. Entonces lo siguiente es
inválido: minuto+1 = hour.

2.11. Comentarios
A medida que los programas se hacen más grandes y complejos, se hacen más difíciles
de leer. Los lenguajes formales son densos; y, a menudo, es difícil mirar una sección de
código y saber qué hace, o por qué lo hace.

Por esta razón, es una buena idea añadir notas a sus programas para explicar, en
lenguaje natural, lo que el programa hace. Estas notas se denominan comentarios y se
marcan con el símbolo #:

# calcula el porcentaje del tiempo transcurrido (en horas)


porcentaje = (minuto * 100) / 60

En este caso el comentario aparece en una línea completa. También se pueden poner
comentarios al final de una línea:

porcentaje = (minute * 100) / 60 # precaución: división entera

Todo lo que sigue desde el símbolo # hasta el final de la línea se ignora — no tiene


efecto alguno en el programa. El mensaje es para el programador que escribe el
programa o para algún programador que podría usar este código en el futuro. En este
caso le recuerda al lector el sorprendente comportamiento de la división entera en
Python.

2.12. Glosario
cadena
Un tipo de dato en Python que tiene una “cadena” de caracteres.

comentario
Información que se incluye en un programa para otro programador (o lector del
código fuente) que no tiene efecto en la ejecución.

composición
La capacidad de combinar expresiones y sentencias simples dentro de sentencias
y expresiones compuestas para representar concisamente cálculos complejos.

concatenar
Unir dos operandos, en el orden en que aparecen.

diagrama de estado
Una representación gráfica de un conjunto de variables y los valores a los que se
refieren.

división entera
Una operación que divide un entero por otro y retorna un entero. La división
entera retorna el número de veces que el denominador cabe en el numerador y
descarta el residuo.

entero
Un tipo de dato en Python que tiene números enteros positivos y negativos.

evaluar
Simplificar una expresión ejecutando varias operaciones hasta obtener un sólo
valor.

expresión
Una combinación de variables, operadores y valores cuyo resultado se representa
por un único valor.
nombre de variable
Es el nombre dado a una variable. Los nombres de variables en Python consisten
en una secuencia de letras (a...z, A...Z, and _) y dígitos (0..9) que empiezan con
una letra. De acuerdo con las buenas prácticas de la programación, los nombres
de variables se eligen, de forma tal, que describan su uso en el programa
haciéndolo autodocumentado.

operador
Un símbolo especial que representa cálculos simples como la suma,
multiplicación, o concatenación de cadenas.

operador de asignación
El símbolo = es el operador de asignación de Python, que no debe confundirse
con el <em>signo igual</em>, utilizado para indicar la igualdad matemática.

operando
Uno de los valores sobre el cual actúa un operador.

2.13. Ejercicios

1. Registre qué sucede cuando usa la sentencia print en combinación con una


sentencia de asignación:

>>> print n = 7

¿Qué sucede con esto otro?

>>> print 7 + 5

¿Y qué con esto otro?

>>> print 5.2, "esto", 4 - 2, "aquello", 5/2.0

¿Puede identificar un uso general para lo que sigue a una sentencia print? ¿Qué es lo
que proporciona como salida la sentencia print?

2. Tome la siguiente oración: Sólo trabajo y nada de juegos hacen de Juan un niño


aburrido. Almacene cada palabra en variables separadas, después muestre la oración en
una sola línea usando la sentencia print.

3. Incluya paréntesis a la expresión 6 * 1 - 2 para cambiar su resultado de 4< a -6.


4. Inserte una línea de comentario en una línea previa a una de código funcional, y
registre qué es lo que sucede cuando corre de nuevo el programa.

5. La diferencia entre la función input y la función raw_input es que la


función input evalúa la cadena introducida y la función raw_input no lo hace.
Escriba lo siguiente en el intérprete de Python y registre qué sucede:

>>> x = input()
3.14
>>> type(x)
>>> x = raw_input()
3.14
>>> type(x)
>>> x = input()
'Los caballeros que dicen "¡no!"'
>>> x

¿Qué sucede si realiza el mismo ejercicio anterior sin las comillas simples?

>>> x = input()
Los caballeros que dicen "¡no!"
>>> x
>>> x = raw_input()
'Los caballeros que dicen "¡no!"'
>>> x

Describa y explique cada resultado.

6. Inicie el intérprete de Python y escriba bruno + 4 en el indicador. Esto dará un


error:

NameError: name 'bruno' is not defined

Asigne un valor a bruno tal que bruno + 4 de 10.

7. Escriba un programa (un guión en Python) que se llame madlib.py, que pida al


usuario escribir una serie de sustantivos, verbos, adjetivos, adverbios, sustantivos
en plural, verbos en pasado, etc., y que genere un párrafo que sea sintácticamente
correcto pero semánticamente ridículo (vea http://madlibs.org — en inglés —
ó http://probar.blogspot.com — en español — como ejemplos).

3. Funciones
3.1. Definiciones y uso
En el contexto de la programación una función es una secuencia de sentencias que
ejecuta una operación deseada y tiene un nombre. Esta operación se especifica en
una definición de función. La sintaxis para una definición de función en Python es:

def NOMBRE( LISTA DE PARAMETROS ):


SENTENCIAS

Usted puede inventar los nombres que desee para sus funciones siempre y cuando no
use una palabra reservada de Python. La lista de parámetros especifica qué información,
si es que la hay, se debe proporcionar a fin de usar la nueva función.

Se puede incluir cualquier número de sentencias dentro de la función, pero todas deben
sangrarse a partir del margen izquierdo. En los ejemplos de este libro usaremos un
sangrado estándar de cuatro espacios. La definición de función es la primera de
diversas sentencias compuestas que veremos más adelante, teniendo todas ellas la
misma estructura:

1. Un encabezado, que empieza con una palabra reservada y termina con dos
puntos.
2. Un cuerpo consistente de una o más sentencias de Python, cada una de ellas con
la misma sangría – 4 espacios es el estándar de Python – a partir del margen
izquierdo.

En una definición de función la palabra reservada en el encabezado es def, y enseguida


se escribe el nombre de la función y una lista de parámetros encerrados entre
paréntesis. La lista de parámetros puede estar vacía o contener un sinnúmero de
parámetros. En cualquier caso los paréntesis se requieren.

El primer par de funciones que escribiremos no tiene parámetros, por lo que la sintaxis
luce así:

def nueva_linea():
print # la sentencia print sin argumentos muestra una nueva línea

Esta función se llama nueva_linea. Los paréntesis vacíos indican que la función no tiene
parámetros. Su cuerpo contiene solamente una única sentencia, cuya salida es una línea
vacía. (Eso es lo que ocurre cuando se usa la sentencia print sin argumentos.)
Nota del traductor: El uso de nombres de funciones (y de nombres de variables) con
acentos sólo es posible en la versión 3.0 — y superiores — del intérprete de Python. Si
tiene alguna versión inferior, no use acentos en los nombres de funciones.

Definir una nueva función no hace que la función se ejecute. Para hacerlo se necesita
una llamada a función. Las llamadas a función contienen el nombre de la función a
ejecutar seguida por la lista de valores, llamados argumentos, que son asignados a los
parámetros en la definición de función. Nuestra primera función tiene una lista vacía de
parámetros, por lo que la llamada a función no tiene ningún argumento. Nótese, sin
embargo, que en la llamada a función se requiere los paréntesis:

print "Primera Línea."


nueva_linea()
print "Segunda Línea."

La salida de este programa es:

Primera Línea.

Segunda Línea.

El espacio extra entre las dos líneas es el resultado de la llamada a la


función nueva_linea(). ¿Qué pasa si deseamos más espacio entre las líneas? Podemos
llamar la misma función repetidamente:

print "Primera Línea."


nueva_linea()
nueva_linea()
nueva_linea()
print "Segunda Línea."

O podemos escribir una nueva función llamada tres_líneas que muestre tres nuevas


líneas:

def tres_lineas():
nueva_linea()
nueva_linea()
nueva_linea()

print "Primera Línea."


tres_lineas()
print "Segunda Línea."

Esta función contiene tres sentencias, y todas están sangradas por cuatro espacios.
Como la siguiente sentencia no está sangrada, Python reconoce que tal sentencia no es
parte de la función.
Hay que destacar algunos aspectos de este programa:

 Usted puede llamar la misma función repetidamente. De hecho, es una práctica


muy común y útil.
 Usted puede llamar una función dentro de otra función; en este
caso tres_líneas llama a nueva_linea().

Hasta este punto, puede que no parezca claro por qué hay que tomarse la molestia de
crear todas estas funciones. De hecho, hay muchas razones, y el ejemplo que acabamos
de ver muestra dos:

1. Crear una nueva función le da a usted la oportunidad de nombrar un grupo de


sentencias. Las funciones pueden simplificar un programa escondiendo un
cálculo complejo detrás de un comando único que usa palabras en lenguaje
natural, en lugar de un código arcano.
2. Crear una nueva función puede recortar el tamaño de un programa eliminando el
código repetitivo. Por ejemplo, una forma más corta de mostrar nueve líneas
consecutivas consiste en llamar la función tres_líneas tres veces.

Así, juntando los fragmentos de código de los párrafos previos en un guión


llamado pruebame1.py, el programa completo luce como sigue:

def nueva_linea():
print

def tres_lineas():
nueva_linea()
nueva_linea()
nueva_linea()

print "Primera Línea."


tres_lineas()
print "Segunda Línea."

Este programa contiene dos definiciones de función: nueva_linea y tres_líneas. Las


definiciones de función se ejecutan como las otras sentencias, pero su efecto es crear
nuevas funciones. Las sentencias dentro de la función no se ejecutan hasta que la
función sea llamada, y la definición de función no genera salida.

Como usted puede imaginar, se tiene que crear una función antes de ejecutarla. En otras
palabras, la definición de función tiene que ejecutarse antes de llamarla por primera vez.

3.2. Flujo de ejecución


Con el fin de asegurar que una función se defina antes de su primer uso usted tiene que
saber el orden en el que las sentencias se ejecutan, este orden de ejecución se
denomina flujo de ejecución.

La ejecución siempre empieza con la primera sentencia del programa. Las sentencias se
ejecutan una a una, desde arriba hacia abajo.

Las definiciones de función no alteran el flujo de ejecución del programa, pero recuerde
que las sentencias que están dentro de las funciones no se ejecutan hasta que éstas
sean llamadas. Aunque no es muy común, usted puede definir una función dentro de
otra. En este caso, la definición interna no se ejecuta hasta que la función externa sea
llamada.

Las llamadas a función son como un desvío en el flujo de ejecución. En lugar de


continuar con la siguiente sentencia, el flujo salta a la primera línea de la función
llamada, ejecuta todas las sentencias de la función, y regresa para continuar donde
estaba previamente.

Esto suena sencillo, hasta que tenemos en cuenta que una función puede llamar a otra.
Mientras se está ejecutando una función, el programa puede ejecutar las sentencias de
otra función. Pero, mientras se está ejecutando la nueva función, el programa puede
tener que ejecutar ¡otra función!

Afortunadamente, Python es experto en hacer el seguimiento de sus movimientos, así


que cada vez que una función termina, el programa regresa al punto de la función desde
donde fue llamada la función que recién fue terminada. Cuando llega al fin del
programa, la ejecución termina.

¿Cuál es la moraleja de esta sórdida historia? Cuando lea un programa, no lo haga de


arriba hacia abajo. En lugar de esto, siga el flujo de ejecución.

3.3. Parámetros, argumentos y la sentencia import


La mayoría de las funciones requieren argumentos, los valores que controlan la manera
en que la funciones trabajan. Por ejemplo, si usted quiere encontrar el valor absoluto de
un número, tiene que indicar cuál es el número. Python tienen una función integrada en
su biblioteca de funciones para calcular el valor absoluto:

>>> abs(5)
5
>>> abs(-5)
5

En este ejemplo los argumentos de la función abs son 5 y -5.


Algunas funciones necesitan más de un argumento. Por ejemplo, la función de
biblioteca pow toma dos argumentos, la base y el exponente. Dentro de la función, los
valores que se pasan se asignan a variables llamadas parámetros.

>>> pow(2, 3)
8
>>> pow(7, 4)
2401

Otra función de biblioteca que toma más de un argumento es max.

>>> max(7, 11)


11
>>> max(4, 1, 17, 2, 12)
17
>>> max(3 * 11, 5**3, 512 - 9, 1024**0)
503

La función max puede enviar a la definición de función cualquier número de argumentos,


separados por comas, y la llamada a función devolverá el máximo de los valores
enviados. Los argumentos pueden ser valores simples o expresiones. En el último
ejemplo la llamada a función regresa 503, puesto que es el mayor de 33, 125 y 1.

Aquí hay un ejemplo de una función definida por el programador que toma un
parámetro:

def muestra_doble(bruno):
print bruno, bruno

Esta función toma un sólo argumento y lo asigna a un parámetro llamado bruno. El valor


del parámetro (en este momento no tenemos idea de lo que será) se muestra dos veces
seguido por un salto de línea. El nombre bruno se escogió para sugerir que el nombre
que se le asigna a un parámetro depende de usted; pero, en general, usted deseará
escoger algo más apropiado que bruno.

La línea de comandos de Python nos proporciona una forma apropiada de probar


nuestras funciones. Podemos usar la sentencia import para traer las funciones — que
hemos definido en un guión — a la sesión del intérprete de Python. Para saber cómo
funciona considere que la función muestra_doble está definida en un guión
llamado cap03.py. Podemos probarla interactivamente importándola en nuestra sesión
de la línea de comandos de Python:

>>> from cap03 import *


>>> muestra_doble('Basura')
Basura Basura
>>> muestra_doble(5)
5 5
>>> muestra_doble(3.14159)
3.14159 3.14159

En una llamada a función el valor del argumento se asigna al parámetro correspondiente


en la definición de función. En efecto, esto sucede si se
ejecuta bruno = 'Basura' cuando la función muestra_doble('Basura')  es llamada, ó
cuando se ejecuta bruno = 5 en muestra_doble(5),
ó bruno = 3.14159 en muestra_doble(3.14159) .

Cualquier tipo de argumento que pueda ser mostrado, puede ser enviado a la
función muestra_doble. En la primera llamada a función el argumento es una cadena. En
la segunda es un entero. En la tercera es un número de punto flotante (tipo float).

De la misma manera que con las funciones de biblioteca, podemos usar una expresión
como argumento para la función muestra_doble:

>>> muestra_doble('Basura' * 4)
BasuraBasuraBasuraBasura BasuraBasuraBasuraBasura

Primero se evalúa 'Basura' * 4 para producir 'BasuraBasuraBasuraBasura' , el cual se


pasa como un argumento a la función muestra_doble.

3.4. Composición
Asi como las funciones matemáticas, las funciones de Python pueden componerse, esto
es, puede usar el resultado de una función como entrada de otra

>>> muestra_doble(abs(-7))
7 7
>>> muestra_doble(max(3, 1, abs(-11), 7))
11 11

En el primer ejemplo, abs(-7) produce 7, el cual es ahora el argumento de la


función muestra_doble. En el segundo ejemplo tenemos dos niveles de composición
puesto que primero se evalúa abs(-11) que produce 11, y luego se
evalúa max(3, 1, 11, 7) que da como resultado 11; finalmente la
función muestra_doble(11) muestra el resultado.

También podemos usar una variable como un argumento:


>>> miguel = 'Eric, el medio abeja.'
>>> muestra_doble(miguel)
Eric, el medio abeja. Eric, el medio abeja.

Note algo muy importante en este ejemplo: el nombre de la variable que pasamos como
argumento (miguel) no tiene nada que ver con el nombre del parámetro (bruno). Es decir,
no importa cómo se nombraba el valor originalmente (desde la llamada de función);
aquí, en la función muestra_doble llamamos a cualquiera de ellos bruno.

3.5. Las variables y los parámetros son locales


Cuando usted crea una variable local en una función, solamente existe dentro de la
función y no fuera de ella. Por ejemplo:

def concatena_doble(parte1, parte2):


concatena = parte1 + parte2
muestra_doble(concatena)

Esta función toma dos argumentos, los concatena, y luego muestra el resultado dos
veces. Podemos llamar a la función con dos cadenas:

>>> cantico1 = "Pie Jesu domine, "


>>> cantico2 = "Dona eis requiem."
>>> concatena_doble(cantico1, cantico2)
Pie Jesu domine, Dona eis requiem. Pie Jesu domine, Dona eis requiem.

Cuando concatena_doble termina, la variable concatena se destruye. Si intentamos


mostrarla obtenemos un error:

>>> print concatena


NameError: name 'concatena' is not defined

Los parámetros también son locales. Por ejemplo, afuera de la función muestra_doble,


no existe algo como bruno. Si usted intenta usarlo Python se quejará.

3.6. Diagramas de pila


Para seguir la pista de qué variables se usan en qué lugares es útil dibujar un diagrama
de pila. Como los diagramas de estado, los diagramas de pila muestran el valor de cada
variable y además muestran a qué función pertenece cada una.

Cada función se representa por un marco. Un marco es un recuadro con el nombre de


una función al lado y los parámetros y variables adentro. El diagrama de pila para el
ejemplo anterior luce así:
El orden de la pila mustra el flujo de ejecución. La función muestra_doble fue llamada
por concatena_doble, y concatena_doble fue llamada por __main__, que es un nombre
especial para la función de más alto nivel. Esto significa que cuando usted crea una
variable afuera de cualquier función, tal variable pertenece a __main__.

Cada parámetro se refiere al mismo valor que su argumento correspondiente.


Así, parte1 tiene el mismo valor que cantico1, parte2 tiene el mismo valor
que cantico2, y bruno tiene el mismo valor que concatena.

Si sucede un error durante una llamada de función, Python muestra el nombre de ésta, el
nombre de la función que la llamó, el nombre de la función que llamó a esta otra, y así
sucesivamente hasta llegar a la función de más alto nivel.

Para ver cómo funciona esto cree un guión en Python que se llame pruebame2.py que
luce como sigue:

def muestra_doble(bruno):
print bruno, bruno
print concatena

def concatena_doble(parte1, parte2):


concatena = parte1 + parte2
muestra_doble(concatena)

cantico1 = "Pie Jesu domine, "


cantico2 = "Dona eis requim."
concatena_doble(cantico1, cantico2)

Hemos agregado la sentencia print concatena en la función muestra_doble; sin


embargo, concatena no está definida en esta función. Al ejecutar este guión se producirá
un mensaje de error como el siguiente:
Esta lista de funciones se denomina trazado inverso. Nos informa en qué archivo de
programa ocurrió el error, en qué línea, y qué funciones se estaban ejecutando en ese
momento. También muestra la línea de código que causó el error.

Note la similitud entre el trazado inverso y el diagrama de pila. Esto no es una


coincidencia. De hecho, otro nombre común para el trazado inverso es trazado de pila.

3.7. Glosario
función

Secuencia de sentencias etiquetadas que llevan a cabo determinada operación de


utilidad. Las funciones pueden tomar parámetros o no, y pueden producir un
resultado o no.

definición de función
Sentencia que crea una nueva función, especificando su nombre, parámetros y las
sentencias que ejecuta.

sentencia compuesta

Sentencia que consiste de dos partes:

1. encabezado - que empieza con una palabra reservada que determina el


tipo de sentencia, y finaliza con dos puntos.
2. cuerpo - que contiene una o más sentencias con el mismo sangrado
desde el encabezado.

La sintaxis de una sentencia compuesta se ve así:

.. sourcecode:: python

palabra_reservada expresión:

sentencia sentencia ...


encabezado
Primera parte de una sentencia compuesta. Los encabezados empiezan con una
palabra reservada y terminan con dos puntos.

cuerpo
Segunda parte de una sentencia compuesta. El cuerpo consiste de una secuencia
de sentencias sangradas la misma distancia a partir del inicio del encabezado. El
sangrado usual usado en la comunidad Python es de 4 espacios.

llamada a función
Una sentencia que ejecuta una función. Está compuesta por el nombre de la
función más una lista de argumentos encerrados entre paréntesis.

flujo de ejecución
Orden en el que se ejecutan las sentencias durante la ejecución de un programa.

parámetro
Nombre que se usa dentro de una función para referirse al valor que se le pasa
como argumento.

import

Sentencia que permite que las funciones y variables definidas en un guión de


Python estén disponibles en el ámbito de otro guión o en una sesión interactiva
con la terminal de Python.

Por ejemplo, suponga que las siguientes instrucciones están en un guión


llamado pruebame.py:

def muestra_tres_veces(algo):
print algo, algo, algo

n = 42
c = "Y ahora algo completamente diferente..."

Ahora inicie una sesión en la terminal de Python desde el mismo directorio donde
se localiza pruebame.py:

$ ls
pruebame.py &lt;y otras cosas...&gt;
$ python
>>>
Se han definido tres nombres en pruebame.py: muestra_tres_veces, n, y c. Si
intentamos acceder a cualquiera de ellos desde la terminal, sin haberlos
importado primero, obtenemos un error:

Sin embargo, si importamos todo el contenido de pruebame.py, podemos usar


todo lo que ahí está definido:

Nótese que usted no incluyó la extensión .py del nombre del guión en la


sentencia import.

argumento

Valor que se le pasa a una función cuando se la llama. El valor se asigna al


parámetro correspondiente de la función.

composición de función
Uso de la salida de una llamada a función como la entrada de otra.

variable local
Variable definida dentro de una función. Las variables locales sólo pueden usarse
dentro de su función.

diagrama de pila
Representación gráfica de una pila de funciones, sus variables y los valores a los
que se refieren.
marco
Recuadro que en un diagrama de pila representa una llamada a función. Contiene
las variables locales y los parámetros de la función.

trazado inverso
Listado de las funciones en curso de ejecución, presentadas cuando sucede un
error en tiempo de ejecución. Es común que al trazado inverso también se le
conozca como trazado de pila porque lista las funciones en el orden en el cual
son almacenadas en la pila de llamadas.

3.8. Ejercicios

1. Con un editor de texto cree un guión de Python que se llame pruebame3.py.


Escriba en este archivo una función que se llame nueve_lineas que use la
función tres_lineas para mostrar nueve líneas en blanco. Enseguida agregue una
función que se llame limpia_pantalla que muestre veinticinco líneas en blanco. La
última instrucción en su programa debe ser una llamada a limpia_pantalla.

2. Mueva la última instrucción del archivo pruebame3.py al inicio del programa, de


forma tal que la llamada a la función limpia_pantalla esté antes que la definición
de función. Ejecute el programa y registre qué mensaje de error obtiene. ¿Puede
establecer una regla sobre las definiciones de funciones y las llamadas a
función que describa la posición relativa entre ellas en el programa?

3. Utilizando la versión que funciona de pruebame3.py mueva la definición de nueva_


línea después de la definición de tres_líneas. Registre qué sucede cuando
ejecuta el programa. Ahora mueva la definición de nueva_linea debajo de una
llamada a tres_líneas(). Explique cómo es que éste es un ejemplo de la regla que
estableció en el ejercicio previo.

4. Cree el cuerpo de la definición de función de concatena_n_veces de forma tal que


muestre la cadena c, n veces:

def concantena_n_veces(c, n):


"Cree su código aquí"

Guarde este función en un guión llamado prueba_import.py. Ahora en el indicador de


Unix asegúrese de que usted se encuentra en el mismo directorio donde se localiza el
archivo prueba_import.py (el comando ls debe mostrar el archivo prueba_import.py).
Inicie la terminal de Python y pruebe lo siguiente:
>>> from prueba_import import *
>>> concatena_n_veces('Basura', 7)
BasuraBasuraBasuraBasuraBasuraBasuraBasura

Si todo sale bien su sesión lucirá como esta. Experimente con otras llamadas
a concatena_n_veces hasta que usted se sienta a gusto con los resultados obtenidos.

4. Condicionales

4.1. El operador módulo


El operador módulo funciona con enteros (y expresiones enteras), y devuelve el residuo
de dividir el primer operando entre el segundo. En Python, el operador módulo es el
signo de tanto por ciento (%). La sintaxis es la misma que para otros operadores:

>>> cociente = 7 / 3
>>> print cociente
2
>>> residuo = 7 % 3
>>> print residuo
1

Así que 7 dividido entre 3 da 2 con residuo 1.

El operador residuo resulta ser sorprendentemente útil. Por ejemplo, puede comprobar
si un número es divisible entre otro —si x % y es cero, entonces x es divisible entre y.

También puede usar el operador módulo para extraer el dígito más a la derecha de un
número. Por ejemplo, x % 10 devuelve el dígito más a la derecha de x (en base 10). De
manera similar, x % 100 devuelve los dos últimos dígitos.

4.2. Expresiones y valores booleanos


El almacenamiento de valores verdaderos y falsos en Python es del tipo bool, nombrado
así debido al matemático Británico George Boole. George Boole creó el Algebra booleana,
que es la base de toda la aritmética computacional moderna.

Solo hay dos valores booleanos: True y False. Las mayúsculas son importantes, ya


que true y false no son valores booleanos. La traducción al español de true y false es
verdadero y falso, respectivamente.
Una expresión booleana es una expresión cuya evaluación produce un valor booleano. El
operador == compara dos valores y produce un valor booleano:

>>> 5 == 5
True
>>> 5 == 6
False

En la primera sentencia, los dos operandos son iguales, así que la evaluación de la
expresión produce True; en la segunda sentencia, 5 no es igual a 6, así que
obtenemos False.

El operador == es uno de los operadores de comparación; los otros son:

x != y # x no es igual a y
x > y # x es mayor que y
x < y # x es menor que y
x >= y # x es mayor o igual que y
x <= y # x es menor o igual que y

Aunque probablemente estas operaciones le resulten familiares, los símbolos en Python


son diferentes de los matemáticos. Un error habitual es utilizar un signo igual sencillo
(=) en lugar del doble (==). Recuerde que el símbolo = es un operador de asignación y
que el símbolo == es un operador de comparación. Además, en Python no existe el
símbolo =< ni el símbolo =>.

4.3. Operadores lógicos


Existen tres operadores lógicos: and, or, y not. La semántica (significado) de estos
operadores es similar a sus significados en inglés (en español “y”, “o” y “no”). Por
ejemplo, x > 0 and x < 10 es verdadero sólo si x es mayor que 0 y menor que 10.

n % 2 == 0 or n % 3 == 0 es verdadero si cualquiera de las condiciones es verdadera, o


sea, si el número es divisible por 2 o por 3.

Finalmente, el operador not niega una expresión booleana, de forma que not(x > y) es


verdadero si (x > y) es falso, o sea, si x es menor o igual que y.
4.4. Ejecución condicional
Para escribir programas útiles, casi siempre necesitamos la capacidad de comprobar
ciertas condiciones y cambiar el comportamiento del programa como corresponda.
Las sentencias condicionales nos dan esta capacidad. La forma más sencilla es
la sentencia if:

if x > 0:
print "x es positivo"

La expresión que sigue a la sentencia if se llama condición. Si es verdadera, entonces la


sentencia sangrada se ejecuta. Si no lo es, no pasa nada.

La sintaxis para una sentencia if se ve así:

if EXPRESION BOOLEANA:
SENTENCIAS

Así como la definición de función del capítulo anterior y otras sentencias compuestas, la
sentencia if consiste de un encabezado y un cuerpo. El encabezado empieza con la
palabra reservada if seguida por una expresión booleana y termina con dos puntos (:).

Al conjunto de sentencias sangradas que siguen se le llama bloque. La primera sentencia


no sangrada marca el fin del bloque. Un bloque de sentencias dentro de una sentencia
compuesta recibe el nombre de cuerpo de la sentencia.

Cada una de las sentencias dentro del cuerpo se ejecuta en orden si la expresión
booleana produce el valor True. El bloque completo es ignorado si la expresión booleana
produce el valor False.

No hay límite en el número de sentencias que puede aparecer en el cuerpo de una


sentencia if, pero debe haber al menos una. A veces, es útil tener un cuerpo sin
sentencias (normalmente como reserva de espacio para código que todavía no ha
escrito). En ese caso puede usar la sentencia pass, que no hace nada.

if True: # Esto siempre es verdadero


pass # por lo que esto siempre se ejecuta, pero no hace nada

4.5. Ejecución alternativa


Una segunda forma de la sentencia if es la ejecución alternativa, en la que hay dos
posibilidades, y la condición determina cuál de ellas se ejecuta. La sintaxis se ve así:
if x % 2 == 0:
print x, "es par"
else:
print x, "es impar"

Si el residuo de dividir x entre 2 es 0, entonces sabemos que x es par, y el programa


muestra un mensaje anunciando esto. Si la condición es falsa, la segunda sentencia se
ejecuta. Puesto que la condición debe ser verdadera o falsa, se ejecutará exactamente
una de las alternativas. Estas alternativas se denominan ramas, porque son ramas en el
flujo de ejecución.

Como comentario al margen, si piensa que querrá comprobar con frecuencia la paridad
(pares o nones) de números, quizá desee “envolver” este código en una función:

def muestra_paridad(x):
if x % 2 == 0:
print x, "es par."
else:
print x, "es non."

Para cualquier valor de x, la función muestra_paridad produce un mensaje apropiado.


Cuando se llama a la función, se le puede pasar cualquier expresión entera como
argumento.

>>> muestra_paridad(17)
17 es non.
>>> y = 41
>>> muestra_paridad(y+1)
42 es par.

4.6. Condicionales encadenadas


A veces hay más de dos posibilidades y necesitamos más de dos ramas. Una forma de
expresar tal cómputo es una condicional encadenada:

if x < y:
print x, "es menor que", y
elif x > y:
print x, "es mayor que", y
else:
print x, "y", y, "son iguales"

elif es una abreviatura de “else if”. De nuevo, sólo se ejecutará una rama. No hay límite
al número de sentencias elif, pero sólo se permite una sentencia else (que es opcional)
y debe ser la última rama de la sentencia:
Las condiciones se comprueban en orden. Si la primera es falsa, se comprueba la
siguiente, y así se sigue con las demás. Si una de ellas es cierta, se ejecuta la rama
correspondiente y termina la sentencia. Incluso, si es cierta más de una condición, sólo
se ejecuta la primera rama verdadera.

4.7. Condicionales anidadas


Una condicional puede estar anidada dentro de otra. Podríamos haber escrito el ejemplo
de tricotomía como sigue:

if x == y:
print x, "y", y, "son iguales"
else:
if x > y:
print x, "es menor que", y
else:
print x, "es mayor que", y

La condicional externa contiene dos ramas. La primera rama contiene una sentencia
simple de salida. La segunda rama contiene otra sentencia if, que tiene dos ramas
propias. Estas dos ramas son ambas sentencias de salida, aunque podrían ser
igualmente sentencias condicionales.

Aunque el sangrado de las sentencias hace la estructura evidente, las condicionales


anidadas muy pronto se vuelven difíciles de leer. En general es una buena idea evitarlas
cuando pueda.

Los operadores lógicos proporcionan a menudo formas de simplificar las sentencias


condicionales anidadas. Por ejemplo, podemos reescribir el siguiente código con un sólo
condicional:

if 0 < x:
if x < 10:
print "x es un número positivo de un solo dígito."
La sentencia print sólo se ejecuta si conseguimos superar ambas condicionales, así que
podemos usar el operador and:

if 0 < x and x < 10:


print "x es un número positivo de un solo dígito."

Este tipo de condiciones son comunes, por lo que Python nos proporciona una sintaxis
alternativa similar a la notación matemática:

if 0 < x < 10:


print "x es un número positivo de un solo dígito."

Semánticamente esta condición es la misma que la expresión booleana compuesta y que


la condicional anidada.

4.8. La sentencia return
La sentencia return le permite terminar la ejecución de una función antes de alcanzar su
final. Una razón para usarla es detectar una condición de error:

def muestra_raiz_cuadrada(x):
if x <= 0:
print "Por favor, use sólo números positivos."
return

resultado = x**0.5
print "La raíz cuadrada de x es", resultado

La función muestra_raiz_cuadrada toma un parámetro llamado x. Lo primero que hace


es comprobar si x es menor o igual que cero, en cuyo caso muestra un mensaje de error
y luego usa return para salir de la función. El flujo de la ejecución vuelve
inmediatamente a la sentencia de llamada a función y no se ejecutan las líneas restantes
de la función.

4.9. Entrada por teclado


En Introducción de datos vimos las funciones de biblioteca de Python que reciben
entradas desde el teclado: raw_input e input. Veamos ahora estas funciones con mayor
detalle.

Cuando alguna de estas funciones es llamada, el programa se detiene y espera que el


usuario escriba algo. Cuando el usuario presiona la tecla Retorno o Entrar, el programa
se reanuda y raw_input devuelve como tipo cadena (str) lo que el usuario escribió:
Antes de llamar a raw_input es conveniente mostrar un mensaje que le pida al usuario el
dato solicitado. Este mensaje se llama indicador. Podemos proporcionarle un indicador
a raw_input como argumento:

>>> nombre = raw_input("¿Cómo te llamas? ")


¿Cómo te llamas? Arturo, ¡Rey de los británicos!
>>> print nombre
Arturo, ¡Rey de los británicos!

Note que el indicador es una cadena, por lo que debe ir encerrada entre paréntesis.

Si esperamos que la respuesta sea un entero, podemos usar la función input que evalúa


la respuesta como una expresión de Python:

indicador = "¿Cuál es la velocidad de una golondrina sin carga?\n"


velocidad = input(indicador)

Si el usuario escribe una cadena de números, se convertirá en un entero y se asignará


a velocidad. Por desgracia, si el usuario escribe caracteres que no sean una expresión
válida de Python, el programa dará un error:

>>> velocidad = input(indicador)


¿Cuál es la velocidad de una golondrina sin carga?
¿Se refiere a la golondrina europea o a la africana?
...
SyntaxError: invalid syntax

Si en este último ejemplo el usuario hubiese escrito una expresión válida de Python
colocando comillas en su respuesta, no habría obtenido un error:

Para evitar este tipo de error, es buena idea usar raw_input para obtener una cadena y
usar entonces las funciones de conversión para transformarla en otros tipos.
4.10. Conversión de tipos
Cada tipo en Python viene con un comando de biblioteca que convierte los valores de un
tipo en el tipo asociado al comando. El comando int(ARGUMENTO), por ejemplo, toma
cualquier valor y lo convierte, si es posible, en un entero, si no, dará un mensaje de
error:

>>> int("32")
32
>>> int("Hola")
ValueError: invalid literal for int() with base 10: 'Hola'

El comando int también puede convertir valores de punto flotante en enteros, pero


recuerde que este comando trunca las fracciones:

>>> int(-2.3)
-2
>>> int(3.99999)
3
>>> int("42")
42
>>> int(1.0)
1

El comando float(ARGUMENTO) convierte enteros y cadenas en números de punto


flotante:

>>> float(32)
32.0
>>> float("3.14159")
3.14159
>>> float(1)
1.0

Pareciera extraño que Python distinga el valor entero 1 del valor en punto flotante 1.0;
son el mismo número, pero pertenecen a tipos distintos. La razón es que se representan
en la computadora de manera diferente.
El comando str(ARGUMENTO) convierte cualquier argumento dado, en tipo cadena (str):

El comando str(ARGUMENTO) trabaja con cualquier valor y lo convierte en una cadena.


Como se mencionó antes, True es un valor booleano; true no lo es.

La situación es especialmente interesante para valores booleanos:

Python asigna valores booleanos a los valores de otros tipos. Para tipos numéricos como
enteros y de punto flotante, los valores cero son valores falsos y los valores diferentes
de cero son valores verdaderos. Para cadenas, las cadenas vacías son falsas y las no
vacías son verdaderas.

4.11. GASP
GASP (Graphics API for Students of Python - Gráficas API para Estudiantes de Python)
nos permitirá escribir programas que involucren gráficas. Antes de se puede utilizar el
GASP, se necesita instalarlo en su máquina. Si está ejecutando Ubuntu GNU/Linux,
véase GASP en Apéndice A.

Para iniciar gasp intente lo siguiente:


Antes del último comando, que cierra la ventana de gráficos, debería verla luciendo así:

A partir de ahora estaremos usando gasp para ilustrar (en el más amplio sentido de la
palabra) los conceptos de programación de computadoras, y para divertirnos mientras
aprendemos.

4.12. Glosario
operador módulo

Operador que, denotado por el signo de tanto por ciento (%), trabaja sobre
enteros y devuelve el residuo cuando un número es dividido por otro.

valor booleano
Existen exactamente dos valores booleanos: True y False. Los valores booleanos
se obtienen cuando una expresión booleana es evaluada por el intérprete de
Python. Estos valores son del tipo bool.

expresión booleana
Una expresión que es falsa o verdadera.
operador de comparación
Uno de los operadores que comparan dos valores: ==, !=, >, <, >=, y <=.

operador lógico
Uno de los operadores que combinan expresiones booleanas: and, or, y not.

sentencia condicional
Sentencia que controla el flujo de ejecución dependiendo de cierta condición. En
Python las palabras reservadas if, elif, y else son usadas por las sentencias
condicionales.

condición
En una sentencia condicional es una expresión booleana que determina cuál rama
se ejecutará.

bloque
Grupo de sentencias consecutivas con el mismo sangrado.

cuerpo
En una sentencia compuesta es el bloque que está después del encabezado.

rama
Uno de los posibles caminos del flujo de ejecución determinado por la ejecución
condicional.

condicional encadenada
Rama condicional con más de dos posibles flujos de ejecución. En Python las
condicionales encadenadas se escriben con las sentencias if ... elif ... else.

anidamiento
Estructura de un programa dentro de otra, tal como una sentencia condicional
dentro de una rama de otra sentencia condicional.

indicador
Indicación visual que invita al usuario a introducir datos.

conversión de tipos
Sentencia explícita que toma un valor de un tipo y calcula el valor
correspondiente a otro tipo.
4.13. Ejercicios

1. Intente evaluar
mentalmente las siguientes expresiones numéricas, luego use el intérprete de
Python para verificar sus respuestas:
1. >>> 5 % 2
2. >>> 9 % 5
3. >>> 15 % 12
4. >>> 12 % 15
5. >>> 6 % 6
6. >>> 0 % 7
7. >>> 7 % 0

¿Qué pasó con el último ejemplo? ¿Por qué? Si pudo anticipar correctamente todas las
respuestas de la computadora — excepto la última, es el momento de continuar con los
demás ejercicios, si no, tómese un tiempo para realizar ejemplos similares por su
cuenta. Explore el operador módulo hasta que tenga plena confianza que ha entendido
cómo funciona.

if x < y:
print x, "es menor que", y
elif x > y:
print x, "es mayor que", y
else:
print x, "y", y, "son iguales"

2. Envuelva este
código en una función llamada comparar(x, y). Llame a la función comparar tres
veces: una en la que el primer argumento sea menor que el segundo, otra en la que
aquel sea mayor que éste, y una tercera en la que los argumentos sean iguales.

3. Para entender
mejor las expresiones booleanas es útil la construcción de tablas de verdad. Dos
expresiones booleanas son lógicamente equivalentes si y solo si tienen la misma
tabla de verdad.

El siguiente guión de Python muestra la tabla de verdad para cualquier expresión


booleana de dos variables, p y q:
expresion = raw_input("Introduzca una expresión booleana de dos variables, p y
q: ")

print " p q %s" % expresion


longitud = len( " p q %s" % expresion)
print longitud*"="

for p in True, False:


for q in True, False:
print "%-7s %-7s %-7s" % (p, q, eval(expresion))

En capítulos posteriores usted aprenderá cómo trabaja este guión. Por ahora lo usará
para aprender sobre expresiones booleanas. Copie este programa en un archivo
llamado p_y_q.py, luego ejecútelo desde la línea de comandos, y cuando el indicador
solicite una expresión booleana escriba: p or q. Debería obtener la siguiente salida:

p q p or q
=====================
True True True
True False True
False True True
False False False

Ahora que sabemos cómo trabaja el guión, pongámoslo en una función para facilitar su
uso:

def tabla_de_verdad(expresion):
print " p q %s" % expresion
longitud = len( " p q %s" % expresion)
print longitud*"="

for p in True, False:


for q in True, False:
print "%-7s %-7s %-7s" % (p, q, eval(expresion))

Luego podemos importar el archivo en una terminal de Python y llamar la


función tabla_de_verdad con una cadena que contenga nuestra expresión booleana con
p y q como argumento:
Use la función tabla_de_verdad con las siguientes expresiones booleanas, guardando la
tabla de verdad producida cada vez:

1. not(p or q)
2. p and q
3. not(p and q)
4. not(p) or not(q)
5. not(p) and not(q)

¿Cuáles de estas expresiones son lógicamente equivalentes?

4. Introduzca las
siguientes expresiones en la terminal de Python:

Analice los resultados. ¿Qué observaciones tiene sobre los diferentes tipos de valores y
los operadores lógicos? ¿Puede escribir sus observaciones en forma de reglas simples
sobre las expresiones que usan and y or?

5. Envuelva este
código en una función llamada aviso(eleccion). Luego defina las
funciones funcion_a, funcion_b, y funcion_c de forma tal que muestren un aviso de
que fueron llamadas. Por ejemplo:

def funcion_a():
print "la funcion_a fue llamada..."

Coloque las cuatro funciones (aviso, funcion_a, funcion_b, y funcion_c) en un guión


llamado cap4ejer5.py. Al final de este guión agregue una llamada a aviso('b'). Su
salida debería ser:

la funcion_b fue llamada...

Finalmente, modifique el guión para que el usuario pueda introducir ‘a’, ‘b’, o ‘c’.
Pruébelo importando su guión en la terminal de Python.

6. Escriba una
función llamada es_divisible_entre_3 que tome un valor entero como un
argumento y muestre “Este número es divisible entre tres.” si el argumento es
exactamente divisible entre 3, y que muestre “Este número no es divisible entre
tres.” en caso contrario.

Ahora escriba una función similar llamada es_divisible_entre_5.

7. Generalice las
funciones que escribió en el ejercicio anterior en una función
llamada es_divisible_entre_n(x, n) que tome dos enteros como argumentos y
muestre cuándo el primero es divisible por el segundo y cuándo no. Guarde esta
función en un archivo llamado cap04e07.py. Importe el archivo en una terminal y
úselo. Una muestra de su sesión sería:

>>> from cap04e07 import *


>>> es_divisible_entre_n(20, 4)
Sí, 20 es divisible entre 4
>>> es_divisible_entre_n(21, 8)
No, 21 no es divisible entre 8

¿Cuál será la salida de lo siguiente?

if "¡No!":
print 'Somos los caballeros que dicen "¡No!"'
else:
print "¡Basta! ¡No más!"

if 0:
print "Y ahora algo completamente diferente..."
else:
print "Entonces, ¿qué es todo esto?"

Explique qué sucede y por qué sucede.

8. El siguiente
guión de gasp — escrito en un archivo llamado casa.py — dibuja una casa simple en
una ventana de gasp:

from gasp import * # importa todas las funciones del módulo gasp

begin_graphics() # abre la ventana de gráficos

Box((20, 20), 100, 100) # la casa


Box((55, 20), 30, 50) # la puerta
Box((40, 80), 20, 20) # la ventana izquierda
Box((80, 80), 20, 20) # la ventana derecha
Line((20, 120), (70, 160)) # la azotea izquierda
Line((70, 160), (120, 120)) # la azotea derecha

update_when('key_pressed') # mantiene la ventana abierta hasta que


end_graphics() # presione una tecla cierra la ventana (lo
# que pasará de cualquier manera puesto que
# el guión termina aquí, pero es mejor ser
# explícito).

Ejecute este guión y confirme que obtiene una ventana que se ve como esta:
1. Envuelva el código de la casa en una función que se llame dibuja_casa().
2. Ahora ejecute el guión. ¿Ve la casa? ¿Por qué no?
3. Agregue una llamada a dibuja_casa() al final del guión, tal que la casa
vuelva a la pantalla.
4. Parametrice la función con los parámetros x y y — el encabezado debería
ser def dibuja_casa(x, y):, de forma tal que pueda pasar la localización de la casa
a la ventana de gasp.
5. Use dibuja_casa para ubicar cinco casas en la ventana de gasp en
diferentes localizaciones.

Potrebbero piacerti anche