Continuum en Encuentro Linux 2009…

Hace varios días (para ser exacto 22, 23 y 24 de octubre) estuvimos con todo el equipo de Continuum (y dos invitados especiales: Desi Mcadam y Obie Fernandez) en “Encuentro Linux 2009“, celebrando los 10 años del evento.

Continuum en Encuentro Linux 2009

Continuum, Obie & Desi en Encuentro Linux 2009

Nota: En la imagen faltan gente del equipo que estaban regados por el evento.

Resumiendo nuestra participación cronologicamente:

Llegamos tarde el día de la inaguración por problemas ajenos a nuestra voluntad :P , e incluso nos perdimos la parte donde la organización nombraba la presencia de Continuum en el evento !.

El primer día participamos de varias charlas interesante, entre las que se destacaron “Tecnologias GIS Open Source” y “Android, la plataforma movil de Google“, pero lo mejor del día fueron las ligthning talks, sobre todo recuerdo la de DNSSEC y la disertación de “DNS en un minuto”.

El viernes 23 llegó el resto del equipo, y nos fuimos a recorrer las sedes en el día distribuido, participamos en algunas charlas. Ese día se destacó en particular la charla “Benchmark y predicción en el mercado inmobiliario chileno utilizando Pentaho Suite Business Intelligence CE“.

Esa noche nos fuimos todos a celebrar a cualquier bar del bajo mundo de Viña del Mar y yo terminé compartiendo una cerveza con mi Macbook Pro (para que tomen cerveza basta con derramarla sobre el teclado) quien por suerte decidió que aún no era la hora de dejar de funcionar !…

Al otro día me tocó presentar mi charla “JRuby on Rails al rescate de J2EE“, sobre el uso del lenguaje dinámico Ruby (más exactamente el framework web Rails) sobre una plataforma J2EE para agilizar el desarrollo de aplicaciones empresariales:

Luego de mi charla, le tocó el turno a mi colega Leo Soto, quien presentó “Jython: Python para la plataforma Java”, con varios excelentes demos de diferentes escenarios donde es posible usar el lenguaje Python sobre la JVM (Leo escribió más sobre su participación en el evento en su blog) :

Finalmente y para cerrar el evento, nuevamente las lightning talks se robaron el show, y esta vez fue Obie quien le puso color el final cuando comprimió su famosa charla “The Hashrocket Way” en tan solo 8 minutos:

Queremos extender una felicitación y enviar un abrazo al equipo organizador del evento por el trabajo que realizaron y sobre todo por el trato que recibimos de su parte !, ahora nos veremos obligados a participar en próximas instancias de tan magna conferencia !.

Uncompress.py – Descompactando .tar.gz y .zip

Este es un pequeño utilitario escrito en python para descompactar archivos .tar.gz y .zip.

Para el caso .tar.gz es trivial ( solo 2 lineas de código ), en el caso de .zip hay primero que listar el contenido, creando la estructura de directorios. Luego para cada archivo escribir su contenido en el path que le pertenece en la estructura.

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

__version__ = "$Revision$"

# $Id$
# $Source$

""" uncompress.py
    Clase utilitaria para descompactar tanto tar.gz
    como .zip (NO funciona para ZipGenius)
"""
# autor Jorge Rodrigez <jorge.rodriguez@continuum.cl>

import sys
import zipfile
import tarfile
import os
import os.path

class UnCompress:
    # file - str. Path del archivo
    # dir - str. Path donde descompactar el file
    def uncompress(self, file, dir):

        if os.path.exists(dir):
            # si existe lo borramos
            for root, dirs, files in os.walk(dir, topdown=False):
                for name in files:
                    os.remove(os.path.join(root, name))
                for name in dirs:
                    os.rmdir(os.path.join(root, name))
            if os.path.exists(dir): os.rmdir(dir)

        # creamos el dir target
        os.mkdir(dir)

        # si es un tar.gz
        if file.endswith(".tar.gz"):
            # extremadamente trivial
            tar = tarfile.open(file, mode='r:gz')
            tar.extractall(dir)
        # sino, si es un zip (mas complejo)
        elif file.endswith(".zip"):
            # creamos la estructura de directorio
            # donde copiar los archivos
            self._createstructure(file, dir)
            zf = zipfile.ZipFile(file)
           # para cada archivo que lista el zip
            for i, name in enumerate(zf.namelist()):
                # si no termina con '/' asumimos que es un archivo
                if not name.endswith('/'):
                    # creamos el archivo
                    outfile = open(os.path.join(dir, name), 'wb')
                    # copiamos el contenido
                    outfile.write(zf.read(name))
                    outfile.flush()
                    outfile.close()

    def _createstructure(self, file, dir):
        self._makedirs(self._listdirs(file), dir)

    def _makedirs(self, directories, basedir):
        """ crea los directorios """
        for dir in directories:
            curdir = os.path.join(basedir, dir)
            if not os.path.exists(curdir):
                os.mkdir(curdir)

    def _listdirs(self, file):
        """ crea una lista de los directorios
            que hay que crear
        """
        zf = zipfile.ZipFile(file)

        dirs = []
        for name in zf.namelist():
            if name.endswith('/'):
                dirs.append(name)
        # la ordenamos de menor a mayor
        dirs.sort()
        return dirs

