Ej. 39 : Trabajando con diccionarios…

Voy a ver otro contenedor que puedo utilizar que me abrirá un mundo de posibilidades. Se trata de el contenedor más útil: el diccionario.

Python los llama «dicts». Otros lenguajes los llaman «hashes». Lo que impota es lo que hacen cuando se comparan con las listas. Una lista puede hacer cosas como las siguientes:

Ej. 39 - Python ej lista

Podemos usar los números para indicar el número de una lista, lo que significa que podemos usar números para encontrar lo que hay en ella (ver ejercicio 34).

Lo que hace un diccionario es permitirme usar cualquier cosa, no sólo números. Un diccionario asocia una cosa a otra, sin importar lo que sea. Ejemplo:

Ej. 39 - Python ej lista 2

En lugar de usar sólo números, estoy usando cadenas para decir que elementos quiero. También puedo añadir elementos nuevos al diccionario usando las cadenas de texto, los nombres.

También puedo hacer lo siguiente:

Ej. 39 - Python ej lista 3 error

Vaya. ¡No me deja!

Mmmmmm. Es que he cerrado Python, y debería de haber continuado desde la pantalla anterior…

Ej. 39 - Python ej lista 3

Ahora si. En éste código he usado números y luego puedo ver que hay números y cadenas como claves en el diccionario cuando lo muestro en la pantalla.

Por supuesto, un diccionario en el que sólo se pueden poner cosas es muy aburrido. Se borra con la palabra clave del de la siguiente forma:

Ej. 39 - Python ej lista 4

Bien. Ahora escribo un programa interesante.

Ej. 39 - Programa 1

Me da el siguiente error en la línea 3.

Ej. 39 - Programa 1 error

He cambiado cosas (he puesto lo del código ASCII en la línea 1) y no doy con la tecla.

El error está ahora en la línea 4. 😦

No lo puedo ejecutar todavía. Jur. Dejo el resto del código aquí, aunque como todavía no lo he ejecutado, no se si tiene errores o no.

Ej. 39 - Programa 2

Corrijo cosas básicas que estaban mal desde el ppio. Los diccionarios usan LLAVES, NO CORCHETES.

Ej. 39 - Programa con errores

La línea 20 y 21 las cambio también, no estaban bien planteadas. Igual hay otra forma más parecida a lo que había en el anterior programa, pero yo he tirado de lo conocido (arriba).

Al ejecutar, voy depurando y me va saliendo lo siguiente, hasta el siguiente atasco:

Ej. 39 - Programa errores

Error en la línea 25. Cambio a llaves, pero me sale lo mismo. Me temo que es la estructura, aunque me diga invalid syntax. ¿Está mal planteado? Lo que sigue a continuación también estará mal…porque es lo mismo… 😛

Bien. Ya he salido del bache. Dando vueltas y con nuestro método favorito: pueba-error mientras sigo observando. Love it. Éste es el programa corregidoEj. 39 - Programa 1 corregidoEj. 39 - Programa 2 corregido

Que ejecutando resulta:

Ej. 39 - Terminal corregido

Nice. 🙂

PREGUNTAS

P: ¿Qué diferencia hay entre  una lista y un diccionario?

R: Una lista es una lista ordenada de elementos. Un diccionario (o dict) es para crear una relación entre unos elementos (llamados «clave») y otros (llamados «valores»).

P: ¿Para qué debería de usar un diccionario?

R: Úsalo siempre que tengas que tomar un valor «consultando» otro valor. De hecho, podrían llamarse «tablas de consulta».

P: ¿Para qué debería de usar una lista?

R: Una lista es para cualquier secuencia de cosas que necesitan estar ordenadas y sólo necesitas consultarlas por un índice numérico.

P: ¿Y si necesito un diccionario, pero necesito que esté ordenado?

R: Echa un vistazo a la siguiente estructura de datos de Python: collections.OrderedDict. Búscalo en internet y lee documentación sobre ésto.

Por curiosidad, también lo miro en pydoc y me sale ésto:

Ej. 39 - Pydoc collections.OrderedDict

Ej. 38 : Practicando con listas…

Cuando escribo el código Python mysuff.append(‘hello’), en  realidad se están desencadenando una serie de procesos dentro de Python para que suceda algo a la lista mystuff. Así funciona:

  1. Python ve que indiqué mystuff y revisa esa variable. Puede que revise si anteriormente se creó con un =, si se trata de un parámetro de una función o si es una variable global. En cualquier caso, tiene que encontrar donde aparece por primera vez mystuff.
  2. Una vez encuentra mystuff, llega al operador . (punto) y empieza a revisar las variables que son parte de mystuff. Desde el momento que sabe que mystuff es una lista, también sabe que tiene muchas funciones asociadas.
  3. Luego encuentra append y lo compara con todas las funciones y variables de mystuff. Si append está ahí, la usa.
  4. A continuación, Python ve los paréntesis y dice «¡Oh! Ésto debe de ser una función». En ese momento, llama o ejecuta la función con un parámetro extra.
  5. El parámetro extra es…¡¡mystuff!! Lo sé, es raro, ¿verdad? Pero así es como funciona Python, así que lo mejor es simplemente recordarlo y asumir que eso es lo correcto. Lo que ocurre es que la llamada a la función, en el fondo se procesa de una forma similar a append (mystuff, ‘hello’), en lugar de mystuff.append(‘hello’).

No es necesario saber que ésto está pasando pero me será de ayuda para cuando tenga mensaje de error como éste:

>>> class Thing(object) :

…  def test (hi) :

…  print «hi»

>>> a = Thing ()

>>> a.test («hello»)

Traceback (most recent call last): 

File «<stdin>», line 1, in <module>

TypeError: test () takes exactly 1 argument  (2 given)

>>>

Más adelante lo veré, pero el error significa que Python cambió a.test(«hello») por test(a,»hello») y que en algún lugar alguien se confundió y no añadió el argumento o parámentro para a.

Dedicaré algunos ejercicios para que éste concepto quede claro. Haré éste ejercicio que mezcla cadenas y listas para divertirme un poco.

Ej. 38 - Editor Ej. 38 - Terminal

PREGUNTAS

P: ¿No dijimos que no era recomendable usar bucles while?

R: Las reglas se pueden romper si tienes una buena razón. No hay que ser esclavos de las reglas.

P: ¿Qué hace stuff[3:5]?

R: Obtiene una parte de la lista, del elemento 3 al 4, lo que significa que no incluye el 5. Es similar a como funciona range (3,5).  Aunque no es lo mismo, ¿eh?. Con stuff[3:5] se obtiene una sublista de stuff, tenga lo que tenga, range sólo devuelve números.

P: ¿Por qué no funciona join(‘ ‘, stuff)?

R: Esa forma no tiene sentido. No funciona de esa manera, ya que join es un método asociado a una cadena. Reescríbelo así: ‘ ‘.join(stuff).

+ EJERCICIOS

  1. Toma cada llamada a una función y revísala siguiendo los pasos descritos anteriormente para traducirlo a lo que hace Python. Por ejemplo,   ‘ ‘.join(cosas) es join(‘ ‘ , cosas).
  2. Traduce estas dos formas de ver las llamadas a funciones. Por ejemplo, ‘ ‘.join(cosas) se puede leer como «join cosas aplicado a ‘ ‘ «. Otra forma es «Llamada a join con ‘ ‘ y cosas». En realidad es lo mismo.
  3. Busca en internet sobre PROGRAMACIÓN ORIENTADA A OBJETOS (OOP).
  4. Busca que es class en Python, no en otros lenguajes, que puede dar lugar a confusión.
  5. ¿Cuál es la relación entre dir(algo) y la class de algo?

Ej. 32 : Aprendiendo con bucles y listas…

Ahora puedo hacer programas mucho más interesantes.

Sin embargo, los programas también necesitan hacer cosas de manera repetitiva y muy rápida.

En éste ejercicio voy a utilizar un bucle para generar e imprimir varias listas.

Antes de usar un bucle for, necesitamos una forma de almacenar en algún lugar los resultados del bucle. La mejor manera es hacerlo es una lista. Una lista es exactamente lo que dice su nombre, un contenedor de cosas que están organizadas en orden. No es complicado. Sólo hay que aprender una sintaxis nueva. Ésta es la forma de crear una lista:

hairs = [‘brown’, ‘blond’, ‘red’]

eyes = [‘brown’, ‘blue’, ‘green’]

weights =[1, 2, 3, 4]

Lo que hago es empezar la lista con el corchete izquierdo para abrir la lista. Luego escribo cada uno de los elementos que deseo que contenga la lista. Igual que hacía con los parámetros de las funciones. Por último, termino y cierro con corchete derecho. Python toma ésta lista y todo su contenido, y lo asigna a una variable.

