Marcos Dione: wrapping-return-by-reference-functions-with-SWIG

At MegaCorp I'm developing in C++, but the APIs are in C. From time to time, we use Python for scripting something using those APIs. We write the bindings in SWIG.

All the functions in the APIs return a status code; it can be OK or many different values for different type of errors. This means that if a function needs to return a value, it actually takes a pointer (not a reference)[1] to such a value and at the end of the function, depending on its success, the value is returned at that address.

Then came the question of wrapping such functions with SWIG. According to the scarce documentation about it one should declare the type (+name if needed) as argout and not much more... except for the first part of the example. See, what numinputs=0 is doing is to make SWIG ignore that type as argument[2], meaning that the wrapper function won't be expecting it. Even so, the body does something, and a very important something. Let's see in my example:

// ignore any input parameter of type PageSetHandle t *
%typemap(in, numinputs=0) PageSetHandle t *pPageSetHandle (PageSetHandle_t temp) {
    $1= &temp;
}

// on the other hand, this is how we convert a PageSetHandle t* to a PyCObject
// and add it to the list of returned values
%typemap(argout) PageSetHandle t * {
    $result= SWIG_Python_AppendOutput ($result, PyCObject_FromVoidPtr (*$1, NULL));
}

In my case the type is PageSetHandle_t. The fact that behind is an actual void * is not important[3], but that messed with my head while trying to understand the problem. What the first part is saying is «look, ignore any parameter of type PageSetHandle_t *, but when you find one, create a temporary variable of the dereferenced type (PageSetHandle_t, in this case), and assign a reference to it to the parameter you're going to pass to the C function». This is extremely important; otherwise, you wouldn't have an address where to store the reference returned by the function. Notice that that temporary variable will be declared in the wrapper's stack and will die when the wrapper finishes, but that's OK because of what we do in the actual conversion code: we create a PyCObject from the dereferencing of the parameter. Here's part of the generated code:

SWIGINTERN PyObject *_wrap_MFaST_PMCreatePageSet(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PageSetHandle t *arg3 = (PageSetHandle_t *) 0 ;
  PageSetHandle t temp3 ;

  {
    arg3= &temp3;
  }
  result = MFaST_PMCreatePageSet(arg1,arg2,arg3);
  resultobj = SWIG_NewPointerObj((new FqStatusCode_t(static_cast< const FqStatusCode t& >(result))), SWIGTYPE_p__FqStatusCode_, SWIG_POINTER_OWN |  0 );
  {
    resultobj= SWIG_Python_AppendOutput (resultobj, PyCObject_FromVoidPtr (*arg3, NULL));
  }
  return resultobj;
}

This means that now I can call pm.MFaST_PMCreatePageSet() with only two parameters instead of three, and that both the status and the returned value will be returned in a tuple. Notice again the variables generated by SWIG and how they interact in the body of the typemap(in) and specially in the typemap(argout), where you can't reference the temporary variable, which means you can only dereference the argument (*$1) instead of trying to use the tempvar (temp).


[1] That is, the parameter is declared as int *foo and not int &foo. I think this is a mistake.

[2] I understand what it means now that I saw it in effect. At the beginning it was not clear, mostly because the (int temp) part and the fact that it has code associated.

[3] Except for the part that I will use PyObject_FromVoidPtr() and PyObject_AsVoidPtr() to create Pyhton objects with such values.


python

Roberto Alsina: Nikola Logo Contest!

So you ha­ve de­sign ski­ll­s? Want to make a li­ttle mo­ney whi­le do­ing a good thin­g? ­Then jo­in the con­tes­t! the­re is a 200 US do­llars gua­ran­teed pri­ze, and the con­test wi­ll be ju­dged by a group of Niko­la de­ve­lo­per­s.

So­me gui­dan­ce:

  • The na­me Niko­la co­mes from Niko­la Tes­la, so thi­nk con­cep­ts con­nec­ted to that
    • The Wa­r­­den­­cl­­y­­ffe to­­wer
    • Tes­­la Coils
    • Li­­gh­­tning
    • Ele­c­­tri­­ci­­ty
    • Ea­r­­ly 20­­th cen­­tu­­ry
  • I ho­pe the lo­go wo­rks we­ll in a va­rie­ty of for­ma­ts so, keep it sim­ple. B/W is good.
  • A drawing wi­thout the word Niko­la is good, but a good de­sign wi­th the word in it ­could be good al­so.

The con­test las­ts a week, you ha­ve 4 da­ys for the qua­li­fying roun­d.

And re­mem­be­r: it has to be be­tter than the­se

