jueves, 3 de mayo de 2012

Reflexiones con Pareto

Nada como temprano en la mañana con 10 estudiantes para aprovechar de hacer algunas reflexiones. Hoy quiero compartir una que andaba rondando mi cabeza hace algunos años ya... y al final con los estudiantes salio algo en concreto. Para todo efecto, programador principiante y estudiante se utilizan para indicar lo mismo en este texto.

Contexto

Los estudiantes presentaron un práctico de programación relativamente complejo implementando el algoritmo de Dijkstra para encontrar el camino entre dos nodos de un grafo. El ambiente era, por supuesto, de caras largas, desvelados y con algo de frustración en lo poco de impulso que les quedaba. Todo esto a pesar de haber tenido varios días feriados y suficiente tiempo para preparar esto.

Entiendo que es algo que un estudiante hace e hizo desde siempre... en toda latitud, pero con ligeros cambios (ya lo veremos)

Pareto

Luego de la revisión comenzamos leyendo lo que indica este principio en wikipedia:

Así por ejemplo cuando hablamos de los costes de desarrollo podríamos decir que "el 80% del esfuerzo de desarrollo (en tiempo y recursos) produce el 20% del código, mientras que el 80% restante es producido con tan sólo un 20% del esfuerzo"

Acompañado por el siguiente diagrama en la pizarra:

con los comentarios

  1. Si en 10 días se hace algo, en los primeros 2 tenemos 80% del código.
  2. Qué se hace en los otros 8?
  3. Ah... en los primeros 8 leemos y entendemos y en los últimos dos se codea todo.

Vamos por partes. La primera oración es un buen punto de partida. Cuando ya se han hecho algunos sistemas, no le queda a uno otra que sentar la cabeza y aceptar lo indiscutible. Se sabe y está recontra probado que el 80% del esfuerzo sirve para dejar al sistema sin errores y listo para ser llevado al cliente... lo cual responde a nuestra segunda pregunta.

La tercera es más interesante en el sentido que refleja la percepcion de sistema desde el punto de vista de un desarrollador principiante conformista.

El conformista

En un ambiente poco tecnológico como es el ambiente académico en Bolivia, existen pocas chances que los programadores principiantes se empapen de buenas prácticas a nivel internacional, de ahí el contagio de una percepción errónea de un sistema. Luego de varios años de docencia, aquí planteo la visión del conformista recabada de la percepción de programadores de 19, 20 y 21 años (alrededor de 100 personas) durante los últimos 5 años:

Así, para el conformista, el 100% del sistema significa el terminarlo hasta cuando funciona para el caso más trivial donde todo va bien. Esto se traduce a una típica ausencia de: manejo de errores, testeo, control de calidad, funcionalidad avanzada, y otros. Además, siendo esa la percepción, nuestro individuo además dice: "Mmmhh... con 90% que haga ya la rompí". Lastimosamente, como se ve en la figura, ese 90% en realidad se transforma en un 72% muy mediocre (regla de tres simple) que es el que percibe el cliente. /p>

Para liquidar a la tercera premisa, algunos estudiantes me preguntaron: qué es de esos 8 días donde se lee y entiende el problema para hacerlo? La respuesta es trivial, esos días están simplemente fuera del gráfico y se encuentran ANTES de realizar el esfuerzo :-)

Al principio hice una alusión a estudiantes en todas las latitudes. La diferencia está en cómo percibe el estudiante ese 100%. Es por ello que puse la palabra conformista. El conformismo NO es cierto en todas las latitudes y, por supuesto, en aquellos lugares de mayor renombre la percepción del 100% está mucho más cerca de la realidad.

... y la solución?

Hasta aquí el ejercicio sirve para reflexionar, pero cómo encontramos soluciones para esto? No es un problema sencillo, implica inculcar en las personas la percepción del cliente (mínimamente) y es más, en lo posible pensar en un 120% total donde el 20% extra es lo que ofrecemos al cliente como valor agregado.

