Matías E. Gieco: La gravedad en el mundo de Firefox :P

   Publicado:

En una nota que dice "Satélite crea un mapa de la gravedad de la Tierra con una precisión sin precedentes

Un satélite europeo recopiló datos para crear un mapa de la gravedad de la Tierra con una precisión sin precedentes. Es una referencia fundamental para medir la circulación de océanos, el cambio del nivel del mar y la dinámica del hielo. "

Salió está foto:

Con esa imagen, es facilmente reconocible:


O sea que la "Recreación de la Tierra según la fuerza de la gravedad" es influenciada directamente por Firefox.

Cuac cuac cuac :up:

Martín Cerdeira: Intención del código (o, me descargo un poco)

   Publicado:

Este post, probablemente, parezca una pelotudez. Probablemente alguien diga "esto es obvio"o "no me digas", pero, es que lo he visto tantas veces, me he topado con esto tanto, que empiezo a creer que no es tan obvio.


Me ha tocado leer/mantener código que no fue escrito por mi. Es decir, meterme a tocar, mejorar, fixear, código ajeno en vez de escribirlo desde cero. En esos casos, me he topado con cosas como esta (*):

Function Foobar(n){
    n = n * 3
    return n
}


El tema es el siguiente, dada una función escrita en algún lenguaje de programación, puedo saber si está bien?

Esa función, es correcta o no es correcta?? Digamos, desde el punto de vista de la sintaxis (suponiendo que eso es la sintaxis de algún lenguaje) puede no fallar. Pero, está bien? Cómo se que intención tenía? Qué se supone que hace? O que esperar? Por qué nos cuesta tanto documentar eso en comentarios?

En casos peores, he visto cosas como:

Function Foobar(n){ //Devuelve n multiplicado por 3
    n = n * 3
    return n
}


Donde, no solo sigo teniendo el problema de no saber si está bien o no, sino que, además, me dice algo que es obvio.

Entonces, queridos amigos programadores, cuando comentemos procuremos poner la intención de ese cacho de código. NO quiero que me digan lo que puedo ver leyendo el código, sino, justamente, lo que se les pasó por la cabecita cuando lo escribieron. Por qué? Porque es mucho más sencillo arreglarla (si fuera necesario) sabiendo que se supone que hace, que tener que deducirlo teniendo en cuenta quien la llama, por ejemplo. Además, si la función estuviera mal, es más complejo deducir que en realidad, quisieron poner, no se, n = n + 3, por decir algo, aumentando mis posibilidades de romper algo que estaba bien, pero que parecía mal.

Gracias

(*) Aclaración para los despistados, esa función es solo ilustrativa, no es un caso real =)

Patricio Molina: Eight queens puzzle en GitHub

   Publicado:

Subí el código del eight queens puzzle, posteado hace un par de meses en este blog, a GitHub.

El repo es https://github.com/pmolina/eqp.

Carlos Joel Delgado Pizarro: Python Everywhere

   Publicado:

Python Everywhere


Maximiliano Robaina: django y base de datos heredadas

   Publicado:

En un proyecto en el que estamos trabajando, el cual básicamente consiste en migrar una aplicación de escritorio a un entorno web, decidimos mantener la herramienta que venimos usando justamente para todo lo que sea desarrollo web, es decir, django.

Ahora, el tema con django es simple cuando se empieza un proyecto desde cero, pero en este caso, ya heredamos la base de datos con la que debemos trabajar y por lo tanto tenemos que atarnos a esto. Además, la base de datos que debemos utilizar es Firebird SQL ( si, firebird :) ), y django no dispone de soporte “out the box” para este motor de base de datos, pero por suerte hay un grupito de gente (autobombo)[1]  que se interesa por dar este soporte ;) y por lo tanto tenemos un módulo que nos permite trabajar con django y firebird.

Uno de los primeros temas que se nos planteó al tener que usar una base de datos legacy, es con el tipo de datos Boolean.
Firebird, al igual que otros motores de base de datos SQL, no tiene un tipo de datos nativo que represente un Boolean, es decir, que permita trabajar con valores True o False.
Si bien esto no es un inconveniente ya que en estos caso se reemplaza por un tipo de datos que permite almacenar, por ejemplo, un valor entero (1 = True, 0 = False) o un valor de tipo caracter, que era nuestro caso el cual utiliza el valor “S” para verdadero (true) y “N” para falso (false).

