Python: Aprendiendo a leer

Objetivo: aproximación al trabajo con ficheros en Python, mostrando cómo leer el contenido de un archivo de texto.

Como programador, necesitas familiarizarte cuanto antes con el trabajo con ficheros. Con frecuencia tu aplicación deberá recuperar información de un fichero para su procesamiento, o bien almacenará en él el resultado de ese proceso. Es común también el intercambio de información con el exterior en ambos sentidos: la aplicación se nutre de datos externos almacenados en ficheros y genera información que se guarda nuevamente ellos después.

Nos aproximaremos al trabajo con ficheros en Python de un modo gradual y aprenderemos a realizar las tareas más típicas partiendo de lo más simple: la lectura de un archivo de texto.

Supongo que ya conoces la diferencia entre los ficheros de texto y los binarios. Expresada de un modo simple, los primeros pueden ser leídos empleando un editor de texto plano, como gedit en Linux o el bloc de notas de Windows. Más técnicamente, podríamos decir que los ficheros de texto mantienen una codificación estándar que permite la asociación de cada byte (o un grupo de ellos) con un determinado carácter de texto, mientras que en los binarios el significado de cada byte es determinado por la propia aplicación, pudiendo representar cualquier tipo de entidad.

Ya sabes que para Python todo son objetos y, naturalmente, los ficheros también. Para que podamos interactuar con un fichero, Python crea una abstracción, un objeto, a través del cual se nos ofrece una serie de métodos para que podamos trabajar con él. Hay métodos para leer, escribir o modificar el cursor (la posición en la que se realizará la lectura o escritura), por indicar algunos.

Lo primero que debemos aprender es a crear esa abstracción, el objeto sobre el cual trabajaremos para interacturar con el fichero físico real. Es lo que se conoce como abrir el fichero.

Para hacerlo disponemos de la función open(), que usaremos del siguiente modo:

nombre_del_objeto = open(fichero_real, modo_de_apertura)

nombre_del_objeto es el nombre con el que designaremos la abstracción que envolverá al fichero_real. Dependiendo del valor que indiquemos en modo_de_apertura Python construirá un tipo de objeto u otro y determinará qué tipo de operaciones podemos realizar con él.

Iremos conociendo los distintos modos en los sucesivos artículos, pero por el momento quédate con la idea de que, cuando no se especifica un modo, Python sobreentiende que se trata de un fichero tipo texto y que sólo vas a realizar operaciones de lectura. Esto es justo lo que pretendemos lograr hoy, ser capaces de leer el contenido de un archivo de texto.

Créate un fichero de pruebas y abre un intérprete de comandos en el mismo directorio.

En este ejemplo, he creado el fichero pruebas.txt, con el siguiente contenido:

Comienza el fichero con una mención a la casa de la pradera.
La segunda línea suele hallarse después de la primera.

Esta es la cuarta línea, en la tercera había una línea en blanco.
Es una verdadera lástima que esta sea la última línea.

Observa que se trata de un fichero de cinco líneas en el que he dejado la tercera expresamente en blanco.

Para leer el fichero, la primera acción a realizar es, como hemos visto, abrirlo:

>>> fichero = open('pruebas.txt')

He elegido como nombre del objeto, fichero, sin complicarme la vida más. Entre comillas, como argumento de la función open() figura el nombre del archivo. Si no se encontrase en el mismo directorio en el que hemos ejecutado Python, deberíamos especificar su path completo.

Recuerda lo dicho anteriormente: si no indicamos un segundo parámetro con el modo de apertura, se sobreentiende el siguiente: texto y lectura.

Si tienes curiosidad por saber qué tipo de objeto ha creado Python, pregúntaselo:

>>> type(fichero)
<class '_io.TextIOWrapper'>

Que es algo así como un «envoltorio de entrada y salida texto».

Existen diversas formas de leer el fichero. Una de ellas es aprovecharnos de una particularidad muy interesante: podemos iterar sobre un fichero de texto recorriéndolo línea a línea, de modo semejante al que iteramos recorriendo una lista de principio a fin con el bucle for.

Ensayemos lo siguiente:

>>> for linea in fichero:
  print(linea)

  
Comienza el fichero con una mención a la casa de la pradera.

La segunda línea suele hallarse después de la primera.

Esta es la cuarta línea, en la tercera había una línea en blanco.

Es una verdadera lástima que esta sea la última línea.

Salvo por el detalle de que ha intercalado una línea en blanco adicional entre cada línea, el resultado es bastante decente.

Enseguida veremos cómo solucionar esto, pero antes necesito que observes un comportamiento curioso.

Vamos a intentar iterar una segunda vez y veamos qué ocurre:

>>> for linea in fichero:
  print(linea)

  
>>> 

No ha devuelto absolutamente nada. La iteración está agotada.

Python, paralelamente al proceso de lectura, actualiza un cursor indicando cúal es el siguiente elemento a leer. Como ya ha llegado al final, un nuevo intento de lectura fracasa, pues no hay nada más que leer.

¿Significa esto que no podemos leer un fichero varias veces? En absoluto. Existe un método que nos permite mover el cursor de lectura al punto deseado.

>>> fichero.seek(0)
0

Esta instrucción nos posiciona nuevamente al comienzo del fichero (carácter en la posición 0). La trataremos con detalle en otro momento, pero por ahora es suficiente con que retengas este uso.

Ya estamos en condiciones de realizar una segunda lectura, pero esta vez lo haremos sin que se impriman las líneas en blanco adicionales.

¿A qué se debe que haya dos líneas en blanco?

