Cesar Systems

Herramientas Informaticas

3.12. Funciones con resultado

Seguramente ha notado ya que algunas de las funciones que estamos usando, igual que las funciones matemáticas, devuelven un resultado.

Otras funciones, como nueva línea, llevan a cabo una acción pero no devuelven un valor. Ello suscita varias preguntas:

1. ¿Que sucede si llama usted a una función y no hace nada con el resultado (es decir, no lo asigna a una variable ni lo usa como parte de una expresión mas amplia)?

2. ¿Que sucede si usa una función sin resultado como parte de una expresión, por ejemplo nueva línea() + 7?

3. ¿Se pueden escribir funciones que devuelvan resultados, o debemos limitarnos a funciones simples como nueva línea e imprimeDoble?

La respuesta a la tercera pregunta es “sí, puede escribir funciones que devuelvan valores”, y lo haremos en el capítulo 5.

Como actividad final, constaste a las otras dos preguntas intentando hacerlas en la practica. Cada vez que tenga una duda sobre lo que es legal o ilegal en Python, preguntar al interprete será una buena manera de averiguarlo.

3.13. Glosario

llamada a función: Una sentencia que ejecuta una función. Esta compuesta por el nombre de la función mas una lista de argumentos encerrados entre paréntesis.

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.

valor de retorno: Es el resultado de una función. Si se usa una llamada a función a modo de expresión, el valor de retorno es el valor de la expresión.

conversión de tipo: Una sentencia explícita que toma un valor de un tipo y calcula el valor correspondiente de otro tipo.

coerción: Conversión tipos que ocurre automáticamente de acuerdo con las reglas de coerción de Python.

módulo: Fichero que contiene una colección de funciones y clases relacionadas.

notación de punto: La sintaxis para llamar a una función de otro modulo, especificando el nombre del modulo, seguido por un punto y el nombre de la función.

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.

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 a el valor que se le pasa como argumento.

variable local: variable definida dentro de una función. Las variables locales solo pueden usarse dentro de su función.

diagrama de pila: Representación grafica de una pila de funciones, sus variables y los valores a los que se refieren.

traza inversa: (traceback en ingles) Una lista de las funciones en curso de ejecución, presentadas cuando sucede un error en tiempo de ejecución. notación de punto traza inversa

Capítulo 4

Condicionales y

recursividad

 

4.1. El operador modulo

El operador modulo funciona con enteros (y expresiones enteras), y devuelve el resto de dividir el primer operando entre el segundo. En Python, el operador de modulo es el signo de tanto por ciento ( %). La sintaxis es la misma de los otros operadores:

   1: >>> cociente = 7 / 3

   2: >>> print 

   3: cociente

   4: 2

   5: >>> resto = 7 % 3

   6: >>> print resto

   7: 1

Así, 7 dividido entre 3 da 2 con 1 de resto.

El operador de modulo resulta ser soprendentemente util. Por ejemplo, puede comprobar si un numero es divisible entre otro: si x % y es cero, entonces x es divisible entre y.

También puede usar el operador modulo para extraer el dígito mas a la derecha de un numero. Por ejemplo, x % 10 devuelve el dígito mas a la derecha de x (en base 10). De forma similar, x % 100 devuelve los dos últimos dígitos.

4.2. Expresiones booleanas

Una expresión booleana es una expresión que es cierta o falsa. En Python, una expresión que es cierta tiene el valor 1, y una expresión que es falsa tiene el valor 0.

El operador == compara dos valores y entrega una expresión booleana:

   1: >>> 5 == 5

   2: 1

   3: >>> 5 == 6

   4: 0

En la primera sentencia, los dos operandos son iguales, así que la expresion se evalúa como 1 (verdadero); en la segunda sentencia, 5 no es igual a 6, así que obtenemos 0 (falso).

El operador == es uno de los operadores de comparacion; los otros son:

   1: x != y # x no es igual a y

   2: x > y # x es mayor que y

   3: x < y # x es 

   4: menor que y

   5: x >= y # x es mayor o igual que y

   6: x <= y # x es menor o 

   7: igual que y

