lunes, 19 de octubre de 2015

No hagas las tareas de los demas

Aunque parezca una tonteria tener que recordarlo y aunque creas que no haces el trabajo de los demas, es mas comun de lo que crees. El problema no es realmente que pierdas un tiempo que puedes dedicar a tu propio trabajo, el problema es estas perjudicando a largo plazo a la persona(1) a la que ayudas y estas afectando a la estructura del todo el equipo(2). ¿Por que?

1) Pejudicas a largo plazo a la persona a la que ayudas porque esta persona no aprende a hacer su trabajo o sabrá hacerlo pero no de forma correcta.

2)  Si el trabajo X que deberia estar haciendo una persona A lo hace una persona B, eso quiere decir que el trabajo X se realiza en la zona B cuando un jefe o responsable piensa que se hace en la zona A. Si se detecta un fallo en el trabajo X entonces el jefe o responsable pensara que el problema esta en A cuando en realidad el trabajo problematico lo esta haciendo B. Esto es como si un individuo A acude a un medico con algun problema, le indica que la solucion es tomar unas pastillas, se las toma un individuo B y esperes que mejore el individuo A.

Hay que gastar esfuerzo en intentar que cada uno haga su trabajo. Por lo que cada individuo tiene que estar seguro que esta haciendo lo que tiene que hacer y asegurarse que las personas que lo rodean hacen el suyo. Cuando un individuo tiene que asegurarse que las personas que lo rodean hacen se trabajo se puede encontrar tres escenarios:

- La persona que no hace su trabajo es un superior: No tienes que hacer nada. Es responsabilidad de otro.

- La persona que no hace su trabajo es un subordinado: Hay que examinar el trabajo de

La motivación ¿es una clave?

La motivación es la clave para que los trabajadores dejen de tener un rendimiento bajo y se conviertan en los mejores. En las películas, el peor equipo de la liga en verdad es el mejor solo que le faltaba motivación. La motivación es la clave del éxito ¿verdad? ¿o no? No puede que esta idea no sea mas que una leyenda urbana o, como pasa tanto en informática, la idea es buena pero en la practica todo el mundo sabe que no es así.

La motivación es una tactica proactiva ante un desarrollo que puede ser beneficioso para el resultado final. Pero tambien puede ser perjudicial (por ejemplo que la excesiva motivación se consiga con dinero y al final el coste total del proyecto sea desorbitado). Ademas puede crear el efecto "dios" en los programadores haciéndoles creer que son mejores de lo que en realidad son.

Seamos prácticos, esta por demostrar que la motivación sea "clave". Mas "clave" que la motivación es la frustración. Empíricamente, no se puede demostrar que la motivación tenga un efecto realemente positivo pero se puede demostrar que la frustración si tiene un efecto negativo. Por lo que es mas importante evitar la frustración que conseguir la motivación.

Un programador motivado estará mas contento y con ganas de hacer cosas pero ¿Eso te garantiza que lo que haga esta bien? ¿sea entable?. Esto no se puede saber.

Pero con el enfoque de la frustración. Si el programador esta frustrado esta claro que va a tardar mas en hacer sus trabajos y que serán de peor calidad.

Ademas, retomemos el efecto "dios". Es mejor que un programador piense ante una tarea que no a podido acometer:

1º uff, no me esta saliendo y no lo entiendo. ¿que puedo hacer?.

o que piense:

2º Eso estaba bien desde el principio. Solo falla esto en concreto y eso no puede hacerlo nadie.  

La 1 (frustración) es una situación mas dura sin duda pero tambien es una situación que se puede afrontar y se puede resolver la clave esta en ayudar al programador a llegar a una solución.

En la 2 (motivación) mejor que lo dejes como esta o que lo haga otro programador. En el punto en el que esta, ese programador nunca va a dar la vuelta.

jueves, 8 de octubre de 2015

Hacer login programaticamente contra j_security_check

Os adjunto un codigo para hacer login programaticamente contra un servidor con seguridad estandar de Java (un tomcat para ser exacto).

Con este codigo, el ultimo System.out.print muestra una pagina protegida (en el ejemplo index.html esta protegida)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;




