Introspecció a Python

Per tenir les dades que genera una aplicació que estic fent amb Python he escrit un parell de funcions que em permeten tenir un document estructurat (en xml) de totes les dades que es generen[1].

La tècnica de introspecció es basa en aprofitar les meta-dades (per dir-ho d’alguna manera) que tens sobre els objectes que has anat construint en l’aplicació per (dinàmicament) poder-ho formatar d’alguna manera.

Amb Python tenim algunes propietats, com molt bé es descriuen en un article d’IBM [2]:

  • objecte.__dict__ : Ens retorna una llista amb els elements que formen part de l’objecte. Així per mostrar els elements faríem:
  • for element in objecte__dict__:
    print “%s val %s” % (element, objecte.__dict__[element])

  • Si volem refinar el que volem mostrar tenim tot un seguit de funcions que ens diuen quin tipus de variable estem tractant: les comparacions amb el comparador is (exemple: if x is dict ….) per als tipus bàsics, callable per saber si és tracta d’un mètode, i per a objectes i classes isinstance(objecte, classe-o-llista-de-classes) i issubclass(classe, info-de-classe).

Només amb això podem treure molt suc a la informació que tenim ara mateix a les estructures de dades que estem muntant i si es fa el més genèric possible, no caldrà tocar ni una coma quan afegim més dades o hi encadenem alguna altra estructura.

[1] En certa manera hi ha truc perquè el sistema són classes que tenen diccionaris de classes a dintre fins a 5 nivells de manera que la introspecció és recursiva per naturalesa.

[2] És una mica vell, del 2002, però pels meus objectius n’he tingut ben prou :)

pas d’arguments amb Python


Per pas d’arguments s’entén que quan crides una funció li dius amb quins valors vols que faci la seva funció.

Per exemple:

suma(3,4) # retorna 7
suma(4,5) # retorna 9

El problema pot passar (com m’acabo de trobar i solucionar) en que si haig de passar força arguments (6 en concret) i a més els haig de redirigir es fa pesat mantenir les llistes d’arguments sincronitzades, per exemple si tenim un parell de classes que una hereda (Secundaria) de l’altre (Principal) i volem cridar el constructor de Principal des del constructor de Secundaria haurem de fer una cosa per l’estil:

class Principal():
def __init__(self, primer, segon, tercer, quart, cinquè, sisé):
/* … operem amb ells …*/
class Secundaria (Principal):
def __init__(self, primer, segon, tercer, quart, cinquè, sisé):
Principal.__init__(primer, segon, tercert, quart, cinquè, sisé)

Per a simplificar-ho Python ens permet diverses coses:

  • valors predeterminats: Si sabem que un valor serà gairebé sempre el mateix i en contades vegades un de diferent podem fer que sigui opcional donant-li un valor des de la declaració de la funció
  • def taula_multiplicar(base, inici=0, final=10): # declarem una funció amb 3 paràmetres dos dels quals ja tenen un valor assignat
    taula_multiplicar(3) # ens mostraria la taula de multiplicar del 3 des de 3*0 fins a 3*10, la típica de l’escola
    taula_multiplicar(4, 5) # ens mostraria la taula del 4 des del 5 fins al 10
    taula_multiplicar(4, 9, 12) # ens mostraria la taula del 4 des del 9 fins al 12

  • llista d’arguments: Si no sabem quants arguments (o no ens importa) podem dir que els agafi tots
  • def crea_directoris(*directoris): # declarem una funció que agafa tots els arguments que li passen i els posa en una llista (tupla en Python)
    crea_directoris(‘/home/gil’, ‘/home/silvia’, ‘/home/softcatala’, ‘/home/gnome’) # ens crearia els 4 directoris que li passem
    llista = ( ‘/home/gil’, ‘/home/silvia’) # creem una llista amb els arguments
    crea_directoris(*llista) # passem la llista enlloc de tot el text en la crida, li indiquem que es una llista amb el símbol *

  • diccionari d’arguments: Si el que volem es enviar les dades però no ens recordem de l’ordre en que estan posats en la declaració (per exemple si fem taula_multiplicar(3,5,7) però volíem la taula del 7 del 3 al 5 ens trobarem amb la taula del 3 del 5 al 7) podem fer servir els noms dels arguments
  • taula_multiplicar(inici=3, final=5, base=7) # ara ja tindrem la taula de multiplicar del 7 des del 3 al 5def parelles(**valors): # declarem una funció en que rebrem parelles de valors
    parelles(un=1, dos=2, tres=3) # passem parelles de paràmetres amb nom amb el seus valors
    diccionari = { ‘un’: 1 , ‘dos’: 2, ‘tres’: 3} # creem un diccionari
    parelles(**diccionari) # enlloc d’haver-ho de posar tot en la crida a la funció creem un diccionari abans i ho indiquem en la crida amb els dos * (igual com en el pas per llista)