Django dispone de un tipo de datos para soporte de Booleans y como no todos los motores de base de datos soportan True y False (por ej, MySQL para el cual django tiene soporte “de fabrica”, tampoco tiene un dato nativo boolean y por lo tanto se implementa generalmente como un Smallint con los valores 1 y 0 para True / False respectivamente), pero por defecto trabaja con valores 1 y 0.

¿Cómo hacemos entonces para usar los valores S y N heredados como si fuesen booleans nativos?

Herencia al rescate.!

No me voy a poner a explicar como se hace en django para escribir tipos de campos personalizados. La documentación de django es muy completa y explica todo al respecto.

http://docs.djangoproject.com/en/1.2/howto/custom-model-fields/

Pero si quería exponer como quedó nuestra implementación de BooleanField, al cual llamamos en un arranque furioso de creatividad, BoolField.

class BoolField(models.BooleanField):
    __metaclass__ = models.SubfieldBase

    def db_type(self, connection):
        return “CHAR(1) NOT NULL CHECK (%s IN (’S’,’N’))”
   
    def get_prep_value(self, value):
        if value:
            return u’S’
        return u’N’
   
    def to_python(self, value):
        if isinstance(value, basestring):
            if value.strip() == ‘S’:
                return True
            return False
        return value


Y con esto, ya tenemos nuestro BooleanField ala Firebird.


[1] http://code.google.com/p/django-firebird/

Marcelo Fernández: Cursos Asterisk 2011

   Publicado:

Hola, paso a dejar un lindo chivo aviso sobre cursos de Asterisk que están armando un grupo de gente conocida y amiga, en su versión 2011:

Bitsense, empresa dedicada a la implementación de soluciones telefónicas, dará comienzo a su curso de capacitación de Telefonía IP denominado BiaC (Bitsense Initial Asterisk Course) edición 2011, el mismo es el primer curso en la Argentina dictado por dos instructores certificados dCAP (Digium-certified Asterisk Professional) junto con el apoyo de certificados Cisco y Juniper. Este curso está orientado a brindarle las herramientas y conocimientos necesarios para implementar una infreastructura de Telefonía IP basado en Asterisk desde su inicio.

Para solicitar mas informacion envienos un mail a capacitacion@bitsense.com.ar y un representante se comunicará con usted o llamenos al telefono 5353.9858 (opción 2).

Le informamos también que referenciando esta publicación (si, ¡este blog!) usted accederá a un descuento especial.

http://www.bitsense.com.ar/cursos/biac/

Saludos

Esteban Ordano: Book Review: Mindset

   Publicado:

Estuve leyendo un libro muy interesante que saqué de la biblioteca de Infosys. El libro es de la psicóloga estadounidense Carol Dweck, y se podría considerar un libro de auto ayuda. Se llama Mindset: The New Psychology of Success Básicamente, distingue entre dos tipos de personas: personas con el "fixed mindset" y personas con el [...]

Maximiliano Robaina: Por qué elegir python

   Publicado:

Hace un par de años atrás (fines de 2009) un cliente de españa al cual le ofrezco servicios de outsourcing, me envió un mail solicitandome mi punto de vista para el reemplazo de su herramienta de desarrollo: Delphi 6.

Acá expongo entonces los fragmentos principales de mi respuesta y mi opinión sobre por que elegir python como herramienta de desarrollo de software.

DISCLAIMER: hay que tener en cuenta que este mail lo escribí hace 2 años atrás donde además expuse pensamientos sobre investigaciones que hacía 4 o 5 años antes (2005-2006) inclusive.

Hace un tiempo, digamos unos 3 años (en realidad fue un poco más, quizás 5 años pero decididamente hace 3), empecé a buscar alternativas a Delphi. Por un montón de cosas: el lenguaje no evolucionaba, la incertidumbre de que iba a pasar con la herramienta, si seguia Borland o no, etc. Entonces empecé a buscar herramientas (más precisamente un lenguaje de programación) que cumplan con la siguiente características:

1. Que sea multiplataforma: que me permita ejecutar mi programa tanto en Windows como en Linux sin cambiar nada o al menos muy poco.
2. Que sea open source: quiero poder ver como esta hecha, y si fuese necesario, mejorarla y/o adaptarla a mi necesidades sin restricciones de licencias.
3. Influenciado por el punto anterior (2), que tenga una buena comunidad de usuarios que la respalden.
4. Que pueda hacer desarrollos tanto de aplicaciones de escritorio, como aplicaciones web sin tener que aprender otro lenguaje.
5. Un lenguaje de programación que sea intuitivo y permita un rápido desarrollo, que sea fácil de aprender. Es decir, que sea productivo, que acorte los tiempos de desarrollo.
6. Que tenga una buena base de librerías para desarrollar y sobre todo completa: (acceso a base de datos, mails, tratamiento de imagenes, etc.)

