miércoles, junio 25, 2008

Desde luego navegapolis me está gustando mucho. Espero sigan en la misma linea...
Su último post: Directivos sin talento.

martes, junio 24, 2008

Futuro de python vs perl

De comp.lang.python: Python 3000 vs Perl 6.

Avances en C++

Aunque hace siglos que no toco C++, hay que estar al tanto..
Veo en el blog de Herb Sutter una entrada sobre unos cambios interesantes: Type Inference vs. Static/Dynamic Typing.

Un cambio en el lenguaje muy prometedor.
Gracias a ese post he llegado a una librería que desconocía: POCO.

Y ya para acabar aquí unos links a unas charlas (que no he visto, pero me gustaría) sobre el futuro de C++.

jueves, junio 19, 2008

Outsourcing

En Ingenieros de Primera tienen un artículo majetón sobre el Outsourcing : Aplicación del Outsourcing en las "Tecnologías de la Información".
Mucho mejor que los de la wikipedia [es][en].

Lo que no definen son algunos de los terminos usados: CIO (este no tengo claro a que se refiere exactamente), ROI, CTO.

martes, junio 10, 2008

refs refs refs

Hacia tiempo que Ian Bicking no publicaba nada. Acaba de publicar un post sobre Erlang.
Lo interesante ya no es el post en si, sino la cantidad de referencia que suelta en él, a saber:
  • Monkey path: "is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, Javascript, Ruby, Perl, and Python) without altering the original source code."
  • Bencode: "is the encoding used by the peer-to-peer file sharing system BitTorrent for storing and transmitting loosely structured data."
  • JSON: "(JavaScript Object Notation) is a lightweight data-interchange format." En dicha página hay muchas referencias sobre JSON y Python.
  • WebOb: "WebOb provides objects for HTTP requests and responses"
Y como no vamos a desvelar todas las cosillas interesantes... pues mas enlaces en el post...

CSV en python

Python tiene un modulo para manejar CSVs: csv [PEP].
Buscando un poco seguro que podeis encontrar otras implementaciones. Está bien que la librería incorpore este manejo de archivos ya que es bastante común.

Una cosa interesante que tiene, son los dialectos. Veamoslo con un ejemplo:


>>> import csv
>>> csv.list_dialects()
['excel-tab', 'excel']

Como podeis ver, el módulo incorpora dos dialectos para escribir/leer csv's del agrado de excel. Y es que hay que decir que no hay un estandar sobre CSV.

El hecho de estar mirando esto es porque estoy implementando un reader y andaba pensando si reutilizar este... En principio estoy por la labor... Si hay algo implementado mejor reutilizarlo ¿no?.
Lo que si que necesito de todas todas es un recubrimiento...
En principio hay dos cosas que me llaman la atención:
  • Si al consctructor del DictReader se le pasan los campos, si el fichero tiene cabecera, la lee como una línea normal ¡Ojo!. Si no se pasan los campos toma la primera linea como claves para el diccionario.
  • El constructor es muy flexible en su uso, a la hora de pasarle los parámetros.
  • El modulo tiene una clase para intentar deducir el formato de un csv: Sniffer.
Veamos un ejemplo:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import csv
import sys


class midialecto(csv.Dialect):
delimiter = 'þ'
quotechar = '"'
lineterminator = '\r\n'
doublequote = True
skipinitialspace = True
quoting = csv.QUOTE_MINIMAL

csv.register_dialect("midialecto", midialecto)


campos = ['campo1','campo2']
f = open("ejemplo.csv","r")

# A descomentar la que mas nos guste
#
#dr = csv.DictReader(f,campos,None,None,'midialecto')
#dr = csv.DictReader(f,dialect='midialecto',fieldnames=campos)
#dr = csv.DictReader(f,dialect='midialecto')


for row in dr:
print row.keys()
print row.values()
sys.exit()


En el anterior ejemplo (descomentar una de las lineas que crean el 'dr') se imprime la primera línea que se lee del fichero, y se aborta.
Con los 3 constructores podemos ver la flexibilidad en la construcción, y como se comporta ante la presencia del argumento 'fieldnames' (si no se pasa => la primera linea se usa para formar las claves del diccionario).
Los parámetros que definen el formateo, pueden pasarse incluso en un diccionario.
Me han comentado en una entrada, y he creido conveniente crear la etiqueta 'lingüística'.
Para que haya contenido sobre el tema ahí van dos links de la wikipedia :p:

