La estructura mágica: los diccionarios

Esta estructura es parecida a la de las listas pero veremos que tiene sus diferencias. Un diccionario es como una lista pero que en lugar de estar posicionada por números lo está por cualquier cosa. Veamos un ejemplo de Visual Studio Code:

Interfaz de Visual Studio Code - CC0. Fte: Elaboración propia

Como podemos ver el diccionario también contiene como en la lista los valores que le he metido, en este caso 8, 5 y 9, que representan las notas que han sacado 3 personas. Pero en lugar de guardarlo en posiciones numéricas, como antes hacíamos en la posición 0,1 y 2, ahora lo guardamos en posiciones de tipo cadena. De esta manera, en la posición "Juan" hemos guardado su nota: 8 y así con los demás. ¿Para qué sirven? Pues para guardar datos que no tienen un orden como en este caso, porque no es que vaya Juan antes que Julia. No necesitamos guardar la posición que tiene en la estructura, sino una información que necesitamos para identificarlo, en este caso, su nombre. Porque queremos guardar para cada nombre qué nota ha sacado.

Por lo contrario, si yo quisiera guardar posiciones en la que han quedado en una carrera, sí tendría más sentido una lista, de manera que en la posición 0 tendríamos el nombre del ganador, en la posición 1 el que haya quedado segundo y así sucesivamente. Por tanto, es importante que cuando analicemos el problema sepamos qué estructuras vamos a necesitar. ¿Y cómo accedemos a los valores de diccionario? Pues siguen la misma lógica que antes: si con las listas que tenían las posiciones con números accedíamos con números, ahora que las posiciones son las cadenas Juan, Julia y Ana, usaremos lo mismo:

print(diccionario['Ana']) #Muestra 9

Como podemos ver estas estructuras nos permiten almacenar nuestra información y es la práctica lo que nos conferirá la destreza de saber cuándo usar cada estructura.

Estructuras de datos

Hasta ahora hemos enfocado la programación desde el punto de vista del algoritmo: if/else, bucles y es correcto que es la base de la programación. Pero si recordamos el artículo de Qué es la programación la programación involucraba dos cosas: algoritmos y datos. Así que en este artículo nos vamos a centrar en las estructuras de datos. El caso es que los hemos estado usando sin darnos cuenta y sin fijarnos en ciertos detalles. Por ejemplo, en ejemplos anteriores era habitual que cuando leíamos un número del usuario aplicáramos la función int(). ¿Por qué? Porque la función input devuelve un dato de tipo "Cadena" y nosotros queríamos aplicar operaciones matemáticas, esto es, sumar, restar, etc. Por tanto, lo teníamos que convertir. Veamos que se puede hacer con una cadena y qué se puede hacer con un número con un ejemplo:

Cadenas

saludo = "hola "
nombre = "Javi"
concatenacion = saludo + nombre
print(concatenacion)

Efectivamente, sumar en el mundo de las cadenas, es concatenar. ¿Qué es concatenar? Pues como podéis ver es crear una cadena que está formada por la suma de las otras 2, es decir, que cuando acabe la primera cadena empezará la segunda.

Enteros

a = 1
b = 2
suma = a + b

Con esto ya estamos más familiarizados y no necesita mucha más explicación. Al crear la variable como 1 o 2, definimos una variable de tipo entero, es decir, un número entero, y por tanto, le puedo aplicar operaciones como la suma en este caso. Vemos que no se aplica el mismo sentido que si es una cadena. De hecho si fuera un 1 con las comillas dobles que representan una cadena el resultado sería bien distinto. Veámoslo:

a = "1"
b = "2"
suma = a + b
print(suma)
# Muestra lo siguiente por pantalla: "12"

Listas

Las listas son fundamentales en la programación y sirven para guardar elementos. Pero voy a usar una foto donde he definido mi lista y usando Visual Studio Code, mostramos que contiene esa lista:


Interfaz de Visual Studio Code - CC0. Fte: Elaboración propia