public class Cliente {
    
public static void main(String[] agrs) throws MalformedURLException, 
IOException {
           
    HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/servletname/index.html").openConnection();
        connection.setInstanceFollowRedirects(false);
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        reader.close();
        
        String cookie = connection.getHeaderField("Set-Cookie");
        cookie = cookie.substring(0, cookie.lastIndexOf(';'));
        String location = "http://localhost:8080/servletname/j_security_check?j_username=a&j_password=a";
        connection = (HttpURLConnection) new URL(location).openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Cookie", cookie);
        connection.setInstanceFollowRedirects(false);
        
       
        location = connection.getHeaderField("Location");
        connection = (HttpURLConnection) new URL(location).openConnection();
        connection.setRequestProperty("Cookie", cookie);
        connection.setInstanceFollowRedirects(true);
       
       BufferedReader in = new BufferedReader(new InputStreamReader(
                                    connection.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);

       }    

}

viernes, 21 de agosto de 2015

Sin reaccion

Supongamos el siguiente caso:

Un programador termina un desarrollo. El responsable evalue al desarrollo y encuentra varios fallos. Se los indica al programador. El programador los soluciona. El responsable vuelve a evaluar los cambios pero sigue viendo el fallo. Se lo dice al programador. El programador indica al responsable que ya esta solucionado.

Lo normal es que el responsable ya no compruebe mas resultado y se fie del programador (no es lo mas correcto pero no se suele tener mas tiempo en el proyecto para mas).

Al tiempo, el evaluador (o otro miembro del equipo del proyecto) sigue encontrado fallos ya detectados y que el responsable ya le indico al programador que lo solucionara.

¿Que se ha hecho mal? Hay muchas cosas (que el responsable pruebe hasta que no vea fallos, fases de pruebas, etc..) que se puede hacer pero normalmente no hay tiempo para hacerlo por lo que lo unico que queda es FIARTE de que el programador lo va a hacer correctamente tras una (o como mucho dos) evaluación.

¿Que ha pasado? Factores a tener en cuenta:

La frustración que produce la tarea. Hacer codigo nuevo gusta, volver a un codigo que el programador creia terminado y ajustarlo no gusta.

Desconocimiento funcional de lo que se tiene que hacer.

Falta de responsabilidad con lo desarrollado. Un programador lo que quiere es terminar lo mas rapido posible y luego si hay un fallo pues intentar justificarlo con que es un fallo del grupo.

¿Que hacer para paliar estos factores?

Evaluar mientras el codigo sea nuevo.

Antes de picar nada de codigo, se debe asegurar que los programadores saben lo que tiene hacer correctamente y cual es la solucion propuesta

Suena horrible pero la solución es ser puñetero y quisquillos. Hay que mirar codigo, explicar porque ser ha hecho esto asi o asa y criticar. Con mano izquierda pero hay que ser puñetero que se justifiquen los desarrollos. Asi no solo se consigue mas calidad, se consigue que el programador sienta una relación mas estrecha con lo que ha programado.

Arduino. Leer cadena de caracteres en Serail Software

Un codigo estandar para leer una cadena de caracteres en Arduino podria ser este:


#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
const int MAX = 256;
void setup() {
  mySerial.begin(9600);

}

void loop() {
   int cont = 0;
 while (mySerial.available() && cont < MAX) {
    read[cont]=mySerial.read();
    cont++;
  } 

// do something with the read characteres

} 

Este codigo funciona puede no funcionar correctamente debido a muchos factores:

  • El tipo de microcontrolador. Un arduino tiene un microcontrolador ATmega168 o superior; este microcontrolador soporta perfectamente este codigo pero puede que sea neceario que este codigo funcione en otro microcontrolador menos potente (menos frecuencia y/o capacidad) por lo que puede que un codigo funcione en Arduino no tiene porque funcionar en otro microcontrolador.
  • El origen de datos. El puerto SoftwareSerial esta conectado a algun dispositivo que suministra la informacion de este codigo. El Arduino lee correctamente (forma y velocidad) los caracteres del puerto SoftwareSerial pero en otros sistemas puede que el dispositivo transmita mas lento/rapido. Ademas puede que aparezca mas o menos basura.
En resumen, cuando se desarrolla un codigo para un sistema (que no esta basado en Arduino) con un Arduino se debe adecuar el codigo al sistema final. La forma mas normal de adecuar el codigo es incluir retardos. 

Si el sistema final lee los caracteres demasiado rapido entonces de debe incluir un retardo entre lectura y lectura:


void loop() {
   int cont = 0;
 while (mySerial.available() && cont < MAX) {
    read[cont]=mySerial.read();
   delay (10); // retardo para leer el caracter correcto 
    cont++;
  } 


Si el sistema final lee los caracteres correctamente pero los caracteres se establecen en la variable "read" demasiado lento entonces de debe incluir un retardo entre lectura y lectura:


void loop() {
   int cont = 0;
 while (mySerial.available() && cont < MAX) {
    read[cont]=mySerial.read();
    cont++;
  } 

 delay (10); // retardo para darle tiempo a los caracteres a establecerse en la variable "read"

// do something with the read characteres

} 

El valor del retardo depende del sistema final.

domingo, 5 de julio de 2015

La cruda realidad

Cuando no se ha podido acometer un desarrollo de un proyecto de software o se ha acometido pero no con la calidad deseada y la unica conclusion posible (o almenos la mas plausible) es que no ha dado tiempo suficiente tambien lo que se esta diciendo es que EL EQUIPO X NO HA PODIDO LLEVAR A CABO EN UN TIEMPO Z EL DESARROLLO DEL PROYECTO DE SOFTWARE. Es decir, se esta aceptando una limitación de las personas que forman el equipo; pero es curioso porque nunca se enfoca asi. Si le preguntas a un miembro del equipo sobre porque no ha podido hacer esto asi o porque su parte desarrollada contiene tantos fallos entonces el te contestara algo como:

- Es que con el tiempo que tenia solo podia hacerlo asi.
- Es que con el tiempo que tenia no se podia probar mejor.

Pero nunca (o al menos casi nunca) se obtiene la respuesta de:

- Es que con el tiempo que tenia solo he sabido hacerlo asi.
- Es que con el tiempo que tenia no he podido probar mejor.

Es distinto ¿verdad?

Llegados a este punto merece la pena puntualizar que esta entrada del blog no es para que los componentes del equipo de desarrollo piensen que son malos. Esta entrada es para comprender que es muy importante conocer la capacidad real de cada uno de los miembros del equipo de desarrollo. De que cada miembro del equipo conozca sus limitaciones.

Como individuo, es dificil admitir limitaciones porque nuestros propios mecanismos de defensa no nos permiten ver dichas limitaciones. Cuando no se ha podido acometer un desarrollo de un proyecto de software o se ha acometido pero no con la calidad deseada, si se le pregunta a un miembro del equipo de desarrollo cual es el fallo, parece que se forma automaticamente dos bandos donde en uno estan todos los miembros que tuvieron la culpa del fracaso y otro grupo donde estan todos los inocentes que querian hacerlo de otra manera. Y el miembro consultado siempre esta en el segundo grupo.  

Esto es la cruda realidad. Y mas sobre la cruda realidad, los miembros del equipo de desarrollo (en la gran mayoria de los casos) no cambia. No mejora su rendimiento ni acepta mejor sus limitaciones. Este aspecto es duro pero es mejor aceptarlo y trabajar con lo que se tiene.

Poner limites

Siempre que no se cumple con un proyecto (con un desarrollo de software) o se cumple pero no con la calidad deseada aparecen todo tipo conclusiones:

- No se hizo bien esto.
- Esto no tendriamos a haberlo hecho. Tendriamos que haber hecho lo otro.
- No nos cordinamos bien.
- etc..

Cuando todas estas explicaciones son bastante dificiles de mantener siempre está la respuesta mas obvia: NO HABIA SUFICIENTE TIEMPO.

El tiempo (como ya he comentado en entradas anteriores) es la unidad de medida basica de todo. Al decir que no ha habido tiempo suficiente para llevar a cabo un desarrollo tambien se esta diciendo de forma implicita que EL EQUIPO X NO HA PODIDO LLEVAR A CABO EN UN TIEMPO Z EL DESARROLLO DEL PROYECTO DE SOFTWARE (un proyecto que tiene una carga Y). Esta conclusion es muy importante porque nos permite establecer una metrica de capacidad para el equio de desarrollo. Podemos utilizar distintas formulas como:

Si Y es 1000 de carga
Si X tiene 10 personas                                                  
Si Z es un total de 2848 horas (1 año de trabajo)

Productividad maxima por persona = 1000/(2848*10) = 0,03

Si sabemos que la productidad media del equipo es 0,03 se deberia usar este dato para futuros desarrollos ya que si en un futuro se quiere acometer un desarrollo se deberia saber que con este equipo no se puede obtener mas productividad que 0,03. Pensar que si cambio esta tecnica, o sigo esta metodologia, etc.. puedo llegar es engañarse a si mismo. Con el mismo equipo la productividad (en el mejor de los casos) sera 0,03