Gonzalo Martinez: Por que todavia no hay un PaaS en Argentina?

Es necesario que haya un PaaS en Argentina? Hay mercado? que tan buenos son los proveedores que hoy ofrecen algo parecido al IaaS o simplemente VPSs?

Este post va a ser simplemente una opinión y está por consiguiente cargado por mi vagaje, de creencias y/o de ideologia.

Amazon y RackSpace son enormes y son los que hoy se llevan todos los aplausos cuando se habla de IaaS [0] Son empresas que han innovado un montón. Amazon pasó de ser un enorme E-Commerce de libros, a una enorme empresa basada en lo último sobre redes, servidores y servicios de IT. RackSpace tiene otra historia pero hoy son dos de las más grandes y tienen varias ventajas con empresas nacionales razones obvias son que todo el hardware, redes, conexión a la red de internet y todo lo que es "VITAL" se comercializa en la misma moneda de su país de origen (eso obviamente no le quita todos los méritos de innovación o de masividad que han generado) pero si les dá una ventaja enorme por sobre cualquier otra empresa local que quiera hacer algo parecido. Hay desarrolladores y buenos ingenieros en argentina? Sin lugar a dudas dense una vuelta por los videos de PyConAr del año pasado[1] y verán un "¿montón de gente?" que hace cosas y que ama lo que hace. Nos faltan ingenieros lo sé, pero a ellos también les falta sino entren a sus Webs y verán que todas estás empresas tienen varios puestos abiertos alrededor del mundo de manera constante. Pero bueno yo creo que su principal ventaja es tener dos cosas una el monopolio de la moneda que ellos mismos imprimen y dos una cultura del esfuerzo y de la creencia firme de que se puede ser de los grandes [2]. Incluso esa idea es tan fuerte que atrae más a los inmigrantes que a los estadounidenses mismos. (Como aquello que cuando lo tenés muy cerca hace tanto ruido que te ensordece pero que desde la lejania te suena bien)

Sin IaaS no hay PaaS? Y básicamente no, por que PaaS es una capa de servicios más por encima de IaaS, conozco o veo buscando por internet muchas empresas de las nuestras que ofrecen todavia Hostings PHP/ASP+ MySQL y esas cosas que son viejisimas. El rango se reduce cuando buscás alguna que ofrezca VPS (ni hablar de los costos o rendimiento)  y el rango es casi nulo cuando se busca directamente infraestructura. Algunas empresas de las grandes (Telecom/IPLAN) seguramente ofrecen algo más parecido al IaaS a empresas grandes pero no hay nada para la otra gran parte del universo del mercado que son las pujantes pero grandes inversoras locales PyMes. Una PyMe o una StartUp técnologica hoy viendo costos no duda en pagar los dolares con su tarjeta más impuestos antes de poner su innovación dorada en los servidoruchos de muchos de los Hostings Locales. Sin ir más lejos "ElServer.com" todavía no puede estabilizar su servicio de correos que siempre anduvo muy mal y estamos hablando de correo no de OpenStack.

Puede haber mercado en la Argentina para esto? No lo sé. Acaso Amazon hizo un analisis de mercado o vió que podía hacerlo y lo hizo? Acaso la gente de Facebook antes de viralizarse se sentó y diagramó un gran plan comercial para ver si se podía o era fáctible ellos hicieron algo mejor algo mucho mejor. Hicieron Algo y ellos mismos construyeron a su alrededor la demanda.

Para finalizar por que no hay PaaS? No hay por que no hay IaaS y no hay IaaS por que todos los servidores, switches, caños de conexión a internet vienen envasados en "dolares". Software para hacerlo no nos falta por que hay miles de muestras opensorce esperando a ser forkeadas OpenStack, OpenNebula, CloudStack, Docker, lxc, Debian, Ubuntu, Fedora, CentOs, Dokku, y cientos de personas o empresas que han compartido un pedazo de su conocimiento.

En fin, yo quiero un PaaS que pueda pagar en pesos. Una locura tal vez? Pero una firme creencia de que llegará.

[0] http://en.wikipedia.org/wiki/Infrastructure_as_a_service#Infrastructure_as_a_service_.28IaaS.29
[1] http://www.youtube.com/results?search_query=PyConAr%202013&sm=3
[2] http://es.wikipedia.org/wiki/Sue%C3%B1o_americano

Gonzalo Martinez: Patrones de Diseño - Builder

Builder

Objetivo, Separa la construcción de un objeto complejo de su representación de modo que el mismo proceso de construcción puede crear diferentes representaciones.

Motivo:

