DevelUY

Planeta de desarrolladores uruguayos

15 de septiembre de 2017

Enrique Almeida

Métricas sobre modularización de KB

Cuando tengo un sistema desarrollado, tengo muchísimas formas de dividirlo en módulos. Segun la bibliografia, el problema mas general de particionar un grafo en diferentes agrupamientos de nodos (clusters) es considerado NP-Completo, por lo que no se ha encontrado aun una forma eficiente de resolverlo.

Al tener tantas opciones, es bueno contar con alguna herramienta que me permita medir que tan buena o mal es dicha division, en el caso de una KB, seria medir que tan buena o mala es la modularizacion que he realizado.

Algunas de las características perseguidas por la modularizacion, son la de tener un gran cohesion entre los nodos que están dentro de un modulo y tener poco acoplamiento con otros módulos.

Esto se traduce, a que queremos maximizar las  aristas dentro de los módulos y minimizar las aristas entre los módulos.

Resulta mas facil, verlo en imagenes. Supongamos que tenemos un grafo que representa la relaciones entre objetos. Los objetos pueden ser cualquier objeto ejecutable (procedimientos, data providers, data selectors, web panels, SDPanels, etc) y tambien tablas que son leidas o actualizadas por dichos programas. No se consideran ningun de los objetos "no ejecutables" como las instancias de patterns, atributos, folders, modulos, documentacion, diagramas, etc.

Un ejemplo, de una KB muy sencilla con un unico modulo, seria:
En este caso, todos las llamadas serian INTRA-modulo.

En el otro extremo, podemos definir un modulo, por cada objeto:
En este caso, todas las llamadas serian INTER-modulos.

En un caso mas util, podria definir dos modulos de la forma:

con lo cual, tendriamos llamadas INTER e INTRA modulos.

Indicador de cohesion. 

Para cada modulo, podemos contar la cantidad de aristas intra-modulos y dividirla por la mayor cantidad de aristas posibles (es la cantidad de nodos del modulo al cuadrado).

Por ejemplo, si tengo el módulo1:

que tiene

Cantidad de aristas intra-modulo = 3
Cantidad de aristas posibles = (Cantidad de Nodos del Modulo) al cuadrado = 9

Indicador A1 = 3/9 = 0.3333....

Este valor, (que va a estar entre 0 y 1) querriamos que fuera lo mas alto posible y lo podremos mejorar, moviendo nodos de un modulo a otro.


Indicador de acoplamiento. 

Dado dos modulos, M1 y M2, cada uno con N1 y N2 nodos respectivamente.
Queremos medir que tan acoplados estan dichos modulos, por lo que podemos definir un indicador que mire la cantidad de aristas que une un modulo con el otro y dividir entre la cantidad posible de arcos que puede tener entre ambos (2 * N1 * N2)

Por ejemplo, si tenemos
M1
Cantidad de Nodos = N1 = 3

M2
Cantidad de Nodos = N2 = 4

El indicador de acoplamiento entre M1 y M2 se llama E12 y se puede calcular

E12 = Cantidad de aristas entre M1 y M2 / Cantidad de aristas posibles entre M1 y M2

E12 = 1 / (2*3*4) = 1/24.

Este indicador va a estar entre 0 y 1.
Siempre trataremos de minimizar este indicador entre los diferentes modulos, de forma que queden bien desacoplados, o sea tener modulos lo mas independientes posibles, lo cual hara que sean mas faciles de mantener.

Indicador de Modularizacion MQ  

Si tenemos un buen indicador para la cohesion (que queremos maximizar) y un buen indicador para el acoplamiento (que queremos minimizar) podemos unirlos en un unico indicador que sea:


MQ = Suma indicadores de cohesion de todos los modulos - Suma indicadores de acoplamiento para todo par de modulos.

Para poder tener un indicador que sea comparable en forma independiente de la cantidad de modulos que tenga la KB, se puede normalizar por dicha cantidad, con la que la formula definitiva quedaria.




donde k es la cantidad de modulo de la KB, Ai es el indicador de acoplamiento del modulo i y Eij es el indicador de acoplamiento entre el modulo i y el modulo j.

Algunos ejemplos


Solo un modulo

En el caso de tener solo un modulo en la KB, tendriamos
k = 1
A1
 Cantidad de aristas intra-modulo = 9
 Cantidad de aristas posibles - intra-modulo = 7 Nodos al cuadrado = 49

A1 = 9 / 49 = 0,183

MQ = 0.183

Siete Módulos


En este caso, tenemos 
k=7

A1-A7 
 Cantidad de Aristas intra-modulo = 0
 Cantidad de Aristas posibles intra-modulo = 1
  A1-A7 = 0

E12
Cantidad de Aristas entre modulos 1 y 2 = 1
Cantidad de Aristas posibles entre modulos 1 y 2 = 2*1*1 = 2
E12= 0.5

