Introduccion a-la-programacion-python
Upcoming SlideShare
Loading in...5
×
 

Introduccion a-la-programacion-python

on

  • 1,373 views

 

Statistics

Views

Total Views
1,373
Views on SlideShare
1,373
Embed Views
0

Actions

Likes
0
Downloads
25
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Introduccion a-la-programacion-python Introduccion a-la-programacion-python Document Transcript

    • Introducción a la programación con Python Andrés Marzal Isabel Gracia Departamento de lenguajes y sistemas informáticos Codis d’assignatura II04 i IG04Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9  Introducción a la programación con Python - UJI
    • Introducci´n a la programaci´n o o con Python Andr´s Marzal e Isabel Gracia Departamento de Lenguajes y Sistemas Inform´ticos a Universitat Jaume IEdita: Publicacions de la Universitat Jaume I. Servei de Comunicació i Publicacions Campus del Riu Sec. Edifici Rectorat i Serveis Centrals. 12071 Castelló de la Plana http://www.tenda.uji.es e-mail: publicacions@uji.esCol·lecció Sapientia, 23www.sapientia.uji.esISBN: 978-84-692-5869-9Aquest text està subjecte a una llicència Reconeixement-NoComercial-CompartirIgual deCreative Commons, que permet copiar, distribuir i comunicar públicament l’obra sempreque especifique l’autor i el nom de la publicació i sense objectius comercials, i també per-met crear obres derivades, sempre que siguen distribuïdes amb aquesta mateixa llicència.http://creativecommons.org/licenses/by-nc-sa/2.5/es/deed.ca Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 II Introducción a la programación con Python - UJI
    • Prefacio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 III Introducción a la programación con Python - UJI
    • Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 IV Introducción a la programación con Python - UJI
    • Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9  Introducción a la programación con Python - UJI
    • Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 VI Introducción a la programación con Python - UJI
    • Prefacio˂˂Introducci´n a la programaci´n con Python˃˃ e ˂˂Introducci´n a la programaci´n con C˃˃ o o o odesarrollan el temario de la asignatura ˂˂Metodolog´ y tecnolog´ de la programaci´n˃˃ de ıa ıa olas titulaciones de Ingenier´ Inform´tica e Ingenier´ T´cnica en Inform´tica de Gesti´n ıa a ıa e a ode la Universitat Jaume I. En ella se pretende ense˜ar a programar y, a diferencia de lo nque es usual en cursos introductorios a la programaci´n, se propone el aprendizaje con odos lenguajes de programaci´n: Python y C. o ¿Por qu´ dos lenguajes de programaci´n? Python y C son bien diferentes. El primero e oes un lenguaje de muy alto nivel que permite expresar algoritmos de forma casi directa(ha llegado a considerarse ˂˂pseudoc´digo ejecutable˃˃) y hemos comprobado que se trata ode un lenguaje particularmente adecuado para la ense˜anza de la programaci´n. Esta n oimpresi´n se ve corroborada por la adopci´n de Python como lenguaje introductorio en o ootras universidades. El lenguaje C exige una gran atenci´n a multitud de detalles que odificultan la implementaci´n de algoritmos a un estudiante que se enfrenta por primera ovez al desarrollo de programas. No obstante, C sigue siendo un lenguaje de programaci´n ode referencia y debe formar parte del curr´ ıculum de todo inform´tico: su proximidad al acomputador nos permite controlar con gran precisi´n el consumo de recursos computacio- onales. Aprender Python antes que C permite estudiar las estructuras de control y de datosb´sicas con un alto nivel de abstracci´n y, as´ entender mejor qu´ supone, exactamente, a o ı, ela mayor complejidad de la programaci´n en C y hasta qu´ punto es mayor el grado o ede control que nos otorga. Por ejemplo, una vez se han estudiado listas en Python, suimplementaci´n en C permite al estudiante no perder de vista el objetivo ultimo: cons- o ´truir una entidad con cierto nivel de abstracci´n usando unas herramientas concretas (los opunteros). De ese modo se evita una desafortunada confusi´n entre estructuras din´micas o ay punteros que es frecuente cuando ´stas se estudian unicamente a la luz de un lenguaje e ´como C. En cierto modo, pues, Python y C se complementan en el aprendizaje y ofrecenuna visi´n m´s rica y completa de la programaci´n. Las similitudes y diferencias entre o a oambos permiten al estudiante inferir m´s f´cilmente qu´ es fundamental y qu´ accesorio a a e eo accidental al dise˜ar programas en un lenguaje de programaci´n cualquiera. n o ¿Y por qu´ otro libro de texto introductorio a la programaci´n? Ciertamente hay muchos e olibros que ense˜an a programar desde cero. Creemos que estos dos libros de texto se ndiferencia de ellos tanto en el hecho de estudiar secuencialmente dos lenguajes como enla forma en que se exponen y desarrollan los conocimientos. Hemos procurado adoptarsiempre el punto de vista del estudiante y presentar los conceptos y estrategias paradise˜ar programas b´sicos paso a paso, incrementalmente. La experiencia docente nos ha n aido mostrando toda una serie l´ ıneas de razonamiento inapropiadas, errores y vicios enlos que caen muchos estudiantes. El texto trata de exponer, con mayor o menor fortuna,esos razonamientos, errores y vicios para que el estudiante los tenga presentes y procureevitarlos. As´ en el desarrollo de algunos programas llegamos a ofrecer versiones err´neas ı, opara, acto seguido, estudiar sus defectos y mostrar una versi´n corregida. Los apuntes oest´n repletos de cuadros que pretenden profundizar en aspectos marginales, llamar la aatenci´n sobre alg´n extremo, ofrecer algunas pinceladas de historia o, sencillamente, o udesviarse de lo sustancial con alguna digresi´n que podr´ resultar motivadora para el o ıa 1  Introducción a la programación con Python - UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9
    • estudiante. Hemos de recalcar que este libro pretende ense˜ar a programar y no es un manual nexhaustivo sobre el lenguaje de programaci´n Python. Son particularmente rese˜ables o ndos omisiones: los diccionarios y las clases. No forman parte de esta edici´n (aunque oposiblemente se incluir´n en otra posterior) porque hemos preferido centrarnos en aquellos aaspectos que tanto Python como C presentan en com´n. La orientaci´n a objetos se puede u otratar a partir del material expuesto en estos vol´menes, pero hubiera resultado dif´ u ıcilincluir estos contenidos en el volumen de Python y no poder tratarlos adecuadamente enel volumen dedicado a C. Queremos aprovechar para dar un consejo a los estudiantes que no nos cansamos derepetir: es imposible aprender a programar limit´ndose a leer unos apuntes o a seguir apasivamente una explicaci´n en clase (especialmente si el per´ o ıodo de estudio se concen-tra en una o dos semanas). Programar al nivel propio de un curso introductorio no esparticularmente dif´ pero constituye una actividad intelectual radicalmente nueva para ıcil,los estudiantes. Es necesario darse una oportunidad para ir asentando los conocimien-tos y las estrategias de dise˜o de programas (y as´ superar el curso). Esa oportunidad n ı,requiere tiempo para madurar. . . y trabajo, mucho trabajo; por eso el texto ofrece m´s de acuatrocientos ochenta ejercicios. S´lo tras haberse enfrentado a buena parte de ellos se oestar´ preparado para demostrar que se ha aprendido lo necesario. a Hay centenares de diferencias entre las dos primeras ediciones (publicadas comoapuntes en la Universidad Jaume I y en formato electr´nico en Internet) y ´sta. No s´lo o e ohemos corregido erratas (y errores), hemos a˜adido tambi´n nuevos ejemplos, modificado n eotros, preparado nuevos ejercicios, reubicado ejercicios para que aparezcan en lugaresque hemos juzgado m´s apropiados, etc. Los programas se presentan con una tipograf´ a ıaque, creemos, facilita notablemente la lectura. El documento PDF ofrece, adem´s, la aposibilidad de descargar c´modamente el texto de los programas (que se pueden descargar ode http://ocw.uji.es). Esperamos que esta posibilidad se traduzca en un mayor animo ´del estudiante para experimentar con los programas.Convenios tipogr´ficos aHemos tratado de seguir una serie de convenios tipogr´ficos a lo largo del texto. Los aprogramas, por ejemplo, se muestran con fondo gris, as´ ı: 1 print ’ Hola,␣mundo!’ !Por regla general, las l´ ıneas del programa aparecen numeradas a mano izquierda. Estanumeraci´n tiene por objeto facilitar la referencia a puntos concretos del programa y no odebe reproducirse en el fichero de texto si se copia el programa. Cuando se quiere destacar el nombre del fichero en el que reside un programa, sedispone este en una barra encima del c´digo: o hola mundo.py print ’ Hola,␣mundo!’ ! 1 Si se trabaja con la versi´n electr´nica del libro en formato PDF (disponible en la o op´gina web http://ocw.uji.es) es posible acceder c´modamente al texto de los pro- a ogramas. Para ello, basta con desempaquetar el fichero programas.tgz (o programas.zip)en el mismo directorio en el que est´ ubicado el documento PDF. Los programas accesibles etienen un icono que representa un documento escrito en la esquina superior izquierda.Junto al icono aparece el nombre real del fichero: como ofrecemos varias versiones de unmismo programa, nos hemos visto obligados a seguir un esquema de numeraci´n que modi- ofica el propio nombre del fichero. La primera versi´n de un fichero llamado hola mundo.py oes hola mundo 1.py, la segunda hola mundo 2.py, y as´ sucesivamente. ıIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o  2 Introducción a la programación con Python - c UJI UJI
    • hola mundo 1.py hola mundo.py 1 print ’ Hola,’, ’mundo!’ !Si, aunque haya varias versiones, no aparece un n´mero al final del nombre del fichero udescargable, se entiende que esa es la versi´n definitiva. o hola mundo.py hola mundo.py 1 print ’ Hola,␣mundo!’ !Al pinchar en el icono, se abre un fichero de texto con el navegador web o editor de textosque se indique en las preferencias del visualizador de documentos PDF. Cuando el programa contiene alg´n error grave, aparecen un par de rayos flanqueando ual nombre del programa: E hola mundo.py E rint ’ Hola,␣mundo!’ ! 1Algunos programas no est´n completos y, por ello, presentan alguna deficiencia. No aobstante, hemos optado por no marcarlos como err´neos cuando ´stos evolucionaban en o eel curso de la exposici´n. o La informaci´n que se muestra por pantalla aparece siempre recuadrada. El resultado ode ejecutar hola mundo.py se mostrar´ as´ a ı:! Hola, mundo! En ocasiones mostraremos las ´rdenes que deben ejecutarse en un int´rprete de o eo´rdenes Unix. El prompt del int´rprete se representar´ con un s´ e a ımbolo de d´lar: o ↱$ python hola_mundo.py!Hola, mundo!La parte que debe teclear el usuario o el programador se muestra siempre con un fondogris. El retorno de carro se representa expl´ıcitamente con el s´ ımbolo . ↱ Las sesiones interactivas del int´rprete de Python tambi´n se muestran recuadradas. e eEl prompt primario del int´rprete Python se muestra con los caracteres ˂˂>>>˃˃ y el esecundario con ˂˂...˃˃. Las expresiones y sentencias que teclea el programador se destacancon fondo gris. ↱>>> ’Hola,’ + ’␣’ + ’mundo!’ !’ Hola, mundo!’ ↱>>> if ’Hola’ == ’mundo’: ↱... print ’si’ ↱... else: ↱... print ’no’ ↱...noAgradecimientosEste texto es fruto de la experiencia docente de todo el profesorado de las asignaturas de˂˂Metodolog´ y tecnolog´ de la programaci´n˃˃ y se ha enriquecido con las aportaciones, ıa ıa ocomentarios y correcciones de muchos profesores del departamento de Lenguajes y Sis-temas Inform´ticos de la Universitat Jaume I de Castell´: Juan Pablo Aibar Ausina, Rafael a oBerlanga Llavor´ Antonio Castellanos L´pez, Pedro Garc´ Sevilla, Mar´ Dolores Llid´ ı, o ıa ıa oEscriv´, David Llorens Pi˜ana, Jos´ Luis Llopis Borr´s, Juan Miguel Vilar Torres, V´ a n e a ıctorManuel Jim´nez Pelayo y Ram´n Mollineda C´rdenas. Para todos ellos, nuestro agrade- e o acimiento. El agradecimiento a David Llorens Pi˜ana es doble por desarrollar, adem´s, el n aIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 3 Introducción a la programación con Python - UJI c UJI
    • entorno de programaci´n PythonG. Finalmente, agradecemos la colaboraci´n de cuantos o onos han hecho llegar sugerencias o han detectado erratas. Castell´ de la Plana, a 8 de octubre de 2009. o Andr´s Marzal Var´ e Isabel Gracia Luengo. e oIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o  4 Introducción a la programación con Python - cUJI UJI
    • Cap´ ıtulo 1Introducci´n o ¿Qu´ sabes de este asunto? pregunt´ el Rey a Alicia. e o Nada dijo Alicia. ¿Absolutamente nada? insisti´ el Rey. o Absolutamente nada dijo Alicia. Esto es importante dijo el Rey, volvi´ndose hacia los jurados. e LEWIS CARROLL, Alicia en el pa´ de la maravillas. ısEl objetivo de este curso es ense˜arte a programar, esto es, a dise˜ar algoritmos y expre- n nsarlos como programas escritos en un lenguaje de programaci´n para poder ejecutarlos oen un computador. Seis t´rminos t´cnicos en el primer p´rrafo. No est´ mal. Vayamos paso a paso: e e a aempezaremos por presentar en qu´ consiste, b´sicamente, un computador. e a1.1. ComputadoresEl diccionario de la Real Academia define computador electr´nico como ˂˂M´quina electr´- o a onica, anal´gica o digital, dotada de una memoria de gran capacidad y de m´todos de tra- o etamiento de la informaci´n, capaz de resolver problemas matem´ticos y l´gicos mediante o a ola utilizaci´n autom´tica de programas inform´ticos.˃˃ o a a La propia definici´n nos da indicaciones acerca de algunos elementos b´sicos del o acomputador: la memoria, y alg´n dispositivo capaz de efectuar c´lculos matem´ticos y l´gicos. u a a o La memoria es un gran almac´n de informaci´n. En la memoria almacenamos todo tipo e ode datos: valores num´ricos, textos, im´genes, etc. El dispositivo encargado de efectuar e aoperaciones matem´ticas y l´gicas, que recibe el nombre de Unidad Aritm´tico-L´gica a o e o(UAL), es como una calculadora capaz de trabajar con esos datos y producir, a partirde ellos, nuevos datos (el resultado de las operaciones). Otro dispositivo se encarga detransportar la informaci´n de la memoria a la UAL, de controlar a la UAL para que efect´e o ulas operaciones pertinentes y de depositar los resultados en la memoria: la Unidad deControl. El conjunto que forman la Unidad de Control y la UAL se conoce por UnidadCentral de Proceso (o CPU, del ingl´s ˂˂Central Processing Unit˃˃). e Podemos imaginar la memoria como un armario enorme con cajones numerados y laCPU como una persona que, equipada con una calculadora (la UAL), es capaz de buscaroperandos en la memoria, efectuar c´lculos con ellos y dejar los resultados en la memoria. a 5 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9  Introducción a la programación con Python - UJI
    • Memoria 1 2 Unidad Central de Proceso 3 . 4 Unidad de Control Unidad Aritm´tico-L´gica e o . . Utilizaremos un lenguaje m´s t´cnico: cada uno de los ˂˂cajones˃˃ que conforman la a ememoria recibe el nombre de celda (de memoria) y el n´mero que lo identifica es su uposici´n o direcci´n, aunque a veces usaremos estos dos t´rminos para referirnos tambi´n o o e ea la correspondiente celda. Cada posici´n de memoria permite almacenar una secuencia de unos y ceros de otama˜o fijo. ¿Por qu´ unos y ceros? Porque la tecnolog´ actual de los computadores n e ıase basa en la sencillez con que es posible construir dispositivos binarios, es decir, quepueden adoptar dos posibles estados: encendido/apagado, hay corriente/no hay corriente,cierto/falso, uno/cero. . . ¿Es posible representar datos tan variados como n´meros, textos, uim´genes, etc. con s´lo unos y ceros? La respuesta es s´ (aunque con ciertas limitaciones). a o ıPara entenderla mejor, es preciso que nos detengamos brevemente a considerar c´mo seorepresenta la informaci´n con valores binarios. o1.2. Codificaci´n de la informaci´n o oUna codificaci´n asocia signos con los elementos de un conjunto a los que denominamos osignificados. En occidente, por ejemplo, codificamos los n´meros de cero a nueve con uel conjunto de signos {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. Al hacerlo, ponemos en correspondenciaestos s´ ımbolos con cantidades, es decir, con su significado: el s´ ımbolo ˂˂6˃˃ representa ala cantidad seis. El conjunto de signos no tiene por qu´ ser finito. Podemos combinar elos d´ıgitos en secuencias que ponemos en correspondencia con, por ejemplo, los n´meros unaturales. La sucesi´n de d´ o ıgitos ˂˂99˃˃ forma un nuevo signo que asociamos a la cantidadnoventa y nueve. Los ordenadores s´lo tienen dos signos b´sicos, {0, 1}, pero se pueden o acombinar en secuencias, as´ que no estamos limitados a s´lo dos posibles significados. ı o Una variable que s´lo puede tomar uno de los dos valores binarios recibe el nombre ode bit (acr´nimo del ingl´s ˂˂binary digit˃˃). Es habitual trabajar con secuencias de bits o ede tama˜o fijo. Una secuencia de 8 bits recibe el nombre de byte (aunque en espa˜ol el n nt´rmino correcto es octeto, ´ste no acaba de imponerse y se usa la voz inglesa). Con una e esecuencia de 8 bits podemos representar 256 (28 ) significados diferentes. El rango [0, 255]de valores naturales comprende 256 valores, as´ que podemos representar cualquiera de ıellos con un patr´n de 8 bits. Podr´ o ıamos decidir, en principio, que la correspondenciaentre bytes y valores naturales es completamente arbitraria. As´ podr´ ı, ıamos decidir quela secuencia 00010011 representa, por ejemplo, el n´mero natural 0 y que la secuencia u01010111 representa el valor 3. Aunque sea posible esta asociaci´n arbitraria, no es odeseable, pues complica enormemente efectuar operaciones con los valores. Sumar, porejemplo, obligar´ a tener memorizada una tabla que dijera cu´l es el resultado de efectuar ıa ala operaci´n con cada par de valores, ¡y hay 65536 pares diferentes! o Los sistemas de representaci´n posicional de los n´meros permiten establecer esa o uasociaci´n entre secuencias de bits y valores num´ricos naturales de forma sistem´tica. o e aCentramos el discurso en secuencias de 8 bits, aunque todo lo que exponemos a con-tinuaci´n es v´lido para secuencias de otros tama˜os1 . El valor de una cadena de bits o a nb7 b6 b5 b4 b3 b2 b1 b0 es, en un sistema posicional convencional, 7 bi ·2i . As´ la secuencia i=0 ı,de bits 00001011 codifica el valor 0·27 +0·26 +0·25 +0·24 +1·23 +0·22 +1·21 +1·20 =8 + 2 + 1 = 11. El bit de m´s a la izquierda recibe el nombre de ˂˂bit m´s significativo˃˃ a ay el bit de m´s a la derecha se denomina ˂˂bit menos significativo˃˃. a Ocho bits ofrecen un rango de valores muy limitado. Es habitual en los ordenadores modernos trabajar 1con grupos de 4 bytes (32 bits) u 8 bytes (64 bits). Introducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 6 Introducción a la programación con Python - UJI c UJI
    • . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 1 ¿Cu´l es el m´ximo valor que puede representarse con 16 bits y un sistema de a arepresentaci´n posicional como el descrito? ¿Qu´ secuencia de bits le corresponde? o e· 2 ¿Cu´ntos bits se necesitan para representar los n´meros del 0 al 18, ambos inclu- a usive? .................................................................................. El sistema posicional es especialmente adecuado para efectuar ciertas operacionesaritm´ticas. Tomemos por caso la suma. Hay una ˂˂tabla de sumar˃˃ en binario que te emostramos a continuaci´n: o sumandos suma acarreo 0 0 0 0 0 1 1 0 1 0 1 0 1 1 0 1El acarreo no nulo indica que un d´ ıgito no es suficiente para expresar la suma de dosbits y que debe a˜adirse el valor uno al bit que ocupa una posici´n m´s a la izquierda. n o aPara ilustrar la sencillez de la adici´n en el sistema posicional, hagamos una suma de odos n´meros de 8 bits usando esta tabla. En este ejemplo sumamos los valores 11 y 3 en usu representaci´n binaria: o 00001011 + 00000011Empezamos por los bits menos significativos. Seg´n la tabla, la suma 1 y 1 da 0 con uacarreo 1: Acarreo 1 00001011 + 00000011 0El segundo d´ıgito empezando por derecha toma el valor que resulta de sumar a 1 y 1 elacarreo que arrastramos. O sea, 1 y 1 es 0 con acarreo 1, pero al sumar el acarreo quearrastramos de la anterior suma de bits, el resultado final es 1 con acarreo 1: Acarreo 1 1 00001011 + 00000011 10Ya te habr´s hecho una idea de la sencillez del m´todo. De hecho, ya lo conoces bien, a epues el sistema de numeraci´n que aprendiste en la escuela es tambi´n posicional, s´lo o e oque usando diez d´ ıgitos diferentes en lugar de dos, as´ que el procedimiento de suma es ıesencialmente id´ntico. He aqu´ el resultado final, que es la secuencia de bits 00001110, e ıo sea, el valor 14: Acarreo 1 1 00001011 + 00000011 00001110 La circuiter´ electr´nica necesaria para implementar un sumador que act´e como el ıa o udescrito es extremadamente sencilla. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 3 Calcula las siguientes sumas de n´meros codificados con 8 bits en el sistema uposicional:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o  7 Introducción a la programación con Python - UJIUJI c
    • a) 01111111 + 00000001 b) 01010101 + 10101010 c) 00000011 + 00000001 .................................................................................. Debes tener en cuenta que la suma de dos n´meros de 8 bits puede proporcionar una ucantidad que requiere 9 bits. Suma, por ejemplo, las cantidades 255 (en binario de 8 bitses 11111111) y 1 (que en binario es 00000001): Acarreo 1 1 1 1 1 1 1 11111111 + 00000001 (1)00000000El resultado es la cantidad 256, que en binario se expresa con 9 bits, no con 8. Decimosen este caso que la suma ha producido un desbordamiento. Esta anomal´ debe ser tenida ıaen cuenta cuando se usa o programa un ordenador. Hasta el momento hemos visto c´mo codificar valores positivos. ¿Podemos representar otambi´n cantidades negativas? La respuesta es s´ Consideremos brevemente tres formas e ı.de hacerlo. La primera es muy intuitiva: consiste en utilizar el bit m´s significativo para acodificar el signo; si vale 0, por ejemplo, el n´mero expresado con los restantes bits es upositivo (con la representaci´n posicional que ya conoces), y si vale 1, es negativo. Por oejemplo, el valor de 00000010 es 2 y el de 10000010 es −2. Efectuar sumas con valorespositivos y negativos resulta relativamente complicado si codificamos as´ el signo de un ın´mero. Esta mayor complicaci´n se traslada tambi´n a la circuiter´ necesaria. Mala u o e ıacosa. Una forma alternativa de codificar cantidades positivas y negativas es el denominado˂˂complemento a uno˃˃. Consiste en lo siguiente: se toma la representaci´n posicional de oun n´mero (que debe poder expresarse con 7 bits) y se invierten todos sus bits si es unegativo. La suma de n´meros codificados as´ es relativamente sencilla: se efect´a la u ı usuma convencional y, si no se ha producido un desbordamiento, el resultado es el valorque se deseaba calcular; pero si se produce un desbordamiento, la soluci´n se obtiene osumando el valor 1 al resultado de la suma (sin tener en cuenta ya el bit desbordado).Ve´moslo con un ejemplo. Sumemos el valor 3 al valor −2 en complemento a uno: a Acarreo 1 1 1 1 1 1 1 00000011 + 11111101 (1)00000000 ↓ 00000000 + 00000001 00000001La primera suma ha producido un desbordamiento. El resultado correcto resulta de sumaruna unidad a los 8 primeros bits. La codificaci´n en complemento a uno tiene algunas desventajas. Una de ellas es que ohay dos formas de codificar el valor 0 (con 8 bits, por ejemplo, tanto 00000000 como11111111 representan el valor 0) y, por tanto, s´lo podemos representar 255 valores o([−127, 127]), en lugar de 256. Pero el principal inconveniente es la lentitud con que serealizan operaciones como la suma: cuando se produce un desbordamiento se han deefectuar dos adiciones, es decir, se ha de invertir el doble de tiempo. Una codificaci´n alternativa (y que es la utilizada en los ordenadores) es la denomina- oda ˂˂complemento a dos˃˃. Para cambiar el signo a un n´mero hemos de invertir todos sus ubits y sumar 1 al resultado. Esta codificaci´n, que parece poco natural, tiene las ventajas ode que s´lo hay una forma de representar el valor nulo (el rango de valores representados oIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 8  Introducción a la programación con Python - cUJI UJI
    • es [−128, 127]) y, principalmente, de que una sola operaci´n de suma basta para obtener oel resultado correcto de una adici´n. Repitamos el ejemplo anterior. Sumemos 3 y −2, opero en complemento a dos: Acarreo 1 1 1 1 1 1 00000011 + 11111110 (1)00000001Si ignoramos el bit desbordado, el resultado es correcto.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 4 Codifica en complemento a dos de 8 bits los siguientes valores:a) 4 b) −4 c) 0 d) 127 e) 1 f) −1·5 Efect´a las siguientes sumas y restas en complemento a dos de 8 bits: ua) 4 + 4 b) −4 + 3 c) 127 − 128 d) 128 − 127 e) 1 − 1 f) 1 − 2 .................................................................................. Bueno, ya hemos hablado bastante acerca de c´mo codificar n´meros (aunque m´s o u aadelante ofreceremos alguna reflexi´n acerca de c´mo representar valores con parte frac- o ocional). Preocup´monos por un instante acerca de c´mo representar texto. Hay una tabla e oque pone en correspondencia 127 s´ ımbolos con secuencias de bits y que se ha asumidocomo est´ndar. Es la denominada tabla ASCII, cuyo nombre son las siglas de ˂˂American aStandard Code for Information Interchange˃˃. La correspondencia entre secuencias de bitsy caracteres determinada por la tabla es arbitraria, pero aceptada como est´ndar. La letra a˂˂a˃˃, por ejemplo, se codifica con la secuencia de bits 01100001 y la letra ˂˂A˃˃ se codificacon 01000001. En el ap´ndice A se muestra esta tabla. El texto se puede codificar, pues, ecomo una secuencia de bits. Aqu´ tienes el texto ˂˂Hola˃˃ codificado con la tabla ASCII: ı 01001000 01101111 01101100 01100001 Pero, cuando vemos ese texto en pantalla, no vemos una secuencia de bits, sino laletra ˂˂H˃˃, seguida de la letra ˂˂o˃˃,. . . Lo que realmente vemos es un gr´fico, un patr´n de a op´ ıxeles almacenado en la memoria del ordenador y que se muestra en la pantalla. Un bitde valor 0 puede mostrarse como color blanco y un bit de valor 1 como color negro. Laletra ˂˂H˃˃ que ves en pantalla, por ejemplo, es la visualizaci´n de este patr´n de bits: o o 01000010 01000010 01000010 01111110 01000010 01000010 01000010 En la memoria del ordenador se dispone de un patr´n de bits para cada car´cter2 . o aCuando se detecta el c´digo ASCII 01001000, se muestra en pantalla el patr´n de bits o ocorrespondiente a la representaci´n gr´fica de la ˂˂H˃˃. Truculento, pero eficaz. o a No s´lo podemos representar caracteres con patrones de p´ o ıxeles: todos los gr´ficos ade ordenador son simples patrones de p´ ıxeles dispuestos como una matriz. Como puedes ver, basta con ceros y unos para codificar la informaci´n que manejamos oen un ordenador: n´meros, texto, im´genes, etc. u a 2 La realidad es cada vez m´s compleja. Los sistemas modernos almacenan los caracteres en memoria de aotra forma, pero hablar de ello supone desviarnos mucho de lo que queremos contar.Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o  9 Introducción a la programación con Python - UJIUJI c
    • 1.3. Programas y lenguajes de programaci´n oAntes de detenernos a hablar de la codificaci´n de la informaci´n est´bamos comentando o o aque la memoria es un gran almac´n con cajones numerados, es decir, identificables con evalores num´ricos: sus respectivas direcciones. En cada caj´n se almacena una secuencia e ode bits de tama˜o fijo. La CPU, el ˂˂cerebro˃˃ del ordenador, es capaz de ejecutar acciones nespecificadas mediante secuencias de instrucciones. Una instrucci´n describe una acci´n o omuy simple, del estilo de ˂˂suma esto con aquello˃˃, ˂˂multiplica las cantidades que hay ental y cual posici´n de memoria˃˃, ˂˂deja el resultado en tal direcci´n de memoria˃˃, ˂˂haz o ouna copia del dato de esta direcci´n en esta otra direcci´n˃˃, ˂˂averigua si la cantidad o oalmacenada en determinada direcci´n es negativa˃˃, etc. Las instrucciones se representan omediante combinaciones particulares de unos y ceros (valores binarios) y, por tanto, sepueden almacenar en la memoria. Combinando inteligentemente las instrucciones en una secuencia podemos hacer quela CPU ejecute c´lculos m´s complejos. Una secuencia de instrucciones es un programa. a aSi hay una instrucci´n para multiplicar pero ninguna para elevar un n´mero al cubo, po- o udemos construir un programa que efect´e este ultimo c´lculo a partir de las instrucciones u ´ adisponibles. He aqu´ grosso modo, una secuencia de instrucciones que calcula el cubo a ı,partir de productos: 1. Toma el n´mero y multipl´ u ıcalo por s´ mismo. ı 2. Multiplica el resultado de la ultima operaci´n por el n´mero original. ´ o u Las secuencias de instrucciones que el ordenador puede ejecutar reciben el nombrede programas en c´digo de m´quina, porque el lenguaje de programaci´n en el que est´n o a o aexpresadas recibe el nombre de c´digo de m´quina. Un lenguaje de programaci´n es o a ocualquier sistema de notaci´n que permite expresar programas. o1.3.1. C´digo de m´quina o aEl c´digo de m´quina codifica las secuencias de instrucciones como sucesiones de unos o ay ceros que siguen ciertas reglas. Cada familia de ordenadores dispone de su propiorepertorio de instrucciones, es decir, de su propio c´digo de m´quina. o a Un programa que, por ejemplo, calcula la media de tres n´meros almacenados en las uposiciones de memoria 10, 11 y 12, respectivamente, y deja el resultado en la posici´n ode memoria 13, podr´ tener el siguiente aspecto expresado de forma comprensible para ıanosotros: Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´n 13 o 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´n 13 o 3 Dividir contenido de direcci´n 13 por 3 y dejar resultado en direcci´n 13 o o 4 Detener En realidad, el contenido de cada direcci´n estar´ codificado como una serie de unos o ıay ceros, as´ que el aspecto real de un programa como el descrito arriba podr´ ser ´ste: ı ıa e Memoria 1 10101011 00001010 00001011 00001101 2 10101011 00001101 00001100 00001101 Unidad Central de Proceso (CPU) 3 00001110 00001101 00000011 00001101 4 00000000 00000000 00000000 00000000 Unidad de Control Unidad Aritm´tico-L´gica e o . . . Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 10 Introducción a la programación con Python - UJIIntroducci´n a la programaci´n con Python o o 10 c UJI
    • La CPU es un ingenioso sistema de circuitos electr´nicos capaz de interpretar el osignificado de cada una de esas secuencias de bits y llevar a cabo las acciones quecodifican. Cuando la CPU ejecuta el programa empieza por la instrucci´n contenida en ola primera de sus posiciones de memoria. Una vez ha ejecutado una instrucci´n, pasa a ola siguiente, y sigue as´ hasta encontrar una instrucci´n que detenga la ejecuci´n del ı o oprograma. Supongamos que en las direcciones de memoria 10, 11 y 12 se han almacenado losvalores 5, 10 y 6, respectivamente. Representamos as´ la memoria: ı Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´n 13 o 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´n 13 o 3 Dividir contenido de direcci´n 13 por 3 y dejar resultado en direcci´n 13 o o 4 Detener .. .. . .10 511 1012 6 .. .. . . Naturalmente, los valores de las posiciones 10, 11 y 12 estar´n codificados en binario, aaunque hemos optado por representarlos en base 10 en aras de una mayor claridad. La ejecuci´n del programa procede del siguiente modo. En primer lugar, se ejecuta la oinstrucci´n de la direcci´n 1, que dice que tomemos el contenido de la direcci´n 10 (el o o ovalor 5), lo sumemos al de la direcci´n 11 (el valor 10) y dejemos el resultado (el valor 15) oen la direcci´n de memoria 13. Tras ejecutar esta primera instrucci´n, la memoria queda o oas´ ı: Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´n 13 o 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´n 13 o 3 Dividir contenido de direcci´n 13 por 3 y dejar resultado en direcci´n 13 o o 4 Detener .. .. . .10 511 1012 613 15 .. .. . .A continuaci´n, se ejecuta la instrucci´n de la direcci´n 2, que ordena que se tome el o o ocontenido de la direcci´n 13 (el valor 15), se sume al contenido de la direcci´n 12 (el o ovalor 6) y se deposite el resultado (el valor 21) en la direcci´n 13. La memoria pasa a oquedar en este estado. Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´n 13 o 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´n 13 o 3 Dividir contenido de direcci´n 13 por 3 y dejar resultado en direcci´n 13 o o 4 Detener .. .. . .10 511 1012 613 21 .. .. . .Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 11 11 Introducción a la programación con Python - cUJI UJI
    • Ahora, la tercera instrucci´n dice que hemos de tomar el valor de la direcci´n 13 (el valor o o21), dividirlo por 3 y depositar el resultado (el valor 7) en la direcci´n 13. Este es el oestado en que queda la memoria tras ejecutar la tercera instrucci´n: o Memoria 1 Sumar contenido de direcciones 10 y 11 y dejar resultado en direcci´n 13 o 2 Sumar contenido de direcciones 13 y 12 y dejar resultado en direcci´n 13 o 3 Dividir contenido de direcci´n 13 por 3 y dejar resultado en direcci´n 13 o o 4 Detener .. .. . .10 511 1012 613 7 .. .. . .Y finalmente, la CPU detiene la ejecuci´n del programa, pues se encuentra con la ins- otrucci´n Detener en la direcci´n 4. o o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 6 Ejecuta paso a paso el mismo programa con los valores 2, −2 y 0 en las posicionesde memoria 10, 11 y 12, respectivamente.· 7 Dise˜a un programa que calcule la media de cinco n´meros depositados en las n uposiciones de memoria que van de la 10 a la 14 y que deje el resultado en la direcci´n o ¯de memoria 15. Recuerda que la media x de cinco n´meros x1 , x2 , x3 , x4 y x5 es u 5 i=1 xi x1 + x2 + x3 + x4 + x5 ¯ x= = . 5 5· 8 Dise˜a un programa que calcule la varianza de cinco n´meros depositados en las n uposiciones de memoria que van de la 10 a la 14 y que deje el resultado en la direcci´n ode memoria 15. La varianza, que se denota con σ 2 , es 5 i=1 (xi − x )2 ¯ σ2 = , 5 ¯donde x es la media de los cinco valores. Sup´n que existe una instrucci´n ˂˂Multiplicar el o ocontenido de direcci´n a por el contenido de direcci´n b y dejar el resultado en direcci´n o o oc˃˃. .................................................................................. ¿Qu´ instrucciones podemos usar para confeccionar programas? Ya hemos dicho que eel ordenador s´lo sabe ejecutar instrucciones muy sencillas. En nuestro ejemplo, s´lo o ohemos utilizado tres instrucciones distintas: una instrucci´n de suma de la forma ˂˂Sumar contenido de direcciones p y o q y dejar resultado en direcci´n r˃˃;o una instrucci´n de divisi´n de la forma ˂˂Dividir contenido de direcci´n p o o o por q y dejar resultado en direcci´n r˃˃; o y una instrucci´n que indica que se ha llegado al final del programa: Detener. o¡Pocos programas interesantes podemos hacer con tan s´lo estas tres instrucciones! Na- oturalmente, en un c´digo de m´quina hay instrucciones que permiten efectuar sumas, o arestas, divisiones y otras muchas operaciones. Y hay, adem´s, instrucciones que permiten aescoger qu´ instrucci´n se ejecutar´ a continuaci´n, bien directamente, bien en funci´n e o a o ode si se cumple o no determinada condici´n (por ejemplo, ˂˂Si el ´ltimo resultado o ues negativo, pasar a ejecutar la instrucci´n de la posici´n p˃˃). o oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 12 12 Introducción a la programación con Python - UJIUJI c
    • 1.3.2. Lenguaje ensambladorEn los primeros tiempos de la inform´tica los programas se introduc´ en el ordenador a ıandirectamente en c´digo de m´quina, indicando uno por uno el valor de los bits de cada una o ade las posiciones de memoria. Para ello se insertaban manualmente cables en un panelde conectores: cada cable insertado en un conector representaba un uno y cada conectorsin cable representaba un cero. Como puedes imaginar, programar as´ un computador ıresultaba una tarea ardua, extremadamente tediosa y propensa a la comisi´n de errores. oEl m´s m´ a ınimo fallo conduc´ a un programa incorrecto. Pronto se dise˜aron notaciones ıa nque simplificaban la programaci´n: cada instrucci´n de c´digo de m´quina se representaba o o o amediante un c´digo mnemot´cnico, es decir, una abreviatura f´cilmente identificable con o e ael prop´sito de la instrucci´n. o o Por ejemplo, el programa desarrollado antes se podr´ representar como el siguiente ıatexto: SUM #10, #11, #13 SUM #13, #12, #13 DIV #13, 3, #13 FINEn este lenguaje la palabra SUM representa la instrucci´n de sumar, DIV la de dividir y oFIN representa la instrucci´n que indica que debe finalizar la ejecuci´n del programa. La o oalmohadilla (#) delante de un n´mero indica que deseamos acceder al contenido de la uposici´n de memoria cuya direcci´n es dicho n´mero. Los caracteres que representan el o o uprograma se introducen en la memoria del ordenador con la ayuda de un teclado y cadaletra se almacena en una posici´n de memoria como una combinaci´n particular de unos o oy ceros (su c´digo ASCII, por ejemplo). o Pero, ¿c´mo se puede ejecutar ese tipo de programa si la secuencia de unos y ceros oque la describe como texto no constituye un programa v´lido en c´digo de m´quina? Con a o ala ayuda de otro programa: el ensamblador. El ensamblador es un programa traductorque lee el contenido de las direcciones de memoria en las que hemos almacenado c´digos omnemot´cnicos y escribe en otras posiciones de memoria sus instrucciones asociadas en ec´digo de m´quina. o a El repertorio de c´digos mnemot´cnicos traducible a c´digo de m´quina y las reglas o e o aque permiten combinarlos, expresar direcciones, codificar valores num´ricos, etc., recibe eel nombre de lenguaje ensamblador, y es otro lenguaje de programaci´n. o1.3.3. ¿Un programa diferente para cada ordenador?Cada CPU tiene su propio juego de instrucciones y, en consecuencia, un c´digo deomaquina y uno o m´s lenguajes ensambladores propios. Un programa escrito para una aCPU de la marca Intel no funcionar´ en una CPU dise˜ada por otro fabricante, como a nMotorola3 . ¡Incluso diferentes versiones de una misma CPU tienen juegos de instruccionesque no son totalmente compatibles entre s´ los modelos m´s evolucionados de una familia ı!: ade CPU pueden incorporar instrucciones que no se encuentran en los m´s antiguos4 . a Si queremos que un programa se ejecute en m´s de un tipo de ordenador, ¿habr´ que a aescribirlo de nuevo para cada CPU particular? Durante mucho tiempo se intent´ definir oalg´n tipo de ˂˂lenguaje ensamblador universal˃˃, es decir, un lenguaje cuyos c´digos u o 3 A menos que la CPU se haya dise˜ado expresamente para reproducir el funcionamiento de la primera, ncomo ocurre con los procesadores de AMD, dise˜ados con el objetivo de ejecutar el c´digo de m´quina de n o alos procesadores de Intel. 4 Por ejemplo, a˜adiendo instrucciones que faciliten la programaci´n de aplicaciones multimedia (como n oocurre con los Intel Pentium MMX y modelos posteriores) impensables cuando se dise˜´ la primera CPU de nola familia (el Intel 8086).Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 13 13 Introducción a la programación con Python - UJI c UJI
    • ¡Hola, mundo! Nos gustar´ mostrarte el aspecto de los programas escritos en lenguajes ensambladores ıa reales con un par de ejemplos. Es una tradici´n ilustrar los diferentes lenguajes de o programaci´n con un programa sencillo que se limita a mostrar por pantalla el mensaje o ˂˂Hello, World!˃˃ (˂˂¡Hola, mundo!˃˃), as´ que la seguiremos. He aqu´ ese programa escrito ı ı en los lenguajes ensambladores de dos CPU distintas: a mano izquierda, el de los procesadores 80x86 de Intel (cuyo ultimo representante por el momento es el Pentium ´ 4) y a mano derecha, el de los procesadores de la familia Motorola 68000 (que es el procesador de los primeros ordenadores Apple Macintosh). .data start: msg: move.l #msg,-(a7) .string "Hello, World!n" move.w #9,-(a7) len: trap #1 .long . - msg addq.l #6,a7 .text move.w #1,-(a7) .globl _start trap #1 _start: addq.l #2,a7 push $len clr -(a7) push $msg trap #1 push $1 msg: dc.b "Hello, World!",10,13,0 movl $0x4, %eax call _syscall addl $12, %esp push $0 movl $0x1, %eax call _syscall _syscall: int $0x80 ret Como puedes ver, ambos programas presentan un aspecto muy diferente. Por otra parte, los dos son bastante largos (entre 10 y 20 l´ ıneas) y de dif´ comprensi´n. ıcil omnemot´cnicos, sin corresponderse con los del c´digo de m´quina de ning´n ordenador e o a uconcreto, fuesen f´cilmente traducibles al c´digo de m´quina de cualquier ordenador. a o aDisponer de dicho lenguaje permitir´ escribir los programas una sola vez y ejecutarlos ıaen diferentes ordenadores tras efectuar las correspondientes traducciones a cada c´digo ode m´quina con diferentes programas ensambladores. a Si bien la idea es en principio interesante, presenta serios inconvenientes: Un lenguaje ensamblador universal no puede tener en cuenta c´mo se dise˜ar´n or- o n a denadores en un futuro y qu´ tipo de instrucciones soportar´n, as´ que posiblemente e a ı quede obsoleto en poco tiempo. Programar en lenguaje ensamblador (incluso en ese supuesto lenguaje ensamblador universal) es complicad´ ısimo por los numerosos detalles que deben tenerse en cuenta.Adem´s, puestos a dise˜ar un lenguaje de programaci´n general, ¿por qu´ no utilizar a n o eun lenguaje natural, es decir un lenguaje como el castellano o el ingl´s? Programar un ecomputador consistir´ simplemente, en escribir (¡o pronunciar frente a un micr´fono!) ıa, oun texto en el que indic´semos qu´ deseamos que haga el ordenador usando el mismo a elenguaje con que nos comunicamos con otras personas. Un programa inform´tico podr´ a ıaencargarse de traducir nuestras frases al c´digo de m´quina, del mismo modo que un o aprograma ensamblador traduce lenguaje ensamblador a c´digo de m´quina. Es una idea o aatractiva, pero que queda lejos de lo que sabemos hacer por varias razones:Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 14 14 Introducción a la programación con Python - cUJI UJI
    • La complejidad intr´ ınseca de las construcciones de los lenguajes naturales dificulta enormemente el an´lisis sint´ctico de las frases, es decir, comprender su estructura a a y c´mo se relacionan entre s´ los diferentes elementos que las constituyen. o ı El an´lisis sem´ntico, es decir, la comprensi´n del significado de las frases, es a a o a´n m´s complicado. Las ambig¨edades e imprecisiones del lenguaje natural hacen u a u que sus frases presenten, f´cilmente, diversos significados, aun cuando las poda- a mos analizar sint´cticamente. (¿Cu´ntos significados tiene la frase ˂˂Trabaja en un a a banco.˃˃?) Sin una buena comprensi´n del significado no es posible efectuar una o traducci´n aceptable. o1.3.4. Lenguajes de programaci´n de alto nivel oHay una soluci´n intermedia: podemos dise˜ar lenguajes de programaci´n que, sin ser tan o n opotentes y expresivos como los lenguajes naturales, eliminen buena parte de la compleji-dad propia de los lenguajes ensambladores y est´n bien adaptados al tipo de problemas eque podemos resolver con los computadores: los denominados lenguajes de programaci´n ode alto nivel. El calificativo ˂˂de alto nivel˃˃ se˜ala su independencia de un ordenador nconcreto. Por contraposici´n, los c´digos de m´quina y los lenguajes ensambladores se o o adenominan lenguajes de programaci´n de bajo nivel. o He aqu´ el programa que calcula la media de tres n´meros en un lenguaje de alto ı univel t´ ıpico (Python):a = 5b = 10c = 6media = (a + b + c) / 3Las tres primeras l´ ıneas definen los tres valores y la cuarta calcula la media. Como puedesver, resulta mucho m´s legible que un programa en c´digo de m´quina o en un lenguaje a o aensamblador. Para cada lenguaje de alto nivel y para cada CPU se puede escribir un programa quese encargue de traducir las instrucciones del lenguaje de alto nivel a instrucciones dec´digo de m´quina, con lo que se consigue la deseada independencia de los programas con o arespecto a los diferentes sistemas computadores. S´lo habr´ que escribir una versi´n del o a oprograma en un lenguaje de programaci´n de alto nivel y la traducci´n de ese programa o oal c´digo de m´quina de cada CPU se realizar´ autom´ticamente. o a a a1.3.5. Compiladores e int´rpretes eHemos dicho que los lenguajes de alto nivel se traducen autom´ticamente a c´digo de a om´quina, s´ pero has de saber que hay dos tipos diferentes de traductores dependiendo a ı,de su modo de funcionamiento: compiladores e int´rpretes. e Un compilador lee completamente un programa en un lenguaje de alto nivel y lotraduce en su integridad a un programa de c´digo de m´quina equivalente. El programa o ade c´digo de m´quina resultante se puede ejecutar cuantas veces se desee, sin necesidad o ade volver a traducir el programa original. Un int´rprete act´a de un modo distinto: lee un programa escrito en un lenguaje de e ualto nivel instrucci´n a instrucci´n y, para cada una de ellas, efect´a una traducci´n a o o u olas instrucciones de c´digo de m´quina equivalentes y las ejecuta inmediatamente. No o ahay un proceso de traducci´n separado por completo del de ejecuci´n. Cada vez que o oejecutamos el programa con un int´rprete, se repite el proceso de traducci´n y ejecuci´n, e o oya que ambos son simult´neos. aIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 15 15 Introducción a la programación con Python - UJI c UJI
    • Compiladores e int´rpretes. . . de idiomas e Puede resultarte de ayuda establecer una analog´ entre compiladores e int´rpretes de ıa e lenguajes de programaci´n y traductores e int´rpretes de idiomas. o e Un compilador act´a como un traductor que recibe un libro escrito en un idioma u determinado (lenguaje de alto nivel) y escribe un nuevo libro que, con la mayor fidelidad posible, contiene una traducci´n del texto original a otro idioma (c´digo de m´quina). o o a El proceso de traducci´n (compilaci´n) tiene lugar una sola vez y podemos leer el libro o o (ejecutar el programa) en el idioma destino (c´digo de m´quina) cuantas veces queramos. o a Un int´rprete de programas act´a como su hom´nimo en el caso de los idiomas. Sup´n e u o o que se imparte una conferencia en ingl´s en diferentes ciudades y un int´rprete ofrece e e su traducci´n simult´nea al castellano. Cada vez que la conferencia es pronunciada, o a el int´rprete debe realizar nuevamente la traducci´n. Es m´s, la traducci´n se produce e o a o sobre la marcha, frase a frase, y no de un tir´n al final de la conferencia. Del mismo modo o act´a un int´rprete de un lenguaje de programaci´n: traduce cada vez que ejecutamos u e o el programa y adem´s lo hace instrucci´n a instrucci´n. a o o Por regla general, los int´rpretes ejecutar´n los programas m´s lentamente, pues e a aal tiempo de ejecuci´n del c´digo de m´quina se suma el que consume la traducci´n o o a osimult´nea. Adem´s, un compilador puede examinar el programa de alto nivel abarcando a am´s de una instrucci´n cada vez, por lo que es capaz de producir mejores traducciones. a oUn programa interpretado suele ser mucho m´s lento que otro equivalente que haya sido acompilado (¡t´ıpicamente entre 2 y 100 veces m´s lento!). a Si tan lento resulta interpretar un programa, ¿por qu´ no se usan unicamente compi- e ´ladores? Es pronto para que entiendas las razones, pero, por regla general, los int´rpretes epermiten una mayor flexibilidad que los compiladores y ciertos lenguajes de programaci´n ode alto nivel han sido dise˜ados para explotar esa mayor flexibilidad. Otros lenguajes nde programaci´n, por contra, sacrifican la flexibilidad en aras de una mayor velocidad ode ejecuci´n. Aunque nada impide que compilemos o interpretemos cualquier lenguaje de oprogramaci´n, ciertos lenguajes se consideran apropiados para que la traducci´n se lleve o oa cabo con un compilador y otros no. Es m´s apropiado hablar, pues, de lenguajes de aprogramaci´n t´ o ıpicamente interpretados y lenguajes de programaci´n t´o ıpicamente com-pilados. Entre los primeros podemos citar Python, BASIC, Perl, Tcl, Ruby, Bash, Java oLisp. Entre los segundos, C, C#, Pascal, C++ o Fortran. En este curso aprenderemos a programar usando dos lenguajes de programaci´n dis-otintos: uno interpretado, Python, y otro compilado, C. Este volumen se dedica al lenguajede programaci´n con Python. Otro volumen de la misma colecci´n se dedica al estudio o ode C, pero partiendo de la base de que ya se sabe programar con Python.1.3.6. PythonExisten muchos otros lenguajes de programaci´n, ¿por qu´ aprender Python? Python o epresenta una serie de ventajas que lo hacen muy atractivo, tanto para su uso profesionalcomo para el aprendizaje de la programaci´n. Entre las m´s interesantes desde el punto o ade vista did´ctico tenemos: a Python es un lenguaje muy expresivo, es decir, los programas Python son muy compactos: un programa Python suele ser bastante m´s corto que su equivalente a en lenguajes como C. (Python llega a ser considerado por muchos un lenguaje de programaci´n de muy alto nivel.) o Python es muy legible. La sintaxis de Python es muy elegante y permite la escritura de programas cuya lectura resulta m´s f´cil que si utiliz´ramos otros lenguajes de a a a programaci´n. oIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 16 16 Introducción a la programación con Python - c UJI UJI
    • Python ofrece un entorno interactivo que facilita la realizaci´n de pruebas y ayuda o a despejar dudas acerca de ciertas caracter´ısticas del lenguaje. El entorno de ejecuci´n de Python detecta muchos de los errores de programaci´n o o que escapan al control de los compiladores y proporciona informaci´n muy rica o para detectarlos y corregirlos. Python puede usarse como lenguaje imperativo procedimental o como lenguaje orientado a objetos. Posee un rico juego de estructuras de datos que se pueden manipular de modo sencillo. Estas caracter´ısticas hacen que sea relativamente f´cil traducir m´todos de c´lculo a a e aprogramas Python. Python ha sido dise˜ado por Guido van Rossum y est´ en un proceso de continuo n adesarrollo por una gran comunidad de desarrolladores. Aproximadamente cada seis mesesse hace p´blica una nueva versi´n de Python. ¡Tranquilo! No es que cada medio a˜o se u o ncambie radicalmente el lenguaje de programaci´n, sino que ´ste se enriquece manteniendo o een lo posible la compatibilidad con los programas escritos para versiones anteriores.Nosotros utilizaremos caracter´ ısticas de la versi´n 2.3 de Python, por lo que deber´s o autilizar esa versi´n o una superior. o Una ventaja fundamental de Python es la gratuidad de su int´rprete. Puedes descar- egar el int´rprete de la p´gina web http://www.python.org. El int´rprete de Python e a etiene versiones para pr´cticamente cualquier plataforma en uso: sistemas PC bajo Linux, asistemas PC bajo Microsoft Windows, sistemas Macintosh de Apple, etc. Para que te vayas haciendo a la idea de qu´ aspecto presenta un programa completo een Python, te presentamos uno que calcula la media de tres n´meros que introduce por uteclado el usuario y muestra el resultado por pantalla:a = float(raw_input(’Dame un n´mero:’)) ub = float(raw_input(’Dame otro n´mero:’)) uc = float(raw_input(’Y ahora, uno m´s:’)) amedia = (a + b + c) / 3print ’La media es’, media En los ultimos a˜os Python ha experimentado un important´ ´ n ısimo aumento del n´mero ude programadores y empresas que lo utilizan. Aqu´ tienes unas citas que han encabezado ıdurante alg´n tiempo la web oficial de Python (http://www.python.org): u Python ha sido parte importante de Google desde el principio, y lo sigue siendo a medida que el sistema crece y evoluciona. Hoy d´ docenas de ıa, ingenieros de Google usan Python y seguimos buscando gente diestra en este lenguaje. PETER NORVIG, director de calidad de b´squedas de Google Inc. u Python juega un papel clave en nuestra cadena de producci´n. Sin ´l, un pro- o e yecto de la envergadura de ˂˂Star Wars: Episodio II˃˃ hubiera sido muy dif´ ıcil de sacar adelante. Visualizaci´n de multitudes, proceso de lotes, composici´n o o de escenas. . . Python es lo que lo une todo. TOMMY BRUNETTE, director t´cnico senior de Industrial Light & Magic . eIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 17 17 Introducción a la programación con Python - UJI c UJI
    • Python est´ en todas partes de Industrial Light & Magic. Se usa para extender a la capacidad de nuestras aplicaciones y para proporcionar la cola que las une. Cada imagen generada por computador que creamos incluye a Python en alg´n punto del proceso. u PHILIP PETERSON, ingeniero principal de I+D de Industrial Light & Magic.1.3.7. CEl lenguaje de programaci´n C es uno de los m´s utilizados en el mundo profesional. La o amayor´ de las aplicaciones comerciales y libres se han desarrollado con el lenguaje de ıaprogramaci´n C. El sistema operativo Linux, por ejemplo, se ha desarrollado en C en su opr´ctica totalidad. a ¿Por qu´ es tan utilizado el lenguaje C? C es un lenguaje de prop´sito general e oque permite controlar con gran precisi´n los factores que influyen en la eficiencia de olos programas. Pero esta capacidad de control ˂˂fino˃˃ que ofrece C tiene un precio: laescritura de programas puede ser mucho m´s costosa, pues hemos de estar pendientes ade numerosos detalles. Tan es as´ que muchos programadores afirman que C no es un ılenguaje de alto nivel, sino de nivel intermedio. ¡Hola de nuevo, mundo! Te presentamos los programas ˂˂¡Hola, mundo!˃˃ en Python (izquierda) y C (derecha). print ’Hello, world!’ #include <stdio.h> int main(void) { printf("Hello, world!n"); return 0; } Como puedes comprobar, Python parece ir directamente al problema: una sola l´ ınea. Empezaremos aprendiendo Python. Aqu´ tienes una version en C del c´lculo de la media de tres n´meros le´ ı a u ıdos porteclado:#include <stdio.h>int main(void){ double a, b, c, media; printf("Dame un n´mero: "); u scanf("%lf", &a); printf("Dame otro n´mero: "); u scanf("%lf", &b); printf("Y ahora, uno m´s: "); a scanf("%lf", &c); media = (a + b + c) / 3; printf("La media es %fn", media); return 0;} C ha sufrido una evoluci´n desde su dise˜o en los a˜os 70. El C, tal cual fue concebido o n npor sus autores, Brian Kernighan y Dennis Ritchie, de la compa˜´ norteamericana de nıaIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 18 18 Introducción a la programación con Python - UJI c UJI
    • telecomunicaciones AT&T, se conoce popularmente por K&R C y est´ pr´cticamente en a adesuso. En los a˜os 80, C fue modificado y estandarizado por el American National nStandards Institute (ANSI), que dio lugar al denominado ANSI C y que ahora se conocecomo C89 por el a˜o en que se public´. El est´ndar se revis´ en los a˜os 90 y se n o a o nincorporaron nuevas caracter´ ısticas que mejoran sensiblemente el lenguaje. El resultadoes la segunda edici´n del ANSI C, m´s conocida como C99. Esta es la versi´n que o a oestudiaremos en este curso. En la asignatura utilizaremos un compilador de C gratuito: el gcc en su versi´n 3.2 oo superior. Inicialmente se denomin´ a gcc as´ tomando las siglas de GNU C Compiler. o ıGNU es el nombre de un proyecto que tiene por objeto ofrecer un sistema operativo ˂˂libre˃˃y todas las herramientas que es corriente encontrar en una plataforma Unix. Hoy d´ se ıaha popularizado enormemente gracias a la plataforma GNU/Linux, que se compone deun n´cleo de sistema operativo de la familia del Unix (Linux) y numerosas herramientas udesarrolladas como parte del proyecto GNU, entre ellas gcc. La versi´n de gcc que ousaremos no soporta a´n todas las caracter´ u ısticas de C99, pero s´ las que aprenderemos ıen el curso. Cualquier distribuci´n reciente de Linux5 incorpora la versi´n de gcc que utili- o ozaremos o una superior. Puedes descargar una versi´n de gcc y las utilidades aso- ociadas para Microsoft Windows en http://www.delorie.com/djgpp. En la p´gina ahttp://www.bloodshed.net/devcpp.html encontrar´s un entorno integrado (editor ade texto, depurador de c´digo, compilador, etc.) que tambi´n usa el compilador gcc. o e ¡Ojo!, no todos los compiladores soportan algunas caracter´ ısticas de la ultima versi´n ´ ode C, as´ que es posible que experimentes alg´n problema de compatibilidad si utilizas ı uun compilador diferente del que te recomendamos.1.4. M´s all´ de los programas: algoritmos a aDos programas que resuelven el mismo problema expresados en el mismo o en diferenteslenguajes de programaci´n pero que siguen, en lo fundamental, el mismo procedimien- oto, son dos implementaciones del mismo algoritmo. Un algoritmo es, sencillamente, unasecuencia de pasos orientada a la consecuci´n de un objetivo. o Cuando dise˜amos un algoritmo podemos expresarlo en uno cualquiera de los nu- nmerosos lenguajes de programaci´n de prop´sito general existentes. Sin embargo, ello o oresulta poco adecuado: no todos los programadores conocen todos los lenguajes y no hay consenso acerca de cu´l es el m´s adecuado para expresar las soluciones a los diferentes problemas, a a cualquiera de los lenguajes de programaci´n presenta particularidades que pueden o interferir en una expresi´n clara y concisa de la soluci´n a un problema. o o Podemos expresar los algoritmos en lenguaje natural, pues el objetivo es comunicar unprocedimiento resolutivo a otras personas y, eventualmente, traducirlos a alg´n lenguaje ude programaci´n. Si, por ejemplo, deseamos calcular la media de tres n´meros le´ o u ıdos deteclado podemos seguir este algoritmo: 1. solicitar el valor del primer n´mero, u 2. solicitar el valor del segundo n´mero, u 3. solicitar el valor del tercer n´mero, u 5 En el momento en que se redact´ este texto, las distribuciones m´s populares y recientes de Linux eran o aSuSE 8.2, RedHat 9, Mandrake 9.1 y Debian Woody.Introducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 19 19 Introducción a la programación con Python - c UJI UJI
    • La torre de Babel Hemos dicho que los lenguajes de programaci´n de alto nivel pretend´ entre otros o ıan, objetivos, paliar el problema de que cada ordenador utilice su propio c´digo de m´quina. o a Puede que, en consecuencia, est´s sorprendido por el n´mero de lenguajes de progra- e u maci´n citados. Pues los que hemos citado son unos pocos de los m´s utilizados: ¡hay o a centenares! ¿Por qu´ tantos? e El primer lenguaje de programaci´n de alto nivel fue Fortran, que se dise˜´ en los o no primeros a˜os 50 (y a´n se utiliza hoy d´ aunque en versiones evolucionadas). Fortran n u ıa, se dise˜´ con el prop´sito de traducir f´rmulas matem´ticas a c´digo de m´quina (de he- no o o a o a cho, su nombre proviene de ˂˂FORmula TRANslator˃˃, es decir, ˂˂traductor de f´rmulas˃˃). o Pronto se dise˜aron otros lenguajes de programaci´n con prop´sitos espec´ n o o ıficos: Cobol (Common Business Oriented Language), Lisp (List Processing language), etc. Cada uno de estos lenguajes hac´ f´cil la escritura de programas para solucionar problemas de ıa a ambitos particulares: Cobol para problemas de gesti´n empresarial, Lisp para ciertos ´ o problemas de Inteligencia Artificial, etc. Hubo tambi´n esfuerzos para dise˜ar lenguajes e n de ˂˂prop´sito general˃˃, es decir, aplicables a cualquier dominio, como Algol 60 (Algo- o rithmic Language). En la d´cada de los 60 hicieron su aparici´n nuevos lenguajes de e o programaci´n (Algol 68, Pascal, Simula 67, Snobol 4, etc.), pero quiz´ lo m´s notable o a a de esta d´cada fue que se sentaron las bases te´ricas del dise˜o de compiladores e e o n int´rpretes. Cuando la tecnolog´ para el dise˜o de estas herramientas se hizo accesible e ıa n a m´s y m´s programadores hubo un aut´ntico estallido en el n´mero de lenguajes de a a e u programaci´n. Ya en 1969 se hab´ dise˜ado unos 120 lenguajes de programaci´n y se o ıan n o hab´ implementado compiladores o int´rpretes para cada uno de ellos. ıan e La existencia de tant´ ısimos lenguajes de programaci´n cre´ una situaci´n similar a o o o la de la torre de Babel: cada laboratorio o departamento inform´tico usaba un lenguaje a de programaci´n y no hab´ forma de intercambiar programas. o ıa Con los a˜os se ha ido produciendo una selecci´n de aquellos lenguajes de progra- n o maci´n m´s adecuados para cada tipo de tarea y se han dise˜ado muchos otros que o a n sintetizan lo aprendido de lenguajes anteriores. Los m´s utilizados hoy d´ son C, C++ a ıa , Java, Python, Perl y PHP. Si tienes curiosidad, puedes ver ejemplos del programa ˂˂Hello, world!˃˃ en m´s de a 100 de lenguajes de programaci´n diferentes (y m´s de 400 dialectos) visitando la p´gina o a a http://www.uni-karlsruhe.de/˜uu9r/lang/html/lang-all.en.html 4. sumar los tres n´meros y dividir el resultado por 3, u 5. mostrar el resultado.Como puedes ver, esta secuencia de operaciones define exactamente el proceso que nospermite efectuar el c´lculo propuesto y que ya hemos implementado como programas en aPython y en C. Los algoritmos son independientes del lenguaje de programaci´n. Describen un pro- ocedimiento que puedes implementar en cualquier lenguaje de programaci´n de prop´sito o ogeneral o, incluso, que puedes ejecutar a mano con l´piz, papel y, quiz´, la ayuda de una a acalculadora. ¡Ojo! No es cierto que cualquier procedimiento descrito paso a paso pueda conside-rarse un algoritmo. Un algoritmo debe satisfacer ciertas condiciones. Una analog´ con ıarecetas de cocina (procedimientos para preparar platos) te ayudar´ a entender dichas arestricciones. Estudia esta primera receta: 1. poner aceite en una sart´n, e 2. encender el fuego, 3. calentar el aceite,Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 20 20 Introducción a la programación con Python - cUJI UJI
    • 4. coger un huevo, 5. romper la c´scara, a 6. verter el contenido del huevo en la sart´n, e 7. aderezar con sal, 8. esperar a que tenga buen aspecto.En principio ya est´: con la receta, sus ingredientes y los utiles necesarios somos capaces a ´de cocinar un plato. Bueno, no del todo cierto, pues hay unas cuantas cuestiones que noquedan del todo claras en nuestra receta: ¿Qu´ tipo de huevo utilizamos?: ¿un huevo de gallina?, ¿un huevo de rana? e ¿Cu´nta sal utilizamos?: ¿una pizca?, ¿un kilo? a ¿Cu´nto aceite hemos de verter en la sart´n?: ¿un cent´ a e ımetro c´bico?, ¿un litro? u ¿Cu´l es el resultado del proceso?, ¿la sart´n con el huevo cocinado y el aceite? a e En una receta de cocina hemos de dejar bien claro con qu´ ingredientes contamos y ecu´l es el resultado final. En un algoritmo hemos de precisar cu´les son los datos del a aproblema (datos de entrada) y qu´ resultado vamos a producir (datos de salida). e Esta nueva receta corrige esos fallos: Ingredientes: 10 cc. de aceite de oliva, una gallina y una pizca de sal. M´todo: e 1. esperar a que la gallina ponga un huevo, 2. poner aceite en una sart´n, e 3. encender el fuego, 4. calentar el aceite, 5. coger el huevo, 6. romper la c´scara, a 7. verter el contenido del huevo en la sart´n, e 8. aderezar con sal, 9. esperar a que tenga buen aspecto. Presentaci´n: depositar el huevo frito, sin aceite, en un plato. o Pero la receta a´n no est´ bien del todo. Hay ciertas indefiniciones en la receta: u a 1. ¿Cu´n caliente ha de estar el aceite en el momento de verter el huevo?, ¿humeando?, a ¿ardiendo? 2. ¿Cu´nto hay que esperar?, ¿un segundo?, ¿hasta que el huevo est´ ennegrecido? a e 3. Y a´n peor, ¿estamos seguros de que la gallina pondr´ un huevo? Podr´ ocurrir u a ıa que la gallina no pusiera huevo alguno. Para que la receta est´ completa, deber´ e ıamos especificar con absoluta precisi´n cada ouno de los pasos que conducen a la realizaci´n del objetivo y, adem´s, cada uno de ellos o adeber´ ser realizable en tiempo finito. ıa No basta con decir m´s o menos c´mo alcanzar el objetivo: hay que decir exactamente a oc´mo se debe ejecutar cada paso y, adem´s, cada paso debe ser realizable en tiempo o afinito. Esta nueva receta corrige algunos de los problemas de la anterior, pero presentaotros de distinta naturaleza:Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 21 21 Introducción a la programación con Python - cUJI UJI
    • Ingredientes: 10 cc. de aceite de oliva, un huevo de gallina y una pizca de sal. M´todo: e 1. poner aceite en una sart´n, e 2. encender el fuego a medio gas, 3. calentar el aceite hasta que humee ligeramente, 4. coger un huevo, 5. romper la c´scara con el poder de la mente, sin tocar el huevo, a 6. verter el contenido del huevo en la sart´n, e 7. aderezar con sal, 8. esperar a que tenga buen aspecto. Presentaci´n: depositar el huevo frito, sin aceite, en un plato. oEl quinto paso no es factible. Para romper un huevo has de utilizar algo m´s que ˂˂el apoder de la mente˃˃. En todo algoritmo debes utilizar unicamente instrucciones que pueden ´llevarse a cabo. He aqu´ una receta en la que todos los pasos son realizables: ı Ingredientes: 10 cc. de aceite de oliva, un huevo de gallina y una pizca de sal. M´todo: e 1. poner aceite en una sart´n, e 2. sintonizar una emisora musical en la radio, 3. encender el fuego a medio gas, 4. echar una partida al solitario, 5. calentar el aceite hasta que humee ligeramente, 6. coger un huevo, 7. romper la c´scara, a 8. verter el contenido del huevo en la sart´n, e 9. aderezar con sal, 10. esperar a que tenga buen aspecto. Presentaci´n: depositar el huevo frito, sin aceite, en un plato. o En esta nueva receta hay acciones que, aunque expresadas con suficiente precisi´n yosiendo realizables, no hacen nada util para alcanzar nuestro objetivo (sintonizar la radio ´y jugar a cartas). En un algoritmo, cada paso dado debe conducir y acercarnos m´s a la aconsecuci´n del objetivo. o Hay una consideraci´n adicional que hemos de hacer, aunque en principio parezca ouna obviedad: todo algoritmo bien construido debe finalizar tras la ejecuci´n de un n´mero o ufinito de pasos. Aunque todos los pasos sean de duraci´n finita, una secuencia de instrucciones puede orequerir tiempo infinito. Piensa en este m´todo para hacerse millonario: e 1. comprar un n´mero de loter´ v´lido para el pr´ximo sorteo, u ıa a o 2. esperar al d´ de sorteo, ıa 3. cotejar el n´mero ganador con el nuestro, uIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 22 22 Introducción a la programación con Python - cUJI UJI
    • 4. si son diferentes, volver al paso 1; en caso contrario, somos millonarios.Como ves, cada uno de los pasos del m´todo requiere una cantidad finita de tiempo, pero eno hay ninguna garant´ de alcanzar el objetivo propuesto. ıa En adelante, no nos interesar´n m´s las recetas de cocina ni los procedimientos para a aenriquecerse sin esfuerzo (¡al menos no como objeto de estudio de la asignatura!). Losalgoritmos en los que estaremos interesados son aquellos que describen procedimientosde c´lculo ejecutables en un ordenador. Ello limitar´ el ambito de nuestro estudio a la a a ´manipulaci´n y realizaci´n de c´lculos sobre datos (num´ricos, de texto, etc.). o o a e Abu Ja‘far Mohammed ibn Mˆsˆ Al-Khowˆrizm y Euclides u a a La palabra algoritmo tiene origen en el nombre de un matem´tico persa del siglo IX: Abu a Ja‘far Mohammed ibn Mˆsˆ Al-Khowˆrizm (que significa ˂˂Mohammed, padre de Ja‘far, u a a hijo de Moises, nacido en Khowˆrizm˃˃). Al-Khowˆrizm escribi´ tratados de aritm´tica a a o e y algebra. Gracias a los textos de Al-Khowˆrizm se introdujo el sistema de numeraci´n ´ a o hind´ en el mundo arabe y, m´s tarde, en occidente. u ´ a En el siglo XIII se publicaron los libros Carmen de Algorismo (un tratado de aritm´tica e ¡en verso!) y Algorismus Vulgaris, basados en parte en la Aritm´tica de Al-Khowˆrizm. e a Al-Khowˆrizm escribi´ tambi´n el libro ˂˂Kitab al jabr w’al-muqabala˃˃ (˂˂Reglas de a o e restauraci´n y reducci´n˃˃), que dio origen a una palabra que ya conoces: ˂˂´lgebra˃˃. o o a Abelardo de Bath, uno de los primeros traductores al lat´ de Al-Khowˆrizm, em- ın a pez´ un texto con ˂˂Dixit Algorismi. . . ˃˃ (˂˂Dijo Algorismo. . . ˃˃), popularizando as´ el o ı t´rmino algorismo, que pas´ a significar ˂˂realizaci´n de c´lculos con numerales hindo- e o o a ar´bigos˃˃. En la edad media los abaquistas calculaban con abaco y los algorismistas a ´ con ˂˂algorismos˃˃. En cualquier caso, el concepto de algoritmo es muy anterior a Al-Khowˆrizm. En el a siglo III a.C., Euclides propuso en su tratado ˂˂Elementos˃˃ un m´todo sistem´tico para e a el c´lculo del M´ximo Com´n Divisor (MCD) de dos n´meros. El m´todo, tal cual fue a a u u e propuesto por Euclides, dice as´ ˂˂Dados dos n´meros naturales, a y b, comprobar si ı: u ambos son iguales. Si es as´ a es el MCD. Si no, si a es mayor que b, restar a a el ı, valor de b; pero si a es menor que b, restar a b el valor de a. Repetir el proceso con los nuevos valores de a y b˃˃. Este m´todo se conoce como ˂˂algoritmo de Euclides˃˃, e aunque es frecuente encontrar, bajo ese mismo nombre, un procedimiento alternativo y m´s eficiente: ˂˂Dados dos n´meros naturales, a y b, comprobar si b es cero. Si es as´ a u ı, a es el MCD. Si no, calcular c, el resto de dividir a entre b. Sustituir a por b y b por c y repetir el proceso˃˃. Un algoritmo debe poseer las siguientes caracter´ ısticas: 1. Ha de tener cero o m´s datos de entrada. a 2. Debe proporcionar uno o m´s datos de salida como resultado. a 3. Cada paso del algoritmo ha de estar definido con exactitud, sin la menor am- big¨edad. u 4. Ha de ser finito, es decir, debe finalizar tras la ejecuci´n de un n´mero finito de o u pasos, cada uno de los cuales ha de ser ejecutable en tiempo finito. 5. Debe ser efectivo, es decir, cada uno de sus pasos ha de poder ejecutarse en tiempo finito con unos recursos determinados (en nuestro caso, con los que proporciona un sistema computador). Adem´s, nos interesa que los algoritmos sean eficientes, esto es, que alcancen su aobjetivo lo m´s r´pidamente posible y con el menor consumo de recursos. a a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 9 Dise˜a un algoritmo para calcular el area de un c´ n ´ ırculo dado su radio. (Recuerdaque el area de un c´ ´ ırculo es π veces el cuadrado del radio.)Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 23 23 Introducción a la programación con Python - UJIUJI c
    • · 10 Dise˜a un algoritmo que calcule el IVA (16%) de un producto dado su precio de nventa sin IVA.· 11 ¿Podemos llamar algoritmo a un procedimiento que escriba en una cinta de papeltodos los n´meros decimales de π? u ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 24 24 Introducción a la programación con Python - UJIUJI c
    • Cap´ ıtulo 2Una calculadora avanzada ¿Sabes sumar? le pregunt´ la Reina Blanca. ¿Cu´nto es uno m´s uno o a a m´s uno m´s uno m´s uno m´s uno m´s uno m´s uno m´s uno m´s uno m´s a a a a a a a a a uno? No lo s´ dijo Alicia. Perd´ la cuenta. e ı No sabe hacer una adici´n le interrumpi´ la Reina Roja. o o LEWIS CARROLL, Alicia a trav´s del espejo. eEl objetivo de este tema es que te familiarices con el entorno interactivo de Python,que aprendas a construir expresiones aritm´ticas almacenando los resultados en varia- ebles mediante asignaciones y que conozcas los tipos de datos b´sicos del lenguaje de aprogramaci´n Python. o2.1. Sesiones interactivasCuando programamos utilizamos un conjunto de herramientas al que denominamos entornode programaci´n. Entre estas herramientas tenemos editores de texto (que nos permiten oescribir programas), compiladores o int´rpretes (que traducen los programas a c´digo e ode m´quina), depuradores (que ayudan a detectar errores), analizadores de tiempo de aejecuci´n (para estudiar la eficiencia de los programas), etc. o Los lenguajes interpretados suelen ofrecer una herramienta de ejecuci´n interactiva. oCon ella es posible dar ´rdenes directamente al int´rprete y obtener una respuesta in- o emediata para cada una de ellas. Es decir, no es necesario escribir un programa completopara empezar a obtener resultados de ejecuci´n, sino que podemos ˂˂dialogar˃˃ con el oint´rprete de nuestro lenguaje de programaci´n: le pedimos que ejecute una orden y nos e oresponde con su resultado. El entorno interactivo es de gran ayuda para experimentarcon fragmentos de programa antes de incluirlos en una versi´n definitiva. En esta secci´n o overemos c´mo realizar sesiones de trabajo interactivo con Python.1 o Si hemos instalado Python en nuestro ordenador podemos iniciar una sesi´n de otrabajo escribiendo python en la l´ ınea de ´rdenes Unix.2 El sistema nos responder´ o adando un mensaje informativo sobre la versi´n de Python que estamos utilizando (y ocu´ndo fue compilada, con qu´ compilador, etc.) y, a continuaci´n, mostrar´ el prompt: a e o a ↱$ pythonPython 2.3 (#1, Aug 2 2003, 12:14:49) 1 Abusando del lenguaje, llamaremos indistintamente Python al entorno de programaci´n, al int´rprete o edel lenguaje y al propio lenguaje de programaci´n. o 2 En el entorno Microsoft Windows puedes arrancar el int´rprete interactivo activando el icono correspon- ediente (que es una caricatura de una serpiente pit´n) o seleccionando el programa desde el men´ ˂˂Inicio˃˃. o u 25 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 25 Introducción a la programación con Python - UJI
    • [GCC 3.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> El prompt es la serie de caracteres ˂˂>>>˃˃ que aparece en la ultima l´ ´ ınea. El promptindica que el int´rprete de Python espera que nosotros introduzcamos una orden utili- ezando el teclado. La orden Unix python Hemos invocado el entorno interactivo escribiendo python en la l´ ınea de ´rdenes Unix o y pulsando el retorno de carro. Al hacer esto, el entorno de ejecuci´n de ´rdenes Unix o o (al que se suele denominar shell) busca en el ordenador una aplicaci´n llamada python o y la ejecuta. Esa aplicaci´n es un programa que lee una l´ o ınea introducida por teclado, la interpreta como si fuera un fragmento de programa Python y muestra por pantalla el resultado obtenido. (En realidad hace m´s cosas. Ya las iremos viendo.) a Por regla general, la aplicaci´n python reside en /usr/local/bin/ o en o /usr/bin/. Son directorios donde normalmente el shell busca programas. Si al es- cribir python y dar al retorno de carro no arranca el int´rprete, aseg´rate de que est´ e u a instalado el entorno Python. Si es as´ puedes intentar ejecutar el entorno dando la ruta ı, completa hasta el programa: por ejemplo /usr/local/bin/python. Escribamos una expresi´n aritm´tica, por ejemplo ˂˂2+2˃˃, y pulsemos la tecla de retorno o ede carro. Cuando mostremos sesiones interactivas destacaremos el texto que teclea elusuario con texto sobre fondo gris representaremos con el s´ ımbolo ˂˂ ˃˃ la pulsaci´n de o ↱la tecla de retorno de carro. Python eval´a la expresi´n (es decir, obtiene su resultado) u oy responde mostrando el resultado por pantalla. ↱$ pythonPython 2.3 (#1, Aug 2 2003, 12:14:49)[GCC 3.3] on linux2Type "help", "copyright", "credits" or "license" for more information. ↱>>> 2+24>>> La ultima l´ ´ ınea es, nuevamente, el prompt: Python acab´ de ejecutar la ultima orden o ´(evaluar una expresi´n y mostrar el resultado) y nos pide que introduzcamos una nueva oorden. Si deseamos acabar la sesi´n interactiva y salir del int´rprete Python, debemos o eintroducir una marca de final de fichero, que en Unix se indica pulsando la tecla decontrol y, sin soltarla, tambi´n la tecla d. (De ahora en adelante representaremos una ecombinaci´n de teclas como la descrita as´ C-d.) o ı:2.1.1. Los operadores aritm´ticos eLas operaciones de suma y resta, por ejemplo, se denotan con los s´ımbolos u operadores+ y -, respectivamente, y operan sobre dos valores num´ricos (los operandos). Probemos ealgunas expresiones formadas con estos dos operadores: ↱>>> 1 + 23 ↱>>> 1 + 2 + 36 ↱>>> 1 - 2 + 32Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 2626 c UJI Introducción a la programación con Python - UJI
    • Final de fichero La ˂˂marca de final de fichero˃˃ indica que un fichero ha terminado. ¡Pero nosotros no trabajamos con un fichero, sino con el teclado! En realidad, el ordenador considera al teclado como un fichero. Cuando deseamos ˂˂cerrar el teclado˃˃ para una aplicaci´n, o enviamos una marca de final de fichero desde el teclado. En Unix, la marca de final de fichero se env´ pulsando C-d; en MS-DOS o Microsoft Windows, pulsando C-z. ıa Existe otro modo de finalizar la sesi´n; escribe o ↱ >>> from sys import exit ↱ >>> exit() En ingl´s, ˂˂exit˃˃ significa ˂˂salir˃˃. S´ pero, ¿qu´ significa ˂˂from sys import exit˃˃ y e ı e por qu´ hay un par de par´ntesis detr´s de la palabra ˂˂exit˃˃ en la segunda l´ e e a ınea? M´s a adelante lo averiguaremos. Observa que puedes introducir varias operaciones en una misma l´ ınea o expresi´n. oEl orden en que se efect´an las operaciones es (en principio) de izquierda a derecha. uLa expresi´n 1 - 2 + 3, por ejemplo, equivale matem´ticamente a ((1 − 2) + 3); por ello o adecimos que la suma y la resta son operadores asociativos por la izquierda. Podemos representar gr´ficamente el orden de aplicaci´n de las operaciones utili- a ozando arboles sint´cticos. Un arbol sint´ctico es una representaci´n gr´fica en la que ´ a ´ a o adisponemos los operadores y los operandos como nodos y en los que cada operador est´ aconectado a sus operandos. El arbol sint´ctico de la expresi´n ˂˂1 - 2 + 3˃˃ es ´ste: ´ a o e + - 3 1 2 El nodo superior de un arbol recibe el nombre de nodo ra´ Los nodos etiquetados ´ ız.con operadores (representados con c´ ırculos) se denominan nodos interiores. Los nodosinteriores tienen uno o m´s nodos hijo o descendientes (de los que ellos son sus res- apectivos nodos padre o ascendientes). Dichos nodos son nodos ra´ de otros (sub)´rboles ız asint´cticos (¡la definici´n de arbol sint´ctico es auto-referencial!). Los valores resultantes a o ´ ade evaluar las expresiones asociadas a dichos (sub)´rboles constituyen los operandos de ala operaci´n que representa el nodo interior. Los nodos sin descendientes se denomi- onan nodos terminales u hojas (representados con cuadrados) y corresponden a valoresnum´ricos. e La evaluaci´n de cada operaci´n individual en el arbol sint´ctico ˂˂fluye˃˃ de las hojas o o ´ ahacia la ra´ (el nodo superior); es decir, en primer lugar se eval´a la subexpresi´n ˂˂1 - 2˃˃, ız u oque corresponde al sub´rbol m´s profundo. El resultado de la evaluaci´n es −1: a a o + −1 - 3 1 2A continuaci´n se eval´a la subexpresi´n que suma el resultado de evaluar ˂˂1 - 2˃˃ al o u ovalor 3:Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 27 27 Introducción a la programación con Python - cUJI UJI
    • 2 + −1 - 3 1 2As´ se obtiene el resultado final: el valor 2. ı Si deseamos calcular (1−(2+3)) podemos hacerlo a˜adiendo par´ntesis a la expresi´n n e oaritm´tica: e ↱>>> 1 - (2 + 3)-4 El arbol sint´ctico de esta nueva expresi´n es ´ a o - 1 + 2 3En este nuevo arbol, la primera subexpresi´n evaluada es la que corresponde al sub´rbol ´ o aderecho. Observa que en el arbol sint´ctico no aparecen los par´ntesis de la expresi´n. El arbol ´ a e o ´sint´ctico ya indica el orden en que se procesan las diferentes operaciones y no necesita apar´ntesis. La expresi´n Python, sin embargo, necesita los par´ntesis para indicar ese e o emismo orden de evaluaci´n.o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 12 ¿Qu´ expresiones Python permiten, utilizando el menor n´mero posible de par´ntesis, e u eefectuar en el mismo orden los c´lculos representados con estos arboles sint´cticos? a ´ a + + - 4 + 1 - + 3 - + 2 + 1 2 1 2 3 4 3 4 a) b) c)· 13 Dibuja los arboles sint´cticos correspondientes a las siguientes expresiones arit- ´ am´ticas: ea) 1 + 2 + 3 + 4 b) 1 - 2 - 3 - 4 c) 1 - (2 - (3 - 4) + 1) .................................................................................. Los operadores de suma y resta son binarios, es decir, operan sobre dos operandos. Elmismo s´ımbolo que se usa para la resta se usa tambi´n para un operador unario, es decir, eun operador que act´a sobre un unico operando: el de cambio de signo, que devuelve el u ´valor de su operando cambiado de signo. He aqu´ algunos ejemplos: ıIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 2828 c Introducción a la programación con Python - UJIUJI
    • Espacios en blanco Parece que se puede hacer un uso bastante liberal de los espacios en blanco en una expresi´n. o ↱ >>> 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´mero. u ↱ >>> 10 + 2 0 + 30 Los espacios en blanco entre el 2 y el 0 hacen que Python no lea el n´mero 20, u sino el n´mero 2 seguido del n´mero 0 (lo cual es un error, pues no hay operaci´n u u o alguna entre ambos n´meros). u No puedes poner espacios al principio de la expresi´n. o ↱ >>> 10 + 20 + 30 Los espacios en blanco entre el prompt y el 10 provocan un error. A´n es pronto u para que conozcas la raz´n. o ↱>>> -3-3 ↱>>> -(1 + 2)-3 ↱>>> --33 He aqu´ los arboles sint´cticos correspondientes a las tres expresiones del ejemplo: ı ´ a - - - + - 3 1 2 3 Existe otro operador unario que se representa con el s´ ımbolo +: el operador identidad.El operador identidad no hace nada ˂˂´til˃˃: proporciona como resultado el mismo n´mero u uque se le pasa. ↱>>> +33 ↱>>> +-3-3Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 29 29 Introducción a la programación con Python - UJI c UJI
    • El operador identidad s´lo sirve para, en ocasiones, poner ´nfasis en que un n´mero o e ues positivo. (El ordenador considera tan positivo el n´mero 3 como el resultado de evaluar u+3.) Los operadores de multiplicaci´n y divisi´n son, respectivamente, * y /: o o ↱>>> 2*36 ↱>>> 4/22 ↱>>> 3*4/26 ↱>>> 12 / 3 * 28 Observa que estos operadores tambi´n son asociativos por la izquierda: la expresi´n e o 3·4˂˂3 * 4 / 2˃˃ equivale a ((3 · 4)/2) = 2 , es decir, tiene el siguiente arbol sint´ctico: ´ a / * 2 3 4 12y la expresi´n 12 / 3 * 2 equivale a ((12/3) · 2) = o 3 · 2, o sea, su arbol sint´ctico es: ´ a * / 2 12 3 ¿Qu´ pasa si combinamos en una misma expresi´n operadores de suma o resta con e ooperadores de multiplicaci´n o divisi´n? F´ o o ıjate en que la regla de aplicaci´n de operadores ode izquierda a derecha no siempre se observa: ↱>>> 2 * 4 + 513 ↱>>> 2 + 4 * 522 En la segunda expresi´n, primero se ha efectuado el producto 4 * 5 y el resultado ose ha sumado al valor 2. Ocurre que los operadores de multiplicaci´n y divisi´n son o oprioritarios frente a los de suma y resta. Decimos que la multiplicaci´n y la divisi´n o otienen mayor nivel de precedencia o prioridad que la suma y la resta. El arbol sint´ctico de 2 * 4 + 5 es: ´ a + * 5 2 4y el de 2 + 4 * 5 es:Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 30 30 Introducción a la programación con Python - UJI c UJI
    • + 2 * 4 5 Pero, ¡atenci´n!, el cambio de signo tiene mayor prioridad que la multiplicaci´n y la o odivisi´n: o ↱>>> -2 * 2-4 ↱>>> --2 * 24Los arboles sint´cticos correspondientes a estas dos expresiones son, respectivamente: ´ a * * - 2 - 2 2 - 2 Si los operadores siguen unas reglas de precedencia que determinan su orden deaplicaci´n, ¿qu´ hacer cuando deseamos un orden de aplicaci´n distinto? Usar par´ntesis, o e o ecomo hacemos con la notaci´n matem´tica convencional. o a La expresi´n 2 * (4 + 5), por ejemplo, presenta este arbol sint´ctico: o ´ a * 2 + 4 5 Comprob´moslo con el int´rprete: e e ↱>>> 2 * (4 + 5)18 Existen m´s operadores en Python. Tenemos, por ejemplo, el operador m´dulo, que a ose denota con el s´ımbolo de porcentaje % (aunque nada tiene que ver con el c´lculo ade porcentajes). El operador m´dulo devuelve el resto de la divisi´n entera entre dos o ooperandos. ↱>>> 27 % 52 ↱>>> 25 % 50 El operador % tambi´n es asociativo por la izquierda y su prioridad es la misma que ela de la multiplicaci´n o la divisi´n. o o El ultimo operador que vamos a estudiar es la exponenciaci´n, que se denota con dos ´ oasteriscos juntos, no separados por ning´n espacio en blanco: **. u Lo que en notaci´n matem´tica convencional expresamos como 23 se expresa en Py- o athon con 2 ** 3.Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 31 31 c UJI Introducción a la programación con Python - UJI
    • ↱>>> 2 ** 38 Pero, ¡ojo!, la exponenciaci´n es asociativa por la derecha. La expresi´n 2 ** 3 ** o o2 equivale a 2 (32 ) = 29 = 512, y no a (23 )2 = 82 = 64, o sea, su arbol sint´ctico es: a ´ ** 2 ** 3 2 Por otra parte, la exponenciaci´n tiene mayor precedencia que cualquiera de los otros ooperadores presentados. He aqu´ varias expresiones evaluadas con Python y sus correspondientes arboles ı ´sint´cticos. Est´dialos con atenci´n: a u o ↱ +>>> 2 + 3 ** 2 * 547 2 * ** 5 3 2 ↱ +>>> 2 + ((3 ** 2) * 5)47 2 * ** 5 3 2 ↱ +>>> 2 + 3 ** (2 * 5)59051 2 ** 3 * 2 5 ↱ ->>> -3 ** 2-9 ** 3 2Introducci´n a la programaci´n con Python o o 32 32 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • ↱ ->>> -1-1 1 La tabla 2.1 resume las caracter´ısticas de los operadores Python: su aridad (n´mero ude operandos), asociatividad y precedencia. Operaci´n o Operador Aridad Asociatividad Precedencia Exponenciaci´n o ** Binario Por la derecha 1 ............................................................................ Identidad + Unario  2 Cambio de signo - Unario  2 ............................................................................ Multiplicaci´n o * Binario Por la izquierda 3 Divisi´n o / Binario Por la izquierda 3 M´dulo (o resto) o % Binario Por la izquierda 3 ............................................................................ Suma + Binario Por la izquierda 4 Resta - Binario Por la izquierda 4 Tabla 2.1: Operadores para expresiones aritm´ticas. El nivel de precedencia 1 es el de e mayor prioridad y el 4 el de menor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 14 ¿Qu´ resultados se obtendr´n al evaluar las siguientes expresiones Python? e aDibuja el arbol sint´ctico de cada una de ellas, calcula a mano el valor resultante de ´ acada expresi´n y comprueba, con la ayuda del ordenador, si tu resultado es correcto. oa) 2 + 3 + 1 + 2 c) (2 + 3) * 1 + 2 e) +---6b) 2 + 3 * 1 + 2 d) (2 + 3) * (1 + 2) f) -+-+6· 15 Traduce las siguientes expresiones matem´ticas a Python y eval´alas. Trata de a uutilizar el menor n´mero de par´ntesis posible. u ea) 2 + (3 · (6/2)) c) (4/2)5 e) (−3)2 4+6b) d) (4/2)5+1 f) −(32 ) 2+3(Nota: El resultado de evaluar cada expresi´n es: a) 11; b) 2; c) 32; d) 64; e) 9; f) −9.) o ..................................................................................2.1.2. Errores de tecleo y excepcionesCuando introducimos una expresi´n y damos la orden de evaluarla, es posible que nos oequivoquemos. Si hemos formado incorrectamente una expresi´n, Python nos lo indicar´ o acon un mensaje de error. El mensaje de error proporciona informaci´n acerca del tipo de oerror cometido y del lugar en el que ´ste ha sido detectado. Aqu´ tienes una expresi´n e ı oerr´nea y el mensaje de error correspondiente: o ↱>>> 1 + 2) File "<stdin>", line 1 1 + 2)Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 3333 c Introducción a la programación con Python - UJIUJI
    • ˆSyntaxError: invalid syntax En este ejemplo hemos cerrado un par´ntesis cuando no hab´ otro abierto previa- e ıamente, lo cual es incorrecto. Python nos indica que ha detectado un error de sintaxis(SyntaxError) y ˂˂apunta˃˃ con una flecha (el car´cter ˆ) al lugar en el que se encuentra. a(El texto ˂˂File "<stdin> ", line 1˃˃ indica que el error se ha producido al leer deteclado, esto es, de la entrada est´ndar stdin es una abreviatura del ingl´s ˂˂standard a einput˃˃, que se traduce por ˂˂entrada est´ndar˃˃.) a En Python los errores se denominan excepciones. Cuando Python es incapaz deanalizar una expresi´n, produce una excepci´n. Cuando el int´rprete interactivo detecta o o ela excepci´n, nos muestra por pantalla un mensaje de error. o Veamos algunos otros errores y los mensajes que produce Python. ↱>>> 1 + * 3 File "<stdin>", line 1 1 + * 3 ˆSyntaxError: invalid syntax ↱>>> 2 + 3 % File "<stdin>", line 1 2 + 3 % ˆSyntaxError: invalid syntax ↱>>> 1 / 0Traceback (innermost last): File "<stdin>", line 1, in ?ZeroDivisionError: integer division or modulo En el ejemplo, el ultimo error es de naturaleza distinta a los anteriores (no hay ´un car´cter ˆ apuntando a lugar alguno): se trata de un error de divisi´n por cero a o(ZeroDivisionError), cuando los otros eran errores sint´cticos (SyntaxError). La canti- adad que resulta de dividir por cero no est´ definida y Python es incapaz de calcular un avalor como resultado de la expresi´n 1 / 0. No es un error sint´ctico porque la expresi´n o a oest´ sint´cticamente bien formada: el operador de divisi´n tiene dos operandos, como a a otoca. Edici´n avanzada en el entorno interactivo o Cuando estemos escribiendo una expresi´n puede que cometamos errores y los detec- o temos antes de solicitar su evaluaci´n. A´n estaremos a tiempo de corregirlos. La tecla o u de borrado, por ejemplo, elimina el car´cter que se encuentra a la izquierda del cursor. a Puedes desplazar el cursor a cualquier punto de la l´ınea que est´s editando utilizando a las teclas de desplazamiento del cursor a izquierda y a derecha. El texto que teclees se insertar´ siempre justo a la izquierda del cursor. a Hasta el momento hemos tenido que teclear desde cero cada expresi´n evaluada, aun o cuando muchas se parec´ bastante entre s´ Podemos teclear menos si aprendemos a ıan ı. utilizar algunas funciones de edici´n avanzadas. o Lo primero que hemos de saber es que el int´rprete interactivo de Python memo- e riza cada una de las expresiones evaluadas en una sesi´n interactiva por si deseamos o recuperarlas m´s tarde. La lista de expresiones que hemos evaluado constituye la his- a toria de la sesi´n interactiva. Puedes ˂˂navegar˃˃ por la historia utilizando la teclas o de desplazamiento de cursor hacia arriba y hacia abajo. Cada vez que pulses la tecla de desplazamiento hacia arriba recuperar´s una expresi´n m´s antigua. La tecla de a o a desplazamiento hacia abajo permite recuperar expresiones m´s recientes. La expresi´n a o recuperada aparecer´ ante el prompt y podr´s modificarla a tu antojo. a aIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 3434 c UJI Introducción a la programación con Python - UJI
    • 2.2. Tipos de datosVamos a efectuar un experimento de resultado curioso: ↱>>> 3 / 21 ¡El resultado de dividir 3 entre 2 no deber´ ser 1, sino 1.5!3 ¿Qu´ ha pasado? ¿Se ha ıa eequivocado Python? No. Python ha actuado siguiendo unas reglas precisas en las queparticipa un nuevo concepto: el de tipo de dato.2.2.1. Enteros y flotantesCada valor utilizado por Python es de un tipo determinado. Hasta el momento s´lo hemos outilizado datos de tipo entero, es decir, sin decimales. Cuando se efect´a una operaci´n, u oPython tiene en cuenta el tipo de los operandos a la hora de producir el resultado. Silos dos operandos son de tipo entero, el resultado tambi´n es de tipo entero, as´ que la e ıdivisi´n entera entre los enteros 3 y 2 produce el valor entero 1. o Si deseamos obtener resultados de tipo real, deberemos usar operandos reales. Losoperandos reales deben llevar, en principio, una parte decimal, aunque ´sta sea nula. e ↱>>> 3.0 / 2.01.5 Hay diferencias entre enteros y reales en Python m´s all´ de que los primeros no a atengan decimales y los segundos s´ El n´mero 3 y el n´mero 3.0, por ejemplo, son ı. u uindistinguibles en matem´ticas, pero s´ son diferentes en Python. ¿Qu´ diferencias hay? a ı e Los enteros suelen ocupar menos memoria. Las operaciones entre enteros son, generalmente, m´s r´pidas. a aAs´ pues, utilizaremos enteros a menos que de verdad necesitemos n´meros con decimales. ı u Hemos de precisar algo respecto a la denominaci´n de los n´meros con decimales: o uel t´rmino ˂˂reales˃˃ no es adecuado, ya que induce a pensar en los n´meros reales de e ulas matem´ticas. En matem´ticas, los n´meros reales pueden presentar infinitos decima- a a ules, y eso es imposible en un computador. Al trabajar con computadores tendremos queconformarnos con meras aproximaciones a los n´meros reales. u Recuerda que todo en el computador son secuencias de ceros y unos. Deberemos,pues, representar internamente con ellos las aproximaciones a los n´meros reales. Para ufacilitar el intercambio de datos, todos los computadores convencionales utilizan una mis-ma codificaci´n, es decir, representan del mismo modo las aproximaciones a los n´meros o ureales. Esta codificaci´n se conoce como ˂˂IEEE Standard 754 floating point˃˃ (que se pue- ode traducir por ˂˂Est´ndar IEEE 754 para coma flotante˃˃), as´ que llamaremos n´meros a ı uen formato de coma flotante o simplemente flotantes a los n´meros con decimales que upodemos representar con el ordenador. Un n´mero flotante debe especificarse siguiendo ciertas reglas. En principio, consta ude dos partes: mantisa y exponente. El exponente se separa de la mantisa con la letra˂˂e˃˃ (o ˂˂E˃˃). Por ejemplo, el n´mero flotante 2e3 (o 2E3) tiene mantisa 2 y exponente 3, uy representa al n´mero 2 · 103 , es decir, 2000. u 3 Una advertencia sobre convenios tipogr´ficos. En espa˜ol, la parte fraccionaria de un n´mero se separa a n ude la parte entera por una coma, y no por un punto. Sin embargo, la norma anglosajona indica que debeutilizarse el punto. Python sigue esta norma, as´ que el n´mero que en espa˜ol se denota como 1,5 debe ı u nescribirse como 1.5 para que Python lo interprete correctamente. En aras de evitar confusiones, utilizaremossiempre el punto como car´cter de separaci´n entre parte entera y fraccionaria de un n´mero. a o u Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 35 Introducción a la programación con Python - UJIIntroducci´n a la programaci´n con Python o o 35 c UJI
    • El exponente puede ser negativo: 3.2e-3 es 3.2·10−3 , o sea, 0.0032. Ten en cuenta quesi un n´mero flotante no lleva exponente debe llevar parte fraccionaria. ¡Ah! Un par de ureglas m´s: si la parte entera del n´mero es nula, el flotante puede empezar directamente a ucon un punto, y si la parte fraccionaria es nula, puede acabar con un punto. Veamos un parde ejemplos: el n´mero 0.1 se puede escribir tambi´n como .1; por otra parte, el n´mero u e u2.0 puede escribirse como 2., es decir, en ambos casos el cero es opcional. ¿Demasiadasreglas? No te preocupes, con la pr´ctica acabar´s record´ndolas. a a a IEEE Standard 754 Un n´mero en coma flotante presenta tres componentes: el signo, la mantisa y el ex- u ponente. He aqu´ un n´mero en coma flotante: −14.1 × 10−3 . El signo es negativo, la ı u mantisa es 14.1 y el exponente es −3. Los n´meros en coma flotante normalizada pre- u sentan una mantisa menor o igual que 10. El mismo n´mero de antes, en coma flotante u normalizada, es −1.41×10−2. Una notaci´n habitual para los n´meros en coma flotante o u sustituye el producto (×) y la base del exponente por la letra ˂˂e˃˃ o ˂˂E˃˃. Notar´ıamos con -1.41e-2 el n´mero del ejemplo. u Los flotantes de Python siguen la norma IEEE Standard 754. Es una codificaci´n o binaria y normalizada de los n´meros en coma flotante y, por tanto, con base 2 para u el exponente y mantisa de valor menor que 2. Usa 32 bits (precisi´n simple) o 64 o bits (precisi´n doble) para codificar cada n´mero. Python utiliza el formato de doble o u precisi´n. En el formato de precisi´n doble se reserva 1 bit para el signo del n´mero, 11 o o u para el exponente y 52 para la mantisa. Con este formato pueden representarse n´meros u tan pr´ximos a cero como 10−323 (322 ceros tras el punto decimal y un uno) o de valor o absoluto tan grande como 10308 . No todos los n´meros tienen una representaci´n exacta en el formato de coma flo- u o tante. Observa qu´ ocurre en este caso: e ↱ >>> 0.1 0.10000000000000001 La mantisa, que vale 1/10, no puede representarse exactamente. En binario obtenemos la secuencia peri´dica de bits o 0.0001100110011001100110011001100110011001100110011. . . No hay, pues, forma de representar 1/10 con los 52 bits del formato de doble precisi´n. o En base 10, los 52 primeros bits de la secuencia nos proporcionan el valor 0.1000000000000000055511151231257827021181583404541015625. Es lo m´s cerca de 1/10 que podemos estar. En pantalla, Python s´lo nos muestra sus a o primeros 17 decimales (con el redondeo correspondiente). Una peculiaridad adicional de los n´meros codificados con la norma IEEE 754 es u que su precisi´n es diferente seg´n el n´mero representado: cuanto m´s pr´ximo a ce- o u u a o ro, mayor es la precisi´n. Para n´meros muy grandes se pierde tanta precisi´n que o u o no hay decimales (¡ni unidades, ni decenas. . . !). Por ejemplo, el resultado de la su- ma 100000000.0+0.000000001 es 100000000.0, y no 100000000.000000001, como cabr´ ıa esperar. A modo de conclusi´n, has de saber que al trabajar con n´meros flotantes es posible o u que se produzcan peque˜os errores en la representaci´n de los valores y durante los n o c´lculos. Probablemente esto te sorprenda, pues es vox populi que ˂˂los ordenadores a nunca se equivocan˃˃. Es posible mezclar en una misma expresi´n datos de tipos distintos. o ↱>>> 3.0 / 21.5Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 36 36 Introducción a la programación con Python - UJI c UJI
    • Python sigue una regla sencilla: si hay datos de tipos distintos, el resultado es deltipo ˂˂m´s general˃˃. Los flotantes son de tipo ˂˂m´s general˃˃ que los enteros. a a ↱>>> 1 + 2 + 3 + 4 + 5 + 6 + 0.521.5 ↱>>> 1 + 2 + 3 + 4 + 5 + 6 + 0.021.0 Pero, ¡atenci´n!, puede parecer que la regla no se observa en este ejemplo: o ↱>>> 1.0 + 3 / 22.0 El resultado debiera haber sido 2.5, y no 2.0. ¿Qu´ ha pasado? Python eval´a la e uexpresi´n paso a paso. Analicemos el arbol sint´ctico de esa expresi´n: o ´ a o + flotante 2.0 1.0 / entero 1 3 2La divisi´n es prioritaria frente a la suma, por lo que ´sta se lleva a cabo en primer lugar. o eLa divisi´n tiene dos operandos, ambos de tipo entero, as´ que produce un resultado de o ıtipo entero: el valor 1. La suma recibe, pues, un operando flotante (el de su izquierda)de valor 1.0, y otro entero (el que resulta de la divisi´n), de valor 1. El resultado es un oflotante y su valor es 2.0. ¿Qu´ pasar´ si ejecut´ramos 1 + 3 / 2.0? e ıa a ↱>>> 1 + 3 / 2.02.5 El arbol sint´ctico es, en este caso, ´ a + flotante 2.5 1 / flotante 1.5 3 2.0 As´ pues, la divisi´n proporciona un resultado flotante, 1.5, que al ser sumado al entero ı o1 de la izquierda proporciona un nuevo flotante: 2.5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 16 ¿Qu´ resultar´ de evaluar las siguientes expresiones? Presta especial atenci´n e a oal tipo de datos que resulta de cada operaci´n individual. Haz los c´lculos a manoo aayud´ndote con arboles sint´cticos y comprueba el resultado con el ordenador. a ´ aa) 1 / 2 / 4.0 f) 4.0 ** (1 / 2)b) 1 / 2.0 / 4.0 g) 4.0 ** (1 / 2) + 1 / 2c) 1 / 2.0 / 4 h) 4.0 ** (1.0 / 2) + 1 / 2.0d) 1.0 / 2 / 4 i) 3e3 / 10e) 4 ** .5 j) 10 / 5e-3Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 37 37 Introducción a la programación con Python - UJIUJI c
    • k) 10 / 5e-3 + 1 l) 3 / 2 + 1 ..................................................................................2.2.2. Valores l´gicos oDesde la versi´n 2.3, Python ofrece un tipo de datos especial que permite expresar os´lo dos valores: cierto y falso. El valor cierto se expresa con True y el valor falso con oFalse. Son los valores l´gicos o booleanos. Este ultimo nombre deriva del nombre de un o ´matem´tico, Boole, que desarroll´ un sistema algebraico basado en estos dos valores y a otres operaciones: la conjunci´n, la disyunci´n y la negaci´n. Python ofrece soporte para o o oestas operaciones con los operadores l´gicos. o2.3. Operadores l´gicos y de comparaci´n o oHay tres operadores l´gicos en Python: la ˂˂y l´gica˃˃ o conjunci´n (and), la ˂˂o l´gica˃˃ o o o o odisyunci´n (or) y el ˂˂no l´gico˃˃ o negaci´n (not). o o o El operador and da como resultado el valor cierto si y s´lo si son ciertos sus dos ooperandos. Esta es su tabla de verdad: and operandos resultado izquierdo derecho True True True True False False False True False False False False El operador or proporciona True si cualquiera de sus operandos es True, y False s´lo ocuando ambos operandos son Falses. Esta es su tabla de verdad: or operandos resultado izquierdo derecho True True True True False True False True True False False False El operador not es unario, y proporciona el valor True si su operando es False yviceversa. He aqu´ su tabla de verdad: ı not operando resultado True False False True Podemos combinar valores l´gicos y operadores l´gicos para formar expresiones o ol´gicas. He aqu´ algunos ejemplos: o ıIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 38 38 Introducción a la programación con Python - c UJI UJI
    • ↱>>> True and FalseFalse ↱>>> not TrueFalse ↱>>> (True and False) or TrueTrue ↱>>> True and True or FalseTrue ↱>>> False and True or TrueTrue ↱>>> False and True or FalseFalse Has de tener en cuenta la precedencia de los operadores l´gicos: o Operaci´n o Operador Aridad Asociatividad Precedencia Negaci´n o not Unario  alta ............................................................................ Conjunci´n o and Binario Por la izquierda media ............................................................................ Disyunci´n o or Binario Por la izquierda baja Tabla 2.2: Aridad, asociatividad y precedencia de los operadores l´gicos. o Del mismo modo que hemos usado arboles sint´cticos para entender el proceso de ´ ac´lculo de los operadores aritm´ticos sobre valores enteros y flotantes, podemos recurrir a ea ellos para interpretar el orden de evaluaci´n de las expresiones l´gicas. He aqu´ el o o ıarbol sint´ctico de la expresi´n True or False and not False:´ a o or True True and False False not True False Hay una familia de operadores que devuelven valores booleanos. Entre ellos tenemosa los operadores de comparaci´n, que estudiamos en este apartado. Uno de ellos es el ooperador de igualdad, que devuelve True si los valores comparados son iguales. El ope-rador de igualdad se denota con dos iguales seguidos: ==. Ve´moslo en funcionamiento: a ↱>>> 2 == 3False ↱>>> 2 == 2True ↱>>> 2.1 == 2.1True ↱>>> True == TrueTrue ↱>>> True == FalseFalse ↱>>> 2 == 1+1TrueIntroducci´n a la programaci´n con Python o o 39 39 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • Observa la ultima expresi´n evaluada: es posible combinar operadores de comparaci´n ´ o oy operadores aritm´ticos. No s´lo eso, tambi´n podemos combinar en una misma expresi´n e o e ooperadores l´gicos, aritm´ticos y de comparaci´n: o e o ↱>>> (True or (2 == 1 + 2)) == TrueTrue Este es el arbol sint´ctico correspondiente a esa expresi´n: ´ a o == booleano True or booleano True True True == booleano False 2 + entero 3 1 2Hemos indicado junto a cada nodo interior el tipo del resultado que corresponde a susub´rbol. Como ves, en todo momento operamos con tipos compatibles entre s´ a ı. Antes de presentar las reglas de asociatividad y precedencia que son de aplicaci´n oal combinar diferentes tipos de operador, te presentamos todos los operadores de compa-raci´n en la tabla 2.3 y te mostramos algunos ejemplos de uso4 : o operador comparaci´n o == es igual que != es distinto de < es menor que <= es menor o igual que > es mayor que >= es mayor o igual que Tabla 2.3: Operadores de comparaci´n. o ↱>>> 2 <1False ↱>>> 1 <2True ↱>>> 5 >1True ↱>>> 5 >= 1True ↱>>> 5 >5False ↱>>> 5 >= 5True ↱>>> 1 != 0True ↱>>> 1 != 1 4 Hay una forma alternativa de notar la comparaci´n ˂˂es distinto de˃˃: tambi´n puedes usar el s´ o e ımbolo<>. La comparaci´n de desigualdad en el lenguaje de programaci´n C se denota con != y en Pascal con <>. o oPython permite usar cualquiera de los dos s´ ımbolos. En este texto s´lo usaremos el primero. oIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 40 40 Introducción a la programación con Python - UJI c UJI
    • False ↱>>> -2 <= 2True Es hora de que presentemos una tabla completa (tabla 2.4) con todos los operadoresque conocemos para comparar entre s´ la precedencia de cada uno de ellos cuando aparece ıcombinado con otros. Operaci´n o Operador Aridad Asociatividad Precedencia Exponenciaci´n o ** Binario Por la derecha 1 ...................................................................... Identidad + Unario  2 Cambio de signo - Unario  2 ...................................................................... Multiplicaci´no * Binario Por la izquierda 3 Divisi´n o / Binario Por la izquierda 3 M´dulo (o resto) o % Binario Por la izquierda 3 ...................................................................... Suma + Binario Por la izquierda 4 Resta - Binario Por la izquierda 4 ...................................................................... Igual que == Binario  5 Distinto de != Binario  5 Menor que < Binario  5 Menor o igual que <= Binario  5 Mayor que > Binario  5 Mayor o Igual que >= Binario  5 ...................................................................... Negaci´no not Unario  6 ...................................................................... Conjunci´no and Binario Por la izquierda 7 ...................................................................... Disyunci´no or Binario Por la izquierda 8 Tabla 2.4: Caracter´ ısticas de los operadores Python. El nivel de precedencia 1 es el de mayor prioridad. En la tabla 2.4 hemos omitido cualquier referencia a la asociatividad de los compara-dores de Python, pese a que son binarios. Python es un lenguaje peculiar en este sentido.Imaginemos que fueran asociativos por la izquierda. ¿Qu´ significar´ esto? El opera- e ıador suma, por ejemplo, es asociativo por la izquierda. Al evaluar la expresi´n aritm´tica o e2 + 3 + 4 se procede as´ primero se suma el 2 al 3; a continuaci´n, el 5 resultante se ı: osuma al 4, resultando un total de 9. Si el operador < fuese asociativo por la izquierda, laexpresi´n l´gica 2 < 3 < 4 se evaluar´ as´ primero, se compara el 2 con el 3, resultando el o o ıa ı:valor True; a continuaci´n, se compara el resultado obtenido con el 4, pero ¿qu´ significa o ela expresi´n True < 4? No tiene sentido. o Cuando aparece una sucesi´n de comparadores como, por ejemplo, 2 < 3 < 4, Python ola eval´a igual que (2 < 3) and (3 < 4). Esta soluci´n permite expresar condiciones com- u oplejas de modo sencillo y, en casos como el de este ejemplo, se lee del mismo modo quese leer´ con la notaci´n matem´tica habitual, lo cual parece deseable. Pero ¡ojo! Python ıa o apermite expresiones que son m´s extra˜as; por ejemplo, 2 < 3 > 1, o 2 < 3 == 5. a n. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 17 ¿Qu´ resultados se muestran al evaluar estas expresiones? eIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 4141 c Introducción a la programación con Python - UJIUJI
    • Una rareza de Python: la asociatividad de los comparadores Algunos lenguajes de programaci´n de uso com´n, como C y C++, hacen que sus o u operadores de comparaci´n sean asociativos, por lo que presentan el problema de que o expresiones como 2 < 1 < 4 producen un resultado que parece il´gico. Al ser asociativo o por la izquierda el operador de comparaci´n <, se eval´a primero la subexpresi´n 2 < o u o 1. El resultado es falso, que en C y C++ se representa con el valor 0. A continuaci´n se o eval´a la comparaci´n 0 < 4, cuyo resultado es. . . ¡cierto! As´ pues, para C y C++ es u o ı cierto que 2 < 1 < 4. Pascal es m´s r´ a ıgido a´n y llega a prohibir expresiones como 2 < 1 < 4. En Pascal u hay un tipo de datos denominado boolean cuyos valores v´lidos son true y false. a Pascal no permite operar entre valores de tipos diferentes, as´ que la expresi´n 2 < 1 ı o se eval´a al valor booleano false, que no se puede comparar con un entero al tratar u de calcular el valor de false < 4. En consecuencia, se produce un error de tipos si intentamos encadenar comparaciones. La mayor parte de los lenguajes de programaci´n convencionales opta por la soluci´n o o del C o por la soluci´n del Pascal. Cuando aprendas otro lenguaje de programaci´n, te o o costar´ ˂˂deshabituarte˃˃ de la elegancia con que Python resuelve los encadenamientos a de comparaciones. ↱>>> True == True != False ↱>>> 1<2<3<4<5 ↱>>> (1 < 2 < 3) and (4 < 5) ↱>>> 1<2<4<3<5 ↱>>> (1 < 2 < 4) and (3 < 5) ..................................................................................2.4. Variables y asignacionesEn ocasiones deseamos que el ordenador recuerde ciertos valores para usarlos m´s ade- alante. Por ejemplo, supongamos que deseamos efectuar el c´lculo del per´ a ımetro y el area ´de un c´ırculo de radio 1.298373 m. La f´rmula del per´ o ımetro es 2πr, donde r es el radio,y la f´rmula del area es πr 2 . (Aproximaremos el valor de π con 3.14159265359.) Podemos o ´realizar ambos c´lculos del siguiente modo: a ↱>>> 2 * 3.14159265359 * 1.2983738.1579181568392176 ↱>>> 3.14159265359 * 1.298373 ** 25.2960103355249037 Observa que hemos tenido que introducir dos veces los valores de π y r por lo que, altener tantos decimales, es muy f´cil cometer errores. Para paliar este problema podemos autilizar variables: ↱>>> pi = 3.14159265359 ↱>>> r = 1.298373 ↱>>> 2 * pi * r8.1579181568392176 ↱>>> pi * r ** 25.2960103355249037 En la primera l´ınea hemos creado una variable de nombre pi y valor 3.14159265359.A continuaci´n, hemos creado otra variable, r, y le hemos dado el valor 1.298373. El acto ode dar valor a una variable se denomina asignaci´n. Al asignar un valor a una variable oIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 42 42 Introducción a la programación con Python - UJI c UJI
    • que no exist´ Python reserva un espacio en la memoria, almacena el valor en ´l y crea ıa, euna asociaci´n entre el nombre de la variable y la direcci´n de memoria de dicho espacio. o oPodemos representar gr´ficamente el resultado de estas acciones as´ a ı: pi 3.14159265359 r 1.298373 A partir de ese instante, escribir pi es equivalente a escribir 3.14159265359, y escribirr es equivalente a escribir 1.298373. Podemos almacenar el resultado de calcular el per´ ımetro y el area en sendas variables: ´ ↱>>> pi = 3.14159265359 ↱>>> r = 1.298373 ↱>>> perimetro = 2 * pi * r ↱>>> area = pi * r**2 pi 3.14159265359 r 1.298373 perimetro 8.1579181568392176 area 5.2960103355249037 La memoria se ha reservado correctamente, en ella se ha almacenado el valor corres-pondiente y la asociaci´n entre la memoria y el nombre de la variable se ha establecido, opero no obtenemos respuesta alguna por pantalla. Debes tener en cuenta que las asig-naciones son ˂˂mudas˃˃, es decir, no provocan salida por pantalla. Si deseamos ver cu´nto avale una variable, podemos evaluar una expresi´n que s´lo contiene a dicha variable: o o ↱>>> area5.2960103355249037 As´ pues, para asignar valor a una variable basta ejecutar una sentencia como ´sta: ı e variable = expresi´n oTen cuidado: el orden es importante. Hacer ˂˂expresi´n = variable˃˃ no es equivalente. oUna asignaci´n no es una ecuaci´n matem´tica, sino una acci´n consistente en (por este o o a oorden): 1. evaluar la expresi´n a la derecha del s´ o ımbolo igual (=), y 2. guardar el valor resultante en la variable indicada a la izquierda del s´ ımbolo igual. Se puede asignar valor a una misma variable cuantas veces se quiera. El efecto esque la variable, en cada instante, s´lo ˂˂recuerda˃˃ el ultimo valor asignado. . . hasta que o ´se le asigne otro. ↱>>> a=1 ↱>>> 2*a2 ↱>>> a+23 ↱>>> a=2 ↱>>> a*a4Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 43 43 Introducción a la programación con Python - UJI c UJI
    • == no es = (comparar no es asignar) Al aprender a programar, muchas personas confunden el operador de asignaci´n, =, con o el operador de comparaci´n, ==. El primero se usa exclusivamente para asignar un valor o a una variable. El segundo, para comparar valores. Observa la diferente respuesta que obtienes al usar = y == en el entorno interactivo: ↱ >>> a = 10 ↱ >>> a 10 ↱ >>> a == 1 False ↱ >>> a 10 Una asignaci´n no es una ecuaci´n o o Hemos de insistir en que las asignaciones no son ecuaciones matem´ticas, por mucho a que su aspecto nos recuerde a ´stas. F´ e ıjate en este ejemplo, que suele sorprender a aquellos que empiezan a programar: ↱ >>> x = 3 ↱ >>> x = x + 1 ↱ >>> x 4 La primera l´ ınea asigna a la variable x el valor 3. La segunda l´ ınea parece m´s a complicada. Si la interpretas como una ecuaci´n, no tiene sentido, pues de ella se o concluye absurdamente que 3 = 4 o, sustrayendo la x a ambos lados del igual, que 0 = 1. Pero si seguimos paso a paso las acciones que ejecuta Python al hacer una asignaci´n, la cosa cambia: o 1. Se eval´a la parte derecha del igual (sin tener en cuenta para nada la parte u izquierda). El valor de x es 3, que sumado a 1 da 4. 2. El resultado (el 4), se almacena en la variable que aparece en la parte izquierda del igual, es decir, en x. As´ pues, el resultado de ejecutar las dos primeras l´ ı ıneas es que x vale 4. El nombre de una variable es su identificador. Hay unas reglas precisas para construiridentificadores. Si no se siguen, diremos que el identificador no es v´lido. Un identifi- acador debe estar formado por letras5 min´sculas, may´sculas, d´ u u ıgitos y/o el car´cter de asubrayado (_), con una restricci´n: que el primer car´cter no sea un d´ o a ıgito. Hay una norma m´s: un identificador no puede coincidir con una palabra reservada o apalabra clave. Una palabra reservada es una palabra que tiene un significado predefinidoy es necesaria para expresar ciertas construcciones del lenguaje. Aqu´ tienes una lista ıcon todas las palabras reservadas de Python: and, assert, break, class, continue, def, del,elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass,print, raise, return, try, while y yield. Por ejemplo, los siguientes identificadores son v´lidos: h, x, Z , velocidad, aceleracion, ax, fuerza1, masa_ 2, _a, a_ , prueba_ 123, desviacion_tipica. Debes tener presente quePython distingue entre may´sculas y min´sculas, as´ que area, Area y AREA son tres u u ı 5 Exceptuando los s´ımbolos que no son propios del alfabeto ingl´s, como las vocales acentuadas, la letra e‘˜’, la letra ‘c’, etc.. n ¸Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 44 44 Introducción a la programación con Python - cUJI UJI
    • identificadores v´lidos y diferentes. a Cualquier car´cter diferente de una letra, un d´ a ıgito o el subrayado es inv´lido en un aidentificador, incluyendo el espacio en blanco. Por ejemplo, edad media (con un espacioen medio) son dos identificadores (edad y media), no uno. Cuando un identificador seforma con dos palabras, es costumbre de muchos programadores usar el subrayado parasepararlas: edad_media; otros programadores utilizan una letra may´scula para la inicial ude la segunda: edadMedia. Escoge el estilo que m´s te guste para nombrar variables, apero permanece fiel al que escojas. Dado que eres libre de llamar a una variable con el identificador que quieras, hazlocon clase: escoge siempre nombres que guarden relaci´n con los datos del problema. Si, opor ejemplo, vas a utilizar una variable para almacenar una distancia, llama a la variabledistancia y evita nombres que no signifiquen nada; de este modo, los programas ser´n am´s legibles. a. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 18 ¿Son v´lidos los siguientes identificadores? aa) Identificador g) desviaci´n o m) UnaVariable r) area ´b) Indicedos h) a˜o n n) a(b) s) area-rectc) Dos palabras i) from n) 12 ˜ t) x_______ 1d) __ j) var! o) uno.dos u) ________ 1e) 12horas k) ’var’ p) x v) _x_f) hora12 l) import_from q) π w) x_x· 19 ¿Qu´ resulta de ejecutar estas tres l´ e ıneas? ↱>>> x = 10 ↱>>> x = x * 10 ↱>>> x· 20 Eval´a el polinomio x 4 + x 3 + 2x 2 − x en x = 1.1. Utiliza variables para evitar uteclear varias veces el valor de x. (El resultado es 4.1151.)· 21 Eval´a el polinomio x 4 + x 3 + 1 x 2 − x en x = 10. Aseg´rate de que el resultado u 2 usea un n´mero flotante. (El resultado es 11040.0.) u ..................................................................................2.4.1. Asignaciones con operadorF´ıjate en la sentencia i = i + 1: aplica un incremento unitario al contenido de la variablei. Incrementar el valor de una variable en una cantidad cualquiera es tan frecuente queexiste una forma compacta en Python. El incremento de i puede denotarse as´ ı: ↱>>> i += 1 (No puede haber espacio alguno entre el + y el =.) Puedes incrementar una variablecon cualquier cantidad, incluso con una que resulte de evaluar una expresi´n: o ↱>>> a=3 ↱>>> b=2 ↱>>> a += 4 * b ↱>>> a11Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 45 45 Introducción a la programación con Python - UJIUJI c
    • Todos los operadores aritm´ticos tienen su asignaci´n con operador asociada. e oz += 2z *= 2z /= 2z -= 2z %= 2z **= 2 Hemos de decirte que estas formas compactas no aportan nada nuevo. . . salvo como-didad, as´ que no te preocupes por tener que aprender tantas cosas. Si te vas a sentir ıinc´modo por tener que tomar decisiones y siempre est´s pensando ˂˂¿uso ahora la forma o anormal o la compacta?˃˃, es mejor que ignores de momento las formas compactas.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 22 ¿Qu´ resultar´ de ejecutar las siguientes sentencias? e a ↱>>> z =2 ↱>>> z += 2 ↱>>> z += 2 - 2 ↱>>> z *= 2 ↱>>> z *= 1 + 1 ↱>>> z /= 2 ↱>>> z %= 3 ↱>>> z /= 3 - 1 ↱>>> z -= 2 + 1 ↱>>> z -= 2 ↱>>> z **= 3 ↱>>> z ..................................................................................2.4.2. Variables no inicializadasEn Python, la primera operaci´n sobre una variable debe ser la asignaci´n de un valor. o oNo se puede usar una variable a la que no se ha asignado previamente un valor: ↱>>> a + 2Traceback (most recent call last): File "<stdin>", line 1, in ?NameError: name ’a’ is not defined Como puedes ver, se genera una excepci´n NameError, es decir, de ˂˂error de nombre˃˃. oEl texto explicativo precisa a´n m´s lo sucedido: ˂˂name ’a’ is not defined˃˃, es decir, u a˂˂el nombre a no est´ definido˃˃. a La asignaci´n de un valor inicial a una variable se denomina inicializaci´n de la o ovariable. Decimos, pues, que en Python no es posible usar variables no inicializadas.2.5. El tipo de datos cadenaHasta el momento hemos visto que Python puede manipular datos num´ricos de dos tipos: eenteros y flotantes. Pero Python tambi´n puede manipular otros tipos de datos. Vamos a eestudiar ahora el tipo de datos que se denomina cadena. Una cadena es una secuenciade caracteres (letras, n´meros, espacios, marcas de puntuaci´n, etc.) y en Python se u odistingue porque va encerrada entre comillas simples o dobles. Por ejemplo, ’cadena’,’otro␣ejemplo’, "1,␣2␣1o␣3", ’ Si!’, "...Python" son cadenas. Observa que los !Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 46 46 Introducción a la programación con Python - UJIUJI c
    • ¡M´s operadores! a S´lo te hemos presentado los operadores que utilizaremos en el texto y que ya est´s o a preparado para manejar. Pero has de saber que hay m´s operadores. Hay operadores, a por ejemplo, que est´n dirigidos a manejar las secuencias de bits que codifican los a valores enteros. El operador binario & calcula la operaci´n ˂˂y˃˃ bit a bit, el operador o binario | calcula la operaci´n ˂˂o˃˃ bit a bit, el operador binario ˆ calcula la ˂˂o exclusiva˃˃ o (que devuelve cierto si y s´lo si los dos operandos son distintos), tambi´n bit a bit, y o e el operador unario ˜ invierte los bits de su operando. Tienes, adem´s, los operadores a binarios << y >>, que desplazan los bits a izquierda o derecha tantas posiciones como le indiques. Estos ejemplos te ayudar´n a entender estos operadores: a En decimal En binario Expresi´n Resultado o Expresi´n o Resultado 5 & 12 4 00000101 & 00001100 00000100 5 | 12 13 00000101 | 00001100 00001101 5 ˆ 12 9 00000101 ˆ 00001100 00001001 ˜5 -6 ˜00000101 11111010 5 << 1 10 00000101 << 00000001 00001010 5 << 2 20 00000101 << 00000010 00010100 5 << 3 40 00000101 << 00000011 00101000 5 >> 1 2 00000101 >> 00000010 00000010 ¡Y estos operadores presentan, adem´s, una forma compacta con asignaci´n: <<=, |=, a o etc.! M´s adelante estudiaremos, adem´s, los operadores is (e is not) e in (y not in), los a a operadores de indexaci´n, de llamada a funci´n, de corte. . . o oespacios en blanco se muestran as´ en este texto: ˂˂␣˃˃. Lo hacemos para que resulte f´cil ı acontar los espacios en blanco cuando hay m´s de uno seguido. Esta cadena, por ejemplo, aest´ formada por tres espacios en blanco: ’␣␣␣’. a Las cadenas pueden usarse para representar informaci´n textual: nombres de personas, onombres de colores, matr´ıculas de coche... Las cadenas tambi´n pueden almacenarse en evariables. ↱>>> nombre = ’Pepe’ ↱>>> nombre’Pepe’ nombre ’Pepe’ Es posible realizar operaciones con cadenas. Por ejemplo, podemos ˂˂sumar˃˃ cadenasa˜adiendo una a otra. n ↱>>> ’a’ + ’b’’ab’ ↱>>> nombre = ’Pepe’ ↱>>> nombre + ’Cano’’PepeCano’ ↱>>> nombre + ’␣’ + ’Cano’’Pepe Cano’ ↱>>> apellido = ’Cano’ ↱>>> nombre + ’␣’ + apellido’Pepe Cano’ Hablando con propiedad, esta operaci´n no se llama suma, sino concatenaci´n. El o os´ ımbolo utilizado es +, el mismo que usamos cuando sumamos enteros y/o flotantes; peroIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 47 47 Introducción a la programación con Python - UJI c UJI
    • Una cadena no es un identificador Con las cadenas tenemos un problema: muchas personas que est´n aprendiendo a pro- a gramar confunden una cadena con un identificador de variable y viceversa. No son la misma cosa. F´ ıjate bien en lo que ocurre: ↱ >>> a = 1 ↱ >>> ’a’ ’a’ ↱ >>> a 1 La primera l´ınea asigna a la variable a el valor 1. Como a es el nombre de una variable, es decir, un identificador, no va encerrado entre comillas. A continuaci´n hemos o escrito ’a’ y Python ha respondido tambi´n con ’a’: la a entre comillas es una cadena e formada por un unico car´cter, la letra ˂˂a˃˃, y no tiene nada que ver con la variable a. ´ a A continuaci´n hemos escrito la letra ˂˂a˃˃ sin comillas y Python ha respondido con el o valor 1, que es lo que contiene la variable a. Muchos estudiantes de programaci´n cometen errores como estos: o Quieren utilizar una cadena, pero olvidan las comillas, con lo que Python cree que se quiere usar un identificador; si ese identificador no existe, da un error: ↱ >>> Pepe Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name ’Pepe’ is not defined Quieren usar un identificador pero, ante la duda, lo encierran entre comillas: ↱ >>> ’x’ = 2 SyntaxError: can’t assign to literal Recuerda: s´lo se puede asignar valores a variables, nunca a cadenas, y las cadenas no o son identificadores.aunque el s´ımbolo sea el mismo, ten en cuenta que no es igual sumar n´meros que uconcatenar cadenas: ↱>>> ’12’ + ’12’’1212’ ↱>>> 12 + 1224 Sumar o concatenar una cadena y un valor num´rico (entero o flotante) produce un eerror: ↱>>> ’12’ + 12Traceback (innermost last): File "<stdin>", line 1, in ?TypeError: illegal argument type for built-in operation Y para acabar, hay un operador de repetici´n de cadenas. El s´ o ımbolo que lo denotaes *, el mismo que hemos usado para multiplicar enteros y/o flotantes. El operador derepetici´n necesita dos datos: uno de tipo cadena y otro de tipo entero. El resultado es la oconcatenaci´n de la cadena consigo misma tantas veces como indique el n´mero entero: o u ↱>>> ’Hola’ * 5’HolaHolaHolaHolaHola’Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 48 48 Introducción a la programación con Python - UJI c UJI
    • ↱>>> ’-’ * 60’------------------------------------------------------------’ ↱>>> 60 * ’-’’------------------------------------------------------------’. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 23 Eval´a estas expresiones y sentencias en el orden indicado: ua) a = ’b’b) a + ’b’c) a + ’a’d) a * 2 + ’b’ * 3e) 2 * (a + ’b’)· 24 ¿Qu´ resultados se obtendr´n al evaluar las siguientes expresiones y asignaciones e aPython? Calcula primero a mano el valor resultante de cada expresi´n y comprueba, con ola ayuda del ordenador, si tu resultado es correcto.a) ’a’ * 3 + ’/*’ * 5 + 2 * ’abc’ + ’+’b) palindromo = ’abcba’ (4 * ’<’ + palindromo + ’>’ * 4) * 2c) subcadena = ’=’ + ’-’ * 3 + ’=’ ’10’ * 5 + 4 * subcadenad) 2 * ’12’ + ’.’ + ’3’ * 3 + ’e-’ + 4 * ’76’· 25 Identifica regularidades en las siguientes cadenas, y escribe expresiones que,partiendo de subcadenas m´s cortas y utilizando los operadores de concatenaci´n y a orepetici´n, produzcan las cadenas que se muestran. Introduce variables para formar las oexpresiones cuando lo consideres oportuno.a) ’%%%%%./././<-><->’b) ’(@)(@)(@)======(@)(@)(@)======’c) ’asdfasdfasdf=-=-=-=-=-=-=-??????asdfasdf’d) ’........*****---*****---........*****---*****---’ .................................................................................. El concepto de comparaci´n entre n´meros te resulta familiar porque lo has estudiado o uantes en matem´ticas. Python extiende el concepto de comparaci´n a otros tipos de datos, a ocomo las cadenas. En el caso de los operadores == y != el significado est´ claro: dos acadenas son iguales si son iguales car´cter a car´cter, y distintas en caso contrario. a aPero, ¿qu´ significa que una cadena sea menor que otra? Python utiliza un criterio de ecomparaci´n de cadenas muy natural: el orden alfab´tico. En principio, una cadena es o emenor que otra si la precede al disponerlas en un diccionario. Por ejemplo, ’abajo’ esmenor que ’arriba’. ¿Y c´mo se comparan cadenas con caracteres no alfab´ticos? Es decir, ¿es ’@@’ o emenor o mayor que ’abc’? Python utiliza los c´digos ASCII de los caracteres para odecidir su orden alfab´tico (ver tablas en ap´ndice A). Para conocer el valor num´rico e e eque corresponde a un car´cter, puedes utilizar la funci´n predefinida ord, a la que le has a ode pasar el car´cter en cuesti´n como argumento. a oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 49 49 Introducción a la programación con Python - UJIUJI c
    • Otros tipos de datos Python posee un rico conjunto de tipos de datos. Algunos, como los tipos de datos estructurados, se estudiar´n con detalle m´s adelante. Sin embargo, y dado el car´cter a a a introductorio de este texto, no estudiaremos con detalle otros dos tipos b´sicos: los a n´meros enteros ˂˂largos˃˃ y los n´meros complejos. Nos limitaremos a presentarlos u u sucintamente. El rango de los n´meros flotantes puede resultar insuficiente para ciertas aplicacio- u nes. Python ofrece la posibilidad de trabajar con n´meros con un n´mero de cifras arbi- u u trariamente largo: los enteros ˂˂largos˃˃. Un entero largo siempre acaba con la letra L. He aqu´ algunos ejemplos de enteros largos: 1L, -52L, 1237645272817635341571828374645L. ı Los n´meros enteros promocionan autom´ticamente a enteros largos cuando es necesario. u a ↱ >>> 2**30 1073741824 ↱ >>> 2**31 2147483648L Observa la ˂˂L˃˃ que aparece al final del segundo resultado: aunque 2 y 31 son n´meros enteros ˂˂normales˃˃, el resultado de evaluar 2**31 es un entero largo. Esto es u as´ porque los enteros normales se codifican en complemento a 2 de 32 bits, y 2**31 ı no puede representarse en complemento a 2 de 32 bits. Si bien los enteros largos resultan c´modos por no producir nunca errores de desbor- o damiento, debes tener presente que son muy ineficientes: ocupan (mucha) m´s memoria a que los enteros normales y operar con ellos resulta (mucho) m´s lento. a Finalmente, Python tambi´n ofrece la posibilidad de trabajar con n´meros complejos. e u √ Un n´mero complejo puro finaliza siempre con la letra j, que representa el valor −1. u Un n´mero complejo con parte real se expresa sumando la parte real a un complejo puro. u He aqu´ ejemplos de n´meros complejos: 4j, 1 + 2j, 2.0 + 3j, 1 - 0.354j. ı u ↱>>> ord(’a’)97 La funci´n inversa (la que pasa un n´mero a su car´cter equivalente) es chr. o u a ↱>>> chr(97)’a’ La tabla ASCII presenta un problema cuando queremos ordenar palabras: las letrasmay´sculas tienen un valor num´rico inferior a las letras min´sculas (por lo que ’Zapata’ u e uprecede a ’ajo’) y las letras acentuadas son siempre ˂˂mayores˃˃ que sus equivalentes sinacentuar (’abanico’ es menor que ’´baco’). Hay formas de configurar el sistema operativo apara que tenga en cuenta los criterios de ordenaci´n propios de cada lengua al efectuar ocomparaciones, pero esa es otra historia. Si quieres saber m´s, lee el cuadro titulado a˂˂C´digo ASCII y c´digo IsoLatin-1˃˃ y consulta el ap´ndice A. o o e. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 26 ¿Qu´ resultados se muestran al evaluar estas expresiones? e ↱>>> ’abalorio’ < ’abecedario’ ↱>>> ’abecedario’ < ’abecedario’ ↱>>> ’abecedario’ <= ’abecedario’ ↱>>> ’Abecedario’ < ’abecedario’ ↱>>> ’Abecedario’ == ’abecedario’ ↱>>> 124 < 13 ↱>>> ’124’ < ’13’ ↱>>> ’␣a’ < ’a’Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 50 50 Introducción a la programación con Python - UJIUJI c
    • C´digo ASCII y c´digo IsoLatin-1 o o En los primeros d´ de los computadores, los caracteres se codificaban usando 6 o ıas 7 bits. Cada ordenador usaba una codificaci´n de los caracteres diferente, por lo que o hab´ problemas de compatibilidad: no era f´cil transportar datos de un ordenador a ıa a otro. Los estadounidenses definieron una codificaci´n est´ndar de 7 bits que asignaba o a un car´cter a cada n´mero entre 0 y 127: la tabla ASCII (de American Standard Code a u for Information Interchange). Esta tabla (que puedes consultar en un ap´ndice) s´lo e o conten´ los caracteres de uso com´n en la lengua inglesa. La tabla ASCII fue enriquecida ıa u posteriormente definiendo un c´digo de 8 bits para las lenguas de Europa occidental: o la tabla IsoLatin-1, tambi´n conocida como ISO-8859-1 (hay otras tablas para otras e lenguas). Esta tabla coincide con la tabla ASCII en sus primeros 128 caracteres y a˜ade n todos los s´ımbolos de uso com´n en las lenguas de Europa occidental. Una variante u estandarizada es la tabla ISO-8859-15, que es la ISO-8859-1 enriquecida con el s´ ımbolo del euro. . . . (Nota: .el. c´digo. ASCII. del .car´.cter . ’␣’. es. 32,. .y. .el . del. .car´.cter .’a’ . es .97.) . . . . . . . . . . . . . . . . o. . . . . . . . . . . . . . .a . . . . . . . . . . . . .. ..a ... ... .. ... .2.6. Funciones predefinidasHemos estudiado los operadores aritm´ticos b´sicos. Python tambi´n proporciona funcio- e a enes que podemos utilizar en las expresiones. Estas funciones se dice que est´n predefi- anidas.6 La funci´n abs, por ejemplo, calcula el valor absoluto de un n´mero. Podemos usarla o ucomo en estas expresiones: ↱>>> abs(-3)3 ↱>>> abs(3)3 El n´mero sobre el que se aplica la funci´n se denomina argumento. Observa que el u oargumento de la funci´n debe ir encerrado entre par´ntesis: o e ↱>>> abs(0)0 ↱>>> abs 0 File "<stdin>", line 1 abs 0 ˆSyntaxError: invalid syntax Existen muchas funciones predefinidas, pero es pronto para aprenderlas todas. Teresumimos algunas que ya puedes utilizar: float: conversi´n a flotante. Si recibe un n´mero entero como argumento, devuelve o u el mismo n´mero convertido en un flotante equivalente. u ↱ >>> float(3) 3.0 La funci´n float tambi´n acepta argumentos de tipo cadena. Cuando se le pasa una o e cadena, float la convierte en el n´mero flotante que ´sta representa: u e 6 Predefinidas porque nosotros tambi´n podemos definir nuestras propias funciones. Ya llegaremos. eIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 51 51 Introducción a la programación con Python - UJI c UJI
    • ↱ >>> float(’3.2’) 3.2 ↱ >>> float(’3.2e10’) 32000000000.0 Pero si la cadena no representa un flotante, se produce un error de tipo ValueError, es decir, ˂˂error de valor˃˃: ↱ >>> float(’un␣texto’) Traceback (innermost last): File "<stdin>", line 1, in ? ValueError: invalid literal for float(): un texto Si float recibe un argumento flotante, devuelve el mismo valor que se suministra como argumento. int: conversi´n a entero. Si recibe un n´mero flotante como argumento, devuelve el o u entero que se obtiene eliminando la parte fraccionaria.7 ↱ >>> int(2.1) 2 ↱ >>> int(-2.9) -2 Tambi´n la funci´n int acepta como argumento una cadena: e o ↱ >>> int(’2’) 2 Si int recibe un argumento entero, devuelve el argumento tal cual. str: conversi´n a cadena. Recibe un n´mero y devuelve una representaci´n de ´ste o u o e como cadena. ↱ >>> str(2.1) ’2.1’ ↱ >>> str(234E47) ’2.34e+49’ La funci´n str tambi´n puede recibir como argumento una cadena, pero en ese caso o e devuelve como resultado la misma cadena. round: redondeo. Puede usarse con uno o dos argumentos. Si se usa con un s´lo o argumento, redondea el n´mero al flotante m´s pr´ximo cuya parte decimal sea u a o nula. ↱ >>> round(2.1) 2.0 ↱ >>> round(2.9) 3.0 ↱ >>> round(-2.9) -3.0 ↱ >>> round(2) 2.0 7 El redondeo de int puede ser al alza o a la baja seg´n el ordenador en que lo ejecutes. Esto es as´ porque u ıint se apoya en el comportamiento del redondeo autom´tico de C (el int´rprete de Python que usamos est´ a e aescrito en C) y su comportamiento est´ indefinido. Si quieres un comportamiento homog´neo del redondeo, a epues usar las funciones round, floor o ceil, que se explican m´s adelante. aIntroducci´n a la programaci´n con Python o o 52 52 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • (¡Observa que el resultado siempre es de tipo flotante!) Si round recibe dos argu- mentos, ´stos deben ir separados por una coma y el segundo indica el n´mero de e u decimales que deseamos conservar tras el redondeo. ↱ >>> round(2.1451, 2) 2.15 ↱ >>> round(2.1451, 3) 2.145 ↱ >>> round(2.1451, 0) 2.0 Estas funciones (y las que estudiaremos m´s adelante) pueden formar parte de ex- apresiones y sus argumentos pueden, a su vez, ser expresiones. Observa los siguientesejemplos: ↱>>> abs(-23) % int(7.3)2 ↱>>> abs(round(-34.2765,1))34.3 ↱>>> str(float(str(2) * 3 + ’.123’)) + ’321’222.123321 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 27 Calcula con una unica expresi´n el valor absoluto del redondeo de −3.2. (El ´ oresultado es 3.0.)· 28 Convierte (en una unica expresi´n) a una cadena el resultado de la divisi´n ´ o o5011/10000 redondeado con 3 decimales.· 29 ¿Qu´ resulta de evaluar estas expresiones? e ↱>>> str(2.1) + str(1.2) ↱>>> int(str(2) + str(3)) ↱>>> str(int(12.3)) + ’0’ ↱>>> int(’2’+’3’) ↱>>> str(2 + 3) ↱>>> str(int(2.1) + float(3)) ..................................................................................2.7. Funciones definidas en m´dulos oPython tambi´n proporciona funciones trigonom´tricas, logaritmos, etc., pero no est´n e e adirectamente disponibles cuando iniciamos una sesi´n. Antes de utilizarlas hemos de oindicar a Python que vamos a hacerlo. Para ello, importamos cada funci´n de un m´dulo. o o2.7.1. El m´dulo math oEmpezaremos por importar la funci´n seno (sin, del ingl´s ˂˂sinus˃˃) del m´dulo matem´tico o e o a(math): ↱>>> from math import sin Ahora podemos utilizar la funci´n en nuestros c´lculos: o aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 53 53 Introducción a la programación con Python - UJIUJI c
    • ↱>>> sin(0)0.0 ↱>>> sin(1)0.841470984808 Observa que el argumento de la funci´n seno debe expresarse en radianes. o Inicialmente Python no ˂˂sabe˃˃ calcular la funci´n seno. Cuando importamos una fun- oci´n, Python ˂˂aprende˃˃ su definici´n y nos permite utilizarla. Las definiciones de funciones o oresiden en m´dulos. Las funciones trigonom´tricas residen en el m´dulo matem´tico. Por o e o aejemplo, la funci´n coseno, en este momento, es desconocida para Python. o ↱>>> cos(0)Traceback (innermost last): File "<stdin>", line 1, in ?NameError: cos Antes de usarla, es necesario importarla del m´dulo matem´tico: o a ↱>>> from math import cos ↱>>> cos(0)1.0 En una misma sentencia podemos importar m´s de una funci´n. Basta con separar a osus nombres con comas: ↱>>> from math import sin, cos Puede resultar tedioso importar un gran n´mero de funciones y variables de un m´dulo. u oPython ofrece un atajo: si utilizamos un asterisco, se importan todos los elementos de unm´dulo. Para importar todas las funciones del m´dulo math escribimos: o o ↱>>> from math import * As´ de f´cil. De todos modos, no resulta muy aconsejable por dos razones: ı a Al importar elemento a elemento, el programa gana en legibilidad, pues sabemos de d´nde proviene cada identificador. o Si hemos definido una variable con un nombre determinado y dicho nombre coincide con el de una funci´n definida en un m´dulo, nuestra variable ser´ sustituida por la o o a funci´n. Si no sabes todos los elementos que define un m´dulo, es posible que esta o o coincidencia de nombre tenga lugar, te pase inadvertida inicialmente y te lleves una sorpresa cuando intentes usar la variable. He aqu´ un ejemplo del segundo de los problemas indicados: ı ↱>>> pow = 1 ↱>>> from math import * ↱>>> pow += 1Traceback (most recent call last): File "<stdin>", line 1, in ?TypeError: unsupported operand type(s) for +=: ’builtin_function_or_method’and ’int’ Python se queja de que intentamos sumar un entero y una funci´n. Efectivamente, ohay una funci´n pow en el m´dulo math. Al importar todo el contenido de math, nuestra o ovariable ha sido ˂˂machacada˃˃ por la funci´n. o Te presentamos algunas de las funciones que encontrar´s en el m´dulo matem´tico: a o aIntroducci´n a la programaci´n con Python o o 54 54 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • Evitando las coincidencias Python ofrece un modo de evitar el problema de las coincidencias: importar s´lo el o m´dulo. o ↱ >>> import math De esta forma, todas las funciones del m´dulo math est´n disponibles, pero usando o a el nombre del m´dulo y un punto como prefijo: o ↱ >>> import math ↱ >>> print math.sin(0) 0.0 sin(x) Seno de x, que debe estar expresado en radianes. cos(x) Coseno de x, que debe estar expresado en radianes. tan(x) Tangente de x, que debe estar expresado en radianes. exp(x) El n´mero e elevado a x. u ceil(x) Redondeo hacia arriba de x (en ingl´s, ˂˂ceiling˃˃ significa techo). e floor(x) Redondeo hacia abajo de x (en ingl´s, ˂˂floor˃˃ significa suelo). e log(x) Logaritmo natural (en base e) de x. log10(x) Logaritmo decimal (en base 10) de x. sqrt(x) Ra´ cuadrada de x (del ingl´s ˂˂square root˃˃). ız e En el m´dulo matem´tico se definen, adem´s, algunas constantes de inter´s: o a a e ↱>>> from math import pi, e ↱>>> pi3.1415926535897931 ↱>>> e2.7182818284590451 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 30 ¿Qu´ resultados se obtendr´n al evaluar las siguientes expresiones Python? Cal- e acula primero a mano el valor resultante de cada expresi´n y comprueba, con la ayuda del oordenador, si tu resultado es correcto.a) int(exp(2 * log(3)))b) round(4*sin(3 * pi / 2))c) abs(log10(.01) * sqrt(25))d) round(3.21123 * log10(1000), 3) ..................................................................................2.7.2. Otros m´dulos de inter´s o eExiste un gran n´mero de m´dulos, cada uno de ellos especializado en un campo de apli- u ocaci´n determinado. Precisamente, una de las razones por las que Python es un lenguaje opotente y extremadamente util es por la gran colecci´n de m´dulos con que se distribuye. ´ o oHay m´dulos para el dise˜o de aplicaciones para web, dise˜o de interfaces de usua- o n nrio, compresi´n de datos, criptograf´ multimedia, etc. Y constantemente aparecen nuevos o ıa,m´dulos: cualquier programador de Python puede crear sus propios m´dulos, a˜adiendo o o nIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 55 55 Introducción a la programación con Python - UJIUJI c
    • Precisi´n de los flotantes o Hemos dicho que los argumentos de las funciones trigonom´tricas deben expresarse en e radianes. Como sabr´s, sen(π) = 0. Veamos qu´ opina Python: a e ↱ >>> from math import sin, pi ↱ >>> sin(pi) 1.2246063538223773e-16 El resultado que proporciona Python no es cero, sino un n´mero muy pr´ximo a cero: u o 0.00000000000000012246063538223773. ¿Se ha equivocado Python? No exactamente. Ya dijimos antes que los n´meros flotantes tienen una precisi´n limitada. El n´mero π est´ u o u a definido en el m´dulo matem´tico como 3.1415926535897931, cuando en realidad posee o a un n´mero infinito de decimales. As´ pues, no hemos pedido exactamente el c´lculo del u ı a seno de π, sino el de un n´mero pr´ximo, pero no exactamente igual. Por otra parte, el u o m´dulo matem´tico hace c´lculos mediante algoritmos que pueden introducir errores en o a a el resultado.as´ funciones que simplifican la programaci´n en un ambito cualquiera y poni´ndolas ı o ´ ea disposici´n de otros programadores. Nos limitaremos a presentarte ahora unas pocas ofunciones de un par de m´dulos interesantes. o Vamos con otro m´dulo importante: sys (sistema), el m´dulo de ˂˂sistema˃˃ (sys es o ouna abreviatura del ingl´s ˂˂system˃˃). Este m´dulo contiene funciones que acceden al e osistema operativo y constantes dependientes del computador. Una funci´n importante es oexit, que aborta inmediatamente la ejecuci´n del int´rprete (en ingl´s significa ˂˂salir˃˃). o e eLa variable maxint, tambi´n definida en sys, contiene el n´mero entero m´s grande con e u ael que se puede trabajar, y la variable version, indica con qu´ versi´n de Python estamos e otrabajando: ↱>>> from sys import maxint, version ↱>>> maxint2147483647 ↱>>> version’2.3 (#1, Aug 2 2003, 09:00:57) n[GCC 3.3]’ ¡Ojo! Con esto no queremos decirte que la funci´n version o el valor predefinido maxint osean importantes y que debas aprender de memoria su nombre y cometido, sino que losm´dulos de Python contienen centenares de funciones utiles para diferentes cometidos. Un o ´buen programador Python sabe manejarse con los m´dulos. Existe un manual de referencia oque describe todos los m´dulos est´ndar de Python. Lo encontrar´s con la documentaci´n o a a oPython bajo el nombre ˂˂Library reference˃˃ (en ingl´s significa ˂˂referencia de biblioteca˃˃) ey podr´s consultarla con un navegador web.8 . a2.8. M´todos eLos datos de ciertos tipos permiten invocar unas funciones especiales: los denominados˂˂m´todos˃˃. De los que ya conocemos, s´lo las cadenas permiten invocar m´todos sobre e o eellas. Un m´todo permite, por ejemplo, obtener una versi´n en min´sculas de la cadena e o usobre la que se invoca: 8 En una instalaci´n Linux lo encontrar´s en file:/usr/doc/python/html/index.html (aunque di- o aferentes distribuciones lo pueden albergar en otro lugar). Si est´s trabajando en un ordenador con acceso a aInternet, prueba con http://www.python.org/python/doc/2.3/lib/lib.html.Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 56 56 Introducción a la programación con Python - UJI c UJI
    • ↱>>> cadena = ’Un␣EJEMPLO␣de␣Cadena’ ↱>>> cadena.lower()’un ejemplo de cadena’ ↱>>> ’OTRO␣EJEMPLO’.lower()’otro ejemplo’ La sintaxis es diferente de la propia de una llamada a funci´n convencional. Lo primero oque aparece es el propio objeto sobre el se efect´a la llamada. El nombre del m´todo se u esepara del objeto con un punto. Los par´ntesis abierto y cerrado al final son obligatorios. e Existe otro m´todo, upper (˂˂uppercase˃˃, en ingl´s, significa ˂˂may´sculas˃˃), que pasa e e utodos los caracteres a may´sculas. u ↱>>> ’Otro␣ejemplo’.upper()’OTRO EJEMPLO’ Y otro, title que pasa la inicial de cada palabra a may´sculas. Te preguntar´s para qu´ u a epuede valer esta ultima funci´n. Imagina que has hecho un programa de recogida de datos ´ oque confecciona un censo de personas y que cada individuo introduce personalmente sunombre en el ordenador. Es muy probable que algunos utilicen s´lo may´sculas y otros o umay´sculas y min´sculas. Si aplicamos title a cada uno de los nombres, todos acabar´n u u aen un formato unico: ´ ↱>>> ’PEDRO␣F.␣MAS’.title()’Pedro F. Mas’ ↱>>> ’Juan␣CANO’.title()’Juan Cano’ Algunos m´todos aceptan par´metros. El m´todo replace, por ejemplo, recibe como e a eargumento dos cadenas: un patr´n y un reemplazo. El m´todo busca el patr´n en la o e ocadena sobre la que se invoca el m´todo y sustituye todas sus apariciones por la cadena ede reemplazo. ↱>>> ’un␣peque˜o␣ejemplo’.replace(’peque˜o’, ’gran’) n n’un gran ejemplo’ ↱>>> una_cadena = ’abc’.replace(’b’, ’-’) ↱>>> una_cadena’a-c’ Conforme vayamos presentando nuevos tipos de datos y profundizando en nuestroconocimiento de las cadenas, ir´s conociendo nuevos m´todos. a e Cadenas, m´todos y el m´dulo string e o Los m´todos de las cadenas fueron funciones de m´dulos en versiones antiguas de e o Python. Para pasar una cadena a may´sculas, por ejemplo, hab´ que hacer lo siguiente: u ıa ↱ >>> from string import upper ↱ >>> upper(’Otro␣ejemplo’) ’OTRO EJEMPLO’ Y a´n puedes hacerlo as´ aunque resulta m´s c´modo usar m´todos. El m´dulo string u ı, a o e o sigue ofreciendo esas funciones para garantizar la compatibilidad de los programas escritos hace tiempo con las nuevas versiones de Python.Introducci´n a la programaci´n con Python o o 57 57 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • Cap´ ıtulo 3Programas ¡Querida, realmente tengo que conseguir un l´piz m´s fino! No puedo en a a absoluto manejar ´ste: escribe todo tipo de cosas, sin que yo se las dicte. e LEWIS CARROLL, Alicia a trav´s del espejo. eHasta el momento hemos utilizado Python en un entorno interactivo: hemos introducidoexpresiones (y asignaciones a variables) y Python las ha evaluado y ha proporcionadoinmediatamente sus respectivos resultados. Pero utilizar el sistema unicamente de este modo limita bastante nuestra capacidad ´de trabajo. En este tema aprenderemos a introducir secuencias de expresiones y asig-naciones en un fichero de texto y pedir a Python que las ejecute todas, una tras otra.Denominaremos programa al contenido del fichero de texto1 . Puedes generar los ficheros con cualquier editor de texto. Nosotros utilizaremos unentorno de programaci´n: el entorno PythonG. Un entorno de programaci´n es un conjunto o ode herramientas que facilitan el trabajo del programador.3.1. El entorno PythonGEl entorno de programaci´n PythonG es un programa escrito en Python util para es- o ´cribir tus programas Python. Encontrar´s el programa PythonG en la direcci´n web a ohttp://marmota.act.uji.es/MTP. Una vez lo hayas instalado, ejecuta el programapythong.py. En pantalla aparecer´ una ventana como la que se muestra en la figura 3.1. aPuedes introducir expresiones en el entorno interactivo de PythonG, del mismo modo quehemos hecho al ejecutar el int´rprete python desde un terminal. e No nos demoremos m´s y escribamos nuestro primer programa. En el men´ Fichero a uhay una opci´n llamada Nuevo. Al seleccionarla, se crea una ventana de edici´n que o osustituye al entorno interactivo. Entre la ventana y el men´ aparecer´ una pesta˜a con u a nel texto <an´nimo> (figura 3.2). Puedes volver al int´rprete interactivo en cualquier mo- o emento haciendo clic en la pesta˜a <python>. Escribe el siguiente texto en la ventana n<an´nimo>2 : o <an´nimo> o 1 from math import pi 2 3 radio = 1 4 perimetro = 2 * pi * radio Tambi´n se suele denominar scripts a los programas Python. 1 e No debes teclear los n´meros de l´ 2 u ınea que aparecen en el margen izquierdo de los programas. Losponemos unicamente para facilitar posteriores referencias a sus l´ ´ ıneas. 58 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 58 Introducción a la programación con Python - UJI
    • Figura 3.1: El entorno de programaci´n PythonG. En la zona superior aparece una barra o de men´s. Bajo ella, a mano izquierda, un area de trabajo en la que se muestra un entorno u ´ interactivo Python. En la zona derecha hay dos cuadros: el superior es una zona de dibujo y el inferior una consola de entrada/salida para los programas Python. El bot´n con la o letra G permite ocultar/mostrar el area de salida gr´fica. ´ a perimetro Figura 3.2: Al escoger la opci´n o del men´u aparece una pesta˜a con el texto n y una ventana de edici´n que oculta al int´rprete de PythonG. o e Guarda el texto que has escrito en un fichero denominado seleccio-nando la opci´n o del men´ u . from math import pi radio 1 perimetro 2 pi radio perimetro La opci´n o del men´u te permite ejecutar el programa: selec-ci´nala. ¿Qu´ ocurre? Nada. Aunque el programa se ha ejecutado, no vemos el resultado o epor ninguna parte. Analicemos el programa paso a paso. La primera l´ınea de no producesalida alguna: se limita a importar la variable pi. La segunda l´ınea est´ en blanco. Las al´ ıneas en blanco s´lo sirven para hacer m´s legible el programa separando diferentes o apartes del mismo. La tercera define una variable llamada radio y le asigna el valor1, y ya vimos que las asignaciones no producen un resultado visible por pantalla. LaIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 59 59 Introducción a la programación con Python - cUJI UJI
    • Punto py Hay un convenio por el que los ficheros que contienen programas Python tienen ex- tensi´n py en su nombre. La extensi´n de un nombre de fichero son los caracteres del o o mismo que suceden al (´ltimo) punto. Un fichero llamado ejemplo.py tiene extensi´n u o py. La idea de las extensiones viene de antiguo y es un mero convenio. Puedes prescindir de ´l, pero no es conveniente. En entornos gr´ficos (como KDE, Gnome o Microsoft e a Windows) la extensi´n se utiliza para determinar qu´ icono va asociado al fichero y qu´ o e e aplicaci´n debe arrancarse para abrir el fichero al hacer clic (o doble clic) en el mismo. ocuarta l´ ınea tambi´n es una asignaci´n. La quinta l´ e o ınea est´ en blanco y la ultima es a ´una expresi´n (aunque muy sencilla). Cuando aparec´ una expresi´n en una l´ o ıa o ınea, elentorno interactivo mostraba el resultado de su evaluaci´n. Sin embargo, no ocurre lo omismo ahora que trabajamos con un programa. Esta es una diferencia importante entre eluso interactivo de Python y la ejecuci´n de programas: la evaluaci´n de expresiones no o oproduce salida por pantalla en un programa. Entonces ¿c´mo veremos los resultados que oproducen nuestros programas? Hemos de aprender a utilizar una nueva sentencia: print(en ingl´s, ˂˂imprimir˃˃). En principio, se usa de este modo: e print expresi´n oy escribe en pantalla el resultado de evaluar la expresi´n. o Modificamos el programa para que se lea as´ ı: miprograma.py miprograma.py 1 from math import pi 2 3 radio = 1 4 perimetro = 2 * pi * radio 5 6 print perimetro Si ejecutas ahora el programa aparecer´ el resultado en el cuadro inferior derecho. aEn ese cuadro aparece la salida de toda sentencia print, como se aprecia en la figura 3.3.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 31 Dise˜a un programa que, a partir del valor del lado de un cuadrado (3 metros), nmuestre el valor de su per´ ımetro (en metros) y el de su area (en metros cuadrados). ´ (El per´ ımetro debe darte 12 metros y el area 9 metros cuadrados.)´· 32 Dise˜a un programa que, a partir del valor de la base y de la altura de un tri´ngulo n a(3 y 5 metros, respectivamente), muestre el valor de su area (en metros cuadrados). ´ Recuerda que el area A de un tri´ngulo se puede calcular a partir de la base b y la ´ aaltura h como A = 1 bh. 2 h b (El resultado es 7.5 metros cuadrados.)· 33 Dise˜a un programa que, a partir del valor de los dos lados de un rect´ngulo (4 y n a6 metros, respectivamente), muestre el valor de su per´ ımetro (en metros) y el de su area ´(en metros cuadrados). (El per´ ımetro debe darte 20 metros y el area 24 metros cuadrados.) ´ ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 60 60 Introducción a la programación con Python - UJIUJI c
    • Teclas El editor de textos que integra el entorno PythonG puede manejarse de forma muy sencilla con el rat´n y los men´s. Muchas de las ´rdenes que puedes dar seleccionando o u o la opci´n de men´ correspondiente tienen un atajo de teclado, es decir, una combinaci´n o u o de teclas que te permite ejecutar la orden sin tener que coger el rat´n, desplazarte a o la barra de men´s, mantener el rat´n pulsado (o hacer clic) en uno de ellos y soltar u o el rat´n (o hacer un nuevo clic) en la opci´n asociada a la orden. Si te acostumbras a o o usar los atajos de teclado, ser´s mucho m´s productivo. Memorizarlos cuesta bastante a a esfuerzo al principio, pero recompensa a medio y largo plazo. Te resumimos aqu´ los atajos de teclado para las diferentes ´rdenes. Algunos atajos ı o requieren la pulsaci´n de cuatro teclas, bueno, de dos grupos de dos teclas que se pulsan o simult´neamente. Por ejemplo, para abrir un fichero has de pulsar C-x y, despu´s, C-f. a e Una secuencia doble como esa se indicar´ as´ C-x C-f. a ı: Nuevo fichero C-x C-n Abrir fichero C-x C-f Guardar C-x C-s Guardar como C-x C-w Cerrar C-x k Salir C-x C-c Deshacer C-z Rehacer C-M-z Cortar C-x Copiar C-c Pegar C-v Buscar C-s Reemplazar Esc % Ir a l´ ınea n´mero u Esc g Aumentar tama˜o letra n C-+ Reducir tama˜o letra n C-- Ejecutar programa C-c C-c Abortar ejecuci´n o C-c C-c (Esc representa a la tecla de ˂˂escape˃˃ (la tecla de la esquina superior izquierda en el teclado) y M (en C-M-z) a la tecla Alt, aunque es la inicial del t´rmino ˂˂meta˃˃.) e Hay otras combinaciones de teclas que resultan muy utiles y cuyas ´rdenes no son ´ o accesibles a trav´s de un men´. Aqu´ las tienes: e u ı Ir a principio de l´ ınea C-a Ir a final de l´ ınea C-e Adelantar palabra C-→ Volver una palabra atr´s a C-← Seleccionar S-<tecla de cursor> (S es la tecla de may´sculas, que en ingl´s se llama ˂˂shift˃˃.) u e Edici´n de ficheros en el entorno Unix o Puedes utilizar cualquier editor de texto para escribir programas Python.¡Ojo!, no debes usar un procesador de texto, es decir, el texto no debe tener formato (cambios de tipo- graf´ de tama˜os de letra, etc.). Aplicaciones como el Microsoft Word s´ dan formato ıa, n ı al texto. El bloc de notas de Microsoft Windows, por ejemplo, es un editor de texto apropiado para la programaci´n (aunque muy pobre). o En Unix existe una gran variedad de editores de texto. Los m´s utilizados son el vi a y el Emacs (o su variante XEmacs). Si has de usar un editor de texto, te recomendamos este ultimo. XEmacs incorpora un modo de trabajo Python (python-mode) que facilita ´ enormemente la escritura de programas Python. Las combinaciones de teclas de PythonG se han definido para hacer f´cil el trabajo a con XEmacs, pues son b´sicamente id´nticas. De ese modo, no te resultar´ dif´ alternar a e a ıcil entre PythonG y XEmacs.3.2. Ejecuci´n de programas desde la l´ o ınea de ´rdenes Unix oUna vez has escrito un programa es posible ejecutarlo directamente, sin entrar en elentorno PythonG. Si invocas al int´rprete python seguido del nombre de un fichero edesde la l´ ınea de ´rdenes Unix, no se iniciar´ una sesi´n con el int´rprete interactivo, o a o eIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 61 61 Introducción a la programación con Python - c UJI UJI
    • Figura 3.3: Programa de c´lculo del per´ a ımetro. El resultado de la ejecuci´n se muestra en o la consola (cuadro de la esquina inferior derecha).sino que se ejecutar´ el programa contenido en el fichero en cuesti´n. a o Por ejemplo, si ejecutamos la orden python miprograma.py en la l´ ınea de ´rdenes otenemos el siguiente resultado: ↱$ python miprograma.py6.28318530718 A continuaci´n volver´ a aparecer el prompt del int´rprete de ´rdenes Unix pi- o a e odi´ndonos nuevas ´rdenes. e o3.3. Entrada/salidaLos programas que hemos visto en la secci´n anterior adolecen de un serio inconveniente: ocada vez que quieras obtener resultados para unos datos diferentes deber´s editar el afichero de texto que contiene el programa. Por ejemplo, el siguiente programa calcula el volumen de una esfera a partir de suradio, que es de un metro: volumen esfera 8.py volumen esfera.py 1 from math import pi 2 3 radio = 1 4 volumen = 4.0 / 3.0 * pi * radio ** 3 5 6 print volumenAqu´ tienes el resultado de ejecutar el programa: ı ↱$ python volumen_esfera.py4.18879020479 Si deseas calcular ahora el volumen de una esfera de 3 metros de radio, debes editarel fichero que contiene el programa, yendo a la tercera l´ ınea y cambi´ndola para que el aprograma pase a ser ´ste: eIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 6262 Introducción a la programación con Python - UJI c UJI
    • Ejecuci´n impl´ o ıcita del int´rprete e No es necesario llamar expl´ ıcitamente al int´rprete de Python para ejecutar los pro- e gramas. En Unix existe un convenio que permite llamar al int´rprete autom´ticamente: e a si la primera l´ ınea del fichero de texto empieza con los caracteres #!, se asume que, a continuaci´n, aparece la ruta en la que encontrar el int´rprete que deseamos utilizar o e para ejecutar el fichero. Si, por ejemplo, nuestro int´rprete Python est´ en /usr/local/bin/python, el e a siguiente fichero: miprograma 5.py miprograma.py 1 #! /usr/local/bin/python 2 3 from math import pi 4 5 radio = 1 6 perimetro = 2 * pi * radio 7 8 print perimetro adem´s de contener el programa, permitir´ invocar autom´ticamente al int´rprete de a ıa a e Python. O casi. Nos faltar´ un ultimo paso: dar permiso de ejecuci´n al fichero. Si ıa ´ o deseas dar permiso de ejecuci´n has de utilizar la orden Unix chmod. Por ejemplo, o ↱ $ chmod u+x miprograma.py da permiso de ejecuci´n al usuario propietario del fichero. A partir de ahora, para ejecutar o el programa s´lo tendremos que escribir el nombre del fichero: o ↱ $ miprograma.py 6.28318530718 Si quieres practicar, genera ficheros ejecutables para los programas de los ultimos ´ tres ejercicios. Ten en cuenta que, a veces, este procedimiento falla. En diferentes sistemas puede que Python est´ instalado en directorios diferentes. Puede resultar m´s pr´ctico sustituir e a a la primera l´ınea por esta otra: miprograma 6.py miprograma.py 1 #! /usr/bin/env python 2 3 from math import pi 4 5 radio = 1 6 perimetro = 2 * pi * radio 7 8 print perimetro El programa env (que deber´ estar en /usr/bin en cualquier sistema) se encarga de ıa ˂˂buscar˃˃ al programa python. volumen esfera 9.py volumen esfera.py 1 from math import pi 2 3 radio = 3 4 volumen = 4.0 / 3.0 * pi * radio ** 3 5 6 print volumenIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 63 63 Introducción a la programación con Python -cUJI UJI
    • Ahora podemos ejecutar el programa: ↱$ python volumen_esfera.py113.097335529 Y si ahora quieres calcular el volumen para otro radio, vuelta a empezar: abre elfichero con el editor de texto, ve a la tercera l´ ınea, modifica el valor del radio y guardael fichero. No es el colmo de la comodidad.3.3.1. Lectura de datos de tecladoVamos a aprender a hacer que nuestro programa, cuando se ejecute, pida el valor delradio para el que vamos a efectuar los c´lculos sin necesidad de editar el fichero de aprograma. Hay una funci´n predefinida, raw_input (en ingl´s significa ˂˂entrada en bruto˃˃), que o ehace lo siguiente: detiene la ejecuci´n del programa y espera a que el usuario escriba un otexto (el valor del radio, por ejemplo) y pulse la tecla de retorno de carro; en ese momentoprosigue la ejecuci´n y la funci´n devuelve una cadena con el texto que tecle´ el usuario. o o o Si deseas que el radio sea un valor flotante, debes transformar la cadena devuelta porraw_input en un dato de tipo flotante llamando a la funci´n float. La funci´n float recibir´ o o acomo argumento la cadena que devuelve raw_input y proporcionar´ un n´mero en coma a uflotante. (Recuerda, para cuando lo necesites, que existe otra funci´n de conversi´n, int, o oque devuelve un entero en lugar de un flotante.) Por otra parte, raw_input es una funci´n oy, por tanto, el uso de los par´ntesis que siguen a su nombre es obligatorio, incluso ecuando no tenga argumentos. He aqu´ el nuevo programa: ı volumen esfera 10.py volumen esfera.py 1 from math import pi 2 3 texto_leido = raw_input() 4 radio = float(texto_leido) 5 volumen = 4.0 / 3.0 * pi * radio ** 3 6 7 print volumen Esta otra versi´n es m´s breve: o a volumen esfera 11.py volumen esfera.py 1 from math import pi 2 3 radio = float(raw_input()) 4 volumen = 4.0 / 3.0 * pi * radio ** 3 5 6 print volumen Al ejecutar el programa desde la l´ınea de ´rdenes Unix, el ordenador parece quedar obloqueado. No lo est´: en realidad Python est´ solicitando una entrada de teclado y espe- a ara que se la proporcione el usuario. Si tecleas, por ejemplo, el n´mero 3 y pulsas la tecla ude retorno de carro, Python responde imprimiendo en pantalla el valor 113.097335529.Puedes volver a ejecutar el programa y, en lugar de teclear el n´mero 3, teclear cualquier uotro valor; Python nos responder´ con el valor del volumen de la esfera para un radio aigual al valor que hayas tecleado. Pero el programa no es muy elegante, pues deja al ordenador bloqueado hasta queel usuario teclee una cantidad y no informa de qu´ es exactamente esa cantidad. Vamos eIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 64 64 Introducción a la programación con Python - UJI c UJI
    • a hacer que el programa indique, mediante un mensaje, qu´ dato desea que se teclee. La efunci´n raw_input acepta un argumento: una cadena con el mensaje que debe mostrar. o Modifica el programa para que quede as´ ı: volumen esfera 12.py volumen esfera.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio:␣’)) 4 volumen = 4.0 / 3.0 * pi * radio ** 3 5 6 print volumenAhora, cada vez que lo ejecutes, mostrar´ por pantalla el mensaje ˂˂Dame el radio:˃˃ y adetendr´ su ejecuci´n hasta que introduzcas un n´mero y pulses el retorno de carro. a o u ↱$ python volumen_esfera.pyDame el radio: 3113.097335529 La forma de uso del programa desde PythonG es muy similar. Cuando ejecutas elprograma, aparece el mensaje ˂˂Dame el radio:˃˃ en la consola de entrada/salida y sedetiene la ejecuci´n (figura 3.4 (a)). El usuario debe teclear el valor del radio, que va oapareciendo en la propia consola (figura 3.4 (b)), y pulsar al final la tecla de retorno decarro. El resultado aparece a continuaci´n en la consola (figura 3.4 (c)). o (a) (b) (c) Figura 3.4: Entrada/salida en la consola al ejecutar el programa volumen esfera.py. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 34 Dise˜a un programa que pida el valor del lado de un cuadrado y muestre el valor nde su per´ ımetro y el de su area. ´ (Prueba que tu programa funciona correctamente con este ejemplo: si el lado vale 1.1,el per´ ımetro ser´ 4.4, y el area 1.21.) a ´· 35 Dise˜a un programa que pida el valor de los dos lados de un rect´ngulo y muestre n ael valor de su per´ımetro y el de su area. ´ (Prueba que tu programa funciona correctamente con este ejemplo: si un lado mide 1y el otro 5, el per´ ımetro ser´ 12.0, y el area 5.0.) a ´· 36 Dise˜a un programa que pida el valor de la base y la altura de un tri´ngulo y n amuestre el valor de su area. ´ (Prueba que tu programa funciona correctamente con este ejemplo: si la base es 10 yla altura 100, el area ser´ 500.0.) ´ aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 65 65 Introducción a la programación con Python - UJIUJI c
    • · 37 Dise˜a un programa que pida el valor de los tres lados de un tri´ngulo y calcule n ael valor de su area y per´ ´ ımetro. Recuerda que el area A de un tri´ngulo puede calcularse a partir de sus tres lados, ´ aa, b y c, as´ A = s(s − a)(s − b)(s − c), donde s = (a + b + c)/2. ı: (Prueba que tu programa funciona correctamente con este ejemplo: si los lados miden3, 5 y 7, el per´ ımetro ser´ 15.0 y el area 6.49519052838.) a ´ ..................................................................................3.3.2. M´s sobre la sentencia print aLas cadenas pueden usarse tambi´n para mostrar textos por pantalla en cualquier mo- emento a trav´s de sentencias print. e volumen esfera 13.py volumen esfera.py 1 from math import pi 2 3 print ’Programa␣para␣el␣c´lculo␣del␣volumen␣de␣una␣esfera.’ a 4 5 radio = float(raw_input(’Dame␣el␣radio:␣’)) 6 volumen = 4.0 / 3.0 * pi * radio ** 3 7 8 print volumen 9 print ’Gracias␣por␣utilizar␣este␣programa.’Cuando ejecutes este programa, f´ ıjate en que las cadenas que se muestran con print noaparecen entrecomilladas. El usuario del programa no est´ interesado en saber que le aestamos mostrando datos del tipo cadena: s´lo le interesa el texto de dichas cadenas. oMucho mejor, pues, no mostrarle las comillas. Una sentencia print puede mostrar m´s de un resultado en una misma l´ a ınea: bastacon separar con comas todos los valores que deseamos mostrar. Cada una de las comasse traduce en un espacio de separaci´n. El siguiente programa: o volumen esfera 14.py volumen esfera.py 1 from math import pi 2 3 print ’Programa␣para␣el␣c´lculo␣del␣volumen␣de␣una␣esfera.’ a 4 5 radio = float(raw_input(’Dame␣el␣radio␣(en␣metros):␣’)) 6 volumen = 4.0/3.0 * pi * radio ** 3 7 8 print ’Volumen␣de␣la␣esfera:’, volumen, ’metros␣c´bicos’ uhace que se muestre el texto ˂˂Volumen de la esfera:˃˃, seguido del valor de la variablevolumen y acabado con ˂˂metros c´bicos˃˃. Observa que los elementos del ultimo print u ´se separan entre s´ por espacios en blanco: ıPrograma para el c´lculo del volumen de una esfera. aDame el radio (en metros): 2El volumen de la esfera es de 33.5103216383 metros c´bicos u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 38 El area A de un tri´ngulo se puede calcular a partir del valor de dos de sus lados, ´ aa y b, y del angulo θ que ´stos forman entre s´ con la f´rmula A = 1 ab sin(θ). Dise˜a un ´ e ı o 2 nprograma que pida al usuario el valor de los dos lados (en metros), el angulo que estos ´forman (en grados), y muestre el valor del area. ´Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 66 66 Introducción a la programación con Python - UJIUJI c
    • b θ a (Ten en cuenta que la funci´n sin de Python trabaja en radianes, as´ que el angulo o ı ´que leas en grados deber´s pasarlo a radianes sabiendo que π radianes son 180 grados. aPrueba que has hecho bien el programa introduciendo los siguientes datos: a = 1, b = 2,θ = 30; el resultado es 0.5.)· 39 Haz un programa que pida al usuario una cantidad de euros, una tasa de inter´s y eun n´mero de a˜os. Muestra por pantalla en cu´nto se habr´ convertido el capital inicial u n a atranscurridos esos a˜os si cada a˜o se aplica la tasa de inter´s introducida. n n e Recuerda que un capital de C euros a un inter´s del x por cien durante n a˜os se e nconvierten en C · (1 + x/100) n euros. (Prueba tu programa sabiendo que una cantidad de 10 000 ¤ al 4.5% de inter´s anual ese convierte en 24 117.14 ¤ al cabo de 20 a˜os.) n· 40 Haz un programa que pida el nombre de una persona y lo muestre en pantallarepetido 1000 veces, pero dejando un espacio de separaci´n entre aparici´n y aparici´n o o odel nombre. (Utiliza los operadores de concatenaci´n y repetici´n.) o o .................................................................................. Por lo visto hasta el momento, cada print empieza a imprimir en una nueva l´ ınea.Podemos evitarlo si el anterior print finaliza en una coma. F´ ıjate en este programa: volumen esfera.py volumen esfera.py 1 from math import pi 2 3 print ’Programa␣para␣el␣c´lculo␣del␣volumen␣de␣una␣esfera.’ a 4 5 radio = float(raw_input(’Dame␣el␣radio␣(en␣metros):␣’)) 6 volumen = 4.0/3.0 * pi * radio ** 3 7 8 print ’Volumen␣de␣la␣esfera:’, 9 print volumen, ’metros␣c´bicos’ uLa pen´ltima l´ u ınea es una sentencia print que finaliza en una coma. Si ejecutamos elprograma obtendremos un resultado absolutamente equivalente al de la versi´n anterior: oPrograma para el c´lculo del volumen de una esfera. aDame el radio (en metros): 2El volumen de la esfera es de 33.5103216383 metros c´bicos u Ocurre que cada print imprime, en principio, un car´cter especial denominado ˂˂nueva al´ ınea˃˃, que hace que el cursor (la posici´n en la que se escribe la salida por pantalla en ocada instante) se desplace a la siguiente l´ınea. Si print finaliza en una coma, Python noimprime el car´cter ˂˂nueva l´ a ınea˃˃, as´ que el cursor no se desplaza a la siguiente l´ ı ınea.El siguiente print, pues, imprimir´ inmediatamente a continuaci´n, en la misma l´ a o ınea.3.3.3. Salida con formatoCon la sentencia print podemos controlar hasta cierto punto la apariencia de la salida.Pero no tenemos un control total: Cada coma en la sentencia print hace que aparezca un espacio en blanco en la pantalla. ¿Y si no deseamos que aparezca ese espacio en blanco?Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 6767 c Introducción a la programación con Python - UJIUJI
    • Cada n´mero ocupa tantas ˂˂casillas˃˃ de la pantalla como caracteres tiene. Por u ejemplo, el n´mero 2 ocupa una casilla, y el n´mero 2000, cuatro. ¿Y si queremos u u que todos los n´meros ocupen el mismo n´mero de casillas? u u Python nos permite controlar con absoluta precisi´n la salida por pantalla. Para ello ohemos de aprender un nuevo uso del operador %. Estudia detenidamente este programa: potencias 1.py potencias.py 1 numero = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 2, numero ** 2) 4 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 3, numero ** 3) 5 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 4, numero ** 4) 6 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 5, numero ** 5) Cada una de las cuatro ultimas l´ ´ ıneas presenta este aspecto: print cadena % (valor, valor, valor) La cadena es especial, pues tiene unas marcas de la forma %d. ¿Tienen alg´n signifi- ucado? Despu´s de la cadena aparece el operador %, que hemos visto en el tema anterior ecomo operador de enteros o flotantes, pero que aqu´ combina una cadena (a su izquierda) ıcon una serie de valores (a su derecha). ¿Qu´ hace en este caso? e Para entender qu´ hacen las cuatro ultimas l´ e ´ ıneas, ejecutemos el programa:Dame un n´mero: 3 u3 elevado a 2 es 93 elevado a 3 es 273 elevado a 4 es 813 elevado a 5 es 243 Cada marca de formato %d en la cadena ’%d␣elevado␣a␣%d␣es␣%d’ ha sido sus-tituida por un n´mero entero. El fragmento %d significa ˂˂aqu´ va un n´mero entero˃˃. u ı u¿Qu´ n´mero? El que resulta de evaluar cada una de las tres expresiones que aparecen e useparadas por comas y entre par´ntesis a la derecha del operador %. e ’ %d elevado a %d es %d ’ % ( numero , 2 , numero ** 2 ) No s´lo podemos usar el operador % en cadenas que vamos a imprimir con print: el oresultado es una cadena y se puede manipular como cualquier otra: ↱>>> x = 2 ↱>>> print ’n´mero␣%d␣y␣n´mero␣%d’ % (1, x) u un´mero 1 y n´mero 2 u u ↱>>> a = ’n´mero␣%d␣y␣n´mero␣%d’ % (1, x) u u ↱>>> a’n´mero 1 y n´mero 2’ u u ↱>>> print (’n´mero␣%d␣y␣n´mero␣%d’ % (1, x)).upper() u uN´MERO 1 Y N´MERO 2 U U. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 41 ¿Qu´ mostrar´ por pantalla este programa? e aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 68 68 Introducción a la programación con Python - UJIUJI c
    • 1 print ’%d’ % 1 2 print ’%d␣%d’ % (1, 2) 3 print ’%d%d’ % (1, 2) 4 print ’%d,␣%d’ % (1, 2) 5 print 1, 2 6 print ’%d␣2’ % 1· 42 Un alumno inquieto ha experimentado con las marcas de formato y el m´todo eupper y ha obtenido un resultado sorprendente: ↱>>> print (’n´mero␣%d␣y␣n´mero␣%d’ % (1, 2)).upper() u uN´MERO 1 Y N´MERO 2 U U ↱>>> print ’n´mero␣%d␣y␣n´mero␣%d’.upper() % (1, 2) u uTraceback (most recent call last): File "<stdin>", line 1, in ?ValueError: unsupported format character ’D’ (0x44) at index 8 ¿Qu´ crees que ha pasado? e (Nota: Aunque experimentar conlleva el riesgo de equivocarse, no podemos enfatizarsuficientemente cu´n importante es para que asimiles las explicaciones. Probarlo todo, acometer errores, reflexionar sobre ellos y corregirlos es uno de los mejores ejerciciosimaginables.) .................................................................................. Vamos a modificar ligeramente el programa: potencias.py potencias.py 1 numero = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 print ’%d␣elevado␣a␣%d␣es␣%4d’ % (numero, 2, numero ** 2) 4 print ’%d␣elevado␣a␣%d␣es␣%4d’ % (numero, 3, numero ** 3) 5 print ’%d␣elevado␣a␣%d␣es␣%4d’ % (numero, 4, numero ** 4) 6 print ’%d␣elevado␣a␣%d␣es␣%4d’ % (numero, 5, numero ** 5) El tercer %d de cada l´ınea ha sido sustituido por un %4d. Veamos qu´ ocurre al eejecutar el nuevo programa:Dame un n´mero: 3 u3␣elevado␣a␣2␣es␣␣␣␣93␣elevado␣a␣3␣es␣␣␣273␣elevado␣a␣4␣es␣␣␣813␣elevado␣a␣5␣es␣␣243 Los n´meros enteros que ocupan la tercera posici´n aparecen alineados a la derecha. u oEl fragmento %4d significa ˂˂aqu´ va un entero que representar´ ocupando 4 casillas˃˃. Si ı eel n´mero entero tiene 4 o menos d´ u ıgitos, Python lo representa dejando delante de ´l los eespacios en blanco que sea menester para que ocupe exactamente 4 espacios. Si tienem´s de 4 d´ a ıgitos, no podr´ cumplir con la exigencia impuesta, pero seguir´ representando a ael n´mero entero correctamente. u Hagamos la prueba. Ejecutemos de nuevo el mismo programa, pero introduciendo otron´mero: uDame un n´mero: 7 u7␣elevado␣a␣2␣es␣␣␣497␣elevado␣a␣3␣es␣␣3437␣elevado␣a␣4␣es␣24017␣elevado␣a␣5␣es␣16807Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 6969 Introducción a la programación con Python - UJIUJI c
    • ¿Ves? El ultimo n´mero tiene cinco d´ ´ u ıgitos, as´ que ˂˂se sale˃˃ por el margen derecho. ı Las cadenas con marcas de formato como %d se denominan cadenas con formato y eloperador % a cuya izquierda hay una cadena con formato es el operador de formato. Las cadenas con formato son especialmente utiles para representar adecuadamente ´n´meros flotantes. F´ u ıjate en el siguiente programa: area con formato.py area con formato.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio:␣’)) 4 area = pi*radio**2 5 6 print ’El␣´rea␣de␣un␣c´rculo␣de␣radio␣%f␣es␣%f’ % (radio, area) a ı 7 print ’El␣´rea␣de␣un␣c´rculo␣de␣radio␣%6.3f␣es␣%6.3f’ % (radio, area) a ı Ejecutemos el programa:Dame el radio: 2El ´rea de un c´rculo de radio 2.000000 es 12.566371 a ıEl ´rea de un c´rculo de radio 2.000 es 12.566 a ı Observa: la marca %f indica que ah´ aparecer´ un flotante. Podemos meter un n´mero ı a ucon decimales entre el % y la f. ¿Qu´ significa? Indica cu´ntas casillas deseamos que e aocupe el flotante (parte entera del n´mero entre la % y la f) y, de ellas, cu´ntas queremos u aque ocupen los n´meros decimales (parte decimal del mismo n´mero). u u Hemos visto que hay marcas de formato para enteros y flotantes. Tambi´n hay una emarca para cadenas: %s. El siguiente programa lee el nombre de una persona y la saluda: saluda 3.py saluda.py 1 nombre = raw_input(’Tu␣nombre:␣’) 2 print ’Hola,␣%s.’ % (nombre) Probemos el programa:Tu nombre: JuanHola, Juan. ¡Ah! Los par´ntesis en el argumento de la derecha del operador de formato son eopcionales si s´lo se le pasa un valor. Esta nueva versi´n del programa es equivalente: o o saluda 4.py saluda.py 1 nombre = raw_input(’Tu␣nombre:␣’) 2 print ’Hola,␣%s.’ % nombre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 43 ¿Qu´ peque˜a diferencia hay entre el programa saluda.py y este otro cuando e nlos ejecutamos? saluda2.py 1 nombre = raw_input(’Tu␣nombre:␣’) 2 print ’Hola,’, nombre, ’.’· 44 La marca %s puede representar cadenas con un n´mero fijo de casillas. A la vista ude c´mo se pod´ expresar esta caracter´ o ıa ıstica en la marca de enteros %d, ¿sabr´ como ıasindicar que deseamos representar una cadena que ocupa 10 casillas? ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 70 70 Introducción a la programación con Python - UJIUJI c
    • 3.4. Legibilidad de los programasLos programas que estamos dise˜ando son bastante sencillos. No ocupan m´s all´ de n a atres o cuatro l´ ıneas y siempre presentan una misma estructura: Piden el valor de una serie de datos (mediante raw_input). Efect´an unos c´lculos con ellos. u a Muestran el resultado de los c´lculos (con print). aEstos programas son f´ciles de leer y, en cierto modo, autoexplicativos. a F´ıjate en este programa y trata de descifrar qu´ hace: e ilegible.py ilegible.py 1 h = float(raw_input(’Dame␣h:␣’)) 2 v = float(raw_input(’y␣v:␣’)) 3 z=h*v 4 print ’Resultado␣1␣%6.2f’ % z 5 v=2*h+v+v 6 print ’Resultado␣2␣%6.2f’ % v Mmmm. . . no est´ muy claro, ¿verdad? Podemos entender qu´ hace el programa l´ a e ıneaa l´ ınea, pero es dif´ captar su prop´sito. ıcil o Ahora trata de leer este otro. legible.py legible.py 1 print ’Programa␣para␣el␣c´lculo␣del␣per´metro␣y␣el␣´rea␣de␣un␣rect´ngulo.’ a ı a a 2 3 altura = float(raw_input(’Dame␣la␣altura␣(en␣metros):␣’)) 4 anchura = float(raw_input(’Dame␣la␣anchura␣(en␣metros):␣’)) 5 6 area = altura * anchura 7 perimetro = 2 * altura + 2 * anchura 8 9 print ’El␣per´metro␣es␣de␣%6.2f␣metros.’ % perimetro ı10 print ’El␣´rea␣es␣de␣%6.2f␣metros␣cuadrados.’ % area a Sencillo, ¿verdad? Hemos separado visualmente cuatro zonas con la ayuda de l´ ıneasen blanco. En la primera l´ ınea se anuncia el cometido del programa. En las dos siguientesl´ ıneas no blancas se pide el valor de dos datos y el nombre de las variables en los que losalmacenamos ya sugiere qu´ son esos datos. A continuaci´n, se efect´an unos c´lculos. e o u aTambi´n en este caso el nombre de las variables ayuda a entender qu´ significan los e eresultados obtenidos. Finalmente, en las dos ultimas l´ ´ ıneas del programa se muestran losresultados por pantalla. Evidentemente, el programa pide la altura y la anchura de unrect´ngulo y calcula su per´ a ımetro y area, valores que muestra a continuaci´n. ´ o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 45 Dise˜a un programa que solicite el radio de una circunferencia y muestre su area n ´y per´ ımetro con s´lo 2 decimales. o ..................................................................................3.4.1. Algunas claves para aumentar la legibilidad¿Por qu´ uno de los programas ha resultado m´s sencillo de leer que el otro? e a Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 71 Introducción a la programación con Python - UJIIntroducci´n a la programaci´n con Python o o 71 c UJI
    • ilegible.py usa nombres arbitrarios y breves para las variables, mientras que legible.py utiliza identificadores representativos y tan largos como sea necesa- rio. El programador de ilegible.py pensaba m´s en teclear poco que en hacer a comprensible el programa. ilegible.py no tiene una estructura clara: mezcla c´lculos con impresi´n de resul- a o tados. En su lugar, legible.py diferencia claramente zonas distintas del programa (lectura de datos, realizaci´n de c´lculos y visualizaci´n de resultados) y llega a o a o usar marcas visuales como las l´ ıneas en blanco para separarlas. Probablemente el programador de ilegible.py escrib´ el programa conforme se le iban ocurrien- ıa do cosas. El programador de legible.py ten´ claro qu´ iba a hacer desde el ıa e principio: planific´ la estructura del programa. o ilegible.py utiliza f´rmulas poco frecuentes para realizar algunos de los c´lculos: o a la forma en que calcula el per´ ımetro es v´lida, pero poco ortodoxa. Por contra, a legible.py utiliza formas de expresi´n de los c´lculos que son est´ndar. El pro- o a a gramador de ilegible.py deber´ haber pensado en los convenios a la hora de ıa utilizar f´rmulas. o Los mensajes de ilegible.py, tanto al pedir datos como al mostrar resultados, son de p´sima calidad. Un usuario que se enfrenta al programa por primera vez tendr´ e a serios problemas para entender qu´ se le pide y qu´ se le muestra como resultado. e e El programa legible.py emplea mensajes de entrada/salida muy informativos. Seguro que el programador de ilegible.py pensaba que ´l ser´ el unico usuario e ıa ´ de su programa. La legibilidad de los programas es clave para hacerlos pr´cticos. ¿Y por qu´ querr´ a e ıaun programador leer programas ya escritos? Por varias razones. He aqu´ algunas: ı Es posible que el programa se escribiera hace unas semanas o meses (o incluso a˜os) y ahora se desee modificar para extender su funcionalidad. Un programa n legible nos permitir´ ponernos mano a la obra r´pidamente. a a Puede que el programa contenga errores de programaci´n y deseemos detectarlos y o corregirlos. Cuanto m´s legible sea el programa, m´s f´cil y r´pido ser´ depurarlo. a a a a a O puede que el programa lo haya escrito un programador de la empresa que ya no est´ trabajando en nuestro equipo. Si nos encargan trabajar sobre ese programa, a nos gustar´ que el mismo estuviera bien organizado y fuera f´cilmente legible.3 ıa a Atenerte a la reglas usadas en legible.py ser´ fundamental para hacer legibles tus aprogramas.3.4.2. ComentariosDentro de poco empezaremos a realizar programas de mayor envergadura y con muchamayor complicaci´n. Incluso observando las reglas indicadas, va a resultar una tarea oardua leer un programa completo. Un modo de aumentar la legibilidad de un programa consiste en intercalar comentariosque expliquen su finalidad o que aclaren sus pasajes m´s oscuros. a Como esos comentarios s´lo tienen por objeto facilitar la legibilidad de los programas opara los programadores, pueden escribirse en el idioma que desees. Cuando el int´rprete ePython ve un comentario no hace nada con ´l: lo omite. ¿C´mo le indicamos al int´rprete e o e 3 Si ´ste es tu libro de texto, m´ e ıralo desde un lado ˂˂acad´micamente pragm´tico˃˃: si tus programas han e ade ser evaluados por un profesor, ¿qu´ calificaci´n obtendr´s si le dificultas enormemente la lectura? ;-) e o aIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 72 72 Introducción a la programación con Python - c UJI UJI
    • que cierto texto es un comentario? Necesitamos alguna marca especial. Los comentariosPython se inician con el s´ımbolo # (que se lee ˂˂almohadilla˃˃): todo texto desde la al-mohadilla hasta el final de la l´ ınea se considera comentario y, en consecuencia, es omitidopor Python. He aqu´ un programa con comentarios: ı rectangulo.py rectangulo.py 1 # Programa: rectangulo.py 2 # Prop´sito: Calcula el per´ o ımetro y el area de un rect´ngulo a partir ´ a 3 # de su altura y anchura. 4 # Autor: John Cleese 5 # Fecha: 1/1/2001 6 7 # Petici´n de los datos (en metros) o 8 altura = float(raw_input(’Dame␣la␣altura␣(en␣metros):␣’)) 9 anchura = float(raw_input(’Dame␣la␣anchura␣(en␣metros):␣’))1011 # C´lculo del area y del per´ a ´ ımetro12 area = altura * anchura13 perimetro = 2 * altura + 2 * anchura1415 # Impresi´n de resultados por pantalla o16 print ’El␣per´metro␣es␣de␣%6.2f␣metros’ % perimetro # s´lo dos decimales. ı o17 print ’El␣´rea␣es␣de␣%6.2f␣metros␣cuadrados’ % area a Observa que hemos puesto comentarios: en la cabecera del programa, comentando el nombre del programa, su prop´sito, el o autor y la fecha; al principio de cada una de las ˂˂grandes zonas˃˃ del programa, indicando qu´ se e hace en ellas; y al final de una de las l´ ıneas (la pen´ltima), para comentar alguna peculiaridad u de la misma. Es buena pr´ctica que ˂˂comentes˃˃ tus programas. Pero ten presente que no hay areglas fijas que indiquen cu´ndo, d´nde y c´mo comentar los programas: las que acabes a o oadoptando formar´n parte de tu estilo de programaci´n. a o3.5. Gr´ficos aTodos los programas que te hemos presentado utilizan el teclado y la pantalla en ˂˂modotexto˃˃ para interactuar con el usuario. Sin embargo, est´s acostumbrado a interactuar con ael ordenador mediante un terminal gr´fico y usando, adem´s del teclado, el rat´n. En este a a oapartado vamos a introducir brevemente las capacidades gr´ficas del entorno PythonG. aEn el ap´ndice B se resumen las funciones que presentamos en este y otros apartados. e Inicia el entorno PythonG y ver´s que hay un cuadrado en blanco en la zona superior aderecha. Es la ventana gr´fica o lienzo. Todos los elementos gr´ficos que produzcan tus a aprogramas se mostrar´n en ella. La esquina inferior izquierda de la ventana gr´fica tiene a acoordenadas (0, 0), y la esquina superior derecha, coordenadas (1000, 1000). Nuestro primer programa gr´fico es muy sencillo: dibuja una l´ a ınea en el lienzo queva del punto (100, 100) al punto (900, 900). La funci´n create_line dibuja una l´ o ınea enpantalla. Debes suministrarle cuatro valores num´ricos: las coordenadas del punto inicial ey las del punto final de la recta: una recta.py una recta.py 1 create_line(100,100, 900,900)Introducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 73 73 Introducción a la programación con Python - c UJI UJI
    • Ejecuta el programa. Obtendr´s la salida que se muestra en la figura 3.5. a Figura 3.5: Programa que dibuja una recta en la ventana gr´fica del entorno PythonG. a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 46 Dibuja esta figura. (Te indicamos las coordenadas de las esquinas inferior iz-quierda y superior derecha.) (900, 900) (100, 100) .................................................................................. Adem´s de l´ a ıneas rectas, puedes dibujar otros elementos gr´ficos. He aqu´ una relaci´n a ı ode las funciones de creaci´n de elementos gr´ficos que te ofrece PythonG: o a create_point(x, y): dibuja un punto en (x, y). (x, y) create_line(x1, y1, x2, y2): dibuja una l´ ınea de (x1, y1) a (x2, y2). (x2 , y2 ) (x1 , y1 ) create_circle(x, y, radio): dibuja una circunferencia con centro en (x, y) y radio radio. radio (x, y)Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 74 74 Introducción a la programación con Python - UJIUJI c
    • create_rectangle(x1, y1, x2, y2): dibuja un rect´ngulo con esquinas opuestas en a (x1, y1) y (x2, y2). (x2 , y2 ) (x1 , y1 ) create_text(x, y, cadena, tama˜o, anclaje): dibuja el texto cadena en el punto n (x, y). El par´metro tama˜o expresa el tama˜o del tipo de letra en puntos. Un valor a n n razonable para las fuentes es 10 o 12 puntos. El ultimo par´metro, anclaje, indica si ´ a el texto se ˂˂ancla˃˃ al punto (x, y) por el centro (’CENTER’), por la esquina superior izquierda (’NW’), inferior izquierda (’SW’), etc. Esta figura muestra los puntos de anclaje y la cadena que hemos de suministrar como par´metro:a ’CENTER’ ’NW’ ’N’ ’NE’ ’W’ Una cadena anclada ’E’ ’SW’ ’S’ ’SE’ Por ejemplo, create_text(100, 100, ’Hola’, 10, ’NE’) dibuja en pantalla el texto ˂˂Hola˃˃ anclando la esquina superior derecha en las coordenadas (100, 100). (100, 100) Hola create_filled_circle(x, y, radio): dibuja un c´ ırculo relleno (de color negro) con centro en (x, y) y radio radio. create_filled_rectangle(x1, y1, x2, y2): dibuja un rect´ngulo relleno (de color a negro) con esquinas opuestas en (x1, y1) y (x2, y2).. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 47 Dibuja esta figura.Los tres c´ ırculos conc´ntricos tienen radios 100, 200 y 300, respectivamente. e· 48 Dibuja esta figura. a d b cLos tres c´ ırculos conc´ntricos tienen radios 100, 200 y 300, respectivamente. eIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 75 75 Introducción a la programación con Python - UJIUJI c
    • .................................................................................. Has de saber que todas las funciones de creaci´n de elementos gr´ficos aceptan un o apar´metro opcional: una cadena que puede tomar el valor ’white’ (blanco), ’black’ a(negro), ’red’ (rojo), ’blue’ (azul), ’green’ (verde), ’yellow’ (amarillo), ’cyan’ (ci´n) ao ’magenta’ (magenta). Con ese par´metro se indica el color del elemento. Si se omite, atoma el valor por defecto ’black’.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 49 Dibuja esta figura. a d b c(Hemos usado los colores amarillo y magenta para las l´ ıneas rectas, verde y azul paralos c´ ırculos y negro para las letras.) .................................................................................. Vamos a hacer un primer programa con salida gr´fica y que presente cierta utilidad: un aprograma que muestra el porcentaje de suspensos, aprobados, notables y sobresalientesde una asignatura mediante un ˂˂gr´fico de pastel˃˃. He aqu´ un ejemplo de gr´fico como a ı ael que deseamos para una tasa de suspensos del 10%, un 20% de aprobados, un 40% denotables y un 30% de sobresalientes: Apr (20 %) Sus (10 %) Not (40 %) Sob (30 %) Empecemos. El c´ ırculo resulta f´cil: tendr´ centro en (500, 500) y su radio ser´ de a a a500 unidades. As´ conseguimos que ocupe la mayor proporci´n posible de pantalla. ı o pastel 8.py pastel.py 1 create_circle(500,500, 500) Mejor vamos a independizar relativamente el programa del centro y radio de la cir-cunferencia: pastel 9.py pastel.py 1 x = 500 2 y = 500 3 radio = 500 4 create_circle(x, y, radio)De este modo, cambiar la ubicaci´n o el tama˜o del gr´fico de pastel resultar´ sencillo. o n a aSigamos. Vamos a dibujar el corte de las personas que han suspendido, o sea, nuestroobjetivo ahora es conseguir este dibujo:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 76 76 Introducción a la programación con Python - UJIUJI c
    • Hemos de dibujar dos l´ ıneas. La l´ ınea horizontal es muy sencilla: parte de (x, y) yllega a (x + radio, y): pastel 10.py pastel.py 1 x = 500 2 y = 500 3 radio = 500 4 create_circle(x, y, radio) 5 create_line(x, y, x+radio, y) La segunda l´ ınea es m´s complicada. ¿Qu´ coordenadas tiene el punto (x1 , y1 ) de a eesta figura: (x1 , y1 ) α (x, y) radio Un poco de trigonometr´ nos vendr´ bien. Si conoci´semos el angulo α, el c´lculo ıa a e ´ aresultar´ sencillo: ıa x1 = x + radio cos(α) y1 = y + radio sin(α)El angulo α representa la porci´n del c´ ´ o ırculo que corresponde a los suspensos. Como unacircunferencia completa recorre un angulo de 2π radianes, y los suspensos constituyen el ´10% del total, el angulo α es 2π · 10/100 o, para que quede m´s claro, 2π · suspensos/100. ´ a pastel 11.py pastel.py 1 from math import sin, cos, pi 2 3 x = 500 4 y = 500 5 radio = 500 6 suspensos = 10 7 aprobados = 20 8 notables = 40 9 sobresalientes = 301011 create_circle(x, y, radio)12 create_line(x, y, x+radio, y)1314 alfa = 2*pi*suspensos/10015 create_line(x, y, x+radio*cos(alfa), y+radio*sin(alfa))Ya est´. De paso, hemos preparado variables para almacenar el porcentaje de suspensos, aaprobados, etc. Vamos a por la siguiente l´ınea, la que corresponde a los aprobados. ¿Qu´ valor epresenta el angulo β? Si lo conocemos, es inmediato conocer x2 e y2 : ´ (x2 , y2 ) β (x, y) radioIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 77 77 Introducción a la programación con Python - cUJI UJI
    • Podr´ pensar que si α se calcul´ como 2π ·suspensos/100, β ser´ 2π ·aprobados/100. ıas o aPero te equivocas. El angulo β no representa el 20% de la circunferencia, sino el 30%, ´que es el resultado de sumar aprobados y suspensos: β = 2π · (suspensos + aprobados)/100 pastel 12.py pastel.py 1 from math import sin, cos, pi 2 3 x = 500 4 y = 500 5 radio = 500 6 suspensos = 10 7 aprobados = 20 8 notables = 40 9 sobresalientes = 301011 create_circle(x, y, radio)12 create_line(x, y, x+radio, y)1314 alfa = 2*pi*suspensos/10015 create_line(x, y, x+radio*cos(alfa), y+radio*sin(alfa))1617 beta = 2*pi*(suspensos+aprobados)/10018 create_line(x, y, x+radio*cos(beta), y+radio*sin(beta)) Te vamos a dejar que completes t´ mismo el programa incluyendo a los notables y usobresalientes. Acabaremos presentando, eso s´ el modo en que ponemos las leyendas ı,que indican a qu´ corresponde cada parte del pastel. Queremos etiquetar as´ el primer e ıfragmento: sus (10 %)Usaremos la funci´n create_text. Necesitamos determinar las coordenadas del centro del otexto, que cae en el centro justo de la porci´n de pastel que corresponde a los suspensos. o α/2El punto tiene por coordenadas (0.5radio cos(α/2), 0.5radio sin(α/2)): pastel 13.py pastel.py 1 from math import sin, cos, pi 2 3 x = 500 4 y = 500Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 78 78 Introducción a la programación con Python - cUJI UJI
    • 5 radio = 500 6 suspensos = 10 7 aprobados = 20 8 notables = 40 9 sobresalientes = 301011 create_circle(x, y, radio)12 create_line(x, y, x+radio, y)1314 alfa = 2*pi*suspensos/10015 create_line(x, y, x+radio*cos(alfa), y+radio*sin(alfa))16 create_text(x+.5*radio*cos(alfa/2), y+.5*radio*sin(alfa/2),’sus␣(%d%%)’ % suspensos)1718 beta = 2*pi*(suspensos+aprobados)/10019 create_line(x, y, x+radio*cos(beta), y+radio*sin(beta)) ¿Y la leyenda de los aprobados? ¿Qu´ coordenadas tiene su centro? F´ e ıjate bien encu´nto vale el angulo que determina su posici´n: a ´ o α + (β − α)/2 Ya est´: a pastel 14.py pastel.py 1 from math import sin, cos, pi 2 3 x = 500 4 y = 500 5 radio = 500 6 suspensos = 10 7 aprobados = 20 8 notables = 40 9 sobresalientes = 301011 create_circle(x, y, radio)12 create_line(x, y, x+radio, y)1314 alfa = 2*pi*suspensos/10015 create_line(x, y, x+radio*cos(alfa), y+radio*sin(alfa))16 create_text(x+.5*radio*cos(alfa/2), y+.5*radio*sin(alfa/2),’sus␣(%d%%)’ % suspensos)1718 beta = 2*pi*(suspensos+aprobados)/10019 create_line(x, y, x+radio*cos(beta), y+radio*sin(beta))20 create_text(x+.5*radio*cos(alfa+(beta-alfa)/2), 21 y+.5*radio*sin(alfa+(beta-alfa)/2),’apr␣(%d%%)’ % aprobados Observa la l´ ınea 20. Acaba en una barra invertida y la sentencia contin´a en la ul´ ınea 21. Es una forma de indicar a Python que la sentencia es demasiado larga paraque resulte c´modo o legible disponerla en una sola l´ o ınea y que, por tanto, contin´a en ula siguiente l´ınea. Ponemos ´nfasis en ˂˂acaba˃˃ porque la barra invertida ˂˂˃˃ debe ir einmediatamente seguida de un salto de l´ınea. Si pones un espacio en blanco o cualquierotro car´cter detr´s, Python se˜alar´ un error. Lo cierto es que la barra era innecesaria. a a n aIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 79 79 Introducción a la programación con Python - cUJI UJI
    • Si una l´ ınea finaliza sin que se hayan cerrado todos los par´ntesis (o llaves, o corchetes) eabiertos, puede continuar en la siguiente l´ ınea. Completa el programa t´ mismo. u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 50 Modifica el programa para que sea el usuario quien proporcione, mediante elteclado, el valor del porcentaje de suspensos, aprobados, notables y sobresalientes.· 51 Modifica el programa para que sea el usuario quien proporcione, mediante elteclado, el n´mero de suspensos, aprobados, notables y sobresalientes. (Antes de dibujar uel gr´fico de pastel debes convertir esas cantidades en porcentajes.) a· 52 Queremos representar la informaci´n de forma diferente: mediante un gr´fico de o abarras. He aqu´ c´mo: ı o 40 % 30 % 20 % 10 % Sus Apr Not SobDise˜a un programa que solicite por teclado el n´mero de personas con cada una de las n ucuatro calificaciones y muestre el resultado con un gr´fico de barras. a ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 80 80 Introducción a la programación con Python - UJIUJI c
    • Cap´ ıtulo 4Estructuras de control De ah´ que est´n dando vueltas continuamente, supongo dijo Alicia. ı e Si, as´ es dijo el Sombrerero, conforme se van ensuciando las cosas. ı Pero ¿qu´ ocurre cuando vuelven al principio de nuevo? se atrevi´ a e o preguntar Alicia. LEWIS CARROLL, Alicia a trav´s del espejo. eLos programas que hemos aprendido a construir hasta el momento presentan siempre unamisma secuencia de acciones: 1. Se piden datos al usuario (asignando a variables valores obtenidos con raw_input). 2. Se efect´an c´lculos con los datos introducidos por el usuario, guardando el resul- u a tado en variables (mediante asignaciones). 3. Se muestran por pantalla los resultados almacenados en variables (mediante la sentencia print). Estos programas se forman como una serie de l´ ıneas que se ejecutan una tras otra,desde la primera hasta la ultima y siguiendo el mismo orden con el que aparecen en el ´fichero: el flujo de ejecuci´n del programa es estrictamente secuencial. o No obstante, es posible alterar el flujo de ejecuci´n de los programas para hacer que: o tomen decisiones a partir de los datos y/o resultados intermedios y, en funci´n de o ´stas, ejecuten ciertas sentencias y otras no; e tomen decisiones a partir de los datos y/o resultados intermedios y, en funci´n de o ´stas, ejecuten ciertas sentencias m´s de una vez. e aEl primer tipo de alteraci´n del flujo de control se efect´a con sentencias condicionales o uo de selecci´n y el segundo tipo con sentencias iterativas o de repetici´n. Las sentencias o oque permiten alterar el flujo de ejecuci´n se engloban en las denominadas estructuras de ocontrol de flujo (que abreviamos con el t´rmino ˂˂estructuras de control˃˃). e Estudiaremos una forma adicional de alterar el flujo de control que permite se˜alar, ndetectar y tratar los errores que se producen al ejecutar un programa: las sentencias deemisi´n y captura de excepciones. o 81 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 81 Introducción a la programación con Python - UJI
    • 4.1. Sentencias condicionales4.1.1. Un programa de ejemplo: resoluci´n de ecuaciones de primer grado oVeamos un ejemplo. Dise˜emos un programa para resolver cualquier ecuaci´n de primer n ogrado de la forma ax + b = 0,donde x es la inc´gnita. o Antes de empezar hemos de responder a dos preguntas: 1. ¿Cu´les son los datos del problema? (Generalmente, los datos del problema se a pedir´n al usuario con raw_input.) a En nuestro problema, los coeficientes a y b son los datos del problema. 2. ¿Qu´ deseamos calcular? (T´ e ıpicamente, lo que calculemos se mostrar´ al usuario a mediante una sentencia print.) Obviamente, el valor de x. Ahora que conocemos los datos de entrada y el resultado que hemos de calcular, esdecir, los datos de salida, nos preguntamos: ¿c´mo calculamos la salida a partir de la oentrada? En nuestro ejemplo, despejando x de la ecuaci´n llegamos a la conclusi´n de o oque x se obtiene calculando −b/a. Siguiendo el esquema de los programas que sabemos hacer, procederemos as´ ı: 1. Pediremos el valor de a y el valor de b (que supondremos de tipo flotante). 2. Calcularemos el valor de x como −b/a. 3. Mostraremos por pantalla el valor de x. Escribamos el siguiente programa en un fichero de texto llamado primer grado.py: primer grado 7.py primer grado.py 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 x = -b / a 5 6 print ’Soluci´n:␣’, x oLas l´ ıneas se ejecutan en el mismo orden con el que aparecen en el programa. Ve´moslo afuncionar:Valor de a: 10Valor de b: 2Soluci´n: -0.2 o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 53 Un programador propone el siguiente programa para resolver la ecuaci´n de primer ogrado: 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 a*x+b=0 5 6 print ’Soluci´n:␣’, x o¿Es correcto este programa? Si no, explica qu´ est´ mal. e a Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 82 Introducción a la programación con Python - UJIIntroducci´n a la programaci´n con Python o o 82 c UJI
    • · 54 Otro programador propone este programa: 1 x = -b / a 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 6 print ’Soluci´n:␣’, x o¿Es correcto? Si no lo es, explica qu´ est´ mal. e a .................................................................................. Nuestro programa presenta un punto d´bil: cuando a vale 0, se produce un error de edivisi´n por cero: oValor de a: 0Valor de b: 3Traceback (innermost last): File ’primer_grado.py’, line 3, in ? x = -b / aZeroDivisionError: float division En la medida de lo posible hemos de tratar de evitar los errores en tiempo de ejecuci´n: odetienen la ejecuci´n del programa y muestran mensajes de error poco comprensibles para oel usuario del programa. Si al escribir el programa hemos previsto una soluci´n para todo oposible error de ejecuci´n, podemos (y debemos) tomar el control de la situaci´n en todo o omomento. Errores de ejecuci´n o Hemos dicho que conviene evitar los errores de programa que se producen en tiempo de ejecuci´n y, ciertamente, la industria de desarrollo de software realiza un gran esfuerzo o para que sus productos est´n libres de errores de ejecuci´n. No obstante, el gran tama˜o e o n de los programas y su complejidad (unidos a las prisas por sacar los productos al mercado) hacen que muchos de estos errores acaben haciendo acto de presencia. Todos hemos sufrido la experiencia de, ejecutando una aplicaci´n, obtener un mensaje de error o indicando que se ha abortado la ejecuci´n del programa o, peor a´n, el computador o u se ha quedado ˂˂colgado˃˃. Si la aplicaci´n conten´ datos de trabajo importantes y no o ıa los hab´ ıamos guardado en disco, ´stos se habr´n perdido irremisiblemente. Nada hay e a m´s irritante para el usuario que una aplicaci´n poco estable, es decir, propensa a la a o comisi´n de errores en tiempo de ejecuci´n. o o El sistema operativo es, tambi´n, software, y est´ sujeto a los mismos problemas de e a desarrollo de software que las aplicaciones convencionales. Sin embargo, los errores en el sistema operativo son, por regla general, m´s graves, pues suelen ser ´stos los que a e dejan ˂˂colgado˃˃ al ordenador. El famoso ˂˂sal y vuelve a entrar en la aplicaci´n˃˃ o ˂˂reinicia el computador˃˃ que o suele proponerse como soluci´n pr´ctica a muchos problemas de estos es consecuencia o a de los bajos niveles de calidad de buena parte del software que se comercializa.4.1.2. La sentencia condicional ifEn nuestro programa de ejemplo nos gustar´ detectar si a vale cero para, en ese caso, ıano ejecutar el c´lculo de la cuarta l´ a ınea de primer grado.py, que es la que provoca elerror. ¿C´mo hacer que cierta parte del programa se ejecute o deje de hacerlo en funci´n o ode una condici´n determinada? o Los lenguajes de programaci´n convencionales presentan una sentencia especial cuyo osignificado es:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 83 83 Introducción a la programación con Python - UJIUJI c
    • ˂˂Al llegar a este punto, ejecuta esta(s) acci´n(es) s´lo si esta condici´n es cierta.˃˃ o o oEste tipo de sentencia se denomina condicional o de selecci´n y en Python es de la osiguiente forma: if condici´n: o acci´n o acci´n o ... acci´n o(En ingl´s ˂˂if˃˃ significa ˂˂si˃˃.) e En nuestro caso, deseamos detectar la condici´n ˂˂a no vale 0˃˃ y, s´lo en ese caso, o oejecutar las ultimas l´ ´ ıneas del programa: primer grado 8.py primer grado.py 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 if a != 0: 5 x = -b/a 6 print ’Soluci´n:␣’, x o Analicemos detenidamente las l´ ıneas 4, 5 y 6. En la l´ ınea 4 aparece la sentenciacondicional if seguida de lo que, seg´n hemos dicho, debe ser una condici´n. La condici´n u o ose lee f´cilmente si sabemos que != significa ˂˂es distinto de˃˃. As´ pues, la l´ a ı ınea 4 se lee˂˂si a es distinto de 0˃˃. La l´ınea que empieza con if debe finalizar obligatoriamente condos puntos (:). F´ıjate en que las dos siguientes l´ ıneas se escriben m´s a la derecha. Para adestacar esta caracter´ ıstica, hemos dibujados dos l´ıneas verticales que marcan el nivelal que apareci´ el if. Decimos que esta l´ o ınea presentan mayor indentaci´n o sangrado oque la l´ınea que empieza con if. Esta mayor indentaci´n indica que la ejecuci´n de estas o odos l´ıneas depende de que se satisfaga la condici´n a != 0: s´lo cuando ´sta es cierta o o ese ejecutan las l´ıneas de mayor sangrado. As´ pues, cuando a valga 0, esas l´ ı ıneas no seejecutar´n, evitando de este modo el error de divisi´n por cero. a o Veamos qu´ ocurre ahora si volvemos a introducir los datos que antes provocaron el eerror:Valor de a: 0Valor de b: 3 Mmmm. . . no ocurre nada. No se produce un error, es cierto, pero el programa acabasin proporcionar ninguna informaci´n. Analicemos la causa. Las dos primeras l´ o ıneas delprograma se han ejecutado (nos piden los valores de a y b); la tercera est´ en blanco; ala cuarta l´ınea tambi´n se ha ejecutado, pero dado que la condici´n no se ha cumplido e o(a vale 0), las l´ıneas 5 y 6 se han ignorado y como no hay m´s l´ a ıneas en el programa,la ejecuci´n ha finalizado sin m´s. No se ha producido un error, ciertamente, pero acabar o aas´ la ejecuci´n del programa puede resultar un tanto confuso para el usuario. ı o Veamos qu´ hace este otro programa: e primer grado 9.py primer grado.py 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 if a != 0: 5 x = -b/a 6 print ’Soluci´n:␣’, x o 7 if a == 0: 8 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o oIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 84 84 Introducción a la programación con Python - UJI c UJI
    • Las l´ ıneas 7 y 8 empiezan, nuevamente, con una sentencia condicional. En lugar de !=,el operador de comparaci´n utilizado es ==. La sentencia se lee ˂˂si a es igual a 0˃˃. o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 55 Un estudiante ha tecleado el ultimo programa y, al ejecutarlo, obtiene este mensaje ´de error. File "primer_grado4.py", line 7 if a = 0: ˆSyntaxError: invalid syntax Aqu´ tienes el contenido del fichero que ´l ha escrito: ı e primer grado 10.py E primer grado.py E 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 if a != 0: 5 x = -b/a 6 print ’Soluci´n:␣’, x o 7 if a = 0: 8 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o ´Por m´s que el estudiante lee el programa, no encuentra fallo alguno. El dice que la al´ ınea 7, que es la marcada como err´nea, se lee as´ ˂˂si a es igual a cero. . . ˃˃ ¿Est´ en lo o ı: acierto? ¿Por qu´ se detecta un error? e .................................................................................. Ejecutando el programa con los mismos datos, tenemos ahora:Valor de a: 0Valor de b: 3La ecuaci´n no tiene soluci´n. o o Pero, ante datos tales que a es distinto de 0, el programa resuelve la ecuaci´n: oValor de a: 1Valor de b: -1Soluci´n: 1 o Estudiemos con detenimiento qu´ ha pasado en cada uno de los casos: e a=0yb=3 a = 1 y b = −1 Las l´ıneas 1 y 2 se ejecutan, con lo que Las l´ıneas 1 y 2 se ejecutan, con lo que se leen los valores de a y b. se leen los valores de a y b. ...................................... ...................................... La l´ ınea 4 se ejecuta y el resultado de la La l´ ınea 4 se ejecuta y el resultado de la comparaci´n es falso. o comparaci´n es cierto. o ...................................... ...................................... Las l´ıneas 5 y 6 se ignoran. Se ejecutan las l´ıneas 5 y 6, con lo que se muestra por pantalla el valor de la so- luci´n de la ecuaci´n: Soluci´n: 1. o o o ...................................... ...................................... La l´ ınea 7 se ejecuta y el resultado de la La l´ ınea 7 se ejecuta y el resultado de la comparaci´n es cierto. o comparaci´n es falso. o ...................................... ...................................... La l´ınea 8 se ejecuta y se muestra por La l´ ınea 8 se ignora. pantalla el mensaje ˂˂La ecuaci´n noo tiene soluci´n.˃˃ oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 85 85 Introducción a la programación con Python - UJIUJI c
    • Este tipo de an´lisis, en el que seguimos el curso del programa l´ a ınea a l´ ınea parauna configuraci´n dada de los datos de entrada, recibe el nombre de traza de ejecuci´n. o oLas trazas de ejecuci´n son de gran ayuda para comprender qu´ hace un programa y o elocalizar as´ posibles errores. ı . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 56 Un programador primerizo cree que la l´ ınea 7 de la ultima versi´n de primer grado.py ´ oes innecesaria, as´ que propone esta otra versi´n como soluci´n v´lida: ı o o a primer grado 11.py E primer grado.py E 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 if a != 0: 5 x = -b/a 6 print ’Soluci´n:␣’, x o 7 8 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o oHaz una traza del programa para a = 2 y b = 2. ¿Son correctos todos los mensajes quemuestra por pantalla el programa?..................................................................................4.1.3. Trazas con PythonG: el depuradorEl entorno PythonG te puede ayudar a seguir paso a paso la ejecuci´n de un programa. oIntroduce el texto del programa en una ventana de edici´n y selecciona la opci´n ˂˂Activar o omodo depuraci´n˃˃ del men´ Python. El aspecto del entorno ser´ similar al de la figura 4.1. o u a Figura 4.1: Modo de depuraci´n activado. Aparecen dos nuevos marcos: uno bajo la ventana o de edici´n y otro bajo la consola de entrada/salida. El primero incluye una botonera para o controlar la ejecuci´n del programa. En la ventana de edici´n aparece una l´ o o ınea destacada (la primera): es la siguiente l´ ınea a ejecutar. La l´ ınea que se va a ejecutar a continuaci´n aparece con el fondo destacado. Pulsa oen el bot´n etiquetado con ˂˂Sig. (F8)˃˃ (o pulsa la tecla de funci´n ˂˂F8˃˃) y se ejecutar´ o o ala primera l´ ınea. En la consola se solicita el valor de a. Introduce el valor 0 y pulsa elretorno de carro. Se destacar´ ahora la segunda l´ a ınea (ver figura 4.2).Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 86 86 Introducción a la programación con Python - UJIUJI c
    • Figura 4.2: Modo de depuraci´n. Se va a ejecutar la segunda l´ o ınea. Pulsa nuevamente el bot´n o . Se solicitar´ el valor de b. Introduce el valor a4 y pulsa el retorno de carro. La l´ınea destacada pasa a ser la cuarta (la tercera est´ aen blanco, as´ que el depurador la ignora), como puedes apreciar en la figura 4.3 (a). La ıexpresi´n a o 0 se eval´a a False, as´ que las l´ u ı ıneas 5 y 6 se ignoran y se pasa a lal´ ınea 7 (figura 4.3 (b)) y, al ser a 0 cierto, se sigue con la l´ınea 8 (figura 4.3 (c)). (a) (b) (c) Figura 4.3: Modo de depuraci´n. Tras leer el valor de a y b, se ejecuta la cuarta l´ o ınea (a). Como la condici´n no se satisface, se pasa entonces a la l´ o ınea 7 (b). La condici´n de esa o l´ ınea s´ cumple, as´ que la siguiente l´ ı ı ınea a ejecutar es la ultima (c). ´Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 87 87 Introducción a la programación con Python - cUJI UJI
    • Utiliza el depurador cuando dudes acerca del flujo de ejecuci´n de un programa, es odecir, la secuencia de l´ ıneas ejecutadas, o cuando observes un comportamiento extra˜o nen tus programas.4.1.4. Sentencias condicionales anidadasVamos a realizar un ultimo refinamiento del programa. De momento, cuando a es 0 ´el programa muestra un mensaje que indica que la ecuaci´n no tiene soluci´n. Bueno, o onosotros sabemos que esto no es cierto: si, adem´s, b vale 0, entonces la ecuaci´n tiene a oinfinitas soluciones. Para que el programa d´ una informaci´n correcta vamos a modificarlo e ode modo que, cuando a sea 0, muestre un mensaje u otro en funci´n del valor de b: o primer grado 12.py primer grado.py 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 if a != 0: 5 x = -b/a 6 print ’Soluci´n:␣’, x o 7 if a == 0: 8 if b != 0: 9 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o10 if b == 0:11 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ oF´ıjate en la indentaci´n de las l´ o ıneas. Las l´ ıneas 8–11 est´n m´s a la derecha que la a al´ ınea 7. Ninguna de ellas se ejecutar´ a menos que la condici´n de la l´ a o ınea 7 se satisfaga.M´s a´n, la l´ a u ınea 9 est´ m´s a la derecha que la l´ a a ınea 8, por lo que su ejecuci´n depende odel resultado de la condici´n de dicha l´ o ınea; y la ejecuci´n de la l´ o ınea 11 depende dela satisfacci´n de la condici´n de la l´ o o ınea 10. Recuerda que en los programas Python laindentaci´n determina de qu´ sentencia depende cada bloque de sentencias. o e Pues bien, acabamos de presentar una nueva idea muy potente: las estructuras decontrol pueden anidarse, es decir, aparecer unas ˂˂dentro˃˃ de otras. Esto no ha hecho m´s aque empezar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 57 Indica qu´ l´ e ıneas del ultimo programa (y en qu´ orden) se ejecutar´n para cada ´ e auno de los siguientes casos:a) a = 2 y b = 6. b) a = 0 y b = 3. c) a = 0 y b = −3. d) a = 0 y b = 0.· 58 Dise˜a un programa que lea un n´mero flotante por teclado y muestre por pantalla n uel mensaje ˂˂El n´mero es negativo.˃˃ s´lo si el n´mero es menor que cero. u o u· 59 Dise˜a un programa que lea un n´mero flotante por teclado y muestre por pantalla n uel mensaje ˂˂El n´mero es positivo.˃˃ s´lo si el n´mero es mayor o igual que cero. u o u· 60 Dise˜a un programa que lea la edad de dos personas y diga qui´n es m´s joven, n e ala primera o la segunda. Ten en cuenta que ambas pueden tener la misma edad. En talcaso, hazlo saber con un mensaje adecuado.· 61 Dise˜a un programa que lea un car´cter de teclado y muestre por pantalla el n amensaje ˂˂Es par´ntesis˃˃ s´lo si el car´cter le´ es un par´ntesis abierto o cerrado. e o a ıdo e· 62 Indica en cada uno de los siguientes programas qu´ valores en las respectivas eentradas provocan la aparici´n de los distintos mensajes. Piensa primero la soluci´n y o ocomprueba luego que es correcta ayud´ndote con el ordenador. aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 88 88 Introducción a la programación con Python - UJIUJI c
    • a) misterio 3.py misterio.py 1 letra = raw_input(’Dame␣una␣letra␣min´scula:␣’) u 2 3 if letra <= ’k’: 4 print ’Es␣de␣las␣primeras␣del␣alfabeto’ 5 if letra >= ’l’: 6 print ’Es␣de␣las␣´ltimas␣del␣alfabeto’ ub) misterio 4.py misterio.py 1 from math import ceil # ceil redondea al alza. 2 3 grados = float(raw_input(’Dame␣un␣´ngulo␣(en␣grados):␣’)) a 4 5 cuadrante = int(ceil(grados) % 360) / 90 6 if cuadrante == 0: 7 print ’primer␣cuadrante’ 8 if cuadrante == 1: 9 print ’segundo␣cuadrante’ 10 if cuadrante == 2: 11 print ’tercer␣cuadrante’ 12 if cuadrante == 3: 13 print ’cuarto␣cuadrante’· 63 ¿Qu´ mostrar´ por pantalla el siguiente programa? e a comparaciones.py comparaciones.py 1 if 14 < 120: 2 print ’Primer␣saludo’ 3 if ’14’ < ’120’: 4 print ’Segundo␣saludo’ .................................................................................. Por lo visto hasta el momento podemos comparar valores num´ricos con valores enum´ricos y cadenas con cadenas. Tanto los valores num´ricos como las cadenas pueden e eser el resultado de una expresi´n que aparezca expl´ o ıcitamente en la propia comparaci´n. oPor ejemplo, para saber si el producto de dos n´meros enteros es igual a 100, podemos uutilizar este programa: compara expresiones.py compara expresiones.py 1 n = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 m = int(raw_input(’Dame␣otro␣n´mero:␣’)) u 3 4 if n * m == 100: 5 print ’El␣producto␣%d␣*␣%d␣es␣igual␣a␣100’ % (n, m) 6 if n * m != 100: 7 print ’El␣producto␣%d␣*␣%d␣es␣distinto␣de␣100’ % (n, m) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 64 Dise˜a un programa que, dado un n´mero entero, muestre por pantalla el men- n usaje ˂˂El n´mero es par.˃˃ cuando el n´mero sea par y el mensaje ˂˂El n´mero es u u uimpar.˃˃ cuando sea impar. (Una pista: un n´mero es par si el resto de dividirlo por 2 es 0, e impar en caso ucontrario.)· 65 Dise˜a un programa que, dado un n´mero entero, determine si ´ste es el doble n u ede un n´mero impar. (Ejemplo: 14 es el doble de 7, que es impar.) uIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 89 89 Introducción a la programación con Python - UJIUJI c
    • · 66 Dise˜a un programa que, dados dos n´meros enteros, muestre por pantalla uno de n uestos mensajes: ˂˂El segundo es el cuadrado exacto del primero.˃˃, ˂˂El segundoes menor que el cuadrado del primero.˃˃ o ˂˂El segundo es mayor que el cuadradodel primero.˃˃, dependiendo de la verificaci´n de la condici´n correspondiente al sig- o onificado de cada mensaje.· 67 Un capital de C euros a un inter´s del x por cien anual durante n a˜os se convierte e nen C · (1 + x/100) n euros. Dise˜a un programa Python que solicite la cantidad C y el ninter´s x y calcule el capital final s´lo si x es una cantidad positiva. e o· 68 Realiza un programa que calcule el desglose en billetes y monedas de una cantidadexacta de euros. Hay billetes de 500, 200, 100, 50, 20, 10 y 5 ¤ y monedas de 2 y 1 ¤. Por ejemplo, si deseamos conocer el desglose de 434 ¤, el programa mostrar´ porapantalla el siguiente resultado:2 billetes de 200 euros.1 billete de 20 euros.1 billete de 10 euros.2 monedas de 2 euros. (¿Que c´mo se efect´a el desglose? Muy f´cil. Empieza por calcular la divisi´n entera o u a oentre la cantidad y 500 (el valor de la mayor moneda): 434 entre 500 da 0, as´ que no hay ıbilletes de 500 ¤ en el desglose; divide a continuaci´n la cantidad 434 entre 200, cabe a o2 y sobran 34, as´ que en el desglose hay 2 billetes de 200 ¤; dividimos a continuaci´n ı o34 entre 100 y vemos que no hay ning´n billete de 100 ¤ en el desglose (cabe a 0); ucomo el resto de la ultima divisi´n es 34, pasamos a dividir 34 entre 20 y vemos que el ´ odesglose incluye un billete de 20 ¤ y a´n nos faltan 14 ¤ por desglosar. . . ) u ..................................................................................4.1.5. Otro ejemplo: resoluci´n de ecuaciones de segundo grado oPara afianzar los conceptos presentados (y aprender alguno nuevo), vamos a presentarotro ejemplo. En esta ocasi´n vamos a resolver ecuaciones de segundo grado, que son de ola forma ax 2 + bx + c = 0. ¿Cu´les son los datos del problema? Los coeficientes a, b y c. ¿Qu´ deseamos calcular? a eLos valores de x que hacen cierta la ecuaci´n. Dichos valores son: o √ √ −b + b2 − 4ac −b − b2 − 4ac x1 = y x2 = . 2a 2aUn programa directo para este c´lculo es: a segundo grado 11.py segundo grado.py 1 from math import sqrt # sqrt calcula la ra´ cuadrada. ız 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 8 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a) 910 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o Ejecutemos el programa:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 90 90 Introducción a la programación con Python - UJIUJI c
    • Valor de a: 2Valor de b: 7Valor de c: 2Soluciones de la ecuaci´n: x1=-0.314 y x2=-3.186 o Un problema evidente de nuestro programa es la divisi´n por cero que tiene lugar ocuando a vale 0 (pues entonces el denominador, 2a, es nulo). Tratemos de evitar elproblema de la divisi´n por cero del mismo modo que antes, pero mostrando un mensaje odistinto, pues cuando a vale 0 la ecuaci´n no es de segundo grado, sino de primer grado. o segundo grado 12.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)10 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o11 if a == 0:12 print ’No␣es␣una␣ecuaci´n␣de␣segundo␣grado.’ o4.1.6. En caso contrario (else)F´ ıjate en que tanto en el ejemplo que estamos desarrollando ahora como en el anteriorhemos recurrido a sentencias condicionales que conducen a ejecutar una acci´n si se ocumple una condici´n y a ejecutar otra si esa misma condici´n no se cumple: o o if condici´n: o acciones if condici´n contraria: o otras accionesEste tipo de combinaci´n es muy frecuente, hasta el punto de que se ha incorporado al olenguaje de programaci´n una forma abreviada que significa lo mismo: o if condici´n: o acciones else: otras accionesLa palabra ˂˂else˃˃ significa, en ingl´s, ˂˂si no˃˃ o ˂˂en caso contrario˃˃. Es muy importante eque respetes la indentaci´n: las acciones siempre un poco a la derecha, y el if y el else, oalineados en la misma columna. segundo grado 13.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)Introducci´n a la programaci´n con Python o o 91 91 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • 10 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o11 else:12 print ’No␣es␣una␣ecuaci´n␣de␣segundo␣grado.’ o El programa no acaba de estar bien. Es verdad que cuando a vale 0, la ecuaci´n es ode primer grado, pero, aunque sabemos resolverla, no lo estamos haciendo. Ser´ mucho ıamejor si, en ese caso, el programa nos ofreciera la soluci´n: o segundo grado 14.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)10 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o11 else:12 x = -c / b13 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o Mmmm. . . a´n hay un problema: ¿Qu´ pasa si a vale 0 y b tambi´n vale 0? La u e esecuencia de l´ ıneas que se ejecutar´n ser´: 1, 2, 3, 4, 5, 6, 7, 11 y 12. De la l´ a a ınea 12 nopasar´ porque se producir´ una divisi´n por cero. a a oValor de a: 0Valor de b: 0Valor de c: 2Traceback (innermost last): File ’segundo_grado.py’, line 12, in ? x = -c / bZeroDivisionError: float division ¿C´mo evitar este nuevo error? Muy sencillo, a˜adiendo nuevos controles con la sen- o ntencia if, tal y como hicimos para resolver correctamente una ecuaci´n de primer grado: o segundo grado 15.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)10 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o11 else:12 if b != 0:13 x = -c / b14 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o15 else:16 if c!= 0:17 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o18 else:19 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ oIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 9292 Introducción a la programación con Python - UJI c UJI
    • Es muy importante que te fijes en que las l´ ıneas 12–19 presentan una indentaci´n tal que otodas ellas dependen del else de la l´ınea 11. Las l´ ıneas 13 y 14 dependen del if de lal´ ınea 12, y las l´ ıneas 16–19 dependen del else de la l´ ınea 15. Estudia bien el programa:aparecen sentencias condicionales anidadas en otras sentencias condicionales que, a suvez, est´n anidadas. ¿Complicado? No tanto. Los principios que aplicamos son siempre los amismos. Si analizas el programa y lo estudias por partes, ver´s que no es tan dif´ de a ıcilentender. Pero quiz´ lo verdaderamente dif´ no sea entender programas con bastantes a ıcilniveles de anidamiento, sino dise˜arlos. n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 69 ¿Hay alguna diferencia entre el programa anterior y este otro cuando los ejecu-tamos? segundo grado 16.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a == 0: 8 if b == 0: 9 if c == 0:10 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o11 else:12 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o13 else:14 x = -c / b15 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o16 else:17 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)18 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)19 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o· 70 ¿Hay alguna diferencia entre el programa anterior y este otro cuando los ejecu-tamos? segundo grado 17.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a == 0 and b == 0 and c == 0: 8 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o 9 else:10 if a == 0 and b == 0:11 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o12 else:13 if a == 0:14 x = -c / b15 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o16 else:17 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)18 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)19 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o· 71 Ejecuta paso a paso, con ayuda del entorno de depuraci´n de PythonG, el oprograma del ejercicio anterior.Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 93 93 Introducción a la programación con Python - UJIUJI c
    • · 72 Dise˜a un programa Python que lea un car´cter cualquiera desde el teclado, y n amuestre el mensaje ˂˂Es una MAY´SCULA˃˃ cuando el car´cter sea una letra may´scula y U a uel mensaje ˂˂Es una MINU ´SCULA˃˃ cuando sea una min´scula. En cualquier otro caso, no umostrar´ mensaje alguno. (Considera unicamente letras del alfabeto ingl´s.) Pista: aunque a ´ eparezca una obviedad, recuerda que una letra es min´scula si est´ entre la ’a’ y la ’z’, u ay may´scula si est´ entre la ’A’ y la ’Z’. u a· 73 Ampl´ la soluci´n al ejercicio anterior para que cuando el car´cter introducido ıa o ano sea una letra muestre el mensaje ˂˂No es una letra˃˃. (Nota: no te preocupes porlas letras e˜e, ce cedilla, vocales acentuadas, etc.) n· 74 Ampl´ el programa del ejercicio anterior para que pueda identificar las letras e˜e ıa nmin´scula y may´scula. u u· 75 Modifica el programa que propusiste como soluci´n al ejercicio 66 sustituyendo otodas las condiciones que sea posible por cl´usulas else de condiciones anteriores. a ..................................................................................4.1.7. Una estrategia de dise˜o: refinamientos sucesivos nEs l´gico que cuando est´s aprendiendo a programar te cueste gran esfuerzo construir o ementalmente un programa tan complicado, pero posiblemente sea porque sigues unaaproximaci´n equivocada: no debes intentar construir mentalmente todo el programa de ouna vez. Es recomendable que sigas una estrategia similar a la que hemos usado aldesarrollar los programas de ejemplo: 1. Primero haz una versi´n sobre papel que resuelva el problema de forma directa o y, posiblemente, un tanto tosca. Una buena estrategia es plantearse uno mismo el problema con unos datos concretos, resolverlo a mano con l´piz y papel y hacer a un esquema con el orden de las operaciones realizadas y las decisiones tomadas. Tu primer programa puede pedir los datos de entrada (con raw_input), hacer los c´lculos del mismo modo que t´ los hiciste sobre el papel (utilizando variables para a u los resultados intermedios, si fuera menester) y mostrar finalmente el resultado del c´lculo (con print). a 2. Analiza tu programa y considera si realmente resuelve el problema planteado: ¿es posible que se cometan errores en tiempo de ejecuci´n?, ¿hay configuraciones de o los datos que son especiales y, para ellas, el c´lculo debe ser diferente? a 3. Cada vez que te plantees una de estas preguntas y tengas una respuesta, modifica el programa en consecuencia. No hagas m´s de un cambio cada vez. a 4. Si el programa ya funciona correctamente para todas las entradas posibles y eres capaz de anticiparte a los posibles errores de ejecuci´n, ¡enhorabuena!, ya casi has o terminado. En caso contrario, vuelve al paso 2. 5. Ahora que ya est´s ˂˂seguro˃˃ de que todo funciona correctamente, teclea el programa a en el ordenador y efect´a el mayor n´mero de pruebas posibles, comprobando u u cuidadosamente que el resultado calculado es correcto. Presta especial atenci´n o a configuraciones extremas o singulares de los datos (los que pueden provocar divisiones por cero o valores muy grandes, o muy peque˜os, o negativos, etc.). Si n el programa calcula algo diferente de lo esperado o si se aborta la ejecuci´n del o programa por los errores detectados, vuelve al paso 2. Nadie es capaz de hacer un programa suficientemente largo de una sentada, empe-zando a escribir por la primera l´ ınea y acabando por la ultima, una tras otra, del mismo ´Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 94 94 Introducción a la programación con Python - UJIUJI c
    • modo que nadie escribe una novela o una sinfon´ de una sentada1 . Lo normal es empezar ıacon un borrador e ir refin´ndolo, mejor´ndolo poco a poco. a a Un error frecuente es tratar de dise˜ar el programa directamente sobre el ordenador, nescribi´ndolo a bote pronto. Es m´s, hay estudiantes que se atreven a empezar con la e aescritura de un programa sin haber entendido bien el enunciado del problema que sepretende resolver. Es f´cil pillarlos en falta: no saben resolver a mano un caso particular adel problema. Una buena pr´ctica, pues, es solucionar manualmente unos pocos ejemplos aconcretos para estar seguros de que conocemos bien lo que se nos pide y c´mo calcularlo. oUna vez superada esta fase, estar´s en condiciones de elaborar un borrador con los pasos aque has de seguir. Cr´enos: es mejor que pienses un rato y dise˜es un borrador del e nalgoritmo sobre papel. Cuando est´s muy seguro de la validez del algoritmo, implem´ntalo e een Python y pru´balo sobre el ordenador. Las pruebas con el ordenador te ayudar´n a e aencontrar errores. Ciertamente es posible utilizar el ordenador directamente, como si fuera el papel.Nada impide que el primer borrador lo hagas ya en pantalla, pero, si lo haces, ver´s que: a Los detalles del lenguaje de programaci´n interferir´n en el dise˜o del algoritmo o a n (˂˂¿he de poner dos puntos al final de la l´ ınea?˃˃, ˂˂¿uso marcas de formato para imprimir los resultados?˃˃, etc.): cuando piensas en el m´todo de resoluci´n del e o problema es mejor hacerlo con cierto grado de abstracci´n, sin tener en cuenta o todas las particularidades de la notaci´n. o Si ya has tecleado un programa y sigue una aproximaci´n incorrecta, te resultar´ o a m´s molesto prescindir de ´l que si no lo has tecleado a´n. Esta molestia conduce a e u a la tentaci´n de ir poniendo parches a tu deficiente programa para ver si se o puede arreglar algo. El resultado ser´, muy probablemente, un programa ilegible, a p´simamente organizado. . . y err´neo. Te costar´ la mitad de tiempo empezar de e o a cero, pero esta vez haciendo bien las cosas: pensando antes de escribir nada.4.1.8. Un nuevo refinamiento del programa de ejemploParece que nuestro programa ya funciona correctamente. Probemos a resolver esta ecua-ci´n: o x 2 + 2x + 3 = 0Valor de a: 1Valor de b: 2Valor de c: 3Traceback (innermost last): File ’segundo_grado.py’, line 8, in ? x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)ValueError: math domain error ¡Nuevamente un error! El mensaje de error es diferente de los anteriores y es un˂˂error de dominio matem´tico˃˃. a El problema es que estamos intentando calcular la ra´ cuadrada de un n´mero ne- ız ugativo en la l´ ınea 8. El resultado es un n´mero complejo, pero el m´dulo math no ˂˂sabe˃˃ u ode n´meros complejos, as´ que sqrt falla y se produce un error. Tambi´n en la l´ u ı e ınea 9se tiene que calcular la ra´ cuadrada de un n´mero negativo, pero como la l´ ız u ınea 8 seejecuta en primer lugar, es ah´ donde se produce el error y se aborta la ejecuci´n. La ı ol´ ınea 9 no llega a ejecutarse. 1 Aunque hay excepciones: cuenta la leyenda que Mozart escrib´ sus obras de principio a fin, sin volver ıaatr´s para efectuar correcciones. aIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 95 95 Introducción a la programación con Python - UJI c UJI
    • El s´ ındrome ˂˂a m´ nunca se me hubiera ocurrido esto˃˃ ı Programar es una actividad que requiere un gran esfuerzo intelectual, no cabe duda, pero sobre todo, ahora que empiezas, es una actividad radicalmente diferente de cualquier otra para la que te vienes preparando desde la ense˜anza primaria. Llevas muchos a˜os n n aprendiendo lengua, matem´ticas, f´ a ısica, etc., pero nunca antes hab´ programado. Los ıas programas que hemos visto en este cap´ ıtulo te deben parecer muy complicados, cuando no lo son tanto. La reacci´n de muchos estudiantes al ver la soluci´n que da el profesor o el libro o o de texto a un problema de programaci´n es decirse ˂˂a m´ nunca se me hubiera ocurrido o ı esto˃˃. Debes tener en cuenta dos factores: La soluci´n final muchas veces esconde la l´ o ınea de razonamiento que permiti´ o llegar a ese programa concreto. Nadie construye los programas de golpe: por regla general se hacen siguiendo refinamientos sucesivos a partir de una primera versi´n bastante tosca. o La soluci´n que se te presenta sigue la l´ o ınea de razonamiento de una persona concreta: el profesor. Puede que tu l´ ınea de razonamiento sea diferente y, sin embargo, igualmente v´lida (¡o incluso mejor!), as´ que tu programa puede no a ı parecerse en nada al suyo y, a la vez, ser correcto. No obstante, te conviene estudiar la soluci´n que te propone el profesor: la lectura de programas escritos o por otras personas es un buen m´todo de aprendizaje y, probablemente, la soluci´n e o que te ofrece resuelva cuestiones en las que no hab´ reparado (aunque s´lo sea ıas o porque el profesor lleva m´s a˜os que t´ en esto de programar). a n u Podemos controlar este error asegur´ndonos de que el t´rmino b2 −4ac (que recibe el a enombre de ˂˂discriminante˃˃) sea mayor o igual que cero antes de calcular la ra´ cuadrada: ız segundo grado 18.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 if b**2 - 4*a*c >= 0: 9 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)10 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)11 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o12 else:13 print ’No␣hay␣soluciones␣reales.’14 else:15 if b != 0:16 x = -c / b17 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o18 else:19 if c !=0:20 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o21 else:22 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 76 Un programador ha intentado solucionar el problema del discriminante negativocon un programa que empieza as´ ı:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 96 96 Introducción a la programación con Python - UJIUJI c
    • E segundo grado.py E 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 if sqrt(b**2 - 4*a*c) >= 0: 9 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)10 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)11 ...Evidentemente, el programa es incorrecto y te sorprender´ saber que algunos estudiantes aproponen soluciones similares a ´sta. El problema estriba en el posible valor negativo edel argumento de sqrt, as´ que la comparaci´n es incorrecta, pues pregunta por el signo ı ode la ra´ de dicho argumento. Pero el programa no llega siquiera a dar soluci´n alguna ız o(bien o mal calculada) cuando lo ejecutamos con, por ejemplo, a = 4, b = 2 y c = 4.¿Qu´ sale por pantalla en ese caso? ¿Por qu´? e e .................................................................................. Dado que s´lo hemos usado sentencias condicionales para controlar los errores, es oposible que te hayas llevado la impresi´n de que ´sta es su unica utilidad. En absoluto. o e ´Vamos a utilizar una sentencia condicional con otro prop´sito. Mira qu´ ocurre cuando o etratamos de resolver la ecuaci´n x 2 − 2x + 1 = 0: oValor de a: 1Valor de b: -2Valor de c: 1Soluciones de la ecuaci´n: x1=1.000 y x2=1.000 o Las dos soluciones son iguales, y queda un tanto extra˜o que el programa muestre nel mismo valor dos veces. Hagamos que, cuando las dos soluciones sean iguales, s´lo se omuestre una de ellas: segundo grado 19.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 if b**2 - 4*a*c >= 0: 9 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a)10 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)11 if x1 == x2:12 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x1 o o13 else:14 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o15 else:16 print ’No␣hay␣soluciones␣reales.’17 else:18 if b != 0:19 x = -c / b20 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o21 else:22 if c !=0:23 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o oIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 97 97 Introducción a la programación con Python - UJI c UJI
    • 24 else:25 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o Optimizaci´n o Podemos plantear un nuevo refinamiento que tiene por objeto hacer un programa m´s a r´pido, m´s eficiente. F´ a a ıjate que en las l´ ıneas 8, 9 y 10 del ultimo programa se calcula ´ cada vez la expresi´n b**2 - 4*a*c. ¿Para qu´ hacer tres veces un mismo c´lculo? Si o e a las tres veces el resultado va a ser el mismo, ¿no es una p´rdida de tiempo repetir el e c´lculo? Podemos efectuar una sola vez el c´lculo y guardar el resultado en una variable. a a segundo grado 20.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 if a != 0: 8 discriminante = b**2 - 4*a*c 9 if discriminante >= 0: 10 x1 = (-b + sqrt( discriminante )) / (2 * a) 11 x2 = (-b - sqrt( discriminante )) / (2 * a) 12 if x1 == x2: 13 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x1 o o 14 else: 15 print ’Soluciones␣de␣la␣ecuaci´n:’,o 16 print ’x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) 17 else: 18 print ’No␣hay␣soluciones␣reales.’ 19 else: 20 if b != 0: 21 x = -c / b 22 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x o o 23 else: 24 if c !=0: 25 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o 26 else: 27 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o Modificar un programa que funciona correctamente para hacer que funcione m´s efi- a cientemente es optimizar el programa. No te obsesiones con la optimizaci´n de tus o programas. Ahora est´s aprendiendo a programar. Aseg´rate de que tus programas fun- a u cionan correctamente. Ya habr´ tiempo para optimizar m´s adelante. a a4.1.9. Otro ejemplo: m´ximo de una serie de n´meros a uAhora que sabemos utilizar sentencias condicionales, vamos con un problema sencillo,pero que es todo un cl´sico en el aprendizaje de la programaci´n: el c´lculo del m´ximo a o a ade una serie de n´meros. u Empezaremos por pedirle al usuario dos n´meros enteros y le mostraremos por pan- utalla cu´l es el mayor de los dos. a Estudia esta soluci´n, a ver qu´ te parece: o e maximo 5.py maximo.pyIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 98 98 Introducción a la programación con Python - c UJI UJI
    • 1 a = int(raw_input(’Dame␣el␣primer␣n´mero:␣’)) u 2 b = int(raw_input(’Dame␣el␣segundo␣n´mero:␣’)) u 3 4 if a > b: 5 maximo = a 6 else: 7 maximo = b 8 9 print ’El␣m´ximo␣es’, maximo a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 77 ¿Qu´ l´ e ıneas del ultimo programa se ejecutan y qu´ resultado aparece por pantalla ´ een cada uno de estos casos?a) a = 2 y b = 3. b) a = 3 y b = 2. c) a = −2 y b = 0. d) a = 1 y b = 1. Analiza con cuidado el ultimo caso. Observa que los dos n´meros son iguales. ¿Cu´l ´ u aes, pues, el m´ximo? ¿Es correcto el resultado del programa? a· 78 Un aprendiz de programador ha dise˜ado este otro programa para calcular el nm´ximo de dos n´meros: a u maximo 6.py maximo.py 1 a = int(raw_input(’Dame␣el␣primer␣n´mero:␣’)) u 2 b = int(raw_input(’Dame␣el␣segundo␣n´mero:␣’)) u 3 4 if a > b: 5 maximo = a 6 if b > a: 7 maximo = b 8 9 print ’El␣m´ximo␣es’, maximo a¿Es correcto? ¿Qu´ pasa si introducimos dos n´meros iguales? e u .................................................................................. Vamos con un problema m´s complicado: el c´lculo del m´ximo de tres n´meros a a a uenteros (que llamaremos a, b y c). He aqu´ una estrategia posible: ı 1. Me pregunto si a es mayor que b y, si es as´ de momento a es candidato a ser el ı, mayor, pero no s´ si lo ser´ definitivamente hasta compararlo con c. Me pregunto, e a pues, si a es mayor que c. a) Si a tambi´n es mayor que c, est´ claro que a es el mayor de los tres. e a b) Y si no, c es el mayor de los tres. 2. Pero si no es as´ es decir, si a es menor o igual que b, el n´mero b es, de momento, ı, u mi candidato a n´mero mayor. Falta compararlo con c. u a) Si tambi´n es mayor que c, entonces b es el mayor. e b) Y si no, entonces c es el mayor. Ahora que hemos dise˜ado el procedimiento, construyamos un programa Python que nimplemente ese algoritmo: maximo de tres 3.py maximo de tres.py 1 a = int(raw_input(’Dame␣el␣primer␣n´mero:␣’)) u 2 b = int(raw_input(’Dame␣el␣segundo␣n´mero:␣’)) u 3 c = int(raw_input(’Dame␣el␣tercer␣n´mero:␣’)) uIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 9999 Introducción a la programación con Python - UJIUJI c
    • 4 5 if a > b: 6 if a > c: 7 maximo =a 8 else: 9 maximo =c10 else:11 if b > c:12 maximo =b13 else:14 maximo =c1516 print ’El␣m´ximo␣es’, maximo a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 79 ¿Qu´ secuencia de l´ e ıneas de este ultimo programa se ejecutar´ en cada uno de ´ aestos casos?a) a = 2, b = 3 y c = 4. b) a = 3, b = 2 y c = 4. c) a = 1, b = 1 y c = 1. Ay´date con el modo de depuraci´n de PythonG. u o .................................................................................. Puede que la soluci´n que hemos propuesto te parezca extra˜a y que t´ hayas di- o n use˜ado un programa muy diferente. Es normal. No existe un unico programa para solucio- n ´nar un problema determinado y cada persona desarrolla un estilo propio en el dise˜o de nlos programas. Si el que se propone como soluci´n no es igual al tuyo, el tuyo no tiene opor qu´ ser err´neo; quiz´ s´lo sea distinto. Por ejemplo, este otro programa tambi´n e o a o ecalcula el m´ximo de tres n´meros, y es muy diferente del que hemos propuesto antes: a u maximo de tres 4.py maximo de tres.py 1 a = int(raw_input(’Dame␣el␣primer␣n´mero:␣’)) u 2 b = int(raw_input(’Dame␣el␣segundo␣n´mero:␣’)) u 3 c = int(raw_input(’Dame␣el␣tercer␣n´mero:␣’)) u 4 5 candidato = a 6 if b > candidato: 7 candidato = b 8 if c > candidato: 9 candidato = c10 maximo = candidato1112 print ’El␣m´ximo␣es’, maximo a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 80 Dise˜a un programa que calcule el m´ximo de 5 n´meros enteros. Si sigues una n a uestrategia similar a la de la primera soluci´n propuesta para el problema del m´ximo de o a3 n´meros, tendr´s problemas. Intenta resolverlo como en el ultimo programa de ejemplo, u a ´es decir con un ˂˂candidato a valor m´ximo˃˃ que se va actualizando al compararse con acada n´mero.u· 81 Dise˜a un programa que calcule la menor de cinco palabras dadas; es decir, la nprimera palabra de las cinco en orden alfab´tico. Aceptaremos que las may´sculas son e u˂˂alfab´ticamente˃˃ menores que las min´sculas, de acuerdo con la tabla ASCII. e u· 82 Dise˜a un programa que calcule la menor de cinco palabras dadas; es decir, la nprimera palabra de las cinco en orden alfab´tico. No aceptaremos que las may´sculas e usean ˂˂alfab´ticamente˃˃ menores que las min´sculas. O sea, ’pepita’ es menor que e u’Pepito’.Introducci´n a la programaci´n con Python o o Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 100 100 c Introducción a la programación con Python - UJIUJI
    • · 83 Dise˜a un programa que, dados cinco n´meros enteros, determine cu´l de los n u acuatro ultimos n´meros es m´s cercano al primero. (Por ejemplo, si el usuario introduce ´ u alos n´meros 2, 6, 4, 1 y 10, el programa responder´ que el n´mero m´s cercano al 2 es u a u ael 1.)· 84 Dise˜a un programa que, dados cinco puntos en el plano, determine cu´l de n alos cuatro ultimos puntos es m´s cercano al primero. Un punto se representar´ con dos ´ a avariables: una para la abcisa y otra para la ordenada. La distancia entre dos puntos(x1 , y1 ) y (x2 , y2) es (x1 − x2 )2 + (y1 − y2 )2 . .................................................................................. Las comparaciones pueden incluir cualquier expresi´n cuyo resultado sea interpre- otable en t´rminos de cierto o falso. Podemos incluir, pues, expresiones l´gicas tan com- e oplicadas como deseemos. F´ ıjate en el siguiente programa, que sigue una aproximaci´n odiferente para resolver el problema del c´lculo del m´ximo de tres n´meros: a a u maximo de tres.py maximo de tres.py 1 a = int(raw_input(’Dame␣el␣primer␣n´mero:␣’)) u 2 b = int(raw_input(’Dame␣el␣segundo␣n´mero:␣’)) u 3 c = int(raw_input(’Dame␣el␣tercer␣n´mero:␣’)) u 4 5 if a >= b and a >= c: 6 maximo = a 7 if b >= a and b >= c: 8 maximo = b 9 if c >= a and c >= b:10 maximo = c11 print ’El␣m´ximo␣es’, maximo aLa expresi´n a >= b and a >= c por ejemplo, se lee ˂˂a es mayor o igual que b y a es omayor o igual que c˃˃. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 85 Indica en cada uno de los siguientes programas qu´ valores o rangos de valores eprovocan la aparici´n de los distintos mensajes: oa) aparcar.py aparcar.py 1 dia = int(raw_input(’Dime␣qu´␣d´a␣es␣hoy:␣’)) e ı 2 3 if 0 < dia <= 15: 4 print ’Puedes␣aparcar␣en␣el␣lado␣izquierdo␣de␣la␣calle’ 5 else: 6 if 15 < dia < 32: 7 print ’Puedes␣aparcar␣en␣el␣lado␣derecho␣de␣la␣calle’ 8 else: 9 print ’Ning´n␣mes␣tiene␣%d␣d´as.’ % dia u ıb) estaciones.py estaciones.py 1 mes = int(raw_input(’Dame␣un␣mes:␣’)) 2 3 if 1 <= mes <= 3: 4 print ’Invierno.’ 5 else: 6 if mes == 4 or mes == 5 or mes == 6: 7 print ’Primavera.’ 8 else: 9 if not (mes < 7 or 9 < mes): 10 print ’Verano.’ 11 else: 12 if not (mes != 10 and mes != 11 and mes != 12):Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 101 101 Introducción a la programación con Python - UJIUJI c
    • 13 print ’Oto˜o.’ n 14 else: 15 print ’Ning´n␣a˜o␣tiene␣%d␣meses.’ % mes u nc) identificador.py identificador.py 1 car = raw_input(’Dame␣un␣car´cter:␣’) a 2 3 if ’a’ <= car.lower() <= ’z’ or car == ’ ’: 4 print ’Este␣car´cter␣es␣v´lido␣en␣un␣identificador␣en␣Python.’ a a 5 else: 6 if not (car < ’0’ or ’9’ < car): 7 print ’Un␣d´gito␣es␣v´lido␣en␣un␣identificador␣en␣Python,’, ı a 8 print ’siempre␣que␣no␣sea␣el␣primer␣car´cter.’ a 9 else: 10 print ’Car´cter␣no␣v´lido␣para␣formar␣un␣identificador␣en␣Python.’ a ad) bisiesto.py bisiesto.py 1 anyo = int(raw_input(’Dame␣un␣a˜o:␣’)) n 2 3 if anyo % 4 == 0 and (anyo % 100 != 0 or anyo % 400 == 0): 4 print ’El␣a˜o␣%d␣es␣bisiesto.’ % anyo n 5 else: 6 print ’El␣a˜o␣%d␣no␣es␣bisiesto.’ % anyo n· 86 La f´rmula C = C ·(1+x/100)n nos permite obtener el capital final que lograremos oa partir de un capital inicial (C ), una tasa de inter´s anual (x) en tanto por cien y un en´mero de a˜os (n). Si lo que nos interesa conocer es el n´mero de a˜os n que tardaremos u n u nen lograr un capital final C partiendo de un capital inicial C a una tasa de inter´s anual ex, podemos despejar n en la f´rmula del ejercicio 67 de la siguiente manera: o log(C ) − log(C ) n= log(1 + x/100) Dise˜a un programa Python que obtenga el n´mero de a˜os que se tarda en conseguir n u nun capital final dado a partir de un capital inicial y una tasa de inter´s anual tambi´n e edados. El programa debe tener en cuenta cu´ndo se puede realizar el c´lculo y cu´ndo a a ano en funci´n del valor de la tasa de inter´s (para evitar una divisi´n por cero, el c´lculo o e o ade logaritmos de valores negativos, etc). . . con una excepci´n: si C y C son iguales, oel n´mero de a˜os es 0 independientemente de la tasa de inter´s (incluso de la que u n eprovocar´ un error de divisi´n por cero). ıa o (Ejemplos: Para obtener 11 000 ¤ por una inversi´n de 10 000 ¤ al 5% anual es onecesario esperar 1.9535 a˜os. Obtener 11 000 ¤ por una inversi´n de 10 000 ¤ al 0% n oanual es imposible. Para obtener 10 000 ¤ con una inversi´n de 10 000 ¤ no hay que oesperar nada, sea cual sea el inter´s.) e· 87 Dise˜a un programa que, dado un n´mero real que debe representar la calificaci´n n u onum´rica de un examen, proporcione la calificaci´n cualitativa correspondiente al n´mero e o udado. La calificaci´n cualitativa ser´ una de las siguientes: ˂˂Suspenso˃˃ (nota menor que o a5), ˂˂Aprobado˃˃ (nota mayor o igual que 5, pero menor que 7), ˂˂Notable˃˃ (nota mayor oigual que 7, pero menor que 8.5), ˂˂Sobresaliente˃˃ (nota mayor o igual que 8.5, pero menorque 10), ˂˂Matr´ıcula de Honor˃˃ (nota 10).· 88 Dise˜a un programa que, dado un car´cter cualquiera, lo identifique como vocal n amin´scula, vocal may´scula, consonante min´scula, consonante may´scula u otro tipo de u u u ucar´cter. a ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 102 102 Introducción a la programación con Python - UJIUJI c
    • De Morgan Las expresiones l´gicas pueden resultar complicadas, pero es que los programas hacen, o en ocasiones, comprobaciones complicadas. Tal vez las m´s dif´ a ıciles de entender son las que comportan alg´n tipo de negaci´n, pues generalmente nos resulta m´s dif´ u o a ıcil razonar en sentido negativo que afirmativo. A los que empiezan a programar les l´ ıan muy frecuentemente las negaciones combinadas con or o and. Veamos alg´n ejemplo u ˂˂de juguete˃˃. Sup´n que para aprobar una asignatura hay que obtener m´s de un 5 o a en dos ex´menes parciales, y que la nota de cada uno de ellos est´ disponible en las a a variables parcial1 y parcial2, respectivamente. Estas l´ ıneas de programa muestran el mensaje ˂˂Has suspendido.˃˃ cuando no has obtenido al menos un 5 en los dos ex´menes: a if not (parcial1 >= 5.0 and parcial2 >= 5.0): print ’Has␣suspendido.’ Lee bien la condici´n: ˂˂si no es cierto que has sacado al menos un 5 en ambos (por eso o el and) parciales. . . ˃˃. Ahora f´ ıjate en este otro fragmento: if not parcial1 >= 5.0 or not parcial2 >= 5.0: print ’Has␣suspendido.’ Le´moslo: ˂˂si no has sacado al menos un cinco en uno u otro (por eso el or) parcial. . . ˃˃. a O sea, los dos fragmentos son equivalentes: uno usa un not que se aplica al resultado de una operaci´n and; el otro usa dos operadores not cuyos resultados se combinan con o un operador or. Y sin embargo, dicen la misma cosa. Los l´gicos utilizan una notaci´n o o especial para representar esta equivalencia: ¬(p ∧ q) ←→ ¬p ∨ ¬q, ¬(p ∨ q) ←→ ¬p ∧ ¬q. (Los l´gicos usan ‘¬’ para not, ‘∧’ para and y ‘∨’ para or.) Estas relaciones se deben al o matem´tico De Morgan, y por ese nombre se las conoce. Si es la primera vez que las a ves, te resultar´n chocantes, pero si piensas un poco, ver´s que son de sentido com´n. a a u Hemos observado que los estudiantes comet´is errores cuando hay que expresar la e condici´n contraria a una como ˂˂a and b˃˃. Muchos escrib´ ˂˂not a and not b˃˃ y est´ o ıs a mal. La negaci´n correcta ser´ ˂˂not (a and b)˃˃ o, por De Morgan, ˂˂not a or not b˃˃. o ıa ¿Cu´l ser´ por cierto, la negaci´n de ˂˂a or not b˃˃? a ıa, o4.1.10. Evaluaci´n con cortocircuitos oLa evaluaci´n de expresiones l´gicas es algo especial. Observa la condici´n de este if: o o o if a == 0 or 1/a > 1: ...¿Puede provocar una divisi´n por cero? No, nunca. Observa que si a vale cero, el primer ot´rmino del or es True. Como la evaluaci´n de una o l´gica de True con cualquier otro e o ovalor, True o False, es necesariamente True, Python no eval´a el segundo t´rmino y se u eahorra as´ un esfuerzo innecesario. ı Algo similar ocurre en este otro caso: if a != 0 and 1/a > 1: ...Si a es nulo, el valor de a != 0 es falso, as´ que ya no se procede a evaluar la segunda ıparte de la expresi´n. o Al calcular el resultado de una expresi´n l´gica, Python eval´a (siguiendo las reglas o o ude asociatividad y precedencia oportunas) lo justo hasta conocer el resultado: cuando elIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 103 103 Introducción a la programación con Python - c UJI UJI
    • primer t´rmino de un or es cierto, Python acaba y devuelve directamente cierto y cuando eel primer t´rmino de un and es falso, Python acaba y devuelve directamente falso. Este emodo de evaluaci´n se conoce como evaluaci´n con cortocircuitos. o o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 89 ¿Por qu´ obtenemos un error en esta sesi´n de trabajo con el int´rprete interactivo? e o e ↱>>> a = 0 ↱>>> if 1/a > 1 and a != 0: ↱... print a ↱...Traceback (most recent call last): File "<stdin>", line 1, in ?ZeroDivisionError: integer division or modulo by zero ..................................................................................4.1.11. Un ´ltimo problema: men´s de usuario u uYa casi acabamos esta (largu´ ısima) secci´n. Introduciremos una nueva estructura sint´ctica o aplanteando un nuevo problema. El problema es el siguiente: imagina que tenemos unprograma que a partir del radio de una circunferencia calcula su di´metro, per´ a ımetro oarea. S´lo queremos mostrar al usuario una de las tres cosas, el di´metro, el per´´ o a ımetro oel area; la que ´l desee, pero s´lo una. ´ e o Nuestro programa podr´ empezar pidiendo el radio del c´ ıa ırculo. A continuaci´n, podr´ o ıamostrar un men´ con tres opciones: ˂˂calcular el di´metro˃˃, ˂˂calcular el per´ u a ımetro˃˃ y˂˂calcular el area˃˃. Podr´ ´ ıamos etiquetar cada opci´n con una letra y hacer que el usuario otecleara una de ellas. En funci´n de la letra tecleada, calcular´ o ıamos una cosa u otra. Analiza este programa: circulo 5.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 # Men´ u 6 print ’Escoge␣una␣opci´n:␣’ o 7 print ’a)␣Calcular␣el␣di´metro.’ a 8 print ’b)␣Calcular␣el␣per´metro.’ ı 9 print ’c)␣Calcular␣el␣´rea.’ a10 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)1112 if opcion == ’a’: # C´lculo del di´metro. a a13 diametro = 2 * radio14 print ’El␣di´metro␣es’, diametro a15 else:16 if opcion == ’b’: # C´lculo del per´ a ımetro.17 perimetro = 2 * pi * radio18 print ’El␣per´metro␣es’, perimetro ı19 else:20 if opcion == ’c’: # C´lculo del area. a ´21 area = pi * radio ** 222 print ’El␣´rea␣es’, area a Ejecutemos el programa y seleccionemos la segunda opci´n: oDame el radio de un c´rculo: 3 ıEscoge una opci´n: oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 104 104 Introducción a la programación con Python - UJIUJI c
    • a) Calcular el di´metro. ab) Calcular el per´metro. ıc) Calcular el ´rea. aTeclea a, b o c y pulsa el retorno de carro: bEl per´metro es 18.8495559215 ı Ejecut´moslo de nuevo, pero seleccionando esta vez la tercera opci´n: e oDame el radio de un c´rculo: 3 ıEscoge una opci´n: oa) Calcular el di´metro. ab) Calcular el per´metro. ıc) Calcular el ´rea. aTeclea a, b o c y pulsa el retorno de carro: cEl ´rea es 28.2743338823 a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 90 Nuestro aprendiz de programador ha tecleado en su ordenador el ultimo programa, ´pero se ha despistado y ha escrito esto: circulo 6.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 print ’Escoge␣una␣opci´n:␣’ o 6 print ’a)␣Calcular␣el␣di´metro.’ a 7 print ’b)␣Calcular␣el␣per´metro.’ ı 8 print ’c)␣Calcular␣el␣´rea.’ a 9 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)1011 if opcion == a:12 diametro = 2 * radio13 print ’El␣di´metro␣es’, diametro a14 else:15 if opcion == b:16 perimetro = 2 * pi * radio17 print ’El␣per´metro␣es’, perimetro ı18 else:19 if opcion == c:20 area = pi * radio ** 221 print ’El␣´rea␣es’, area aLas l´ ıneas sombreadas son diferentes de sus equivalentes del programa original. ¿Fun-cionar´ el programa del aprendiz? Si no es as´ ¿por qu´ motivo?. a ı, e .................................................................................. Acabemos de pulir nuestro programa. Cuando el usuario no escribe ni la a, ni lab, ni la c al tratar de seleccionar una de las opciones, deber´ ıamos decirle que se haequivocado: circulo 7.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 print ’Escoge␣una␣opci´n:␣’ o 6 print ’a)␣Calcular␣el␣di´metro.’ aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 105 105 c Introducción a la programación con Python - UJIUJI
    • 7 print ’b)␣Calcular␣el␣per´metro.’ ı 8 print ’c)␣Calcular␣el␣´rea.’ a 9 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)1011 if opcion == ’a’:12 diametro = 2 * radio13 print ’El␣di´metro␣es’, diametro a14 else:15 if opcion == ’b’:16 perimetro = 2 * pi * radio17 print ’El␣per´metro␣es’, perimetro ı18 else:19 if opcion == ’c’:20 area = pi * radio ** 221 print ’El␣´rea␣es’, area a22 else:23 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.’ o24 print ’T´␣has␣tecleado’, opcion u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 91 Haz una traza del programa suponiendo que el usuario teclea la letra d cuandose le solicita una opci´n. ¿Qu´ l´ o e ıneas del programa se ejecutan?· 92 El programa presenta un punto d´bil: si el usuario escribe una letra may´scula e uen lugar de min´scula, no se selecciona ninguna opci´n. Modifica el programa para que u otambi´n acepte letras may´sculas. e u ..................................................................................4.1.12. Una forma compacta para estructuras condicionales m´ltiples (elif) uEl ultimo programa presenta un problema est´tico: la serie de l´ ´ e ıneas que permiten se-leccionar el c´lculo que hay que efectuar en funci´n de la opci´n de men´ seleccionada a o o u(l´ ıneas 11–24) parece m´s complicada de lo que realmente es. Cada opci´n aparece in- a odentada m´s a la derecha que la anterior, as´ que el c´lculo del area acaba con tres a ı a ´niveles de indentaci´n. Imagina qu´ pasar´ si el men´ tuviera 8 o 9 opciones: ¡el pro- o e ıa ugrama acabar´ tan a la derecha que pr´cticamente se saldr´ del papel! Python permite ıa a ıauna forma compacta de expresar fragmentos de c´digo de la siguiente forma: o if condici´n: o ... else: if otra condici´n: o ...Un else inmediatamente seguido por un if puede escribirse as´ ı: if condici´n: o ... elif otra condici´n: o ...con lo que nos ahorramos una indentaci´n. El ultimo programa se convertir´ pues, en o ´ ıa,este otro: circulo 8.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 106 106 Introducción a la programación con Python - UJIUJI c
    • 5 print ’Escoge␣una␣opci´n:␣’ o 6 print ’a)␣Calcular␣el␣di´metro.’ a 7 print ’b)␣Calcular␣el␣per´metro.’ ı 8 print ’c)␣Calcular␣el␣´rea.’ a 9 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)1011 if opcion == ’a’:12 diametro = 2 * radio13 print ’El␣di´metro␣es’, diametro a14 elif opcion == ’b’:15 perimetro = 2 * pi * radio16 print ’El␣per´metro␣es’, perimetro ı17 elif opcion == ’c’:18 area = pi * radio ** 219 print ’El␣´rea␣es’, area a20 else:21 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.␣T´␣has␣tecleado’, opcion o u El programa es absolutamente equivalente, ocupa menos l´ ıneas y gana mucho enlegibilidad: no s´lo evitamos mayores niveles de indentaci´n, tambi´n expresamos de o o eforma clara que, en el fondo, todas esas condiciones est´n relacionadas. a Formas compactas: ¿complicando las cosas? Puede que comprender la estructura condicional if te haya supuesto un esfuerzo consi- derable. A eso has tenido que a˜adir la forma if-else. ¡Y ahora el if-elif! Parece que no n hacemos m´s que complicar las cosas. M´s bien todo lo contrario: las formas if-else e a a if-elif (que tambi´n acepta un if-elif-else) debes considerarlas una ayuda. En realidad, e ninguna de estas formas permite hacer cosas que no pudi´ramos hacer con s´lo el if, e o aunque, eso s´ necesitando un esfuerzo mayor. ı, Mientras est´s dando tus primeros pasos en la programaci´n, si dudas sobre qu´ e o e forma utilizar, trata de expresar tu idea con s´lo el if. Una vez tengas una soluci´n, o o plant´ate si tu programa se beneficiar´ del uso de una forma compacta. Si es as´ e ıa ı, usala. M´s adelante seleccionar´s instintivamente la forma m´s apropiada para cada ´ a a a caso. Bueno, eso cuando hayas adquirido bastante experiencia, y s´lo la adquirir´s o a practicando.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 93 Modifica la soluci´n del ejercicio 87 usando ahora la estructura elif. ¿No te parece om´s legible la nueva soluci´n? a o..................................................................................4.2. Sentencias iterativasA´n vamos a presentar una ultima reflexi´n sobre el programa de los men´s. Cuando el u ´ o uusuario no escoge correctamente una opci´n del men´ el programa le avisa, pero finaliza o uinmediatamente. Lo ideal ser´ que cuando el usuario se equivocara, el programa le pidiera ıade nuevo una opci´n. Para eso ser´ necesario repetir la ejecuci´n de las l´ o ıa o ıneas 11–21.Una aproximaci´n na¨ consistir´ b´sicamente, en a˜adir al final una copia de esas l´ o ıf ıa, a n ıneasprecedidas de un if que comprobara que el usuario se equivoc´. Pero esa aproximaci´n o oes muy mala: ¿qu´ pasar´ si el usuario se equivocara una segunda vez? Cuando decimos e ıaque queremos repetir un fragmento del programa no nos referimos a copiarlo de nuevo,sino a ejecutarlo otra vez. Pero, ¿es posible expresar en este lenguaje que queremos quese repita la ejecuci´n de un trozo del programa? oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 107 107 Introducción a la programación con Python - UJIUJI c
    • Python permite indicar que deseamos que se repita un trozo de programa de dosformas distintas: mediante la sentencia while y mediante la sentencia for. La primera deellas es m´s general, por lo que la estudiaremos en primer lugar. a4.2.1. La sentencia whileEn ingl´s, ˂˂while˃˃ significa ˂˂mientras˃˃. La sentencia while se usa as´ e ı: while condici´n: o acci´n o acci´n o ... acci´n oy permite expresar en Python acciones cuyo significado es: ˂˂Mientras se cumpla esta condici´n, repite estas acciones.˃˃ oLas sentencias que denotan repetici´n se denominan bucles. o Vamos a empezar estudiando un ejemplo y viendo qu´ ocurre paso a paso. Estudia edetenidamente este programa: contador 3.py contador.py 1 i=0 2 while i < 3: 3 print i 4 i += 1 5 print ’Hecho’Observa que la l´ınea 2 finaliza con dos puntos (:) y que la indentaci´n indica que las ol´ ıneas 3 y 4 dependen de la l´ ınea 2, pero no la l´ ınea 5. Podemos leer el programa as´ı:primero, asigna a i el valor 0; a continuaci´n, mientras i sea menor que 3, repite estas oacciones: muestra por pantalla el valor de i e incrementa i en una unidad; finalmente,muestra por pantalla la palabra ˂˂Hecho˃˃. Si ejecutamos el programa, por pantalla aparecer´ el siguiente texto: a012Hecho Veamos qu´ ha ocurrido paso a paso con una traza. e Se ha ejecutado la l´ ınea 1, con lo que i vale 0. Despu´s, se ha ejecutado la l´ e ınea 2, que dice ˂˂mientras i sea menor que 3, hacer. . . ˃˃. Primero se ha evaluado la condici´n i < 3, que ha resultado ser cierta. Como la o condici´n se satisface, deben ejecutarse las acciones supeditadas a esta l´ o ınea (las l´ ıneas 3 y 4). Se ejecuta en primer lugar la l´ ınea 3, que muestra el valor de i por pantalla. Aparece, pues, un cero. Se ejecuta a continuaci´n la l´ o ınea 4, que incrementa el valor de i. Ahora i vale 1. ¡Ojo!, ahora no pasamos a la l´ ınea 5, sino que volvemos a la l´ ınea 2. Cada vez que finalizamos la ejecuci´n de las acciones que dependen de un while, volvemos a la o l´ ınea del while.Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 108 108 Introducción a la programación con Python - UJI c UJI
    • i = 0 while i <3: ⇐ la condici´n se satisface o print i i += 1 print ’Hecho’ Estamos nuevamente en la l´ ınea 2, as´ que comprobamos si i es menor que 3. Es ı as´ por lo que toca ejecutar de nuevo las l´ ı, ıneas 3 y 4. Volvemos a ejecutar la l´ ınea 3, as´ que aparece un 1 por pantalla. ı Volvemos a ejecutar la l´ ınea 4, con lo que i vuelve a incrementarse y pasa de valer 1 a valer 2. Nuevamente pasamos a la l´ ınea 2. Siempre que acaba de ejecutarse la ultima acci´n ´ o de un bucle while, volvemos a la l´ ınea que contiene la palabra ·while·. Como i sigue siendo menor que 3, deberemos repetir las acciones expresadas en las l´ ıneas 3 y 4. As´ que ejecutamos otra vez la l´ ı ınea 3 y en pantalla aparece el n´mero 2. u Incrementamos de nuevo el valor de i, como indica la l´ ınea 4, as´ que i pasa de ı valer 2 a valer 3. Y de nuevo pasamos a la l´ ınea 2. Pero ahora ocurre algo especial: la condici´n no o se satisface, pues i ya no es menor que 3. Como la condici´n ya no se satisface, no o hay que ejecutar otra vez las l´ıneas 3 y 4. Ahora hemos de ir a la l´ınea 5, que es la primera l´ınea que no est´ ˂˂dentro˃˃ del bucle. a i = 0 while i <3: ⇐ la condici´n no se satisface o print i i += 1 print ’Hecho’ Se ejecuta la l´ ınea 5, que muestra por pantalla la palabra ˂˂Hecho˃˃ y finaliza el programa.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 94 Ejecuta el ultimo programa paso a paso con el entorno de depuraci´n de PythonG. ´ o.................................................................................. Pero, ¿por qu´ tanta complicaci´n? Este otro programa muestra por pantalla lo mismo, e ose entiende m´s f´cilmente y es m´s corto. a a a contador simple.py 1 print 0 2 print 1 3 print 2 4 print ’Hecho’Bueno, contador.py es un programa que s´lo pretende ilustrar el concepto de bucle, oas´ que ciertamente no hace nada demasiado util, pero aun as´ nos permite vislumbrar la ı ´ ıpotencia del concepto de iteraci´n o repetici´n. Piensa en qu´ ocurre si modificamos un o o es´lo n´mero del programa: o u 109 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9Introducci´n a la programaci´n con Python o o 109 Introducción a la programación con Python - UJI c UJI
    • contador 4.py contador.py 1 i=0 2 while i < 1000: 3 print i 4 i += 1 5 print ’Hecho’¿Puedes escribir f´cilmente un programa que haga lo mismo y que no utilice bucles? a. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 95 Haz una traza de este programa: ejercicio bucle 9.py ejercicio bucle.py 1 i=0 2 while i <= 3: 3 print i 4 i += 1 5 print ’Hecho’· 96 Haz una traza de este programa: ejercicio bucle 10.py ejercicio bucle.py 1 i=0 2 while i < 10: 3 print i 4 i += 2 5 print ’Hecho’· 97 Haz una traza de este programa: ejercicio bucle 11.py ejercicio bucle.py 1 i=3 2 while i < 10: 3 i += 2 4 print i 5 print ’Hecho’· 98 Haz una traza de este programa: ejercicio bucle 12.py ejercicio bucle.py 1 i=1 2 while i < 100: 3 i *= 2 4 print i· 99 Haz una traza de este programa: ejercicio bucle 13.py ejercicio bucle.py 1 i = 10 2 while i < 2: 3 i *= 2 4 print i· 100 Haz unas cuantas trazas de este programa para diferentes valores de i. ejercicio bucle 14.py ejercicio bucle.py 1 i = int(raw_input(’Valor␣inicial:␣’)) 2 while i < 10: 3 print i 4 i += 1¿Qu´ ocurre si el valor de i es mayor o igual que 10? ¿Y si es negativo? eIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 110 110 Introducción a la programación con Python - UJIUJI c
    • · 101 Haz unas cuantas trazas de este programa para diferentes valores de i y delimite. ejercicio bucle 15.py ejercicio bucle.py 1 i = int(raw_input(’Valor␣inicial:␣’)) 2 limite = int(raw_input(’L´mite:␣’)) ı 3 while i < limite: 4 print i 5 i += 1· 102 Haz unas cuantas trazas de este programa para diferentes valores de i, de limitey de incremento. ejercicio bucle 16.py ejercicio bucle.py 1 i = int(raw_input(’Valor␣inicial:␣’)) 2 limite = int(raw_input(’L´mite:␣’)) ı 3 incremento = int(raw_input(’Incremento:␣’)) 4 while i < limite: 5 print i 6 i += incremento· 103 Implementa un programa que muestre todos los m´ltiplos de 6 entre 6 y 150, uambos inclusive.· 104 Implementa un programa que muestre todos los m´ltiplos de n entre n y m · n, uambos inclusive, donde n y m son n´meros introducidos por el usuario. u· 105 Implementa un programa que muestre todos los n´meros potencia de 2 entre 20 uy 230 , ambos inclusive. .................................................................................. Bucles sin fin Los bucles son muy utiles a la hora de confeccionar programas, pero tambi´n son peli- ´ e grosos si no andas con cuidado: es posible que no finalicen nunca. Estudia este programa y ver´s qu´ queremos decir: a e E bucle infinito.py E 1 i=0 2 while i < 10: 3 print i La condici´n del bucle siempre se satisface: dentro del bucle nunca se modifica el valor o de i, y si i no se modifica, jam´s llegar´ a valer 10 o m´s. El ordenador empieza a a a a mostrar el n´mero 0 una y otra vez, sin finalizar nunca. Es lo que denominamos un bucle u sin fin o bucle infinito. Cuando se ejecuta un bucle sin fin, el ordenador se queda como ˂˂colgado˃˃ y nunca nos devuelve el control. Si est´s ejecutando un programa desde la l´ a ınea de ´rdenes Unix, o puedes abortarlo pulsando C-c. Si la ejecuci´n tiene lugar en el entorno PythonG (o o en el editor XEmacs) puedes abortar la ejecuci´n del programa con C-c C-c. o4.2.2. Un problema de ejemplo: c´lculo de sumatorios aAhora que ya hemos presentado lo fundamental de los bucles, vamos a resolver algunosproblemas concretos. Empezaremos por un programa que calcula la suma de los 1000primeros n´meros, es decir, un programa que calcula el sumatorio u 1000 i, i=1Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 111 111 Introducción a la programación con Python - UJIUJI c
    • o, lo que es lo mismo, el resultado de 1 + 2 + 3 + · · · + 999 + 1000. Vamos paso a paso. La primera idea que suele venir a quienes aprenden a programar es reproducir la f´rmula con una sola expresi´n Python, es decir: o o E sumatorio.py E 1 sumatorio = 1 + 2 + 3 + . . + 999 + 1000 . 2 print sumatorio Pero, obviamente, no funciona: los puntos suspensivos no significan nada para Python. Aunque una persona puede aplicar su intuici´n para deducir qu´ significan los puntos o e suspensivos en ese contexto, Python carece de intuici´n alguna: exige que todo se describa o de forma precisa y rigurosa. Esa es la mayor dificultad de la programaci´n: el nivel de o detalle y precisi´n con el que hay que describir qu´ se quiere hacer. o e Bien. Abord´moslo de otro modo. Vamos a intentar calcular el valor del sumatorio e ˂˂acumulando˃˃ el valor de cada n´mero en una variable. Analiza este otro programa u (incompleto): 1 sumatorio =0 2 sumatorio += 1 3 sumatorio += 2 4 sumatorio += 3 . . .1000 sumatorio += 9991001 sumatorio += 10001002 print sumatorio Como programa no es el colmo de la elegancia. F´ ıjate en que, adem´s, presenta una a estructura casi repetitiva: las l´ ıneas de la 2 a la 1001 son todas de la forma sumatorio += n´mero u donde n´mero va tomando todos los valores entre 1 y 1000. Ya que esa sentencia, con u ligeras variaciones, se repite una y otra vez, vamos a tratar de utilizar un bucle. Empecemos construyendo un borrador incompleto que iremos refinando progresivamente: sumatorio.py 1 sumatorio = 0 2 while condici´n : o 3 sumatorio += n´mero u 4 print sumatorio Hemos dicho que n´mero ha de tomar todos los valores crecientes desde 1 hasta 1000. u Podemos usar una variable que, una vez inicializada, vaya tomando valores sucesivos con cada iteraci´n del bucle: o sumatorio.py 1 sumatorio = 0 2 i=1 3 while condici´n : o 4 sumatorio += i 5 i += 1 6 print sumatorio S´lo resta indicar la condici´n con la que se decide si hemos de iterar de nuevo o, o o por el contrario, hemos de finalizar el bucle: Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 112 112 Introducción a la programación con Python - UJI c UJI
    • sumatorio 4.py sumatorio.py 1 sumatorio = 0 2 i=1 3 while i <= 1000 : 4 sumatorio += i 5 i += 1 6 print sumatorio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 106 Estudia las diferencias entre el siguiente programa y el ultimo que hemos estu- ´diado. ¿Producen ambos el mismo resultado? sumatorio 5.py sumatorio.py 1 sumatorio = 0 2 i=0 3 while i < 1000: 4 i += 1 5 sumatorio += i 6 print sumatorio· 107 Dise˜a un programa que calcule n m i, i=ndonde n y m son n´meros enteros que deber´ introducir el usuario por teclado. u a· 108 Modifica el programa anterior para que si n > m, el programa no efect´e ning´n u uc´lculo y muestre por pantalla un mensaje que diga que n debe ser menor o igual que am.· 109 Queremos hacer un programa que calcule el factorial de un n´mero entero po- usitivo. El factorial de n se denota con n!, pero no existe ning´n operador Python que upermita efectuar este c´lculo directamente. Sabiendo que a n! = 1 · 2 · 3 · . . . · (n − 1) · ny que 0! = 1, haz un programa que pida el valor de n y muestre por pantalla el resultadode calcular n!.· 110 El n´mero de combinaciones que podemos formar tomando m elementos de un uconjunto con n elementos es: m n n! Cn = = . m (n − m)! m! mDise˜a un programa que pida el valor de n y m y calcule Cn . (Ten en cuenta que n ha nde ser mayor o igual que m.) (Puedes comprobar la validez de tu programa introduciendo los valores n = 15 ym = 10: el resultado es 3003.) ..................................................................................4.2.3. Otro programa de ejemplo: requisitos en la entradaVamos con otro programa sencillo pero ilustrativo. Estudia este programa:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 113 113 Introducción a la programación con Python - UJIUJI c
    • raiz 4.py raiz.py 1 from math import sqrt 2 3 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 4 5 print ’La␣ra´z␣cuadrada␣de␣%f␣es␣%f’ % (x, sqrt(x)) ıComo puedes ver, es muy sencillo: pide un n´mero (flotante) y muestra por pantalla su ura´ cuadrada. Como sqrt no puede trabajar con n´meros negativos, pedimos al usuario ız uque introduzca un n´mero positivo. Pero nada obliga al usuario a introducir un n´mero u upositivo. En lugar de adoptar una soluci´n como las estudiadas anteriormente, esto es, evitando oejecutar el c´lculo de la ra´ cuadrada cuando el n´mero es negativo con la ayuda de una a ız usentencia condicional, vamos a obligar a que el usuario introduzca un n´mero positivo urepitiendo la sentencia de la l´ ınea 3 cuantas veces sea preciso. Dado que vamos arepetir un fragmento de programa, utilizaremos una sentencia while. En principio, nuestroprograma presentar´ este aspecto: a raiz.py 1 from math import sqrt 2 3 while condici´n: o 4 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 5 6 print ’La␣ra´z␣cuadrada␣de␣%f␣es␣%f’ % (x, sqrt(x)) ı¿Qu´ condici´n poner? Est´ claro: el bucle deber´ leerse as´ ˂˂mientras x sea un valor e o a ıa ıinv´lido, hacer. . . ˃˃, es decir, ˂˂mientras x sea menor que cero, hacer. . . ˃˃; y esa ultima frase a ´se traduce a Python as´ ı: raiz 5.py E raiz.py E 1 from math import sqrt 2 3 while x < 0 : 4 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 5 6 print ’La␣ra´z␣cuadrada␣de␣%f␣es␣%f’ % (x, sqrt(x)) ı Pero el programa no funciona correctamente. Mira qu´ obtenemos al ejecutarlo: eTraceback (innermost last): File ’raiz.py’, line 3, in ? while x < 0:NameError: x Python nos indica que la variable x no est´ definida (no existe) en la l´ a ınea 3. ¿Qu´ eocurre? Vayamos paso a paso: Python empieza ejecutando la l´ ınea 1, con lo que importala funci´n sqrt del m´dulo math; la l´ o o ınea 2 est´ en blanco, as´ que, a continuaci´n, Python a ı oejecuta la l´ ınea 3, lo cual pasa por saber si la condici´n del while es cierta o falsa. Y ah´ o ıse produce el error, pues se intenta conocer el valor de x cuando x no est´ inicializada. aEs necesario, pues, inicializar antes la variable; pero, ¿con qu´ valor? Desde luego, no econ un valor positivo. Si x empieza tomando un valor positivo, la l´ ınea 4 no se ejecutar´. aProbemos, por ejemplo, con el valor −1. raiz.py 1 from math import sqrt 2 3 x = -1 4 while x < 0:Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 114 114 Introducción a la programación con Python - UJI c UJI
    • 5 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 6 7 print ’La␣ra´z␣cuadrada␣de␣%f␣es␣%f’ % (x, sqrt(x)) ı Ahora s´ Hagamos una traza. ı. 1. Empezamos ejecutando la l´ ınea 1, con lo que importa la funci´n sqrt. o 2. La l´ ınea 2 se ignora. 3. Ahora ejecutamos la l´ ınea 3, con lo que x vale −1. 4. En la l´ ınea 4 nos preguntamos: ¿es x menor que cero? La respuesta es s´ de modo ı, que debemos ejecutar la l´ ınea 5. 5. La l´ ınea 5 hace que se solicite al usuario un valor para x. Supongamos que el usuario introduce un n´mero negativo, por ejemplo, −3. u 6. Como hemos llegado al final de un bucle while, volvemos a la l´ ınea 4 y nos volvemos a preguntar ¿es x menor que cero? De nuevo, la respuesta es s´ as´ que pasamos ı, ı a la l´ ınea 4. 7. Supongamos que ahora el usuario introduce un n´mero positivo, pongamos que el u 16. 8. Por llegar al final de un bucle, toca volver a la l´ ınea 4 y plantearse la condici´n: o ¿es x menor que cero? En este caso la respuesta es no, as´ que salimos del bucle ı y pasamos a ejecutar la l´ ınea 7, pues la l´ ınea 6 est´ vac´ a ıa. 9. La l´ ınea 7 muestra por pantalla ˂˂La ra´z cuadrada de 16.000000 es 4.000000˃˃. ı Y ya hemos acabado.F´ ıjate en que las l´ ıneas 4–5 se pueden repetir cuantas veces haga falta: s´lo es posible osalir del bucle introduciendo un valor positivo en x. Ciertamente hemos conseguido obligaral usuario a que los datos que introduce satisfagan una cierta restricci´n. o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 111 ¿Qu´ te parece esta otra versi´n del mismo programa? e o raiz 6.py raiz.py 1 from math import sqrt 2 3 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 4 while x < 0: 5 x = float(raw_input(’Introduce␣un␣n´mero␣positivo:␣’)) u 6 7 print ’La␣ra´z␣cuadrada␣de␣%f␣es␣%f’ % (x, sqrt(x)) ı· 112 Dise˜a un programa que solicite la lectura de un n´mero entre 0 y 10 (ambos n uinclusive). Si el usuario teclea un n´mero fuera del rango v´lido, el programa solicitar´ u a anuevamente la introducci´n del valor cuantas veces sea menester. o· 113 Dise˜a un programa que solicite la lectura de un texto que no contenga letras nmay´sculas. Si el usuario teclea una letra may´scula, el programa solicitar´ nuevamente u u ala introducci´n del texto cuantas veces sea preciso. o ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 115 115 Introducción a la programación con Python - UJIUJI c
    • 4.2.4. Mejorando el programa de los men´s uAl acabar la secci´n dedicada a sentencias condicionales presentamos este programa: o circulo 4.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 print ’Escoge␣una␣opci´n:␣’ o 6 print ’a)␣Calcular␣el␣di´metro.’ a 7 print ’b)␣Calcular␣el␣per´metro.’ ı 8 print ’c)␣Calcular␣el␣´rea.’ a 9 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)1011 if opcion == ’a’:12 diametro = 2 * radio13 print ’El␣di´metro␣es’, diametro a14 elif opcion == ’b’:15 perimetro = 2 * pi * radio16 print ’El␣per´metro␣es’, perimetro ı17 elif opcion == ’c’:18 area = pi * radio ** 219 print ’El␣´rea␣es’, area a20 else:21 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.␣T´␣has␣tecleado’, opcion o uY al empezar esta secci´n, dijimos que cuando el usuario no introduce correctamente una ode las tres opciones del men´ nos gustar´ volver a mostrar el men´ hasta que escoja u ıa uuna opci´n v´lida. o a En principio, si queremos que el men´ vuelva a aparecer por pantalla cuando el usuario use equivoca, deberemos repetir desde la l´ınea 5 hasta la ultima, as´ que la sentencia while ´ ıdeber´ aparecer inmediatamente despu´s de la segunda l´ a e ınea. El borrador del programapuede quedar as´ ı: circulo 13.py E circulo.py E 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 while opcion < ’a’ or opcion > ’c’: 6 print ’Escoge␣una␣opci´n:␣’o 7 print ’a)␣Calcular␣el␣di´metro.’ a 8 print ’b)␣Calcular␣el␣per´metro.’ ı 9 print ’c)␣Calcular␣el␣´rea.’ a10 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)11 if opcion == ’a’:12 diametro = 2 * radio13 print ’El␣di´metro␣es’, diametro a14 elif opcion == ’b’:15 perimetro = 2 * pi * radio16 print ’El␣per´metro␣es’, perimetro ı17 elif opcion == ’c’:18 area = pi * radio ** 219 print ’El␣´rea␣es’, area a20 else:21 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.␣T´␣has␣tecleado’, opcion o u Parece correcto, pero no lo es. ¿Por qu´? El error estriba en que opcion no existe ela primera vez que ejecutamos la l´ ınea 5. ¡Nos hemos olvidado de inicializar la variableIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 116 116 Introducción a la programación con Python - c UJI UJI
    • opcion! Desde luego, el valor inicial de opcion no deber´ ser ’a’, ’b’ o ’c’, pues ıaentonces el bucle no se ejecutar´ (piensa por qu´). Cualquier otro valor har´ que el ıa e aprograma funcione. Nosotros utilizaremos la cadena vac´ para inicializar opcion: ıa circulo 14.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 opcion = ’’ 6 while opcion < ’a’ or opcion > ’c’: 7 print ’Escoge␣una␣opci´n:␣’o 8 print ’a)␣Calcular␣el␣di´metro.’ a 9 print ’b)␣Calcular␣el␣per´metro.’ ı10 print ’c)␣Calcular␣el␣´rea.’ a11 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)12 if opcion == ’a’:13 diametro = 2 * radio14 print ’El␣di´metro␣es’, diametro a15 elif opcion == ’b’:16 perimetro = 2 * pi * radio17 print ’El␣per´metro␣es’, perimetro ı18 elif opcion == ’c’:19 area = pi * radio ** 220 print ’El␣´rea␣es’, area a21 else:22 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.␣T´␣has␣tecleado’, opcion o u . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 114 ¿Es correcto este otro programa? ¿En qu´ se diferencia del anterior? ¿Cu´l te e aparece mejor (si es que alguno de ellos te parece mejor)? circulo 15.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 opcion = ’’ 6 while opcion < ’a’ or opcion > ’c’: 7 print ’Escoge␣una␣opci´n:␣’ o 8 print ’a)␣Calcular␣el␣di´metro.’ a 9 print ’b)␣Calcular␣el␣per´metro.’ ı10 print ’c)␣Calcular␣el␣´rea.’ a11 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)12 if opcion < ’a’ or opcion > ’c’:13 print ’S´lo␣hay␣tres␣opciones:␣a,␣b␣o␣c.␣T´␣has␣tecleado’, opcion o u1415 if opcion == ’a’:16 diametro = 2 * radio17 print ’El␣di´metro␣es’, diametro a18 elif opcion == ’b’:19 perimetro = 2 * pi * radio20 print ’El␣per´metro␣es’, perimetro ı21 elif opcion == ’c’:22 area = pi * radio ** 223 print ’El␣´rea␣es’, area a ..................................................................................Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 117 117 Introducción a la programación con Python - UJIUJI c
    • Es habitual que los programas con men´ repitan una y otra vez las acciones de pre- usentaci´n del listado de opciones, lectura de selecci´n y ejecuci´n del c´lculo. Una opci´n o o o a odel men´ permite finalizar el programa. Aqu´ tienes una nueva versi´n de circulo.py u ı oque finaliza cuando el usuario desea: circulo 16.py circulo.py 1 from math import pi 2 3 radio = float(raw_input(’Dame␣el␣radio␣de␣un␣c´rculo:␣’)) ı 4 5 opcion = ’’ 6 while opcion != ’d’: 7 print ’Escoge␣una␣opci´n:␣’o 8 print ’a)␣Calcular␣el␣di´metro.’ a 9 print ’b)␣Calcular␣el␣per´metro.’ ı10 print ’c)␣Calcular␣el␣´rea.’ a11 print ’d)␣Finalizar.’12 opcion = raw_input(’Teclea␣a,␣b␣o␣c␣y␣pulsa␣el␣retorno␣de␣carro:␣’)13 if opcion == ’a’:14 diametro = 2 * radio15 print ’El␣di´metro␣es’, diametro a16 elif opcion == ’b’:17 perimetro = 2 * pi * radio18 print ’El␣per´metro␣es’, perimetro ı19 elif opcion == ’c’:20 area = pi * radio ** 221 print ’El␣´rea␣es’, area a22 elif opcion != ’d’:23 print ’S´lo␣hay␣cuatro␣opciones:␣a,␣b,␣c␣o␣d.␣T´␣has␣tecleado’, opcion o u2425 print ’Gracias␣por␣usar␣el␣programa’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 115 El programa anterior pide el valor del radio al principio y, despu´s, permite eseleccionar uno o m´s c´lculos con ese valor del radio. Modifica el programa para que a apida el valor del radio cada vez que se solicita efectuar un nuevo c´lculo. a· 116 Un vector en un espacio tridimensional es una tripleta de valores reales (x, y, z).Deseamos confeccionar un programa que permita operar con dos vectores. El usuario ver´ aen pantalla un men´ con las siguientes opciones: u1) Introducir el primer vector2) Introducir el segundo vector3) Calcular la suma4) Calcular la diferencia5) Calcular el producto escalar6) Calcular el producto vectorial7) Calcular el ´ngulo (en grados) entre ellos a8) Calcular la longitud9) Finalizar Puede que necesites que te refresquemos la memoria sobre los c´lculos a realizar. Si aes as´ la tabla 4.1 te ser´ de ayuda: ı, a Tras la ejecuci´n de cada una de las acciones del men´ ´ste reaparecer´ en pantalla, a o ue amenos que la opci´n escogida sea la n´mero 9. Si el usuario escoge una opci´n diferente, o u oel programa advertir´ al usuario de su error y el men´ reaparecer´. a u a Las opciones 4 y 6 del men´ pueden proporcionar resultados distintos en funci´n del u oorden de los operandos, as´ que, si se escoge cualquiera de ellas, deber´ mostrarse un ı aIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 118 118 Introducción a la programación con Python - UJIUJI c
    • Operaci´n o C´lculo a Suma: (x1 , y1 , z1 ) + (x2 , y2 , z2 ) (x1 + x2 , y1 + y2 , z1 + z2 ) Diferencia: (x1 , y1 , z1 ) − (x2 , y2 , z2 ) (x1 − x2 , y1 − y2 , z1 − z2 ) Producto escalar: (x1 , y1 , z1 ) · (x2 , y2 , z2 ) x1 x2 + y1 y2 + z1 z2 Producto vectorial: (x1 , y1 , z1 ) × (x2 , y2 , z2 ) (y1 z2 − z1 y2 , z1 x2 − x1 z2 , x1 y2 − y1 x2 )   ´ 180 x1 x2 + y1 y2 + z1 z2 Angulo entre (x1 , y1 , z1 ) y (x2 , y2 , z2 ) · arccos   π x 2 + y2 + z 2 x 2 + y2 + z 2 1 1 1 2 2 2 Longitud de (x, y, z) x 2 + y2 + z 2 Tabla 4.1: Recordatorio de operaciones b´sicas sobre vectores. anuevo men´ que permita seleccionar el orden de los operandos. Por ejemplo, la opci´n 4 u omostrar´ el siguiente men´: a u1) Primer vector menos segundo vector2) Segundo vector menos primer vector Nuevamente, si el usuario se equivoca, se le advertir´ del error y se le permitir´ a acorregirlo. La opci´n 8 del men´ principal conducir´ tambi´n a un submen´ para que el usuario o u a e udecida sobre cu´l de los dos vectores se aplica el c´lculo de longitud. a a Ten en cuenta que tu programa debe contemplar y controlar toda posible situaci´n oexcepcional: divisiones por cero, ra´ con argumento negativo, etc´tera. (Nota: La funci´n ıces e oarcocoseno se encuentra disponible en el m´dulo math y su identificador es acos.) o ..................................................................................4.2.5. El bucle for-inHay otro tipo de bucle en Python: el bucle for-in, que se puede leer como ˂˂para todoelemento de una serie, hacer. . . ˃˃. Un bucle for-in presenta el siguiente aspecto: for variable in serie de valores: acci´n o acci´n o ... acci´n o Veamos c´mo funciona con un sencillo ejemplo: o saludos.py saludos.py 1 for nombre in [’Pepe’, ’Ana’, ’Juan’]: 2 print ’Hola,␣%s.’ % nombre F´ıjate en que la relaci´n de nombres va encerrada entre corchetes y que cada nombre ose separa del siguiente con una coma. Se trata de una lista de nombres. M´s adelante aestudiaremos con detalle las listas. Ejecutemos ahora el programa. Por pantalla aparecer´ ael siguiente texto:Hola, Pepe.Hola, Ana.Hola, Juan. 119 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9Introducci´n a la programaci´n con Python o o 119 Introducción a la programación con Python - UJI c UJI
    • Se ha ejecutado la sentencia m´s indentada una vez por cada valor de la serie de anombres y, con cada iteraci´n, la variable nombre ha tomado el valor de uno de ellos o(ordenadamente, de izquierda a derecha). En el cap´ ıtulo anterior estudiamos el siguiente programa: potencias 2.py potencias.py 1 numero = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 2, numero ** 2) 4 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 3, numero ** 3) 5 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 4, numero ** 4) 6 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, 5, numero ** 5) Ahora podemos ofrecer una versi´n m´s simple: o a potencias.py potencias.py 1 numero = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 for potencia in [2, 3, 4, 5]: 4 print ’%d␣elevado␣a␣%d␣es␣%d’ % (numero, potencia, numero ** potencia)El bucle se lee de forma natural como ˂˂para toda potencia en la serie de valores 2, 3, 4y 5, haz. . . ˃˃. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 117 Haz un programa que muestre la tabla de multiplicar de un n´mero introducido upor teclado por el usuario. Aqu´ tienes un ejemplo de c´mo se debe comportar el programa: ı oDame un n´mero: 5 u5 x 1 = 55 x 2 = 105 x 3 = 155 x 4 = 205 x 5 = 255 x 6 = 305 x 7 = 355 x 8 = 405 x 9 = 455 x 10 = 50· 118 Realiza un programa que proporcione el desglose en billetes y monedas de unacantidad entera de euros. Recuerda que hay billetes de 500, 200, 100, 50, 20, 10 y 5 ¤ ymonedas de 2 y 1 ¤. Debes ˂˂recorrer˃˃ los valores de billete y moneda disponibles conuno o m´s bucles for-in. a· 119 Haz un programa que muestre la ra´ n-´sima de un n´mero le´ por teclado, ız e u ıdopara n tomando valores entre 2 y 100. .................................................................................. El ultimo ejercicio propuesto es todo un desaf´ a nuestra paciencia: teclear 99 ´ ıon´meros separados por comas supone un esfuerzo b´rbaro y conduce a un programa u apoco elegante. Es hora de aprender una nueva funci´n predefinida de Python que nos ayudar´ a o aevitar ese tipo de problemas: la funci´n range (que en ingl´s significa ˂˂rango˃˃). En o eprincipio, range se usa con dos argumentos: un valor inicial y un valor final (con matices).Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 120 120 Introducción a la programación con Python - UJIUJI c
    • ↱>>> range(2, 10)[2, 3, 4, 5, 6, 7, 8, 9] ↱>>> range(0, 3)[0, 1, 2] ↱>>> range(-3, 3)[-3, -2, -1, 0, 1, 2] Observa que la lista devuelta contiene todos los enteros comprendidos entre los ar-gumentos de la funci´n, incluyendo al primero pero no al ultimo. o ´ La funci´n range devuelve una lista de n´meros enteros. Estudia este ejemplo: o u contador con for.py contador con for.py 1 for i in range(1, 6): 2 print iAl ejecutar el programa, veremos lo siguiente por pantalla:12345 La lista que devuelve range es usada por el bucle for-in como serie de valores arecorrer. El ultimo ejercicio propuesto era pesad´ ´ ısimo: ¡nos obligaba a escribir una serie de 99n´meros! Con range resulta much´ u ısimo m´s sencillo. He aqu´ la soluci´n: a ı o raices 2.py raices.py 1 numero = float(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 for n in range(2, 101): 4 print ’la␣ra´z␣%d-´sima␣de␣%f␣es␣%f’ % (numero, n, numero**(1.0/n)) ı e(F´ ıjate en que range tiene por segundo argumento el valor 101 y no 100: recuerda queel ultimo valor de la lista es el segundo argumento menos uno.) ´ Podemos utilizar la funci´n range con uno, dos o tres argumentos. Si usamos range ocon un argumento estaremos especificando unicamente el ultimo valor (m´s uno) de la ´ ´ aserie, pues el primero vale 0 por defecto: ↱>>> range(5)[0, 1, 2, 3, 4] Si usamos tres argumentos, el tercero permite especificar un incremento para la seriede valores. Observa en estos ejemplos qu´ listas de enteros devuelve range: e ↱>>> range(2, 10, 2)[2, 4, 6, 8] ↱>>> range(2, 10, 3)[2, 5, 8] F´ ıjate en que si pones un incremento negativo (un decremento), la lista va de losvalores altos a los bajos. Recuerda que con range el ultimo elemento de la lista no llega ´a ser el valor final ↱>>> range(10, 5, -1)[10, 9, 8, 7, 6] ↱>>> range(3, -1, -1)[3, 2, 1, 0]Introducci´n a la programaci´n con Python o o 121 121 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • As´ pues, si el tercer argumento es negativo, la lista finaliza en el valor final m´s uno ı a(y no menos uno). Finalmente, observa que es equivalente utilizar range con dos argumentos a utilizarlacon un valor del incremento igual a 1. ↱>>> range(2, 5, 1)[2, 3, 4] ↱>>> range(2, 5)[2, 3, 4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 120 Haz un programa que muestre, en l´ ıneas independientes, todos los n´meros pares ucomprendidos entre 0 y 200 (ambos inclusive).· 121 Haz un programa que muestre, en l´ıneas independientes y en orden inverso, todoslos n´meros pares comprendidos entre 0 y 200 (ambos inclusive). u· 122 Escribe un programa que muestre los n´meros pares positivos entre 2 y un un´mero cualquiera que introduzca el usuario por teclado. u .................................................................................. Obi Wan Puede resultar sorprendente que range(a, b) incluya todos los n´meros enteros com- u prendidos entre a y b, pero sin incluir b. En realidad la forma ˂˂natural˃˃ o m´s frecuente a de usar range es con un s´lo par´metro: range(n) que devuelve una lista con los n o a primeros n´meros enteros incluyendo al cero (hay razones para que esto sea lo con- u veniente, ya llegaremos). Como incluye al cero y hay n n´meros, no puede incluir al u propio n´mero n. Al extenderse el uso de range a dos argumentos, se ha mantenido u la ˂˂compatibilidad˃˃ eliminando el ultimo elemento. Una primera ventaja es que resulta ´ f´cil calcular cu´ntas iteraciones realizar´ un bucle range(a, b): exactamente b - a. a a a (Si el valor b estuviera incluido, el n´mero de elementos ser´ b - a + 1.) u ıa Hay que ir con cuidado, pues es f´cil equivocarse ˂˂por uno˃˃. De hecho, equivocarse a ˂˂por uno˃˃ es tan frecuente al programar (y no s´lo con range) que hay una expresi´n o o para este tipo de error: un error Obi Wan (Kenobi), que es m´s o menos como suena en a ingl´s ˂˂off by one˃˃ (pasarse o quedarse corto por uno). e4.2.6. for-in como forma compacta de ciertos whileCiertos bucles se ejecutan un n´mero de veces fijo y conocido a priori. Por ejemplo, al udesarrollar el programa que calcula el sumatorio de los 1000 primeros n´meros utilizamos uun bucle que iteraba exactamente 1000 veces: sumatorio 6.py sumatorio.py 1 sumatorio = 0 2 i=1 3 while i <= 1000 : 4 sumatorio += i 5 i += 1 6 print sumatorio El bucle se ha construido de acuerdo con un patr´n, una especie de ˂˂frase hecha˃˃ odel lenguaje de programaci´n: o i = valor inicial while i <= valor final : acciones i += 1Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 122 122 Introducción a la programación con Python - UJIUJI c
    • En este patr´n la variable i suele denominarse ´ o ındice del bucle. Podemos expresar de forma compacta este tipo de bucles con un for-in siguiendo esteotro patr´n: o for i in range(valor inicial, valor final + 1): accionesF´ ıjate en que las cuatro l´ ıneas del fragmento con while pasan a expresarse con s´lo dos ogracias al for-in con range. El programa de c´lculo del sumatorio de los 1000 primeros n´meros se puede expresar a uahora de este modo: sumatorio.py sumatorio.py 1 sumatorio = 0 2 for i in range(1, 1001): 3 sumatorio += i 4 5 print sumatorio¡Bastante m´s f´cil de leer que usando un while! a a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 123 Haz un programa que pida el valor de dos enteros n y m y que muestre porpantalla el valor de m i. i=nDebes usar un bucle for-in para el c´lculo del sumatorio. a· 124 Haz un programa que pida el valor de dos enteros n y m y que muestre porpantalla el valor de m i2 . i=n· 125 Haz un programa que pida el valor de dos enteros n y m y calcule el sumatoriode todos los n´meros pares comprendidos entre ellos (incluy´ndolos en el caso de que u esean pares). ..................................................................................4.2.7. N´meros primos uVamos ahora con un ejemplo m´s. Nos proponemos construir un programa que nos diga asi un n´mero (entero) es o no es primo. Recuerda: un n´mero primo es aquel que s´lo es u u odivisible por s´ mismo y por 1. ı ¿C´mo empezar? Resolvamos un problema concreto, a ver qu´ estrategia seguir´ o e ıamosnormalmente. Supongamos que deseamos saber si 7 es primo. Podemos intentar dividirlopor cada uno de los n´meros entre 2 y 6. Si alguna de las divisiones es exacta, entonces uel n´mero no es primo: u Dividendo Divisor Cociente Resto 7 2 3 1 7 3 2 1 7 4 1 3 7 5 1 2 7 6 1 1Ahora estamos seguros: ninguno de los restos dio 0, as´ que 7 es primo. Hagamos que el ıordenador nos muestre esa misma tabla:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 123 123 Introducción a la programación con Python - UJIUJI c
    • es primo 10.py es primo.py 1 num = 7 2 3 for divisor in range(2, num): 4 print ’%d␣entre␣%d’ % (num, divisor) , 5 print ’es␣%d␣con␣resto␣%d’ % (num / divisor, num % divisor)(Recuerda que range(2,num) comprende todos los n´meros enteros entre 2 y num - 1.) uAqu´ tienes el resultado de ejecutar el programa: ı7 entre 2 es 3 con resto 17 entre 3 es 2 con resto 17 entre 4 es 1 con resto 37 entre 5 es 1 con resto 27 entre 6 es 1 con resto 1 Est´ claro que probar todas las divisiones es f´cil, pero, ¿c´mo nos aseguramos de a a oque todos los restos son distintos de cero? Una posibilidad es contarlos y comprobar quehay exactamente num - 2 restos no nulos: es primo 11.py es primo.py 1 num = 7 2 3 restos_no_nulos = 0 4 for divisor in range(2, num): 5 if num % divisor != 0: 6 restos_no_nulos += 1 7 8 if restos_no_nulos == num - 2: 9 print ’El␣n´mero’, num, ’es␣primo’ u10 else:11 print ’El␣n´mero’, num, ’no␣es␣primo’ u Pero vamos a proponer un m´todo distinto basado en una ˂˂idea feliz˃˃ y que, m´s e aadelante, nos permitir´ acelerar notabil´ a ısimamente el c´lculo. Vale la pena que la estudies abien: la utilizar´s siempre que quieras probar que toda una serie de valores cumple una apropiedad. En nuestro caso la propiedad que queremos demostrar que cumplen todos losn´meros entre 2 y num-1 es ˂˂al dividir a num, da resto distinto de cero˃˃. u Empieza siendo optimista: sup´n que la propiedad es cierta y asigna a una variable o el valor ˂˂cierto˃˃. Recorre todos los n´meros y cuando alguno de los elementos de la secuencia no u satisfaga la propiedad, modifica la variable antes mencionada para que contenga el valor ˂˂falso˃˃. Al final del todo, mira qu´ vale la variable: si a´n vale ˂˂cierto˃˃, es que nadie la puso e u a ˂˂falso˃˃, as´ que la propiedad se cumple para todos los elementos y el n´mero es ı u primo; y si vale ˂˂falso˃˃, entonces alguien la puso a ˂˂falso˃˃ y para eso es preciso que alg´n elemento no cumpliera la propiedad en cuesti´n, por lo que el n´mero u o u no puede ser primo.Mira c´mo plasmamos esa idea en un programa: o es primo 12.py es primo.py 1 num = 7 2Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 124 124 Introducción a la programación con Python - UJI c UJI
    • 3 creo_que_es_primo = True 4 for divisor in range(2, num): 5 if num % divisor == 0: 6 creo_que_es_primo = False 7 8 if creo_que_es_primo: 9 print ’El␣n´mero’, num, ’es␣primo’ u10 else:11 print ’El␣n´mero’, num, ’no␣es␣primo’ u. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 126 Haz un traza del programa para los siguientes n´meros: ua) 4 b) 13 c) 18 d) 2 (¡ojo con ´ste!) e .................................................................................. True == True F´ ıjate en la l´ ınea 8 de este programa: es primo.py 1 num = 7 2 3 creo_que_es_primo = True 4 for divisor in range(2, num): 5 if num % divisor == 0: 6 creo_que_es_primo = False 7 8 if creo_que_es_primo: 9 print ’El␣n´mero’, num, ’es␣primo’ u 10 else: 11 print ’El␣n´mero’, num, ’no␣es␣primo’ u La condici´n del if es muy extra˜a, ¿no? No hay comparaci´n alguna. ¿Qu´ condici´n o n o e o es esa? Muchos estudiantes optan por esta f´rmula alternativa para las l´ o ıneas 8 y sucesivas es primo.py . . . 8 if creo_que_es_primo == True: 9 print ’El␣n´mero’, num, ’es␣primo’ u 10 else: 11 print ’El␣n´mero’, num, ’no␣es␣primo’ u Les parece m´s natural porque de ese modo se compara el valor de creo_que_es_primo a con algo. Pero, si lo piensas bien, esa comparaci´n es superflua: a fin de cuentas, o el resultado de la comparaci´n creo_que_es_primo == True es True y, directamente, o creo_que_es_primo vale True. No es que est´ mal efectuar esa comparaci´n extra, sino que no aporta nada y resta e o legibilidad. Ev´ıtala si puedes. Despu´s de todo, no es tan dif´ Aunque esta idea feliz la utilizar´s muchas veces, e ıcil. aes probable que cometas un error (al menos, muchos compa˜eros tuyos caen en ´l una y n eotra vez). F´ ıjate en este programa, que est´ mal: a es primo 13.py E es primo.py EIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 125 125 Introducción a la programación con Python - UJIUJI c
    • 1 num = 7 2 3 creo_que_es_primo = True 4 for divisor in range(2, num): 5 if num % divisor == 0: 6 creo_que_es_primo = False 7 else: 8 creo_que_es_primo = True 910 if creo_que_es_primo:11 print ’El␣n´mero’, num, ’es␣primo’ u12 else:13 print ’El␣n´mero’, num, ’no␣es␣primo’ u¡El programa s´lo se acuerda de lo que pas´ con el ultimo valor del bucle! Haz la prueba: o o ´haz una traza sustituyendo la asignaci´n de la l´ o ınea 1 por la sentencia num = 4. El n´mero uno es primo, pero al no ser exacta la divisi´n entre 4 y 3 (el ultimo valor de divisor en o ´el bucle), el valor de creo_que_es_primo es True. El programa concluye, pues, que 4 esprimo. Vamos a refinar el programa. En primer lugar, haremos que trabaje con cualquiern´mero que el usuario introduzca: u es primo 14.py es primo.py 1 num = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 creo_que_es_primo = True 4 for divisor in range(2, num): 5 if num % divisor == 0: 6 creo_que_es_primo = False 7 8 if creo_que_es_primo: 9 print ’El␣n´mero’, num, ’es␣primo’ u10 else:11 print ’El␣n´mero’, num, ’no␣es␣primo’ uF´cil. Ahora vamos a hacer que vaya m´s r´pido. Observa qu´ ocurre cuando tratamos a a a ede ver si el n´mero 1024 es primo o no. Empezamos dividi´ndolo por 2 y vemos que el u eresto de la divisi´n es cero. Pues ya est´: estamos seguros de que 1024 no es primo. Sin o aembargo, nuestro programa sigue haciendo c´lculos: pasa a probar con el 3, y luego con ael 4, y con el 5, y as´ hasta llegar al 1023. ¿Para qu´, si ya sabemos que no es primo? ı eNuestro objetivo es que el bucle deje de ejecutarse tan pronto estemos seguros de que eln´mero no es primo. Pero resulta que no podemos hacerlo con un bucle for-in, pues este utipo de bucles se basa en nuestro conocimiento a priori de cu´ntas iteraciones vamos a ahacer. Como en este caso no lo sabemos, hemos de utilizar un bucle while. Escribamosprimero un programa equivalente al anterior, pero usando un while en lugar de un for-in: es primo 15.py es primo.py 1 num = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 creo_que_es_primo = True 4 divisor = 2 5 while divisor < num: 6 if num % divisor == 0: 7 creo_que_es_primo = False 8 divisor += 1 910 if creo_que_es_primo:Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 126 126 Introducción a la programación con Python - cUJI UJI
    • Se cumple para todos/se cumple para alguno Muchos de los programas que dise˜aremos necesitan verificar que cierta condici´n se n o cumple para alg´n elemento de un conjunto o para todos los elementos del conjunto. En u ambos casos tendremos que recorrer todos los elementos, uno a uno, y comprobar si la condici´n es cierta o falsa para cada uno de ellos. o Cuando queramos comprobar que todos cumplen una condici´n, haremos lo siguiente: o 1. Seremos optimistas y empezaremos suponiendo que la condici´n se cumple para o todos. 2. Preguntaremos a cada uno de los elementos si cumple la condici´n. o 3. S´lo cuando detectemos que uno de ellos no la cumple, cambiaremos de opini´n o o y pasaremos a saber que la condici´n no se cumple para todos. Nada nos podr´ o a hacer cambiar de opini´n. o He aqu´ un esquema que usa la notaci´n de Python: ı o 1 creo_que_se_cumple_para_todos = True 2 for elemento in conjunto: 3 if not condici´n: o 4 creo_que_se_cumple_para_todos = False 5 6 if creo_que_se_cumple_para_todos: 7 print ’Se␣cumple␣para␣todos’ Cuando queramos comprobar que alguno cumple una condici´n, haremos lo siguiente: o 1. Seremos pesimistas y empezaremos suponiendo que la condici´n no se cumple o para ninguno. 2. Preguntaremos a cada uno de los elementos si se cumple la condici´n. o 3. S´lo cuando detectemos que uno de ellos s´ la cumple, cambiaremos de opini´n o ı o y pasaremos a saber que la condici´n se cumple para alguno. Nada nos podr´ o a hacer cambiar de opini´n. o He aqu´ un esquema que usa la notaci´n de Python: ı o 1 creo_que_se_cumple_para_alguno = False 2 for elemento in conjunto: 3 if condici´n: o 4 creo_que_se_cumple_para_alguno = True 5 6 if creo_que_se_cumple_para_alguno: 7 print ’Se␣cumple␣para␣alguno’11 print ’El␣n´mero’, num, ’es␣primo’ u12 else:13 print ’El␣n´mero’, num, ’no␣es␣primo’ u. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 127 Haz una traza del ultimo programa para el n´mero 125. ´ u.................................................................................. Hemos sustituido el for-in por un while, pero no hemos resuelto el problema: conel 1024 seguimos haciendo todas las pruebas de divisibilidad. ¿C´mo hacer que el bucle oacabe tan pronto se est´ seguro de que el n´mero no es primo? Pues complicando un e upoco la condici´n del while: oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 127 127 Introducción a la programación con Python - UJIUJI c
    • Error para alguno/error para todos Ya te hemos dicho que muchos de los programas que dise˜aremos necesitan verificar n que cierta condici´n se cumple para alg´n elemento de un conjunto o para todos los o u elementos del conjunto. Y tambi´n te hemos dicho c´mo abordar ambos problemas. Pero, e o aun as´ es probable que cometas un error (muchos, muchos estudiantes lo hacen). Aqu´ ı, ı tienes un ejemplo de programa err´neo al tratar de comprobar que una condici´n se o o cumple para todos los elementos de un conjunto: 1 creo_que_se_cumple_para_todos = True E 2 for elemento in conjunto: 3 if not condici´n: o 4 creo_que_se_cumple_para_todos = False 5 else: # Esta l´ ınea y la siguiente sobran 6 creo_que_se_cumple_para_todos = True 7 8 if creo_que_se_cumple_para_todos: 9 print ’Se␣cumple␣para␣todos’ Y aqu´ tienes una versi´n err´nea para el intento de comprobar que una condici´n se ı o o o cumple para alguno: 1 creo_que_se_cumple_para_alguno = False E 2 for elemento in conjunto: 3 if condici´n: o 4 creo_que_se_cumple_para_alguno = True 5 else: # Esta l´ınea y la siguiente sobran 6 creo_que_se_cumple_para_alguno = False 7 8 if creo_que_se_cumple_para_alguno: 9 print ’Se␣cumple␣para␣alguno’ En ambos casos, s´lo se est´ comprobando si el ultimo elemento del conjunto cumple o o a ´ no la condici´n. o es primo 16.py es primo.py 1 num = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 creo_que_es_primo = True 4 divisor = 2 5 while divisor < num and creo_que_es_primo : 6 if num % divisor == 0: 7 creo_que_es_primo = False 8 divisor += 1 910 if creo_que_es_primo:11 print ’El␣n´mero’, num, ’es␣primo’ u12 else:13 print ’El␣n´mero’, num, ’no␣es␣primo’ uAhora s´ ı.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 128 Haz una traza del ultimo programa para el n´mero 125. ´ u· 129 Haz un programa que calcule el m´ximo com´n divisor (mcd) de dos enteros a upositivos. El mcd es el n´mero m´s grande que divide exactamente a ambos n´meros. u a u· 130 Haz un programa que calcule el m´ximo com´n divisor (mcd) de tres enteros a uIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 128 128 Introducción a la programación con Python - UJIUJI c
    • positivos. El mcd de tres n´meros es el n´mero m´s grande que divide exactamente a los u u atres. ..................................................................................4.2.8. Rotura de bucles: breakEl ultimo programa dise˜ado aborta su ejecuci´n tan pronto sabemos que el n´mero ´ n o uestudiado no es primo. La variable creo_que_es_primo juega un doble papel: ˂˂recordar˃˃si el n´mero es primo o no al final del programa y abortar el bucle while tan pronto usabemos que el n´mero no es primo. La condici´n del while se ha complicado un poco u opara tener en cuenta el valor de creo_que_es_primo y abortar el bucle inmediatamente. Hay una sentencia que permite abortar la ejecuci´n de un bucle desde cualquier opunto del mismo: break (en ingl´s significa ˂˂romper˃˃). Observa esta nueva versi´n del e omismo programa: es primo 17.py es primo.py 1 num = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 creo_que_es_primo = True 4 divisor = 2 5 while divisor < num : 6 if num % divisor == 0: 7 creo_que_es_primo = False 8 break 9 divisor += 11011 if creo_que_es_primo:12 print ’El␣n´mero’, num, ’es␣primo’ u13 else:14 print ’El␣n´mero’, num, ’no␣es␣primo’ uCuando se ejecuta la l´ınea 8, el programa sale inmediatamente del bucle, es decir, pasaa la l´ ınea 10 sin pasar por la l´ ınea 9. Nuevamente estamos ante una comodidad ofrecida por el lenguaje: la sentencia breakpermite expresar de otra forma una idea que ya pod´ expresarse sin ella. S´lo debes ıa oconsiderar la utilizaci´n de break cuando te resulte c´moda. No abuses del break: a o oveces, una condici´n bien expresada en la primera l´ o ınea del bucle while hace m´s legible aun programa. La sentencia break tambi´n es utilizable con el bucle for-in. Analicemos esta nueva eversi´n de es primo.py: o es primo 18.py es primo.py 1 num = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 creo_que_es_primo = True 4 for divisor in range(2, num): 5 if num % divisor == 0: 6 creo_que_es_primo = False 7 break 8 9 if creo_que_es_primo:10 print ’El␣n´mero’, num, ’es␣primo’ u11 else:12 print ’El␣n´mero’, num, ’no␣es␣primo’ uIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 129 129 Introducción a la programación con Python - c UJI UJI
    • Versiones eficientes de ˂˂se cumple para alguno/se cumple para todos˃˃ Volvemos a visitar los problemas de ˂˂se cumple para alguno˃˃ y ˂˂se cumple para todos˃˃. Esta vez vamos a hablar de c´mo acelerar el c´lculo gracias a la sentencia break. o a Si quieres comprobar si una condici´n se cumple para todos los elementos de un o conjunto y encuentras que uno de ellos no la satisface, ¿para qu´ seguir? ¡Ya sabemos e que no se cumple para todos! 1 creo_que_se_cumple_para_todos = True 2 for elemento in conjunto: 3 if not condici´n: o 4 creo_que_se_cumple_para_todos = False 5 break 6 7 if creo_que_se_cumple_para_todos: 8 print ’Se␣cumple␣para␣todos’ Como ves, esta mejora puede suponer una notable aceleraci´n del c´lculo: cuando el o a primer elemento del conjunto no cumple la condici´n, acabamos inmediatamente. Ese es o el mejor de los casos. El peor de los casos es que todos cumplan la condici´n, pues nos o vemos obligados a recorrer todos los elementos del conjunto. Y eso es lo que hac´ ıamos hasta el momento: recorrer todos los elementos. O sea, en el peor de los casos, hacemos el mismo esfuerzo que ven´ ıamos haciendo para todos los casos. ¡No est´ nada mal! a Si quieres comprobar si una condici´n se cumple para alguno de los elementos de o un conjunto y encuentras que uno de ellos la satisface, ¿para qu´ seguir? ¡Ya sabemos e que la cumple alguno! 1 creo_que_se_cumple_para_alguno = False 2 for elemento in conjunto: 3 if condici´n: o 4 creo_que_se_cumple_para_alguno = True 5 break 6 7 if creo_que_se_cumple_para_alguno: 8 print ’Se␣cumple␣para␣alguno’ Podemos hacer la misma reflexi´n en torno a la eficiencia de esta nueva versi´n que en o o el caso anterior. Esta versi´n es m´s concisa que la anterior (ocupa menos l´ o a ıneas) y, en cierto sentido,m´s elegante: el bucle for-in expresa mejor la idea de que divisor recorre ascendente- amente un rango de valores.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 131 Haz una traza del programa para el valor 125.· 132 En realidad no hace falta explorar todo el rango de n´meros entre 2 y n − 1 para usaber si un n´mero n es o no es primo. Basta con explorar el rango de n´meros entre 2 y u ula parte entera de n/2. Piensa por qu´. Modifica el programa para que s´lo exploremos e oese rango.· 133 Ni siquiera hace falta explorar todo el rango de n´meros entre 2 y n/2 para usaber si un n´mero n es o no es primo. Basta con explorar el rango de n´meros entre 2 u u √y la parte entera de n. (Cr´etelo.) Modifica el programa para que s´lo exploremos ese e orango.· 134 Haz un programa que vaya leyendo n´meros y mostr´ndolos por pantalla hasta u aque el usuario introduzca un n´mero negativo. En ese momento, el programa mostrar´ un u amensaje de despedida y finalizar´ su ejecuci´n. a oIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 130 130 Introducción a la programación con Python - UJIUJI c
    • · 135 Haz un programa que vaya leyendo n´meros hasta que el usuario introduzca un un´mero negativo. En ese momento, el programa mostrar´ por pantalla el n´mero mayor u a ude cuantos ha visto. ..................................................................................4.2.9. Anidamiento de estructurasAhora vamos a resolver otro problema. Vamos a hacer que el programa pida un n´mero uy nos muestre por pantalla los n´meros primos entre 1 y el que hemos introducido. Mira ueste programa: primos.py primos.py 1 limite = int(raw_input(’Dame␣un␣n´mero:␣’)) u 2 3 for num in range(1, limite+1): 4 creo_que_es_primo = True 5 for divisor in range(2, num): 6 if num % divisor == 0: 7 creo_que_es_primo = False 8 break 9 if creo_que_es_primo:10 print numNo deber´ resultarte dif´ entender el programa. Tiene bucles anidados (un for-in ıa ıcildentro de un for-in), pero est´ claro qu´ hace cada uno de ellos: el m´s exterior recorre a e acon num todos los n´meros comprendidos entre 1 y limite (ambos inclusive); el m´s interior u aforma parte del procedimiento que determina si el n´mero que estamos estudiando en ucada instante es o no es primo. Dicho de otro modo: num va tomando valores entre 1 y limite y para cada valor de numse ejecuta el bloque de las l´ ıneas 4–10, as´ que, para cada valor de num, se comprueba ısi ´ste es primo o no. S´lo si el n´mero resulta ser primo se muestra por pantalla. e o u Puede que te intrigue el break de la l´ ınea 8. ¿A qu´ bucle ˂˂rompe˃˃? S´lo al m´s e o ainterior: una sentencia break siempre aborta la ejecuci´n de un solo bucle y ´ste es el o eque lo contiene directamente. Antes de acabar: existen procedimientos m´s eficientes para determinar si un n´mero a ues primo o no, as´ como para listar los n´meros primos en un intervalo. Hacer buenos ı uprogramas no s´lo pasa por conocer bien las reglas de escritura de programas en un olenguaje de programaci´n: has de saber dise˜ar algoritmos y, muchas veces, buscar los o nmejores algoritmos conocidos en los libros.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 136 ¿Qu´ resultar´ de ejecutar estos programas? e aa) ejercicio for 7.py ejercicio for.py 1 for i in range(0, 5): 2 for j in range(0, 3): 3 print i, jb) ejercicio for 8.py ejercicio for.py 1 for i in range(0, 5): 2 for j in range(i, 5): 3 print i, jc) ejercicio for 9.py ejercicio for.py 1 for i in range(0, 5): 2 for j in range(0, i): 3 print i, jIntroducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 131 131 Introducción a la programación con Python - UJIUJI c
    • ´ Indice de bucle for-in: ¡prohibido asignar! Hemos aprendido que el bucle for-in utiliza una variable ´ ındice a la que se van asig- nando los diferentes valores del rango. En muchos ejemplos se utiliza la variable i, pero s´lo porque tambi´n en matem´ticas los sumatorios y productorios suelen utilizar la o e a letra i para indicar el nombre de su variable ´ındice. Puedes usar cualquier nombre de variable v´lido. a Pero que el ´ındice sea una variable cualquiera no te da libertad absoluta para hacer con ella lo que quieras. En un bucle, las variables de ´ ındice s´lo deben usarse para o consultar su valor, nunca para asignarles uno nuevo. Por ejemplo, este fragmento de programa es incorrecto: 1 for i in range(0, 5): 2 i += 2 E Y ahora que sabes que los bucles pueden anidarse, tambi´n has de tener mucho e cuidado con sus ´ ındices. Un error frecuente entre primerizos de la programaci´n es o utilizar el mismo ´ ındice para dos bucles anidados. Por ejemplo, estos bucles anidados est´n mal: a 1 for i in range(0, 5): 2 for i in range(0, 3): E 3 print i En el fondo, este problema es una variante del anterior, pues de alg´n modo se est´ u a asignando nuevos valores a la variable i en el bucle interior, pero i es la variable del bucle exterior y asignarle cualquier valor est´ prohibido. a Recuerda: nunca debes asignar un valor a un ´ ındice de bucle ni usar la misma variable ´ ındice en bucles anidados.d) ejercicio for 10.py ejercicio for.py 1 for i in range(0, 4): 2 for j in range(0, 4): 3 for k in range(0, 2): 4 print i, j, ke) ejercicio for 11.py ejercicio for.py 1 for i in range(0, 4): 2 for j in range(0, 4): 3 for k in range(i, j): 4 print i, j, kf) ejercicio for 12.py ejercicio for.py 1 for i in range(1, 5): 2 for j in range(0, 10, i): 3 print i, j ..................................................................................4.3. Captura y tratamiento de excepcionesYa has visto que en nuestros programas pueden aparecer errores en tiempo de ejecuci´n,oes decir, pueden generar excepciones: divisiones por cero, intentos de calcular ra´ ıcesde valores negativos, problemas al operar con tipos incompatibles (como al sumar unacadena y un entero), etc. Hemos presentado la estructura de control if como un mediopara controlar estos problemas y ofrecer un tratamiento especial cuando convenga (aunqueluego hemos considerado muchas otras aplicaciones de esta sentencia). La detecci´n de oIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 132 132 Introducción a la programación con Python - c UJI UJI
    • Una excepci´n a la regla de indentaci´n o o Cada vez que una sentencia acaba con dos puntos (:), Python espera que la sentencia o sentencias que le siguen aparezcan con una mayor indentaci´n. Es la forma de marcar o el inicio y el fin de una serie de sentencias que ˂˂dependen˃˃ de otra. Hay una excepci´n: si s´lo hay una sentencia que ˂˂depende˃˃ de otra, puedes escribir o o ambas en la misma l´ ınea. Este programa: 1 a = int(raw_input(’Dame␣un␣entero␣positivo:␣’)) 2 while a < 0: 3 a = int(raw_input(’Te␣he␣dicho␣positivo:␣’)) 4 if a % 2 == 0: 5 print ’El␣n´mero␣es␣par’ u 6 else: 7 print ’El␣n´mero␣es␣impar’ u y este otro: 1 a = int(raw_input(’Dame␣un␣entero␣positivo:␣’)) 2 while a < 0: a = int(raw_input(’Te␣he␣dicho␣positivo:␣’)) 3 if a % 2 == 0: print ’El␣n´mero␣es␣par’ u 4 else: print ’El␣n´mero␣es␣impar’ u son equivalentes.posibles errores con if resulta un tanto pesada, pues modifica sensiblemente el aspectodel programa al llenarlo de comprobaciones. Hay una estructura de control especial para la detecci´n y tratamiento de excepciones: otry-except. Su forma b´sica de uso es ´sta: a e try: acci´n o potencialmente err´nea o acci´n o potencialmente err´nea o ... acci´n o potencialmente err´nea o except: acci´n o para tratar el error acci´n o para tratar el error ... acci´n o para tratar el errorPodemos expresar la idea fundamental as´ ı: ˂˂Intenta ejecutar estas acciones y, si se comete un error, ejecuta inmediatamente estas otras.˃˃ Es f´cil entender qu´ hace b´sicamente si estudiamos un ejemplo sencillo. Volvamos a e aa considerar el problema de la resoluci´n de una ecuaci´n de primer grado: o o primer grado 14.py primer grado.py 1 a = float(raw_input(’Valor␣de␣a:␣’)) 2 b = float(raw_input(’Valor␣de␣b:␣’)) 3 4 try: 5 x = -b/a 6 print ’Soluci´n:␣’, x o 7 except: 8 if b != 0: 9 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o oIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 133 133 Introducción a la programación con Python - cUJI UJI
    • 10 else:11 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o Las l´ ıneas 5 y 6 est´n en un bloque que depende de la sentencia try. Es admisible aque se lancen excepciones desde ese bloque. Si se lanza una, la ejecuci´n pasar´ inme- o adiatamente al bloque que depende de la sentencia except. Hagamos dos trazas, una parauna configuraci´n de valores de a y b que provoque un error de divisi´n por cero y una o opara otra que no genere excepci´n alguna: o a=0yb=3 a = 1 y b = −1 Las l´ıneas 1 y 2 se ejecutan, con lo que Las l´ıneas 1 y 2 se ejecutan, con lo que se leen los valores de a y b. se leen los valores de a y b. ...................................... ...................................... La l´ ınea 4 se ejecuta, pero no hay un efec- La l´ ınea 4 se ejecuta, pero no hay un efec- to asociado a su ejecuci´n. o to asociado a su ejecuci´n. o ...................................... ...................................... Al ejecutarse la l´ınea 5, se produce una Se ejecutan las l´ıneas 5 y 6, con lo que excepci´n (divisi´n por cero). Se salta in- o o se muestra por pantalla el valor de la so- mediatamente a la l´ ınea 8. luci´n de la ecuaci´n: Soluci´n: 1. La o o o ejecuci´n finaliza. o ...................................... Se ejecuta la l´ ınea 8 y el resultado de la comparaci´n es cierto. o ...................................... La l´ ınea 9 se ejecuta y se muestra por pantalla el mensaje ˂˂La ecuaci´n noo tiene soluci´n.˃˃ o Atrev´monos ahora con la resoluci´n de una ecuaci´n de segundo grado: a o o segundo grado 23.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 try: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)10 if x1 == x2:11 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x1 o o12 else:13 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o14 except:15 # No sabemos si llegamos aqu´ por una divisi´n por cero o si llegamos ı o16 # por intentar calcular la ra´ cuadrada de un discriminante negativo. ız17 print ’O␣no␣hay␣soluciones␣reales␣o␣es␣una␣ecuaci´n␣de␣primer␣grado’ o Como es posible que se cometan dos tipos de error diferentes, al llegar al bloquedependiente del except no sabemos cu´l de los dos tuvo lugar. Evidentemente, podemos aefectuar las comprobaciones pertinentes sobre los valores de a, b y c para deducir elerror concreto, pero queremos contarte otra posibilidad de la sentencia try-except. Lasexcepciones tienen un ˂˂tipo˃˃ asociado y podemos distinguir el tipo de excepci´n para oactuar de diferente forma en funci´n del tipo de error detectado. Una divisi´n por cero o oes un error de tipo ZeroDivisionError y el intento de calcular la ra´ cuadrada de un ızvalor negativo es un error de tipo ValueError. Mmmm. Resulta dif´ recordar de qu´ ıcil etipo es cada error, pero el int´rprete de Python resulta util para recordar si provocamos e ´deliberadamente un error del tipo que deseamos tratar:Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 134 134 Introducción a la programación con Python - cUJI UJI
    • ↱>>> 1 / 0Traceback (most recent call last): File "<stdin>", line 1, in ?ZeroDivisionError: integer division or modulo by zero ↱>>> from math import sqrt ↱>>> sqrt(-1)Traceback (most recent call last): File "<stdin>", line 1, in ?ValueError: math domain error Es posible usar varias cl´usulas except, una por cada tipo de error a tratar: a segundo grado 24.py segundo grado.py 1 from math import sqrt 2 3 a = float(raw_input(’Valor␣de␣a:␣’)) 4 b = float(raw_input(’Valor␣de␣b:␣’)) 5 c = float(raw_input(’Valor␣de␣c:␣’)) 6 7 try: 8 x1 = (-b + sqrt(b**2 - 4*a*c)) / (2 * a) 9 x2 = (-b - sqrt(b**2 - 4*a*c)) / (2 * a)10 if x1 == x2:11 print ’Soluci´n␣de␣la␣ecuaci´n:␣x=%4.3f’ % x1 o o12 else:13 print ’Soluciones␣de␣la␣ecuaci´n:␣x1=%4.3f␣y␣x2=%4.3f’ % (x1, x2) o14 except ZeroDivisionError:15 if b != 0:16 print ’La␣ecuaci´n␣no␣tiene␣soluci´n.’ o o17 else:18 print ’La␣ecuaci´n␣tiene␣infinitas␣soluciones.’ o19 except ValueError:20 print ’No␣hay␣soluciones␣reales’4.4. Algunos ejemplos gr´ficos a4.4.1. Un graficador de funcionesNuestro objetivo ahora es utilizar las funciones gr´ficas predefinidas para representar la afunci´n seno entre −2π y 2π. Vamos a empezar definiendo el nuevo sistema de coordena- odas con una llamada a window_coordinates(x1, y1, x2, y2). Est´ claro que x1 valdr´ a a−2π y x2 valdr´ 2π. ¿Qu´ valores tomar´n y1 e y2? La funci´n seno toma valores entre a e a o−1 y 1, as´ que esos son los valores que asignaremos a y1 e y2, respectivamente. ı Recuerda que, en el sistema de coordenadas del lienzo, la esquina inferior izquierdaes el punto (0, 0) y la esquina superior derecha es el punto (1000, 1000). Si dibujamosdirectamente valores de la funci´n seno, no apreciaremos el aspecto ondulado que es- operamos: el valor m´ximo del seno es 1, que sobre 1000 es un valor muy peque˜o, y el a nvalor m´ ınimo es −1, que ni siquiera se mostrar´ en pantalla. Hay una funci´n predefinida a oque nos permite cambiar el sistema de coordenadas, window_coordinates, y otra que nospermite cambiar el tama˜o del lienzo, window_size. n window_coordinates(x1, y1, x2, y2): Cambia el sistema de coordenadas del lien- zo. La esquina inferior izquierda pasa a tener coordenadas (x1, y1) y la esquina superior derecha pasa a tener coordenadas (x2, y2).Introducci´n a la programaci´n con Python o o 135 135 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • window_size(x, y): Cambia el tama˜o del lienzo, que pasa a tener una anchura n de x p´ ıxels y una altura de y p´ ıxels. Empezaremos ajustando las dimensiones del lienzo, su sistema de coordenadas ydibujando algunos puntos de la funci´n seno: o seno 6.py seno.py 1 from math import pi, sin 2 3 window_size (500, 500) 4 window_coordinates(-2*pi, -1.5, 2*pi, 1.5) 5 6 create_point(-2*pi, sin(-2*pi)) 7 create_point(-1.5*pi, sin(-1.5*pi)) 8 create_point(-pi, sin(-pi)) 9 create_point(-0.5*pi, sin(-0.5*pi))10 create_point(0, sin(0))11 create_point(0.5*pi, sin(0.5*pi))12 create_point(pi, sin(pi))13 create_point(1.5*pi, sin(1.5*pi))14 create_point(2*pi, sin(2*pi)) Figura 4.4: Primeras pruebas de dibujo con la funci´n seno. o La figura 4.4 muestra el resultado que aparece en pantalla. Vamos bien. Aparecenpocos puntos, pero podemos apreciar que est´n dispuestos como corresponde a la funci´n a oseno. La cosa mejorar´ a˜adiendo m´s puntos, pero desde luego que no lo haremos ıa n arepitiendo l´ ıneas en el programa como en el ejemplo: usaremos un bucle while. La idea es hacer que una variable x vaya recorriendo, paso a paso, el intervalo[−2π, 2π], y para cada valor, llamar a create_point(x, sin(x)). ¿Qu´ queremos decir con e˂˂paso a paso˃˃? Pues que de una iteraci´n a la siguiente, aumentaremos x en una cantidad ofija. Pongamos, inicialmente, que esta cantidad es 0.05. Nuestro programa presentar´ este aaspectoIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 136 136 Introducción a la programación con Python - cUJI UJI
    • seno.py 1 from math import pi, sin 2 3 window_size (500, 500) 4 window_coordinates(-2*pi, -1.5, 2*pi, 1.5) 5 6 x = valor inicial 7 while condici´n : o 8 create_point(x, sin(x)) 9 x += 0.05¿Qu´ valor inicial asignamos a x? Podemos probar con −2π, que es la coordenada X del eprimer punto que nos interesa mostrar. ¿Y qu´ condici´n ponemos en el while? A ver, nos e ointeresa repetir mientras x sea menor que 2π. Pues ya est´: a seno 7.py seno.py 1 from math import pi, sin 2 3 window_size (500, 500) 4 window_coordinates(-2*pi, -1.5, 2*pi, 1.5) 5 6 x = -2*pi 7 while x <= 2*pi : 8 create_point(x, sin(x)) 9 x += 0.05 Figura 4.5: La funci´n seno trazada con varios puntos. oLa figura 4.5 muestra el resultado de ejecutar el programa. Esto ya es otra cosa. A´n as´ u ı,nos gustar´ mostrar m´s puntos. Ahora el cambio que debemos efectuar es muy sencillo: ıa aen lugar de poner un incremento de 0.05, podemos poner un incremento m´s peque˜o. a nCuanto menor sea el incremento, m´s puntos dibujaremos. ¿Y si deseamos que aparezcan aexactamente 1000 puntos? Muy sencillo: podemos calcular el incremento dividiendo entre1000 el dominio de la funci´n: oIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 137 137 Introducción a la programación con Python - cUJI UJI
    • seno 8.py seno.py 1 from math import pi, sin 2 3 window_size (500, 500) 4 window_coordinates(-2*pi, -1.5, 2*pi, 1.5) 5 6 incremento = (2*pi - -2*pi) / 1000 7 8 x = -2*pi 9 while x <= 2*pi :10 create_point(x, sin(x))11 x += incremento Figura 4.6: La funci´n seno trazada con 1000 puntos. o Hagamos que el usuario pueda introducir el intervalo de valores de x que deseaexaminar, as´ como el n´mero de puntos que desee representar: ı u seno 9.py seno.py 1 from math import pi, sin 2 3 x1 = float(raw_input(’Dime␣el␣l´mite␣inferior␣del␣intervalo:␣’)) ı 4 x2 = float(raw_input(’Dime␣el␣l´mite␣superior␣del␣intervalo:␣’)) ı 5 puntos = int(raw_input(’Dime␣cu´ntos␣puntos␣he␣de␣mostrar:␣’)) a 6 7 window_size(500, 500) 8 window_coordinates(x1, -1.5, x2, 1.5) 910 incremento = (x2 - x1) / puntos1112 x = x113 while x <= x2:14 create_point(x, sin(x))Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 138 138 Introducción a la programación con Python - cUJI UJI
    • 15 x += incremento Haz varias pruebas con el programa. Los dibujos punto a punto no parecen formaruna gr´fica cont´ a ınua a menos que usemos un n´mero muy elevado de puntos. ¿Y si en ulugar de puntos aislados mostramos las l´ ıneas que los unen? Estudia este otro programa,a ver si averiguas qu´ hace y c´mo: e o seno 10.py seno.py 1 from math import pi, sin 2 3 x1 = float(raw_input(’Dime␣el␣l´mite␣inferior␣del␣intervalo:␣’)) ı 4 x2 = float(raw_input(’Dime␣el␣l´mite␣superior␣del␣intervalo:␣’)) ı 5 puntos = int(raw_input(’Dime␣cu´ntos␣puntos␣he␣de␣mostrar:␣’)) a 6 7 window_size(500, 500) 8 window_coordinates(x1, -1.5, x2, 1.5) 910 incremento = (x2 - x1) / puntos1112 x = x113 while x <= x2 - incremento:14 create_line(x, sin(x), x+incremento, sin(x+incremento))15 x += incremento Prueba el programa con diferentes valores. F´ıjate en qu´ programa tan util hemos e ´construido con muy pocos elementos: variables, bucles, el m´dulo math y unas pocas ofunciones predefinidas para trabajar con gr´ficos. a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 137 Haz un programa que muestre la funci´n coseno en el intervalo que te indiqueoel usuario.· 138 Modifica el programa anterior para que se muestren dos funciones a la vez: lafunci´n seno y la funci´n coseno, pero cada una en un color distinto. o o· 139 Haz un programa que muestre la funci´n 1/(x + 1) en el intervalo [−2, 2] con 100 opuntos azules. Ten en cuenta que la funci´n es ˂˂problem´tica˃˃ en x = −1, por lo que o adibujaremos un punto rojo en las coordenadas (−1, 0).· 140 Haz un programa que, dados tres valores a, b y c, muestre la funci´n f (x) = oax 2 + bx + c en el intervalo [z , z ], donde z y z son valores proporcionados por el 1 2 1 2usuario. El programa de dibujo debe calcular el valor m´ximo y m´ a ınimo de f (x) en elintervalo indicado para ajustar el valor de window_coordinates de modo que la funci´n ose muestre sin recorte alguno.· 141 A˜ade a la gr´fica del ejercicio anterior una representaci´n de los ejes coorde- n a onados en color azul. Dibuja con c´ ırculos rojos los puntos en los que la par´bola f (x) corta ael eje horizontal. Recuerda que la par´bola corta al eje horizontal en los puntos x1 y x2 aque son soluci´n de la ecuaci´n de segundo grado ax 2 + bx + c = 0. o o ..................................................................................4.4.2. Una animaci´n: simulaci´n gravitacional o oVamos a construir ahora un peque˜o programa de simulaci´n gravitacional. Representare- n omos en pantalla dos cuerpos y veremos qu´ movimiento presentan bajo la influencia mutua ede la gravedad en un universo bidimensional. Nos har´ falta repasar algunas nociones ab´sicas de f´ a ısica.Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 139 139 Introducción a la programación con Python - UJIUJI c
    • La ley de gravitaci´n general de Newton nos dice que dos cuerpos de masas m1 y om2 se atraen con una fuerza m1 m2 F =G 2 , rdonde G es la constante de gravitaci´n universal y r es la distancia que separa a los ocuerpos. Sometido a esa fuerza, cada cuerpo experimenta una aceleraci´n. Recuerda que ola aceleraci´n a experimentada por un cuerpo de masa m sometido a una fuerza F es oa = F /m. Cada cuerpo experimentar´ una aceleraci´n distinta: a o m2 a1 = G , r2 m1 a2 = G 2. rComo los cuerpos ocupan las posiciones (x1 , y1 ) y (x2 , y2 ) en el plano, podemos dar unaformulaci´n vectorial de las f´rmulas anteriores: o o m2 r12 a1 = G , r3 m1 r21 a2 = G 3 , rdonde los s´ ımbolos en negrita son vectores. m2 y2 r21 r12 y 1 m1 x1 x2En particular, r12 es el vector (x2 − x1 , y2 − y1 ) y r21 es el vector (x1 − x2 , y1 − y2 ). Elvalor de r, su m´dulo, es o (x2 − x1 )2 + (y2 − y1 )2 . La aceleraci´n afecta en cada instante de tiempo a la velocidad de cada cuerpo. Si un ocuerpo se desplaza en un instante dado a una velocidad (vx , vy ), una unidad de tiempo m´s atarde se desplazar´ a velocidad (vx +ax , vy +ay ), siendo (ax , ay ) su vector de aceleraci´n. a oEl vector de aceleraci´n del primer cuerpo es proporcional a r12 , y el del segundo cuerpo oes proporcional a r21 . Ya basta de f´ısica. Volvamos al mundo de PythonG. Para abordar nuestra tarea hemosde aprender un par de nuevas funciones y alguna t´cnica que a´n no hemos estudiado. e u Representaremos cada cuerpo con un c´ ırculo cuyo radio es proporcional a su masa.La funci´n create_circle acepta como par´metros las coordenadas del centro de una o acircunferencia, su radio y, opcionalmente, el color. ¿Con qu´ datos modelamos cada cuerpo? Una variable almacenar´ la masa de cada e acuerpo, eso est´ claro. Llamemos a esas variables m1 y m2. En cada instante, cada cuerpo aocupa una posici´n en el plano. Cada posici´n se representa con dos valores: la posici´n o o oen el eje X y la posici´n en el eje Y . Las variables x1 e y1 almacenar´n la posici´n del o a oprimer cuerpo y las variables x2 e y2 las del segundo. Otro dato importante es la velocidadque cada cuerpo lleva en un instante dado. La velocidad es un vector, as´ que necesitamos ıdos variables para representarla. Las variables velocidad_x1 y velocidad_y1 almacenar´n ael vector de velocidad del primer cuerpo y las variables velocidad_x2 y velocidad_y2el del segundo. Tambi´n la aceleraci´n de cada cuerpo requiere dos variables y para e oIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 140 140 Introducción a la programación con Python - cUJI UJI
    • representarla seguiremos el mismo patr´n, s´lo que las variables empezar´n con el prefijo o o aaceleracion. Inicialmente cada cuerpo ocupa una posici´n y lleva una velocidad determinada. Nues- otro programa puede empezar, de momento, as´ ı: gravedad.py 1 x1 = -200 2 y1 = -200 3 velocidad_x1 = 0.1 4 velocidad_y1 = 0 5 m1 = 20 6 7 x2 = 200 8 y2 = 200 9 velocidad_x2 = -0.110 velocidad_y2 = 011 m2 = 20 Los c´lculos que nos permiten actualizar los valores de posici´n y velocidad de cada a ocuerpo son, de acuerdo con las nociones de f´ ısica que hemos repasado, estos: gravedad.py13 r = sqrt( (x2-x1)**2 + (y2-y1)**2 )1415 aceleracion_x1 = m2 * (x2 - x1) / r**316 aceleracion_y1 = m2 * (y2 - y1) / r**317 aceleracion_x2 = m1 * (x1 - x2) / r**318 aceleracion_y2 = m1 * (y1 - y2) / r**31920 velocidad_x1 += aceleracion_x121 velocidad_y1 += aceleracion_y122 velocidad_x2 += aceleracion_x223 velocidad_y2 += aceleracion_y22425 x1 += velocidad_x126 y1 += velocidad_y127 x2 += velocidad_x228 y2 += velocidad_y2Advertir´s que no hemos usado la constante de gravitaci´n G. Como afecta linealmente a a ola f´rmula, su unico efecto pr´ctico es ˂˂acelerar˃˃ la simulaci´n, as´ que hemos decidido o ´ a o ıprescindir de ella. Mostraremos los cuerpos con sendas llamadas a create_circle: gravedad.py30 create_circle(x1, y1, m1, ’red’)31 create_circle(x2, y2, m2, ’blue’) Si queremos ver c´mo evolucionan los cuerpos a lo largo del tiempo, deberemos repetir oeste c´lculo numerosas veces, as´ que formar´ parte de un bucle. Para ver qu´ ocurre a a ı a elo largo de 10000 unidades de tiempo, por ejemplo, insertaremos esa serie de accionesen un bucle al final del cual se redibujan los dos cuerpos: gravedad 6.py gravedad.py 1 from math import sqrt 2 3 window_coordinates(-500,-500, 500,500) # Puedes cambiar estos valores para hacer zoom 4 5 x1 = -200Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 141 141 Introducción a la programación con Python - cUJI UJI
    • 6 y1 = -200 7 velocidad_x1 = 0.1 8 velocidad_y1 = 0 9 m1 = 201011 x2 = 20012 y2 = 20013 velocidad_x2 = -0.114 velocidad_y2 = 015 m2 = 201617 for t in range(10000):18 r = sqrt( (x2-x1)**2 + (y2-y1)**2 )1920 aceleracion_x1 = m2 * (x2 - x1) / r**321 aceleracion_y1 = m2 * (y2 - y1) / r**322 aceleracion_x2 = m1 * (x1 - x2) / r**323 aceleracion_y2 = m1 * (y1 - y2) / r**32425 velocidad_x1 += aceleracion_x126 velocidad_y1 += aceleracion_y127 velocidad_x2 += aceleracion_x228 velocidad_y2 += aceleracion_y22930 x1 += velocidad_x131 y1 += velocidad_y132 x2 += velocidad_x233 y2 += velocidad_y23435 create_circle(x1, y1, m1, ’red’)36 create_circle(x2, y2, m2, ’blue’) Y ya est´: ejecutemos el programa en el entorno PythonG. He aqu´ el resultado final a ı(en pantalla aparecer´ como una animaci´n): a o Como puedes observar, no apreciamos ya la posici´n de los cuerpos: se han dibujado otantos c´ırculos que unos tapan a otros. Deber´ ıamos haber desplazado cada c´ ırculo enlugar de ir a˜adiendo un c´ n ırculo tras otro. Lamentablemente, no sabemos (a´n) de ninguna ufunci´n que permita desplazar un c´ o ırculo. S´ disponemos, no obstante, de la posibilidad ıde borrar un c´ ırculo existente. Si borramos cada c´ ırculo antes de dibujar el siguiente,conseguiremos el mismo efecto que si desplaz´semos un solo c´ a ırculo. Esa es la primerat´cnica que usaremos para efectuar la animaci´n. e o ¿C´mo borramos un c´ o ırculo? Mediante la funci´n predefinida erase. Esa funci´n no o os´lo borra c´ o ırculos: borra cualquier objeto creado con una funci´n predefinida que empieza opor create_ . Para ello, hemos de asociar una variable al objeto creado cuando invocamosa una funci´n create_ . He aqu´ un ejemplo de uso: o ı 1 c = create_circle(0, 0, 100, ’yellow’) 2 erase(c)Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 142 142 Introducción a la programación con Python - cUJI UJI
    • Ya est´ claro c´mo actuar: a o gravedad 7.py gravedad.py 1 from math import sqrt 2 3 window_coordinates(-500, -500, 500, 500) 4 5 x1 = -200 6 y1 = -200 7 velocidad_x1 = 0.1 8 velocidad_y1 = 0 9 m1 = 201011 x2 = 20012 y2 = 20013 velocidad_x2 = -0.114 velocidad_y2 = 015 m2 = 201617 circulo_ 1 = create_circle(x1, y1, m1, ’red’)18 circulo_ 2 = create_circle(x2, y2, m2, ’blue’)1920 for t in range(10000):2122 r = sqrt( (x2-x1)**2 + (y2-y1)**2 )2324 aceleracion_x1 = m2 * (x2 - x1) / r**325 aceleracion_y1 = m2 * (y2 - y1) / r**326 aceleracion_x2 = m1 * (x1 - x2) / r**327 aceleracion_y2 = m1 * (y1 - y2) / r**328 velocidad_x1 += aceleracion_x129 velocidad_y1 += aceleracion_y130 velocidad_x2 += aceleracion_x231 velocidad_y2 += aceleracion_y232 x1 += velocidad_x133 y1 += velocidad_y134 x2 += velocidad_x235 y2 += velocidad_y23637 erase(circulo_ 1)38 circulo_ 1 = create_circle(x1, y1, m1, ’red’)39 erase(circulo_ 2)40 circulo_ 2 = create_circle(x2, y2, m2, ’blue’) Si ejecutas ahora el programa ver´s c´mo la r´pida creaci´n y destrucci´n del c´ a o a o o ırculoprovocan la ilusi´n de un desplazamiento. Pero hay un problema: aparece un molesto oparpadeo. Al destruir y crear r´pidamente los objetos, hay breves instantes en los que, asencillamente, no est´n en pantalla. Esta desaparici´n y aparici´n continuadas se tra- a o oducen en un p´simo efecto. Una soluci´n posible consiste en invertir el orden: en lugar e ode destruir y crear, crear y destruir. Ello supone que, en algunos instantes, haya doscopias del mismo objeto en pantalla (ligeramente desplazadas). El efecto conseguido noobstante, es agradable. Hay una funci´n adicional especialmente pensada para animaciones: move. La funci´n o omove recibe tres par´metros: un objeto creado con una funci´n create_ y dos valores dx a oe dy . Si el objeto se encuentra en el punto (x, y), el efecto de move es desplazar el objetoal punto (x + dx , y + dy ). gravedad 8.py gravedad.pyIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 143 143 Introducción a la programación con Python - cUJI UJI
    • 1 from math import sqrt 2 3 window_coordinates(-500, -500, 500, 500) 4 5 x1 = -200 6 y1 = -200 7 velocidad_x1 = 0.1 8 velocidad_y1 = 0 9 m1 = 201011 x2 = 20012 y2 = 20013 velocidad_x2 = -0.114 velocidad_y2 = 015 m2 = 201617 circulo_ 1 = create_circle(x1, y1, m1, ’red’)18 circulo_ 2 = create_circle(x2, y2, m2, ’blue’)1920 for t in range(10000):2122 r3 = sqrt( (x2-x1)**2 + (y2-y1)**2 ) ** 32324 aceleracion_x1 = m2 * (x2 - x1) / r325 aceleracion_y1 = m2 * (y2 - y1) / r326 aceleracion_x2 = m1 * (x1 - x2) / r327 aceleracion_y2 = m1 * (y1 - y2) / r32829 velocidad_x1 += aceleracion_x130 velocidad_y1 += aceleracion_y131 velocidad_x2 += aceleracion_x232 velocidad_y2 += aceleracion_y23334 x1 += velocidad_x135 y1 += velocidad_y136 x2 += velocidad_x237 y2 += velocidad_y23839 move(circulo_ 1, velocidad_x1, velocidad_y1)40 move(circulo_ 2, velocidad_x2, velocidad_y2)F´ ıjate en que hemos hecho otro cambio: en lugar de calcular el valor de r y elevarlo alcubo en cuatro ocasiones (una operaci´n costosa), hemos calculado directamente el valor odel cubo de r. Nos gustar´ ahora que los cuerpos dejasen una ˂˂traza˃˃ de los lugares por los que ıahan pasado, pues as´ resultar´ m´s f´cil apreciar las ´rbitas que describen. Estudia este ı a a a ootro programa y averigua c´mo hemos hecho para dejar esa traza: o gravedad 9.py gravedad.py 1 from math import sqrt 2 3 window_coordinates(-500, -500, 500, 500) 4 5 x1 = -200 6 y1 = -200 7 velocidad_x1 = 0.1 8 velocidad_y1 = 0 9 m1 = 2010Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 144 144 Introducción a la programación con Python - cUJI UJI
    • 11 x2 = 20012 y2 = 20013 velocidad_x2 = -0.114 velocidad_y2 = 015 m2 = 201617 circulo_ 1 = create_circle(x1, y1, m1, ’red’)18 circulo_ 2 = create_circle(x2, y2, m2, ’blue’)1920 for t in range(10000):2122 r3 = sqrt( (x2-x1)**2 + (y2-y1)**2 ) ** 32324 aceleracion_x1 = m2 * (x2 - x1) / r325 aceleracion_y1 = m2 * (y2 - y1) / r326 aceleracion_x2 = m1 * (x1 - x2) / r327 aceleracion_y2 = m1 * (y1 - y2) / r32829 velocidad_x1 += aceleracion_x130 velocidad_y1 += aceleracion_y131 velocidad_x2 += aceleracion_x232 velocidad_y2 += aceleracion_y23334 viejo_x1 = x135 viejo_y1 = y136 viejo_x2 = x237 viejo_y2 = y23839 x1 += velocidad_x140 y1 += velocidad_y141 x2 += velocidad_x242 y2 += velocidad_y24344 move(circulo_ 1, velocidad_x1, velocidad_y1)45 create_line(viejo_x1, viejo_y1, x1, y1, ’red’)46 move(circulo_ 2, velocidad_x2, velocidad_y2)47 create_line(viejo_x2, viejo_y2, x2, y2, ’blue’) Esta imagen se ha obtenido cuando el programa iba por la iteraci´n 5000: o Divi´rtete con el programa. He aqu´ algunas configuraciones iniciales interesantes: e ıa) 1 x1 = -200 2 y1 = -200 3 velocidad_x1 = 0.1 4 velocidad_y1 = 0 5 m1 = 0.001 6 7 x2 = 200 8 y2 = 200Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 145 145 Introducción a la programación con Python - cUJI UJI
    • 9 velocidad_x2 = 0 10 velocidad_y2 = 0 11 m2 = 20b) 1 x1 = -200 2 y1 = -200 3 velocidad_x1 = -0.1 4 velocidad_y1 = 0 5 m1 = 20 6 7 x2 = 200 8 y2 = 200 9 velocidad_x2 = -0.1 10 velocidad_y2 = 0 11 m2 = 20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 142 ¿Qu´ pasar´ si los dos cuerpos ocuparan exactamente la misma posici´n en el e ıa oplano? Modifica el programa para que, si se da el caso, no se produzca error alguno yfinalice inmediatamente la ejecuci´n del bucle. o· 143 Modifica el programa para que la simulaci´n no finalice nunca (bueno, s´lo o ocuando el usuario interrumpa la ejecuci´n del programa). o· 144 ¿Ser´ capaz de extender el programa para que muestre la interacci´n entre ıas otres cuerpos? Repasa la formulaci´n f´ o ısica del problema antes de empezar a programar. ..................................................................................4.4.3. Un programa interactivo: un videojuegoYa sabemos dibujar gr´ficas y mostrar sencillas animaciones. Demos el siguiente paso: ahagamos un programa gr´fico interactivo. En este apartado dise˜aremos un videojuego a nmuy simple que nos ponga a los mandos de una nave espacial que debe aterrizar en unaplataforma m´vil. o La nave aparecer´ en pantalla a cierta altura y, desde el primer instante, empezar´ a aa caer atra´ por la gravedad del planeta. Disponemos de un control muy rudimentario: ıdapodemos activar los propulsores de la nave con las teclas de cursor para contrarrestarel efecto de la gravedad, as´ como desplazarnos lateralmente. El desplazamiento lateral ıser´ necesario para conseguir que la nave aterrice sobre la plataforma, pues ´sta se ir´ a e atrasladando por la superficie del planeta durante el juego. Con cada activaci´n de los propulsores se consumir´ una determinada cantidad de o afuel. Cuando nos quedemos sin combustible, la nave entrar´ en ca´ libre. Perderemos a ıdala partida si no acertamos a aterrizar en la plataforma o si, al aterrizar, la velocidad deca´ es excesiva. ıda Planifiquemos el trabajo: 1. Empezaremos por mostrar la nave espacial en pantalla y ˂˂dejarla caer˃˃. As´ apren- ı deremos a simular el efecto de la gravedad. 2. A continuaci´n nos encargaremos de controlar el propulsor inferior de la nave, el o que contrarresta el efecto de la gravedad. 3. El siguiente objetivo ser´ permitir el movimiento lateral de la nave. a 4. Iremos entonces a por el dibujo de la plataforma de aterrizaje y su desplazamiento.Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 146 146 Introducción a la programación con Python - UJIUJI c
    • 5. En seguida pasaremos a considerar el consumo de fuel y a mostrar en pantalla algunos datos informativos, como la velocidad de ca´ y el fuel disponible. ıda 6. Para acabar, detectaremos los aterrizajes y valoraremos la actuaci´n del jugador o (si gan´ o perdi´ y, en este ultimo caso, por qu´ motivo). o o ´ e Vamos all´. El mundo en el que trascurre la acci´n ser´ un simple plano con el a o asistema de coordenadas que decidamos. Como la ventana gr´fica de PythonG tiene una aresoluci´n por defecto de 400 × 400, asumiremos ese sistema de coordenadas. o aterrizaje.py 1 # Paisaje 2 altura_paisaje = 400 3 anchura_paisaje = 400 4 window_coordinates(0, 0, anchura_paisaje, altura_paisaje) No estamos para alardes gr´ficos: nuestra nave ser´ un sencillo cuadrado de color a aazul de 10 × 10 p´ ıxels en cierta posici´n (x, y). o aterrizaje.py 1 ... 2 # Nave 3 tamanyo_nave = 10 4 x = anchura_paisaje / 2 5 y = altura_paisaje - 100 6 create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’) Que empiece la acci´n. ¿C´mo efectuamos la simulaci´n de la atracci´n gravitatoria? o o o oNo hace falta complicarse tanto la vida como en la secci´n anterior: aqu´ la gravedad o ısiempre tira de la nave hacia abajo. El simulador actuar´ as´ la nave tiene una velocidad a ı:de ca´ y, con cada iteraci´n de la simulaci´n, esta aumenta en cierta cantidad (digamos ıda o og). La nave ir´ actualizando su posici´n a partir de la posici´n y velocidad de ca´ en a o o ıdacada instante. aterrizaje.py 1 ... 2 # Gravedad 3 g=1 4 5 # Nave 6 tamanyo_nave = 10 7 x = anchura_paisaje / 2 8 y = altura_paisaje - 100 9 vy = 010 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1112 # Simulaci´n o13 while condici´n : o14 vy -= g15 y += vy16 move(nave, 0, vy) Varias cosas. Por un lado, ¿no hemos dicho que la velocidad de ca´ aumentar´ ıda ıaen cada paso? Pues no estamos sumando el valor de g a la velocidad vertical vy, sinorest´ndolo. No te preocupes: es lo correcto. La velocidad aumenta en valor absoluto, pero asu direcci´n es de ca´ de ah´ que el signo del incremento sea negativo. Por otra parte, o ıda, ı¿qu´ condici´n determina el final de la simulaci´n? Est´ claro: que la nave toque tierra, e o o aIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 147 147 Introducción a la programación con Python - cUJI UJI
    • es decir, que su altura sea igual o menor que cero. ¿Por qu´ menor que cero? Es posible eque la nave lleve tal velocidad de ca´ que ˂˂aterrice˃˃ formando un hermoso cr´ter. Mejor ıda aestar preparados para esa eventualidad. Aqu´ tienes el programa completo en su estado ıactual. aterrizaje 14.py aterrizaje.py 1 # Paisaje 2 altura_paisaje = 400 3 anchura_paisaje = 400 4 window_coordinates(0, 0, anchura_paisaje, altura_paisaje) 5 6 # Gravedad 7 g=1 8 9 # Nave10 tamanyo_nave = 1011 x = anchura_paisaje / 212 y = altura_paisaje - 10013 vy = 014 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1516 # Simulaci´n o17 while y > 0:18 vy -= g19 y += vy20 move(nave, 0, vy) Ejecuta el programa. ¿Qu´ ocurre? La nave aparece directamente en el suelo. En erealidad, ha pasado por varios sitios en su ca´ hasta el suelo, s´lo que lo ha hecho ıda otan r´pidamente que no hemos podido percibir el desplazamiento. Hemos de modificar ael valor de g para obtener una simulaci´n m´s lenta. Un valor de g razonable en el o aordenador en el que estamos desarrollando el programa es 0.0001. Encuentra t´ el m´s u aadecuado para tu ordenador. aterrizaje 15.py aterrizaje.py 1 # Paisaje 2 altura_paisaje = 400 3 anchura_paisaje = 400 4 window_coordinates(0, 0, anchura_paisaje, altura_paisaje) 5 6 # Gravedad 7 g = 0.00001 8 9 # Nave10 tamanyo_nave = 1011 x = anchura_paisaje / 212 y = altura_paisaje - 10013 vy = 014 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1516 # Simulaci´n o17 while y > 0:18 vy -= g19 y += vy20 move(nave, 0, vy) Es hora de habilitar el control del propulsor vertical. PythonG ofrece una funci´n opredefinida para acceder al teclado: keypressed (en ingl´s significa ˂˂tecla pulsada˃˃). La epuedes llamar de estas dos formas diferentes (entre otras):Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 148 148 Introducción a la programación con Python - cUJI UJI
    • keypressed(1): devuelve None si no hay ninguna tecla pulsada y una cadena que describe la tecla pulsada en caso contrario. None significa ˂˂ausencia de valor˃˃ y es equivalente al valor l´gico falso. o keypressed(2): espera a que el usuario pulse una tecla y devuelve entonces una cadena que la describe. Nos interesa detectar la pulsaci´n de la tecla de cursor hacia arriba. La cadena que ola describe es ’Up’. Su efecto es sumar cierta cantidad, a la que llamaremos impulso_y,a la velocidad de ca´ ıda. ¿Qu´ cantidad sumar? Si es g, mal: como mucho podremos econtrarrestar el efecto gravitatorio, pero no podremos moderar la velocidad de ca´ ıda.Pongamos que impulso_y es dos veces g. aterrizaje 16.py aterrizaje.py 1 # Paisaje 2 altura_paisaje = 400 3 anchura_paisaje = 400 4 window_coordinates(0, 0, anchura_paisaje, altura_paisaje) 5 6 # Gravedad 7 g = 0.00001 8 9 # Nave10 tamanyo_nave = 1011 x = anchura_paisaje / 212 y = altura_paisaje - 10013 vy = 014 impulso_y = 2*g1516 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1718 # Simulaci´n o19 while y > 0:20 vy -= g21 if keypressed(1) == ’Up’:22 vy += impulso_y23 y += vy24 move(nave, 0, vy) Prueba ahora el juego. Frena la nave manteniendo pulsada la tecla ’Up’. No te pases:¡puede que la nave desaparezca por el extremo superior de la imagen! Mmmm. Eso noparece bueno. ¿Qu´ hacer si la nave se sale por encima? No hab´ e ıamos contemplado esaeventualidad en la especificaci´n del juego. Improvisemos una soluci´n: haremos que el o ojuego termine tambi´n en ese caso y, adem´s, lo consideraremos un fracaso del jugador. e a aterrizaje 17.py aterrizaje.py 1 # Paisaje . . .1718 # Simulaci´n o19 while y > 0 and y < altura_paisaje :20 vy -= g21 if keypressed(1) == ’Up’:22 vy += impulso_y23 y += vy24 move(nave, 0, vy)Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 149 149 Introducción a la programación con Python - cUJI UJI
    • Siguiendo nuestro plan de trabajo hemos de ocuparnos ahora del desplazamientolateral de la nave. Para conseguir un efecto ˂˂realista˃˃ dotaremos a dicho movimiento deinercia. Es decir, la nave llevar´ una velocidad horizontal que s´lo se modificar´ cuando a o aactuemos sobre los propulsores laterales. El propulsor izquierdo se activar´ con la tecla ade cursor a izquierdas (’Left’) y el propulsor derecho con la tecla de cursor a derechas(’Right’). Y ahora que dotamos de desplazamiento lateral a la nave, el jugador puedechocar con las ˂˂paredes˃˃. Consideraremos tambi´n que chocar contra las ˂˂paredes˃˃ es eun fracaso del jugador. aterrizaje 18.py aterrizaje.py 1 # Paisaje . . .15 impulso_x = 0.0000116 vx = 017 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1819 # Simulaci´n o20 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave :21 vy -= g22 if keypressed(1) == ’Up’:23 vy += impulso_y24 elif keypressed(1) == ’Left’:25 vx -= impulso_x26 elif keypressed(1) == ’Right’:27 vx += impulso_x28 y += vy29 x += vx30 move(nave, vx, vy)El valor de impulso_x se ha escogido para obtener un buen comportamiento de la naveen nuestro ordenador. Tendr´s que encontrar un valor adecuado para tu m´quina. a a A por la plataforma de aterrizaje. La plataforma se representar´ con un rect´ngulo de a acolor diferente, pongamos rojo. ¿D´nde dibujarla? Empezaremos ubic´ndola en la zona o acentral: aterrizaje 19.py aterrizaje.py 1 # Paisaje . . .1819 # Plataforma20 px = anchura_paisaje / 221 py = 022 anchura_plataforma = 4023 altura_plataforma = 32425 plataforma = create_rectangle(px, py,26 px+anchura_plataforma, py+altura_plataforma, ’red’)2728 # Simulaci´n o29 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave: . . . Perfecto. Dijimos que la plataforma se desplazar´ lateralmente. El juego a˜adir´ una ıa n acantidad vpx (por ˂˂velocidad de plataforma en el eje X ˃˃) al valor de px con cada paso yIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 150 150 Introducción a la programación con Python - cUJI UJI
    • actualizar´ su imagen en pantalla. Cuando llegue a un extremo de la imagen, cambiar´ a ade direcci´n. o aterrizaje 20.py aterrizaje.py 1 # Paisaje . . .1819 # Plataforma20 px = anchura_paisaje / 221 py = 022 vpx = .0523 anchura_plataforma = 4024 altura_plataforma = 32526 plataforma = create_rectangle(px, py,27 px+anchura_plataforma, py+altura_plataforma, ’red’)2829 # Simulaci´n o30 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave: . . .40 px += vpx41 if px <= 0 or px >= anchura_paisaje - anchura_plataforma:42 vpx = -vpx43 move(nave, vx, vy)44 move(plataforma, vpx, 0)(Puede que necesites ajustar el valor de vpx para que la plataforma se desplace a unavelocidad razonable en tu ordenador.) ¿Qu´ implementamos ahora? ¡Ah, s´ El consumo e ı!de fuel. Empezaremos con el dep´sito lleno: 1000 litros de fuel. Cada vez que se active oun propulsor consumiremos una cierta cantidad de fuel, digamos 1 litro. aterrizaje 21.py aterrizaje.py 1 # Paisaje . . .2829 # Tanque de combustible30 fuel = 100031 consumo = 13233 # Simulaci´n o34 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave:35 vy -= g36 if keypressed(1) == ’Up’:37 vy += impulso_y38 fuel -= consumo39 elif keypressed(1) == ’Left’:40 vx -= impulso_x41 fuel -= consumo42 elif keypressed(1) == ’Right’:43 vx += impulso_x44 fuel -= consumo . . .47 px += vpx48 if px <= 0 or px >= anchura_paisaje - anchura_plataforma:49 vpx = -vpx50 move(nave, vx, vy)51 move(plataforma, vpx, 0)Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 151 151 Introducción a la programación con Python - cUJI UJI
    • Recuerda que no podemos usar los propulsores cuando no hay fuel: aterrizaje 22.py aterrizaje.py 1 # Paisaje . . .34 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave:35 vy -= g36 if keypressed(1) == ’Up’ and fuel > 0:37 vy += impulso_y38 fuel -= consumo39 elif keypressed(1) == ’Left’ and fuel > 0 :40 vx -= impulso_x41 fuel -= consumo42 elif keypressed(1) == ’Right’ and fuel > 0:43 vx += impulso_x44 fuel -= consumo . . . El simulador debe mostrar en pantalla la cantidad de fuel disponible. Vamos a mos-trarlo con una representaci´n del tanque de combustible y la proporci´n de fuel con o orespecto a su capacidad. aterrizaje 23.py aterrizaje.py 1 # Paisaje . . .30 fuel = 100031 consumo = 132 create_rectangle(0,altura_paisaje, 10, altura_paisaje-100, ’black’)33 lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, ’green’)3435 # Simulaci´n o36 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave: . . .53 move(plataforma, vpx, 0)54 viejo_lleno = lleno55 lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, ’green’)56 erase(viejo_lleno) Mmmm. Parece que nuestra nave consume demasiado: el dep´sito se vac´ con apenas o ıaactivar un propulsor. Hemos de ajustar, pues, el consumo. En nuestro programa lo hemosajustado a un valor de 0.1. Tambi´n interesa mostrar la velocidad de ca´ Dibujaremos un dial con la velocidad e ıda.y una aguja que nos indique la velocidad actual. Estudia el fragmento de programa quete presentamos a continuaci´n: o aterrizaje 24.py aterrizaje.py 1 from math import sin, cos, pi 2 # Paisaje . . .3536 # Dial de velocidad37 create_circle(anchura_paisaje-50, altura_paisaje-50, 50, ’black’)38 for i in range(0, 360, 10):39 create_line(anchura_paisaje-50 + 40 * sin(i*pi/180), Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 152 152 Introducción a la programación con Python - cUJI UJI
    • 40 altura_paisaje-50 + 40 * cos(i*pi/180), 41 anchura_paisaje-50 + 50 * sin(i*pi/180), 42 altura_paisaje-50 + 50 * cos(i*pi/180))4344 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 45 anchura_paisaje-50 + 50 * sin(0*pi/180), 46 altura_paisaje-50 + 50 * cos(0*pi/180), ’blue’) . . .70 vieja_aguja = aguja71 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 72 anchura_paisaje-50 + 50 * sin(1000*vy*pi/180), 73 altura_paisaje-50 + 50 * cos(1000*vy*pi/180), ’blue’)74 erase(vieja_aguja) Una cuesti´n est´tica. Nos vendr´ bien poner alg´n texto en pantalla para rotular o e ıa uel dep´sito o el veloc´ o ımetro. Recuerda que PythonG te ofrece la funci´n predefinida ocreate_text para dibujar texto. aterrizaje 25.py aterrizaje.py 1 from math import sin, cos, pi 2 # Paisaje . . .3536 create_text(25, altura_paisaje-8, ’0%’, 10, ’W’)37 create_text(30, altura_paisaje-95, ’100%’, 10, ’W’)38 # Dial de velocidad39 create_circle(anchura_paisaje-50, altura_paisaje-50, 50, ’black’)40 for i in range(0, 360, 10):41 create_line(anchura_paisaje-50 + 40 * sin(i*pi/180), 42 altura_paisaje-50 + 40 * cos(i*pi/180), 43 anchura_paisaje-50 + 50 * sin(i*pi/180), 44 altura_paisaje-50 + 50 * cos(i*pi/180))4546 if i % 30 == 0:47 create_text(anchura_paisaje-50 + 30 * sin(i*pi/180), 48 altura_paisaje-50 + 30 * cos(i*pi/180), str(i), 5, ’CENTER’)4950 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 51 anchura_paisaje-50 + 50 * sin(0*pi/180), 52 altura_paisaje-50 + 50 * cos(0*pi/180), ’blue’) . . .76 vieja_aguja = aguja77 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 78 anchura_paisaje-50 + 50 * sin(1000*vy*pi/180), 79 altura_paisaje-50 + 50 * cos(1000*vy*pi/180), ’blue’)80 erase(vieja_aguja) Y aqu´ tienes una imagen del aspecto actual de nuestro simulador: ıIntroducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 153 153 Introducción a la programación con Python - cUJI UJI
    • Ya estamos cerca del final. Nos queda determinar si el jugador gan´ o perdi´ la o opartida e informarle del resultado. Las ultimas l´ ´ ıneas del programa, que te mostramosahora completo, se encargan de ello: aterrizaje 26.py aterrizaje.py 1 from math import sin, cos, pi 2 # Paisaje 3 altura_paisaje = 400 4 anchura_paisaje = 400 5 window_coordinates(0, 0, anchura_paisaje, altura_paisaje) 6 7 # Gravedad 8 g = 0.00001 910 # Nave11 tamanyo_nave = 1012 x = anchura_paisaje / 213 y = altura_paisaje - 10014 vy = 015 impulso_y = 2*g16 impulso_x = 0.0000117 vx = 018 nave = create_filled_rectangle(x, y, x+tamanyo_nave, y+tamanyo_nave, ’blue’)1920 # Plataforma21 px = anchura_paisaje / 222 py = 023 vpx = .0524 anchura_plataforma = 4025 altura_plataforma = 32627 plataforma = create_rectangle(px, py,28 px+anchura_plataforma, py+altura_plataforma, ’red’)2930 # Tanque de combustible31 fuel = 100032 consumo = 0.133 create_rectangle(0,altura_paisaje, 10, altura_paisaje-100, ’black’)34 lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, ’green’)3536 create_text(25, altura_paisaje-8, ’0%’, 10, ’W’)37 create_text(30, altura_paisaje-95, ’100%’, 10, ’W’)Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 154 154 Introducción a la programación con Python - cUJI UJI
    • 38 # Dial de velocidad39 create_circle(anchura_paisaje-50, altura_paisaje-50, 50, ’black’)40 for i in range(0, 360, 10):41 create_line(anchura_paisaje-50 + 40 * sin(i*pi/180), 42 altura_paisaje-50 + 40 * cos(i*pi/180), 43 anchura_paisaje-50 + 50 * sin(i*pi/180), 44 altura_paisaje-50 + 50 * cos(i*pi/180))4546 if i % 30 == 0:47 create_text(anchura_paisaje-50 + 30 * sin(i*pi/180), 48 altura_paisaje-50 + 30 * cos(i*pi/180), str(i), 5, ’CENTER’)4950 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 51 anchura_paisaje-50 + 50 * sin(0*pi/180), 52 altura_paisaje-50 + 50 * cos(0*pi/180), ’blue’)5354 # Simulaci´n o55 while y > 0 and y < altura_paisaje and x > 0 and x < anchura_paisaje - tamanyo_nave:56 vy -= g57 if keypressed(1) == ’Up’ and fuel > 0:58 vy += impulso_y59 fuel -= consumo60 elif keypressed(1) == ’Left’ and fuel > 0:61 vx -= impulso_x62 fuel -= consumo63 elif keypressed(1) == ’Right’ and fuel > 0:64 vx += impulso_x65 fuel -= consumo66 y += vy67 x += vx68 px += vpx69 if px <= 0 or px >= anchura_paisaje - anchura_plataforma:70 vpx = -vpx71 move(nave, vx, vy)72 move(plataforma, vpx, 0)73 viejo_lleno = lleno74 lleno = create_filled_rectangle(1,altura_paisaje, 9, altura_paisaje-fuel/10, ’green’)75 erase(viejo_lleno)76 vieja_aguja = aguja77 aguja = create_line(anchura_paisaje-50, altura_paisaje-50, 78 anchura_paisaje-50 + 50 * sin(1000*vy*pi/180), 79 altura_paisaje-50 + 50 * cos(1000*vy*pi/180), ’blue’)80 erase(vieja_aguja)8182 msg_x = anchura_paisaje/283 msg_y1 = altura_paisaje/284 msg_y2 = altura_paisaje/385 if y >= altura_paisaje:86 create_text(msg_x, msg_y1, ’Perdiste’, 24, ’CENTER’) create_text(msg_x, msg_y2, ’ Rumbo␣a␣las␣estrellas?’, 12, ’CENTER’) ?8788 elif y <= 0 and vy < -0.1:89 create_text(msg_x, msg_y1, ’Perdiste’, 24, ’CENTER’)90 create_text(msg_x, msg_y2, ’Te␣has␣estrellado.’, 12, ’CENTER’)91 elif y <= 0 and 92 abs((px+anchura_plataforma/2)-(x+tamanyo_nave/2)) >= anchura_plataforma/2:93 create_text(msg_x, msg_y1, ’Perdiste’, 24, ’CENTER’)94 create_text(msg_x, msg_y2, ’ Qu´␣mala␣punter´a!’, 12, ’CENTER’) e !ı95 elif x <= 0 or x >= anchura_paisaje - tamanyo_nave:96 create_text(msg_x, msg_y1, ’Perdiste’, 24, ’CENTER’)Introducci´n a la programaci´n con - ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia Python o o 155 155 Introducción a la programación con Python -cUJI UJI
    • 97 create_text(msg_x, msg_y2, ’Chocaste␣con␣la␣pared.’, 12, ’CENTER’) 98 else: 99 create_text(msg_x, msg_y1, ’Ganaste’, 24, ’CENTER’)100 create_text(msg_x, msg_y2, ’ Enhorabuena,␣piloto!’, 12, ’CENTER’) ! A disfrutar del juego. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 145 Modifica el juego para que la barra que indica el combustible disponible seponga de color rojo cuando quede menos del 25%.· 146 Modifica el juego para que el usuario pueda escoger, con un men´, un nivel ude dificultad. Ofrece al menos tres niveles: f´cil, normal y dif´ Puedes modificar la a ıcil.dificultad del juego a voluntad alterando par´metros como el fuel disponible, el consumo, ala fuerza de la gravedad, la velocidad de desplazamiento de la plataforma, etc.· 147 Modifica el juego para que la plataforma no est´ en el suelo, sino flotando. eEl usuario debe aterrizar en la plataforma desde arriba, claro est´. Si se golpea a la aplataforma desde abajo, la nave se destruir´ y el jugador habr´ fracasado. a a· 148 A˜ade efectos especiales al juego. Por ejemplo, cambia el color del fondo para que nsea negro y a˜ade unas estrellas. Tambi´n puedes mostrar una l´ n e ıneas amarillas saliendode la nave cuando se activa alg´n propulsor. Si se acciona el propulsor inferior, la l´ u ıneassaldr´n de debajo de la nave, y si se activa un propulsor lateral, las l´ a ıneas saldr´n del alado correspondiente.· 149 Modifica el juego para que aparezca un n´mero determinado de meteoritos en upantalla (tres, por ejemplo). Cada meteorito se representar´ con un c´ a ırculo de color rojoy se ir´ desplazando por la pantalla. Si la nave toca un meteorito, ´sta se destruir´. a e a· 150 Programa un juego de front´n electr´nico. El usuario controlar´ una raqueta en o o ael lado inferior de la pantalla. Con la raqueta podr´ golpear una pelota que rebotar´ en a alas paredes. Si la pelota se sale por el borde inferior de la pantalla, el juego finaliza.· 151 Modifica el juego del front´n para convertirlo en un teletenis. El ordenador ocontrolar´ una raqueta en el lado superior de la imagen. No permitas que el ordenador ahaga trampas, es decir, la velocidad de desplazamiento de la raqueta ha de ser (comomucho) la misma que la del usuario. ..................................................................................4.5. Una reflexi´n final oEn este tema te hemos presentado varias estructuras de control de flujo que, esencial-mente, se reducen a dos conceptos: la selecci´n condicional de sentencias y la repetici´n o ocondicional de sentencias. En los primeros tiempos de la programaci´n no siempre se uti- olizaban estas estructuras: exist´ una sentencia comod´ que permit´ ˂˂saltar˃˃ a cualquier ıa ın ıapunto de un programa: la que se conoce como sentencia goto (en ingl´s, ˂˂ir-a˃˃). e Observa c´mo se podr´ haber escrito el programa es primo.py (secci´n 4.2.7) en o ıa oel lenguaje de programaci´n BASIC, que originariamente carec´ de estructuras como el o ıabucle while:Introducci´n a la programaci´n con ISBN: 978-84-692-5869-9 Andrés Marzal/Isabel Gracia - Python o o 156 156 Introducción a la programación con Python - UJIUJI c
    • 10 INPUT "DAME UN N´MERO:"; NUM U 20 DIVISOR = 2 30 IF INT(NUM / DIVISOR) = NUM / DIVISOR THEN GOTO 90 40 DIVISOR = DIVISOR + 1 50 IF DIVISOR = NUM THEN GOTO 70 60 GOTO 30 70 PRINT .El n´mero", NUM, .es primo" u 80 GOTO 100 90 PRINT .El n´mero", NUM, "no es primo" u 100 END Cada l´ınea del programa est´ numerada y la sentencia GOTO indica en qu´ l´ a e ınea debecontinuar la ejecuci´n del programa. Como es posible saltar a cualquier l´ o ınea en funci´node la satisfacci´n de una condici´n, es posible ˂˂montar a mano˃˃ cualquier estructura de o ocontrol. Ahora bien, una cosa es que sea posible y otra que el resultado presente un m´ ınimode elegancia. El programa BASIC del ejemplo es endiabladamente complejo: resulta dif´ ıcilapreciar que las l´ıneas 30–60 forman un bucle while. Los programas construidos abusandodel GOTO recib´ el nombre de ˂˂c´digo spaghetti˃˃, pues al representar con flechas los ıan oposibles saltos del programa se formaba una mara˜a que recuerda a un plato de spaghetti. n En los a˜os 70 hubo una corriente en el campo de la inform´tica que propugnaba la n asupresi´n de la sentencia goto. Edsger W. Dijkstra public´ un influyente art´ o o ıculo titulado˂˂Goto considered harmful˃˃ (˂˂La sentencia “Goto” considerada da˜ina˃˃) en el que se hac´ n ıauna severa cr´ıtica al uso de esta sentencia en los programas. Se demostr´ que era posible oconstruir cualquier programa con s´lo selecciones y repeticiones condicionales y que estos oprogramas resultaban mucho m´s legibles. La denominada programaci´n estructurada es a ola corriente que propugna (entre otros principios) la programaci´n usando unicamente o ´estructuras de control (if, while, for-in, . . . ) para alterar el flujo del programa. Al poco tiempo de su aparici´n, la programaci´n estructurada se convirti´ en la meto- o o odolog´ de programaci´n. (Los puristas de la programaci´n estructurada no s´lo censuran ıa o o oel uso de sentencias goto: tambi´n otras como break est´n proscritas.) e a Hay que decir, no obstante, que programar es una forma de describir ideas algor´ ıtmicassiguiendo unas reglas sint´cticas determinadas y que, en ocasiones, romper una regla per- amite una mejor expresi´n. Pero, ¡ojo!, s´lo estar´s capacitado para romper reglas cuando o o alas conozcas perfectamente. Por una cuesti´n de disciplina es preferible que, al principio, oprocures no utilizar en absoluto alteraciones del flujo de control arbitrarias. . . aunque detodos modos no podr´s hacerlo de momento: ¡Python no tiene sentencia goto! a 157 Introducción a la programación con Python - UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9Introducci´n a la programaci´n con Python o o 157 c UJI
    • Cap´ ıtulo 5Tipos estructurados: secuencias Primero llegaron diez soldados portando bastos: ten´ la misma forma que ıan los tres jardineros, plana y rectangular, con las manos y los pies en las esquinas; luego ven´ los diez cortesanos, todos adornados de diamantes, y ıan caminaban de dos en dos, como los soldados. Segu´ los Infantes: eran diez ıan en total y era encantador verlos venir cogidos de la mano, en parejas, dando alegres saltos: estaban adornados con corazones. LEWIS CARROLL, Alicia en el pa´ de las maravillas. ısHasta el momento hemos tratado con datos de tres tipos distintos: enteros, flotantes ycadenas. Los dos primeros son tipos de datos escalares. Las cadenas, por contra, son tiposde datos secuenciales. Un dato de tipo escalar es un elemento unico, at´mico. Por contra, ´ oun dato de tipo secuencial se compone de una sucesi´n de elementos y una cadena es ouna sucesi´n de caracteres. Los datos de tipo secuencial son datos estructurados. En oPython es posible manipular los datos secuenciales de diferentes modos, facilitando as´ ıla escritura de programas que manejan conjuntos o series de valores. En algunos puntos de la exposici´n nos desviaremos hacia cuestiones relativas al omodelo de memoria de Python. Aunque se trata de un material que debes comprender ydominar, no pierdas de vista que lo realmente importante es que aprendas a dise˜ar enimplementar algoritmos que trabajan con secuencias. En este tema empezaremos aprendiendo m´s de lo que ya sabemos sobre cadenas. aDespu´s, te presentaremos las listas. Una lista es una sucesi´n de elementos de cualquier e otipo. Finalmente, aprender´s a definir y manejar matrices: disposiciones bidimensionales ade elementos. Python no incorpora un tipo de datos nativo para matrices, as´ que las ıconstruiremos como listas de listas.5.1. Cadenas5.1.1. Lo que ya sabemosYa vimos en temas anteriores que una cadena es una sucesi´n de caracteres encerrada oentre comillas (simples o dobles). Python ofrece una serie de operadores y funcionespredefinidos que manipulan cadenas o devuelven cadenas como resultado. Repasemosbrevemente las que ya conocemos de temas anteriores: Operador + (concatenaci´n de cadenas): acepta dos cadenas como operandos y o devuelve la cadena que resulta de unir la segunda a la primera. Operador * (repetici´n de cadena): acepta una cadena y un entero y devuelve la o concatenaci´n de la cadena consigo misma tantas veces como indica el entero. o 158 Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 158 Introducción a la programación con Python - UJI
    • Operador % (sustituci´n de marcas de formato): acepta una cadena y una o m´s o a expresiones (entre par´ntesis y separadas por comas) y devuelve una cadena en e la que las marcas de formato (secuencias como %d, %f, etc.) se sustituyen por el resultado de evaluar las expresiones. int: recibe una cadena cuyo contenido es una secuencia de d´ ıgitos y devuelve el n´mero entero que describe. u float: acepta una cadena cuyo contenido describe un flotante y devuelve el flotante en cuesti´n. o str: se le pasa un entero o flotante y devuelve una cadena con una representaci´n o del valor como secuencia de caracteres. ord: acepta una cadena compuesta por un unico car´cter y devuelve su c´digo ASCII ´ a o (un entero). chr: recibe un entero (entre 0 y 255) y devuelve una cadena con el car´cter que a tiene a dicho entero como c´digo ASCII. o Podemos manipular cadenas, adem´s, mediante m´todos que les son propios: a e a.lower() (paso a min´sculas): devuelve una cadena con los caracteres de a con- u vertidos en min´sculas. u a.upper() (paso a may´sculas): devuelve una cadena con los caracteres de a u convertidos en may´sculas. u a.capwords() (paso a palabras con inicial may´scula): devuelve una cadena en la u que toda palabra de a empieza por may´scula. u Aprenderemos ahora a utilizar nuevas herramientas. Pero antes, estudiemos algunaspeculiaridades de la codificaci´n de los caracteres en las cadenas. o5.1.2. EscapesLas cadenas que hemos estudiado hasta el momento consist´ en sucesiones de carac- ıanteres ˂˂normales˃˃: letras, d´ ıgitos, signos de puntuaci´n, espacios en blanco. . . Es posible, ono obstante, incluir ciertos caracteres especiales que no tienen una representaci´n trivial. o Por ejemplo, los saltos de l´ ınea se muestran en pantalla como eso, saltos de l´ ınea,no como un car´cter convencional. Si intentamos incluir un salto de l´ a ınea en una cadenapulsando la tecla de retorno de carro, Python se queja: ↱>>> a = ’una File "<string>", line 1 ’una ˆSyntaxError: invalid token ¿Ves? Al pulsar la tecla de retorno de carro, el int´rprete de Python intenta ejecutar ela sentencia inmediatamente y considera que la cadena est´ inacabada, as´ que notifica a ıque ha detectado un error. Observa esta otra asignaci´n de una cadena a la variable a y mira qu´ ocurre cuando o emostramos el contenido de a: ↱>>> a = ’unancadena’ ↱>>> print aunacadenaIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 159 159 Introducción a la programación con Python - UJI c UJI
    • Al mostrar la cadena se ha producido un salto de l´ ınea detr´s de la palabra una. El asalto de l´ ınea se ha codificado en la cadena con dos caracteres: la barra invertida y laletra n. La barra invertida se denomina car´cter de escape y es un car´cter especial: indica a aque el siguiente car´cter tiene un significado diferente del usual. Si el car´cter que le a asigue es la letra n, por ejemplo, se interpreta como un salto de l´ ınea (la n viene delt´rmino ˂˂new line˃˃, es decir, ˂˂nueva l´ e ınea˃˃). Ese par de caracteres forma una secuenciade escape y denota un unico car´cter. ¿Y un salto de l´ ´ a ınea es un unico car´cter? S´ ´ a ı.Ocupa el mismo espacio en memoria que cualquier otro car´cter (un byte) y se codifica ainternamente con un valor num´rico (c´digo ASCII): el valor 10. e o ↱>>> ord(’n’)10 Cuando una impresora o un terminal de pantalla tratan de representar el car´cter de avalor ASCII 10, saltan de l´ ınea. El car´cter n es un car´cter de control, pues su funci´n a a oes permitirnos ejecutar una acci´n de control sobre ciertos dispositivos (como la impresora oo el terminal). Secuencia de escape para car´cter de control a Resultado a Car´cter de ˂˂campana˃˃ (BEL) a b ˂˂Espacio atr´s˃˃ (BS) a f Alimentaci´n de formulario (FF) o n Salto de l´ ınea (LF) r Retorno de carro (CR) t Tabulador horizontal (TAB) v Tabulador vertical (VT) ooo Car´cter cuyo c´digo ASCII en octal es ooo a o xhh Car´cter cuyo c´digo ASCII en hexadecimal es hh a o Tabla 5.1: Secuencias de escape para caracteres de control en cadenas Python. Hay muchos caracteres de control (ver tabla 5.1), pero no te preocupes: nosotros utili-zaremos fundamentalmente dos: n y t. Este ultimo representa el car´cter de tabulaci´n ´ a ohorizontal o, simplemente, tabulador. El tabulador puede resultar util para alinear en ´columnas datos mostrados por pantalla. Mira este ejemplo, en el que destacamos losespacios en blanco de la salida por pantalla para que puedas contarlos: ↱>>> print ’unotdosttres’uno␣␣␣␣␣dos␣␣␣␣␣tres ↱>>> print ’1t2t3’1␣␣␣␣␣␣␣2␣␣␣␣␣␣␣3 ↱>>> print ’1t12t13n21t2t33’1␣␣␣␣␣␣␣12␣␣␣␣␣␣1321␣␣␣␣␣␣2␣␣␣␣␣␣␣33 Es como si hubiera unas marcas de alineaci´n (los tabuladores) cada 8 columnas. o Alternativamente, puedes usar el c´digo ASCII (en octal o hexadecimal) de un car´cter o ade control para codificarlo en una cadena, como se muestra en las dos ultimas filas de la ´tabla 5.1. El salto de l´ ınea tiene valor ASCII 10, que en octal se codifica con 012 y enhexadecimal con x0a. Aqu´ te mostramos una cadena con tres saltos de l´ ı ınea codificadosde diferente forma:Introducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 160 160 Introducción a la programación con Python - UJI c UJI
    • ↱>>> print ’AnB012Cx0aD’ABCD Ciertos caracteres no se pueden representar directamente en una cadena. La barrainvertida es uno de ellos. Para expresarla, debes usar dos barras invertidas seguidas. ↱>>> print ’ab’ab En una cadena delimitada con comillas simples no puedes usar una comilla simple: siPython trata de analizar una cadena mal formada como ’Munich’72’, encuentra un error,pues cree que la cadena es ’Munich’ y no sabe c´mo interpretar los caracteres 72’. oUna comilla simple en una cadena delimitada con comillas simples ha de ir precedida dela barra invertida. Lo mismo ocurre con la comilla doble en una cadena delimitada concomillas dobles (v´ase la tabla 5.2): e ↱>>> print ’Munich’72’Munich’72 ↱>>> print "Una␣"cosa"␣rara."Una "cosa" rara. Otras secuencias de escape Resultado Car´cter barra invertida () a ’ Comilla simple (’) " Comilla doble (") y salto de l´ ınea Se ignora (para expresar una cadena en varias l´ ıneas). Tabla 5.2: Secuencias de escape para algunos caracteres especiales.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 152 ¿Qu´ se mostrar´ en pantalla al ejecutar estas sentencias? e a ↱>>> print ’n’ ↱>>> print ’157143164141154’ ↱>>> print ’ttunabo’ (Te recomendamos que resuelvas este ejercicio a mano y compruebes la validez detus respuestas con ayuda del ordenador.)· 153 ¿C´mo crees que se pueden representar dos barras invertidas seguidas en una ocadena?· 154 La secuencia de escape a emite un aviso sonoro (la ˂˂campana˃˃). ¿Qu´ hace eexactamente cuando se imprime en pantalla? Ejecuta print ’a’ y lo averiguar´s. a· 155 Averigua el c´digo ASCII de los 10 primeros caracteres de la tabla 5.1. o..................................................................................Introducci´n a la programaci´n con Python o o 161 161 c UJI Andrés Marzal/Isabel Gracia - ISBN: 978-84-692-5869-9 Introducción a la programación con Python - UJI
    • Unix, Microsoft y Apple: condenados a no entenderse Te hemos dicho que n codifica el car´cter de control ˂˂salto de l´ a ınea˃˃. Es cierto, pero no es toda la verdad. En los antiqu´ ısimos sistemas de teletipo (b´sicamente, m´quinas de a a escribir controladas por ordenador que se usaban antes de que existieran los monitores) se necesitaban dos caracteres para empezar a escribir al principio de la siguiente l´ ınea: un salto de l´ ınea (n) y un retorno de carro (r). Si s´lo se enviaba el car´cter n o a el ˂˂carro˃˃ saltaba a la siguiente l´ınea, s´ pero se quedaba en la misma columna. El ı, car´cter r hac´ que el carro retornase a la primera columna. a ıa Con objeto de ahorrar memoria, los dise˜adores de Unix decidieron que el final de n l´ ınea en un fichero deber´ marcarse unicamente con n. Al dise˜ar MS-DOS, Microsoft ıa ´ n opt´ por utilizar dos caracteres: nr. As´ pues, los ficheros de texto de Unix no son o ı directamente compatibles con los de Microsoft. Si llevas un fichero de texto de un sistema Microsoft a Unix ver´s que cada l´ a ınea acaba con un s´ ımbolo extra˜o (¡el retorno n de carro!), y si llevas el fichero de Unix a un sistema Microsoft, parecer´ que las l´ a ıneas est´n mal alineadas. a Para poner peor las cosas, nos falta hablar de la decisi´n que adopt´ Apple en los o o ordenadores Macintosh: usar s´lo el retorno de carro (r). ¡Tres sistemas operativos y o tres formas distintas de decir lo mismo! De todos modos, no te preocupes en exceso, editores de texto como XEmacs y PythonG son bastante ˂˂listos˃˃: suelen detectar estas situaciones y las corrigen au- tom´ticamente. a M´s sobre la codificaci´n de las cadenas a o Hemos visto que podemos codificar cadenas encerrando un texto entre comillas simples o entre comillas dobles. En tal caso, necesitamos usar secuencias de escape para acceder a ciertos caracteres. Python ofrece a´n m´s posibilidades para codificar cadenas. Una u a de ellas hace que no se interpreten las secuencias de escape, es decir, que todos sus caracteres se interpreten literalmente. Estas cadenas ˂˂directas˃˃ (en ingl´s, ˂˂raw strings˃˃) e preceden con la letra ˂˂r˃˃ a las comillas (simples o dobles) que la inician: ↱ >>> print r’un’ un ↱ >>> print r"un" un Cuando una cadena ocupa varias l´ ıneas, podemos usar la secuencia de escape n para marcar cada salto de l´ ınea. O podemos usar una ˂˂cadena multil´ ınea˃˃. Las cadenas multil´ ınea empiezan con tres comillas simples (o dobles) y finalizan con tres comillas simples (o dobles): ↱ >>> print ’’’Una ↱ ... cadena ↱ ... que ocupa ↱ ... varias l´neas’’’ ı Una cadena que ocupa varias l´neas ı5.1.3. Longitud de una cadenaLa primera nueva funci´n que estudiaremos es len (abreviatura del ingl´s ˂˂length˃˃, en o eespa˜ol, ˂˂longitud˃˃) que devuelve la longitud de una cadena, es decir, el n´mero de n uIntroducci´n Marzal/Isabel Gracia -Python 978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 162 162 Introducción a la programación con Python - c UJI UJI
    • caracteres que la forman. Se trata de una funci´n predefinida, as´ que podemos usarla o ıdirectamente: ↱>>> len(’abc’)3 ↱>>> len(’a’)1 ↱>>> len(’abcd’ * 4)16 ↱>>> len(’anb’)3 Hay una cadena que merece especial atenci´n, la cadena que denotamos abriendo y ocerrando inmediatamente las comillas simples, ’’, o dobles, "", sin ning´n car´cter entre u aellas. ¿Qu´ valor devuelve len(’’)? e ↱>>> len(’’)0 La cadena ’’ se denomina cadena vac´ y tiene longitud cero. No confundas la cadena ıavac´ ’’, con la cadena que contiene un espacio en blanco, ’␣’, pues, aunque parecidas, ıa,no son iguales. F´ıjate bien en que la segunda cadena contiene un car´cter (el espacio en ablanco) y, por tanto, es de longitud 1. Podemos comprobarlo f´cilmente: a ↱>>> len(’’)0 ↱>>> len(’␣’)15.1.4. Indexaci´n oPodemos acceder a cada uno de los caracteres de una cadena utilizando un operadorde indexaci´n. El ´ o ındice del elemento al que queremos acceder debe encerrarse entrecorchetes. Si a es una cadena, a[i] es el car´cter que ocupa la posici´n i+1. Debes a otener en cuenta que el primer elemento tiene ´ ındice cero. Los ´ ındices de la cadena’Hola,␣mundo.’ se muestran en esta figura: 0 1 2 3 4 5 6 7 8 9 10 11 H o l a , m u n d o . ↱>>> ’Hola,␣mundo.’[0]’H’ ↱>>> ’Hola,␣mundo.’[1]’o’ ↱>>> a = ’Hola,␣mundo.’ ↱>>> a[2]’l’ ↱>>> a[1]’o’ ↱>>> i=3 ↱>>> a[i]’a’ ↱>>> a[len(a)-1]’.’ Observa que el ultimo car´cter de la cadena almacenada en la variable a no es ´ aa[len(a)], sino a[len(a)-1]. ¿Por qu´? Evidentemente, si el primer car´cter tiene ´ e a ındiceIntroducci´nMarzal/Isabel Gracia - Python978-84-692-5869-9 Andrés a la programaci´n con ISBN: o o 163 163 Introducción a la programación con Python - UJI c UJI
    • 0 y hay len(a) caracteres, el ultimo ha de tener ´ ´ ındice len(a)-1. Si intentamos accederal elemento a[len(a)], Python protesta: ↱>>> a[len(a)]Traceback (innermost last): File "<stdin>", line 1, in ?IndexError: string index out of range El error cometido es del tipo IndexError (error de indexaci´n) y, en el texto explicativo oque lo detalla, Python nos informa de que el ´ ındice de la cadena est´ fuera del rango de avalores v´lidos. a Recuerda que las secuencias de escape codifican caracteres simples, aunque se expre-sen con dos caracteres. La cadena ’Hola,nmundo.’, por ejemplo, no ocupa 13 casillas,sino 12: 0 1 2 3 4 5 6 7 8 9 10 11 H o l a , n m u n d o . Tambi´n puedes utilizar ´ e ındices negativos con un significado especial: los valoresnegativos acceden a los caracteres de derecha a izquierda. El ultimo car´cter de una ´ acadena tiene ´ ındice −1, el pen´ltimo, −2, y as´ sucesivamente. Analiza este ejemplo: u ı ↱>>> a = ’Ejemplo’ ↱>>> a[-1]’o’ ↱>>> a[len(a)-1]’o’ ↱>>> a[-3]’p’ ↱>>> a[-len(a)]’E’ De este modo se simplifica notablemente el acceso a los caracteres del final de lacadena. Es como si dispusieras de un doble juego de ´ ındices: 0 1 2 3 4 5 6 7 8 9 10 11 H o l a , m u n d o . -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJERCICIOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .· 156 La ultima letra del DNI puede calcularse a partir de sus n´meros. Para ello ´ us´lo tienes que dividir el n´mero por 23 y quedarte con el resto. El resto es un n´mero o u uentre 0 y 22. La letra que corresponde a cada n´mero la tienes en esta tabla: u 0 1 2 3 4 5