Viendo la foto es más fácil explicar que una lista contiene los elementos que hemos puesto: "a", "b", "c". Pero si nos fijamos en eso que pone 0: "a", indica que es en la posición 0 donde se encuentra la letra "a", y en la posicion 1 la letra "b". ¿Por qué? En informática por razones de rendimiento toda posición empieza en 0 y es importante que nos acostumbremos a pensar que la primera posición es siempre el 0. Por tanto, la variable lista es una estructura que me permite acceder a las letras a,b y c por la posición. Veamos un ejemplo:

lista = ["a", "b", "c"]
print(lista[2]) # muestra "c"

Si empezamos a contar o simplemente vemos la foto está claro que si quisiéramos acceder a la letra "c" haríamos lista[3], con esta forma de usar los corchetes le decimos que no quiero la estructura entera, sino la posición 2 (la tercera posición) de la lista.

Haciendo algo útil para la clase de mates

Fijaos que ya tenemos realmente los cimientos para construir cualquier software. El resto ya es aprender a usar las funciones que vamos a necesitar y eso se puede aprender leyendo la documentación del autor. Y es que al final gran parte del trabajo consiste en saber leer el código de los demás y saber usar sus funciones. Todo lo demás es usar if, bucles y poco más. Veamos un ejemplo de lo que podemos hacer con lo que sabemos.

 Supongamos que el profesor o profesora de matemáticas nos pide resolver ecuaciones de segundo grado completas y nos deja utilizar la programación para resolverlo, es decir, que podemos resolver las ecuaciones manualmente o haciendo un algoritmo. Y pensamos que con un algoritmo se ahorra trabajos, veamos si es así: Analicemos el problema primero: una ecuación de segundo grado está compuesta de 3 variables: a, b y c. Y se resuelve de esta manera:


By Drini - CC BY-SA 4.0 from Wikimedia Commons

Empecemos dividiendo el problema en subproblemas. Está claro que lo más complicado es la resolución de la raiz cuadrada del cuadrado de b - 4*a*c que vamos a resolver solamente esa parte:

from math import sqrt
   raiz = sqrt(b*b - 4*a*c)
 
Como ya dijimos en Haciendo grandes cosas con poco usamos una función que ya existe para hacer raíces cuadradas que se llama sqrt. Esa línea lo que está diciendo es del paquete "math" voy a usar la función sqrt. Finalmente una vez que tenemos la raíz, le pasamos el parámetro que será el cuadrado - 4*a*c, y ya sabemos que nos devolverá el resultado de la raíz yl o guardamos en la variable raíz.
El segundo subproblema es más sencillo, vamos a calcular el resultado siguiendo la fórmula:

resultado1 = (-b + raiz) / 2 * a
resultado2 = (-b - raiz) / 2 * a
 
Y ya hemos acabado realmente, colocamos para leer los números que nos diga el usuario e imprimimos los resultados quedando el algoritmo entero de esta forma:


from math import sqrt

a = int(input('a:'))
b = int(input('b:'))
c = int(input('c:'))

raiz = sqrt(b*b - 4*a*c)
resultado1 = (-b + raiz) / 2 * a
resultado2 = (-b - raiz) / 2 * a
print("resultado1:{}".format(resultado1))
print("resultado2:{}".format(resultado2))
 
Podríamos quedarnos aquí pero entonces no seguiríamos las prácticamos que llevamos comentando. ¿Qué falta? O mejor dicho, si pensáramos con la mentalidad del software libre, nos deberíamos preguntar: ¿este código lo podría usar alguien? La respuesta es que no, porque no lo hemos encapsulado en ninguna función, veamos lo fácil que se hace:

from math import sqrt

def calcular_ecuacion(a, b, c):
    raiz = sqrt(b*b - 4*a*c)
    resultado1 = (-b + raiz) / 2 * a
    resultado2 = (-b - raiz) / 2 * a
    return resultado1, resultado2

a = int(input('a:'))
b = int(input('b:'))
c = int(input('c:'))
resultado1, resultado2 = calcular_ecuacion(a, b, c)
print("resultado1:{}".format(resultado1))
print("resultado2:{}".format(resultado2))

 
Como vemos, tenemos una función que dados los parámetros a, b y c, devuelve 2 valores: resultado1 y resultado2. Cualquier persona puede usar esa función como hemos hecho abajo y recoger en 2 variables el resultado de la ecuación.

Haciendo cosas grandes con poco: Funciones