Un lector para el formato de intercambio de documentos RTF (Rich Text Format) debería ser capaz de convertir RTF a muchos formato de texto. El lector puede convertir documentos RTF en texto plano ASCII o en un Widget de texto que pueden ser editados interactivamente. El problema, sin embargo, es que el número de conversiones posible es abierto. Por lo tanto, debe ser fácil de añadir una nueva conversión sin modificar el lector.

Aplicabilidad

Usar el patrón Builder cuando:

  • El algoritmo para crear un objeto complejo deber ser independiente de las partes que conforman el objeto y como están ensambladas.
  • El proceso de construcción debe permitir diferentes representaciones para el objeto que es construido.
Participantes

Builder,
- especifica una interfaz abstracta para crear partes de un objeto Product.
ConcreteBuilder
- construye y ensambla partes del productopara implementar la interfaz Builder.
- define y mantiene un seguimiento de la representación que crea.
- provee una interfaz para obtener el producto
Director
- construye un objeto usando la interfaz del Builder.
Product
- representa el objeto complejo en construcción. El ConcreteBuilder construye la representación interna del producto y define el procesos por el cual este es ensamblado.
- incluye clases que definen las partes constituyentes, inclyendo interfaces para ensamblar las partes en el resultado final.

Ejemplos de Código [0] [1]

La diferencia entre el Builder y el Abstract Factory
La principal diferencia es que el Builder se enfoca en construir un objeto complejo paso a paso. El Abstract Factory hace incapié en la familia de objetos producto (ya sea sencilla o compleja). El Builder retorna el producto como un paso final, pero en cuanto al Abstract Factory el producto es retornado inmediatamente.


[0] http://es.wikipedia.org/wiki/Builder_(patr%C3%B3n_de_dise%C3%B1o)
[1] http://tratandodeentenderlo.blogspot.com.ar/2010/02/patrones-de-diseno-builder.html

Gonzalo Martinez: Patrones de Diseño Creacionales - Abstract Factory

Los patrones de diseño creacionales son aquellos que abstraen el proceso de instanciación. Ellos ayudan a hacer un sistema independiente de como sus objetos son creados, compuestos, y representados. Una patrón creacional de clase usa herencia para variar la clase que es instanciada, mientras un patron creacional de objeto delegará la instanciación a otro objeto.

Los patrones creacionales se vuelven importantes en sistemas que pasan a depender más de la composición de objetos que de la herencia de clases. Como eso sucede, el enfasis cambia de modificar dificilmente un conjunto fijo de comportamientos hacia definir un conjunto pequeño de comportamientos fundamentales que pueden ser compuestos dentro de cualquier numero de los más complejos. Creando así objetos con un comportamiento particular que requiere más que simplemente instanciar una clase.

Abstract Factory

Intenta:
proveer una interfaz para la creación de familias objetos relacionados o dependientes sin especificar sus clases concretas.

Aplicación:

  • Un sistema debería ser independiente de como sus productos son creados, compuestos, y representados.
  • Un sistema debería ser configurado con una de múltiples familias de productos.
  • Una familia de objetos producto relacionados es diseñada para ser usados juntos y necestás hacer cumplir esta restricción.
  • Buscás proveer una biblioteca de clases de productos, y buscas revelar solo sus interfaces, no su implementación.
Participantes:
  • Abstract Factory - declara una interfaz para operaciones que crean objetos producto abstractos.
  • ConcreteFactory - implementa las operaciones para crear objetos producto concretos.
  • AbstractProduct - declara una interfaz para un tipo de objeto producto.
  • ConcreteProduct - define un producto objeto para ser creado por el correspondiente Concrete Factory. - implementa la interfaz del AbstractProduct.
  • Client - usa solo las interfaces declaradas por las clases AbstractFactory y AbstractProduct
Ejemplos de Abstract Factory en Python
[0][1][2]

[0] http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Factory.html#abstract-factories
[1] http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
[2] http://jpython.blogspot.com.ar/2012/09/python-design-pattern-abstract-factory.html




Gonzalo Martinez: Aprendiendo Erlang parte 6 Modulos I

Los módulos son un grupo de funciones reagrupadas en un solo archivo, bajo un nombre. Adicionalmente todas las funciones en erlang deben ser definidas en módulos. Ya has usado modulas tal vez sin darte cuenta. Las BIFs (Built-In Functions) mencionadas en el capitulo anterior hd o tl, en realidad pertenecen al módulo erlang, así como toda la aritmética. lógica u operadores booleanos. Los BIFs del módulo erlang difieren de otros módulos en que son automaticamente importados cuando usas Erlang. Cada una de las otras funciones definidas en un modulo que uses debe ser llamada con la forma Modulo:Funcion(Argumentos).