El problema de la «Herencia entre Elipses y Circulos». Solución en Python.

En un artículo de Wikipedia[1] se presenta un pretendido problema de la POO en la herencia. Peor aún, se dice que los problemas presentados incumplen con el genial axioma de Barbara Liskov[2] que le da base a toda la teoría moderna de tipos.

Debieron decir que la POO no tiene ningún problema y que este caso (Herencia entre Elipses y Círculos) es muy simple conceptualmente; que el problema está en la muy mala implementación de muchos de los lenguajes de programación más usados.

Los modelos OO deben representar lo mejor posible la realidad, para demostrar la superioridad del Python frente a otros lenguajes muy establecidos programé este código en apenas 15 minutos y lo he usado para lanzar retos a ver quiénes ofrecen una solución similar en otros lenguajes como C++, C#, Delphi o Java.

Por supuesto que el código está muy simplificado porque no tiene propósitos de resolver un problema real, sólo ilustra la falta de rigor de esté artículo de la Wiki.

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Copyright (C) 2008 Medardo Rodriguez

# This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.

class Shape(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
 
class SizeableShape(Shape):
    def __init__(self, x, y, dx, dy):
        Shape.__init__(self, x, y)
        self.SetSize(dx, dy)
 
    def SetSize(self, dx, dy):
        self.dx = dx
        self.dy = dy
 
    def _IsSquarish(self):
        Epsilon = 1E-10
        return abs(self.dx - self.dy) < Epsilon
 
 
class MutableShape(SizeableShape):
    # analize if some checks are needed here
    def _Mutate(self, _class):
        self.__class__ = _class
 
    def __SetSize(self, dx, dy):
        SizeableShape.SetSize(self, dx, dy)
        subclasses = self.__class__.__subclasses__()
        IsSuperClase = (len(subclasses) > 0)
        NeedMutation = (IsSuperClase == self._IsSquarish())
        if NeedMutation:
            if IsSuperClase:
                _class = subclasses[0]
            else:
                _class = self.__class__.__base__
            self._Mutate(_class)
 
 
class Ellipse(MutableShape):
    def SetSize(self, dx, dy):
        MutableShape.SetSize(self, dx, dy)
        if self._IsSquarish() and (type(self) is Ellipse):
            self._Mutate(Circle)
 
 
class Circle(Ellipse):
    def __init__(self, x, y, radius):
        diameter = 2*radius
        Ellipse.__init__(self, x, y, diameter, diameter)
    def SetSize(self, dx, dy):
        Ellipse.SetSize(self, dx, dy)
        if not self._IsSquarish() and (type(self) is Circle):
            self._Mutate(Ellipse)
 
 
class Rectangle(MutableShape):
    def SetSize(self, dx, dy):
        MutableShape.SetSize(self, dx, dy)
        if self._IsSquarish() and (type(self) is Rectangle):
            self._Mutate(Square)
 
 
class Square(Rectangle):
    def __init__(self, x, y, width):
        Rectangle.__init__(self, x, y, width, width)
 
    def SetSize(self, dx, dy):
        Rectangle.SetSize(self, dx, dy)
        if not self._IsSquarish() and (type(self) is Square):
            self._Mutate(Rectangle)
 
 
class Point(Shape): pass
 
 
if __name__ == '__main__':
    for code in ('ce = Circle(0, 0, 10)', 'ce.SetSize(5, 6)',
    'ce.SetSize(15, 15)'):
        exec code
        print '>>> %s' % code
        for cls in [Circle, Ellipse]:
            print '%s: %s' % (cls.__name__,  isinstance(ce, cls))
        print

[1] http://en.wikipedia.org/wiki/Circle-ellipse_problem
[2] http://en.wikipedia.org/wiki/Liskov_substitution_principle

« Entradas Anteriores

Conócenos

Tel: +56 2 9341951

e-mail: info@continuum.cl

Copyright © 2010 Continuum Ltda.
Coronel Pereira 72. Oficina 903. Las Condes. Santiago. Chile