lunes, enero 28, 2008

No me quedo atras!

como se puede leer en http://www.cesarius.net/desarrollador-de-amarok-se-tatua-el-logo-en-el-brazo/ el desarrollador de amarok se tatuó el logo de su proyecto en el brazo, tuza (mi nuevo asistente de marketing para america latina) me mando una propuesta para que evalúe, se las pongo acá a ver que les parece:

lavoz.com.ar informacion confiable? al instante

titulo del articulo (por si lo cambian)

El fraude a Société Générale alcanzó los 50 millones de euros

titulo de clarin

Francia: Société Générale admitió que el fraude llegó a alcanzar los 50.000 millones de euros

primer párrafo de la nota en lavoz.com.ar

El presunto autor del fraude multimillonario contra Société Générale, uno de los mayores bancos de Francia, compró activos por un valor que alcanzó los 50.000 millones de euros

se les olvidaron unos ceros..

viernes, enero 25, 2008

Instalar solaris [Done]

Siempre quise probar solaris, y hoy llego el CD que había pedido hace unas semanas, así que no pude evitar gastar mi escaso tiempo en instalarlo, acá van una serie de observaciones y screenshots.

Observaciones:
  • Bootea en modo texto: no es para quejarse, un usuario que quiere ver eye candy no va a instalar solaris, pero mi examen es compararlo con ubuntu así que voy a notar las diferencias.
  • 768 MB de RAM para la instalación gráfica: no se si es bueno o malo, pero me obligo a ponerle los 512 MB que tenia por ahí :)
  • Aunque eleji la instalación gráfica el teclado se configura en una interfaz en ncurses.
  • En la seleccion de particiones, no puedo cambiar el tipo de partición a solaris si hay dos particiones del mismo tipo (WTF?).
  • Durante la instalación no hay información detallada sobre que esta haciendo, mas que un mensaje de "Instalando Solaris".
  • La consola de debug, que esta media escondida, es una consola en motif (feo), que no autocompleta y tiene el delete configurado raro.
  • La instalación demora casi 3 horas.
  • Grub se instalo sin detectarme ubuntu, ahora lo único que puedo bootear es solaris.
  • Cuando seleccionas reiniciar o apagar en cualquier lado, se demora mas de un minuto en hacerlo y no da ninguna información de que en realidad esta haciendo lo que le pediste (tanto en la instalación como en el uso del escritorio)
  • No tiene documentación offline, asume que tu red es dhcp y no te deja configurarla en ningún momento durante la instalación. Cuando booteas y vas a Administración -> Redes te dice que no se puede mostrar porque esta habilitado no se que cosa y que para usarla la tenes que deshabilitar (te dice que leas el man para deshabilitarlo).
  • No tengo sonido (aunque para ser una notebook, detecto todo el resto del hardware bastante bien)
  • La consola de root no es bash :S
  • CDE es horrible! (uso gnome 2.18)
  • A diferencia de MS, Sun si usa su lenguaje (Java) para sus aplicaciones.
  • tiene svn, python 2.4.4 y pygtk instalado.
  • emesene funciona una pinturita :P.
  • El look&feel es bastante bonito.
Bueno, basta de observaciones y a los screenshots! :P






jueves, enero 24, 2008

miércoles, enero 23, 2008

Decoradores, introspeccion y señales

Jugando un poco con decoradores y el modulo inspect por primera vez, se me ocurrió intentar reemplazar alguna funcionalidad de gobject.

La funcionalidad que implemente primero, que es bastante útil, es la de notificar a un objeto cuando un atributo de otro objeto cambia, por ejemplo, es útil para la lista de usuarios saber cuando el atributo "status" de un contacto cambia.
Lo que quería, era que las clases "notificadoras" y las clases "notificables" no tuvieran tanto código feo de manejo de eventos, para eso, decidí ver si los decoradores eran la solución, parece ser que si.

ejemplo, una clase "TestObject" tiene un atributo llamado "attribute" con las properties de get/set.
Eel código seria así:


class TestObject(object):
'''a class that have a property called attribute'''

def __init__(self, attribute):
'''class contructor'''
self._attribute = attribute

def set_attribute(self, attribute):
'''set the value of self._attribute'''
self._attribute = attribute

def get_attribute(self):
'''return the value of attribute'''
return self._attribute

attribute = property(fget=get_attribute, fset=set_attribute)


si, ya se que el property en ese caso es al pedo, pero va a ser requerido mas adelante, así que lo pongo :D.

ahora, una clase que desea ser notificada cuando el atributo "attribute" de la clase "TestObject" cambia.
El código seria mas o menos así:


class TestNotificable(object):
'''a class that is notified when an attribute on other object changes'''

def __init__(self):
'''class constructor'''
pass

def on_property_changed(self, obj, attr_name, method_name,
old_value, new_value):
'''method called when an attribute is changed
on an object that we are attached to
'''
print("%s: %s changed in %s(%s).%s from %s to %s" % \
(str(id(self)), attr_name, obj.__class__.__name__,
str(id(obj)), method_name, repr(old_value),
repr(new_value)))