També es poden fer coses més sofisticades i complicades com barrejar llistes, diccionaris, valors predeterminats i paràmetres normals, per exemple:

def funcio_estranya( valor_posicional, valor_predeterminat=5, *resta_arguments): # amb aixo creem una funció que el primer paràmetre es un de normal, després en bé un d’opcional i la resta hauran de ser una llista d’arguments variable

No està malament eh :)

Crear un dipòsit de Subversion amb accés per http i per ssh

A la universitat hem de fer una màquina de Turing (català) i com que l’hem de fer en grup crec que la millor manera és posar un servidor de Subversion (hi estic més acostumat, amb git només he fet “git clone $url“).

Així que “dit i fet“:

  • Com que el servidor és un Gentoo aquesta guia m’ha anat que ni pintat, et descriu els passos per tal de configurar un servidor Subversion a la màquina i com fer per permetre que es pugui accedir en mode lectura per web i els usuaris que vulguis en mode lectura i escriptura.
  • Com que a més vull donar accés per SSH (ja que hi estic acostumat del GNOME) només m’ha fet falta seguir aquesta altra guia que ho deixa força clar :)
  • Però aquí no acaba tot, com que la xarxa que tinc muntada al pis de Girona és una mica peculiar, el port de l’SSH no és el predeterminat (22), de manera que aquesta altra guia m’ha resolt els dubtes.

Ara sí, llestos :)

actualitzada la N800

Des de fa dies que l’he tornat a fer servir, més que res per fer-la servir com a PDA més que no pas per navegar per Internet, i ja que durant el cap de setmana vaig actualitzar-me a l’última versió d’Ubuntu, avui tocava actualitzar la N800 :)

Així que després de trobar un cable USB que anés bé i seguir les instruccions ja tinc la N800 a la versió 2008 :D

Per què els fabricants els agrada tocar el que no sona amb els cables USB? Tant marge tenen de beneficis que han d’inventar-se un connector diferent per a cada aparell i a sobre vendre’l apart?? Ahir vaig posar potes enlaire el pis de Molins i ni així vaig poder trobar un cable USB que em servís (i això que en vaig trobar fins a 3 o 4 de diferents de cables USB!)

Millorar el temps d’engegada de l’Ubuntu (II)

Ahir em vaig actualitzar a la nova versió d’Ubuntu, la 8.10 Intrepid Ibex. En l’actualització només em va donar dos errors, que apart de no sé explicatius tampoc em deixaven cap opció més que la d’acceptar.

Així que al cap d’unes hores entre que es baixéssin els paquets i que s’instal·lessin ja tenia l’Ubuntu nou :)

Un cop acabat i comprovat que tot funcionava bé, m’he decidit a millorar el temps d’engegada, i aquest cop he passat de 37 a 27 (2 més que no pas amb la versió anterior).

Com en l’altra vegada, per saber les millores que anava fent vaig utilitzar el bootchart, i els resultats són:

Sense optimitzar

Optimitzat

comparar dues revisions d’un fitxer amb svn

Quan encara no heu confirmat uns canvis en un fitxer que està versionat amb svn podeu utilitzar l’ordre svn status per saber quins fitxers estan modificats i un svn diff $nom_fitxer per veure el canvis respecte l’última vegada que vau actualitzar el dipòsit amb un svn up (o un svn co $url).

Ara bé, si acabeu de fer la confirmació (commit) i voleu agafar-ne el pedaç per aplicar-lo a una altra branca o enviar-lo a algú com ho podeu fer?

La resposta és senzilla un cop la saps, com de costum :)