Python distingue una línea de otra terminándola con el carácter de nueva línea (\n). Pero, además, la función print() agrega siempre, por defecto, otro carácter de fin de línea al final, de modo que cada impresión queda separada de la anterior en una línea diferente. Por eso encontramos los dos saltos de línea: el que trae cada línea propiamente dicha más el que agrega la función print().

Para esta segunda lectura vamos a modificar la función print(), agregando un parámetro con el carácter o caracteres que deseamos que agregue al final de cada impresión, en lugar de la opción por defecto, el salto de línea. Para indicar que no queremos que agregue nada, el uso de print() debe ser el siguiente:

print(linea, end='')

De modo que nuestra iteración por líneas ahora produciría el resultado deseado:

>>> for linea in fichero:
  print(linea, end='')

  
Comienza el fichero con una mención a la casa de la pradera.
La segunda línea suele hallarse después de la primera.

Esta es la cuarta línea, en la tercera había una línea en blanco.
Es una verdadera lástima que esta sea la última línea.

Voy a presentarte a continuación un método interesante que te permite leer el fichero de una sola vez: read().

Posiciónate de nuevo al comienzo del fichero, que habrá quedado exhausto tras la lectura anterior.

>>> fichero.seek(0)
0

Y ejecuta esta nueva instrucción:

>>> fichero.read()
'Comienza el fichero con una mención a la casa de la pradera.\nLa segunda línea suele hallarse después de la primera.\n\nEsta es la cuarta línea, en la tercera había una línea en blanco.\nEs una verdadera lástima que esta sea la última línea.\n'

Devuelve un string muy largo con el contenido del fichero (probablemente tendrás que usar la barra de desplazamiento al ver esto en el navegador, pues el contenido se muestra en una única línea).

Lo importante es que se aprecia bien la estructura del fichero, con los \n separando cada línea. Fíjate también en la línea en blanco, en la posición donde está el \n\n.

Naturalmente, esta salida la obtienes a través del intérprete interactivo. Si quieres ver el resultado en un programa tendrás que usar la función print() para mostrarla.

>>> fichero.seek(0)
0
>>> print(fichero.read())
Comienza el fichero con una mención a la casa de la pradera.
La segunda línea suele hallarse después de la primera.

Esta es la cuarta línea, en la tercera había una línea en blanco.
Es una verdadera lástima que esta sea la última línea.

Una lectura con read(), al igual que la iteración, deja exhausto el fichero, posicionando el cursor de lectura al final de todo:

>>> fichero.read()
''

Presta mucha atención a esto: la cadena vacía » es el indicativo que tiene Python para detectar que ha llegado al final del archivo, hecho que podremos utilizar en nuestro código a la hora de hacer lecturas.

Otro método que debes conocer es readline() que, a diferencia del anterior, que realiza una lectura completa, recupera cada línea de una en una:

>>> fichero.seek(0)
0
>>> fichero.readline()
'Comienza el fichero con una mención a la casa de la pradera.\n'

Como el cursor estará posicionado al comienzo de la línea siguiente, cada nueva ejecución de readline() nos recuperará la línea adecuada:

>>> fichero.readline()
'La segunda línea suele hallarse después de la primera.\n'
>>> fichero.readline()
'\n'
>>> fichero.readline()
'Esta es la cuarta línea, en la tercera había una línea en blanco.\n'
>>> fichero.readline()
'Es una verdadera lástima que esta sea la última línea.\n'
>>> fichero.readline()
''

Observa nuevamente la cadena vacía para indicar que ya hemos alcanzado el final del archivo.

A continuación, uno de mis metodos favoritos: readlines(), como el anterior, pero esta vez en plural.

Este método devuelve una lista en la que cada elemento es una línea del fichero:

>>> fichero.seek(0)
0
>>> fichero.readlines()
['Comienza el fichero con una mención a la casa de la pradera.\n', 
'La segunda línea suele hallarse después de la primera.\n', 
'\n', 
'Esta es la cuarta línea, en la tercera había una línea en blanco.\n', 
'Es una verdadera lástima que esta sea la última línea.\n']

Asocia su salida a una variable y en una única lectura tendrás una lista que podrás manipular tranquilamente a tus anchas sin preocuparte de cursores.

Para finalizar, una vez hemos terminado de usar el objeto fichero, debemos proceder a cerrarlo, liberando así la memoria que estaba consumiendo y rompiendo el vínculo con el fichero real.

>>> fichero.close()

A partir de ahí, nuestra abstracción fichero dejará de estar disponible. Si necesitaras volver a hacer uso del archivo deberías abrirlo nuevamente.

Suficiente por hoy. No olvides las tres erres: read, readline y readlines.

Javier Montero Gabarró


Python: Aprendiendo a leer


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Python: Hace falta valor

Objetivo: entender cómo responde Python ante la modificación in situ de un objeto.

Hace unos días te presenté un fenómeno cuya comprensión era esencial para entender el modelo de memoria de Python basado en referencias. Quiero mostrarte hoy otro directamente relacionado con él.

Voy a proponerte un problema que te ayudará a testear tu conocimiento sobre Python…

Partamos de alguna operación que modifique in situ el valor de un objeto. Sin ir más lejos, tomemos, por ejemplo, el recientemente aprendido método reverse() para invertir una lista:

>>> a = [1, 2, 3]
>>> b = a.reverse()

Mi pregunta es la siguiente: ¿qué valor crees que tiene la variable b?

Recuerda que el método reverse() invierte la lista in situ (para hacerlo creando un objeto diferente recurríamos al slicing).