Primeramente, empece viendo Java: supongo que porque tiene mucho marketing, hay empresas grandes atrás de este producto. Me conseguí un par de libros, hice un curso básico inicial, traté de hacer alguna que otra cosa más o menos productiva, etc. Conclusión: no me gustó, si para hacer un pequeño programita que imprima “Hola mundo” tengo que escribir más de 10 líneas no me parece muy productivo. Java es muyyyyy grande hay un monton de cosas, ni hablar de que para hacer aplicaciones de tipo empresariales hay que saber usar Java EE que es un mundo aparte. Además de los recursos necesarios para ejecutar una aplicación en Java, por ejemplo un entormo de desarrollo como NetBeans necesitas por lo menos 2 GB de memoria (para una aplicación medianamente grande) y aún así le cuesta.

En el transcurso de mi incursión por Java, también vi .NET, más precisamente C#. Más de lo mismo, mucho código para hacer poco. Quería algo más consiso. El lenguaje (C#) en sí tiene cosas muy interesantes, pero es muy parecido a Java. Y bueno, solo me permitiría usarlo en Windows, no era lo que buscaba. (hay una implementación de .NET para Linux que se llama Mono, pero no se que empuje le pueda dar Microsoft a esto). También el punto de que .NET es de Microsoft y por lo tanto no es Libre. No contemplaba varios de los puntos que expuse anteriormente.

Finalmente caí en Python, bueno no, mentira, primero en Ruby influenciado por el framework Ruby on Rails que es para desarrollo web y que tiene mucha publicidad últimamante (de hecho hay un “Delphi” para Ruby que se llama 3rdRail) . Lo probé un tiempo pero luego lo abandoné, quizás más por falta de tiempo o poque había algo que no me convencia del todo.
Entonces, como decía, empece a ver Python, tenía casi todo lo que buscaba:
- Multiplataforma: sin cambiar una línea de código funcionaba perfecto tanto en Linux como en Windows (salvo que hagas cosas especificas de la plataforma). Es más tambien corre en Mac OSX (el sistema operativo de Apple). De hecho python viene por defecto en todas las distribuciones de Linux.
- Es libre-open source: tiene una gran comunidad que lo respalda.
- Es super fácil de aprender y por lo tanto super productivo. Por su característica de ser muy expresivo es muy fácil de enteder lo que el programador quiere poner en el código, casí como si fuese pseudocódigo.
- Tiene una gran librería estandar (así como Delphi viene con la VCL): pero creo yo, mucho más completa que la de Delphi.
- Poder hacer una aplicación de escritorio o una aplicación web muy fácil y rápido sin tener que aprendar nada nuevo del lenguaje (salvo aprender el framework que resuelva el problema en cuestión).
- En fin, un lenguaje muy completo, de muy alto nivel. Un programador con un poco de experiencia, en 15 días más o menos, ya lo tiene aprendido lo principal

Ahora, no es la pancea, hay cosas que no son para hacer con Python (o al menos no directemente), pero si para todo lo que yo buscaba en ese momento.
Por ejemplo, con respecto al acceso a base de datos: hice un sistema para una entidad del gobierno (un seguro materno infantil de salud)  todo hecho con python.  El framework que use para base de datos me permite, solo tocando un parámetro, usar  Firebird, Oracle, SQL Server, MySQL, etc. practicamente cualquiera. Hoy uso Firebird  pero si mañana quiero usar Oracle: creo toda  la estructura de base de datos en Oracle, migro los datos y a mi aplicación solo le digo que ahora se va a conectar a un motor Oracle, no programo una línea.

Bueno, no me voy a poner a explicar las caracteristicas del lenguaje acá porque no termino más :D pero acá van algunas referencias:

http://es.wikipedia.org/wiki/Python

http://www.python.org/
http://www.python.org/about/
http://www.python.org/about/success/

Y por sobre todo esto:  ¿Quién usa Python?

Google ( y lo usa mucho) - You tube
Yahoo
N.A.S.A.
IBM
Disney
The US Navy
Nokia.
Washington Post (washingtonpost.com)
http://popego.com/
etc, etc, etc…

http://pythonology.org/success

Marcelo Fernández: Estableciendo conexiones HTTPS “bien seguras” en Python

   Publicado:

Hace unos días que tenía pendiente colgar esto acá, ya que a alguien en PyAr le fue útil.