Primer feu un svn log $nom_fitxer i aquest us mostrarà les revisions en que heu modificat el fitxer de manera que si les revisions són la 35 i la 44 només heu de fer un:

svn diff $url_fins_al_fitxer@35 $url_fins_al_fitxer@44

L’URL del fitxer el podeu trobar fàcilment si feu un svn info i afegiu el tros de camí (path) fins al fitxer.

Si fóssin dos fitxers diferents, que pel motiu que sigui els heu bifurcat en el propi dipòsit (per dir alguna cosa: script_v1.sh i script_v2.sh) en principi no caldria posar tot l’url, sinó que amb els camis en local i @REVISIÓ ja n’hi hauria prou.

Uff, fins a 6 ordres hem necessitat: svn {stats, diff, up, co, log, info}

mètodes virtuals? polimorfisme? delegació? herència?

Aquest tros de codi amb Python:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

class main():
   def laptop(self):
      self.p()

class one(main):
   def p(self):
      print "Lenovo"

class two(main):
   def p(self):
      print "Asus"

# Creem un parell d'instàncies
i_one = one()
i_two = two()

i_one.laptop() # mostra "Lenovo"
i_two.laptop() # mostra "Asus"

El que fa bàsicament és crear 3 classes (dues d’elles –one i two– hereden de la primera –main-) de manera que totes les instàncies que es facin de les classes filles tindran els mètodes de la classe mare (el mètode laptop en aquest cas).

A més cada classe filla defineix una mateixa funció (la funció p).

La gràcia d’aquest disseny és que et permet definir una especialització de comportament de manera que per exemple, si tens una col·lecció d’instàncies de one i two barrejades però vols saber-ne quin portàtil tenen, només cal que executis el mètode laptop a tota la col·lecció que sense cap problema ens dirà per a cada un d’ells quin portàtil té.

El dubte que em queda ara és: quin nom rep aquesta tècnica? Perquè he estat buscant en el llibre de Python que tinc (Learning Python d’O’Reilly) d’on he recordat aquesta possibilitat del Python i no he aconseguit trobar-la ni a l’índex del principi (per temes) ni  el del final (per nom).

I el guanyador és …

Com heu pogut veure els que heu vistat el bloc el tema que m’he posat és l’Ahisma, tot i així en vaig trobar moltíssims i alguns dels millors que vaig veure:

I per a currats currats els següents:

També he aconseguit posar de nou el núvol de categories i he vist que hi ha una utilitat integrada amb el propi WordPress que ja et permet passar les categories a etiquetes, però ara no sé ben bé què utilitzar, al cap i a la fi el sistema és el mateix i si tinc el núvol de categories, per passar a que siguin un núvol d’etiquetes es quedar-me amb el mateix.

El que sí tinc pensat canviar és el tema, potser li canviaré algun coloret i sobretot (intentaré almenys) que compleixi els estàndards que ara mateix es passa per alt (html i css)

guifi.net, escollit com a nou “Living Lab” per la Unió Europea

Per manda i parafresejant el que es diu a guifi.net:

En la Gala del ICT2008 de Lyon organitzada per el govern francès en la seva presidència de torn de la Unió Europea, es van anunciar les iniciatives que un equip independent ha revisat i que obtenen el reconeixement com a “Living Lab”.

La notícia a guifi.net

Tafaneja-ho!

Anunci oficial a la web de la Comissió Europea

Llistat dels Living Labs (on es llista guifi.net)

Nota personal:

Ara escrivint això pensava (tot i que ja ho sabia des de feia uns dies) “mira un altre reconeixement de que guifi és un model correcte i a seguir”, però ara mirant els enllaços penso i miro … collons! que és la Comissió Europea la que ens reconeix, no és l’ajuntament de poble (que és el que ens ha fet créixer i ens ha mantingut vius), ni les administracions del país o de l’Estat (que més aviat passen de nosaltres) sinó directament el centre de moltes decisions a nivell d’Europa la que ha dit “Ei aquesta gent ho està fent molt bé i si algú vol fer alguna cosa per l’estil a nivell europeu, hauríen de seguir el seu model” (aquesta és en principi la funció dels Living Labs)

Felicitats a tots els que ho han fet possible!!