no hay mucha magia, solo lo que necesitamos, un atributo y un método el cual es llamado cuando este atributo cambia

imaginen que haciendo:


obj = TestObject(5)
notificable = TestNotificable()
obj.attach(notificable)
obj.attribute = 10


la salida fuera:


3084746540: attribute changed in TestObject(3084722988).set_attribute from 5 to 10


estaría bueno, pero cuantas lineas habría que agregar a cada clase para eso?
si mis cálculos no fallan, 2 lineas a TestObject y ninguna a TestNotificable.

el código de las clases seria:


import signals

class TestNotificable(signals.Notificable):
'''a class that implements the notificable interface'''

def __init__(self):
'''class constructor'''
pass

def on_property_changed(self, obj, attr_name, method_name,
old_value, new_value):
'''method called when a method with the
@notify_change decorator from a signal.Object is called
'''
print "%s: %s changed in %s(%s).%s from %s to %s" % \
(str(id(self)), attr_name, obj.__class__.__name__,
str(id(obj)), method_name, repr(old_value),
repr(new_value))

class TestObject(signals.Object):
'''a class that have a property that notify when it's changed'''

def __init__(self, attribute):
'''class contructor'''
signals.Object.__init__(self)
self._attribute = attribute

@signals.notify_change
def set_attribute(self, attribute):
'''set the value of self._attribute'''
self._attribute = attribute

def get_attribute(self):
'''return the value of attribute'''
return self._attribute

attribute = property(fget=get_attribute, fset=set_attribute)


una función para probar el ejemplo:


def test():
'''test the implementation of signals'''
obj = TestObject(5)

notificable = TestNotificable()
obj.attach(notificable)

obj.attribute = 10

notificable1 = TestNotificable()
obj.attach(notificable1)

print("")
obj.attribute = None
print("")

notificable2 = TestNotificable()
obj.attach(notificable2)

try:
obj.attach("")
print("[EE] doesn't catch not notificables being attached")
except TypeError:
print("catch not notificables being attached")

notificable = None

if len(obj.notificables) == 2:
print("clean the list if a reference is removed")
else:
print("[EE] doesn't clean the list if a reference is removed")

print("")
obj.attribute = True

obj.deattach(notificable2)
print("\nshould show 1 notification\n")
obj.attribute = []

notificable1 = None

if len(obj.notificables) == 0:
print("clean the list if a reference is removed")
else:
print("[EE] doesn't clean the list if a reference is removed")

obj.attribute = "shouldn't be shown"

if __name__ == '__main__':
test()


que produce la salida:


3083871212: attribute changed in TestObject(3083871244).set_attribute from 5 to 10

3083871212: attribute changed in TestObject(3083871244).set_attribute from 10 to None
3083221740: attribute changed in TestObject(3083871244).set_attribute from 10 to None

catch not notificables being attached
clean the list if a reference is removed

3083221740: attribute changed in TestObject(3083871244).set_attribute from None to True
3083222572: attribute changed in TestObject(3083871244).set_attribute from None to True

should show 1 notification

3083221740: attribute changed in TestObject(3083871244).set_attribute from True to []
clean the list if a reference is removed


el código de signals.py es el siguiente:


import weakref
import inspect

'''a module that implement classes and methods to do signals on a pythonic
way
'''

class Object(object):
'''a class that represent an object that can call other objects
to notify about a changed property, must be used with the
@notify_change decorator, the classes that want to register
to receive notifications over property changes must inherit from
the Notificable interface
'''

def __init__(self):
'''class constructor'''
# a list of weakrefs
self.notificables = []

def notify_property_change(self, attr_name, method_name,
old_value, new_value):
'''call the on_property_changed of all the objects on the list
'''
# uncomment the code below to have a nice debug of the changes
# made to the properties on the objects that inherit from this
# class
#print("%s: %s changed in %s(%s).%s from %s to %s" % \
# (str(id(self)), attr_name, obj.__class__.__name__,
# str(id(obj)), method_name, repr(old_value),
# repr(new_value)))

for notificable in self.notificables:
notificable.on_property_changed(self, attr_name, method_name,
old_value, new_value)

def attach(self, notificable):
'''attach an object that implement the Notificable interface,
add a weakref so it's deleted when the other reference to the
object are 0
'''

if Notificable not in notificable.__class__.mro():
raise TypeError("the object must implement Notificable")

self.notificables.append(weakref.proxy(notificable,
self.__clean_refs))

def deattach(self, notificable):
'''remove the notificable obect from the list, if it exists'''
proxy = weakref.proxy(notificable)

if proxy in self.notificables:
self.notificables.remove(proxy)

def __clean_refs(self, reference):
'''remove the reference from the list, since it's going to be
cleaned by the garbage collector
'''

self.notificables.remove(reference)

class Notificable(object):
'''Interface that define the methods to be implemented to be able
to register to an signals.Object to receive notifications when
a method with the @notify_change decorator is called
'''

def on_property_changed(self, obj, attr_name, method_name,
old_value, new_value):
'''method called when a method with the
@notify_change decorator from a signal.Object is called
'''
pass

