lunes, febrero 27, 2006

Más sobre la función timeit


Por Alvaro en el foro python-es en respuesta a "¿El método que acabas de mostrar para medir tiempos se podría hacer con un conjunto de instrucciones y funciones?":

Si viejo. Por ejemplo


X="""
x=4
y=5
z=x*y
"""
from timeit import Timer

Print Timer(X).timeit()

Eso si... Si quieres evaluar el desempeño de una funcion, por ejemplo una
funcion cuadrado te recomiendo:

from timeit import Timer

x="cuadrado(5)"

y="""
def cuadrado(x):
return x*x
"""

print Timer(x,y).timeit()
Tambien podrias incluir dentro de la variable x la definición de la funcion.
Pero eso no seria muy inteligente ya que timeit tambien mediria cuanto se demora en definir la funcion, y eso no es lo que uno quiere.

Por ultimo la funcion timeit tiene un defecto. De que los datos que muestra no son los reales. Lo que hace la clase Timer es simplemente ejecuta una ves lo que le pases como 2do argumento y luego ejecuta un millon de veces (no me acuerdo si es un millon o solo mil veces) lo que le pases como primer argumento, sacando un promedio de cuanto se demoro cada ves que ejecuto el primer argumento. Pero el promedio que saca es cuando "se ejecutan el argumento muchas veces seguido" o dicho de otra forma, con gran estress. Asi que no hay que decir la funcion se demora en ejecutarce 0.55 seg, sino que hay que decir, bajo estress la funcion se demora 0.55 seg.


Para ser mas exactos es mejor no considerar a la funcion timeit como una funcion que mide el tiempo de ejecucion de algo, sino como algo que cuantifique el coste de ejecución de algo y que solo es valido cuando se compara con otra cosa (como por ejemplo cuando comparamos la ejecucion del len con distintos largos de string). Si esto se puede complementar con un

test de hipotesis de comparacion de medias, ideal....





viernes, febrero 24, 2006

Coste de la funcion len() en los strings de Python


Sospechaba que el coste era constante, y según me han comentado así es. Se fija durante la creación de los string, ya que éstos son inmutables.

Su implementación se puede ver aquí.
Y muy interesante la intervención de Alvaro Leiva, en la lista python-es, sobre el modulo timeit (disponible a partir de Python 2.3):


Aparentemente el coste no depende de el tamaño de un string.

En todo caso puedes verlo tu enpiricamente con este programita

from timeit import Timer


x=["a"*10,"a"*100,"a"*1000,"a"*10000]

for i in x*5:
print Timer("len(x)","x='%s'" % i).timeit()

Te daras cuenta que casi siempre te imprime el mismo numero "0.55" en mi
computador....

Esto deja en claro que el coste no depende de el largo del string. No asi
cuando uno ejecuta esto con listas

x=[["a"]*10,["a"]*100,["a"]*1000,["a"]*10000]

for i in x*5:
print Timer("len(x)","x=%s" % i).timeit()

Que arroja siempre valores pequeños de tiempo para ["a"]*10 y los tiempos
siempre son acendentes....

Este metodo del from timeit import Timer siempre lo ocupo cuando tengo una
duda sobre el coste de una funcion... Muy util cuando uno programa
algoritmos de optimisacion lineal como el simplex... Algoritmos famosos por
su tendencia a volverse lentos
Vía barrapunto, veo que The International Obfuscated C Code Contest se sigue celebrando.
Y lo del tatto este es la caña.

jueves, febrero 23, 2006

Aquí se listan los diferentes BOM´s (Byte Order Marks).
Lo mas inmediato para saber tu IP: whatismyip.com.
Comentan en Dirson sobre Google Pages. También la comentan en barrapunto y telendro. Google siempre es noticia...

Autodetección de encodings

He estado buscando un poco en la web sobre el tema... La idea es detectar el encoding sin hacer uso de información existente en declaraciones (del protocolo, lenguaje, ...).

En C++ existe el detector de Mozilla: Mozilla Charset Detectors. (a través de Koders, podemos ver la rama)

En python he encontrado el Universal Encoding Detector. Aquí se explica como funciona (la doc). La librería es un port de la de Mozilla, la cual a su vez se implementó basandose en este articulo: A composite approach to language/encoding detection.
¿Lo que parece que no detecta es ISO-8859-1? Que raro.... (al menos no lo menciona en la documentación).

Antes de encontrar lo que ya he mencionado encontré el siguiente codigo (usando koders):