En el artículo Software libre: no es un concepto, es una actitud se comentaba que cuándo fuéramos a abordar un problema, pensáramos primero si ya estaba resuelto este problema antes en Internet. En este artículo vamos a hacer algo práctico y útil, vamos a abordar un problema real y vamos a ver que juntando las piezas de funciones que han desarrollado terceras personas, podremos hacer algo interesante que nos valga para la vida real. Pero primero es lo primero. ¿Qué son las funciones?

Una función es un trozo de código que vamos a englobar para poder llamarlo cuando queramos. Es decir, que si vemos que estamos repitiendo el mismo código es de buen programador evitarlo. Veamos un ejemplo:

Supongamos que el algoritmo que nos piden es pedir un número al usuario y decirle si es par o impar. Y vemos que en otra ocasión volvemos a necesitar esa misma funcionalidad de ver si el número es par o impar y otra vez. Vemos que al final ese código de comprobar si un número es par tendría que estar repitiéndose varias veces, así que vamos a hacer una función que dado un número nos diga si es par o no:

def es_par(num):
    if num % 2 == 0:
        return True
    else: 
        return False
Se define una función poniendo "def" seguido del nombre de la función, y entre paréntesis los parámetros que va a recibir la función, es decir, los datos que recibe. Hay que hacer return para decir qué va a devolver la función. Si lo pensáis fríamente, un algoritmo al final va a estar compuesto de varias funciones que hacen cosas, y es que el código de la vida real suele estar hecho así. No es normal ver un montón de código apelotonado, si no el uso de muchas funciones, porque eso permite leer mejor el código. Veámoslo como quedaría:

n = input("Dime un numero:")
if (es_par(int(n))):
    print("Es par!!")
else:
    print("no es par :(")

Esto es muy fácil de leer, casi se lee solo: si es_par entonces mostrar por pantalla "es par", sino mostrar "no es par". Sin pararnos a detener lo que hace la función, el uso de ella es trivial, solo tengo que poner el nombre con el que le ha definido(es_par), y entre paréntesis pasarle el parámetro que recibe. Un parámetro, son datos que recibe una función. En el fondo es parecido a la definición de un algoritmo, y es que en el fondo no se hacen algoritmos sin más, sino que suelen englobarse en funciones para que otros usuarios las puedan usar, y esto va muy ligado a lo que decíamos antes. En este caso si fuera una función que pudiera interesar a otros, podríamos publicar la función para que otros puedan utilizarla. Y ahora como sé que os habéis quedado con la intriga de qué hace la función, os lo cuento porque no tiene mucha complicación. El "%" es un operador, igual que tenemos "+" o "-", y nos devuelve el resto de la operación división. Por tanto, si el resto de una división por 2, nos da 0, significa que es 0, es una manera de saberlo. Teniendo una visión global de todo esto, vemos como al final nosotros estamos usando funciones, porque input es una función que nos da Python para leer lo que dice el usuario, print es una función que dada una cadena que le pasamos por parámetro nos muestra por pantalla. Al final la programación es usando otras funciones que otros han hecho, construyo yo las funciones que necesito, y a su vez podrían servir para otras personas, y esta cadena maravilla es la programación.

Estructuras de control: bucles

Llegamos a la joya de la corona, si nos pusiéramos melosos podría decir que los bucles son con lo que se fabrican los sueños. Ahora hablando más en serio, los bucles son el pilar fundamental de la programación y su potencial es enorme. Este artículo se complementa muy bien con el de Estructuras de datos así que recomiendo que se lean estos 2 de manera simultánea para una mejor comprensión.

Un bucle es una repetición de un bloque de código hasta que la condición deje de cumplirse, es decir, que escrito como más formalmente sería algo así:

Mientras (se cumpla una condicion):
   hacer algo
Es decir, que ese "hacer algo" se va a estar repitiendo hasta que la condición deje de cumplirse. Pero veamos un ejemplo práctico:

n = 10
n_entero = int(n)
i = 1
while i<= n_entero:
    print(i)
    i = i + 1