HTTPS es la manera de establecer conexiones HTTP pero seguras, en el sentido de que previo al diálogo HTTP estándar pero luego de establecerse la conexión TCP contra el servidor, se negocia entre los participantes una conexión/sesión “especial” entre ambos.  Allí se intercambian certificados con el fin de autenticar contra quién se “está hablando”, para luego, si hubo éxito en la dicha comprobación, encriptar (o no) todo lo que va para el otro lado, tanto del Servidor al Cliente (generalmente un navegador), como del Cliente al Servidor.

Todo eso forma parte de SSL 3.0 (hoy TLS 1.0), y si bien se puede utilizar para cualquier conexión TCP (SMTP, IMAP, etc., lo pueden usar también), su uso más común se da cuando uno entra a su casilla de Webmail o su cuenta del Banco desde el navegador;  lo que sucede allí es que nuestro navegador autentica al Servidor, y si todo va bien nos muestra el famoso “candadito” e informa que la sesión “es segura”. Ahora bien, en esos casos, el Banco o Webmail no nos autentica a nosotros como Cliente y deja que cualquiera se conecte a su página, ya que eso requiere varios pasos más (sería realmente engorroso que sea obligatorio).

Sin embargo, en nuestra vida de programadores nos solemos encontrar con necesidades del entorno que nos obliguen a esta situación un tanto extrema y bastante más segura: que tanto el Cliente que desarrollamos autentique al Servidor como que el Servidor autentique al Cliente, amén de que la conexión muy probablemente deberá estar encriptada. Esto nos permitirá asegurarnos que los Clientes (software) que se conecten a nuestro Servidor sean únicamente quienes queremos que sean (o casi).

Python, dentro del módulo httplib nos provee de la clase HTTPSConnection, que maneja y nos abstrae en varias de estas cuestiones de SSL/TLS y nos deja trabajar a nivel HTTP (una capa más arriba). Lo que hay que observar bien (y que recién en la versión 2.7 de la documentación apareció en rojo), es que esta clase aún cuando uno le puede pasar como parámetro los paths a certificados, en realidad no hace ninguna comprobación de validez del certificado que el Servidor exporta. Con lo cual, hay un potencial problema: que nuestro cliente mande los datos a cualquier lado menos a nuestro Servidor de confianza.

¿Y cómo se fuerza a que nuestro programa Cliente chequee el certificado del Servidor? Armé esta clase que extiende sólo lo necesario a HTTPSConnection, que funciona en Python 2.6.x y que me permite hacer eso.

Le agregué un ejemplo en la llamada a __main__ para mostrar cómo se usa:

#!/usr/bin/env python
#-*- coding: utf-8 -*-
 
import socket
import ssl
import httplib
 
class HTTPSClientAuthConnection(httplib.HTTPSConnection):
    """ Class to make a HTTPS connection, with support for full client-based
        SSL Authentication.
    """
 
    def __init__(self, host, port, key_file, cert_file, ca_file, timeout=None):
        httplib.HTTPSConnection.__init__(self, host, key_file=key_file,
                                                   cert_file=cert_file)
        self.key_file = key_file
        self.cert_file = cert_file
        self.ca_file = ca_file
        self.timeout = timeout
 
    def connect(self):
        """ Connect to a host on a given (SSL) port.
            If ca_file is pointing somewhere, use it to check Server Certificate.
 
            Redefined/copied and extended from httplib.py:1105 (Python 2.6.x).
            This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter
            to ssl.wrap_socket(), which forces SSL to check server certificate
            against our client certificate.
        """
        sock = socket.create_connection((self.host, self.port), self.timeout)
        if self._tunnel_host:
            self.sock = sock
            self._tunnel()
        # If there's no CA File, don't force Server Certificate Check
        if self.ca_file:
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                        ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED)
        else:
            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
                                              cert_reqs=ssl.CERT_NONE)
 
if __name__ == '__main__':
    # Little test-case of our class
    import sys
    if len(sys.argv) != 6:
        print 'usage: ./https_auth_handler.py host port key_file cert_file ca_file'
        sys.exit(1)
    else:
        host, port, key_file, cert_file, ca_file = sys.argv[1:]
    conn = HTTPSClientAuthConnection(host, port, key_file=key_file,
                                           cert_file=cert_file, ca_file=ca_file)
    conn.request('GET', '/')
    response = conn.getresponse()
    print response.status, response.reason
    data = response.read()
    print data
    conn.close()

En cuanto a la generación de las claves de Cliente, Servidor y CA hay unos cuantos artículos y es relativamente sencillo una vez que se entiende qué se está haciendo. Por otra parte que en estos casos es muy común que el Servidor exija que el Cliente si o sí envíe su certificado o sino la conexión se deberá caer; esto en el caso del Servidor Apache está bien documentado.