def autodetect_encoding(self, new_data):
enc = ""
if len(new_data)<5:
# If this is a very short external entity, it may not
# have enough bytes for auto-detection. In that case,
# it must be UTF-8
enc = "utf-8"
elif new_data[:3] == '\xef\xbb\xbf':
enc = "utf-8" # with BOM
elif new_data[:4] == '\0\0\0\x3c':
enc = "ucs-4-be"
elif new_data[:4] == '\x3c\0\0\0':
enc = "ucs-4-le"
# ignore unusual byte orders 2143 and 3412
elif new_data[:2] == '\xfe\xff':
enc = "utf-16-be" # with BOM
elif new_data[:2] == '\xff\xfe':
enc = "utf-16-le" # with BOM
elif new_data[:4] == '\0\x3c\0\x3f':
enc = "utf-16-be"
elif new_data[:4] == '\0\x3f\0\x3c':
enc = "utf-16-be"
elif new_data[:5] == ' # need to wait for encoding attribute, do not try
# to apply a codec until then.
pass
# ignore EBCDIC
else:
# Does not start with enc = "utf-8"
return enc


Y ya para acabar, unos links:
El link del Universal Feed Parser es de obligada lectura.

miércoles, febrero 22, 2006

Usando los niveles del logging de python


Los valores posibles para definir el nivel de trazas ( con setLevel() ) son (sacados de logging/__init__.py):

CRITICAL = 50

FATAL = CRITICAL

ERROR = 40

WARNING = 30

WARN = WARNING

INFO = 20

DEBUG = 10

NOTSET = 0


Con NOTSET se sacan todas las trazas.
Estos son los valores definidos, pero se puede usar cualquier valor numerico

También hay definido un diccionario que realiza el mapeo entre las constantes y su nombre (string): _levelNames.

Actualización

Probando, NOTSET no se saca nada ¿Esa la documentación mal?
Fresqui, noticias Tecnológicas mitad digg mitad barrapunto.

lunes, febrero 20, 2006

Standards Mode y Quirks Mode



Gracias a haberle leido un tutorial sobre encodings en xhtml, me he enterado que los browsers tienen dos modos de visualización:
  • standards mode (fiel a los estándares de la W3C)
  • quirks mode
Se puede pasar de uno a otro mediante el 'doctype switching'. En otras palabras: si el documento incluye el doctype, se visualiza en 'standards'; en caso contrario se visualiza como 'quirks'.
La reglas son diferentes, y por lo tanto el resultado visual también.
Si el documento tiene una declaración ?xml antes del doctype, en el caso de IE, provoca que se visualice en quirks mode.

En la siguiente página hay mas información sobre los diferentes doctypes y como se comportan los diferentes navegadores con ellos: Activating the Right Layout Mode Using the Doctype Declaration.

En la siguiente página se detallan algunas diferencias.

HTML compatility guidelines for XHTML


Son de utilidad para cuando el xhtml es servido como html.
Ricardo Galli: por lo visto es el pollo que está detrás de meneame.
Interesante: Banda ancha para el móvil, lo mejor del 3GSM. Habrá que ver el coste...

viernes, febrero 17, 2006

Detección de encoding en ficheros html/xhtml


Como se indica aquí, en los ficheros html (o xhtml) el encoding debe de estar especificado. Pero la realidad es otra, y es que puede no venir (los estandares especifican uno por defecto) o incluso no corresponderse con el verdadero encoding.

Buscando en la web, no he encontrado nada para hacer la autodetección. Aunque seguire buscando...
Lo único que he encontrado de momento es este thread.
De momento y para salir del paso usaré el comando 'file' de unix.

En los fichero xhtml nos encontramos con una problematica adicional, y es que pueden venir los encodings especificados en el meta y con el este documento, dependerá de su uso, es decir de como se entreguen. Lo cual no deja de ser un problema si el documento lo tenemos en disco y no sabemos como se ha entragado.
Lo que si especifica bien claro es que el encoding de HTTP tiene prioridad (si se indica) sobre el resto.
Y otro link que todavía no he tenido tiempo de mirar...

Actualización
El siguiente tutorial de W3C es muy bueno: Character sets & encodings in XHTML, HTML and CSS.
Y los diferentes valores para el encoding: IANA registry.

miércoles, febrero 15, 2006

Han inventado una pantalla tactil [barrapunto.com] que es la caña.
Aunque barrapunto ha estado lento. Telendro ya lo había publicado hace días.

lunes, febrero 13, 2006

EBITDA


Hoy me han soltado este termino en una reunión de la compañia. Por lo visto es una medida económica para comparar diferentes empresas, o la evolución de una misma en el tiempo.
Mas info en [1], [2] y [3].

viernes, febrero 10, 2006

Me pasa vlady esta web: genbeta. Va de actualidad sobre software. No parece estal mal. Habrá que seguirla... Curioso que lanzan busquedas a través de Noxtrum.
La caña el interfaz éste [telendro.com.es].
Un par de enlaces de barrapunto:

jueves, febrero 09, 2006

Encoding por defecto en xml y html