¿Crees que b tendrá por valor [3, 2, 1]? Se realiza la inversión y acto seguido b toma ese valor, de modo que a b le corresponde un valor de [3, 2, 1] también, como a.

O, por el contrario, ¿valdrá b, a pesar de todo [1, 2, 3]?

¿Qué piensas?

¿Sabes ya la respuesta sin comprobarla en el intérprete interactivo?

¿Por qué crees que sucede así?

¿Pondrías tu mano en el fuego?

Lamento decirte que, tanto si has elegido la primera opción como si has optado por la segunda te has equivocado completamente.

Veamos la respuesta al problema mostrando el valor de ambas variables tras la operación:

>>> a = [1, 2, 3]
>>> b = a.reverse()
>>> 
>>> a
[3, 2, 1]
>>> b
>>> 

Sorpresa: la variable b no tiene ningún valor, lo que equivale a decir que es None.

>>> type(b)
<class 'NoneType'>

Este fenómemo lo has tenido siempre delante de tus narices, aunque con mucha probabilidad te haya pasado desapercibido.

Por ejemplo, observa cómo responde el intérprete interactivo después de cualquier operación que implique la creación de un nuevo objeto:

>>> 2+3
5
>>> 'pradera'[0:3]
'pra'
>>> [1, 2, 3][::-1]
[3, 2, 1]
>>> 

Es decir, devuelve el resultado de esa operación. Si hubiésemos asignado una variable a esa operación, su valor sería precisamente ese.

Pero presta mucho atención qué sucede ante operaciones in situ, que actúan sobre el propio objeto:

>>> [1, 2, 3].append(4)
>>> [1, 2, 4].reverse()
>>> 

¡Python no devuelve absolutamente nada! O, lo que es lo mismo, devuelve el valor None.

No se trata de ningún bug de Python, sino una consideración de diseño refinadísima.

Python está diseñado expresamente así, de modo que, explícitamente, cada vez que una operación de cualquier tipo modifique in situ un objeto, no se devolverá ningún valor.

Por eso la variable b, en nuestro problema, no toma ningún valor. La inversión de la lista, desde luego, ha hecho su efecto en a, pero no hay valor devuelto por esta inversión.

Hace falta valor para tomar una decisión así, pero es algo absolutamente coherente con el modelo de memoria de Python. De no hacerlo, el sistema entero cojearía en operaciones encadenadas que combinasen modificaciones in situ con creaciones de nuevos objetos: sólo podemos encadenar operaciones (por ejemplo, ejecutando un método que actúe sobre el resultado de otro) cuando esas operaciones impliquen la creación de nuevos objetos. Si en cualquiera de ellas hay una modificación in situ no habrá valor devuelto.

En nuestro pequeño problema, la forma correcta de proceder sería esta:

>>> a = [1, 2, 3]
>>> a.reverse()
>>> b = a
>>> a
[3, 2, 1]
>>> b
[3, 2, 1]

Es decir, invertimos la lista a y sólo después realizamos la asignación de b, una vez a ha sufrido su mutación in situ.

Un pequeño precio a pagar que asegura coherencia y claridad en el código.

Javier Montero Gabarró


http://elclubdelautodidacta.es/wp/2012/10/python-hace-falta-valor/


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Problemas en las suscripciones por correo electrónico

Parece que al fin se han solucionado los problemas del plugin que se ocupa de la gestión de las suscripciones al blog a través del correo electrónico, que ha ocasionado que, durante una semana, se dejasen de recibir los mensajes con los nuevos artículos publicados.

He instalado una nueva versión de Jetpack que presumiblemente corrige el problema. Si recibes un correo con este texto será una buena señal…

Javier Montero

PD: Aprovecho para recordarte que los artículos de programación no se formatean adecuadamente en los mensajes del correo, por lo que te recomiendo que los leas directamente en el blog, en el que utilizo técnicas especiales para preservar el aspecto del código fuente.

Python: El mundo al revés

Objetivo: aprender a invertir secuencias en Python.

¿Cansado de que tu nombre figure siempre en las últimas páginas de las listas de resultados de exámenes? ¿No has podido renovar el DNI después de varias horas esperando en una cola? Si es así, necesitas leer este artículo cuanto antes.

Voy a mostrarte cómo invertir secuencias en Python, ponerlas patas arriba y presentarlas al revés.

Comencemos considerando una cadena de caracteres cualquiera:

>>> a = 'pradera'

La técnica para invertir secuencias se basa en los slices, que ya deben resultarte familiares si has leído los artículos anteriores.

Repasemos su sintaxis:

secuencia[i:j:k]

El primer parámetro indica el índice de comienzo del trozo y el segundo el final, pero sin incluir. El tercero es opcional y, cuando está presente, indica el incremento con el que recorreremos el camino entre el principio y el fin.

Veamos algunos ejemplos:

>>> a[0:3]
'pra'

Hemos cortado un fragmento que abarca desde el carácter que tiene por índice 0 (es decir, el primero), hasta el que tiene 3 sin incluir (esto es, hasta el índice 2).

El siguiente slice hace uso de los tres parámetros:

>>> a[1:6:2]
'rdr'

Para comprenderlo, extrae primero el fragmento que correspondería a [1:6]:

'rader'

Y ahora recorre la secuencia de dos en dos, empezando por el primero:

'rdr'

El siguiente ejemplo muestra la omisión del primer parámetro, indicando que comenzamos desde el principio:

>>> a[:4]
'prad'