Un ejercicio muy pequeño, pero que me ha dado algunos resultados es stackoverflow. Si, desde el momento que los estudiantes comienzan a crear su reputación; pueden ver cómo sus respuestas son editadas, comentadas y van aprendiendo la manera en que el resto de las personas espera una respuesta. De a poco, sus respuestas son más completas y mejor estructuradas. Como todo lo bueno sin embargo, tarda. Y no estoy loco para pensar que los estudiantes aplican esto de la noche a la mañana... son procesos, pero estoy apostando a un pequeño cambio que puede ser monitoreado para medir su impacto; lo cual nos (me) deja en un lugar sustancialmente mejor que hace algunos años cuando comencé (me la inculcaron) estas reflexiones.

viernes, 12 de agosto de 2011

Manual de Latex

Y si, luego de 12 años de haberlo hecho y a sugerencia de Jose Miguel, aqui les paso un manual completito de Latex.

Bueno, qué puede traer de bueno este manual?


  • Aprender Latex como objetivo 1

  • Consulta sobre la funciones matemáticas que tiene Latex

  • Consulta sobre la funciones de bibliografía que tiene Latex



En cada capitulo he tratado de colocar una práctica para que puedan revisar lo aprendido del capitulo y tengan un ejemplo completo.

En general he tratado que el manual tenga todas las funciones que he necesitado para realizar mi tésis, es posible que se me haya ido algo, cualquier pedido extra... me avisan :-)

Aquí el PDF completo

martes, 24 de agosto de 2010

Search MF... search!

Trabajando con los muchachos hemos estado poniendo a punto un mini interprete de SQL para SQL Server. Esto ha dado lugar a una pequeña librería SearchComponent. Lo que queremos hacer es lo siguiente:

  1. Definir en una libreria de Search que queremos buscar en la tabla X, columnas A, B y C.

  2. Tener consultas del estilo: a=Madrid & b=45:56 para decir por ejemplo que filtre en la columna a con un LIKE a Madrid y la columna b con un BETWEEN entre 45 y 56.

  3. Finalmente, obtener el DataSet resultante y mostrarlo.


Por fin tenemos un pequeño prototipo que se puede utilizar y que quisieramos compartir. Esta en forma de un articulo en codeproject:
En el articulo se explica la libreria y de donde sale todo. En este site, para los lectores les damos un ZIP listingo para probarlo:

  1. Crear una base de datos en SQL Server que se llame searching

  2. Restaurarla con el BAK que se encuentra en el ZIP

  3. Abrir, compilar y ejecutar el website en el ZIP para ver la magia


El ejemplo que les paso tiene la siguiente estructura en la base de datos:

Algunos ejemplos de lo que deberian ver estan aqui:

  • Buscar todos los articulos que tienen en la descripcion 'crema nivea'


  • Observe que con FTS se encuentran todas las variaciones.

  • Buscar que antigripales se vendieron en 2008



Como dice... sky is the limit.
Espero les guste.

sábado, 11 de julio de 2009

Hanoi.... para las masas

Un problema muy típico de lenguaje de programación es la muy conocida estructura de torres de hanoi. Es algo básico que tiene cualquier programador.

El programa trata de despertar la recursividad (recurrencia) que está en el programador para mostrarle la solución sencilla a un problema aparentemente complejo:

En suma, se tienen 3 torres con 3 anillos de diferente tamaño colocados en orden:



La idea es llevar los 3 anillos de la primera a la última torre con dos reglas muy sencillas:

- No se puede llevar varios anillos a la vez, tiene que ser de uno en uno
- El anillo que coloques en una torre debe estar obligatoriamente sobre otro más grande

El problema típico es hacer un programa que, como input=3 obtengas:

De 1 a 3
De 1 a 2
De 3 a 2

De 1 a 3

De 2 a 1
De 2 a 3
De 1 a 3

Lo partimos así porque el primer bloque es en realidad hanoi con 2 anillos llevando de torre 1 a torre 2, vamos a ponerlo: hanoi(2, t1, t2)

El tercer bloque es en realidad hanoi con 2 anillos llevando de torre 2 a torre 3: hanoi(2, t2, t3)

La solución general es entonces para n anillos de torre 1 a torre 3:

hanoi(n-1, t1, t2)
hanoi(1, t1, t3)
hanoi(n-1, t2, t3)