Se puede seguir calculando y tenemos

Por lo que el indicador MQ quedara

MQ = Suma A1-A7 - (1/(k(k-1)/2) * Suma Eij (i=1 a 7, j=1 a 7)

MQ = 0 - (1/(7*6/2)) * 4,5 = -0.214 

MQ=-0.214

Ejemplo 2 Módulos. 

A1 = 3 aristas intra modulo / 9 aristas posibles = 0.333
A2= 5 aristas intra modulo / 16 aristas posibles = 0.313

E11 = 0
E12 = 1 arista entre modulos / (2* 3 nodos en M1 * 4 nodos en M2) = 0,041
E21 = 0
E22 = 0

MQ = 1/2 * (A1+A2) -  (1/(2*1)/2) (E11+E12+E21+E22) = 0.343  - 0,041 = 0,302

MQ = 0,302


Conclusiones

El indicador MQ, va a estar entre -1 (sin nada cohesion) y 1 (sin acoplamiento entre módulos y un grafo con todas las aristas dentro de los nodos del modulo).

Cuanto mayor sea el MQ va a ser una modularizacion mejor.

Esta metrica no es demasiado eficiente en su cálculo, pero es fácil de entender.

Teniendo un indicador, hace posible tener una herramienta que compare dos modularizaciones y elija la mejor. Es el primer paso para hacer una modularizacion semi-automática.

UPDATE: En caso de querer utilizar pesos en las aristas, por ejemplo para hacer pesar mas una referencia del tipo ACCEDO A TABLA, que LLAMADO A API, se puede utiliar el siguiente indidador.

donde

= suma de los pesos de arcos intra-modulo
= suma de los pesos de los arcos inter-modulos

Es un poco mas rápida para calcular y permite manejar mejor referencias de diferente peso. El 1/2 es para hacer pesar en ambos módulos el peso de las aristas entre ambos modulos.




por noreply@blogger.com (Enrique Almeida), el 15 de septiembre de 2017 a las 12:42

13 de septiembre de 2017

Fernando Briano

¡Feliz día del programador!

Como es tradición desde hace 10 años en este blog*, aprovecho el día del programador para desearle feliz día a mis colegas y hacer un repaso de lo que he estado haciendo como programador.
*excepto el año pasado que me olvidé o no me sentía motivado para escribir algo al respecto…

El día del programador se celebra en el día número 256 (28) del año por ser la cantidad de valores representables en un byte de datos (13/9 en los años comunes y 12/9 años bisiestos).

Code Monkeys

Este año me agarra en un muy buen momento en lo que se refiere a la programación. Hace poco más de un mes me mudé a Escocia, trabajando en Cultivate. Estuve casi 3 meses trabajando en un proyecto para cliente con Ruby On Rails, y tuvo un cierre bastante exitoso con las partes conformes con el trabajo realizado.

Sigo usando Emacs como editor de texto y aprendiendo como siempre con él. Pero como en Cultivate hacemos mucho pair programming, buscamos usar una herramienta común. Por eso he estado trabajando con Spacemacs, una “distribución” de Emacs que une a Emacs y Vim en un sólo ambiente. Lo hemos incorporado de manera bastante exitosa junto a tmux y tmate para hacer pairing remoto.

                      ░░░░░░░░░▄░░░░░░░░░░░░░░▄░░░░
                      ░░░░░░░░▌▒█░░░░░░░░░░░▄▀▒▌░░░
     Such powerful    ░░░░░░░░▌▒▒█░░░░░░░░▄▀▒▒▒▐░░░
                      ░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐░░░
                      ░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐░░░  Vim and Emacs
                      ░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌░░░    So love
                      ░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌░░      Much forbidden
                      ░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐░░
Very modes            ░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌░
                      ░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌░
                      ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐░
                      ▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌
                      ▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐░
                      ░▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌░
                      ░▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐░░
                      ░░▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌░░
                      ░░░░▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀░░░      Wow.
                      ░░░░░░▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀░░░░░
                      ░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▀▀░░░░░░░░
  ██████╗  ██████╗  ██████╗ ███████╗███╗   ███╗ █████╗  ██████╗███████╗
  ██╔══██╗██╔═══██╗██╔════╝ ██╔════╝████╗ ████║██╔══██╗██╔════╝██╔════╝
  ██║  ██║██║   ██║██║  ███╗█████╗  ██╔████╔██║███████║██║     ███████╗
  ██║  ██║██║   ██║██║   ██║██╔══╝  ██║╚██╔╝██║██╔══██║██║     ╚════██║
  ██████╔╝╚██████╔╝╚██████╔╝███████╗██║ ╚═╝ ██║██║  ██║╚██████╗███████║
  ╚═════╝  ╚═════╝  ╚═════╝ ╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝ ╚═════╝╚══════╝

Como toda nueva herramienta al principio hay que acostumbrarse y aprenderse atajos de teclado, meter mano en alguna configuración y demás. Pero tmux es un camino sólo de ida, sumamente recomendable empezar a usarlo.

Curiosamente en el post de 2015 comentaba que había estado jugando con Elixir, y sería un tema al que volvería. Al terminar el proyecto anterior, empecé de lleno a entrarle a Elixir. En Cultivate se usa y hay algunos proyectos internos, así que estoy estudiando y aprendiendo Elixir. Es un lenguaje funcional, diseñado por José Valim (viejo conocido del mundo Ruby). Esto te lleva a cambiar un poco la forma de programar respecto al paradigma de orientación a objetos.

Lenguaje nuevo, ecosistema nuevo, paradigma nuevo, pero con algunas cosas familiares. Se puede hacer un paralelismo con lo que viene siendo mi vida en un nuevo país. Generalmente me siento perdido, y las cosas no funcionan como antes, pero le termino encontrando la vuelta y sigo adelante. Un desafío bastante grande, entre adaptarse a la nueva cultura y al reto tecnológico. Creo que mi cerebro ha estado absorbiendo y procesando más información en el último mes que muchos meses juntos antes. Pero es una buena experiencia tanto laboral como personal, así que seguro es para bien.

Por otro lado, después de unos cuántos años, vuelvo a asistir a una conferencia de Ruby. A fin de mes voy a ir a Euruko, la conferencia Ruby europea. Si no recuerdo mal, mis últimas conferencias Ruby fueron Scottish Ruby Conference, RubyConf Uruguay y RubyConf Argentina todas en 2014. Desde entonces he ido a conferencias de otras tecnologías pero les perdí bastante el interés (comentaba algo en los 10 años del blog).

Voy a Euruko con mucha expectativa, el keynote inicial está a cargo del mismísimo Matz, creador de Ruby. También hablan Charles Nutter, Sebastián Sogamoso y Netto Farah a quienes he tenido el gusto de ver en RubyConf Uruguay, y Bozhidar Batsov creador de Rubocop, hablando sobre Ruby 4, y otras tantas charlas más muy interesantes. El interés por Elixir medio que renueva las ganas de asistir a eventos también.

Así que una vez más este año apreté “Reset” y arranqué varios aspectos, incluida la programación, desde cero. Así están las cosas por Picando Código. Feliz día del programador. A los que sigan leyendo del otro lado, ¿en qué andan por estos días? ¿Qué están programando?

El día del programador otros años: 200720082009201020112012201320142015

por Fernando, el 13 de septiembre de 2017 a las 09:00

5 de septiembre de 2017

Cristhian Gomez

Tamaño de Campos Blob en MySQL

p, li { white-space: pre-wrap; } Tenía la necesidad de poder saber cuanto pesaban los datos que se estaban guardando en un campo blobs para poder dimensionar y controlar el tamañao que iba a tener mi tabla en el futuro.  Para esto encontré la siguiente consulta: select length(NombreCampoBlob) as byte from Tabla; Esta consulta me tira en bytes el tamaño de mi campo.

por Cristhian Gómez (noreply@blogger.com), el 5 de septiembre de 2017 a las 16:02

3 de septiembre de 2017

Alejandro Segovia

Multiple Directional Realtime Lights

This week work went into supporting multiple directional realtime lights in the new Vortex V3 renderer.

Multiple Realtime Lights rendered by Vortex V3.

Multiple Realtime Lights rendered by Vortex V3.


In the image above, we have a scene composed of several meshes, each with its own material, being affected by three directional lights. The lights have different directions and colors and the final image is a composition of all the color contributions coming from each light.

In order to make the most out of this functionality in the engine, I revamped the Light Component Inspector. It’s now possible to set the direction and color through the UI and see the results affect the scene immediately. You can see the new UI in the screenshot above.

Now, since lights are entities, I considered reusing the entity’s rotation as a way to rotate a predefined vector and thus defining the light. In the end, however, I decided against it. The main reason was that I think it is more clear to explicitly set the direction vector in the UI rather than having the user play with angles in their head to figure out an obscure internal vector. This way, you can specify the vector directly.

I’m pretty happy with the results. Internally, each light is computed individually and then all contributions are additive-blended onto the framebuffer. This means the cost of render n objects affected by m lights is going to be n + m draw calls. This is a big advantage over the forward rendering equivalent, which would require at least n * m draw calls.

Notably missing from the image above is color bleed. Photorealism is addictive: the more your approximate real life, the more you can tell when an image is synthetic if something is missing. This will be a topic for another time however.

Next week I want to make some additions to the material system to make it more powerful, as well as start implementing omnidirectional lights.

Stay tuned for more!

por Ale, el 3 de septiembre de 2017 a las 00:11