O del segundo, lo que significa que sigue hasta el final:

>>> a[3:]
'dera'

O de ambos:

>>> a[:]
'pradera'

Recuerda que ya presentamos esta última técnica como método para duplicar una secuencia.

Visto este pequeño repaso, lo que nos interesa muy particularmente es el caso en el que el tercer parámetro del slice es negativo. Eso significa que el fragmento se extrae no de izquierda a derecha, sino al revés, de derecha a izquierda.

Observa el ejemplo:

>>> a[5:1:-1]
'reda'

Analicemos esto con cuidado esto para asegurarnos de que lo entendemos bien:

Lo primero que quizás te llame la atención es que el primer parámetro es mayor que el segundo. Esto es así debido a que estamos recorriendo la secuencia de derecha a izquierda. El índice de comienzo siempre será más alto (o al menos igual) que el índice de destino.

Comenzamos el corte hacia atrás desde el carácter que tiene por índice 5: ‘r’.

¿Y dónde terminamos? En el inmediatamente anterior al indicado en el segundo parámetro. Puesto que estamos recorriendo la secuencia al revés, el anterior del índice 1 no es el índice cero sino 2: ‘a’.

Y ahora sí, tomamos de derecha a izquierda todos esos caracteres, desde un extremo hasta el otro:

'reda'

Ya estás en condiciones de entender lo que hace esto:

>>> a[::-1]
'aredarp'

Es nuestro buscado string invertido.

Como no fijamos valores iniciales ni finales estamos indicando que actuaremos sobre la cadena completa.

Apréndete bien esta técnica, es el procedimiento básico para invertir secuencias, algo que tendrás que realizar con frecuencia en tu vida como programador.

Naturalmente, con las listas (un tipo de secuencias) otro tanto de lo mismo:

>>> a = [1, 2, 3]
>>> a[::-1]
[3, 2, 1]

Es muy importante que tengas siempre presente que el slicing siempre genera un objeto nuevo. Con los strings puede parecer obvio, ya que son inmutables, pero quizás no tanto con las listas, que no lo son (pueden modificarse in-situ).

Constata que la lista sigue siendo la misma:

>>> a
[1, 2, 3]

Por último, voy a enseñarte otra técnica muy útil para invertir listas, pero con la particularidad de que realizaremos una operación destructiva, modificando in-situ la lista (aprovechándonos de su mutabilidad): el método reverse().

>>> a.reverse()
>>> a
[3, 2, 1]

Observa que no ha habido creación de un duplicado, sino que el objeto original ha sido directamente modificado.

La siguiente lista muestra el resultado de una carrera entre varios colegas:

>>> clasificacion = ['Jesús', 'Pedro', 'José Luis', 'Javier']

No es que me importe particularmente quedarme el último pero, si dispongo de recursos, ¿por qué no los habría de utilizar?

>>> clasificacion.reverse()
>>> clasificacion
['Javier', 'José Luis', 'Pedro', 'Jesús']

Ni slicing ni gaitas: he preferido actuar directamente sobre el objeto, destruyendo el anterior.

Y ahora eso ya tiene otra pinta, ¿somos pythonistas o no?

Javier Montero Gabarró


Python: El mundo al revés


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Construcción de acordes – 20: Sexta con novena

Objetivo: presentar la fórmula del acorde de sexta con novena y aprender a deducir las notas que lo constituyen.

En los últimos artículos hemos estado entretenidos agregando novenas a algunas cuatriadas (o tétradas, según prefieras llamarlas), formando así acordes de cinco notas (péntadas). En estas formaciones la séptima siempre ha estado presente, bien como séptima mayor, originando el acorde de séptima mayor con novena, o como séptima de dominante, construyendo las variantes de séptima con novena, con novena aumentada y con novena menor.

Pero las séptimas no son las únicas cuatriadas que pueden merecer novenas. Podemos partir de un acorde de sexta (la tríada mayor, a la que le sumábamos una sexta), al cual le agregaríamos la novena, obteniendo así el acorde objeto del artículo de hoy.

Si el acorde de sexta tiene por fórmula

1 – 3 – 5 – 6

el de sexta con novena será:

1 – 3 – 5 – 6 – 9

Este acorde suele indicarse como 6/9, 6(9), o incluso 6add9.

Lo importante a comprender es que la séptima no está presente. En los casos en los que esté, veremos más adelante que nos referiremos a ellos como de 13ª, decimotercera (una octava por encima de la sexta), o trecena.

Calculemos ahora, como no, nuestros dos ejemplos típicos: C6/9 y A6/9:

Las escalas mayores respectivas son:

Do mayor: C – D – E – F – G – A – B – C – D

La mayor: A – B – C# – D – E – F# – G# – A – B

Si tomamos los grados indicados en la fórmula obtenemos los acordes buscados:

C6/9 --> C - E - G - A - D

A6/9 --> A - C# - E - F# - B

Otro acorde más para la colección. Búscalo en tu instrumento, interiorízalo y hazlo tuyo usándolo. Si eres guitarrista, al igual que sucede con el resto de las péntadas, probablemente tendrás que omitir alguna nota para poder construirlo. Ya lo sabes, la quinta es el primer grado del que podemos prescindir sin perjudicar la cualidad del acorde.

Javier Montero Gabarró


http://elclubdelautodidacta.es/wp/2012/09/construccion-de-acordes-20-sexta-con-novena/


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Índice de todos los artículos de armonía.

XXIV Carrera Nocturna del Guadalquivir – 2012 Sevilla

