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
finally for from global if import
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 las 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 dá 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: division 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 postivos 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 un 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).