Aquí tienen una solución con Java, Swing y con log4j (para que vayamos creando la costumbre de hacerlo con esto). La estructura es lo más importante.

Espero lo disfrutes!!

lunes, 15 de junio de 2009

Un poco tarde, pero DAO al fin

Hace mucho tiempo que quería escribir este artículo sobre el DAO, pero no había tenido el impulso necesario para hacerlo. No sé bien lo que me impulsa ahora, pero aquí está.

Luego de averiguar por todo lado la mejor manera de hacer esto (conectarse y recuperar datos de una BD de manera ordenada y escalable) descubrí el DAO, un poco tarde ya que al año siguiente salió la versión beta de JPA y claro, todo el DAO se derrumbó (o comenzó a derrumbarse...)

La versión de JAVA basa todo su modelo en esta relación fundamental de 4 componentes:



En el caso del DAO con todas las recomendaciones integradas, tendrás un grupo de clases (DAO, DTO y otras de acuerdo a implementación) por tabla (por ejemplo Persona) por motor de base de datos o persistencia que desees utilizar: XML, Mysql, archivos, etc; donde no necesitas más que lo siguiente para hacer un select * from:


FactoryDAO factory = FactoryDAO.getOrCreate();
PersonaDAO dao = factory.newPersonaDAO();
Vector lista = dao.getTodos();


Lo elegante es que no necesitas SQL en ningún lugar y puedes tener la librería de los DAO aparte.

Pero veamos en detalle este modelo:



Primero podemos observar el modelo de DTO (la object-ivización de la tabla BTNombres en este caso).

También se ve el modelo de Factory que se debe crear (una implemetnación de Factory por persistencia utilizada).

En la siguiente figura:



Se puede ver el modelo de los DAO, BTNombresDAO es la clase que tiene todo el actualizar, seleccionar, eliminar....

Cómo fue que se pudo hacer esto si aplica a tablas diferentes?

1. Todas las tablas tienen un id, un campo que se llama id de tipo entero que funciona de llave
2. La superclase es en realidad una clase generic

De esta manera, el código para hacer el update al registro 3 de la tabla Persona se hace así:


FactoryDAO factory = FactoryDAO.Instancia;
PersonaDAO dao = factory.newPersonaDAO();
PersonaDTO objPersona = dao.seleccionar(3);

objPersona.setNombre("Pedro");
dao.actualizar();


Nuevamente vemos la elegancia de evitar el uso de SQL y la independencia con la conexión: no sabemos si escribe a un fichero, una base de datos, etc.

Para fines más laborales, he creado un generador de capa de datos que sigue el mismo modelo (lo único es que genera csharp y no java... oops), que toma en cuenta también lo siguiente:

- Código para aplicar Logs con log4net
- Los updates solamente se hacen sobre los campos que han cambiado y no sobre todas las columnas de un registro (util para ciertos análisis en algunas bases de datos)
- Posiblidad de realización de transacciones con modelo similar (aumentando dos líneas de código).

La última línea habla de transacciones, sin embargo, todo eso quedó atrás con el Java Transaction y el Java Persistence, por ello el título del artículo.

EL generador y más explicaciones sobre el modelo los subiré en unas semanas a sourceforge (anunciado aquí también). Pero para los impacientes les puedo pasar un código super desprolijo pero que hace el trabajo :-)

miércoles, 6 de mayo de 2009

El paceño, potosino, cochala, sucrense y orureño que no quiere ser colla



Este es un post racista (para algunos); para todos los demás autónomos, ganaderos, terroristas, separatistas de este país trata de ser una reflexión que creo compartir con todos y que además quisiera compartir con el resto de paceños, potosinos, cochalas, sucrenses, orureños y en general para todo aquel que por sus facciones, forma de hablar u otros pueda ser tildado de colla.

En wikipedia:

"Colla se utiliza para denominar a los descendientes aymaras (en su mayoría indígenas o indios) de los departamentos de La Paz, Oruro, y Potosí de Bolivia. Estos departamentos están ubicados en la zona occidental del país. Ocupan mayormente zonas de clima montañoso de los Andes aunque también en áreas tropicales. Los rasgos más sobresalientes de un colla son unas mejillas rojizas y secas quemadas por el frío de los andes bolivianos, tienen rasgos asiáticos, la piel algo más oscura que la de los demás grupos étnicos de Bolivia. El actual presidente boliviano don Evo Morales Aima, es un indígena andino, perteneciente a este grupo étnico."