En XML si no se especifica el encoding, se toma por defecto utf-8, mientras que en html (para text/*) se toma por defecto iso-8859-1.
Para otro tipos de medios, entra en juego la RFP 3023.

Mas información aquí: Determining the character encoding of a feed.

miércoles, febrero 08, 2006

He encontrado un articulo que parece interesante (pero no he leido todavia): The Problem with the Libxml Python Bindings.

Al final del mismo hay un link muy muy interesante: Beware of strangers.
El cual me ha llevado a otros:

Parseando html con libxml2



En primer lugar tengo que comentar que no hay mucha documentación del 'binding' a python de libxml2. Básicamente las alternativas de documentarse son:
  • Tirar de archivos de las listas: [1] y [2]
  • Ver la ayuda: desde el interprete usar 'help(libxml2)' o desde la shell 'pydoc libxml2'.
  • Ver ejemplos. Con la instalación viene alguno.
A continuación pongo un ejemplo que viene con la distribución (pushSAXhtml.py):


#!/usr/bin/python -u
import sys
import libxml2

# Memory debug specific
libxml2.debugMemory(1)

log = ""

class callback:
def startDocument(self):
global log
log = log + "startDocument:"

def endDocument(self):
global log
log = log + "endDocument:"

def startElement(self, tag, attrs):
global log
log = log + "startElement %s %s:" % (tag, attrs)

def endElement(self, tag):
global log
log = log + "endElement %s:" % (tag)

def characters(self, data):
global log
log = log + "characters: %s:" % (data)

def warning(self, msg):
global log
log = log + "warning: %s:" % (msg)

def error(self, msg):
global log
log = log + "error: %s:" % (msg)

def fatalError(self, msg):
global log
log = log + "fatalError: %s:" % (msg)

handler = callback()

ctxt = libxml2.htmlCreatePushParser(handler, "
chunk = " url='tst'>b"
ctxt.htmlParseChunk(chunk, len(chunk), 0)
chunk = "ar"
ctxt.htmlParseChunk(chunk, len(chunk), 1)
ctxt=None

.../...




El poco tiempo que llevo usandolo ya me ha dado para poder reseñar que:
  • Internamente se trabaja con utf-8. Si el encoding viene especificado en el documento no hay problemas. En caso contrario supondrá uno por defecto (no realiza autodetección en este caso). El tema no es nada sencillo, ya que no sólo tenemos este problema, sino que se puede dar el caso de que el encoding no concuerde con lo que viene especificado en la declaración. O incluso que se use más de uno. Vamos una movida... Además en caso de estar parseando xhtml ignora el ?xml. Para xhtml se debería usar el parser xml, pero ¿y si el xhtml no está bien formado? Vamos que aqui hay miga...
  • Desde el callback no podemos parar el parser. La parada hay que hacerla desde fuera. Lo suyo es hacerla entre el paso de un 'chunk' de datos a otro.
  • Con el api de C he visto que el parser te puede notificar que ha habido un problema y que hay que parar, sin embargo esta funcionalidad no es posible en los bindings de python. Según me comenta Daniel Veillard: "The notion of fatal error where the parser stops emitting data (just more error message) exists only in the XML parser." Me parece muy bien, pero esto no explica porque existe esa funcionalidad en el api de C. En los links del post hay un ejemplo de ésto.

Y para acabar unos enlaces interesantes:

martes, febrero 07, 2006

Un thread en el que se indica porque python está indicado para el desarrollo de crawlers.
En dicho thread comentan sobre google-kongulo, un crawler liberado por google y que se usa en su desktop.

Tambien recomiendan como parser BeatifulSoup. Lo que hace es convertir el html a un arbol (no es SAX; ni tampoco DOM).

libxml2 y el encoding


Ando trasteando con libxml2 y ésta página es la que hay que leer con respecto a los encodings.

Ya hace tiempo puse unos cuantos links sobre encodings; y ahora van un par mas extraidos de la página anterior:

Buscando en la web, el único thread que dice algo sobre la autodetección de los encodings para html es éste.

Actualización
Los encodings que soporta son:
  • UTF-8
  • UTF-16 little endian
  • UTF-16 big endian
  • UCS-4 little endian
  • UCS-4 big endian
  • EBCDIC
  • UCS-4 unusual ordering (UCS4_2143)
  • UCS-4 unusual ordering (UCS4_3412)
  • UCS-2
  • ISO-8859-1 ISO Latin 1
  • ISO-8859-2 ISO Latin 2
  • ISO-8859-3
  • ISO-8859-4
  • ISO-8859-5
  • ISO-8859-6
  • ISO-8859-7
  • ISO-8859-8
  • ISO-8859-9
  • ISO-2022-JP
  • Shift_JIS
  • EUC-JP
  • ASCII
Una noticia sobre planes de google para incorporar intersticial (vía telendro). Esta bien además de por la noticia, por el repaso a los diferentes formas de 'advertising'.

lunes, febrero 06, 2006

Para ver los SLDs de los diferentes paises.
Hay un post interesante en ¿Contratación de equipos de desarrollo? [barrapunto.com]
¡Vaya! Nokia usa python. De hecho han liberado código.
Vía barrapunto.

domingo, febrero 05, 2006

El site de Jose Miguel.