Aunque probablemente estas operaciones le resulten familiares, los símbolos en Python son diferentes de los matematicos. Un error habitual es utilizar un signo igual sencillo (=) en lugar del doble (==). Recuerde que = es un operador de asignación y == es un operador de comparacion. Ademas, no existen =.

4.3. Operadores lógico

Hay tres operadores lógicos: and, or, y not. La semántica (significado) de estos operadores es similar a sus significados en ingles. Por ejemplo, x >0 and x <10 es verdadero solo 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 numero es divisible por 2 o por 3.

Finalmente, el operador not niega una expresión booleana, de forma que not(x>y) es cierto si (x >y) es falso, o sea, si x es menor o igual que y.

Hablando estrictamente, los operandos de los operadores lógicos deberían ser expresiones booleanas, pero Python no es muy estricto. Cualquier numero que no sea cero se interpreta como “verdadero“.

   1: >>> x = 5

   2: >>> x and 1

   3: 1

   4: >>> y = 

   5: 0

   6: >>> y and 1

   7: 0

En general, este tipo de cosas no se considera buen estilo. Si quiere comparar un valor con cero, debería hacerlo explícitamente.

4.4. Ejecución condicional

Para escribir programas útiles, casi siempre necesitamos la capacidad de comprobar ciertas condiciones y cambiar el comportamiento del programa en consonancia. Las sentencias condicionales nos dan esta capacidad. La forma mas sencilla es la sentencia if:

   1: if x > 0:

   2:     print "x es positivo"

La expresion booleana tras el if se llama condicion. Si es verdadera, entonces la sentencia indentada se ejecuta. Si la condicion no es verdadera, no pasa nada.

Como otras sentencias compuestas, if consta de una cabecera y un bloque de sentencias:

   1: CABECERA:

   2: PRIMERA SENTENCIA

   3: ...

   4: ULITMA SENTENCIA

 

La cabecera comienza con una nueva línea y termina con el signo de dos puntos.

Los elementos indentados que siguen se llaman bloque de la sentencia. La primera sentencia no indentada marca el fin del bloque. Un bloque de sentencias dentro de una sentencia compuesta recibe el nombre de cuerpo de la sentencia.

 

No hay límite a la cantidad de sentencias que pueden aparecer en el cuerpo de una sentencia if, pero debe haber al menos una. A veces, es util tener un cuerpo sin sentencias, (normalmente como reserva de espacio para algo de código que todavía no ha escrito). En tales casos, puede usted utilizar la sentencia pass, que no hace nada.

4.6. Condiciones encadenadas

A veces hay mas de dos posibilidades y necesitamos mas de dos ramas. Una forma de expresar tal computación es un condicional encadenado:

   1: if x < y:

   2: print x, "es menor que", y

   3: elif x > y:

   4: print x, "es 

   5: mayor que", y

   6: else:

   7: print x, "y", y, "son iguales"

elif es una abreviatura de “else if“. De nuevo, solo se ejecutara una rama. No hay límite al numero de sentencias elif, pero solo se permite una sentencia

   1: else (que puede omitirse) y debe ser la ultima rama de la sentencia:

   2:     if 

   3:         eleccion == 'A':

   4:         funcionA()

   5:     elif eleccion == 'B':

   6:         funcionB()

   7:     elif 

   8:         eleccion == 'C':

   9:         funcionC()

  10:     else:

  11:         print "Eleccion no valida."

  12:     

Las condiciones se comprueban en orden. Si la primera es falsa, se comprueba la siguiente, y así. Si una de ellas es cierta, se ejecuta la rama correspondiente y termina la sentencia. Incluso si es cierta mas de una condicion, solo se ejecuta la primera rama verdadera.

Como ejercicio, envuelva estos ejemplos en funciones llamadas compara(x, y) y resuelve(eleccion).

4.7. Condiciones anidadas

Una condición puede estar anidada dentro de otra. Podíamos haber escrito así el ejemplo de tricotomía:

   1: if x == y:

   2:     print x, "y", y, "son iguales"

   3: else:

   4:     if x < y:

   5:         print 

   6:         x, "es menor que", y

   7:     else:

   8:         print x, "es mayor que", y

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

Aunque la indentacion de las sentencias hace la estructura evidente, las condiciones anidadas en seguida se vuelven difíciles de leer. En general es una buena idea evitarlas cuando pueda.

Los operadores logicos suelen facilitar un modo de simplificar las sentencias condicionales anidadas. Por ejemplo, podemos reescribir el codigo siguiente con un solo condicional:

   1: if 0 < x:

   2:     if x < 10:

   3:         print "x es un numero positivo de un dígito."

La sentencia print solo se ejecuta si conseguimos superar ambos condicionales, así que podemos usar el operador and:

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:

   1: import math

   2:     def imprimeLogaritmo(x):

   3:         if x <= 0:

   4:             print "Solo numeros positivos, por favor."

   5:             return 

   6:         result = math.log(x)

   7:         print "El log de x es", result

La funcion imprimeLogaritmo toma un parametro 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 funcion. El flujo de la ejecución vuelve inmediatamente al llamante y no se ejecutan las líneas restantes de la funcion.

Recuerde que para usar una funcion del modulo math tiene que importarlo.

4.9. Recursividad

Ya mencionamos que es legal que una función llame a otra, y de ello hemos visto ya varios ejemplos. Olvidamos mencionar que también es legal que una función se llame a sí misma. Puede no resultar evidente por que es bueno esto, pero viene a resultar una de las cosas mas interesantes y curiosas que puede hacer un programa. Examine por ejemplo la siguiente función:

   1: def cuenta_atras(n):

   2:     if n == 0:

   3:         print "Despegando!"

   4:     else:

   5:         print  n cuenta_atras(n-1)

   6:     

cuenta atras espera que su parametro, n, sea un entero positivo. Si n el parámetro es cero, muestra la palabra “¡Despegando!”. En otro caso, muestra n y luego llama a la funcion llamada cuenta atras (ella misma) pasandole como argumento n-1.

¿Que sucede si llamamos a la funcion de la siguiente manera?

   1: >>> cuenta_atras(3)

La ejecucion de cuenta atras comienza con n=3, y puesto que n no es cero, da como salida el valor 3, y luego se llama a sí misma …

La ejecucion de cuenta atras comienza con n=2, y puesto que n no es cero, muestra el valor 2 y luego se llama a sí misma …

La ejecucion de cuenta atras comienza con n=1, y puesto que n no es cero, muestra el valor 1, y luego se llama a
sí misma…

La ejecucion de cuenta atras comienza con n=0, y puesto que n es cero, muestra la palabra Despegando!” y luego retorna.

La cuenta atras que dio n=1 retorna.

La cuenta atras que dio n=2 retorna.

La cuenta atras que dio n=3 retorna.

Y entonces ya esta de vuelta en main (menudo viaje). De manera que la salida completa presenta el siguiente aspecto:

3

2

1

¡Despegando!

Como segundo ejemplo, consideremos de nuevo las funciones nuevaLinea and tresLineas.

   1: def nuevaLinea():

   2:     print    

   3: def 

   4:     tresLineas():

   5:     nuevaLinea()

   6:     nuevaLinea()

   7:     nuevaLinea()

Aunque todas funcionan, no serían de mucha ayuda si quisiera mostrar 2 líneas nuevas o 106. Una mejor alternativa será:

   1: def nLineas(n):

   2: if n > 0:

   3: print

   4: nLineas(n-1)

Este programa es parecido a cuenta atras; mientras n sea mayor que cero, muestra una nueva l³nea, y luego se llama a sí misma para mostrar >n-1 nuevas líneas mas. De esta manera, el numero total de nuevas l³neas es 1 + (n-1), que si rescata su algebra vera que es n.

El proceso por el que una funcion se llama a s³ misma se llama recursividad, y dichas funciones se denominan recursivas.

Página 110 de 143

Creado con WordPress & Tema de Anders Norén