Entiendo que en Python 3.2 esto está resuelto en la misma API standard de Python (en su momento abrí un ticket similar para usar esto con urllib2, que incluye cosas importantes como el manejo de cookies, por ejemplo), y comentaron eso.

Según me dijeron en PyAr, es casi seguro que este ejemplo no funcione en Python 2.7, así que en un futuro no muy lejano espero poder adaptar este código a dicha versión y seguramente lo estaré subiendo en esta página.

Saludos

Mariano Reingart: Novedades PyAfipWs -Factura Electrónica- (instalador nsis, pythoncom, soap)

   Publicado:

Recientemente liberé una nueva actualización de la biblioteca PyAfipWs, con varias mejoras:
http://www.pyafipws.com.ar/anuncios/nuevoinstalador106ayejemplosparawsfev1
A continuación se detallan los temas técnicos:

Extension a py2exe para generar un instalador NSIS:

Inicialmente usaba un .BAT para generar el instalador (7-zip autoextraible), para simplificar y mejorar el proceso (detectar archivos en uso, desinstalar copia previa, mostrar licencia, elegir directorio, internacionalización), desarrollé nsis.py, una extensión para py2exe, que agregando dos lineas a un setup.py crea un paquete unico con todo incluido, usando Nullsoft Scriptable Install System:

from nsis import build_installer
setup(
...
cmdclass = {"py2exe": build_installer}
)

Más info en:
http://code.google.com/p/pyafipws/source/browse/setup_wsfev1.py
http://code.google.com/p/pyafipws/source/browse/nsis.py

El código está adaptado de una ejemplo de py2exe para Inno Setup. 

PythonCOM y la ruta de instalación

Para poder acceder a archivos locales en un ambiente empaquetado con py2exe, en general es trivial salvo que el script sea una DLL, ya que el interprete Python se "embebe" dentro del programa anfitrión, y los métodos estándard para determinar donde está ubicado el script fallan.
La solución mas simple fue usar:

  • sys.executable para cuando el script es un .EXE
  • win32api.GetModuleFileName(sys.frozendllhandle) para cuando el script es un .DLL
  • __file__ cuando se ejecuta directamente el .PY

Más info en:
http://code.google.com/p/pyafipws/source/browse/wsfev1.py#129

Type Library y PythonCOM:

Algunos lenguajes de tipado estático (C#, versiones de Cobol) necesitan para las interfaces COM una librería de tipos (mejor conocidas como .TLB) para referenciar y determinar los métodos, parámetros y valores devueltos, ya que Python es un lenguaje dinámico que no ofrece dicha información.
Para mi sorpresa, las implementaciones en lenguajes de tipado estático tampoco parecen ofrecerla, y es necesario en todos los casos usar un compilador de un lenguaje especial de MS (IDL):
http://code.google.com/p/pyafipws/source/browse/pyafipws.idl
Para que lo reconozca hay que agregar al objeto python los atributos _typelib_guid_, _typelib_version_, _com_interfaces_
http://code.google.com/p/pyafipws/source/browse/pyafipws.py#57

Igualmente todo este tema esta deshabilitado ya que el tipado estático ocasiona más problemas que los que resuelve (sobre todo con el registro, DLL hell, falta de flexibilidad, etc.), y hay métodos alternativos más simples para acceder a PythonCOM desde C# y lenguajes similares.

Mi agradecimiento a Mark Hammond (el creador de python-win32) por señalar al ejemplo "pippo" en el directorio win32com\test, como muestra de una asociación entre un objeto Python COM y su TLB.

Mejorando la performance SOAP WSDL:

El protocolo SOAP es complejo, y analizar el XML de la descripción de un webservice (WSDL) para poder comunicarse con el, es un proceso un poco costoso.
Gracias a Python la solución se simplificó bastante, ya que permite guardar y recuperar las estructuras de datos ya procesadas, sin necesidad de artefactos o código generado como en otros lenguajes (.NET, Java, etc.):
http://code.google.com/p/pysimplesoap/source/browse/pysimplesoap/client.py#244

Con el módulo cPickle de la librería estándar (implementado en C) se mejoro el tiempo para cargar un WSDL de 0.4 segundos a aproximadamente a 0.001 segundos, ~ 400 veces más rápido. Con pickle nativo (implementado en python) la mejora era un poco menos significativa (~ 40 veces más rápido).
Los test fueron realizados en una netbook para un webservice medianamente complejo, YMMV
Share