Creo algunas listas usando bucles y las muestro en pantalla:


Ej. 32 - Editor Ej. 32 - Terminal

NOTA: A muchos cerebros les han enseñado que el mundo es plano. En el ejercicio anterior, tenía sentencias del tipo if dentro de otro if. Para algunos, «anidar» unas cosas dentro de otras puede dar lugar a confusión. En programación ésto está por todos lados. Encontraré funciones que llaman a otras funciones que tienen sentencias if y listas con listas dentro de listas. Ante problemas, sugiero papel y lápiz, para un análisis manual.

PREGUNTAS

P: ¿Cómo se hace una lista de dos dimensiones?

R: De una forma similar a ésta: [[1, 2, 3], [4, 5, 6]].

P: ¿Es lo mismo una lista que un array?

R: Interesante. Depende del lenguaje y la implementación. Estrictamente, las listas son muy diferentes a los arrays debido a la forma de implementación. En Ruby, las listas se denominan arrays. En Python, nos referimos a ellas como listas. Por ahora las llamamos listas, ya que Python las llama así.

P: ¿Cómo puede un bucle for usar una variable que no había sido definida antes?

R: La variable queda definida en el bucle y toma un valor en cada iteración.

P: Mmmmm. ¿Y qué es una iteración?

R: De momento, voy a remitirme a las palabras de Wikipedia…

En programación, Iteración es la repetición de un proceso dentro de un programa de computadora. Puede usarse tanto como un término genérico (como sinónimo de repetición) así como para describir una forma específica de repetición con un estado mutable (el ejercicio es el segundo caso).

Cuando se usa en el primer sentido, la recursividad es un ejemplo de iteración, pero que usa su propia notación (notación recursiva), que no es el caso de iteración.

Sin embargo, cuando se usa en el segundo sentido (caso más restringido), como vemos en el ejercicio, la iteración describe el estilo de programación usado en lenguajes de programación imperativa. Esto está en contraposición de la recursividad, la cual tiene un enfoque más declarativo.

He aquí un ejemplo de iteración basándose en asignación destructiva, en pseudocódigo imperativo:

 var i=0, a := 0        // inicializo a antes de comenzar la iteración
 for i from 1 to 3 {  // ciclo 3 veces
     a = a + i       // incremento a con el valor actual de i
     print a              // se imprime el número 6
     }

En este fragmento de programa, el valor de la variable i cambia a medida que la ejecución del programa progresa, tomando los valores 1, 2 y 3. Este cambio de valor —o estado mutable— es característico de una iteración.

Es un tema que da para mucho. Lo retomaré.

P: ¿Qué hace la función range exactamente?

R: Vamos a preguntar a pydoc:

Pydoc - range

P: ¿Por qué for i in range (1, 3): sólo tiene dos iteraciones en lugar de tres?

R: La función range () va del primer al último número, pero no incluye el último. Así que se detiene en dos, no en tres. Es la forma más común de funcionamiento de éste tipo de bucles.

P: ¿Qué hace elements.append () ?

R: Simplemente añade algo al final de la lista. Abre la línea de comandos de Python y prueba ejemplos con cada lista que crees. Así se ve mejor.

PENDIENTE

  1. Buscar info en la documentación de Python sobre las listas. ¿Qué otras operaciones se pueden usar para añadir elementos a las listas?
  2. Profundizar sobre iteración y recursividad.

Ej. 26 : Corrigiendo errores…

He llegado al ecuador de éste nivel 0 de Python. A partir de aquí es donde las cosas se empiezan a poner interesantes. Aprenderé lógica y seré capaz de hacer cosas útiles, como tomar decisiones.

Antes de continuar, voy a hacer una prueba. Voy a solucionar errores de código de 3 tipos:

  • La mayoría de los errores son cosas de las que Phython me avisará.
  • Otros son errores matemáticos que debo encontrar.
  • También habrá errores de formato o faltas de ortografía en las cadenas.

Todos éstos errores son muy comunes. Mi trabajo será corregir éste fichero. Intentaré usar todas mis «habilidades» para mejorarlo. Primero lo analizaré. Arreglaré cada error y e intentaré continuar hasta que el código se ejecute bien. Ésta vez no consultaré ningún tipo de ayuda, y si me quedo atascada, me tomo un descanso y retomo más tarde (que es lo que me ha pasado en el ejercicio anterior).