jueves, junio 05, 2008

Garbage Collector revisited

He mejorada el programita de marras del post anterior. Ahí va la nueva versión:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
import gc
#gc.set_debug(gc.DEBUG_LEAK) # Será necesario ponerlo para rastrear los leaks
# a no ser que invoquemos explicitamente a collect()

#------------------------------------------------------------------------------
class MiList(list):
def __del__(self):
# El método del nos sirve, aparte de para sacar una traza
# para que el objeto sea uncollectable. Sin el __del__
# el recolector es capaz de recolectarlo correctamente.
print "En el __del__"

#------------------------------------------------------------------------------


# Collectable
print "-----> Collectable"
l = MiList()
del l
print "collect:", gc.collect()
print "garbage:", gc.garbage

#------------------------------------------------------------------------------

# Prueba de que con una lista normal no hay problema
# Pero que curioso que el metodo collect() devuelve 1
print "-----> Con una lista"
l2 = []
l2.append(l2)
del l2
print "collect:", gc.collect()
print "garbage:", gc.garbage

#------------------------------------------------------------------------------


# Uncollecable
# He metido dos instancias, para ver como collect() devuelve 2
# Y aparecen ambos en 'garbage'

print "-----> Uncollectable"
l = MiList()
l.append(l)
#l.pop() -> Con solo meter esto se resuelve el ciclo!!!
del l


l3 = MiList()
l3.append(l3)
del l3

#------------------------------------------------------------------------------

# ¿como ver dichos objetos que con Uncollectable?
print "collect:", gc.collect()
print "garbage:", gc.garbage # uncollectable objects ¡¡¡no muestra nada!!!
# A no ser que activemos por ejemplo el flact DEBUG_LEAK
# O hayamos invocado explicitamente a collect() ¡Ojo!



Por cierto... la faq de python tiene pinta de estar muy bien. Me lo anoto como lectura futura.

Un ejemplo:

4.15 Why isn't all memory freed when Python exits?

Objects referenced from the global namespaces of Python modules are not always deallocated when Python exits. This may happen if there are circular references. There are also certain bits of memory that are allocated by the C library that are impossible to free (e.g. a tool like Purify will complain about these). Python is, however, aggressive about cleaning up memory on exit and does try to destroy every single object.

If you want to force Python to delete certain things on deallocation use the sys.exitfunc() hook to run a function that will force those deletions.

Ejemplo de uncollectable object

Quería mostrar a una compi de curro, como funcionaba el tema del recolector de basuras, con lo cual me hice el siguiente programilla:


#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
import gc
#gc.set_debug(gc.DEBUG_LEAK)

class MiList(list):
def __del__(self):
print "En el __del__"

# Collectable
print "-----> Collectable"
l = MiList()
del l
print "garbage:", gc.garbage

# Uncollecable
print "-----> Uncollectable"
l = MiList()
l.append(l)
#l.pop() -> Con solo meter esto se resuelve el ciclo!!!
del l

# ¿como ver dichos objetos que son Uncollectable?
print "garbage:", gc.garbage # uncollectable objects ¡¡¡no muestra nada!!!
# A no ser que activemos por ejemplo el flact DEBUG_LEAK


Si en el segundo bloque no hacemos el pop() vemos que si ponemos el flag DEBUG_LEAK, nos aparecerá el objeto 'uncollectable' en el atributo 'garbage'.
Por defecto no aparece.
Si se nos da una situación como esta, hay que resolverla a mano.

Lo de hacer el ejemplo con una clase que herede de List, en lugar de hacerlo con listas, es para mostrar cuando se invoca el método __del__.

El método __del__ se invocará antes de que se destruya el objeto, pero ¡ojo! si lo invocamos explicitamente no significa que se vaya a destruir y dicha memoria se vaya a liberar.

Otro apunto sobre la liberación de la memoria en python. La memoria se devolverá al gestor de memoria de python, que no significa que se libere al SO.