Lo podés ver por vos mismo:

1> erlang:element(2, {a,b,c}).
b
2> element(2,{a,b,c}).
b
3> lists:seq(1,4).
[1,2,3,4]
4> seq(1,4).
** exception error: undefined shell command seq/2

Aquí la función seq  del modulo lists no fue automáticamente importada mientras que element si lo fue. El error 'undefined shell command' viene desde la shell buscando por un comando shell como f() y no es capaz de encontrarlo. Hay algunas funciones del modulo erlang que no se importan automáticamente, pero tampoco son muy usadas.

Lógicamente, deberías ponet funciones similares dentro de un mismo modulo. Las operaciones comunes sobre listas son mantenidas dentro del modulo lists, mientras que las funciones de entrada y salida (como escribir en una terminal o en un archivo) son agrupadas en el modulo io. Uno de los únicos módulos que no respeta ese patrón es el antes mencionado modulo erlang que tiene funciones de matemática, conversiones, trabajar con multiprocesamiento, o jugar con la configuración de la máquina virtual, etc. Ellos no tienen ningún punto en común solo que son funciones previamente construidas (BIFs). Tu deberías evitar crear módulos como erlang y en su lugar enfocarse en separaciones lógicas limpias.

Declaraciones de Módulos

Cuando escribimos módulos, tu puedes declarar dos tipos de cosas: funciones y atributos. Los atributos son metadatos que describen el módulo en si mismo como es su nombre, las funciones que deberían ser visibles a el mundo exterior, el autor del código y así sucesivamente. Este tipo de metadatos es útil porque le dá indicaciones al compilador sobre como debe hacer su trabajo y también por que este permite a la gente obtener información útil sobre el código compilado sin tener que consultar las fuentes.

Hay una gran variedad de atributos de módulos actualmente usados en el código de Erlang a través del mundo, de hecho, podes incluso declarar tus propios atributos para lo que quieras. Hay algunos atributos predefinidos que aparecerán más frecuentemente que otros en tu código. Todos los atributos de módulo siguen la forma de -Nombre(Atributo).. Solo uno de ellos es necesario para que tu módulo sea compilable.

-module(Nombre).
Este es siempre el primer atributo (y declaración) de un archivo y por una buena razón: este es el nombre del módulo actual, donde el nombre es un atomo. Este es el nombre que usarás para llamar a funciones de otros módulos. Las llamadas son hechas con la forma M:F(A) donde M es el nombre del módulo, F la función, y A los argumentos.
Es hora de escribir código! Nuestro primer módulo será muy simple y poco útil. Abrí tu editor de texto y escribe lo siguiente, y guárdalo baje el nombre userless.erl

-module(useless).

Esta linea de texto es un módulo válido. Realmente! Por supuesto que esto es muy poco útil. Primero vamos a decidir que funciones vamos a exportar de nuestro módulo 'useless'. Para hacer esto, usaremos otro atributo.

-export([Funcion1/Aridad, Funcion2/Aridad, ..., FuncionN/Aridad]).Este es usado para definir que funciones de un módulo puede ser llamadas  desde el mundo exterior. Este toma una lista de funciones con su respectiva aridad. La aridad de una función es un entero que representa cuantos argumentos pueden ser pasados a la función. Esta es una información critica, por que diferentes funciones definidas dentro de un módulo pueden compartir el mismo nombre si y solo sí ellas tienen aridad diferente. Las funciones add(X,Y) y add(X,Y,Z), por lo tanto deberían ser consideradas diferentes y escritas en la forma add/2 y add/3 respectivamente.
Nuestro modulo useless exportará una función útil llamada 'add' que tomará dos argumentos. El siguiente atributo -export puede ser agregado después de la declaración del módulo.

-export([add/2]).

y ahora escribir la función

add(A,B) ->
    A + B.

La sintaxis de una función sigue la forma Nombre(Argumentos) -> Cuerpo. donde el Nombre tiene que ser un átomo y el Cuerpo puede ser uno o más Expresiones Erlang separada por comas.La función finaliza con un punto. Nota que erlang no utiliza la palabra clave 'return' . 'Return' es inutil. En su lugar, la última expresión lógica de una función a ejecutar tendrá su valor retornado al llamador automaticamente sin tener que mencionarlo.

Agrega la siguiente función (por que sí, todo tutorial necesita su ejemplo "Hola Mundo" Incluso en su cuarto cápitulo!)  sin olvidar agregar el atributo -export

%% Mostrar Saludo.
%% io:format/1 es una función estándar para salida de texto.
hello() ->
    io:format("Hola Mundo!~n").