El fichero es el siguiente:Ej. 26 - Editor 1Ej. 26 - Editor 2Ej. 26 - Editor 3Éstas son algunas cosas que he hecho…

Ej. 26 - Errores en Terminal 1 corregidos

Ej. 26 - Errores en Terminal 2 corregidosEj. 26 - Errores en Terminal 3 corre

Hay cosas que no veo claras porque las arrastro del ejercicio anterior, que no he ejecutado todavía. Los dos ejercicios anteriores están en éste. Así que dejo el ejercicio en éste punto, para retomarlo más adelante y avanzar con el siguiente post.

A por el 27!!

Ej. 17 : Haciendo más ficheros (y cometiendo errores)…

Ahora voy a hacer un par de cosas más con ficheros. Voy a escribir un programa Python para copiar un fichero a otro. Será muy corto, aunque me dará una idea de lo que puedo llegar a hacer con ficheros…

Ej. 17 - Código con errores

Qué bonito, ¿verdad? Pues estoy atascadísima. Soy humana. Ya iba yo muy confiada. Hay 1 error fatal y no consigo verlooo…

He ido corrigiendo algunos y eran detalles tontos que en 2 segundos cambiaba al ejecutar, guardaba el código cambiado (ésto es una totería supina, pero hay que estar a todo, y se me ha pasado alguna que otra vez, dándome el mismo error a pesar del cambio, HAY QUE GUARDAR en el editor por cada nuevo cambio).

He aquí mi cadena de errores (casi todos tontunas), que he ido solventado con dignidad hasta llegar al punto muerto en el que me encuentro.

Ej.17 - Errores en cadenaPor lo que leo el error ya me ha pasado antes y no está en el programa, sino a la hora de ejecutar…

¿No debería escribir algo así como … phython  ex17.py  test.txt ?

En realidad quiero escribir test17.txt para no borrar el test del ejercicio, pero eso es ménos importante…

…..

Le voy a dar una vuelta y luego retomo…

😦

SOLUCIÓN

Bien. Me han echado un cable. Pero lo justo para tener que seguir peleando, un poco más, ¿eh?.

Thanks!!!

Al igual que con otros programas, debería ejecutar con dos parámetros o argumentos: el fichero desde el que copiar y el fichero al que copiar. Estaba aquí la cuestión. Creo que leyendo ésto bien, se entiende, necesito 2 archivos txt, no sólo uno.

Lo he hecho en dos pasos:

  1. Había que mostrar el contenido del fichero de «María y su corderito». 🙂 Ese que hice en el ejercicio anterior…el test.txt desde el que copiar. Lo ejecuto en Poweshell con el comando type.. muestra el contenido del fichero…
  2. Y una vez hecho eso, entonces lo ejecuto junto con un new_file que es al que voy a copiar.

That´s all!!

Bueno, había algún detallito en el código solucionados sobre la marcha. Lo importante creo que es ir entendiendo lo que hago, dentro de lo posible.

Insisto en que volveré sobre mis pasos después para completar comentarios y demás. De momento quiero ir avanzando con ritmo.

Éste es el PROGRAMA CORRECTO.

Ej. 17 - Código solucionado

Sigo haciendo intentos de ejecución… Ej.17 - Errores en cadena...y SOLUCIÓN BISLO IMPORTANTE, LO QUE HAY QUE EJECUTAR, DONDE HE DUDADO… Ej.17 - SOLUCIÓN GRANDE

+PREGUNTAS

P: ¿Qué hace el comando(método) exists que he importado?

R: Devuelve True si existe el fichero cuyo nombre en formato string pasamos por parámetro. Devuelve False si no existe.

P: ¿Qué hace import?

R: Es una forma de obtener código libre que han escrito otros programadores, así no tienes que volver a escribirlo.

P: ¿Qué hace type en la línea de comandos?

R: Muestra el contenido de un fichero

P: ¿Qué hace la función len()?

R: Calcula el tamaño o longitud de la cadena pasada por parámetro y lo devuelve como un número.

P: ¿Qué significa el error «Syntax: EOL while scanning string literal.»?

R: Que olvidé poner correctamente el final de una cadena con comillas.

+EJ PARA AMPLIAR…

Para amliar me proponen que haga un programa que pase 4 ficheros como arg, mezclarlos, y generaruna mezcla de los tres primeros.

Ej. Python merge.py  f1 f2 f3 f4

donde f4 = f1 + f2 + F3

Y con ésto y un bizcocho…voy a por el 18…