Analicemos este código: tenemos una condición que se debe cumplir para entrar a ejecutar el bloque de código. La condición dice que la variable i debe ser menor o igual que la variable n. Las variables i y n se han inicializado a 1 y 10, por tanto, como la condición 1 < 10 es verdad, entra dentro del bloque y mostrará por pantalla "1". La gracia de esto está en la siguiente instrucción porque vamos a modificar la variable que está en la condición: la i, y le vamos a sumar el valor 1. Por lo tanto, i vale ahora 2 y volvamos a preguntar por la condición: ¿2 es menor que 10? Sí, por tanto volvemos a entrar y mostramos visualmente 2. Podemos imaginarnos que esto sucederá sucesivamente hasta que la variable i llegue al valor 11, entonces cuando en la condición se pregunte: ¿11 es menor que 10? La respuesta es no, y por tanto no entrará dentro del bloque de código y hemos salido del bucle. Como diría cierto personaje de Marvel: "un gran poder conlleva una gran responsabilidad". Y es que un bucle tiene mucho potencial pero si se comete algún despiste el error puede ser catastrófico. Por ejemplo, qué pasaría si en este mismo código elimináramos la línea: "i= i + 1". Pues nada menos que provocaríamos el temido "bucle infinito". Un bucle infinito que mostraría por pantalla el 1 para siempre y por siempre. Moraleja: siempre debemos ver si la condición dejará de cumplirse en algún momento.

Como precisamente es tan peligroso usar este tipo de bucles donde depende del programador que se produzca un bucle infinito, otra tipo de bucles se crearon para conseguir repetir código de forma más segura: el for. Veamos el mismo ejemplo de antes usando el bucle for:

for i in range(11):
    print(i)
Esa línea deberíamos leerla tal que así: voy a recorrer un rango de números de 0 hasta 11 (no incluído), y ese recorrido me lo vas a ir guardando en la variable i. Osea que tendríamos un código exactamente equivalente al del bucle while. Solamente cambia que ya nos ha introducido la condición y el incremento del i. Como esto es solo para introducirnos en los bucles, no voy a entrar en más detalles pero en general se dice que el bucle for es un bucle de recorrido porque va a recorrer un listado de elementos, mientras que un bucle while sirve para buscar algo. Por tanto, si pensábamos que podíamos olvidarnos del while, me temo que no.

Software libre: no es un concepto, es una actitud

En Python, como en cualquier otro lenguaje de programación, tenemos que tener clara una cosa: todo está ya inventado. ¿Qué quiere decir esto? Que no vamos a reinventar la rueda, por tanto, cada vez que necesitemos resolver un problema, lo primero que hay que preguntarse es: ¿esto lo ha resuelto alguien ya? Y buscar en Internet para encontrarlo. A priori, uno podría pensar que esto está mal y que se está plagiando el código de otro programador, pero estaríamos totalmente equivocados porque este es justamente el espíritu del software libre (Open Source). El software libre no es un término, sino una forma de pensar y trata de entender que el software pertenece a todos.



Volvamos un poco para atrás, bueno mejor volvamos bastante más atrás, al descubrimiento del fuego. Imagináis que los que descubrieron el fuego hubieran privado al mundo de ese descubrimiento. Imaginemos en general cómo el mundo ha avanzado tecnológicamente gracias a la colaboración de millones de personas, a una inteligencia colectiva colaborando entre nosotros porque hay un objetivo común que está por encima de todo.

Lo primero que uno piensa cuando oye todo esto, es un sentimiento de que se están aprovechando de nuestro trabajo pero hay que entender que ojalá pase eso, muy bien te tienen que ir las cosas para que alguien quiera usar tu código y quiera colaborar con él. Probablemente estés creando algo grande.Si todo esto no te es suficiente para querer "regalar trabajo a la gente" piénsalo así: es una oportunidad de enseñar al mundo lo que sabes hacer, un escaparate donde todo el mundo es bienvenido, y actualmente pocas son las empresas que mirarán en portales tan conocidos como GitHub para saber si colaboras con la comunidad y así podrán ver cómo de bueno eres, y quiero terminar con una cita del gran Linus Torvalds:

"Hablar es barato, enséñame tu código" - Linus Torvalds

Configuración de un entorno de programación