Lo que se observa en esta función es que los comentarios son de una sola línea y comienzan con un signo % (se utiliza %% simplemente como una cuestión de estilo). La función  hello/0 demuestra como llamar funciones de otros módulos dentro de tu módulo. En este caso io:format/1 es la función estándar para escribir texto en pantalla como es escrito en el comentario.

[0] http://es.wikipedia.org/wiki/Aridad

Joaquin Tita: About Design

We live surrounded by tons of products that are no longer ordinary or inactives. Most of them are interactive and because we are so used to them, we are not conscious in what manner they contribute to our daily live. Those devices I'm talking about are mobile phones, personal computers, coffee machines, printers, videogames, just to list a few of them.
The important question here is: How many are easy to use and enjoyable without making a huge effort?
Of course, this is pretty easy to answer and the list will be quite small!
Sometimes we end up hammering our heads against the wall because we are not able to complete the desired task with this product.
Why this happens?
The answer is because some products were not designed with the user in mind.
The aim of interaction design is to solve these kind of issues bringing usability to the design process. That is, developing products that are easy, effective, and enjoyable to use from the user perspective.

Good Design vs Poor Design 
A good way to start thinking when a product has a good or bad interactive design is explore some examples that reflect the concept we are looking for.
Hitting the radio
Why I cannot use the radio while carrying my beverages?

Coffee Machine
In this coffee machine after inserting the coins in the slot you have to select your coffee bean. So, you press the rectangular labels to select your coffee but...they are not buttons! Probably you might think this because of Coke Can Machines work that way but...these ones not. Mmm...this is really working? Lets press the + or - sign that supposedly controls the amount of sugar...Wait WHAT? they are not buttons! After 10 minutes standing at the machine you can distinguish BLACK rounded buttons with BLACK background. Clearly a bad design!

Keyboard Layout
The guy who came up with this amazing design should be in prison right now. In fact, a friend used to have this keyboard. I never was able to use it. Every time I wrote something, suddenly the computer shut down unexpectedly...My friend always said to me "you probably has pressed the shut down key".  Nice...thanks for the two hours I have sent to the trash. Terrible design!

Thinking in What, Why and How
Suppose you have to design a new software product what would you do?
Start coding in a frenzy way until you are done with? Studying the characteristics of a well known similar software? Asking your end users about their experience, their problems, studying their tools and based on this start thinking about the what, why and how to design it? Probably the best approach would be the latter one. One of the main advantages is that you will definitely save money, time and effort.   

Conceptual Models
A good way to better understanding the problem domain is to develop conceptual models. By conceptual models we mean a description of the proposed system in terms of ideas and concepts about what it should do and look like also being understandable by the users. 
Developing conceptual models helps to envision the future product based on the user's needs and other requirements identified. As the product is being developed it is highly advisable to do iterative testing to ensure that it is designed to be understandable in the way that was planned. A key aspect in the design process is to identify what tasks the user will be doing when using the product. As with any aspect of interaction design, the process of filtering or cleaning the conceptual models should be done iteratively, using different methods such as sketching ideas, storyboards, brainstorming sessions (or visual brainstorming), describing scenarios (like "stories")  and prototyping aspects of how the system works.

Norman's Framework (1988)
One of the most important activities while developing a conceptual model is to determine if the users will understand the system in the manner intended. Norman presented a framework to make the relationship between the design of a conceptual model and the user's understanding be clearer.
Norman Framework
In this framework we can distinguish three different components:
  • the Design Model represents how the system should work, 
  • the System Image represents how the system actually works
  • the User's Model represents how he thinks the system works.
The point is that even though everybody should have the same idea or (metal model) of the system, real world doesn't work that way. Users, in most of the cases, are not able to complete their tasks effectively and error-free because their mental model is quite different from the Design Model and the System Image.
Jacob Nielsen wrote a blogpost explains a little bit what Mental Models are. In it, he says that mental models are "based on belief, not facts: that is, it's a model of what users know (or think they know) about a system such as your website". This definition brings to the light the discrepancies that Norman's Framework want to iron out. Also, "Metal Models" by Indi Young states that "metal models give you a deep understanding of people’s motivations and thought-processes, along with the emotional and philosophical landscape in which they are operating". Moreover, the author highlight the importance that these kind of models have. She summary this idea in the "three C's":


  • Confidence - guide the decision of the solution, 
  • Clarity - make good user and business decisions,
  • Continuity - ensure longevity of vision and opportunity.
