2. Una calculadora avanzada
2.1.1. Los operadores aritm´ eticos
Las operaciones de suma y resta, por ejemplo, se denotan con los s´ımbolos u operadores + y -, respectivamente, y operan sobre dos valores num´ericos (los operandos). Probemos algunas expresiones formadas con estos dos operadores:
>>> 1 + 2 3
6
>>> 1 - 2 + 3 2
Observa que puedes introducir varias operaciones en una misma l´ınea o expresi´on. El or- den en que se efect´uan las operaciones es (en principio) de izquierda a derecha. La expresi´on 1 - 2 + 3, por ejemplo, equivale matem´aticamente a ((1 − 2) + 3); por ello decimos que la suma y la resta son operadores asociativos por la izquierda.
Podemos representar gr´aficamente el orden de aplicaci´on de las operaciones utilizando ´
arboles sint´acticos. Un ´arbol sint´actico es una representaci´on gr´afica en la que disponemos los operadores y los operandos como nodos y en los que cada operador est´a conectado a sus operandos. El ´arbol sint´actico de la expresi´on((1 - 2 + 3)) es ´este:
+
-
1 2
3
El nodo superior de un ´arbol recibe el nombre de nodo ra´ız . Los nodos etiquetados con operadores (representados con c´ırculos) se denominan nodos interiores. Los nodos interiores tienen uno o m´as nodos hijo o descendientes (de los que ellos son sus respectivos nodos padre o ascendientes). Dichos nodos son nodos ra´ız de otros (sub)´arboles sint´acticos (¡la definici´on de ´arbol sint´actico es auto-referencial!). Los valores resultantes de evaluar las expresiones aso- ciadas a dichos (sub)´arboles constituyen los operandos de la operaci´on que representa el nodo interior. Los nodos sin descendientes se denominan nodos terminales u hojas (representados con cuadrados) y corresponden a valores num´ericos.
La evaluaci´on de cada operaci´on individual en el ´arbol sint´actico((fluye)) de las hojas hacia la ra´ız (el nodo superior); es decir, en primer lugar se eval´ua la subexpresi´on ((1 - 2)), que corresponde al sub´arbol m´as profundo. El resultado de la evaluaci´on es −1:
+
-
1 2
3 −1
A continuaci´on se eval´ua la subexpresi´on que suma el resultado de evaluar ((1 - 2)) al valor 3: + - 1 2 3 −1 2
As´ı se obtiene el resultado final: el valor 2.
Si deseamos calcular (1 − (2 + 3)) podemos hacerlo a˜nadiendo par´entesis a la expresi´on aritm´etica:
>>> 1 - (2 + 3) -4
El ´arbol sint´actico de esta nueva expresi´on es -
1 +
2.1 Sesiones interactivas 2006/09/25-15:31
En este nuevo ´arbol, la primera subexpresi´on evaluada es la que corresponde al sub´arbol derecho. Observa que en el ´arbol sint´actico no aparecen los par´entesis de la expresi´on. El ´arbol sint´actico ya indica el orden en que se procesan las diferentes operaciones y no necesita par´entesis. La expresi´on Python, sin embargo, necesita los par´entesis para indicar ese mismo orden de eva- luaci´on.
. . . ejercicios . . . . · 12 ¿Qu´e expresiones Python permiten, utilizando el menor n´umero posible de par´entesis, efectuar en el mismo orden los c´alculos representados con estos ´arboles sint´acticos?
+ - + 1 2 3 4 + - 1 2 + 3 4 + 1 - 2 + 3 4 a) b) c)
· 13 Dibuja los ´arboles sint´acticos correspondientes a las siguientes expresiones aritm´eticas:
a) 1 + 2 + 3 + 4 b) 1 - 2 - 3 - 4 c) 1 - (2 - (3 - 4) + 1)
. . . .
Espacios en blanco
Parece que se puede hacer un uso bastante liberal de los espacios en blanco en una expresi´on. >>> 10 + 20 + 30 60 >>> 10+20+30 60 >>> 10 +20 + 30 60 >>> 10+ 20+30 60
Es as´ı. Has de respetar, no obstante, unas reglas sencillas:
No puedes poner espacios en medio de un n´umero.
>>> 10 + 2 0 + 30
Los espacios en blanco entre el 2 y el 0 hacen que Python no lea el n´umero 20, sino el n´umero 2 seguido del n´umero 0 (lo cual es un error, pues no hay operaci´on alguna entre ambos n´umeros).
No puedes poner espacios al principio de la expresi´on. >>> 10 + 20 + 30
Los espacios en blanco entre el prompt y el 10 provocan un error. A´un es pronto para que conozcas la raz´on.
Los operadores de suma y resta son binarios, es decir, operan sobre dos operandos. El mismo s´ımbolo que se usa para la resta se usa tambi´en para un operador unario, es decir, un operador que act´ua sobre un ´unico operando: el de cambio de signo, que devuelve el valor de su operando cambiado de signo. He aqu´ı algunos ejemplos:
>>> -3 -3
>>> -(1 + 2) -3
>>> --3 3
He aqu´ı los ´arboles sint´acticos correspondientes a las tres expresiones del ejemplo:
- 3 - + 1 2 - - 3
Existe otro operador unario que se representa con el s´ımbolo +: el operador identidad . El operador identidad no hace nada((´util)): proporciona como resultado el mismo n´umero que se le pasa.
>>> +3 3 >>> +-3 -3
El operador identidad s´olo sirve para, en ocasiones, poner ´enfasis en que un n´umero es positivo. (El ordenador considera tan positivo el n´umero 3 como el resultado de evaluar +3.)
Los operadores de multiplicaci´on y divisi´on son, respectivamente, * y /:
>>> 2 * 3 6 >>> 4 / 2 2 >>> 3 * 4 / 2 6 >>> 12 / 3 * 2 8
Observa que estos operadores tambi´en son asociativos por la izquierda: la expresi´on((3 * 4 / 2)) equivale a ((3 · 4)/2) = 3·42 , es decir, tiene el siguiente ´arbol sint´actico:
/
*
3 4
2
y la expresi´on 12 / 3 * 2 equivale a ((12/3) · 2) = 123 · 2, o sea, su ´arbol sint´actico es: *
/
12 3
2
¿Qu´e pasa si combinamos en una misma expresi´on operadores de suma o resta con operadores de multiplicaci´on o divisi´on? F´ıjate en que la regla de aplicaci´on de operadores de izquierda a derecha no siempre se observa:
>>> 2 * 4 + 5 13
>>> 2 + 4 * 5 22
2.1 Sesiones interactivas 2006/09/25-15:31
En la segunda expresi´on, primero se ha efectuado el producto 4 * 5 y el resultado se ha sumado al valor 2. Ocurre que los operadores de multiplicaci´on y divisi´on son prioritarios frente a los de suma y resta. Decimos que la multiplicaci´on y la divisi´on tienen mayor nivel de precedencia o prioridad que la suma y la resta.
El ´arbol sint´actico de 2 * 4 + 5 es:
+ * 2 4 5 y el de 2 + 4 * 5 es: + 2 * 4 5
Pero, ¡atenci´on!, el cambio de signo tiene mayor prioridad que la multiplicaci´on y la divisi´on:
>>> -2 * 2 -4
>>> --2 * 2 4
Los ´arboles sint´acticos correspondientes a estas dos expresiones son, respectivamente: * - 2 2 * - - 2 2
Si los operadores siguen unas reglas de precedencia que determinan su orden de aplicaci´on, ¿qu´e hacer cuando deseamos un orden de aplicaci´on distinto? Usar par´entesis, como hacemos con la notaci´on matem´atica convencional.
La expresi´on 2 * (4 + 5), por ejemplo, presenta este ´arbol sint´actico: *
2 +
4 5
Comprob´emoslo con el int´erprete:
>>> 2 * (4 + 5) 18
Existen m´as operadores en Python. Tenemos, por ejemplo, el operador m´odulo, que se denota con el s´ımbolo de porcentaje % (aunque nada tiene que ver con el c´alculo de porcentajes). El operador m´odulo devuelve el resto de la divisi´on entera entre dos operandos.
>>> 27 % 5 2
>>> 25 % 5 0
El operador % tambi´en es asociativo por la izquierda y su prioridad es la misma que la de la multiplicaci´on o la divisi´on.
El ´ultimo operador que vamos a estudiar es la exponenciaci´on, que se denota con dos aste- riscos juntos, no separados por ning´un espacio en blanco: **.
Lo que en notaci´on matem´atica convencional expresamos como 23se expresa en Python con
2 ** 3.
>>> 2 ** 3 8
Pero, ¡ojo!, la exponenciaci´on es asociativa por la derecha. La expresi´on 2 ** 3 ** 2 equi- vale a 2(32)
= 29= 512, y no a (23)2= 82= 64, o sea, su ´arbol sint´actico es:
**
2 **
3 2
Por otra parte, la exponenciaci´on tiene mayor precedencia que cualquiera de los otros ope- radores presentados.
He aqu´ı varias expresiones evaluadas con Python y sus correspondientes ´arboles sint´acticos. Est´udialos con atenci´on:
>>> 2 + 3 ** 2 * 5 47 + 2 * ** 3 2 5 >>> 2 + ((3 ** 2) * 5) 47 + 2 * ** 3 2 5 >>> 2 + 3 ** (2 * 5) 59051 + 2 ** 3 * 2 5
2.1 Sesiones interactivas 2006/09/25-15:31 >>> -1 -1 - 1 >>> -3 ** 2 -9 - ** 3 2
La tabla 2.1 resume las caracter´ısticas de los operadores Python: su aridad (n´umero de operandos), asociatividad y precedencia.
Operaci´on Operador Aridad Asociatividad Precedencia
Exponenciaci´on ** Binario Por la derecha 1
. . . .
Identidad + Unario — 2
Cambio de signo - Unario — 2
. . . .
Multiplicaci´on * Binario Por la izquierda 3
Divisi´on / Binario Por la izquierda 3
M´odulo (o resto) % Binario Por la izquierda 3
. . . .
Suma + Binario Por la izquierda 4
Resta - Binario Por la izquierda 4
Tabla 2.1: Operadores para expresiones aritm´eticas. El nivel de precedencia 1 es el de mayor
prioridad y el 4 el de menor.
. . . ejercicios . . . . · 14 ¿Qu´e resultados se obtendr´an al evaluar las siguientes expresiones Python? Dibuja el ´
arbol sint´actico de cada una de ellas, calcula a mano el valor resultante de cada expresi´on y comprueba, con la ayuda del ordenador, si tu resultado es correcto.
a) 2 + 3 + 1 + 2 b) 2 + 3 * 1 + 2 c) (2 + 3) * 1 + 2 d) (2 + 3) * (1 + 2) e) +---6 f) -+-+6
· 15 Traduce las siguientes expresiones matem´aticas a Python y eval´ualas. Trata de utilizar el menor n´umero de par´entesis posible.
a) 2 + (3 · (6/2)) b) 4 + 6 2 + 3 c) (4/2)5 d) (4/2)5+1 e) (−3)2 f) −(32)
(Nota: El resultado de evaluar cada expresi´on es: a) 11; b) 2; c) 32; d) 64; e) 9; f) −9.) . . . .