1. Alfonso de la Guarda Reyes
  2. python-para-todos-reloaded

Commits

Alfonso de la Guarda Reyes  committed 9b4a426

Draft Cap. 4 y Revisiones

  • Participants
  • Parent commits e01e901
  • Branches default

Comments (0)

Files changed (3)

File 2.rst

View file
 lo que ingrese el usuario a la variable *n*. Ingresa, entonces, el 
 número que gustes, digamos *23* y luego:
 
-    >>> print 2011 - int(n)
+    >>> print(2011 - int(n))
 
 El resultado que nos aparecerá es *1988*, pero para llegar a esto 
 tuvimos que "tipar" la variable *n* puesto que la función 
 **raw_input** nos permite ingresar *cadenas* y para efectuar la 
 resta necesitamos que el valor ingresado sea un *entero* (**int**).
 
+Y ahora revisemos este ejemplo::
+
+    >>> n = raw_input("Cual es tu nombre?")
+    >>> print("Bienvenido!", n)
+
+De esta manera podemos concatenar uno o más valores dentro de un 
+**print**, sólo agreguen comas y el valor que deseen.
+
 A esto me refiero con unir las piezas! Podemos ir integrando cada 
 concepto que aprendamos en nuestros programas y hacerlos más 
 ambiciosos y complejos.

File 3.rst

View file
 extensivo de este recurso.  Lo cierto es que su enfoque *funcional* 
 prácticamente nos obliga a aprovecharnos de estas (*colecciones*).
 
+Para acceder a los valores internos de las **colecciones** haremos 
+uso del el operador **[]**. Ahora, tanto las *tuplas* como las 
+*listas* forman parte de un tipo de objetos llamados 
+**secuencias**.  Esto debido, precisamente, a que los valores 
+contenidos son una secuencia de datos.
+
 
 Listas
 ~~~~~~
 tuplas, a excepción de la forma de definirla, para lo que se 
 utilizan paréntesis en lugar de corchetes::
 
-    >>> t = (1, 2, True, python)
+    >>> t = (1, 2, True, "python")
 
 En realidad el constructor de la tupla es la coma, no el paréntesis, 
 pero el intérprete muestra los paréntesis, y nosotros deberíamos 
 
     >>> t = 1, 2, 3
     >>> type(t)
-    type tuple
+    type "tuple"
 
 Además hay que tener en cuenta que es necesario añadir una coma para 
 tuplas de un solo elemento, para diferenciarlo de un elemento entre 
 
     >>> t = (1)
     >>> type(t)
-    type int
+    type "int"
     >>> t = (1,)
     >>> type(t)
-    type tuple
+    type "tuple"
 
-Para referirnos a elementos de una tupla, como en una lista, se usa el
-operador **[]**::
+Para referirnos a elementos de una tupla, como en una lista, 
+empleamos el operador **[]** de esta manera::
 
     >>> mi_var = t[0] # mi_var es 1
     >>> mi_var = t[0:2] # mi_var es (1, 2)
 
-Podemos utilizar el operador **[]** debido a que las *tuplas*, al igual que
-las *listas*, forman parte de un tipo de objetos llamados secuencias.
-Es preciso aclarar que las cadenas de texto también son secuencias, 
-por lo que no les debe extraña que podamos hacer cosas como estas::
-
-    >>> c = “hola mundo”
-    >>> c[0]   # h
-    >>> c[5:] # mundo
-    >>> c[::3] # hauo
-
-Muy bien, hasta ahora lo mismo que hemos visto en las **listas** se 
-aplica a las **tuplas**, entonces: cuál es la diferencia entre 
-ambas? Bueno, vamos a colocar las más importantes:
+Muy bien, hasta ahora lo mismo que hemos visto en 
+las **listas** se aplica a las **tuplas**, entonces: cuál es la 
+diferencia entre ambas? Bueno, vamos a colocar las más importantes:
 
     **Inmutables**
         No pueden modificarse una vez creadas.
     **Consumo de memoria**
         Las tuplas consumen menos memoria que las listas.
 
-Adicionalmente las tuplas no poseen mecanismos de modificación a 
+Adicionalmente, las tuplas no poseen mecanismos de modificación a 
 través de funciones tan útiles como las que poseen las listas.
 
 
 Diccionarios
 ~~~~~~~~~~~~
 
-Los diccionarios, también llamados matrices asociativas, deben su
-nombre a que son colecciones que relacionan una clave y un valor. Por
-ejemplo, veamos un diccionario de películas y directores:
+Los diccionarios, también llamados matrices asociativas deben su 
+nombre a que son colecciones que relacionan una clave y un valor. 
+Por ejemplo, veamos un diccionario de películas y directores::
 
-d = {“Love Actually “: “Richard Curtis”, Kill Bill: Tarantino, Amélie: Jean-Pierre Jeunet}
+    >>> d = {"Star Trek": "J.J. Abrams", "Kill Bill": "Tarantino", "Amélie": "Jean-Pierre Jeunet"}
 