En RAE:

colla.(Voz quechua).

  1. adj. Se dice del individuo mestizo de los pueblos diaguitas, omaguacas, atacamas, quechuas o aimaras, asentados en la Puna o provenientes de ella. U. t. c. s.

  2. adj. Perteneciente o relativo a los collas.

  3. com. Bol. Persona que habita en las mesetas andinas.

  4. com. Bol. Persona que ha nacido o vive en la región occidental de Bolivia.



Lo importante es darnos cuenta que colla es tradicionalmente casi cualquier persona del occidente de Bolivia (como indica RAE). En mi caso particular, debo decir que soy un colla de pura cepa ya que no solamente he NACIDO en La PAz (occidente de Bolivia) sino que tengo ascendencia indígena (mestizo proveniente de aymaras en mi caso).

Llevo con mucha honra este denominativo ya que la descendencia de estos pueblos, como la de todos, es sumamente rica en cultura y tradiciones; aparte de haber jugado su papel en la historia boliviana.

Tengo muchísimos amigos collas a los que con mucho cariño los denomino como tal, por su nombre o por su apodo (no hay un orden particular y depende del momento).

Espero esto ayude al fortalecimiento de la palabra en sí... colla, como un reencuentro con nuestros antepasados y un orgullo de representar a una parte importante del país. Lo que NO ACEPTO, son aquellos que no logran entender la magnitud de esta palabra.

Finalizando, y para aclarar el tema del posible insulto, cabe destacar que a costumbre del insultador, se suele enunciar 'colla de mierda'. Es aquí donde DEBEMOS identificar el insulto, en el 'de mierda', no en el 'colla'. Dejando de lado un papel de víctima racista.

Bueno, estas fueron algunas palabras para aclarar el panorama en este sentido... no me pregunten por qué... estaba matando el tiempo antes del partido.

jueves, 30 de abril de 2009

Algo light... muy light... java / mysql

Algo que todo el mundo no se cansa de tenerlo cerca, una guí breve y rápida para lograr conectar un programita Java con una base de datos Mysql.

Las partes del Logger las pueden quitar (import + log.info + log.error).

package capadatos.test;

import java.net.URL;
import java.sql.*;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
* Esta clase es nada más para realizar un test contra una base de datos
* Mysql. El script de la tabla a la cual se hace consulta sigue a
* continuación:
*
* create table persona (
* id int(10) unsigned NOT NULL auto increment,
* nombre varchar(100) default NULL,
* fechaNacimiento datetime NOT NULL,
* salario float NOT NULL,
* PRIMARY KEY (id)
* );
*/
public class TestMySql {

private static Logger log = Logger.getRootLogger();

public static void main(String[] args) {
String resource = "/auditoria.properties";
URL configFileResource = TestMySql.class.getResource(resource);
PropertyConfigurator.configure(configFileResource);

String host = "localhost";
String database = "estructura";
String instance = "";
int port = 3306;
String username = "root";
String password = "……"; // colocar la contraseña

String url = "jdbc:mysql://" + host + "/" + database;
Connection con = null;

boolean driverOk = false;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
driverOk = true;
} catch (InstantiationException e) {
log.error("No pudo instanciar, seguramente no hay la libreria", e);
} catch (IllegalAccessException e) {
log.error("No tiene permisos para instanciar", e);
} catch (ClassNotFoundException e) {
log.error("No encuentra esa clase, revise la librería o la versión de la misma",
e);
}
if (!driverOk)
System.exit(0);

try {
con = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
log.error("No pudo conectarse a la base de datos", e);
System.exit(0);
}

String query =
"SELECT id, nombre, fechaNacimiento, salario FROM Persona";
ResultSet res = null;
try {
Statement stmt = con.createStatement();
res = stmt.executeQuery(query);
} catch (SQLException e) {
log.error("No puede ejecutar la consulta SQL", e);
System.exit(0);
}

try {
while (res.next()) {
int _id = res.getInt("id");
String _nombre = res.getString("nombre");
Date _fechaNacimiento = res.getDate("fechaNacimiento");
double _salario = res.getDouble("salario");

System.out.println("(" + _id + ") '" + _nombre + "' " + _fechaNacimiento.toString() + " :" + _salario);
}

con.close();
} catch (SQLException e) {
log.error("Error en el motor SQL", e);
}
}
}