Furthermore, Don Norman affirmed previously the idea that "the designer has an obligation to provide an appropriate conceptual model for the way that the device works. It doesn't have to be completely accurate, but it has to be sufficiently accurate that it will help in both the learning of the operation and also dealing with novel situations".


The Process of Design

Pabini Gabriel-Petit, a professional with more than 20 years of experience in User Experience and Design, in an article at uxmatter.com wrote that in the goal for achieving optimal design solutions, designers need an effective process that provides a framework to work with to deliver high quality work.
This should be a user-centered design (UCD) process, but also being a flexible process.  She came up with UC3D Lifecycle that comprises three phases: Discovery, Design, and Development Support.
UC3D Lifecycle - from uxmatters.com
The UC3D can be summarised in the following steps:
Discovery Phase:
  • Learning about your users 
Try to gain all the understanding possible of your users. Use your intuition to put yourself in your user's place. Once you truly understand your users, this understanding provides a basis for modelling your users. 
  • Modelling your users (like using model personas)
Once you are armed with all the information your group can develop profiles (or "personas" which are fictional user archetypes that are representative of your end users). Based on your information, you can develop a set of clearly differentiated user profiles whose goals and needs you intend your product to serve.
  • Analysing your user's tasks
This step comprise the identification of the tasks (task domain) that the user follow while using the future system and will be the basis for designing its workflows. Task analysis is an activity that can help you to understand much in depth the tasks.
  • Eliciting and Defining Clear Product Requirements
During this step requirements are clearly identified and prioritised. The working team will design and define what capabilities, features, and qualities your product must have. 

Design Phase:
  • Developing Conceptual Models
Conceptual modelling is an activity that helps your working group see your product's concepts, workflows, features, and language from your users's viewpoint and envision, define, and design products that are simpler, more consistent, and easier for users to understand.
  • Solving Key Design Problems Through Ideation
During ideation everyone on your working group has an opportunity to communicate requirements and constraints and contribute design ideas. Ideation involves rapidly generating many different possible workflows and user interface design solutions and capturing them by sketching designs on easel pads or whiteboards or in notebooks. As an example this can be seen in the video How Google fixed its design process and started making beautiful apps and also being part of the next step.
  • Doing Detailed Design
Once your working group has agreed on some basic design approaches during previous step, you will continue working on them during this step, continually refining your interaction design solutions by optimising workflows and interaction models, and creating design artifacts that communicate them effectively (like flowcharts and wireframes). All the feedback from the working group is taking into account to make more refinements on the design solutions. After all team is satisfied all stakeholders will approve design artifacts for implementation.

Development Support:
  • Providing Development Support
Your iterative process of design refinement should continue throughout product development as developers discover they need additional design details. All doubts that may arise should be answered by the working team to the people in charge of the development, and clarify design artifacts as necessary.
Also at this stage, if the testing reveals usability problems or usability issues you will need to do recheck your design solutions and artifacts. However, most of the usability issues you discover at this step are not addressed until the next product release. The Development Support Phase ends with the delivery of the (supposedly) high quality product that meets user's needs and is easy to learn and use.


Conclusion
Finally, if we can separate the less possible the Design Model and the User's Model making good conceptual models we will come up with understandable, enjoyable and easy to use products. In addition to have good conceptual models, expertise in the domain can help substantially. But, the implementation of an efficient design process such as UC3D will play a central role in the deliver of a high quality product.

Gonzalo Martinez: Rockeandola con Python Parte 3


Esta seguidilla de Posts sobre algunas cuestiones mas o menos avanzadas de Python tuvieron muchas visitas y eso me gusta no por que me sienta importante ni nada de eso sino por que alimenta mi idea de que compartir mi aprendizaje es útil para mí y para quienes leen cada tanto mi blog.

Hoy terminaré de contarles las cosas que se hacen con With, Partials, una particularidad sobre la relación entre los Zips y Python y algunas rarezas que se encuentran instaladas en nuestra libreria.

With

Este es un elemento copado bien utilizado se ve muy estetico para la lectura del código. Básicamente esta declaración ejecuta sobre el objeto que se le pasa los métodos mágicos __enter__ y __exit__
El ejemplo básico de este método es el de cerrar automáticamente el archivo cuando se sale de su alcance (scope).

with open('archivo.txt') as f:
    print(f.read())

Para la libreria de ejecución de comandos remotos llamada Fabric[2] es muy usada y yo diría tan bien usada que hace como dije al principio una mejor lectura del código un ejemplo es el de ejecutar comandos bajo un mismo directorio.

with cd('/path/to/app'):
    run('.mkdir una_carpeta')
    run('.wget http://unawebcopada.com.ar/el_archivo.tar.gz')