+El primer valor se trata de la *clave* y el segundo del *valor* 
+asociado a la clave.  Como *clave* podemos utilizar cualquier valor 
+inmutable: podríamos usar números, cadenas, booleanos, tuplas, pero 
+no listas o diccionarios, dado que son mutables. Esto es así porque 
+los diccionarios se implementan como tablas *hash* y a la hora de 
+introducir un nuevo par **clave-valor** en el diccionario se calcula 
+el *hash* de la *clave* para después poder encontrar la entrada 
+correspondiente rápidamente. Si se modificara el objeto clave 
+después de haber sido introducido en el diccionario, evidentemente, 
+su hash también cambiaría y no podría ser encontrado.
 
-El primer valor se trata de la clave y el segundo del valor asociado
-a la clave. Como clave podemos utilizar cualquier valor inmutable:
-podríamos usar números, cadenas, booleanos, tuplas, … pero no listas
-o diccionarios, dado que son mutables. Esto es así porque los diccio-
-narios se implementan como tablas hash, y a la hora de introducir un
-nuevo par clave-valor en el diccionario se calcula el hash de la clave
-para después poder encontrar la entrada correspondiente rápidamente.
-Si se modificara el objeto clave después de haber sido introducido en el
-diccionario, evidentemente, su hash también cambiaría y no podría ser
-encontrado.
+La diferencia principal entre los diccionarios y las listas o las 
+tuplas es que a los valores almacenados en un diccionario se les 
+accede no por su índice, porque de hecho no tienen orden, sino por 
+su clave, utilizando de nuevo el operador **[]**::
 
-La diferencia principal entre los diccionarios y las listas o las tuplas es
-que a los valores almacenados en un diccionario se les accede no por su
-índice, porque de hecho no tienen orden, sino por su clave, utilizando
-de nuevo el operador [].
+    >>> d["Love Actually"] # devuelve "Richard Curtis"
 
-d[“Love Actually “] # devuelve “Richard Curtis”
+Al igual que en listas y tuplas también se puede utilizar este 
+operador para reasignar valores::
 
+    >>> d["Kill Bill"] = "Quentin Tarantino"
 
-Al igual que en listas y tuplas también se puede utilizar este operador
-para reasignar valores.
+Sin embargo en este caso no se puede utilizar *slicing*, entre otras 
+cosas porque los diccionarios no son secuencias, si no *mappings* 
+(mapeados, asociaciones).
 
-d[“Kill Bill”] = “Quentin Tarantino”
+Bueno, y cómo agregamos una nueva llave (y su correspondiente 
+valor)?::
 
+    >>> d["Inception"] = "Cristopher Nolan"
 
-Sin embargo en este caso no se puede utilizar slicing, entre otras cosas
-porque los diccionarios no son secuencias, si no mappings (mapeados,
-asociaciones).
+Si imprimes el diccionario, notarás que ahora tenemos cuatro llaves, 
+verdad?
 
+
+Anotaciones sobre **cadenas**
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Se acuerdan de que establecimos que tanto las *listas* como las 
+*tuplas* son *secuencias*? Bueno pues, también tenemos que saber que 
+las *cadenas* son *secuencias* y, por ende, podemos acceder a sus 
+valores a través de nuestro famoso operador **[]**::
+
+    >>> c = "hola mundo"
+    >>> c[0]   # h
+    >>> c[5:]  # mundo
+    >>> c[::3] # hauo
+
+Simpático, verdad? Ahora conocemos algo más del lenguaje que nos 
+permitirá hacer grandes cosas en el futuro inmediato.
+
+
+Complementos útiles
+~~~~~~~~~~~~~~~~~~~
+
+También podemos cambiar el **tipo** de las colecciones y para 
+lograrlo también tenemos unas *funciones* (insisto: un poco más 
+adelante sabremos un poco más sobre este concepto) que nos permiten 
+lograrlo:
+
+    **list**
+        Convierte una secuencia a una lista.  Su sintáxis es **list(SECUENCIA)** donde *SECUENCIA* se debe reemplazar por lo correspondiente.
+    **tuple**
+        Convierte una secuencia a una tupla.  Su sintáxis es **tuple(SECUENCIA)** donde *SECUENCIA* se debe reemplazar por lo correspondiente.
+    **dict**
+        Convierte una secuencia en un diccionario.  Para poder hacer uso de esto debemos considerar que nuestra *secuencia* debe estar agrupada en pares, así se pueda tomar el primer dato como *llave* y el segundo como *valor*.  Su sintáxis es **dict(SECUENCIA)** donde *SECUENCIA* puede ser: *[["uno",1],["dos",2]]*.
+
+Aún hay más: si deseamos crear una *lista* de números sin tener que 
+escribirlos uno a uno, podemos hacer uso de la función **range** y 
+cuya sintáxis es muy básica **range(inicio:fin:paso)** como ya lo 
+vimos líneas arriba, verdad?::
+
+    >>> range(0,10,2) #Nos devolverá 0,2,4,6,8,10
+
+Y qué pasa si lo que deseamos son secuencias únicas donde no hayan 
+repetidos? Entonces hacemos uso de la función **set**, que -para 
+variar- su sintáxis también es simple y podemos emplearlo así::
+
+    >>> a = "Python es hermoso"
+    >>> set(a) # Nos regresa set([' ', 'e', 'h', 'm', 'o', 'n', 'P', 's', 'r', 't', 'y'])
+    >>> b = [6,4,8,2,6,1,2]
+    >>> set(b) # Nos regresa set([8, 1, 2, 4, 6])
+
+Si deseamos contar la cantidad de elementos en una *colección* o un 
+*cadena*, podemos hacer uso la función **len**, de esta manera::
+
+    >>> len(a) #Nos debe regresar 17 (caracteres)
+    >>> len(b) #Nos debe regresar 7 (elementos)
+
+
+Ejercicios
+~~~~~~~~~~
+
+    # Desarrolla un programa donde indiques la cantidad de caracteres de un nombre ingresado por el usuario.
+    
+    # Construye otro programa donde muestres un rango de números creado a partir de los números iniciales y finales proporcionados por el usuario.
+    
+    # Agrega errores intencionales a tus programas, revisa los resultados y *entiende* estos.