def notify_change(method):
'''decorator that add the ability to a setter/fset property to
notify other objects when an attribute of the object is modified
'''

def new_method(*args):
'''the function that decorates the class method, basically it
run the setter and then try to notify the objects about the
change, the setter is runned first since it may raise an
exception, and we dont want to notify over a change that
wasn't made
'''

arguments = inspect.getargspec(method)[0]

if Object not in args[0].__class__.mro():
raise TypeError("object doesn't inherit from signals.Object")

if len(arguments) != 2:
raise ValueError("method should receive two arguments")

self_object = args[0]
name = arguments[1]
method_name = method.__name__
old_value = getattr(self_object, name)
new_value = args[1]

return_value = method(*args)
self_object.notify_property_change(name, method_name,
old_value, new_value)

return return_value

return new_method

miércoles, enero 16, 2008

Buzzword marketing

por alguna razón derivada de la compra de BEA por parte de Oracle termine leyendo la descripción de dos productos de esta empresa para saber a que se dedican aparte de su J2EE Aplication server, entre a ver dos descripciones:

BEA Tuxedo
BEA aqualogic

se hace casi imposible deducir que es lo que hacen, es una descripción totalmente genérica, retorcida y llena de buzzwords, algunos extractos sublimes, pero los invito a leer la descripción y sin consultar fuentes externas, deducir que hacen estos dos productos.

"Usted necesita una plataforma de infraestructura de aplicaciones probada, fiable y escalable: una plataforma que pueda conectar y autorizar a todo tipo de usuarios, a la vez que integra todas sus aplicaciones y datos corporativos en una solución de e-commerce poderosa, flexible y de punto a punto."

"BEA Tuxedo elimina el tiempo, la complejidad y el riesgo de desarrollar y desplegar esta solución."

"La agilidad de la empresa depende del flujo libre de información, servicios y procesos empresariales por toda la organización"

"La Arquitectura Orientada a Servicios (SOA) ha emergido como la estrategia principal de la TI para perfeccionar la presentación de servicios. SOA toma las funciones empresariales discretas contenidas en aplicaciones empresariales y las organiza en servicios interoperativos y basados en estándares que pueden combinarse y reutilizarse rápidamente en procesos y aplicaciones compuestas."

"La Infraestructura de Servicios, se adhiere a los principios de SOA de servicios de grano grueso, débilmente acoplados y basados en servicios para presentar un contenedor neutral para la lógica empresarial que aísla las complejidades de las tecnologías suyacentes."

me envuelve una docena para llevar?

jueves, enero 10, 2008

The daily WTF

leyendo clarin, veo esta noticia: http://www.clarin.com/diario/2008/01/10/um/m-01582119.htm

A titulo "Saquean una casa de Caballito mientras sus dueños estaban de viaje".

Esta noticia me hizo pensar dos cosas:

  • Titular sensacionalista, ya que aunque el uso de saquear esta bien utilizado, en argentina suele tener otra acepción, mas relacionadas con 1989 y 2001.
  • Noticia totalmente "de barrio", porque es tapa de un diario de tirada nacional el hecho de que le roben a una familia la casa?, encima como se ve en la foto, también fue noticia en el canal de televisión TN.
En serio, acaso es la unica casa asaltada en toda la argentina durante esta epoca?, a una persona en Tucuman le importa que asalten una casa en Caballito?.
Con la duda de que por ahí, había algo importante, distinto a otros asaltos en este, me fui a leer el cuerpo de la noticia.
Básicamente tres párrafos cortos, que se podrían referir a cualquier asalto a una casa en verano.

Solo imagino al periodista redactando la noticia..

lunes, enero 07, 2008

Quote


"Bigger is just something you have to live with in Java. Growth is a fact of life. Java is like a variant of the game of Tetris in which none of the pieces can fill gaps created by the other pieces, so all you can do is pile them up endlessly."

"if you begin with the assumption that you need to shrink your code base, you will eventually be forced to conclude that you cannot continue to use Java. Conversely, if you begin with the assumption that you must use Java, then you will eventually be forced to conclude that you will have millions of lines of code."

"But you should take anything a "Java programmer" tells you with a hefty grain of salt, because an "X programmer", for any value of X, is a weak player. You have to cross-train to be a decent athlete these days. Programmers need to be fluent in multiple languages with fundamentally different "character" before they can make truly informed design decisions.

Recently I've been finding that Java is an especially bad value for X. If you absolutely must hire an X programmer, make sure it's Y."

"The second difficulty with the IDE perspective is that Java-style IDEs intrinsically create a circular problem. The circularity stems from the nature of programming languages: the "game piece" shapes are determined by the language's static type system. Java's game pieces don't permit code elimination because Java's static type system doesn't have any compression facilities – no macros, no lambdas, no declarative data structures, no templates, nothing that would permit the removal of the copy-and-paste duplication patterns that Java programmers think of as "inevitable boilerplate", but which are in fact easily factored out in dynamic languages."


http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html

Seguidores

Archivo del Blog