viernes, 5 de diciembre de 2008

El problema chileno - boliviano

Otra del IT world, me imagino que los estudiantes de historia tienen esto muy a mano, sin embargo es la primera vez que lo veo:

http://pds.lib.harvard.edu/pds/view/3813297?n=90&s=4

Una declaración del ministro de relaciones exteriores de CHile realizada el 3 de marzo de 1879. Está el texto original, y más encima traducido al francés e inglés.... un poco al estilo de la declaración de Unasur actual, que ahora la traducirán al quechua, aymará, inglés, portugués y será difundida.

nos vemos

martes, 2 de diciembre de 2008

Luego de varias décadas del bendio teclado y el dañino mouse para nuestras extemidades, aquí algo que ya estamos cerca de lograr. Una visión un tanto diferente:

http://www.youtube.com/watch?v=muibPAUvOXk

"todavía queda mucho por hacer..."

lunes, 1 de diciembre de 2008

a la mercury....

Super lugar geek:

The Mercury Theater Show
http://www.mercurytheatre.info

entre las joyitas de este site está el programa completo de Orson Wells 'The war of the worlds', posiblemente 32 millones de radio escuchas y miles de personas que huían despavoridos.

viernes, 21 de noviembre de 2008

temas pa'l correo g






No podemos quedar indiferentes ante lo espectacular de los temas del gmail a partir de ayer.

Muy bueno!!!

Lo único que hay que hacer es Settings - Themes y ya está ... a elegir. Y por supuesto, en el tema Beach, escoger algún lugar importante para ustedes.

|----------------------------------------------------|
| Esta entrada de blog viene particularmente for- |
| mateada con un estilo similar al tema de termi- |
| nal. |
|----------------------------------------------------|

Por otro lado.... también descubriendo algunos de los temas del tikiwiki. Voy a probar el andreas09... les paso la foto luego.

jueves, 20 de noviembre de 2008

Oil price

Se le cierra la perilla a Chavez

To get the oil price

rtfm

Bueno, otra de las cosas que me encantan de Internet.

letmegooglethatforyou dot com

Lo mejor para darle en el **rto a algunos personajes.

:-)

martes, 18 de noviembre de 2008

osCommerce OK!

Bueno, luuego de mucho bregar con osCommerce. Resulta que ahora eCompras (www.ecompras.com.bo); el bebé de su papá, puede enlazarse con osCommerce.

Lo veremos próximamente con Flores Scarlet... www.scarletflores.com

Por otro lado, lo que me dejó loco es el Instant Boot... una palabra: suuuuper!!!

lunes, 17 de noviembre de 2008

Finoli out, schneier in

La verdad un poco decepcionado del humor finoli... o demasiado avant-garde... qui sait?

Por otro lado, acaba de llegar el Crypto-Gram de B schneier con una espectacular noticia... un nuevo algoritmo de Hash: SKEIN. Y algunos datos de cómo van a seleccionar el nuevo estándar para reemplazar a la familia MD5 y SHA.

Para no variar, siempre quejándose de la tontería de estos gringos... (absurdas medidas contra el terrorismo), me quedo con una frase que simplifica la cuestión:

'Optional security measures don't work,
because the bad guys will opt not to use them. '

viernes, 14 de noviembre de 2008

looking forward to Finoli

Un viejísimo amigo está estrenando un simpático programa humorístico... no lo he visto pero promete algo ... mmmhh... diferente.

El programa: Finoli finoli
El enlace: linkteve.com

Por otro lado, algo que alguna vez puede servir (... difícilmente, pero uno nunca sabe), cómo poner a dormir a un gallo:

http://www.youtube.com/watch?v=QxuPVXE-5EE

mmmhhh.. folklórico...

jueves, 13 de noviembre de 2008

Programación defensiva