File 4.rst

View file
 Control de flujo
 ----------------
 
- En esta lección vamos a ver los condicionales y los bucles.
+
+Consideraciones
+~~~~~~~~~~~~~~~
+
+Llegó el momento de dominar el arte de la programación y es por ello 
+que ahora nos enfrentamos al *control de flujo*, ese término nos 
+permite deducir a qué nos enfrentamos: la manera de poder 
+*controlar* la lógica de nuestro programa, agregar nuestras ideas, 
+algoritmos y poder articular lo que deseamos.
+
+Los comandos, funciones, operaciones de *control de flujo* nos 
+permiten administrar la lógica mediante condicionales (si / no) o 
+bucles (repeticiones, iteraciones), tal como sucede en el mundo 
+real.  La programación lo que busca es recrear los objetos del mundo 
+real en un universo organizado, definido, de tal manera que se 
+puedan construir proposiciones y aprovechar la velocidad de 
+procesamiento que nos ofrecen las computadoras.  Si tenemos en claro 
+esto podemos conquistar el mundo.
+
+Una vez que hayas terminado con este capítulo tendrás el 
+*conocimiento* para poder crear un programa, aunque en Python las 
+opciones que nos ofrece el *control de flujo* son limitadas en 
+número (lo que lo hace más simple de cara al usuario) nos ofrecen lo 
+necesario para hacer cualquier cosa.   Antes no lo he mencionado, 
+pero la filosofía de Python es **"No te fijes en la sintáxis sino en 
+la solución del problema"**, así que todo debe ser simple de 
+procesar de cara al usuario.  Hasta este capítulo, hace unos 20 
+años, los programadores de Basic podían hacer bastante, así que 
+imagina que lo que vamos a dominar te pone en esa misma situación.
+
+Python es un lenguaje "hermoso" estéticamente porque hace uso 
+obligado del *indentado*, que consiste en un espaciado previo al 
+código dependiente de otro, este es el caso del *control de flujo* y 
+otros recursos, que nos obligan a poner las consecuencias o efectos 
+luego de las condiciones.  El *indentando* deben ser cuatro espacios 
+(disculpen, olvídense de los tabulados!) bajo la proposición, cuando 
+lo dejamos de emplear entonces nos mantenemos en la estructura 
+lógica precedente.  Pero lo mejor, es comenzar con la explicación de 
+todo y así poder entenderlo.
+
+Momento! Algo más: en los capítulos previos empleamos 
+*identificadores* como a, b o cosas sin sentido... por favor! para 
+hacer legible el código emplea *identificadores* que sean 
+comprensibles de por sí, es lo más sano para cualquier programador y 
+nos ayudará a nosotros mismos a entender lo que estamos haciendo (un 
+primer nivel de documentación).
 
 
 Sentencias condicionales
- Si un programa no fuera más que una lista de órdenes a ejecutar de
- forma secuencial, una por una, no tendría mucha utilidad. Los con-
- dicionales nos permiten comprobar condiciones y hacer que nuestro
- programa se comporte de una forma u otra, que ejecute un fragmento
- de código u otro, dependiendo de esta condición.
 
- Aquí es donde cobran su importancia el tipo booleano y los operadores
- lógicos y relacionales que aprendimos en el capítulo sobre los tipos
- básicos de Python.
+~~~~~~~~~~~~~~~~~~~~~~~~
 
- if
- La forma más simple de un estamento condicional es un if (del inglés
- si) seguido de la condición a evaluar, dos puntos (:) y en la siguiente
- línea e indentado, el código a ejecutar en caso de que se cumpla dicha
- condición.
+Los condicionales nos permiten comprobar condiciones y hacer que 
+nuestro programa se comporte de una forma u otra, que ejecute un 
+fragmento de código u otro, dependiendo de esta condición.
 
-      fav = “mundogeek.net”
-      # si (if) fav es igual a “mundogeek.net”
-      if fav == “mundogeek.net”:
-          print “Tienes buen gusto!”
-          print “Gracias”
+Aquí es donde cobran su importancia el tipo booleano y los 
+operadores lógicos y relacionales que aprendimos en el capítulo 
+sobre los tipos básicos de Python.
 
 
- Como veis es bastante sencillo.
+if
+**
 
- Eso si, aseguraros de que indentáis el código tal cual se ha hecho en el
- ejemplo, es decir, aseguraros de pulsar Tabulación antes de las dos ór-
- denes print, dado que esta es la forma de Python de saber que vuestra
- intención es la de que los dos print se ejecuten sólo en el caso de que
-                                                                       29
+La forma más simple de una proposición condicional es un **if** (del 
+inglés *si*) seguido de la condición a evaluar, dos puntos (:) y en 
+la siguiente línea e indentado, el código a ejecutar en caso de que 
+se cumpla dicha condición::
 
-                                                       Python para todos
+    opcion = "Python"
+    # SI (if) opcion ES IGUAL A (==) "Python" ENTONCES (:)
+    if opcion == "Python":
+        print "Tienes buen gusto!"
+        print "Gracias"
+    print "Continuamos..."
 
+Sobre este ejemplo, presta atención a la línea del comentario, es 
+como yo le digo a mis alumnos que deben leer una expresión 
+condicional, pensarlo en nuestro idioma nativo y luego reemplazarlo 
+por lo que corresponde computacionalmente.
 
-se cumpla la condición, y no la de que se imprima la primera cadena si
-se cumple la condición y la otra siempre, cosa que se expresaría así:
+Una vez evaluada la *expresión* condicional (del ejemplo), el 
+programa tiene dos opciones: *Si es igual a* Python *entonces* 
+imprime 2 líneas con mensajes decorativos, *de lo contrario* 
+continúa con su ejecución a la altura del mismo *bloque* que la 
+expresión *if*.  Es así que vamos creando una estructura lógica en 
+un programa, agregando condiciones y sus respectivas acciones con la 
+sangría respectiva.
 
-   if fav == “mundogeek.net”:
-       print “Tienes buen gusto!”
-   print “Gracias”
+Y cómo podemos comenzar a integrar todo lo que hemos visto? Fácil!, 
+ya les dije que tenemos que unir las piezas y ahora pongamos un 
+pequenísimo ejemplo debidamente articulado::
 
+    nombre = raw_input("Cuál es tu nombre?")
+    if nombre == "Alfonso":
+        print "(En Vulcano)"
+        print "Dif Tor Heh Smusma!"
+    edad = raw_input("Cuál es tu edad?")
+    calculo = 2011 - int(edad)
+    if calculo > 18:
+        print "Me alegra saber que eres mayor de edad!"
 
-En otros lenguajes de programación los bloques de código se determi-
-nan encerrándolos entre llaves, y el indentarlos no se trata más que de
-una buena práctica para que sea más sencillo seguir el flujo del progra-
-ma con un solo golpe de vista. Por ejemplo, el código anterior expresa-
-do en Java sería algo así:
+Este ejemplo nos muestra claramente como trabajar con bloques 
+lógicos y el uso del indentado dentro de nuestro programa.  Presten 
+atención a la línea que comienza con la variable *edad*, es el fin 
+de la condicional expresada para *nombre* y se ubica a la misma 
+*altura* que dicha expresión (condicional).
 
-   String fav = “mundogeek.net”;
-   if (fav.equals(“mundogeek.net”)){
-       System.out.println(“Tienes buen gusto!”);
-       System.out.println(“Gracias”);
+Una aclaración: en otros lenguajes de programación los bloques de 
+código se determinan encerrándolos entre llaves y el indentarlos no 
+se trata más que de una buena práctica para que sea más sencillo 
+seguir el flujo del programa con un solo golpe de vista. Por 
+ejemplo, el código anterior expresado en *Java* sería algo así:
+
+   String opcion = "Python";
+   if (opcion.equals("Python")){
+       System.out.println("Tienes buen gusto!");
+       System.out.println("Gracias");
    }
 
 
-Sin embargo, como ya hemos comentado, en Python se trata de una
-obligación, y no de una elección. De esta forma se obliga a los progra-
-madores a indentar su código para que sea más sencillo de leer :)
+if … else
+*********
 
-if … else
-Vamos a ver ahora un condicional algo más complicado. ¿Qué haría-
-mos si quisiéramos que se ejecutaran unas ciertas órdenes en el caso de
-que la condición no se cumpliera? Sin duda podríamos añadir otro if
-que tuviera como condición la negación del primero:
+Líneas más arriba hice referencia al concepto *de lo contrario* y de 
+hecho podemos hacer uso de esto a través de un recurso del lenguaje 
+con *else*.  Aunque el contexto es más amplio en este caso, debido a 
+que con este recurso podemos hacer que una expresión haga algo 
+diferente cuando no se cumpla la condición.  Esto se puede lograr 
+claramente con una expresión condicional opuesta a la primera, sin 
+embargo, esto es poco elegante o funcional::
 
-   if fav == “mundogeek.net”:
-       print “Tienes buen gusto!”
-       print “Gracias”
+    if opcion == "Python":
+        print "Tienes buen gusto!"
+        print "Gracias"
+    if opcion != "Python":
+        print "Vaya, lamentamos que no nos prefieras"
 
-   if fav != “mundogeek.net”:
-       print “Vaya, que lástima”
+Así que el mismo efecto lo podemos lograr con el mencionado recurso 
+*else*::
 
+    if opcion == "Python": #SI opcion ES IGUAL A Python ENTONCES
+        print "Tienes buen gusto!"
+        print "Gracias"
+    else: # DE LO CONTRARIO
+        print "Vaya, lamentamos que no nos prefieras"
+    print "El programa continua aquí sea igual o no"
 
-pero el condicional tiene una segunda construcción mucho más útil:
+Está claro como podemos hacer uso de esto? O es A o es B, no hay más 
+opciones y luego podemos seguir con el programa.  Por otro lado, el 
+uso de *else* nos permite darle mayor legibilidad al código y 
+hace más simple expresar la condición alternativa.
 
-   if fav ==   “mundogeek.net”:
-       print   “Tienes buen gusto!”
-       print   “Gracias”
-   else:
-       print   “Vaya, que lástima”
-
-
-                                                                      30
-
-                                                          Control de flujo
-
-
-
-Vemos que la segunda condición se puede sustituir con un else (del
-inglés: si no, en caso contrario). Si leemos el código vemos que tiene
-bastante sentido: “si fav es igual a mundogeek.net, imprime esto y esto,
-si no, imprime esto otro”.
 
 if … elif … elif … else
-Todavía queda una construcción más que ver, que es la que hace uso
-del elif.
+***********************
 
-   if numero < 0:
-       print “Negativo”
-   elif numero > 0:
-       print “Positivo”
-   else:
-       print “Cero”
+Muy bien, y qué pasa cuándo hay múltiples opciones? Es decir, cuando 
+de una variable, colección u objeto (más adelante veremos que es 
+eso) hay diversas posibilidades y debemos actuar de diversa forma 
+por cada una de estas.  Entonces es que hacemos uso de **elif**::
 
+    numero = int(raw_input("Cuál es el número?"))
+    if numero < 0:
+        print "Negativo"
+    elif numero > 0:
+        print "Positivo"
+    else:
+        print "Cero"
 
-elif  es una contracción de else if, por lo tanto elif numero > 0 puede
-leerse como “si no, si numero es mayor que 0”. Es decir, primero se
-evalúa la condición del if. Si es cierta, se ejecuta su código y se con-
-tinúa ejecutando el código posterior al condicional; si no se cumple,
-se evalúa la condición del elif. Si se cumple la condición del elif
-se ejecuta su código y se continua ejecutando el código posterior al
-condicional; si no se cumple y hay más de un elif se continúa con el
-siguiente en orden de aparición. Si no se cumple la condición del if ni
-de ninguno de los elif, se ejecuta el código del else.
+Como podemos deducir, **elif**  es una contracción de *else if*, por 
+lo tanto **elif numero > 0** puede leerse como "si no, si numero es 
+mayor que 0".  Es decir, primero se evalúa la condición del *if*, si 
+es cierta, se ejecuta su código y se continúa ejecutando el código 
+posterior al condicional; si no se cumple, se evalúa la condición 
+del **elif**. Si se cumple la condición del **elif** se ejecuta su 
+código y se continua ejecutando el código posterior al condicional; 
+si no se cumple y hay más de un elif se continúa con el siguiente en 
+orden de aparición. Si no se cumple la condición del *if* ni de 
+ninguno de los **elif**, se ejecuta el código del *else*.
 
-A if C else B
 
-También existe una construcción similar al operador ? de otros lengua-
-jes, que no es más que una forma compacta de expresar un if else. En
-esta construcción se evalúa el predicado C y se devuelve A si se cumple
-o B si no se cumple: A if C else B. Veamos un ejemplo:
+Expresión condicional
+*********************
 
-   var = “par” if (num % 2 == 0) else “impar”
+A partir de la versión 2.5 del lenguaje se han implementado las 
+expresiones condicionales, que son el equivalente a los *operadores 
+ternarios* de otros lenguajes.  El concepto es bastante simple en 
+realidad: compactar la forma de expresar una secuencia *if else*, 
+así tenemos que siguiendo la sintáxis **A if EXPRESION else B** , 
+podemos deducir que si la expresión es cierta se nos devuelve A, de 
+lo contrario B, pero apliquémoslo a un ejemplo concreto::
 
+    numero = int(raw_input("Numero?"))
+    tipo = "par" if (numero % 2 == 0) else "impar"
+    print("El número es ", tipo)
 
-Y eso es todo. Si conocéis otros lenguajes de programación puede que
-esperarais que os hablara ahora del switch, pero en Python no existe
-esta construcción, que podría emularse con un simple diccionario, así
-que pasemos directamente a los bucles.
-                                                                       31
 
-                                                        Python para todos
+Condicionales al estilo Python
+******************************
 
+Ya hemos visto las condicionales Python y sabemos que son comunes en 
+los diversos lenguajes de programación, pero hay algunas *formas* 
+propias del lenguaje que nos ayudarán a sacarle provecho.
 
+Lo primero es el uso del **if** en sí, veamos este extracto de un 
+programa::
+
+    respuesta = "si"
+    if respuesta:
+        print("Respondiste que ", respuesta)
+
+Si se fijan en el **if** podrán notar que no existe una expresión 
+tradicional, de hecho lo que se evalua es su valor *lógico* en sí, 
+es decir: **True** (Verdad) y/o **False** (Falso), en este caso 
+*respuesta* es *VERDAD* porque contiene un valor (no importa el que 
+sea).  Prueben cambiando el valor de *respuesta* por cualquier 
+cadena o número y lo podrán comprobar.
+
+En el siguiente caso, consideramos la excepción a la regla dada 
+líneas arriba::
+
+    estado = False
+    if estado:
+        print("Qué pasa?")
+
+Aquí pueden ver que se forma una condicional, pero si lo prueban 
+notarán que no se imprime ningún mensaje.  Lo que sucede es que 
+*estado* es *FALSO* y cuando evaluamos como expresión obviamente el 
+resultado no es *VERDAD* y no se ejecuta el bloque que contiene el 
+*print*.
+
+Siguiendo con el ejemplo inmediato superior haremos una variación::
+
+    if not estado:
+        print("Sorpresa!")
+        
+Y voilá! Si lo probamos podremos ver que sí se imprime un mensaje.  
+Aquí hacemos uso de recursos combinados y en este caso **not** niega 
+el estado *FALSO* y lo convierte en *VERDAD*.
+
+La gran pregunta del millón: por qué hacer esto? Es que es lógico! 
+Nos acorta redundancias y, más adelante, cuando nos adentremos en el 
+lenguaje lo veremos como un recurso *práctico* y *estético*.
+
+No podemos acabar este título sin hacer mención del recurso **in** 
+(en castellano *en*), con el mismo podemos *analizar* si *algo* está 
+contenido *en* otro *algo*.  De esta manera, podemos tener 
+escenarios como el siguiente::
+
+    menu = "manzana", "pera", "durazno", "piña", "papaya"
+    opcion = raw_input("Qué fruta desea?")
+    if opcion in menu:
+        print("Seguro señor! Ya viene su pedido de ", opcion)
+    else:
+        print("Lo siento, no tenemos eso en el Menu, otra fruta?")
+
+Hermoso! Es algo tan lógico y simple de entender que provoca 
+emplearlo, imagínense hacer esto mismo con **if**, **elif** y 
+**else**, bastantes líneas verdad? Es que este es un recurso 
+*pythonico*.
 
 
 Bucles
- Mientras que los condicionales nos permiten ejecutar distintos frag-
- mentos de código dependiendo de ciertas condiciones, los bucles nos
- permiten ejecutar un mismo fragmento de código un cierto número de
- veces, mientras se cumpla una determinada condición.
+~~~~~~
 
- while
- El bucle while (mientras) ejecuta un fragmento de código mientras se
- cumpla una condición.
+Mientras que los condicionales nos permiten ejecutar distintos 
+fragmentos de código dependiendo de ciertas condiciones, los bucles 
+nos permiten ejecutar un mismo fragmento de código un cierto número 
+de veces, mientras se cumpla una determinada condición.
+
+while
+*****
+
+El bucle **while** (mientras) ejecuta un fragmento de código 
+mientras se cumpla una condición.  Este comportamiento es habitual 
+en el mundo real donde las personas *esperan* hasta que suceda algo 
+y su sintáxis, en lenguaje natural, sería: *MIENTRAS* CONDICION 
+*ENTONCES*, lo que llevado a un ejemplo podría ser::
+
+    edad = 0
+    while edad < 18:
+        edad += 1 # equivalencia: edad = edad + 1
+        print("Felicidades! tienes ", edad)
+    print("Seguimos con el programa...")
+
+La variable edad comienza valiendo 0, como la condición de que edad 
+es menor que 18 es cierta (0 es menor que 18), se entra en el 
+bucle.  Se aumenta edad en 1 y se imprime el mensaje informando de 
+que el usuario ha cumplido un año.  Ahora se vuelve a evaluar la 
+condición y 1 sigue siendo menor que 18, por lo que se vuelve a 
+ejecutar el código que aumenta la edad en un año e imprime la edad 
+en la pantalla. El bucle continuará ejecutándose hasta que edad sea 
+igual a 18, momento en el cual la condición dejará de cumplirse y el 
+programa continuaría ejecutando las instrucciones siguientes al 
+bucle.
+
+Ahora imaginemos que se nos olvidara escribir la instrucción que 
+aumenta la edad. En ese caso nunca se llegaría a la condición de que 
+edad fuese igual o mayor que 18, siempre sería 0, y el bucle 
+continuaría indefinidamente escribiendo en pantalla *"Felicidades! 
+tienes 0"*.  A este escenario se le denomina *bucle infinito* y 
+puede ser peligroso, sin embargo hay situaciones en las que es 
+útil.  Por ejemplo, veamos un pequeño programa que repite todo lo 
+que el usuario diga hasta que escriba *adios*::
+
+    while True:
+        entrada = raw_input("> ")
+        if entrada == "adios":
+            break
+        else:
+            print entrada
+
+Comprobamos entonces si lo que escribió el usuario fue *adios*, en 
+cuyo caso se ejecuta el comando **break** o si era cualquier otra 
+cosa se imprime en pantalla lo que el usuario escribió.  La palabra 
+clave **break** (romper) sale del bucle en el que estamos.
+
+Este bucle se podría haber escrito también, no obstante, de la 
+siguiente forma::
+
+    salir = False
+    while not salir:
+        entrada = raw_input()
+        if entrada == "adios":
+            salir = True
+        else:
+            print entrada
+
+Para este ejemplo, otra vez, integramos recursos de los temas 
+anteriores y nos valemos de los valores lógicos para salir del 
+bucle, lo cual nos sirve para entender el funcionamiento del *break* 
+en el ejemplo anterior.
+
+Otro comando que nos podemos encontrar dentro de los bucles es 
+**continue** (continuar) y como pueden adivinar no hace otra cosa 
+que pasar directamente a la siguiente iteración del bucle.
 
     edad = 0
     while edad < 18:
         edad = edad + 1
-        print “Felicidades, tienes “ + str(edad)
-
-
- La variable edad comienza valiendo 0. Como la condición de que edad
- es menor que 18 es cierta (0 es menor que 18), se entra en el bucle.
- Se aumenta edad en 1 y se imprime el mensaje informando de que
- el usuario ha cumplido un año. Recordad que el operador + para las
- cadenas funciona concatenando ambas cadenas. Es necesario utilizar
- la función str (de string, cadena) para crear una cadena a partir del
- número, dado que no podemos concatenar números y cadenas, pero ya
- comentaremos esto y mucho más en próximos capítulos.
-
- Ahora se vuelve a evaluar la condición, y 1 sigue siendo menor que 18,
- por lo que se vuelve a ejecutar el código que aumenta la edad en un
- año e imprime la edad en la pantalla. El bucle continuará ejecutándose
- hasta que edad sea igual a 18, momento en el cual la condición dejará
- de cumplirse y el programa continuaría ejecutando las instrucciones
- siguientes al bucle.
-
- Ahora imaginemos que se nos olvidara escribir la instrucción que
- aumenta la edad. En ese caso nunca se llegaría a la condición de que
- edad fuese igual o mayor que 18, siempre sería 0, y el bucle continuaría
- indefinidamente escribiendo en pantalla Has cumplido 0.
-
- Esto es lo que se conoce como un bucle infinito.
-
-                                                                       32
-
-                                                           Control de flujo
-
-
-
-Sin embargo hay situaciones en las que un bucle infinito es útil. Por
-ejemplo, veamos un pequeño programa que repite todo lo que el usua-
-rio diga hasta que escriba adios.
-
-   while True:
-       entrada = raw_input(“> “)
-       if entrada == “adios”:
-           break
-       else:
-           print entrada
-
-
-Para obtener lo que el usuario escriba en pantalla utilizamos la función
-raw_input. No es necesario que sepais qué es una función ni cómo
-funciona exactamente, simplemente aceptad por ahora que en cada
-iteración del bucle la variable entrada contendrá lo que el usuario
-escribió hasta pulsar Enter.
-
-Comprobamos entonces si lo que escribió el usuario fue adios, en cuyo
-caso se ejecuta la orden break o si era cualquier otra cosa, en cuyo caso
-se imprime en pantalla lo que el usuario escribió.
-
-La palabra clave break (romper) sale del bucle en el que estamos.
-
-Este bucle se podría haber escrito también, no obstante, de la siguiente
-forma:
-
-   salir = False
-   while not salir:
-       entrada = raw_input()
-       if entrada == “adios”:
-           salir = True
-       else:
-           print entrada
-
-
-pero nos ha servido para ver cómo funciona break.
-
-Otra palabra clave que nos podemos encontrar dentro de los bucles es
-continue (continuar). Como habréis adivinado no hace otra cosa que
-pasar directamente a la siguiente iteración del bucle.
-
-   edad = 0
-   while edad < 18:
-
-                                                                        33
-
-                                                         Python para todos
-
-
-        edad = edad + 1
         if edad % 2 == 0:
             continue
-        printFelicidades, tienes “ + str(edad)
+        print("Felicidades! tienes", edad)
 
-
-Como veis esta es una pequeña modificación de nuestro programa de
-felicitaciones. En esta ocasión hemos añadido un if que comprueba si
-la edad es par, en cuyo caso saltamos a la próxima iteración en lugar de
-imprimir el mensaje. Es decir, con esta modificación el programa sólo
+En esta ocasión hemos añadido un if que comprueba si la edad es par, 
+en cuyo caso saltamos a la próxima iteración en lugar de imprimir el 
+mensaje.  Es decir, con esta modificación el programa sólo 
 imprimiría felicitaciones cuando la edad fuera impar.
 
+
 for … in
-A los que hayáis tenido experiencia previa con según que lenguajes este
-bucle os va a sorprender gratamente. En Python for se utiliza como
-una forma genérica de iterar sobre una secuencia. Y como tal intenta
-facilitar su uso para este fin.
+********
 
-Este es el aspecto de un bucle for en Python:
+Este bucle es diferente a los tradicionales de otros lenguajes y de 
+hecho funciona más como un *foreach* de algunos de ellos (como php, 
+por ejemplo).  Es un iterador de secuencias, por lo que actúa sobre 
+conjuntos de datos siempre y no es un contador tradicional como en 
+la mayoría de lenguajes de programación.  Su sintáxis, en lenguaje 
+natural, sería *PARA* OBJETO *EN* SECUENCIA *ENTONCES* y podemos 
+entenderlo mejor con este ejemplo::
 
-   secuencia = [“uno”, “dos”, “tres”]
-   for elemento in secuencia:
-       print elemento
+    frutas= ["manzana", "pera", "maracuya"]
+    for elemento in secuencia:
+        print elemento
 
+En este caso hemos definido una lista (secuencia) y luego actuamos 
+sobre esta con el **for**, sin embargo, aquí hacemos uso de una 
+*variable* (objeto) denominado (en este caso) *elemento* que es 
+donde se guardará, provisionalmente, cada valor de la secuencia y 
+además se ejecutará un bloque de acciones (líneas de código) por 
+dicho valor.
 
-Como hemos dicho los for se utilizan en Python para recorrer secuen-
-cias, por lo que vamos a utilizar un tipo secuencia, como es la lista, para
-nuestro ejemplo.
+Para nuestro ejemplo, específicamente, se imprimirán una a una las 
+frutas contenidas en la *lista* de manera ordenada, comenzando por 
+*"manzana"* y terminando con *"maracuya"*.
 
-Leamos la cabecera del bucle como si de lenguaje natural se tratara:
-“para cada elemento en secuencia”. Y esto es exactamente lo que hace
-el bucle: para cada elemento que tengamos en la secuencia, ejecuta
-estas líneas de código.
-
-Lo que hace la cabecera del bucle es obtener el siguiente elemento de
-la secuencia secuencia y almacenarlo en una variable de nombre ele-
-mento. Por esta razón en la primera iteración del bucle elemento valdrá
-“uno”, en la segunda “dos”, y en la tercera “tres”.
-
-
-Fácil y sencillo.
-
-En C o C++, por ejemplo, lo que habríamos hecho sería iterar sobre las
-                                                                        34
-
-                                                          Control de flujo
-
-
-posiciones, y no sobre los elementos:
+Simpático, verdad? Sólo como referencia del funcionamiento del *for* 
+en otros lenguajes veremos algo similar para C / C++, en donde se 
+itera sobre las posiciones de los elementos de una secuencia y no 
+sobre sus valores en sí::
 
    int mi_array[] = {1, 2, 3, 4, 5};
    int i;
    for(i = 0; i < 5; i++) {
-       printf(%d\n, mi_array[i]);
+       printf("%d\n", mi_array[i]);
    }
 
+Es decir, tendríamos un bucle for que fuera aumentando una variable 
+i en cada iteración, desde 0 al tamaño de la secuencia, y 
+utilizaríamos esta variable a modo de índice para obtener cada 
+elemento e imprimirlo.
 
-Es decir, tendríamos un bucle for que fuera aumentando una variable
-i en cada iteración, desde 0 al tamaño de la secuencia, y utilizaríamos
-esta variable a modo de índice para obtener cada elemento e imprimir-
-lo.
+Como pueden ver el enfoque de Python es más intuitivo y 
+estéticamente más agradable.
 
-Como veis el enfoque de Python es más natural e intuitivo.
 
-Pero, ¿qué ocurre si quisiéramos utilizar el for como si estuviéramos en
-C o en Java, por ejemplo, para imprimir los números de 30 a 50? No os
-preocupéis, porque no necesitaríais crear una lista y añadir uno a uno
-los números del 30 al 50. Python proporciona una función llamada
-range (rango) que permite generar una lista que vaya desde el primer
-número que le indiquemos al segundo. Lo veremos después de ver al
-fin a qué se refiere ese término tan recurrente: las funciones.
 
 
-
-
-                                                                       35
-