Decoradors a Python
Escrit per Aaloy a 30 de August , 2009 a les 7:22 p.m.
Què és un decorador
Un decorador és el nom d'un patró de disseny. Els decoradors alteren de manera dinàmica la funcionalitat d'una funció, mètode a classe sense tenir-ne que fer subclasses o canviar el codi font de la classe decorada. En el sentit de Python un decorador és quelcom més, inclou el patró de disseny, però van més allà, Bruce Eckel els assimila a les macros de Lisp.
Els decoradors i la seva manera d'utilitzar-se ens ajuden a fer el nostre codi més net, a autodocumentar-lo i a diferència d'altres llenguatges de programació no requereixen que ens aprenguem un altre llenguatge de programació (com passa amb les anotacions de Java per exemple). En la seva utilització podem atracar-nos a la programació orientada a aspectes (AOP) o utilitzar-los per a afegir sistemes de control a les nostres funcions, de log, caché, ... Les possibilitats són infinites. El decoradors formen part de Python des de la versió 2.4 i com diu Michele Simionato ens aporten el següent:
- Redueixen el codi comú i repetitiu (l'anomenat codi boilerplate).
- Afavoreixen la separació de responsabilitats del codi
- Augmenten la legibilitat i la mantenibilitat
- Els decorador són explícits.
Aquesta potència té un preu: en rendiment (que s'haurà d'avaluar per a cada aplicació) i en complexitat a l'hora de desenvolupar-los. Un decorador típic veurem que és molt bo d'escriure, però la cosa es complica un poc quan volem passar paràmetres o mantenir la signatura del mètode. Aquesta complexitat no és tant pel codi que s'ha d'escriure sinó perquè hem de recordar com s'ha d'escriure el decorador per a cada cas.
Afortunadament veurem que gent com Michele Simionato han desenvolupat paquets que ens simplifiquen molt la vida. Tot i això i abans de fer servir aquestes utilitats convé saber què són i desenvolupar-los sense ajuda. És un poc com aprendre's les taules de multiplicar i després ja utilitzar la calculadora.
Classificació dels decoradors
Podem dividir els decoradors en grups:
- Segons els paràmetres que admeten:
- No admeten paràmetres
- Sí admeten paràmetres
- Segons si preserven la signatura del mètode al que decoren:
- Decoradors no que preserven la signatura
- Decoradors que si la preserven
Els decoradors més senzill són aquells que no admeten paràmetres i no preserven la signatura
Un decorador que no fa res
Per començar crearem un decorador que el que farà es convertir qualsevol funció en un /dev/null, és a dir, no retornarà res i no farà res amb la funció.
1 2 3 4 5 6 7 8 | def forat_negre(f): def none(): pass return none @forat_negre def di_hola(): return "hola" |
Si executam di_hola() no tendrem cap resultat, millor dit tindrem None
La sintaxi @ del decorador de Python és el que s'anomena syntactic sugar, és a dir, una manera d'escriure les coses que ens simplifica la legibilitat, però fet i fet es podria escriure perfectament com
1 2 | di_hola = forat_negre(di_hola) di_hola() |
i tendríem el mateix que fa el decorador. Recordem que les funcions són objectes i que es poden assignar i passar com a paràmetres a Python.
Tot i la senzillesa de l'exemple ens serveix per veure el següent:
Un decorador no és més que un envolcall cap a una funció i per tant ha de retornar una funció, més concretament un callable, per a entendre'ns, qualsevol cosa que posant-hi un doble parèntesi al costat () no peti.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def retorna_objecte(f): ....: def obj(): ....: return object() ....: return obj ....: In [17]: def di_hola(): ....: return "Hola" ....: In [18]: di_hola = retorna_objecte(di_hola) In [19]: di_hola() Out[19]: <object object at 0xf7f745e8> |
Al nostre decorador forat_negre li hem passat una funcició sense paràmetres, però si li passam paràmetres ens trobarem una sorpreseta
1 2 3 4 5 6 7 8 | @forat_negre def suma(a,b): return a,b suma(2,3) TypeError Traceback (most recent call last) TypeError: none() takes no arguments (2 given) |
que per una altra banda és del tot normal, hem definit el forat_negre de tal manera que retorna una funció sense paràmetres, així que si li intentam passar els paràmetres que tenia la funció decorada senzillament es queixa i peta.
Anem a definir un poc millor el nostre decorador per a que no ens passi així i poder admetre el mateixos paràmetres que la funció decorada
1 2 3 4 5 6 7 8 9 10 11 12 | def forat_negre(f): "d'aquí no surt res" def none(*args, **kw_args): pass return none @forat_negre def suma(a,b): "suma dos parametres qualsevols si pot" return a+b suma(2,2) |
Ara ja no dona error. Així doncs una altra conclusió: a més de tornar una funció, hem de procurar que la definició de las funció que tornam admeti al manco els mateix nombre de paràmetres que la funció que volem decorar. Si no sabem quants són aquests ens curam en salut amb args i kw_args.
Fixem-nos que no hem mantingut la signatura de la funció i com a experiment intentau fer un help(suma). Tornarem damunt això un poc més endavant. Ara per ara ja sabem com crear decoradors simples a partir d'una funció.
Fent decoradors no intrusius
Si heu fet un help(suma) o un suma.__name__ potser un haureu sorprés en veure que le nom de la funció és none en lloc de l'esperada suma. Si pensau amb el que hem fet tampoc és d'extranyar, fet i fet hem substituït la funció original per
una altra, recordem que el decorador f aplicat damunt la funció g és equivalent a fer g = f(g).
El que és aconsellable és que el decorador sigui capaç de mantenir la documentació i el nom de la funció que decora, ja que d'aquesta manera es simplifica l'ús de la funció i els autocompletadors de codi no es tornen bojos.
Això ho podem fer de dues maneres: la llarga i la curta
La manera llarga
1 2 3 4 5 6 7 | def forat_negre(f): def none(*args, **kw_args): pass none.__doc__= f.__doc__ none.__dict__= f.__dict__ none.__name__= f.__name__ return none |
Amb les tres instruccions adicionals que hem posat tornar a recuperar les metadades de la funció original que passam al decorador. Si hara feim un help veurem que es fa damunt el nom de la funció correcta suma i que l'ajuda també és la seva.
Help on function suma in module __main__:
suma(*args, **kw_args)
Suma dos parametres qualsevols si pot
Fixem-nos en la signatura de la funció no s'ha preservar. Abans admetia dos paràmetres i ara n'admet un nombre qualsevol. Per la majoria de casos això no té més importància, però al final de l'article veurem com es pot resoldre.
La manera curta
Com que el tema de reservar les metadades és força interessant i comú, al mòdul functools hi trobam la funció wraps que és en sí mateixa un decorador i que fa aquesta funció. D'aquesta manera el codi anterior quedaria:
1 2 3 4 5 6 7 | from functools import wraps def forat_negre(f): @wraps(f) def none(*args, **kw_args): pass return none |
Fixau-vos que hem fet servir un decorador per crear un altre decorador. Insistirem en aquest tema més tard.
Un decorador amb arguments
El decorador que hem fet a l'apartat anterior era prou simple, feia ben poca cosa i no tenia paràmetres. Si volem fer decoradors hem de fer primer de tot que siguin útils, i també ens trobarem amb la necessitat de que aquests decoradors admetin paràmetres.
A Django, per exemple, podeu trobar que el decorador de cache admet paràmetres que ens permet dir-li durant quan de temps ha de cachejar els resultats, o el decorador vary_on_headers, que ens permet modificar el contingut de la resposta de les vistes afegint les capçaleres que indiquem.
Anem a veure com ho podem aconseguir nosaltres. També hi ha dues maneres de fer-ho, la clara i la complexa. La manera clara és la que recoman i utilitza una classe per a fer el decorador, la complexa requereix més esforça per a entendre què està fent el decorador, és més curta, però personalment preferesc un codi més legible.
De la mateixa manera els decoradors que hem fet com a funcions es poden crear com a classes, però en aquest cas, crec que la definició en forma de funcions és més bona de seguir, i ens permetrà distingir clarament entre els dos tipus de decoradors: el que no admeten paràmetres que es construeixen preferentment mitjançant funcions i els que admeten paràmetres, que es construeixen preferentment fent servir classes.
Per seguir amb el forat negre, ara el nostre exemple el que farà es mostrar el resultat o no segons li roti. Per això el que farem serà passar-li una funció com a paràmetre que en ser executada determinarà si s'ha de mostrar el resultat de la funció decorada o no
El mètode clar de fer decoradors amb arguments
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/usr/bin/env python # -*- coding: UTF-8 -*- import random class forat_negre_sonat(object): "Un decorador amb fam" def __init__(self, mostrar): self.mostrar = mostrar def __call__(self, f): def none(*args, **kw_args): if self.mostrar(): return f(*args, **kw_args) else: return "Nop" return none @forat_negre_sonat(mostrar = lambda :random.choice((True, False))) def suma(a, b): "Suma dos elements que li passam com a paràmetre" return a+b if __name__=="__main__": print suma(2,3) print suma(5,6) print suma(9,5) |
Fitxem-nos amb que hem fet:
-
Hem creat una classe Python que al seu constructor (l'init) agafa el paràmetre o paràmetres que vulguem. És un constructor normal, així que admet paràmetres per defecte per exemple.
-
Recordem que el decorador hem dit que ha de ser un objecte cridable (callable), a una classe, la cridabilitat la dóna el mètode call. Aquesta classe la definirem de manera que agafi la funció a decorar com a paràmetre. D'aquesta manera tenim accés tant als paràmetres del decorador, que hem passat al constructor, com a la funció decorada, que hem passat com a paràmetre al call.
Després d'això ja sols en queda encapsular la cridada com ho fèiem al cas anterior, retornant el decorador en lloc de la funció decorada.
A l'exemple el que he fet és mostrar que el paràmetre pot ser el que nosaltres vulguem, en concret he passat una funció anònima, creada amb lambda que és la que s'encarrega d'establir l'aleatoritat del resultat.
Si voleu podem fer aquest decorador una mica més complet, fent que admeti a més de funcions valors i que preservi el nom i documentació de la funció decorada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!/usr/bin/env python # -*- coding: UTF-8 -*- import random class forat_negre_sonat(object): "Un decorador amb fam" def __init__(self, mostrar=None): self.mostrar = mostrar def __call__(self, f): def none(*args, **kw_args): if callable(self.mostrar): opcion = self.mostrar() else: opcion = self.mostrar if opcion: return f(*args, **kw_args) else: return "Nop" none.__name__ = f.__name__ none.__doc__ = f.__doc__ return none @forat_negre_sonat(mostrar = lambda :random.choice((True, False))) def suma(a, b): "Suma dos elements que li passam com a paràmetre" return a+b @forat_negre_sonat(mostrar=True) def resta(a,b): return a-b if __name__=="__main__": print "Exemple amb %s " % suma.__name__ print suma(2,3) print suma(5,6) print suma(9,5) print "Exemple amb %s " % resta.__name__ print resta(2,3) print resta(5,6) |
El mètode enrevessat de fer decoradors amb arguments
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def forat_negre_dos(mostrar): def wrap(f): @wraps(f) def wrapped_function(*args, **kw_args): if callable(mostrar): opcion = mostrar() else: opcion = mostrar if opcion: return f(*args, **kw_args) else: return "Nop" return wrapped_function return wrap |
Bé, enrevessat, el que es diu enrevessat no ho és, per una cosa tan simple no té massa història, però fixau-vos que és un poc més mal de seguir.
El primer que hem fet és definir la nostra funció, on hi hem posat els paràmetres que admet. Aquest funció retorna una altra funció que admet un argument, que és la funció decorada, que a la seva vegada admet un nombre indeterminat d'arguments (recordem que això ho estam forçant nosaltres).
Com que la segona funció, wrapped_function està definida dins wrap, té accés al paràmetre del decorador i pot actuar en conseqüència.
Encadenant decoradors
Els decoradors es poden encadenar, és a dir, una funció pot tener tans decoradors com faci falta i necessitem, sols limitats pel nostre sentit comú i la legibilitat del programa. Dos decoradors són habituals, tres no es veuen gaire, quatre o més són per pensar-s'ho.
Per a l'exemple manllevaré un dels decoradors més útils, el memoize, que ens permet cachejar una funció segons els seus paràmetres. Al Python Decorator Library hi ha una implementació del patró memoize prou senzilla de seguir amb el que ara sabem i a més ens servirà per completar la construcció de decoradors sense paràmetres fent servir una classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class memoized(object): """Decorator that caches a function's return value each time it is called. If called later with the same arguments, the cached value is returned, and not re-evaluated. """ def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args): try: return self.cache[args] except KeyError: self.cache[args] = value = self.func(*args) return value except TypeError: # uncachable -- for instance, passing a list as an argument. # Better to not cache than to blow up entirely. return self.func(*args) def __repr__(self): """Return the function's docstring.""" return self.func.__doc__ |
A diferència de la construcció amb paràmetres, al constructor de la classe memoized s'hi posa com a paràmetre la funció a decorar, i al mètode call hi van els paràmetres de la funció, en lloc de la funció a decorar com es feia a l'altre mètode.
Per què s'ha fet servir aquesta manera si l'altra és més senzilla? Dons perquè necesitam mantenir en memòria la caché i el que fa és mantenir-la en un diccionari dins de la mateixa classe. Si la caché fos externa (amb memcached per exemple), això s'hauria pogut fer perfectament en forma de funció.
A més definirem un decorador que ens servirar per indicar quan entram a la funció i comprovar el decorador memoized.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def log(f): "Registra l'execució de la funció" def wrap(*args): print "Excutant %s, args: %s" % \\ (f.__name__, ",".join(str(x) for x in args)) return f(*args) return wrap @memoized @log def fibonacci(n): "Return the nth fibonacci number." if n in (0, 1): return n return fibonacci(n-1) + fibonacci(n-2) print fibonacci(12) |
Provau d'executar aquest codi amb i sense la funció memoized. Amb els dos decoradors activus veureu que el cada decorador agafa com a entrada la funció ja decorada que surt del decorador que té més avall. Així el memoized agafa com a entrada la funció fibonacci ja decorada amb el log.
Podeu fer la prova amb un exemple més simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/usr/bin/env python # -*- coding: UTF-8 -*- def uppercase(f): "Dada una función f que devuelve un string lo pasa todo a mayúsculas" def wrap(): return f().upper() return wrap def make_bold(f): "Dada una función f que devuelve un string le añade los tags de bold" def wrap(): return "<strong>%s</strong>" % f() return wrap @make_bold @uppercase def say_hello(): return "Hello world" print say_hello() |
Provau canviant l'ordre dels decoradors i veureu perfectament com es van aplicant els decoradors des de la funció per amunt. A l'exemple primer es converteix el "Hello word" a majúscules i després se li apliquen els tags de negreta.
La signatura pendent
Abans d'acabar ens queda un tema pendent: la signatura. Els decoradors que hem creat poden preservar el nom i la documentació de la funció que decoren, però no preserven la signatura, és a dir, el nombre de paràmetres que li passam.
Michele Simionato ha escrit un mòdul excel·lent anomenat decorator que extén la utilizació dels decoradors, mantén la signatura de la funció, el nom i la documentació, i a més ens dona la possibilitat de crear factories de decoradors. Una eina per a tenir sempre a mà. Amb aquest mòdul podríem escriure el codi de l'exemple anterior com:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from decorator import decorator @decorator def uppercase(f, *args): "Donada una funció f que retorna un string ho passa a majúscules" return f(*args).upper() @decorator def make_bold(f, *args): "Afegeix el tag strong a la sortida de la funció" return "<strong>%s</strong>" % f(*args) @uppercase @make_bold def say_hello(nom): "Di hola, home!" return "Hello world %s" % nom if __name__=="__main__": from inspect import getargspec print say_hello('World') print say_hello.func_name print say_hello.__doc__ print getargspec(say_hello) |
Si executau el codi podem veure que no ens ha fet falta recore a wraps o a reasignar nom, la pròpia llibreria de Simionato ho ha fet. A més, si ens fixam en la sortida de l'exemple:
<STRONG>HELLO WORLD WORLD</STRONG> say_hello Di hola, home! ArgSpec(args=['nom'], varargs=None, keywords=None, defaults=None)
La primera línea correspon a la sortida de la funció que hem decorat. La segona és el nom d'aquesta funció. Ens surt el nom de la funció original i no el del decorador. La documentació també s'ha mantingut i per acabar, podem veure que la signatura de la funció és correcta, ens diu que té un argument obligatori anomenat nom.
Conclusió
Esper haver deixat un poc més clar el tema dels decoradors. Crear-los no és difícil, utilitzar-los és simple, sols hem de tenir clar què són i quan fer-los servir. Són una eina potent que ens permet fer el nostre codi més legible i cohesionat. Fora por i a disfrutar amb els decoradors.
Com tot en aquesta vida, usau-los amb coneixement i moderació.
Referències
Per escriure aquest article m'he basat en múltiples fonts, les més importants i útils han estat:
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Python Django
Qooxdoo
Escrit per Aaloy a 20 de August , 2009 a les 10:31 p.m.
Qooxdoo és un bastiment per a la creació d'aplicacion web amb aparença d'escriptori, és a dir el que es coneix com a RIA (Rich Internet Applicatinons).
Aquests darrers dies he estat donant-li una ullada a aquest bastiment. Feia temps que li estava seguint la pista i finalment m'he decidit a avaluar-lo com toca, és adir, començant a fer-hi alguna cosa productiva.
Quan un va a la web de Qooxdoo el primer que pot reparar és que el bastiment compta amb un bon conjunt d'exemples que ens permeten veure les possibilitats del producte. L'aparença de Qooxdoo no és tan cuidada com la d'Extjs per exemple, però en el seu conjunt presenta tota les funcionalitats necessàries.
A l'hora d'avaluar el bastiment m'he fixat en dos punts que per mi són claus: la mantenibiliat de les aplicacions i les seves capacitats de connexió amb altres sistemes.
Donat que el cicle de vida de les aplicacions és molt més llarg que el temps de desenvolupament, tenir un bastiment que ens permeti crear aplicacions mantenibles és fonamental. El bastiment ens ha de permetre estructurar l'aplicació en mòduls i a més ens ha d'abstreure de les complexitats del javascript en el que fa a les colisions de noms.
Qooxdoo resol aquest tema molt bé. No és tan sols un bastiment gràfic, sinó que ha creat un vertader llenguatge orientat a objectes amb les possibilitats bàsiques que ens dóna el javascript. La gent que ve de Java es sentirà com a casa amb aquest model d'objectes: ens permet tenir variables i mètodes estàtics, crear fàcilment mètodes, parla de constructors, d'herència i fins i tot hi ha alguan cosa semblant als interfícies. Aquest model de programació es pot aplicar per modularitzar el codi, de manera que podem crear objectes que representin una finestra amb el seu contingut o bé fer un objecte per a representar un aspecte concret: un menú per exemple.
A l'hora de posar el sistema en producció Qooxdoo se n'encarrega d'esbrinar quins són els mòduls que es fan servir i empaquetar i comprimir els distints mòduls que hem creat en un únic arxiu (més de 500 K a les meves proves). Com es pot veure està força ben pensat, i és una de les coses que més m'han agradat, ja que amb una aplicació gran és molt fàcil perdre la pista del que es fa i acabar amb mega-arxius javascript que tenen un poc de tot. Qooxdoo ens ajuda a estructurar el nostre codi sense perder l'avantatge de poder fer el desplegament a producció amb un únic arxiu javascript.
La connexió amb altres sistemes també em feia passar un poc de pena. Hem connectat bastiments javascript fent servir json, xml i cridades ajax i quan més complexe és el bastiment més dificultats hi ha amb el json, ja que sempre ho esperen d'una determinada manera.
Qooxdoo permet connectar-se mitjançant Ajax i fent servir Json RPC. He creat una sèrie de serveis jrpc de prova amb Django i he mirat de connectar-los. M'ha costat una mica ja que no comptava amb el problema de la seguretat del javascript a IE i Firefox. No es permeten cridades a dominis diferents (crossdomain), però tampoc a ports diferents. Com que Django a desenvolupament ho tenia a localhost:8000 i el javascript ho tenia com a file:// no hi havia manera de fer la connexió per POST. La solució ha esta utilitzar nginx per a servir el javascript i a més per servir de proxy invers cap a Django, amb això ja he pogut fer la connexió sense problemes i tenir el millor dels dos mons, independitzant la capa de presentació de la capa del web service, creat amb el servidor Django i amb capacitat d'autodocumentació, de manera que el servidor Django és capaç de generar una plana on es publiquen els mètodes del json rpc i una petita utilitat per comprovar-ne el funcionament. Semblant al WSDL però millor i tot.
Encara és prest per saber si Qooxdoo complirà totes les espectatives que hi tenc. Falta comprovar com es porta amb widgets complexos: taules, llistes, mescla de contingut web html amb el javascript generat i veure com es pot tractar l'autenticació i la seguretat. Per ara pareix que generar interfícies d'usuari potents és prou senzill i que la comunicació amb altres sistemes és possible, i ara per ara li veig moltes més possibilitat que opcions com Dojo i Extjs, sobretot perquè li veig una filossofia que m'agrada: la de tenir un sistema pensat per al desenvolupador i per al qui ha de mantenir l'aplicació.
Traducciones/Translations by apertium
1 comentari, 0 trackbacks (URL) , Tags: Python Django qooxdoo
Dell Latitude 2100, recapitulació
Escrit per Aaloy a 17 de August , 2009 a les 4:52 p.m.
Un comentari de Paco me dóna peu a fer una recapitulació damunt el portàtil. Per cert, he deixat unes quantes fotos de família al Flickr.
El portàtil resulta molt còmode a l'hora de moure'l d'una banda a l'altra. En aquests quinze dies i escacs que duc amb ell he de dir que és nota molt la diferència entre dur aquesta jugueta i el portàtil de 15,4 polzades. La meva esquena ho agraeix, i més si he de caminar una bona estona.
La durada de la bateria, 5 hores, és un poc curta per el que se suposa que hauria de durar una bateria de 6 cel·les, però en el seu favor he de dir que són 5 hores reals, és a dir, fent feina.
El teclat és molt còmode. A l'igual que en a l'altra portàtil m'agradaria poder tenir un botonet per desactivar el touchpad, ja que mentre escrius és molt senzill tocar-lo sense voler i dur el cursor a qualsevol banda.
L'IDE que faig servir per programar actualment és el Netbeans. El Dell 2100 amb 2 GB de RAM no té cap problema per moure'l i va força fluid. La cosa canvia un poc en posar-li un monitor extern. Us explic: aquest portàtil ho faig servir també per programar i ho tenc amb una configuració de monitor dual, és a dir, tenc un escriptori virtual consistent en la pantalla del portàtil (1024x576) i un monitor Dell de (1680x1050). La tarja gràfic mou bé el conjunt, però els scrolls verticals se noten, no són fluids. No és el suficientment greu com per no deixar-te fer feina, però sí una mica empipador. Aquest efecte és nota bastant al Netbeans i un poc al Firefox. És l'emperò més gran que li he trobat per ara...
L'altra cosa a notar és el carregador. És petit si ho comparam amb els carregadors estàndard de Dell, però encara és gran. En el seu favor dir que és compatible amb els carregadors dels seus germans grans i per mi això s'ha convertit en un avantatge, ja que amb el Dell de 15,4" vaig comprar dos carregadors: un per la docking i un per transportar, així puc jugar amb aquest fet i tenir un carregador a cada lloc de feina.
El disc d'estat sòlid es porta mol bé. És ràpid i tot el sistema tan just fa renou. De tant en tant es posa en marxa un ventilador, però ni ho sents. De totes maneres trob que s'encalenteix més del que esperava i potser això explica la "poca" durada de la bateria.
La visibilitat de la pantalla és molt bona. Pràcticament no hi ha reflexos, encara que no he arribat a aprofitar-ne les possibilitat que té el que sigui una pantalla tàctil. Deu ser un trauma infantil, ma mare me deia que és de mala educació assenyalar amb el dit. :)
Traducciones/Translations by apertium
2 comentaris, 0 trackbacks (URL) , Tags: Informàtica
Tal dia com avui
Escrit per Aaloy a 12 de August , 2009 a les 9:23 p.m.
però fa catorze anys (14) em casava amb Na Catalina. En aquestes hores arribàvem al restaurant de Pollença després de la sessió fotogràfica de rigor.
El menuts no es creuen que feim festa. No en feim, però tants d'anys ja són un motiu de celebració.
Traducciones/Translations by apertium
4 comentaris, 0 trackbacks (URL) , Tags: General
La Ruta del éxito de Luis Miravitlles
Escrit per Aaloy a 11 de August , 2009 a les 8:22 p.m.
L'altra dia em deixaren "La Ruta del éxito. MRW Claves de un modelo de gestión innovador" i avui he dedicat una estoneta a llegir-ho.
El llibre és un elogi d'MRW, del seu model d'empresa i de com va passar de una empresa de missatgeria local amb pèrdues a l'empresa que coneixem avui. És un enaltiment de la figura del seu màxim impulsor, Francisco Martín Frias.
A llarg de poc menys de 150 planes, Luis Miravitlles ens conta la història de MRW, la seva obsessió per la qualitat i el tracte al client, el seu compromís amb la gent i de com es va refundar com a franquícia en un moment en que aquest concepte pràcticament no era conegut a espanya. És interessant veure com MRW ha compaginat les tasques de marketing amb la part social de l'empresa, la qual cosa demostra que el benefici empresarial no té perquè anar en contra del benefici social. Si hi ha imaginació i ganes les dues coses es complementen.
El llibre presenta a cops un estil narratiu, d'anecdotari i a altres un estil més formal, amb xifres i documents. L'autor ja n'avisa d'això i com els capítols es poden llegir de manera independent tampoc xoca massa.
No conec MRW per dintre i no puc dir-vos que el que es diu al llibre sigui veritat o no, però sincerament m'agradaria que fos així. És que es compta al llibre és del tipus d'organitzacions que m'agraden, orientades a la feina, amb gent motivada i on hi ha la suficient cultura empresarial per permetre les millores i reconèixer els seus impulsors. Al manco això és el que ens mostra el llibre. Potser sigui una faula, però ja us dic que és del tipus d'històries que m'agraden, segurament perquè un dels meus somnis és poder arribar a fer quelcom semblant a MRW però a l'àmbit del desenvolupament web.
Sigui com sigui el llibre és inspirador, de lectura fàcil (poc menys d'hora i mitja) i adequant per passar una estona llegint i que se't quedi un bon sabor de boca. Pel títol que té segurament no el compraria, però si teniu l'ocasió de fer-li una ullada, hi ha coses pitjors per passar l'estona.
Fitxa tècnica:
La Ruta del éxito MRW Claves de un modelo de gestión innovador Luis Miravitlles Editorial Gestión 2000 ISBN 84-8088-623-4
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Llibres i revistes
La empresa en la web 2.0 de Javier Celaya
Escrit per Aaloy a 09 de August , 2009 a les 11:59 a.m.
Ahir vaig acabar de llegir "La empesa en la Web 2.0" de Javier Celaya. El libre té una estructura i un contigut que recorda els apunts d'un blog. De fet Celaya recorda en el llibre que alguns dels apunts han estat publicat en el seu blog i adjunta alguns comentaris.T enc el llibre en paper, existeix una edició de descàrrega lliure per mòbils, però la veritat és que està força amagada.
Al llarg de 279 planes Celaya intenta explicar des de la òptica empresarial que és això de la web 2.0 i quin impacte pot tenir en les empreses. Tracta temes com la importància de les xarxes socials, el blogging, microblogging i wikis, donant apunts sobre quina ha de ser la posició de les empreses davant aquestes xarxes i com es poden anar introduïnt aspectes de la web 2.0 dins les organitzacios per tal de millorar-ne la gestió.
El llibre m'ha agradat, sobretot perquè compartesc gairebé al 100% les apreciacions de Celaya, i perquè he trobat en el llibre allò que cercava: com explicar en paraules planeres i orientades a gent amb perfil empresarial l'impacte de les noves tecnologies web en les empreses.
No m'ha agradat tant l'extensió del llibre. Crec que hi ha força palla i que ben bé podria ser un llibre de 150 planes. De tant en tant es posa a escriure noms i característiques de llocs web sense entrar-hi a fons i et dona la sensació de que estan allà per omplir.
Com dic el llibre és interessant, no perquè expliqui coses que desconec sinó per la manera d'explicar-les. La relació preu/contingut, però l'he trobada força alta, després d'haver llegit el llibre 20 Eur em pareix car.
Xerrar per exemple amb Benjamí o Ricardo, o amb "els tertulians de la torrada" crec que en temes de web 2.0 aporta tant o més que el llibre. Celaya, però, ho explica orientat al món empresarial i això se li ha de reconèixer.
Fitxa tècnica:
La empresa en la web 2.0 Javier Celaya Ed. Gestión 2000 ISBN: 978-84-9875-008-9
Traducciones/Translations by apertium
6 comentaris, 0 trackbacks (URL) , Tags: Informàtica Llibres i revistes
Llegint codi
Escrit per Aaloy a 06 de August , 2009 a les 8:15 p.m.
Llegir codi és una de les millors maneres que hi ha d'aprendre a programar. Veus com la gent fa certes coses i pots començar per copiar-les per passar a demanar-te per què es fa d'aquella manera i finalment mirar de millorar-ho.
M'agrada llegir codi, però també es veritat que quan he de llegir codi que he comanat per un projecte i veig segons quines coses em pos un poc de mala llet, no és res personal, crec que és un defecte del meu caràcter, d'aquest xic de perfeccionisme que tots duim a dintre.
Primer de tot s'ha de tenir en compte que escriure codi és molt personal, no hi ha una manera única de fer una mateixa cosa i els codi es converteix en una extensió de la personalitat de l'autor i de la seva manera de fer les coses.
Per això convé sempre ser caut a l'hora de valorar el codi d'altres. Sempre hi ha una manera millor de fer-ho, sempre hi ha una altra manera de fer-ho, la nostra manera.
Pel que es veu afectat per la revisió, les coses no són menys fàcils, sovint pareix que el codi és com un fill nostre, i que una vegada escrit, com nin malcriat, se li han de perdonar tots els defectes.
Personalment quan veig alguna cosa que no m'agrada ho dic. Al llarg del temps he desenvolupat una certa habilitat per veure quan un codi fa mala olor, i segons el que he dormit el dia anterior puc ser més o menys políticament correcte.
De tipus d'errors n'hi ha molts, i jo en tenc la meva classificació particular (ja sabeu, el món es divideix en dos tipus de persones, aquells que fan llistes i els que no).
-
Errors puntuals. Són la típica cagada que li ha passat a tothom. Qui digui que a ell no li ha passat és perquè no ha programat prou. Són errors que poden ser greus en termes de les conseqüències, però que s'han de prendre com això, com part de la feina. Són errors per aprendre a no tornar-los fer.
-
Errors de "però mira que guai que sóc". Sovint no són errors, sinó trossos de codi dels quals el creador se'n va sentir molt orgullós però que són mals de depurar i que es poden reescriure fàcilment per fer el mateix de manera més clara i amb menys línies de codi. Potser el programa funciona, però no és correcte, li falta qualitat i a la llarga representa un problema en el mateniment correctiu i evolutiu. Sovint aquest tipus d'error està molt relacionat en el concepte de reinventar la roda i amb el síndrome NIH (Not Invented Here). S'han de corregir tot d'una que es presenten i mirar de conscienciar a la gent per a que no es repetesquin.
-
Errors de seguiment dels estàndards de codificació. No tenen excessiva importància, però dificulten la lectura del codi i l'evolució del programari. Els estàndards de codificació i localització del codi serveixen per a que qualsevol persona que no està familiaritzada amb el codi, pugui llegir-ho sense dificutat i saber on ha d'anar a trobar les coses. Particularment me resulta molt més fàcil llegir un codi amb noms de variables ben posats, amb els comentaris allà o toca. Llegir codi requereix molt atenció i esforç i tenir que bregar a més amb distintes maneres de codificar no ho fa més fàcil.
-
Errors d'arquitectura: Cohesió i acoblament. Cohesió bona, acoblament innecessari dolent. I m'estic referint a l'acoblament de codi, a casa que cada un faci el que pugui. Tenir tot el relacionat a un mateix lloc (llibreria, paquet, arxiu, ...) i no separat en mil i un trocets que fan mil i una coses sols per peresa de no crear un nou arxiu o estructurar el programa, d'això se'n diu cohesió. L'acoblament és la dependència que hi ha entre mòduls distints i que fa que sovint aquests no es puguin reutilitzar de manera independent. L'acoblament és necessari per a construir programes, però ha de tenir un perquè. Cohesió i acoblament són conceptes que van molt lligats i codi amb poca cohesió sols presentar molt acoblament.
-
Errors de concepte. Són els errors que es cometen perquè un no s'ha aturat a pensar en el que està fent i bé per desídia o bé per malentesos crea codi que no té sentit. És el típic error de permetre fer reserves per dies passats i coses semblants. Són errors que em preocupen, perquè vol dir que s'està programant sense reflexionar i això és molt perillós. La programació no és sols picar codi, és picar codi amb una finalitat i aquesta no sols ha de ser la de cobrar a final de mes, sinó que ha de servir al nostre client. Quan són errors per desconeixement del negoci s'ha d'insistir en que se demani tot el que no es coneix, quan són errors per no pensar en el que se està fent convé insistir en conscienciar a la gent del tipus de feina que fa.
-
Errors de code monkey. Errors de copiar i aferrar, funcioni el codi o no. S'ha copiat cinquanta vegades el mateix sense aturar-se a pensar si convendria fer-ho d'una altra manera. Són errors que al igual que l'anterior m'empipen especialment, ja que per defecte vull pensar que la gent fe la seva feina el millor que sap. Em preocupen perquè sovint vol dir que s'ha escrit el codi a tot màquina per cobrir l'expedient i que les hores s'han dedicat a altres coses. Estirada d'orelles.
No passa res per cometre errors, el que no és admissible es no aprendre dels errors, o preferir reinventar la roda per no aturar-se a pensar en maneres alternatives. Quan el problema es molt bàsic hem de pensar que l'error sols estar en la nostra banda, que la funcionalitat existeix però no l'hem vista i hem de llegir més. L'alternativa: codificar-ho nosaltres mateixos, o començar a pensar que l'error és de la pila TCP del nostre ordinador i posar-se a davallar-se el codi per anar a fer la depuració no és la primera opció que un ha de pensar. Primer s'han de provar les coses més habituals, ja que el el 99,9% de casos l'error serà nostre, del nostre codi.
Llegir el codi, el nostre i els d'altres, ens ajuda a reflexionar sobre allò que podem millorar i a evitar els errors més comuns. Recordem que com a programadors no escrivim codi per a ser executats per les màquines, sinó per a ser llegits per altres persones.
Traducciones/Translations by apertium
3 comentaris, 0 trackbacks (URL) , Tags: Informàtica
El economista naturalista
Escrit per Aaloy a 02 de August , 2009 a les 11:15 a.m.
El economista naturalista és un llibre d'iniciació a l'economia de la vida diària. Mitjançant exemples va explicant situacions que ens podem trobar a la vida diària i donant-ne una explicació des del punt de vist econòmic.
L'autor, Robert Frank, ha seleccionat un conjunt de preguntes fetes per estudiants i aprofita les seves respostes per anar introduint conceptes econòmics destacant:
- El cost d'oportunitat
- La relació cost-benefici
- Els costs marginals
- Les barreres per a la segmentació de preus mitjançant els descomptes
- Els mercats perfectes
- La relació entre bens comuns i bens individuals
- La idea de que no hi ha "doblers gratis"
- La relació entre benefici individual i col·lectiu
És un llibre força entretingut, 275 planes d'exemples que van explicant distintes situacions (algunes molt americanes) d'una manera clara. Això no vol dir que les explicacions siguin una veritat absoluta, sinó que hi ha una explicació econòmica per dita situació i que si més no serveix per il·lustrar conceptes econòmics d'interès.
El llibre m'ha agradat força, però no tant com "El economista camuflado", potser no tan lleuger de llegir, però que aprofundeix molt més en cada exemple.
Un llibre molt recomanable pels qui els agrada entendre un poc més el món que els envolta.
Fitxa tècnica Titol: El Economista Naturalista Autor: Robert Frank Editorial: Península ISBN: 978-84-8307-826-6
Traducciones/Translations by apertium
0 comentaris, 0 trackbacks (URL) , Tags: Llibres i revistes