Nos vamos dando cuenta de que programar con todas las de la ley cuesta, y cuesta mucho. Para muestra un botón. Esta es una pequeña muestra de lo que contamos. Esta es una primera versión a la rápida de un código que revisa la versión de la aplicación contra la de la base de datos.

string[] version = ConfigurationManager.AppSettings["version"].Split('.');
int mayor = Convert.ToInt32(version[0]);
int menor = Convert.ToInt32(version[1]);
int? resultado = 0;

DSVersionTableAdapters.VersionCheckTableAdapter adapterVersion =
new DSVersionTableAdapters.VersionCheckTableAdapter();
adapterVersion.GetData(mayor, menor, ref resultado);

if (resultado == 0)
{
log4net.ILog log = log4net.LogManager.GetLogger("Standard");
log.Fatal("No está con buena versión: APP(" + version + ") con la base de datos");
}


Esta es la segunda versión de exactamente el mismo código con un poco de programación defensiva.
string[] version = null;
int mayor = 0;
int menor = 0;
int? resultado = 0;

try
{
version = ConfigurationManager.AppSettings["version"].Split('.');
mayor = Convert.ToInt32(version[0]);
menor = Convert.ToInt32(version[1]);
}
catch (Exception err)
{
log.Fatal("No se encuentra la variable de versión", err);
throw new ApplicationException("No se encuentra la variable de versión, arreglar el Web.config. Debería tener la línea add key=version value=1.0.X", err);
}

try
{
VersionTableAdapters.TBLVERSIONTableAdapter adapterVersion =
new VersionTableAdapters.TBLVERSIONTableAdapter();
adapterVersion.GetData(mayor, menor, ref resultado);
}
catch (Exception err)
{
log.Fatal("No existe la tabla de las versiones");
throw new ApplicationException("La tabla de versiones NO se encuentra o NO tiene una línea de versionamiento", err);
}
if (resultado == 0)
{
log.Fatal("No está con buena versión: APP(" + version + ") con la base de datos");
throw new ApplicationException("La versión de la base de datos NO corresponde con la de la aplicación. Revise la tabla TBLVERSION y el fichero web.config");
}

Es algo que muchísima gente lo hace y lo hace muy bien, pero últimamente he visto algunos ejemplos desprolijos (incluyendo míos y valía la pena la reflexión).

Por otro lado, no importa el código en sí pero si algo hay que saber es que el código con progrmaación defensiva y log/trace es algo así como 6 a 7 veces más grande que el código que contempla solamente el mejor caso.

Así que si haces algo desprolijo, es probable que en realidad sea 6 veces más largo para que sea como la gente

Souvenirs?

Una tienda muy particular para no olvidar los últimos 8 años... gracias Hugo por el input...

http://www.americathegiftshop.com/

saludos
vla

lunes, 10 de noviembre de 2008

funny googling

Bueno, algo que suele pasar...

Te buscas la frase 'google search oracle plsql' y tienes entre las respuestas una página en español sumamente graciosa:

¿Cómo escapar a los personajes en Oracle PL / SQL consultas

o lo que es lo mismo:

How to escape characters in Oracle PL/Sql queries?

:-)

miércoles, 9 de enero de 2008

CMMI

"CMMI® (Capability Maturity Model® Integration) is a process improvement maturity model for the development of products and services. It consists of best practices that address development and maintenance activities that cover the product lifecycle from conception through delivery and maintenance"

Lo más importante y lo que hay que entender de a poco con CMMI es que define el nivel de madurez que tiene la organización para desarrollar un producto y/o servicio. CAINCO debe apuntar a trabajar dentro de un nivel 3 de madurez (hay 5 niveles y ahora estamos en el nivel 1.5).

También define el nivel de capacidad o de aprehensión de ese nivel de madurez. se establece en 6 niveles, apuntamos a un 3 y estamos en un 1.5.

Porqué nivel 3?

Porque comparativamente, todos los demás procesos (ISO y etc) que tiene CAINCO se encuentran en nivel 3.

Cómo ordenarnos para asegurar un CMM3 para CAINCO es lo que trabajaremos jueves en la tarde. A tomar en cuenta que el proceso de desarrollo es algo más complicado que un proceso normal.