Dado que ya empieza a ser el código un poco más complejo lo ideal sería que tuviéramos un entorno de programación porque el intérprete integrado en la web está bien, pero obviamente no da más de sí. De manera que vamos a configurar un entorno en nuestro ordenador para poder programar cómodamente, además con la ventaja de que el lenguaje Python es multiplataforma, es decir, que funciona en cualquier sistema operativo.

Lo primero es instalar Python y os dejo un vídeo que lo explica muy bien:


CC BY License

Una vez tenemos Python instalado, lo suyo es tener un buen editor donde programar. Yo, personalmente recomiendo Visual Studio Code. Hay otros editores bastante buenos para Python como Sublime y por supuesto, si ya queremos algo más avanzado, en lugar de editores, usaríamos un Entorno de desarrollo como PyCharm pero este no es lo más adecuado actualmente porque es un entorno más avanzado y más lento, ahora lo ideal es algo sencillo y rápido de usar.


Estructuras de control: if else

En el post ¿Qué es la programación? creamos nuestro propio algoritmo muy sencillo que hacía la suma de 2 números pero un algoritmo al fin y al cabo. Los algoritmos incorporan una lógica que van a permitir darle potencia a nuestro programa. Esta lógica se conoce como estructuras de control y vamos a hablar de la más básica: if else, que en español se traduciría por: si "pasa esto" entonces "pasara aquello" sino "pasara otra cosa". Como vimos anteriormente podemos jugar con el intérprete que tenemos a la izquierda. Pero antes de ejecutarlo quiero que echemos un vistazo a este código y pensemos que significa usando solamente el sentido común:
    
  a = 2
  if a == 2:
     print("a vale 2")
  else:
     print("a no vale 2")

Vamos a identificar el único dato de entrada, que es la variable a y le hemos asignado el valor 2. Ahora vamos a utilizar la estructura if else, para poder aplicar el siguiente razonamiento: si a es igual a 2 quiero mostrar visualmente a vale 2 y si no es así, quiero mostrar  a no vale 2.

Ya podéis probarlo en el intérprete, y tened en cuenta que el lenguaje que estamos usando (Python) es sensible a los espacios. Por tanto, cuando introduzcamos la variable a = 2, no se deben introducir espacios, y cuando pongamos los print, debido a que están dentro de la estructura if, habrá que introducir espacios (da igual meter un espacio que varios).

Analicemos un poco detalladamente el algoritmo para conocer la sintaxis Python haciendo una simulación de lo que hace internamente para entender qué está pasando:
  • La primera parte es para asignar valor a la variable a era como podíamos suponer ya que es igual en una operación matemática: Variable = valor
  • Para el if habrá que poner la palabra clave if seguido de la condición, en nuestro caso, a == 2. Esta condición utiliza el operador == que indica igualdad, es decir, compara lo que hay a la izquierda con lo que hay a la derecha, en este ejemplo la variable a la compara con 2 y mira si son iguales. Finalmente para indicar que ha terminado la condición ponemos ":". Como hemos dicho esto es igual que en el lenguaje humano decir si "esto" entonces "aquello", pues el signo ":" representa el "entonces".
  • Si se cumple la igualdad (que es así porque hemos asignado anteriormente 2 a la variable a), entonces entra dentro del bloque de código que tenemos después: print("a vale 2"),  provocando que se muestre la frase a vale 2
Como es de esperar si probáis a cambiar la asignación de a = 2 por a = 3 se mostrará el mensaje del else.

Vamos a hacer un mensaje añadido para que quede claro que los espacios son importantes en Python. Supongamos que queremos añadir otro mensaje. Lo haríamos así:
    
  a = 2
  if a == 2:
     print("a vale 2")
     print("sigo estando en el entonces de a==2")
  else:
     print("a no vale 2")
     print("sigo estando en el entonces de a==2")
  print("por aqui pasa siempre, sea igual a 2 o no")

Queda aquí evidenciado que si queremos que otra línea de código se ejecute cuando a == 2 habrá que poner los espacios adecuados

¿Qué es la programación?

La programación involucra 2 términos fundamentales: datos y algoritmos. Con el primero estamos ya acostumbrados pero con el segundo parece que cuesta más digerirlo así que vamos a arrojar un poco de luz.