Fiel a mi cita con el destino, acudí una vez más a la gran carrera multitudinaria sevillana. Más de quince mil corredores con dorsal, más un buen número incontable sin él, nos juntamos en una noche ideal.

Hay veces en las que uno hace las cosas con una especie de piloto automático, un programa que dirige nuestras acciones y que, aunque seamos consciente de él, no podemos modificar su curso.

Es lo que me sucede con esta carrera. Me daba igual que la noche amenazara lluvia o el estado físico en que me pudiera encontrar. Correría y punto.

Lo he dicho muchas veces: la Nocturna del Guadalquivir, junto a la San Silvestre vallecana en Madrid, fueron los motivantes que me empujaron a correr. Volver a estar en ellas reafirma mi compromiso.

No me gusta utilizar el coche en la ciudad, pero opté por cogerlo para desplazarme hasta el estadio olímpico, lugar en el que finalizaría la prueba. No me resultaba atractiva la idea de andar tres kilómetros de vuelta a casa después de doce corriendo. El año anterior lo hice así y me supuso una tiritera tremenda por enfriamiento.

En el camino hacia el punto de salida escuché a un veterano en estas lides transmitiendo su experiencia a otros más jóvenes que lo acompañaban. Contaba que había participado en todas las ediciones de esta carrera y que en la primera de ellas, hace ya veinticuatro años, apenas se registraron algo más de un centenar de participantes.

Al rato oí que alguien me llamaba: era José Luis «JLRodriguez», compañero de desventuras en el foro de atletismo con el que compartí el año pasado la salida en la nocturna. Le acompañaba Javier «alavejezviruelas», otro forero con el que he trabado conversación en ocasiones, pero que no tenía el placer de conocer en persona. Le pedimos a otro amable corredor que nos echara una foto para inmortalizar el momento.

Llevaba meses desconectado del foro, así que me puse al día de sus planes y progresos individuales. Mi tocayo se estaba preparando para su debut en breve en una maratón. Decía que esta sería su última participación en la nocturna, pues en un acontecimiento con tanta participación resultaba complicado calentar adecuadamente, con el consiguiente riesgo de lesión.

Decía, con razón, que no solo los músculos, tendones y articulaciones de las piernas debían calentar bien. Era importante que el corazón (otro músculo) no fuera sometido a un incremento brusco en sus pulsaciones. Un calentamiento suave era la mejor manera de prepararlo para el esfuerzo posterior.

Programé a ForeRundy, mi reloj deportivo, para que como mínimo me llevara a meta a un ritmo de 6:30 /Km. Lo había decidido así hace ya un par de semanas: quería una carrera orientada fundamentalmente al disfrute y sin grandes esfuerzos físicos. Era un ritmo más lento incluso que el que sigo habitualmente en los entrenamientos (entre 6:00 y 6:15), y bastante distante del que mantengo en competición (entre 5:10 y 5:30), pero quería terminar la carrera con muy buenas sensaciones.

A las diez de la noche, aproximadamente, dio comienzo de la carrera y me despedí de mis compañeros para que se dejaran la piel en ella (con excelente resultado, como luego pude comprobar).

Al momento supe que 6:30 iba a ser demasiado lento y rectifiqué la estrategia para correr a 6 minutos por kilómetro, lo que me situaría en meta en algo más de una hora. Solo por debajo de ese ritmo comienzo a tener sensación de sufrimiento, pero con él me parece que podría estar corriendo horas y horas sin detenerme.

Durante todo el trayecto estuve muy concentrado. En un momento dado escuché a alguien decir que ya llevábamos 7 Km. Se me había hecho tremendamente corto y la sensación era la misma que si hubiera empezado a correr. Normalmente, en competición, suele ser a partir de este punto cuando activo el modo SUFRIMIENTO ON, corriendo en agonía el resto de la prueba. Pero esta vez, a ese ritmo tranquilo, me daba la sensación de estar paseando.

El momento visual más impactante fue el paso por el túnel de la calle Arjona, completamente iluminado y mostrando una masa multicolor impresionante de corredores. Me arrepentí de no sacar el móvil y grabar un vídeo. Fue en su salida, tras la cuesta arriba, el único momento de sofoco, pero en pocos segundos logré recuperar el equilibrio mantenido hasta entonces.

Una vez cruzamos el puente de la Barqueta, el par de kilómetros restantes me resultaron cortos también; el año anterior me parecieron eternos.

Entramos en el estadio olímpico por el túnel norte y completamos una vuelta a la pista de atletismo, donde alcancé la meta en una hora y nueve minutos, para una distancia total, según mi reloj, de 11.260 metros, a los que habría que añadir otros 200 o 400 más en los que el GPS perdió la conexión dentro del túnel.

Con excelentes sensaciones físicas, pero triste. Porque todo llega y todo se acaba en la vida, como si una parte de mi quisiera aún seguir en la carrera, con el reloj detenido y atrapado para siempre en el kilómetro siete.

Javier Montero Gabarró


http://elclubdelautodidacta.es/wp/2012/09/xxiv-carrera-nocturna-del-guadalquivir-2012-sevilla/


Puedes consultar el índice completo de artículos pertenecientes a la categoría running.


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta

LaTeX: Generación de bibliografías con thebibliography – 2

Objetivo: aprender a generar bibliografías en LaTeX utilizando el entorno thebibliography (segunda parte).

En el artículo anterior aprendimos a generar una bibliografía en \LaTeX mediante el entorno thebibliography. Nos ocupamos de la tarea más ardua: la creación de la bibliografía en sí. Si no tienes frescos estos conceptos, permíteme recomendarte su relectura previa, te llevará solo un par de minutos.