Partial

Parece ser común (todavia no me pasó) escribir el mismo método varias veces cambiando únicamente un parámetro.
Con partial se puede escribir un método como una plantilla y usarlo con diferentes argumentos fijos para generar un metodo que tenga una funcionalidad especifica algunos ejemplos que encontré por internet que me gustaron son los siguientes.

In [1]: from functools import partial
In [2]: base_dos = partial(int, base=2)
In [3]: base_dos.__doc__ = "Convierte texto de base 2 a un entero"
In [4]: base_dos('10010')
Out[4]: 18

Este [3] primer ejemplo es de crear una función especifica usando como template la función int que transforma un string en enteros para transformarla en una función que pasa strings en base 2 a entero.

In [1]: from functools import partial
In [2]: def plantilla_log(nivel, mensaje):
   ...:         print("{}: {}".format(nivel, mensaje))
   ...:     
In [3]: log_info = partial(plantilla_log, "info")
In [4]: log_cuidado = partial(plantilla_log, "cuidado")
In [5]: log_error = partial(plantilla_log, "error")
In [6]: log_info('Este es un log informativo')
info: Este es un log informativo

En este [4] se trata de una función que es un template sobre como hacer un log via pantalla y luego se generan las funciones especificas donde se fija el primer parámetro que es el nivel.

El amor entre Zip y Python 

Usted se preguntará si en la vida de la ejecución de código en python es todo .py? Esta es una pregunta muy razonable. pero veremos una respuesta un poco extraña

admin@quicuo-kaizen:/tmp$ cat __main__.py 
print "Estoy dentro de un ZIP"
admin@quicuo-kaizen:/tmp$ zip ejemplo __main__.py 
updating: __main__.py (stored 0%)
admin@quicuo-kaizen:/tmp$ python ejemplo.zip 
Estoy dentro de un ZIP

Y finalmente un poco de Diversión para cerrar estas 3 Partes de Rockeandola con Python

Parece que alguien alguna vez estaba hecho un poeta escribió una poesia sobre python y sus bases estéticas o de ideales. Esto pareció gustar tanto que fue incluida en el código fuente y al hacer lo siguiente se puede leer.

In [1]: import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Otra cosa muy interesante es, que es lo que pasa, cuando escribís en la consola interactiva de python "import antigravity". Yo diría que eso, es lo que siente uno cuando escribe en Python, que puede hacer un import y empezar a programar la Matrix misma.

[0] http://magmax.org/2013/09/30/python-avanzado.html
[1] http://effbot.org/zone/python-with-statement.htm
[2] http://docs.fabfile.org/en/1.6/api/core/context_managers.html
[3] http://docs.python.org/3/library/functools.html#functools.partial
[4] http://tech.pro/tutorial/1520/partial-function-application-in-python

Gonzalo Martinez: Patrones de Diseño - GoF - Introducción


"Programa una interfaz, no una implementación"

No declares variables para ser instancias especiales de una clase concreta. En su lugar, genera solo una interfaz definida por una clase abstracta.

Herencia Vs Composición

La herencia indica que una clase hereda muchas o todas sus características de una (o más) clase padre.

Cuando en Python hacemos

class Padre(object):
    def saltar(self):
        print 'Estoy saltando'

class Hijo(Padre):
    pass

Estamos diciendo que la clase Hijo hereda de Padre y le escribimos un "pass" para decir que no vamos a definir nada nuevo en esa clase. Entonces lo que sucederá es que el hijo va a heredar todo el comportamiento de su padre en este caso la clase hijo tiene de manera implícita el método "saltar" que hereda de su "Padre"

Hay otros detalles sobre el uso de herencias múltiples en Python que van a poder ver con más detalle en los links de referencia al final del Post [0]

La composición es definida en tiempo de ejecución a través de un objeto que adquiere referencias a otro objeto.Es un objeto que usa la interfaz de otro objeto lo que genera que se tenga que tener especial cuidado en el diseño. Y el objeto referenciado puede ser cambiado siempre que mantenga las mismas interfaces.

Un ejemplo de composición podría ser el siguiente:

Class HabilidadSalto(objetc):
    def ejecutar(self):
        print 'Estoy saltando'

Class Persona(object):
    def __init__(self):
        self.habilidadSaltar = HabilidadSalto()

    def saltar(self):
        self.habilidadSaltar.ejecutar()

No estoy seguro de que sea un ejemplo muy adecuado pero es aproximadamente a lo que se refiere básicamente un objeto tiene dentro suyo una referencia a otro objeto y usa la interfaz de este último para llamar a acciones concretas.