Un algoritmo es una serie de instrucciones ordenadas que normalmente, dado un conjunto de datos de entrada me dará una salida que yo tengo como objetivo. ¿Muy abstracto no? Pues una receta de cocina podría ser considerado un algoritmo. Digamos que quiero hacer un bizcocho y miro una receta. Sería algo así:
  1. Batir los huevos y añadir azúcar, yogur, aceite y harina.
  2. Verter la mezcla sobre un molde.
  3. Hornear a 180ºC.
Y mis ingredientes serían estos:
  • Huevos, leche, azúcar, aceite, harina.
Está claro que mis datos de entrada son los ingredientes: huevos, leche azúcar, etc... Y que la salida que espero de este algoritmo es un bizcocho. Pero no es solo eso lo que lo convierte en un algoritmo sino el hecho evidente de que si no cumplo exactamente con las instrucciones y en su debido orden el resultado no será el mismo.

Ahora que ya entendemos el concepto abstracto, pasemos a algo más más parecido a la realidad.

Ahora vamos a ser más formales, es decir, vamos a usar un lenguaje más matemático y un ejemplo donde se usen números. Me piden un algoritmo que haga la suma de dos números, es decir, que habrá 2 números que serán los datos de entrada (los llamaremos x e y) y un número de salida (lo llamaremos suma) que será el resultado de la suma de ambos números.

Algoritmo de la suma de dos números
    
  x = 4
  y = 2
  suma = x + y
  print(suma)

Lo único extraño hasta ahora es esa línea de print pero podemos olvidarnos de ella de momento, simplemente sirve para visualizar lo que hemos hecho. ¿Visualizar? ¿Es que este código ya es real? Correcto, de hecho, si introducís este código en el intérprete que veréis a la izquierda en la barra lateral y pulsáis en ejecutar, estaréis ejecutando código Python real que funciona. No es por dramatizar, ¡pero ya estamos programando!


Programación, ¿por qué?

Es algo desconocido y raro. Lo vemos en las películas constantemente: un hombre de dudosa reputación tecleando sin parar y líneas verdes desbordando la pantalla, "hackers" que hacen cosas en "binario" (dicen algunos)  pero poca gente sabe realmente qué es esto de la programación.

Es un término abstracto y complejo y que cuesta explicar, especialmente a la gente que se encuentra fuera del mundillo. Lo normal es que aprender a programar al principio resulte imposible y se oigan frases del estilo: "esto no es para mí" o "yo no estoy hecho para esto". Es importante entender que nuestro cerebro está preparado para programar desde que somos niños, de la misma manera que para hacer sumas o resolver ecuaciones, por tanto, todo el mundo puede programar. Pero es cierto que el mundo de la programación, al igual que el mundo matemático, no es algo tangible, y por ende, el proceso de aprendizaje requerirá tiempo así que hay que tomárselo con paciencia. Pero si lo piensas fríamente no es tan extraño, porque si haces memoria tampoco fue fácil para nadie aprender a sumar o a resolver ecuaciones. Acostumbrar al cerebro a este tipo de razonamiento formal y abstracto lleva su tiempo. De hecho, estos conocimientos básicos matemáticos están tan normalizados y forman parte hasta tal punto de nuestro día a día que no conocerlos nos dejarían fuera de juego del mundo académico y laboral. Y poco a poco, la doctrina de la programación se convertirá en algo igualmente indispensable.

Incorporar estos conceptos matemáticos nos ayudan a pensar y a resolver problemas del día a día. Y no me refiero únicamente a los problemas directos que resuelven obviamente saber sumar, multiplicar o hacer una regla de 3. Sino que ese conocimiento que adquirimos forma parte de nuestra manera de pensar aunque no seamos conscientes de ellos. Programar nos va a aumentar considerablemente nuestra lógica, capacidad de razonamiento, pensamiento creativo. Es más, ¡incluso nos va a dar la capacidad de detectar cuándo alguien nos está engañando! La famosa demagogia. En definitiva, nos va a ayudar a tener pensamiento propio y por tanto, a ser más libres.

Tomad aire, relajaos, porque estamos a punto de adentrarnos en el mundo de la programación.


Semana 10 · Del 10/04/19 al 10/04/19

Hoy ha sido mi último día en el centro y en la primera hora he estado terminando el practicum en la sala de profesores, y después hemos teni...