Nuestra siguiente labor consistirá en aprender a citar la bibliografía dentro del cuerpo del documento, de modo que cuando alguien lo lea y encuentre esa referencia, pueda consultar el índice bibliográfico para localizar la entrada a la que hace mención.

Para lograr esto \LaTeX nos ofrece el comando \cite, al que facilitaremos, entre corchetes, la etiqueta que hemos empleado al generar cada entrada bibliográfica con \bibitem.

Refresquemos el entorno que utilizamos en esa generación:

\begin{thebibliography}{a}
\bibitem{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007  
\bibitem{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca}
1ª ed. Madrid: Naturalistic, 2010 
\end{thebibliography}

El parámetro que pasamos entre corchetes al comando \bibitem es, precisamente, la etiqueda que necesitamos en esta fase.

Ahora, simplemente, introducimos \cite, con esa etiqueta, en el punto justo donde queremos que se produzca la referencia. Localiza en el fichero .tex los dos \cite que he incluido:


\documentclass{article}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\begin{document}
Una de las razones por las que es conveniente enumerar las páginas 
al generar informes es por el efecto altamente hipnótico que produce 
en la mente del paciente quien, al verse privado de un soporte formal 
en el que volcar sus fantasías, recurre a mecanismos de fijación 
periféricos.\cite{pradery}

No debe sorprendernos, por lo tanto, que cada vez  se registren más casos 
de fetichismo peluchil \cite{old}, pues bien es sabida la asociación entre 
este tipo de comportamientos y la negación obsesiva de la realidad.

\begin{thebibliography}{a}
\bibitem{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007.  
\bibitem{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca.}
1ª ed. Madrid: Naturalistic, 2010. 
\end{thebibliography}
\end{document}

Va a ser necesario compilar dos veces el fichero .tex para obtener el pdf final. Durante la primera compilación se resuelven las referencias, pero no es hasta la segunda cuando aparece el resultado. Si observas con cuidado, después de procesar el fichero por primera vez, verás que en el lugar donde deberían figurar las citas aparecen interrogaciones.

Tras la segunda compilación obtenemos, finalmente, nuestras citas perfectamente insertadas:

Si hubiésemos generado la bibliografía para que presentara índices tipo texto, en lugar de los numéricos por defecto, las citas aparecerían adaptadas en consonancia automáticamente.


\documentclass{article}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\begin{document}
Una de las razones por las que es conveniente enumerar las páginas 
al generar informes es por el efecto altamente hipnótico que produce 
en la mente del paciente quien, al verse privado de un soporte formal 
en el que volcar sus fantasías, recurre a mecanismos de fijación 
periféricos.\cite{pradery}

No debe sorprendernos, por lo tanto, que cada vez  se registren más casos 
de fetichismo peluchil \cite{old}, pues bien es sabida la asociación entre 
este tipo de comportamientos y la negación obsesiva de la realidad.

\begin{thebibliography}{aaaa}
\bibitem[Old]{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca.}
1ª ed. Madrid: Naturalistic, 2010. 
\bibitem[Prad]{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007.  
\end{thebibliography}
\end{document}

Si lo deseamos, podemos facilitar información adicional en la cita, por ejemplo, para indicar el número de la página en que se localiza. Para ello, agregamos un argumento opcional (por lo tanto, entre corchetes) al comando \cite con esa información:

\cite[información adicional]{etiqueta}

Por ejemplo:


\documentclass{article}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\begin{document}
Una de las razones por las que es conveniente enumerar las páginas 
al generar informes es por el efecto altamente hipnótico que produce 
en la mente del paciente quien, al verse privado de un soporte formal 
en el que volcar sus fantasías, recurre a mecanismos de fijación 
periféricos.\cite[pág. 856]{pradery}

No debe sorprendernos, por lo tanto, que cada vez  se registren más casos 
de fetichismo peluchil \cite[pág. 32]{old}, pues bien es sabida la asociación 
entre este tipo de comportamientos y la negación obsesiva de la realidad.

\begin{thebibliography}{aaaa}
\bibitem[Old]{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca.}
1ª ed. Madrid: Naturalistic, 2010. 
\bibitem[Prad]{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007.  
\end{thebibliography}
\end{document}

Para finalizar mostraremos cómo modificar a nuestra voluntad el título de la bibliografía si no nos gusta la opción por defecto. Recuerda lo que dijimos en la primera parte: en un artículo se denomina Referencias, como puedes apreciar en los ejemplos anteriores, mientras que en un libro o informe el título es Bibliografía.

Para renombrar la bibliografía vamos a presentar un comando al que recurriremos en otras ocasiones cuando necesitemos modificar otros títulos por defecto:

\renewcommand

El comando exacto va a depender de si estamos usando la clase artículo:

\renewcommand{\refname}{nuevo título}

o la clase libro o informe:

\renewcommand{\bibname}{nuevo título}

Supongamos que, en nuestro ejemplo (artículo), deseamos cambiar el título Referencias por Bibliografía.

Basta con agregar en el cuerpo del documento (no en el preámbulo) el siguiente comando:

\renewcommand{\refname}{Bibliografía}

Observa el código completo junto al resultado final:


\documentclass{article}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\begin{document}
\renewcommand{\refname}{Bibliografía}
Una de las razones por las que es conveniente enumerar las páginas 
al generar informes es por el efecto altamente hipnótico que produce 
en la mente del paciente quien, al verse privado de un soporte formal 
en el que volcar sus fantasías, recurre a mecanismos de fijación 
periféricos.\cite[pág. 856]{pradery}

No debe sorprendernos, por lo tanto, que cada vez  se registren más casos 
de fetichismo peluchil \cite[pág. 32]{old}, pues bien es sabida la asociación 
entre este tipo de comportamientos y la negación obsesiva de la realidad.

\begin{thebibliography}{aaaa}
\bibitem[Old]{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca.}
1ª ed. Madrid: Naturalistic, 2010. 
\bibitem[Prad]{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007.  
\end{thebibliography}
\end{document}

Y eso es todo lo que quería contarte. Más adelante veremos una herramienta especialmente útil para los muy bibliógrafos, los que continuamente están insertando bibliografías y necesitan automatizar estas tareas: BibTex.

Y ahora permíteme que me despida y cierre este artículo sin incluir una bibliografía, que esta palabreja está ya martirizando mis neuronas de tanto recurrir a ella en tan corto espacio de tiempo.

Javier Montero Gabarró


LaTeX: Generación de bibliografías con thebibliography – 2


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Índice completo de artículos relacionados con \LaTeX.

Python: Te repites más que el ajo

Objetivo: aprender a contar las veces que un determinado elemento se repite dentro de una secuencia en Python.

Tarde o temprano tendrás la necesidad de saber cuántas veces ocurre una letra o palabra en determinada frase, o las veces que un elemento aparece en una lista o tupla.

Estos tres tipos, strings, listas y tuplas, pertenecen a la categoría de secuencias en Python, y como buenos amigos, comparten una serie de métodos comunes.

Uno de ellos es count(), que nos sirve para saber cuántas veces sucede un elemento dentro de una secuencia.

Imagínate la siguiente lista:

>>> lista = [3, 7, 6, 2, 1, 7, 3, 1, 1, 5]

¿Cuántas veces aparece el número 1? ¿Y el 4?

>>> lista.count(1)
3
>>> lista.count(4)
0

Con las tuplas es exactamente lo mismo.

Consideremos ahora una cadena de caracteres:

>>> frase = 'la casa de la pradera'

¿Cuántas aes hay? ¿Cuántas veces está la cadena ‘la’?

>>> frase.count('a')
6
>>> frase.count('la')
2

Voy a proponerte un problema para que lo madures. Toma la cadena s = 'lalalala'

¿Qué crees que devolverá s.count('ala')? ¿Por qué?

El método count(), aplicado a un string, tiene algunas sutilezas más respecto a su versión para listas o tuplas. Hablaremos de ellas en otro momento.

Anoche, mientras trabajaba en un programa, me encontré con una lista de 325 strings en la que sabía a ciencia cierta que deberían haber sido 324. Uno de ellos estaba duplicado y era preciso saber cuál.

Hay muchas maneras de resolver este problema sencillo, sin necesidad de ponerme a buscar a pelo de uno en uno. Una de ellas emplea el método count().

for elemento in lista:
    if lista.count(elemento) > 1:
        print(elemento)

Recorremos de principio a fin la lista con un bucle for y en cada parada hacemos una comprobación: si el número de veces que aparece ese elemento es mayor que uno, lo mostramos.

Tras lo cual apareció el polizón (que, naturalmente, se mostró dos veces) y pude deshacerme de él.

Javier Montero Gabarró


Python: Te repites más que el ajo


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Comienza la temporada 2012 – 2013: preparados para la lucha

El comienzo de temporada es una decisión personal de cada corredor. A mí me gusta entenderla una vez finalizan los rigores del verano, estación en la que me limito, deportivamente hablando, a poco más que sobrevivir sin perder demasiada forma física.

Ayer inaguramos el otoño y con él un nuevo ciclo de desafíos y superación personal. Una nueva ocasión de demostrarnos que, aunque seamos un año más viejos, seguimos cogiendo el pulso a la vida, dando lo mejor de nosotros mismos, con la convicción de que no hay lugar, por lejano que pueda parecer, al que nuestras piernas no puedan llevarnos, y que no hay reto que no podamos lograr, aunque eso suponga descubrir los límites de nuestra capacidad física y mental.

En Sevilla inauguramos la temporada con una clásica manifestación multitudinaria. El próximo viernes, 28 de septiembre de 2012, a las 22 horas, dará comienzo la vigésimo cuarta edición de la carrera Nocturna del Guadalquivir, prueba que suele reunir a más de 20.000 corredores.

Hoy he realizado mi penúltimo entrenamiento antes de la carrera. No he tenido pereza para levantarme un domingo a las 7.30 de la mañana, aún de noche, para echarme a correr.

A luchar se aprende luchando; no hay otro camino.

9’45 Km; 57′ 30»; 6:05 /Km

Javier Montero Gabarró


Comienza la temporada 2012 – 2013: preparados para la lucha


Puedes consultar el índice completo de artículos pertenecientes a la categoría running.


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta

LaTeX: Generación de bibliografías con thebibliography – 1

Objetivo: aprender a generar bibliografías en LaTeX utilizando el entorno thebibliography.

En el artículo anterior esbozamos las opciones disponibles a la hora de citar bibliografía con \LaTeX. Hoy hablaremos sobre la más básica, lo que no significa que sea precisamente la menos interesante, pues es la que ofrece una mayor flexibilidad a la hora de crear su estructura.

Deja que te presente el entorno thebibliography, con el que aprenderemos a realizar las siguientes tareas:

  1. Insertar una bibliografía, habitualmente al final del documento.
  2. Personalizar el índice de cada entrada (¿queremos que sea numérico o un texto de nuestra elección?).
  3. Referenciar los elementos de la bibliografía desde el cuerpo del texto.
  4. Mostrar, si es preciso, información adicional en la referencia (como el número de página en que se localiza la cita en cuestión).
  5. Modificar el título de la bibliografía, en el caso de que no nos convenza el que ofrece \LaTeXpor defecto.

Nos ocuparemos de los dos primeros puntos en este artículo y dejaremos los tres restantes para el siguiente.

He preparado un texto simple que nos servirá para la realización de las prácticas (no trates de buscarle un significado):

Puedes bajarte el fichero .tex correspondiente, por si quieres cargarlo en tu editor, aunque cualquier texto te servirá.

Para incluir una bibliografía, insertamos un entorno thebibliography al final del texto del documento:

\begin{thebibliography}
% Aquí figurará la bibliografía
\end{thebibliography}

Entre medias incluiremos cada entrada bibliográfica, que luego se visualizará precedida por un índice, que por defecto será un número de orden correlativo, aunque podremos personalizarlo con el texto que deseemos (por ejemplo, con el apellido del autor). Ese índice, sea numérico o texto, será el que figurará también en el documento en el lugar donde se realice la cita.

Es necesario un parámetro obligatorio más en la definición del entorno. \LaTeXes muy pulcro y quiere hacerse una idea de antemano de la anchura máxima de índice que va a necesitar. Con esta información, indentará las entradas el espacio justo para lograr una alineación elegante.

Lo curioso es la forma de facilitar ese parámetro. Podría ser un valor numérico indicando el tamaño máximo, pero no lo es. En su lugar, sirve con introducir cualquier secuencia alfanumérica de la anchura máxima.

Por ejemplo, si vas a trabajar con índices numéricos y sabes que, como máximo, vas a necesitar una única cifra (es decir, menos de diez entradas), podrías definir el entorno del siguiente modo:

\begin{thebibliography}{x}

o también

\begin{thebibliography}{7}

Si tuvieras más de diez entradas, pero menos de 100, serviría algo así como

\begin{thebibliography}{99}

o incluso

\begin{thebibliography}{yo}

Si vas a utilizar índices de texto, tendrás que tener en cuenta el tamaño del índice más ancho, y no el número de entradas bibliográficas.

Para incluir cada referencia bibliográfica utilizaremos el comando \bibitem con el siguiente formato:

\bibitem[índice opcional]{etiqueta} texto bibliográfico

Comienza por un argumento opcional (por eso aparece entre corchetes y no entre llaves) que emplearemos para facilitar el índice tipo texto, en el caso de que no deseemos utilizar la opción numérica por defecto de \LaTeX. Le sigue otro obligatorio (entre llaves): una etiqueta que nos servirá para después poder referenciar la entrada desde un cualquier sitio en el documento. Esto es algo que, como hemos dicho, trataremos en el siguiente artículo.

Es muy importante tener en cuenta que el formato de presentación de la entrada es responsabilidad plena nuestra; \LaTeXno tomará ninguna decisión en este sentido, por lo que debes tener claro el orden en el que deseas que aparezca cada elemento, así como su apariencia. No olvides que citar bibliografía tiene su ciencia.

Veamos el código \LaTeXque genera la bibliografía en nuestro ejemplo:

\begin{thebibliography}{a}
\bibitem{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007  
\bibitem{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca}
1ª ed. Madrid: Naturalistic, 2010 
\end{thebibliography}

El fichero biblio-2.tex contiene el código completo con todo lo que hemos hecho hasta ahora.

He utilizado el comando \textsc para escribir el autor en mayusculas pequeñas (small caps) y \textit para que el título aparezca en cursiva.

Observa el índice numérico por defecto, así como el título de la bibliografía: Referencias.

Este título va a depender de la clase empleada: en un artículo es Referencias; en un libro o informe, Bibliografía.

Es más, en un artículo aparece justo después del cuerpo del documento. En un libro o en un informe se generaría una página independiente para la bibliografía.

No te preocupes si el título no te satisface, en el próximo artículo veremos lo fácil que es cambiarlo.

¿Y si no queremos índices numéricos y preferimos otros personalizados? Tan simple como facilitar entre corchetes el nuevo índice deseado:

\begin{thebibliography}{aaaa}
\bibitem[Old]{old} \textsc{Old, L.},
\textit{Confesiones de una oveja bizca.}
1ª ed. Madrid: Naturalistic, 2010. 
\bibitem[Prad]{pradery} \textsc{Montero, J.},
\textit{Metodos matemáticos aplicados a la ganadería.}
3ª ed. Sevilla: Ediciones de la pradera, 2007.  
\end{thebibliography}
\end{document}

He invertido el orden de las entradas para que el índice aparezca por orden alfabético, de modo que se facilite su consulta después. Observa también la definición del entorno, en la que he indicado que voy a utilizar un máximo de cuatro caracteres. Gracias a eso se ha logrado la alineación perfecta. Prueba tú mismo qué hubiera pasado de no haber hecho eso.

Ya hemos terminado lo más laborioso, lo que resta es sencillo. En el próximo artículo veremos cómo citar las entradas bibliográficas desde el cuerpo del documento, a la vez que aprenderemos a personalizar la apariencia de la cita y a modificar el título de la bibliografía si lo estimamos necesario.

Javier Montero Gabarró


LaTeX: Generación de bibliografías con thebibliography – 1


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Índice completo de artículos relacionados con \LaTeX.

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies