T2 Programación Python

92
 Parte II Introducción a la programación

Transcript of T2 Programación Python

Parte II

Introduccin a la programacin

CAPTULO

2

Introduccin a la programacin

2.1.2.1.1.

Abstraccin de problemas para su programacin. Conceptos fundamentalesQu es un programa?

La habilidad ms importante del ingeniero es la capacidad para solucionar problemas. La solucin de problemas incluye poder formalizar problemas, pensar en la solucin de manera creativa, y expresar esta solucin en trminos que un ordenador pueda entender. La solucin de problemas mediante el uso del ordenador se consigue a travs de los programas. Denicin Un programa es un texto con una secuencia de instrucciones que un ordenador puede interpretar y ejecutar. Los programas son, por tanto, el medio de comunicacin con el ordenador. Mediante su utilizacin conseguimos que las mquinas aprovechen sus capacidades para resolver los problemas que nos interesan. Sin los programas los ordenadores no son capaces de hacer nada.

2.1.2.

Lenguajes de programacin

Los programas se escriben en lenguajes especializados llamados lenguajes de programacin. Hay muchos lenguajes de programacin, pero para programar no es necesario conocerlos todos. En esencia, la tcnica bsica necesaria para programar es comn a todos los lenguajes. Denicin Un lenguaje de programacin es un idioma formado por un conjunto de smbolos y reglas sintcticas y semnticas que denen la estructura y el signicado de las instrucciones de que consta el lenguaje. Cuando escribimos un programa utilizando un determinado lenguaje de programacin llamamos cdigo fuente, o simplemente cdigo, al texto del programa. Cuando un ordenador lleva a cabo una tarea indicada por un programa, decimos que ejecuta el cdigo. Aunque no vamos a entrar en los detalles de cada uno, es necesario mencionar que a la hora de programar se pueden seguir diversas tcnicas o paradigmas de programacin: programacin

38

Introduccin a la programacin

imperativa, declarativa, estructurada, modular, orientada a objetos, etc. Los lenguajes de programacin suelen soportar varios de estos paradigmas de programacin. Independientemente del lenguaje que se utilice, es importante que el alumno se acostumbre a seguir los principios de la programacin modular, que consiste en dividir un programa en mdulos o subprogramas con el n de hacerlo ms legible y manejable. En general, un problema complejo debe ser dividido en varios subproblemas ms simples, y estos a su vez en otros subproblemas ms simples. Esto debe hacerse hasta obtener subproblemas lo sucientemente simples como para poder ser resueltos fcilmente con algn lenguaje de programacin. En la actualidad los lenguajes de programacin, llamados de alto nivel, estn pensados para que los programas sean comprensibles por el ser humano. Sin embargo, el cdigo fuente de los mismos no es comprendido por el ordenador, ya que ste slo maneja el lenguaje binario o lenguaje mquina. Es necesario hacer una traduccin de los programas escritos en un lenguaje de programacin de alto nivel a lenguaje mquina. Hay dos tipos diferentes de lenguajes dependiendo de la forma de hacer esta traduccin: Lenguajes compilados El Compilador realiza una traduccin completa del programa en lenguaje de alto nivel a un programa equivalente en lenguaje mquina. Este programa resultante, programa ejecutable, se puede ejecutar todas las veces que se quiera sin necesidad de volver a traducir el programa original.

Lenguajes interpretados En este caso, el Intrprete va leyendo el programa en lenguaje de alto nivel instruccin a instruccin, cada una de ellas se traduce y se ejecuta. No se genera un programa directamente ejecutable.

El enfoque compilado genera cdigo ejecutable que utiliza directamente las instrucciones nativas de la CPU. Esto suele implicar que el programa se ejecutar mucho ms velozmente que si se hiciera en un lenguaje interpretado. A cambio, presenta el inconveniente de que el ejecutable resultante de la compilacin slo sirve para ser ejecutado en una CPU concreta y un Sistema Operativo concreto (aquellos para los que se compil), o bien versiones compatibles de la CPU y el operativo, mientras que si se hiciera en un lenguaje interpretado podra ser ejecutado en cualquier arquitectura y operativo para los que exista el intrprete.

2.1 Abstraccin de problemas para su programacin. Conceptos fundamentales

39

2.1.3.

Programas y algoritmos

Cuando se aprende el primer lenguaje de programacin se piensa que la parte difcil de resolver un problema con un ordenador es escribir el programa siguiendo las reglas del lenguaje. Esto es totalmente falso. La parte ms difcil es encontrar el mtodo de resolucin del problema. Una vez encontrado este mtodo, es bastante sencillo traducirlo al lenguaje de programacin necesario: Python, C++, Java o cualquier otro. Denicin Se denomina algoritmo a una secuencia no ambigua, nita y ordenada de instrucciones que han de seguirse para resolver un problema.

Importante Un programa de ordenador es un algoritmo escrito en un lenguaje de programacin. En un algoritmo siempre se deben de considerar tres partes: Entrada: informacin dada al algoritmo. Proceso: operaciones o clculos necesarios para encontrar la solucin del problema. Salida: respuestas dadas por el algoritmo o resultados nales de los procesos realizados. Los algoritmos se pueden expresar de muchas maneras: utilizando lenguajes formales, lenguajes algortmicos (pseudocdigo) o mediante el lenguaje natural (como el castellano). Esta ltima es la forma ms adecuada para la asignatura que nos ocupa. Ejemplo: Algoritmo para calcular el rea de un tringulo 1. Obtener la base del tringulo 2. Obtener la altura del tringulo 3. Hacer la operacin (base altura)/2 4. Mostrar el resultado Este algoritmo de resolucin del rea del tringulo es independiente del lenguaje de programacin que vayamos a utilizar. Cualquier programa que quiera calcular el rea de un tringulo escrito en cualquier lenguaje de programacin debe seguir estos pasos. Terminologa Dos programas distintos codicados en el mismo o en distinto lenguaje de programacin y que resuelven el mismo problema con la misma secuencia de pasos, se dice que son implementaciones del mismo algoritmo.

2.1.4.

Diseo de programas

Aunque el diseo de programas es un proceso creativo, hay que seguir una serie de pasos. Nadie empieza a escribir un programa directamente sin estudiar el problema que se quiere resolver. Todo el proceso de diseo de un programa se puede dividr en dos fases: Fase de resolucin de problemas. El resultado de esta primera fase es un algoritmo, expresado en espaol, para resolver el problema.

40

Introduccin a la programacin Fase de implementacin. A partir del algoritmo obtenido en la fase anterior, se codica y se prueba el programa nal.

Importante Muchos programadores noveles no entienden la necesidad de disear un algoritmo antes de escribir un programa en un lenguaje de programacin. La experiencia ha demostrado que la resolucin de problemas en dos fases da lugar a programas que funcionan correctamente en menos tiempo. Esta forma de disear programas requiere la realizacin de una serie de tareas: Anlisis del problema. A partir de la descripcin del problema, expresado habitualmente en lenguaje natural, es necesario obtener una idea clara sobre qu se debe hacer (proceso), determinar los datos necesarios para conseguirlo (entrada) y la informacin que debe proporcionar la resolucin del problema (salida). Diseo del algoritmo. Se debe identicar las tareas ms importantes para resolver el problema y disponerlas en el orden en el que han de ser ejecutadas. Los pasos en una primera descripcin pueden requerir una revisin adicional antes de que podamos obtener un algoritmo claro, preciso y completo. Transformacin del algoritmo en un programa (codicacin). Solamente despus de realizar las dos etapas anteriores abordaremos la codicacin de nuestro programa en el lenguaje de programacin elegido. Ejecucin y pruebas del programa. Se debe comprobar que el programa resultante est correctamente escrito en el lenguaje de programacin y, ms importante an, que hace lo que realmente debe hacer.

2.1 Abstraccin de problemas para su programacin. Conceptos fundamentales

41

2.1.5.

Python

Python es un lenguaje de alto nivel como pueden ser el C, C++ o el Java. Entonces, por qu hemos escogido precisamente Phyton en este curso? Python presenta una serie de ventajas que lo hacen muy atractivo, tanto para su uso profesional como para el aprendizaje de la programacin. Entre ellas podemos destacar las siguientes: La sintaxis es muy sencilla y cercana al lenguaje natural, lo que facilita tanto la escritura como la lectura de los programas. Es un lenguaje muy expresivo que da lugar a programas compactos, bastante ms cortos que sus equivalentes en otros lenguajes. Es un lenguaje de programacin multiparadigma, que permite al programador elegir entre varios estilos: programacin orientada a objetos, programacin imperativa (y modular) y programacin funcional. Es multiplataforma por lo que podremos utilizarlo tanto en Unix/Linux, Mac/OS o Microsoft Windows. Es un lenguaje interpretado y por tanto interactivo. En el entorno de programacin de Python se pueden introducir sentencias que se ejecutan y producen un resultado visible, que puede ayudarnos a entender mejor el lenguaje y probar los resultados de la ejecucin de porciones de cdigo rpidamente. Python es gratuito, incluso para propsitos empresariales. Es un lenguaje que est creciendo en popularidad. Algunas empresas que utilizan Python son Yahoo, Google, Disney, la NASA, Red Hat, etc. Para saber ms Python es un lenguaje de programacin creado por Guido van Rossum a principios de los aos 90 cuyo nombre est inspirado en el grupo de cmicos ingleses Monty Python. Toda la informacin necesaria sobre el lenguaje la puedes encontrar en http://www. python.org/. Python permite dos modos de interaccin con el lenguaje: 1. Escribir comandos directamente en el intrprete. En este modo, cada lnea que escribimos es ejecutada al pulsar el retorno de carro, y el resultado de la ejecucin se muestra inmediatamente, a continuacin. Es til para probar ejemplos simples y ver inmediatamente el resultado, y para experimentar con diferentes expresiones para comprender mejor sus diferencias y su funcionamiento. El inconveniente es que todo lo que se va escribiendo, se pierde cuando se cierra el intrprete. 2. Escribir un programa completo en un editor de textos, guardar el programa en un chero y despus usar el intrprete para ejecutarlo. En este caso no se ejecuta nada mientras se escribe, sino slo cuando se lanza el intrprete para que ejecute el programa completo que est en el chero. Entonces el intrprete ir leyendo lnea a lnea del chero y las ir ejecutando. No se muestra ningn resultado por pantalla, a menos que el programa contenga la orden print que sirve precisamente para esto (como veremos en su momento).

42

Introduccin a la programacin

A lo largo de este documento, presentaremos ejemplos en ambos formatos. Si se trata de ejemplos muy breves encaminados slo a demostrar alguna caracterstica del lenguaje, usaremos el intrprete directo. Si se trata de ejemplos ms largos que tienen inters suciente para merecer ser guardados en un chero, usaremos el editor. El lector puede diferenciar si usamos el intrprete o el editor, porque el estilo en que se muestra el cdigo es diferente en cada caso. Cuando se usa el intrprete, puede verse el smbolo >>> delante de cada lnea que el usuario teclea, y la respuesta del intrprete en la lnea siguiente:>>> "Ejemplo ejecutado en el interprete" Ejemplo ejecutado en el iterprete

En cambio, cuando se muestra cdigo para ser escrito en el editor, no se ve el resultado de su ejecucin. Adems las lneas estn numeradas para facilitar el referirse a ellas si es necesario (el alumno no debe copiar estos nmeros cuando escriba el cdigo en el editor).1 # Ejemplo para ser escrito en el editor 2 print "Ejemplo"

2.2.2.2.1.

Variables, expresiones, asignacinValores

El principal motivo por el que se escriben programas de ordenador es para manipular la informacin de una forma ms eciente y segura. Desde el punto de vista de la informacin, los programas manejan tpicamente los datos del siguiente modo: 1. Reciben datos de entrada por parte de los usuarios, 2. procesan esos datos, haciendo clculos y operaciones con ellos, y 3. producen resultados que son tiles para los usuarios. Los resultados pueden ser tanto valores calculados (por ejemplo, en una aplicacin de clculo de estructuras, obtener las dimensiones que debe tener una viga), como obtener un informe impreso. Aunque la informacin que manejan los programas puede parecer muy amplia, ya que existen aplicaciones informticas para propsitos muy diversos, en realidad la informacin est formada habitualmente por la agregacin de tres tipos de de datos bsicos: nmeros: 7, 3.14165 textos: Juan, Alonso, Universidad de Oviedo valores lgicos: True, False Combinando estos elementos se puede representar la informacin bsica que usan los programas. Por ejemplo, si se quiere hacer una aplicacin para gestionar los datos de cada cliente de un banco, necesitaremos guardar su nombre y apellidos (textos), el saldo de sus cuentas (nmeros) o si el cliente es preferente o no (valor lgico). Los valores lgicos tal vez parezcan menos tiles, sin embargo es casi lo contrario, no solamente permiten representar aquella informacin que puede ser cierta o falsa, sino que adems son los datos fundamentales para controlar el ujo de ejecucin de los programas (como se ver ms adelante, las sentencias condicionales y los bucles se basan en la manipulacin de valores lgicos).

2.2.2.

Tipos

Cada dato o valor que se maneja en un programa es de un tipo. Python detecta de qu tipo es cada dato por su sintaxis. Una secuencia de dgitos que no contenga el punto (.) se considera un entero. Si contiene el punto se considera un real (que python llama float). Una secuencia arbitraria de caracteres delimitados por el carcter de comillas dobles ("), o de comillas simples ()

2.2 Variables, expresiones, asignacin

43

es considerado una cadena de texto1 . Las palabras especiales True y False se consideran datos de tipo booleano. 7 es de tipo int (de integer), es un nmero entero 3.14165 es de tipo float, un nmero en coma otante (real) "Juan", es de tipo str (de string), es una cadena de caracteres True es de tipo bool (de booleano), un valor de verdad Los tipos denen conjuntos de valores que los programas pueden manejar y las operaciones que se pueden hacer con ellos. Por ejemplo, los programas pueden utilizar, gracias al tipo float, el conjunto de los nmeros reales y podemos sumar dos reales. En concreto, el rango de los nmeros reales que se pueden utilizar es de 1.7e308 que viene dado por el nmero de bytes (8) que se utilizan para representarlos2 . Para saber ms Adems del tipo int, python posee otro tipo entero, long. Normalmente se manejan los valores enteros como int ya que este tipo permite representar valores del orden de millones de billones. Si alguna vez un programa necesita guardar un valor entero an mayor, entonces se representar automticamente (sin que el programador deba hacer nada) como un long. La capacidad de representacin de un long est slo limitada por la cantidad de memoria libre, por lo que en la prctica puede representar valores enteros extremadamente grandes. Para saber el tipo de un valor, se puede utilizar la funcin type. Simplemente hay que indicar el valor del que se quiere conocer su tipo:>>>> type(7) >>> type(3.1416) >>> type("Juan") >>> type(True)

Como se puede apreciar, se imprime en la consola el tipo de cada uno de los valores. En realidad esto no es muy til a la hora de escribir un programa, ya que normalmente el programador sabe de qu tipo es cada uno de los datos que el programa maneja.

2.2.3.

Conversiones entre tipos

A veces los programas reciben valores que son de un cierto tipo y necesitan convertirlos en valores de otro tipo antes de hacer operaciones con ellos. Esta situacin se produce, por ejemplo, con datos que se reciben como string pero que representan nmeros; antes de hacer clculos con ellos es necesario convertirlos en un valor numrico. La forma de hacer esas conversiones es bastante sencilla: primero hay que indicar el nombre del tipo al que se quiere convertir el valor, y posteriormente entre parntesis el valor que se quiere convertir. Por ejemplo:Para delimitar las cadenas se puede usar indistintamente la comilla simple o la doble, pero es forzoso usar el mismo tipo de comilla para abrir y para cerrar. 2 Cuando un nmero real se sale de ese rango se considera 1

44

Introduccin a la programacin

>>> int("7") 7 >>> str(7) 7 >>> float("3.1416") 3.1415999999999999 >>> str(3.1416) 3.1416 >>> int(3.1416) 3 >>> float(7) 7.0

En el primer ejemplo se convierte en int la cadena de caracteres formada solamente por el dgito 7. El valor que se devuelve es el entero 7, que obviamente no es lo mismo la cadena que contiene el dgito 7, ni en cuanto al dato en s mismo, ni sobre todo a las operaciones que se van a poder hacer con l (la cadena con el dgito 7 no se podr dividir por otro valor, mientras que el valor entero s). El ejemplo contrario se da en la siguiente instruccin. En este caso se convierte en cadena (str) el valor entero 7. El valor que se devuelve es ahora una cadena (est entre comillas) formada por el dgito 7. Un caso anlogo se da cuando se convierte nmeros reales en cadenas y viceversa. De nuevo no es lo mismo el nmero real que la cadena formada por los dgitos que componen dicho nmero. En los dos ejemplos nales, se ve cmo se pueden convertir nmeros reales en enteros y al revs. Cuando se convierte un nmero real en entero, se devuelve la parte entera (equivale a truncar) y cuando se convierte un entero en real, la parte decimal vale 0.

2.2.4.

Operadores

Los programas usan los valores que manipulan para hacer clculos y operaciones con ellos. La forma ms sencilla de hacer operaciones con los datos es empleando los operadores del lenguaje. Cada uno de los tipos descritos anteriormente permite hacer operaciones diferentes con sus valores. Antes de estudiar los operadores ms utilizados, es interesante ver unos ejemplos iniciales. En todos estos ejemplos se usan operadores binarios (tienen dos operandos) y su sintaxis es siempre la misma: operando operador operando:>>> 7 + 4 11 >>> 3.1416 * 2 6.2831999999999999 >>> "Juan" + " Alonso" Juan Alonso >>> True and False False

En las instrucciones anteriores se han usado operadores binarios: el operador suma (+) para sumar dos enteros, el operador producto (*) para multiplicar un real por un entero, de nuevo el operador + para concatenar dos cadenas, y por ltimo el operador y-lgico (and) para hacer dicha operacin entre dos valores lgicos. El primer detalle importante que se debe observar es que todas las operaciones producen un valor: cuando sumamos 7 y 4 el resultado es el valor entero 11, o cuando concatenamos las cadenas Juan y Alonso se produce la cadena Juan Alonso. El segundo aspecto fundamental es entender qu hace cada operador. En los dos ejemplos anteriores el mismo operador + se comporta de manera diferente si se suman enteros que si se utiliza para concatenar cadenas. Por ello, se deben conocer los operadores que existen en el lenguaje y las operaciones que hace cada uno de ellos.

2.2 Variables, expresiones, asignacin

45

Aunque hay ms operadores de los que se van a citar a continuacin, los ms utilizados y con los que se pueden hacer la gran mayora de los programas estn agrupados en tres grandes grupos: Aritmticos: + (suma), - (resta), * (producto), / (divisin), % (resto) y ** (potencia). Tambin hay un operador unario (que acta sobre un solo dato, en lugar de dos) que es el - para cambiar de signo al dato que le siga. Relacionales: == (igual), != (distinto), < (menor que), (mayor que) y >= (mayor o igual que) Lgicos: and (y-lgico), or (o-lgico) y not (no-lgico) Los operadores aritmticos se emplean habitualmente con los tipos numricos y permiten hacer las operaciones matemticas tpicas. El nico operador que tiene un comportamiento diferente segn los operandos sean int o float es el operador divisin (/): cuando recibe enteros hace una divisin entera, el cociente ser un valor entero, y con valores reales la divisin es real. Es un buen ejemplo de que el resultado de una expresin que use un operador depende de los operandos que se empleen, en este caso basta con que uno de los dos operandos sea un nmero real para que la divisin sea real. Para saber ms Existen dos variantes del lenguaje Python. La que explicamos en esta asignatura se denomina Python 2, la otra (ms reciente pero an menos extendida) se denomina Python 3. En Python 3, el operador / se comporta de forma diferente a como se ha descrito, ya que siempre realiza la divisin real (otante), incluso si los operandos son enteros. Para el caso en que se quiera realizar la divisin entera se tiene el operador // (que tambin existe en Python 2). Esto suele resultar ms claro para los principiantes. Si quieres que Python 2 se comporte como Python 3 en lo que respecta a la divisin, puedes poner al principio de tus programas una lnea que diga:1 from __future__ import division

Sin entrar a explicar la curiosa sintaxis de esta lnea, basta saber que si la pones, entonces el operador / realizar siempre la divisin real, al igual que en Python 3. Algunos operadores aritmticos, en concreto el operador + y el operador *, se pueden utilizar tambin con cadenas de caracteres3 . Lo que producen son, respectivamente, la concatenacin de dos cadenas, y la concatenacin de una misma cadena varias veces (luego se ver algn ejemplo de esta operacin). Los operadores relacionales sirven para determinar si es cierta o no una relacin de orden entre dos valores, o si stos son iguales o distintos. Por ejemplo, podemos comprobar si 3 >> 2 / 3 0 >>> 2 % 3 2 >>> 2.0 / 3 0.66666666666666663 >>> 2 ** 3 8 >>>> "Pe" * 4 PePePePe >>> not True False >>> 2 > 3 False >>> 3 >> 2 == 3 False >>> 2 != 3 True >>> "Antonio" < "Juan" True

En el primer ejemplo se hace una divisin entre dos enteros, el resultado es el cociente, en ese caso 0. Si hacemos el resto ( % ) de esa misma divisin, el valor obtenido es 2. Cuando uno de los operandos es un nmero real, como pasa en el tercer ejemplo, entonces la divisin es real, produciendo un cociente que es un valor float. Aunque en otros lenguajes no existe este operador, en python es posible calcular la potencia de dos nmeros con el operador **. Una operacin ms extraa es la que se muestra en el quinto ejemplo. Se utiliza el operador * con una cadena de caracteres y un nmero entero. Lo que hace es producir una cadena en la que se repite la cadena que acta como primer operando tantas veces como indica el valor entero del segundo operando. En el ejemplo, la cadena Pe se repite 4 veces, produciendo la cadena PePePePe. El resto de operaciones son todas con operadores relacionales y lgicos, y por ello todas producen un valor bool. La primera es la nica que utiliza un operador unario4 , esto es, un operador que solamente necesita un operando. En el ejemplo se hace la operacin not con el valor True, y produce el valor lgico contrario, es decir, False. El resto de operaciones manejan operadores relacionales y producen un resultado cierto o falso en funcin de que la relacin de orden o igualdad se cumpla o no: 2 no es mayor que 3 (falso), 3 s es menor o igual que 3.1426 (cierto), 2 no es igual que 3 (falso) y 2 s es distinto de 3 (cierto). Tambin el orden puede comprobarse entre cadenas, como muestra el ltimo ejemplo. Se trata de un orden alfabtico en este caso, la cadena Antonio va antes, y por tanto es menor que la cadena Juan, si ordenramos ambas cadenas alfabticamente. Importante Todas las operaciones que se hacen con operandos siempre producen un resultado. Ese resultado ser un valor de un cierto tipo. El programador debe conocer siempre el tipo4

Tambin el operador - puede actuar como operador unario, cambiando el signo del operador numrico que le siga

2.2 Variables, expresiones, asignacin

47

que producir una expresin sabiendo el tipo de sus operandos y la operacin que realiza el operador.

2.2.5.

Variables

Como se dijo al principio de esta seccin, los programas se escriben para, dados unos datos de entrada, hacer clculos con ellos, y producir unos resultados de salida. Para que los programas sean tiles necesitamos un mecanismo que nos permita representar esa informacin que va a cambiar: los datos de entrada que sern diferentes en cada ejecucin y los datos de salida que tomarn valores distintos en funcin de los datos de entrada recibidos. No nos sirve en este caso con usar valores; los valores concretos, como 7 o 3.1416 no cambian. La forma de representar toda esa informacin que vara es a travs de variables. Supongamos que necesitamos hacer un programa que sirva para calcular el rea de un rectngulo, dados los valores de su base y su altura. Sabemos que el clculo del rea de un rectngulo se realiza mediante la ecuacin: area = base altura Los usuarios de nuestro programa quieren poder ejecutarlo las veces que deseen, introducir de alguna forma (generalmente con el teclado) los valores de la base y la altura, y que el programa muestre el resultado del rea. Por ejemplo, si el usuario quiere calcular el rea de un rectngulo de base 5 y altura 4, introducir esos dos datos y nuestro programa debera responder que el rea es 20. Sin embargo, dentro de las instrucciones de nuestro programa no debemos escribir la operacin 5*4 porque no sabemos qu valores va a introducir el usuario cuando lo ejecute. Adems, queremos que nuestro programa calcule el rea de cualquier rectngulo. Si el usuario introdujera 6 y 3, entonces el rea sera 18. La forma de generalizar la operacin de calcular el rea dentro del programa es idntica a la manera en la que se expresa la ecuacin que explica su clculo. En lugar de usar valores concretos, emplearemos nombres de variables para referirnos a esos valores que cambian. Disearemos nuestro programa usando al menos dos variables, base y altura, que tomarn distintos valores en las diferentes ejecuciones, pero la forma de calcular el rea del rectngulo que representan es siempre la misma:>>> base * altura

cuando base o altura cambien de valor, tambin cambiar el producto de ambas y con ello el valor del rea que calcula nuestro programa. Denicin Una variable es el nombre que se utiliza en un programa para representar un dato o valor que puede cambiar. Veamos el funcionamiento de las variables con un ejemplo prctico. En primer lugar, damos un valor a nuestras dos variables base y altura, en concreto los valores 5 y 4 respectivamente:>>> base = 5 >>> altura = 4

Hemos usado dos asignaciones. En el siguiente apartado explicaremos con detalle cmo funciona una asignacin. Intuitivamente, lo que hace la asignacin es cambiar el valor de una variable. Es

48

Introduccin a la programacin

decir, ahora en nuestro ejemplo cuando usemos el nombre base, su valor ser 5 y cuando usemos altura 4. Las variables vienen a ser una forma de referirnos a un valor que est en la memoria usando un nombre. En memoria tenemos los valores 5 y 4, el 5 es el valor de la base del rectngulo y el 4 su altura:

base altura

5 4

Memoria

Cuando queremos utilizar estos datos para hacer alguna operacin simplemente tenemos que poner su nombre. As para calcular el rea escribiremos:>>> base * altura 20

El resultado es naturalmente 20 en funcin del los valores que en ese momento tienen la base y la altura. Sin embargo, a lo mejor el usuario del programa quiere calcular el rea de otro rectngulo distinto, por ejemplo uno que tenga base 5 y altura 2. Cambiaramos el valor de la altura, pero la operacin para calcular el rea sera exactamente la misma, produciendo el resultado deseado:>>> altura = 2 >>> base * altura 10

El dato altura ha cambiado y con l el resultado del rea. En memoria, la variable altura representa el valor 2 en lugar del valor 4. Ahora nuestro programa est usando los valores 5 y 2, el 4 ya ha dejado de usarse (por eso aparece en gris en la gura siguiente).

base altura

5 4 2

Memoria

Cada vez que se utiliza un valor nuevo en un programa en python, se reserva un nuevo espacio en la memoria para guardarlo. El valor de nuestro dato altura ha cambiado, est en otro sitio en la memoria, pero la forma de referirnos a l es la misma, usando el nombre de la variable. Importante Una variable es un nombre con el que representamos un valor, y por tanto, ser de un tipo. Ese valor adems se guardar en una posicin de la memoria. La variable base representa el valor 5, es de tipo int y dicho valor est en una posicin de la memoria concreta. Con el nombre de la variable podremos acceder al valor tantas veces como queramos y la variable podr cambiar de valor tantas veces como se desee. Para conocer el tipo del

2.2 Variables, expresiones, asignacin

49

valor que representa la variable, algo que habitualmente no es necesario, se puede utilizar la funcin type exactamente como se haca con los valores anteriormente. Para saber ms La posicin de la memoria donde se encuentra el valor que representa una variable es intrascendente para la ejecucin del programa; en ejecuciones distintas, el valor se situar en posiciones de la memoria diferentes. Si se quiere conocer la posicin del valor que representa una variable se debe usar la funcin id, indicando entre parntesis el nombre de la variable, p.e., id(base).

2.2.6.

Asignacin

Una de las instrucciones ms importantes para la construccin de programas es la asignacin. La asignacin es la instruccin que nos permite cambiar el valor de una variable. La sintaxis es sencilla, primero se indica el nombre de la variable, despus el operador = y por ltimo la expresin del valor que se desea asignar: variable = expresin o El efecto que tiene una asignacin es diferente en funcin de cmo sea la expresin que aparece en la parte derecha de la asignacin. Hay dos opciones: 1. si se asigna un valor (o en general, el resultado de una operacin), entonces se reserva un nuevo espacio en la memoria para contenerlo 2. si se asigna otra variable, entonces las dos variables se referirn al mismo valor Es decir, a efectos de la memoria que ocupan los datos del programa hay diferencias entre ambas situaciones. Vamos a verlo con un par de ejemplos, utilizando de nuevo el problema del clculo del rea de un rectngulo, nuestras dos variables base y altura y una nueva variable area con la que guardaremos mediante asignaciones el valor del rea del rectngulo que vayamos calculando. Analicemos en primer lugar las siguiente asignaciones:>>> >>> >>> >>> 25 base = 5 altura = base area = base * altura area

En la primera de ellas se asigna a la variable base el valor 5. Como se est asignando un nuevo valor, en memoria se reserva el espacio para contener el valor 5, valor al que nos referiremos usando la variable base. A continuacin se asigna a la variable altura la variable base. Ahora estamos en el segundo caso antes descrito, se est asignando una variable. Por tanto, no se reserva un nuevo espacio en memoria, sino que las dos variables se reeren al mismo valor, 5. Por ltimo, a la variable area se le asigna el resultado de calcular el rea del rectngulo, base * altura. Como es una operacin, produce un nuevo valor, 25, y estamos de nuevo en el primer caso. Por ello se crea una nueva posicin de memoria para contener el valor 25. Grcamente la situacin de la memoria tras estas asignaciones sera la siguiente: Supongamos que ahora se hicieran las asignaciones siguientes:

50

Introduccin a la programacin

base altura area

5

Memoria

25

>>> altura = 4 >>> area = base * altura >>> area 20

En el primer caso, a la variable altura se le asigna el valor 4. Como es un nuevo valor, se crea el espacio de memoria para contenerlo y la variable altura ser el nombre con el que podamos acceder a ese dato. A continuacin, se recalcula el rea del nuevo rectngulo. que en este caso produce el valor 20. Como se asigna un nuevo valor, ste se guarda en una nueva posicin de la memoria, a la que se podra acceder usando la variable area. En esta ocasin el valor 25 ha dejado de ser usado, por lo que aparece en gris en la imagen. Los valores que en ese momento tendra nuestro programa guardados en la memoria seran 5, 4 y 20.

base altura area

5 4 25 20

Memoria

2.2.7.

Otras consideraciones sobre las variables

Hay dos aspectos importantes a la hora de trabajar con las variables que tendrn nuestro programas que a los programadores principiantes les cuesta decidir. La primera es elegir un nombre adecuado para cada variable del programa y la segunda seleccionar qu variables necesitamos usar. El nombre de una variable puede estar formado por letras (a, b, c,. . . ), dgitos (0,1,2,. . . ) y el carcter guin bajo o subrayado (_). Adems deben tenerse en cuenta las siguientes restricciones: el nombre no puede empezar por un dgito el nombre no puede ser igual que una palabra reservada del lenguaje las letras maysculas y minsculas son diferentes Es decir, no podemos usar como nombre de una variable 9numeros ya que empieza por un dgito. Los nombres Numero y numero son diferentes, ya que no es lo mismo la letra N que la n. Y nunca se pueden usar las palabras de las que se compone el lenguaje python y que detallan en

2.2 Variables, expresiones, asignacin

51

el recuadro anexo. Todas estas reglas son bastante similares en cualquier lenguaje de programacin actual. Curiosidad: Palabras reservadas Las palabras reservadas de python son 31. No es necesario memorizarlas, se van aprendiendo a medida que se usan al programar y algunas de ellas no se usarn nunca en los programas de la asignatura. and continue except global lambda raise yield as def exec if not return assert del finally import or try break elif for in pass while class else from is print with

Pero sin duda el aspecto ms importante a la hora de elegir el nombre de una variable es que el nombre sea descriptivo del dato que la variable representa dentro del programa. De esa forma, al leer el programa, tanto por nosotros mismos como autores, como por otros programadores que pudieran leerlo, se entender mejor la utilidad que tiene la variable dentro del programa. Siempre hay que utilizar nombres lo ms descriptivos posibles, aunque sean largos y formados por varias palabras. El convenio que seguiremos en la asignatura es utilizar palabras en minsculas separadas por guiones bajos. Por ejemplo: nombre, velocidad_final, interes, codigo_postal El otro aspecto a tener en cuenta sobre las variables, es cundo hay que usar una variable en un programa? La idea fundamental que se debe tener presente es la siguiente: Importante Las variables son las herramientas que usan los programas para almacenar informacin en la memoria del ordenador. Desde esa perspectiva, siempre que en un programa se desee guardar alguna informacin para luego acceder a ella, entonces es necesario crear una variable. Eso hace que no solamente creemos variables para los datos de entrada y salida del programa, sino tambin para todos aquellos valores intermedios que el programa calcule y de los que queramos mantener el resultado en memoria para acceder a ellos posteriormente. Las variables permiten a los programadores reservar espacio en la memoria para manipular datos. La ventaja de guardar datos calculados previamente es aumentar la velocidad de los programas al no tener que recalcularlos. Otras veces, se guardan datos en memoria desde otros dispositivos como los discos. Por ejemplo, imagina un programa de tratamiento de imgenes que cargue en memoria una imagen desde un archivo. Si la imagen se mantiene en memoria, el programa podr tratarla de forma rpida ya que no necesitar leer su informacin de disco. Los datos que estn en memoria siempre se pueden tratar de una forma ms rpida que si necesitamos acceder a la misma informacin en un dispositivo secundario.

2.2.8.

Expresiones

El objetivo de esta seccin es explicar cmo se ejecutan las operaciones que escribimos en los programas y en las que aparecen valores, variables y operadores, especialmente cuando aparecen varios operadores juntos. Es lo que se denomina una expresin.

52 Denicin

Introduccin a la programacin

Una expresin es una combinacin de operadores y operandos (valores, variables) que produce un resultado (valor) de un cierto tipo.

Varias cosas en esta denicin. Primero, las expresiones se forman al mezclar los operadores con sus operandos. Los operadores son los que denen las operaciones que se van a hacer. En segundo lugar, las expresiones producen siempre un valor. Ese valor ser, como es lgico, de algn tipo. Tanto el valor producido, como su tipo, dependern de los operandos y de los operadores que se usen. La mayor dicultad que entraan las expresiones con varios operadores es saber el orden en que stos se ejecutarn. Eso lo determina lo que se denomina la precedencia de los operadores. La precedencia es la propiedad que sirve para decidir qu operador debe aplicarse primero cuando en una expresin aparecen varios operadores de distintos grupos. Vamos a verlo con dos ejemplos, las expresiones 4+5*7 y (4+5)*7. En ambas aparecen dos operadores, la suma (+) y el producto (*), con los mismos valores, sin embargo el resultado ser diferente por la presencia de los parntesis. En el caso de la expresin 4+5*7, la primera operacin que se hace es el producto ya que el operador * tiene ms precedencia que el operador +. La expresin 5*7 produce el valor 35, al que posteriormente se le suma el valor 4. El resultado nal de la expresin es 39. Grcamente:

4 + 5 * 7 4 + 39En cambio en la expresin (4+5)*7, tenemos los mismos valores y operadores, pero adems se han incluido unos parntesis que delimitan la operacin de suma. Los parntesis sirven para agrupar las operaciones que se quieren hacer primero. En este caso, lo que se indica es que se debe hacer antes la suma que el producto. Primero se realiza 4+5, produciendo el valor entero 9, y a continuacin se hace el producto de dicho valor por 7, con lo que el resultado nal de la expresin es 63:

35

(4 + 5) * 7 9 * 7 63Puedes consultar la tabla de precedencia de operadores en python en mltiples pginas web, por ejemplo en http://docs.python.org/reference/expressions.html. Sin embargo

2.3 Uso de entrada/salida por consola

53

memorizarse la tabla es difcil, y en realidad tampoco es necesario. Como se ha visto en los dos ejemplos anteriores, usando los parntesis adecuadamente se pueden cambiar el orden en que se ejecutan los operadores de una expresin. Adems, el uso de los parntesis hace que algunas expresiones se entiendan mejor al leerlas. En todo caso, las tablas de precedencia de todos los lenguajes suelen seguir una serie de reglas que si se conocen pueden permitirnos escribir expresiones complejas sin abusar tanto del uso de los parntesis. Citaremos las cuatro reglas ms bsicas: 1. lo que est entre parntesis se hace primero 2. los operadores aritmticos tienen ms precedencia que los relacionales, y los relacionales ms que los lgicos 3. los operadores unarios de un grupo ms que los binarios de ese mismo grupo 4. ** ms que los multiplicativos (*, /, %), y stos ms que los aditivos (+, -). Esta regla tambin se da con los lgicos (and ms precedencia que or) La primera regla es la ms importante de todas, ya la hemos comentado sucientemente. En el caso de la segunda, se comprende si se piensa en una expresin como x-1> entrada = raw_input() _ >>> entrada = raw_input() Hola >>> print entrada Hola

Antes de pedir un dato por teclado al usuario, es una buena idea sacar un mensaje informando de lo que se espera. Por este motivo, raw_input puede llevar como parmetro una cedena de caracteres que se saca por la pantalla justo antes de pedir la entrada al usuario (indicador o prompt en ingls).>>> entrada = raw_input("Introduce tu nombre: ") Introduce tu nombre: >>> entrada = raw_input("Introduce tu nombre: ") Introduce tu nombre: Jorge Javier >>> print entrada Jorge Javier

Si necesitamos un nmero como entrada, un entero o un otante, en lugar de una cadena, podemos utilizar las funciones int y oat para convertir la cadena al tipo numrico correspondente.>>> base = float (raw_input("Introduce la base de un tringulo:\n")) Introduce la base de un tringulo: 7

Aunque hay que tener en cuenta que si lo que introduce el usuario no es un nmero vlido se genera un error al no poder realizar la conversin.>>> base = float (raw_input("Introduce la base de un tringulo:\n")) Introduce la base de un tringulo: A Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for float(): A

Como se comentar mas adelante, el carcter especial \n al nal del mensaje del raw_imput (prompt) causa un salto de lnea.

2.3.2.

Salida por pantalla

La forma ms sencilla de mostrar algo en la salida estndar es mediante el uso de la sentencia print, como hemos visto en varios ejemplos anteriores. En su forma ms bsica a la palabra clave print le sigue una cadena de caracteres, que se mostrar en la pantalla del ordenador al ajecutarse la sentencia. Si se omite la cadena de caracteres se produce un salto de lnea.

2.3 Uso de entrada/salida por consola

55

>>> print >>> print "Hola mundo" Hola mundo

Atencin Las comillas que se usan para identicar una cadena de caracteres no aparecen en la salida por pantalla. Por defecto, la sentencia print muestra algo por la pantalla y se posiciona en la lnea siguiente. Si queremos mostrar ms de un resultado en la misma lnea, basta con separar con comas todos los valores que deseamos mostrar. Esto es debido a que Python interpreta la coma como un espacio de separacin.>>> print "Hola mundo", "de la programacin" Hola mundo de la programacin

Tambin se puede usar print para imprimir por pantalla valores que no sean cadenas de caracteres, como nmeros enteros o otantes.>>>print "Te costar entre", 30, "y", 49.5, "euros" Te costar entre 30 y 49.5 euros

Las cadenas de caracteres que muestra la sentencia print pueden contener caracteres especiales. Se trata de caracteres que van precedidos por la barra invertida \ y que tienen un signicado especco. Los ms utilizados son \n, el carcter de nueva lnea, y \t, el de tabulacin. Por ejemplo, la siguiente sentencia imprime la palabra "Hola" seguida de un rengln vaco y en la lnea siguiente (debido a los dos caracteres de nueva lnea, \n) la palabra "mundo" indentada (debido al carcter tabulador, \t).>>>print "Hola\n\n\tmundo" Hola mundo

2.3.3.

Salida con formato

La sentencia print, o ms bien las cadenas que imprime, permiten tambin utilizar tcnicas avanzadas de formateo de la salida. Veamos un ejemplo bastante simple:>>>print "Tengo %d aos" % 25 Tengo 25 aos

Lo nuevo de este ejemplo es la utilizacin una secuencia de formato: %d. Las secuencias de formato ms sencillas estn formadas por el smbolo %, llamado operador de formato, seguido de una letra que indica el tipo con el que formatear el valor proporcionado a continuacin: Secuencia %s %d %f Formato Cadena Entero Flotante

56

Introduccin a la programacin

Volvamos al ejemplo anterior. Lo que hace es construir la cadena introduciendo los valores a la derecha del smbolo % (el valor entero 25) en las posiciones indicadas por la secuencia de formato ( %d). Podemos formatear una cadena de carateres utilizando varias secuencias de formato. En este caso, los valores asociados a cada una de las secuencias deben ir entre parntesis separados por comas. El nmero de secuencias de formato y el nmero de valores asociados debe coincidir para que no se produzca un error. Igualmente, los tipos de los valores (o expresiones) deben coincidir con lo que esperan las secuencias de formato. Veamos un ejemplo un poco ms complicado:>>>print "Tengo %d aos, mido %f m. y soy de %s" % (25, 1.95, "Gijn") Tengo 25 aos, mido 1.950000 m. y soy de Gijn

Cada una de las secuencias de formato se sutituye por los valores que aparecen entre parntesis, tomados de izquierda a derecha:

En el ejemplo anterior se muestra la altura (1.95) con una serie de ceros de ms (1.950000). Esto es debido a que por defecto, el formato para los nmeros de coma otante imprime seis decimales. Sin embargo, para tener ms control sobre el formato de salida, podemos introducir un nmero entre el % y el carcter que indica el tipo al que formatear. Para cadenas y enteros, indica el nmero mnimo de caracteres que queremos que ocupe la cadena generada. Si se precisan menos caracteres de los indicados, se aaden espacios en blanco por la izquierda. En el caso de que el nmero sea negativo, ocurrir exactamente lo mismo, slo que los espacios se aadirn a la derecha de la cadena.>>>print " %10s mundo" % "Hola" Hola mundo >>>print " %-10s mundo" % "Hola" Hola mundo >>>print "Tengo %5d aos" % 25 Tengo 25 aos -->Se aaden 6 espacios a la izquierda -->Se aaden 6 espacios a la derecha -->Se aaden 3 espacios a la izquierda

Para formatear nmeros otantes, podemos introducir dos nmeros a continuacin del % separados por un .: el primero hace referencia a la longitud total y el segundo a la longitud de la parte decimal (se puede indicar slo la longitud de la parte decimal). A continuacin se presentan varios ejemplos para distintos tipos de datos:>>>print "Mido %.2f m." Mido 1.95 m. >>>print "Mido %.3f m." Mido 1.950 m. >>>print "Mido %.1f m." Mido 2.0 m. >>>print "Mi coche pesa % 1.95 -->2 cifras decimales % 1.95 -->3 cifras decimales (se rellena con 0) % 1.95 --> 1 cifra decimal (se redondea) %10.2f Kg." % 1324.728

2.4 Manejo de estructuras bsicas de control de ujoMi coche pesa 1324.73 -->10 caracateres en total, 2 la parte decimal -->(se aaden 3 espacios y se redondea)

57

Importante Los caracteres especiales y las secuencias de formato no slo se pueden utilizar con la sentencia print, se pueden usar con cualquier variable de tipo cadena.1 salida = "\nEl area un triangulo de base %d y altura %d es %.2f \n" 2 % (5, 3, (base*altura)/2) 3 print salida

\

La salida del programa anterior es:El area un triangulo de base 5 y altura 3 es 7.50

Ahora ya estamos en disposicin de entender, incluso de mejorar, el programa que calcula el rea de un tringulo con el que empezamos esta seccin:1 2 3 4 5 6

base = float (raw_input("Dame la base:")) altura = float (raw_input("Dame la altura:")) area =(base*altura)/2 salida = "\nEl area un triangulo de base %.1f y altura %.1f es %.2f \n" % (base, altura, area) print salida

\

2.4.

Manejo de estructuras bsicas de control de ujoSecuencial (BLOQUE) Aternativa simple Universidad de Oviedodoble (SI-ENTONCES-SI_NO) (SI-ENTONCES) o Fundamentos de Informtica Repetitiva (Existen 2 tipos: MIENTRAS y REPETIR-HASTA) 2.5.1 Estructuras de control fundamentales

Existen 3 estructuras de control fundamentales:

Existen 3 estructuras de control fundamentales: Estas estructuras se representan grcamente en la gura 2.1. Obsrvese que todas ellas tienen un nico punto de entrada y un nico punto de salida marcado con el rectngulo en lnea de trazos, o Secuencial (BLOQUE) lo que permitir ms adelante componer unas con otras, enlazndolas por dichos puntos de entrada o Aternativa (SI-ENTONCES-SI_NO) y salida. o Repetitiva (Existen 2 tipos: MIENTRAS y REPETIR-HASTA)

sent.1 sent. 2

V

cond.

F

cond.V

F

sent.F

sent.1 sent. n

sent. 2

sent.

cond.V

BLOQUE

SI-ENTONCES-SI_NOTema 4. Introduccin a la programacin

MIENTRAS

REPETIR-HASTA4-4

Figura 2.1: Estructuras de control fundamentales

58

Introduccin a la programacin

Bhm y Jacopini demostraron en los aos 60 que todo programa puede realizarse a base de las 3 estructuras anteriores: La secuencial, la alternativa, y una cualquiera de las 2 repetitivas, as como de anidamientos de unas estructuras en otras.

2.4.1.

Estructura secuencial (BLOQUE)

Consiste en ejecutar una sentencia a continuacin de otra. Se pueden agrupar varias sentencias para formar una nica sentencia, denominada sentencia compuesta. En otros lenguajes se usan delimitadores de bloque (p.ej: llaves). Implementacin En Python, lo que delimita el bloque es que todas tengan el mismo nivel de indentacin, es decir, el mismo nmero de espacios por la izquierda. Aunque el nmero de espacios puede ser cualquiera que se desee, ha de ser el mismo para todas las sentencias que componen el bloque secuencial. Es costumbre que este nmero de espacios sea mltiplo de 4. Por ejemplo, en la gura 2.2 se muestra la implementacin en lenguaje Python del bloque correspondiente, asumendo que sent1, sent2, etc. son diferentes sentencias Python, (asignaciones, expresiones, etc).

sent.1 sent. 21 sent1 2 sent2 3 ... 4 sentN

sent. n

Figura 2.2: Bloque secuencial Hay que tener en cuenta que el bloque principal en python ha de tener cero espacios de indentacin, y que slo los bloques que aparezcan dentro de otras estructuras de control irn indentados. En los ejemplos que hemos visto hasta este momento, todos los programas tienen un solo bloque, que es el principal y por tanto todos llevan cero espacios de indentacin. En las secciones siguientes en las que usaremos bloques dentro de otras estructuras de control podremos ver ejemplos en los que la indentacin juega su papel fundamental. Se puede usar punto y coma para separar sentencias si estn en la misma lnea, pero en esta asignatura no usaremos esa caracerstica y pondremos siempre cada sentencia en una lnea separada. Hacindolo as, no es necesario poner un punto y coma para separarlas, y en particular no es necesario poner punto y coma al nal de cada lnea (decimos esto porque en otros lenguajes como el C o Java s es obligatorio terminar cada lnea con punto y coma).

2.4.2.

Estructura alternativa

Permite elegir entre dos alternativas, segn sea verdadera o falsa, la condicin que se evala. Existen dos subtipos Aternativa simple (if) Aternativa doble (if-else)

2.4 Manejo de estructuras bsicas de control de ujo

59

En la estructura alternativa simple se proporciona una condicin y una sentencia (o un bloque de ellas). Si la condicin es verdadera se ejecuta la sentencia. Si no, no se ejecuta ninguna accin.

V

cond

F

Pseudocdigo:SI condicin ENTONCES sentencia

sent

Implementacin en python:1 if cond: 2 sent

Figura 2.3: Estructura alternativa simple (if) Esta estructura de control se puede representar grcamente como se muestra en la gura 2.3. En esta misma gura se muestra cmo leer el grco, en forma de pseudocdigo, y la implementacin en el lenguaje python. Sobre la implementacin, observar los siguientes detalles: La condicin (que se representa por cond en la gura) ser una expresin booleana cuyo resultado ser True o False. La condicin no necesita ir encerrada entre parntesis (a diferencia de otros lenguajes como C o Java). Tras la condicin, se ponen dos puntos (:), nalizando as la lnea. La sentencia a ejecutar (representada por sent en la gura) debe ir indentada, habitualmente cuatro espacios como ya hemos dicho antes. Si se trata de un bloque en lugar de una sola sentencia, todo el bloque ir indentado la misma cantidad de espacios. Aunque el pseudocdigo dice SI . . . ENTONCES, lo cierto es que en la implementacin python se escribe solo if, pero no se escribe then. El papel del then lo hacen los dos puntos. Ejemplo Suponiendo que la variable nota contiene la calicacin de un alumno, el siguiente fragmento de programa determina si ha superado la prueba.1 # El programa obtiene la nota por algn medio 2 if nota >= 5.0: 3 print "Prueba superada"

En la estructura alternativa doble (if-else) se proporcionan dos posibles sentencias, a elegir una segn el resultado de la condicin, como se muestra en la gura 2.4. Si la condicin es verdadera se ejecuta la sentencia1. Si no, se ejecuta la sentencia2. Sobre la implementacin, observar los siguientes detalles: La condicin sigue las mismas observaciones que para el caso anterior. La sentencia a ejecutar para el caso True (representada por sent1 en la gura) debe ir indentada, habitualmente cuatro espacios como ya hemos dicho antes. Si se trata de un bloque en lugar de una sola sentencia, todo el bloque ir indentado la misma cantidad de espacios.

60

Introduccin a la programacin

Pseudocdigo:V

cond

F

SI condicin ENTONCES sentencia1 SI_NO sentencia2

sent1

sent2

Implementacin en python:1 if cond: 2 sent1 3 else: 4 sent2

Figura 2.4: Estructura alternativa doble (if-else) Lo mismo cabe decir sobre la sentencia (o bloque) para el caso False, representada por sent2 en la gura. La palabra else ha de nalizarse con dos puntos y ha de tener el mismo nivel de indentacin que la palabra if, de este modo se ve a qu if corresponde el else. Ejemplo El siguiente fragmento de programa determina si la variable num de tipo entero contiene un nmero par o impar.1 # El programa inicializa num por algn medio 2 if num %2 == 0: 3 print "Es par" 4 else: 5 print "Es impar"

Las estructuras alternativas pueden anidarse, esto es, donde debera ir sent1 o sent2 en el diagrama anterior, podemos poner otra estructura alternativa. La gura 2.5 muestra un ejemplo de esto. El anidamiento puede complicarse ms, si en lugar de s1, s2, s3 o s4 en dicha gura, inclumos otra estructura alternativa. El lenguaje no pone lmite al nivel de anidamiento, que puede ser tan profundo como se quiera. En la prctica, sin embargo, utilizar ms de dos niveles resulta difcil de leer, y suele ser un sntoma de que se poda haber diseado el algoritmo de otra forma, o de que parte de l puede ser extrado a una funcin (concepto que veremos ms adelante). Como se ve en la gura, la implementacin en python hace visible el anidamiento de estas estructuras mediante el nivel de indentacin de las lneas. Las lneas que usan el mismo nivel de indentacin, estn al mismo nivel de anidamiento. Es importante que cada else vaya anidado con su if. Finalmente, python proporciona una estructura multialternativa (if-elif-else), que permite elegir entre varias alternativas segn el resultado de diferentes expresiones booleanas. En realidad, puede implementarse mediante una serie de if-else anidados en cascada, pero la sintaxis con if-elif-else resulta ms legible, al reducir el anidamiento. La idea general se leera como si se cumple cond1 haz sent1, si no, si se cumple cond2 haz sent2, si no, si se cumple cond3 haz sent3, etc.. y si no se cumple ninguna, haz sentencia, y la implementacin en Python sera la siguiente:1 if cond1: 2 sent1 3 elif cond2:

2.4 Manejo de estructuras bsicas de control de ujo

61

V

c1

F

Implementacin en python:1 if c1: 2 if c2: 3 s1 4 else: 5 s2 6 else: 7 if c3: 8 s3 9 else: 10 s4

V

c2

F

V

c3

F

s1

s2

s3

s4

Figura 2.5: Estructuras alternativas anidadas4 5 6 7 8 9 10 11

sent2 elif cond3: sent3 ... elif condN: sentN else: sentencia

#cualquier otro caso no contemplado

Observaciones sobre la implementacin: La palabra elif es una contraccin de else if. Cada uno de los elif ha de ir forzosamente alineado con el if inicial, as como el else nal. Se pueden poner tantos elif como se necesiten. El else nal es opcional. Si no se pone, y ninguna de las condiciones se ha cumplido, entonces no se ejecutar ninguna sentencia. Como siempre, cualquiera de las sent del cdigo anterior puede ser un bloque de sentencias. Basta escribir cada una en una lnea y todas con el mismo nivel de indentacin. Ejemplo El siguiente ejemplo pide al usuario una nota numrica y escribe la correspondiente nota con letra. Otro uso tpico de la estructura multialternativa es para crear mens en los que el usuario puede elegir una opcin entre varias que se le presentan.1 2 3 4 5 6 7 8 9 10 11

nota = int(raw_input("Introduzca la nota del examen: ")) if (nota >= 0) and (nota < 5): print "Suspenso" elif (nota >= 5) and (nota < 7): print "Aprobado" elif (nota >= 7) and (nota < 9): print "Notable" elif (nota >= 9) and (nota 5

2.4 Manejo de estructuras bsicas de control de ujo

65

Traducido a python, necesitamos una variable booleana que se mantenga a True mientras el bucle deba repetirse, es decir, mientras el usuario insista en meter nmeros errneos. Un buen nombre para esta variable puede ser numero_erroneo. Es preferible una nombre as, que expresa el signicado de su cometido, que no un nombre genrico como repetir, o seguir, o similar. Piensa como sera la implementacin en python usando esta idea, y comprueba despus si la solucin que se te ha ocurrido es como esta:1 numero_erroneo = True # Antes de leer el numero, suponemos que es erroneo 2 while numero_erroneo: # mientras el usuario siga metiendo numeros erroneos 3 num = int(raw_input("Introduzca un numero entre 1 y 5: ") 4 if not (num < 1 or num > 5): 5 numero_erroneo=False

Observar que, en lugar de la expresin if not (num5) podemos usar tambin if num>=1 and num=1 Y numero= 1 and num =1 and num =1 and num > range(5) [0, 1, 2, 3, 4]

Importante observa como en el resultado de range(5) no aparece el 5. La secuencia se detiene en el valor anterior al nal especicado. Si especicamos dos parmetros, se entender que se trata de los valores inicial y nal, aunque al igual que en el caso anterior, el valor nal no estar includo en la secuencia. El paso tomar por defecto el valor 1. Por ejemplo:>>> range(4,10) [4, 5, 6, 7, 8, 9]

Finalmente, si queremos especicar el paso, necesitamos especicar entonces los tres valores, inicial, nal y paso. La cantidad paso puede ser positiva o negativa, permitiendo as hacer rangos que cuentan hacia adelante o hacia atrs. Un ejemplo de rango ascendente, que recorre los impares menores de 10:>>> range(1,10,2) [1, 3, 5, 7, 9]

68

Introduccin a la programacin

En el bucle ascendente, el ltimo nmero que se incluye en el rango es el mayor que cumpla ser menor que el valor nal. Es decir, el cuanto se encuentra que el valor es mayor o igual que el valor nal, el rango se detiene y ese ya no sera includo. Qu parmetros tendramos que pasarle a range para generar un rango que incluya los nmeros pares comprendidos entre 1 y 10, incluyendo al 10? Se deja como ejercicio para el lector. Finalmente, si el paso es negativo, el valor inicial tendr que ser mayor que el valor nal, de lo contrario se nos generara un rango vaco. Un par de ejemplos:>>> range(1,10,-1) [] >>> range(10,1,-1) [10, 9, 8, 7, 6, 5, 4, 3, 2]

Observa como en el primer caso el rango que se obtiene est vaco, debido a que por error hemos puesto un valor inicial que es menor que el valor nal. En el segundo caso el rango se genera correctamente, pero observa que, al igual que en los rangos ascendentes, el valor nal especicado (el 1) no forma parte de la secuencia que se genera. Es decir, en este caso range va generando nmeros hasta que encuentra uno que es menor o igual que el nal especicado y entonces se detiene y este ltimo no forma parte del resultado. Qu parmetros habra que pasarle a range para que genere todos los mltiplos de 3 positivos y menores de 100? Se deja como ejercicio para el lector. Una vez hemos comprendido como range puede usarse para generar listas de nmeros, slo queda decir cmo usar la sintaxis for para hacer que una variable i vaya tomando valores sobre esa lista. La sintaxis es la siguiente:for i in range(...): sentencia1 sentencia2

Esto crea un bucle formado por sentencia1 y sentencia2 que se repetir un nmero de veces que depende de los parmetros que pongamos en range, y en cada una de esas repeticiones, la variable i va tomando un valor de los generados por range. Por ejemplo, si queremos imprimir los nmeros del 1 al 10:1 for i in range(1,11): 2 print i

Ya que range(1,11) genera una secuencia de 10 enteros, el bucle se repetir 10 veces. En cada iteracin del bucle la i tendr un valor diferente, que va pasando por la secuencia de valores generada por range. Este bucle por tanto es equivalente al que vimos en la pgina 66, aunque como vemos la sintaxis es mucho ms compacta. Es importante sealar que para que el 10 forme tambin parte de la secuencia, debemos especicar 11 como valor nal. Esto puede resultarte chocante, pero es que, si bien las personas, cuando queremos contar N nmeros solemos hacerlo desde 1 hasta N, ambos inclusives, en informtica sin embargo es mucho ms frecuente el caso de que los N nmeros deban ir desde 0 hasta N-1, lo cual es justamente lo que obtenemos si ponemos range(N). Otra forma de imprimir los nmeros entre 1 y 10, por tanto, podra ser:1 for i in range(10): 2 print i+1

En ocasiones, los valores que tome la variable i no nos importan. Si queremos, por ejemplo, imprimir una secuencia de 20 asteriscos en pantalla, nos da igual si la i va entre 1 y 20 o entre 0 y

2.4 Manejo de estructuras bsicas de control de ujo

69

19, con tal de que haya 20 repeticiones del bucle. En ese caso range(20) es perfectamente vlido y ms legible incluso que range(1,21). Por ejemplo:1 for i in range(20): 2 print "*",

# Repetir 20 veces # imprimir asterisco

Ejemplo nal Vamos a escribir un programa que pida al usuario un nmero entero y positivo (debe insistir en que sea positivo, repitiendo la pregunta si el usuario mete uno negativo). Una vez tenemos ese nmero, se calcula el factorial del mismo5 , y se imprime en pantalla el resultado. El cdigo siguiente muestra una posible implementacin:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

# Para forzar a que el numero introducido sea positivo, haremos un bucle # REPETIR-HASTA QUE sea positivo es_positivo = False # Inicialmente suponemos que no lo es while not es_positivo: n = int(raw_input("Introduce un numero positivo o cero: ")) if n >= 0: es_positivo = True # # # # Ahora calcularemos el factorial. Para ello hay que multiplicar todos los numeros entre 1 y n. Usaremos una variable "fact" que inicialmente sea 1 y en cada iteracion del bucle multiplique su valor anterior por el i correspondiente a esa iteracion

fact = 1 for i in range(1,n+1): fact = fact * i # Al salir del bucle tenemos la respuesta, la imprimimos print n, "!=", fact

Algunos comentarios sobre el listado anterior: Observa los parmetros que hemos pasado a range(). Para que la i vaya tomando valores entre 1 y n, ambos inclusive, ha sido necesario poner range(1, n+1). Se trata de un bucle ascendente, pero podra haberse implementado tambin en forma de bucle descendente. Intntalo. Qu ocurre si n es cero? Funciona el programa, o se rompe su ejecucin? Y si funciona produce la respuesta correcta? (nota, el factorial de 0 es igual a 1 por denicin). Pongamos por caso que vamos a calcular el factorial de 6. Fijate que en la primera iteracin del bucle, en la que i vale 1 y fact tambin vale 1, estamos haciendo simplemente el producto 1 * 1, lo cual podra haberse omitido. Si en vez de range(1, n+1) ponemos range(2, n+1) nos saltamos esta primera multiplicacin y el algoritmo es un poco ms veloz. Pero seguir funcionando correctamente para n=0 y para n=1? Pinsalo.

2.4.6.

Ejercicios propuestos

1. Se denomina semi-factorial 6 de un entero N , y se denota por N !!, al producto de N por N 2, por N 4, etc. hasta llegar a 2 1.5

El factorial de N se denota por N ! y se calcula como el producto de todos los enteros positivos menores o iguales En la literatura inglesa es ms frecuente el trmino double factorial, aunque ambos trminos son vlidos.

aN6

70

Introduccin a la programacin Dicho de otra forma, si N es impar, N !! es el producto de todos los impares menores o iguales que N , mientras que si N es par, N !! es el producto de todos los pares menores o iguales que N. Escribe un programa que pida al usuario el valor de N , forzando a que sea positivo, e imprima el resultado del clculo del semi-factorial. 2. Probablemente para resolver el ejercicio anterior has mirado con un if si N era par o impar, haciendo un bucle diferente en cada caso. Piensa cmo podras calcular N !! con un solo bucle que funcione tanto si N es par como si es impar. Pista: intenta con un bucle descendente.

2.5.

Denicin y uso de subprogramas y funciones. mbito de variables

Podemos pensar que un programa se compone de varias partes, como por ejemplo, obtener los datos de entrada por parte del usuario, realizar ciertos clculos con los mismos y mostrar el resultado de esos clculos en la pantalla. Un buen plan de ataque para realizar un programa consiste en descomponer la tarea a realizar en unas cuantas subtareas, que a su vez pueden descomponerse en subtareas ms pequeas o ms simples y as sucesivamente. Llegar un momento en que dichas subtareas sern lo sucientemente pequeas como para que sea sencillo programarlas. Este mtodo se conoce como diseo descendente y da lugar a la programacin modular. La mayora de los lenguajes de programacin cuentan con recursos que les permiten dividir un programa en partes ms pequeas (subprogramas). En el caso del Python estos subprogramas se conocen como funciones. Importante Un subprograma o funcin es un fragmento de cdigo de un programa que resuelve un subproblema con entidad propia

2.5.1.

Deniciones y uso

En el contexto de la programacin una funcin es una secuencia de sentencias que ejecuta una operacin deseada y tiene un nombre. Esta operacin se especica en una denicin de funcin. La sintaxis para una denicin de funcin en Python es:def NOMBRE( LISTA DE PARAMETROS ): SENTENCIAS

Sigue la siguiente estructura: 1. Un encabezado, que empieza con una palabra reservada (def), continua con el nombre que se quiere dar a la funcin, sigue con la lista de parmetros entre parntesis y termina con dos puntos. 2. Un cuerpo consistente en una o ms sentencias de Python, cada una de ellas con la misma sangra a partir del margen izquierdo. En esta asignatura usaremos un sangrado estndar de cuatro espacios. Importante Se pueden inventar los nombres que se deseen para las funciones, siguiendo las mismas reglas que para los nombres de variable (vase pgina 50).

2.5 Denicin y uso de subprogramas y funciones. mbito de variables

71

La lista de parmetros especica qu informacin, si es que la hay, se debe proporcionar a n de usar la nueva funcin. La lista de parmetros puede estar vaca o contener un sinnmero de parmetros. Ms adelante se ampliar la informacin acerca de los parmetros. La primera funcin que escribiremos no tiene parmetros, por lo que la implementacin tiene el siguiente aspecto:1 def nueva_linea(): 2 print # la sentencia print sin parametros muestra una nueva linea

Esta funcin se llama nueva_linea. Los parntesis vacos indican que la funcin no tiene parmetros. Su cuerpo contiene solamente una nica sentencia, cuya salida es una lnea vaca (eso es lo que ocurre cuando se usa la sentencia print sin argumentos). Importante Denir una funcin no hace que la funcin se ejecute. Para que una funcin se ejecute se necesita una llamada a la funcin. Las llamadas a las funciones contienen el nombre de la funcin a ejecutar seguida por la lista, entre parntesis, de los valores que son asignados a los parmetros en la denicin de funcin. Nuestra primera funcin tiene una lista vaca de parmetros, por lo que la llamada a funcin no tiene ningn argumento. Ntese, sin embargo, que en la llamada a la funcin se requieren los parntesis:1 2 3 4 5 6

def nueva_linea(): print # la sentencia print sin parametros muestra una nueva linea print "Primera Linea." nueva_linea() print "Segunda Linea." Primera Lnea. Segunda Lnea.

El espacio extra entre las dos lneas es el resultado de la llamada a la funcin nueva_linea. Qu pasa si deseamos ms espacio entre las lneas? Podemos llamar la misma funcin repetidamente:1 2 3 4 5 6 7 8

def nueva_linea(): print # la sentencia print sin parametros muestra una nueva linea print "Primera Linea." nueva_linea() nueva_linea() nueva_linea() print "Segunda Linea." Primera Lnea.

Segunda Lnea.

O podemos escribir una nueva funcin llamada tres_lineas que muestre tres lneas vacas:1 def nueva_linea(): 2 print # la sentencia print sin parametros muestra una nueva linea

723 4 5 6 7 8 9 10 11

Introduccin a la programacin

def tres_lineas(): # llama 3 veces a nueva_linea() nueva_linea() nueva_linea() nueva_linea() print "Primera Linea." tres_lineas() print "Segunda Linea."

Esta funcin contiene tres llamadas a la funcin nueva_linea. Cada una de estas llamadas ejecutar una vez el cdigo asociado a la funcin, con lo que obtendremos la misma salida en este ejemplo que en el anterior. Importante Dentro de una funcin se puede llamar a cualquier otra funcin que haya sido denida previamente. 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 funcin nos permite agrupar un cierto nmero de sentencias y darles un nombre. Las funciones pueden simplicar un programa escondiendo un clculo complejo detrs de un nico comando que usa palabras en lenguaje natural. 2. Crear una nueva funcin puede recortar el tamao de un programa eliminando el cdigo repetitivo. Por ejemplo, una forma ms corta de mostrar nueve lneas consecutivas consiste en llamar la funcin tres_lineas tres veces.

2.5.2.

Documentacin de funciones

Las funciones en python se pueden documentar con lo que se conocen como cadenas de documentacin o docstrings. Ejemplo:1 2 3 4 5 6 7 8 9 10 11 12 13

def nueva_linea(): """Esta funcion muestra en pantalla una linea vacia""" print # imprime una linea en blanco def tres_lineas(): """Esta funcion muestra en pantalla tres lineas vacia""" nueva_linea() # llama 3 veces a la funcion nueva_linea nueva_linea() nueva_linea() print "Primera Linea." tres_lineas() print "Segunda Linea."

Todo lo que hay entre las comillas es la cadena de documentacin de la funcin, que explica lo que hace sta. Una cadena de documentacin, si existe, debe ser lo primero que se dene en la funcin (es decir, lo primero que aparece tras los dos puntos). No es tcnicamente necesario incluir una cadena de documentacin, pero es recomendable hacerlo siempre. Estas cadenas se estn delimitadas por tres comillas al principio y tres comillas al nal, pudiendo ocupar varias lneas. Muchos entornos de programacin de Python utilizan la cadena de documentacin para proporcionar ayuda sensible al contexto, de modo que cuando se escribe el nombre de una funcin, su

2.5 Denicin y uso de subprogramas y funciones. mbito de variables

73

cadena de documentacin se muestra como ayuda. Otra forma de ver la cadena de documentacin de una funcin es utilizando la funcin help desde el intrprete .>>> help(nueva_linea) Help on function nueva_linea in module main: nueva_linea() Esta funcion muestra en pantalla una linea vacia

Importante La idea de las cadenas de documentacin es describir el comportamiento externo de la funcin, mientras que el funcionamiento interno se describe utilizando comentarios

Importante Escribir cadenas de documentacin y comentarios es una buena prctica de programacin. Sern ms tiles cuanto mejor expliquen el qu hace la funcin y el cmo lo hace

2.5.3.

Parmetros y argumentos

Ya hemos denido un par de funciones cuyo objetivo es escribir lineas vacas. Estas funciones tienen su utilidad, sin embargo, podra sernos ms til tener un cdigo capaz de escribir una lnea a modo de separador, por ejemplo una lnea con 10 asteriscos: ********** o una lnea con 20 guiones: -------------------Para cubrir esta necesidad, podemos implementar dos funciones: una que imprima 10 asteriscos y otra que imprima 20 guiones. Pero, no sera ms til tener una nica funcin capaz de cubrir las dos necesidades? Para ello podramos implementar la funcin pinta_linea, que se utilizara de la siguiente manera:>>> pinta_linea(10,"*") ********** >>> pinta_linea(20,"-") --------------------

Podemos observar que el nombre de la funcin es el mismo. Lo que cambia son los argumentos que se pasan a la funcin y, por tanto, el resultado de su ejecucin. Podramos leer el cdigo anterior como "pinta una lnea de 10 asteriscos" y "pinta una lnea de 20 guiones". Veamos cmo se implementara esta funcin:1 def pinta_linea(veces, car): 2 """Muestra en la pantalla una linea con un determinado numero de caracteres 3 Tiene 2 parametros: 4 - veces, numero de veces que aparecera el caracter en la linea 5 - car, caracter que se quiere mostar""" 6 i=1 7 cadena="" # se crea una cadena vacia 8 while i import mod_pintar >>> mod_pintar.pinta_linea(10,"*") **********

Despus de la sentencia import se escribe el nombre del mdulo, de forma que se importan todas las funciones contenidas en el mismo. Importante A la hora de importar un mdulo no hay que poner la extensin .py. La extensin del chero no forma parte del nombre mdulo. Para utilizar una funcin del mdulo, fjate en que se debe indicar el nombre del mdulo seguido de un punto y nalmente el nombre de la funcin. Esto puede resultar un poco engorroso cuando se van a utilizar mucho estas funciones, as que tenemos una alternativa:>>> from mod_pintar import * >>> pinta_linea(10,"*") **********

En este caso tambin se importan todas las funciones, pero ahora, para utilizarlas no es necesario poner el nombre del mdulo ni el punto. Sin embargo, no siempre necesitamos importar todas las funciones de un mdulo, puesto que nuestro programa, seguramente, no va a utilizarlas todas. Cuando estamos en esta situacin, tenemos la opcin de poder elegir las funciones que queremos importar:>>> from mod_pintar import pinta_linea, pinta_rectangulo >>> pinta_linea(10,"*") ********** >>> pinta_rectangulo(4,10,"*") ********** ********** ********** **********

Como norma general, sin embargo, no se recomienda el uso de from para importar nombres de funcin, como se acaba de ver, sino el uso del import del mdulo aunque despus haya que repetir el nombre del mdulo delante de cada llamada a la funcin. Esto es as por una razn. Es posible que diferentes mdulos implementen funciones con el mismo nombre (aunque hagan diferentes cosas). Por ejemplo, puede haber un mdulo especializado en el procesamiento de cheros con grcos (llammosle el mdulo grafico), y otro para cheros de audio (llammosle el mdulo audio). Es probable que ambos mdulos tengan una funcin cargar para leer del disco datos (imgenes o sonidos, respectivamente). Sin embargo estas funciones son diferentes, ya que una se especializa en formatos grcos y la otra en formatos de audio. Usando la sintaxis modulo.funcion no hay equvoco posible, ya que una se llamara imagenes.cargar y la otra audio.cargar. Curiosidad Cuando importamos un mdulo, el Python crea un chero que se llama como el mdulo pero con la extensin .pyc. Este chero es una versin que python ha creado la primera

84

Introduccin a la programacin

vez que ha cargado ese mdulo, tras comprobar que no contiene errores sintcticos. El chero .pyc contiene un cdigo binario especial, que python puede cargar ms rpidamente pues no necesita comprobar de nuevo la correccin sintctica. Si lo eliminamos no pasar nada y la siguiente vez que se cargue el mdulo se volver a crear. Mdulos existentes Como ya se ha comentado son muchos los mdulos existentes para trabajar en Python. Por ejemplo, el mdulo math contiene las funciones matemticas clsicas, el random funciones que generan nmeros pseudoaleatorios y el string las que trabajan con cadenas de caracteres. Hay otros mdulos que son ms especcos y se centran en problemas concretos, como por ejemplo: Interfaces grcas wxPython, pyGtk, pyQT, . . . Bases de datos MySQLdb, pySQLite, cx_Oracle, . . . Imagen PIL, gdmodule, VideoCapture, . . . Ciencias scipy, numarray, NumPy, . . . Este ltimo, el NumPy lo estudiaremos ms adelante, ya que nos permite trabajar con vectores multidimensionales de una forma muy cmoda Videojuegos Pygame, Soya 3D, pyOpenGL, . . . Sonido pySonic, pyMedia, pyMIDI, . . . Existen tambin mdulos de geolocalizacin, de puertos (USB, serie, paralelo, . . . ), para programacin de dispositivos mviles, Web, programas de mensajera y casi para cualquier cosa que podamos imaginarnos.

2.5.10.

Ejercicios resueltos

[Ejercicio 1] Implementar una funcin que retorne cierto cuando un nmero sea primo y falso en caso contrario.1 def primo(num): 2 """esta funcion recibe un numero y retorna True si el 3 numero es primo y False si no lo es""" 4 div = 2 5 es_primo = True 6 while div fin or ini < 1: return None # si no son naturales o el intervalo no esta bien else: cont = 0 i = ini while i