"Favorece la composición de objetos por sobre la herencia de clases"

Delegación

La delegación es una manera de hacer composición tan potente para su reutilización como la herencia.
Dos objetos son los involucrados donde uno recibe el pedido y delega la operación a su delegado. Un ejemplo podría ser el siguiente que yo escribí en Python basándome en la explicación del libro [1] Design Patterns de GoF.

class Rectangulo(object):
    def __init__(self, ancho, alto):
        self.ancho = ancho
        self.alto = alto

    def Area(self):
        return self.ancho * self.alto

class Ventana(object)
    def __init__(self, ancho, alto):
        self.rectangulo = Rectangulo(ancho, alto)

    def Area(self):
        self.rectangulo.Area()

Esto tiene ventajas como que la ventana podría cambiar su comportamiento en tiempo de ejecución tan solo reemplazando la referencia a la clase Rectángulo por una referencia a otra clase Circular. Esto suponiendo que Circular y Rectángulo son del mismo tipo.

Las siguientes son causas comunes para el rediseño y como los patrones de diseño ayudan en ellas.

1. La creación de un objeto especificando una clase explicitamente. Especificar una nombre de clase cuando creas un objeto te compromete con una implementación particular, en vez de una particular interfaz.
Patrones de Diseño: Abstract Factory, Factory Method, Prototype.

2. Dependencia de operaciones especificas. Cuando especificas una operación particular, te comprometes a una manera de satisfacer un pedido. Para evitar solicitudes codificadas específicamente, deberías hacer más fácil cambiar la manera en que un pedido es satisfecho ambos en tiempo de compilación y en tiempo de ejecución.
Patrones de Diseño: Chain of Responsibility, Command.

3. Dependencia de la plataforma de Software y Hardware. Las Interfaces externas del sistema operativo y de la interfaces de programación de la aplicación (APIs) son diferentes en diferentes plataformas de  hardware  y software. Es importante por lo tanto que el diseño de tu sistema limite las dependencias de la plataforma.
Patrones de Diseño: Abstract Factory, Bridge

4. Dependencia de representaciones de objetos o implementaciones. Los clientes que conocen como un objeto es representado, almacenado, asignado o implementado. puede ser que necesiten ser cambiados cuando el objeto cambie.  Esconder esta infroma de los clientes mantiene los cambios en cascada.
Patrones de Diseño,: Abstract Factory, Bridge, Memento, Proxy.

5. Dependencias Algorítmicas. Los algoritmos son a menudo extendidos, optimizados, y reemplazados durante el desarrollo y reuso. Los objetos que dependan de un algoritmo tendrán que cambiar cuando el algoritmo cambie.
Patrones de diseño: Builder, Iterator, Strategy, Template, Method, Visitor.

6. Estrecho acoplamiento. Las clases que están estrechamente acopladas son dificiles de reusar en aislación, ya que dependen una de otra. El estrecho acoplamiento lleva a sistema moniliticos, donde no puedes cambiar o eliminar una clase sin entender o cambiar muchas otras clases.
El Acoplamiento débil incrementa la probabilidad de que una clase puede ser reusada por si misma y que un sistema pueda ser aprendido, portado, modificado, y extendido más fácilmente.
Patrones de Diseño: Abstract Factory, Bridge, Chain of responsibility, Command, Facade, Mediator, Observer.

7. Extender funcionalidad subclasificando. La personalización de un objeto por subclaseo a menudo no es fácil. Cada nueva clase tiene un implementación fijada desde el vamos (inicialización, finalización, etc). Definir una subclase requiere un profundo entendimiento de la clase padre.
La composición en general y la delegación en paticular proveen alternativas flexibles a la herencia por combinación de comportamientos. Nuevas funcionalidades pueden ser agregadas a nuevas subclases por la composición de objetos en nuevas maneras antes que definir nuevas subclases de clases existentes.
Patrons de Diseño: Bridge, Chain of Reponsibility, Composite, Decorator, Observer, Strategy

8 Inhabilidad de alterar clases convenientemente. A veces tiene que modificar una clase que no puede ser modificada convenientemente. Quizás necesitas el código fuente y no lo tienes (como sería el caso de una librería comercial). O tal vez cualquier cambio requerirá la modificación de muchas de las subclases existentes. Los patrones de diseño ofrecen varias maneras de modificar clases en estas circunstancias.
Patrones de Diseño: Adapter, Decorator, Visitor.

En subsiguientes Posts estaré resumiendo o explicando según mi entendimiento otras partes de este libro que comencé a leer y que me interesa bastante.

[0] http://learnpythonthehardway.org/book/ex44.html
[1] http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612