domingo, 29 de noviembre de 2015

Sony XPeria. BlueTooth. No se puede asociar vincular. PIN o contraseña incorrectos

He intentando asociar un SmartWatch Sony 3 con un Sony Xperia y me ha sucedido que a la hora de asociar el bluetooth me da un fallo de que no se puede asociar vincular debido a que el PIN o clave son incorrectas. Creo que esto puede suceder debido a que los dispositivos ( como el SmartWatch Sony 3) que permiten asociar sin preguntar la clave de forma explicita en verdad si que la piden solo que suelen ser del tipo 1111 o 0000 y si el dispositivo que se quiere asociar no prueba con esas claves simples entonces falla.

La forma en que he conseguido asociar los dos dispositivos es dandole la vuelta. Es decir, he asociado el SmartWatch Sony 3 con otro dispositivo que si que dejaba vincularse, una vez que el SmartWatch Sony 3 ya permitia usar sus funcionalidades he buscado el Sony Xperia y ha sido el SmartWatch Sony 3 el que se ha vinculado asociado al Sony Xperia.

Una vez conseguido esto ya estan vinculados asociados y ya se pueden usar conjuntamente.

miércoles, 25 de noviembre de 2015

Socket en C++. Visual Studio Express 2015

A continuación se muestra como crear un socket en c++.

Este codigo funciona correctamente en el Visual Studio Express 2015

Este codigo lo he sacado del https://msdn.microsoft.com

#include "stdafx.h"

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

struct addrinfo *result = NULL, *ptr = NULL, hints;
#define DEFAULT_PORT "27015"
int main() {

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

WSADATA wsaData;
int iResult;

// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}


// Resolve the local address and port to be used by the server
 iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
}

SOCKET  ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

if (ListenSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}

iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}

freeaddrinfo(result);

if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

SOCKET ClientSocket;


ClientSocket = INVALID_SOCKET;

// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}

closesocket(ListenSocket);

char recvbuf[512];
int  iSendResult;
int recvbuflen = 512;

// Receive until the peer shuts down the connection
do {

iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);

// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}

} while (iResult > 0);


iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
closesocket(ClientSocket);
WSACleanup();
return 0;
}

martes, 3 de noviembre de 2015

Incertidumbre de culminación de tareas

Cuando se le asigna una tarea a un programador para que la cumpla (en general voy a hablar de  tareas que lleva varios días culminarla pero también se puede aplicar a tareas pequeñas) hay varias metricas que se usan para evaluar el grado de avance o resultado si ya esta terminada:


  • Grado de avance respecto a lo planificado.
  • Calidad del desarrollo.
  • % de pruebas superadas.
  • Revisiones de código.
  • etc...

Todas las metricas que se usen se pueden ser mejor o peores para conocer el estado del desarrollo y llevar  a la culminación de la tarea dependiendo de la incertidumbre de culminación de la tarea que presenta el desarrollador encargado de la tarea.

La incertidumbre de culminación de tareas es la probabilidad de que un programador haya implementado una tarea de acuerdo a como el responsable quiere que lo haga.

Cuando el responsable de una tarea piensa (diseña) la tarea no habria mejor persona para acometerla que esa misma persona (no lo va a hacer porque lo que tiene que hacer es diseñarla para que lo haga otros y esa persona pueda hacer otra cosa) y si esa persona acometiera la tarea es casi seguro que al hacerlo se encontrara con realidades (esto es mejor asi, esto asi no sale, etc..) que variarían la forma que tenia pensada en que se acomete la tarea y posiblemente hasta cambios de diseño. Con esta premisa, es lógico pensar que otra persona (un desarrollador) presenta una incertidumbre de culminación de tareas muy alto.

Para evitarlo, es básica la formación continua de los programadores y asegurarse de que comprenden el marco de trabajo que se usa para el desarrollo del proyecto. Pero es muy optimista pensar que con esto vale, se deben usar técnicas con mas supervisión como programación extrema. Quizas la mejor opción es seleccionar un dia al azar y pasar la mayor parte del dia sentado en el sitio del programador, hablar con el, ver como plantea las cosas, que esta haciendo, que es lo que ha entendido, etc.. La claves es asegurarse de que ha entendido el marco de trabajo y que va a culminar la tarea como espera el responsable que se va a resolver.

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

sábado, 6 de junio de 2015

Tiempo. ¿Se le hace caso? ¿Hay suficiente?

El tiempo es la condición basica de un proyecto de desarrollo de software. Es la moneda del proyecto. Se pueden tener infinidad de criterios a tener en cuenta: dinero, recursos, tecnologia, complejidad, etc... pero al final todo se traduce en tiempo

Es bastante dificil estimar cuanto se tardar en realizar un proyecto de desarrollo de software y es una de las tareas a las que se suele dedicar menos tiempo y se suele hacer de manera poco rigurosa (como se suele decir se levanta el dedo y como sople el viento pongo esto o esto otro).

Para poder cumplir con el tiempo de desarrollo del proyecto se debe hacer una planificación donde queden completamente claras las tareas que hay que realizar y las dependencias entre esas tareas. Esta planificación es la guia para todos los miembros del equipo y que los miembros del equipo usen esta guia es la condición basica para que se cumplan los plazos y con la calidad requerida.

Pero los miembros del equipo de un equipo de desarrollo de software no siguen nunca una planificación. Para un programador una planificación es un estorbo, no se ve la utilidad de seguir una planificación; es mas no ve la utilidad de tener que informar del estado global de su desarrollo.  Esto ultimo es lo mas desconcertante ya que un programador informa antes de un problema tecnico que le bloquea su desarrollo (que es un problema de bajo nivel que por definición deberia solucionar el programador) que de un problema de dependencias con otros sistemas (que puede afecta al diseño) o del estado global (que afecta a la planificación).

Hay que hacer que los miembros del equipo se mentalicen con que hay que cumplir con la planificación y que hay que acostumbrarse a informar del estado de la tarea actual que estan desarrollando.

Pero tampoco hay que olvidar la contrapartida a que los miembros del equipo no usen la planificación y es que el tiempo asignado al desarrollo del proyecto de software es poco o muy justo. ¿Que pasa cuando el tiempo de desarrollo de software es poco o muy justo y hay que acometer el desarrollo?
En estos casos hay que intentar acometer el desarrollo de la mejor manera posible por lo que es seguro que la calidad del software se vera resentida. Alguna vez se ve tan resentida que el software es directamente no valido. Esta es la peor situción posible (y lo malo es que se cumple en la mayoria de los casos) ya que los criterios no estan claros y cuando las cosas no funcionan todo el mundo en el equipo de desarrollo de software cree tener razon y nadie parece tener la culpa de nada.

lunes, 4 de mayo de 2015

El cambio de contexto

Cuando se abandona el trabajo de mas bajo nivel y se empieza con tareas de gestión de equipo de desarrollo de software la primera actividad que te golpea en la cara y no sabias que venia es tener que llevar varias cosas a la vez. Si le preguntas a la mayoría de personal que no han gestionado un equipo te dirán cosas como:

  • Tienes que planificar.
  • Habla con el cliente.
  • Hacer seguimiento de las tareas.
  • Etc..


Pero, simplificando, todo al final se divide en tareas que tienes que ir asignado a miembros del equipo para que las lleven acabo y esas tareas tienen sus caracteristicas:


  • Estado de desarrollo.
  • Complejidad.
  • Prioridad.
  • Etc...


Por lo que te encuentras gestionando multiples tareas (de las cuales una puede ir adeltanda, otra atrasada, una mal estimada, una bloqueada, una efectada por errores de los miembros del equipo que la llevan a cabo, etc..) a la vez y seguramente el mismo dia tengas que atender a varias.

Las dificultades del cambio de contexto son muy importantes y son dificiles de detectar. Se puede notar sensaciones muy frustrantes ya que puedes tomar decisiones como si llevas 3 tareas dejar una de ellas de lado por razones completamente personales y terminar las otras dos. Esto es un error enorme y cuando se hace balance lo primero que se pregunta uno mismo son cosas como :¿ Por que hice esto? ¿ Que ha pasado aqui?

Desafortunadamente no conozco ninguna solución para gestores de equipo con este problema pero al menos identificar que este puede ser el problema que se tiene es el primer paso para poder solucionarlo.

viernes, 27 de marzo de 2015

La importancia de cumplir un hito

Para el que gestiona un equipo de trabajo, la importancia de cumplir los  hitos fijados es fundamental. Que una tarea no se termine a tiempo y con la calidad suficiente es un problema que no se le va de la cabeza y tener que retrasar una fecha de entrega es una linea roja que si se traspasa empieza la debacle:

  • Todo parece estar mal hecho.
  • Los jefes nos miran con cara de decepción.
  • Salen mas errores de la nada.
  • ...........un caos
Por increíble que parezca, para un programador un hito no tiene ningún significado especial. Si se cumple bien y si no pues que me den mas tiempo. No conozco la manera de cambiar este comportamiento en un programador pero lo que si se puede hacer es "evolucionar al programador", es decir, crear un puesto intermedio donde tiene que gestionar a otros programadores y hacerse responsable de algo y hacer que un programador ocupe dicho puesto.

¿Como se le asigna el puesto a un programador? Se tiene una reunión con él y se le explica que:

  • Tiene que ser una persona de referencia para todos sus programadores y para los cargos superiores que quieran conecer algo de la parte de la que es responsable.
  • Se le indica que se le va a presionar mas y que CUMPLIR LOS HITOS SON IMPORTANTES.

Con esto ya se tiene al programador donde se quiere para que comprenda la importancia de cumplir los hitos. A partir de ese momento lo que hay que hacer es ir poniendole hitos periodicamente y controlar que los cumpla. En los primeros hitos que no cumpla, seguramente lo que te diga es que por los motivos que sea no puede llegar. Este momento es clave. Tienes que indicarle que si no llega que te busque la solución para llegar; ya no vale el no voy a llegar. Puede darse el caso que es cierto que no llegue (los problemas son insalvables), en este caso lo que tenemos que hacer es que no plante una alternativa, es decir que si no puede entregar todo lo comprometido pues que entregue algo equivalente y que el jefe de equipo considere valido. Pero el hito hay que cumplirlo.


domingo, 15 de marzo de 2015

Manejo de equipo. El grupo

El grupo de desarrollo lo mas normal es que te venga impuesto. Seran muy raras las ocasiones en las que puedes elegir. La mejor que tienes es olvidar el hecho de que tu no has elegido a la gente y partir siempre del punto de que tienes que desarrollar un trabajo con el equipo que te han dado.

El grupo no se puede cambiar nunca completamente (siempre con el tiempo podrias cambiar a alguien pero lo normal es que se queden todos) y este hecho es inmutable por lo que lo primero es alinear los objetivos de desarrollo con el grupo que tenemos. Esto le dará un estructura al grupo que servirá para completar el grupo. La estructura siempre sera un arbol con varios ramas:



Al tener estructura, se dispone de varias opciones que antes no tenias:

  • Puedes asignar roles intermedios para mejorar las habilidades de los miembros del equipo. A estos roles intermedios les tienes que dar guias de lo que quieres que hagan pero no olvides que una vez que empiecen con su nuevo rol son ellos los que tienen que cumplir con el rol y que lo haran como ellos creen que tienen que hacerlo. Esto tiene dos resultados posibles:
    • No cumplen con el rol. Por lo que tienes que  hacer que cumplan en rol.
    • Si cumplen el rol. Analiza como lo cumple ya que en la mayoria de los casos lo cumplirán de una manera que no esperabas y te puede servir para mejorar (feedback)
  • Tiempo. La estructura te obliga a delegar por lo que tendrás mas tiempos que puedes invertir en procesos de mejora.
Evita la sensación de que una persona sobra del grupo. Puede que realmente un miembro del equipo estorbe en el grupo y sea mejor que no esté en el grupo pero no olvidemos dos cosas:
  • Es muy dificil que un miembro del grupo sea un estorbo y que no puede aportar nada de nada(Aunque se puede dar el caso de que si que lo sea por lo que ojito ;)=).
  • Es una reacción muy comun librarse de lo que estorba lo primero (sea cual sea el contexto) pero esta reacción es mas un sintoma de no querer calentarse la cabeza que una reacción inteligente.
Una lección muy valiosa en el ajedrez es que evites cambiar piezas por cambiar porque no sabes que hacer con las piezas. NO SABES COMO USARLAS PARA GANAR LA PARTIDA. Si crees que tienes que prescindir de un miembro del grupo  primero piensa en dos cosas:
  • No quiero a ese miembro del grupo por que realmente estorba o por que no se como usarlo?
  • Estorbe o no estorbe en realidad, puedo usar a ese miembro del grupo de alguna manera no convencional para que me sirva? Por ejemplo, como una justificación de que no has conseguido objetivos porque no tienes suficientes miembros validos en el grupo para acometer el desarrollo.      


miércoles, 25 de febrero de 2015

Decir lo que otro no quiere oir

La evaluación de un trabajo siempre es complicada por muchos aspectos:

- Calidad del servicio.
- A tardado mucho o poco.
- Ha dejado su trabajo mantenible.
- Ha usado la ley del minimo esfuerzo o ha hecho todo lo que ha podido.
- Como condiciona el resultado de esta evaluación para futuras tareas.
- Etc..

La lista es muy larga y cada evaluador puede usar las que mas le guste pero lo mas dificil de evaluar no es la lista de aspectos a tener en cuenta, ni si los aspectos se estan evaluando correctamente. Lo mas dificil es tener que decirle a alguien algo que no quiere oir sobre su trabajo.

La mejor forma de afrontarlo (lo enfoques como lo enfoques) es plantear la charla que uses para contarle lo que no quiere oir de forma constructiva, es decir; en todo momento di cosas buenas y di las cosas malas como continuación (o conclusion) de una cosa buena. Por ejemplos, si el problema es que tienes que decirle a alguien que no sabe mantener el control en una situación de estrés puedes decir:

             - "Eres una persona que habla claro y tienes capacidad para dominar una situación de estrés pero en ciertas ocasiones he visto que ... has perdido la partida (di esto con cara de complicidad) porque te ha faltado ese ultimo esfuerzo de control al final... tienes que pulir eso".

En resumen, le has dicho que si ha tenido 5 situaciones donde deberia haber controlado la situación no ha controlado como minimo tres por lo tanto es un parcial negativo. Ha fallado. Es un punto negativo pero lo comprenderá y lo aceptará mejor que si se lo dices claramente.

Estas siendo falso? puede que si o puede que no. Pero estas son ese tipo de situaciones en las que lo importante es el objetivo no los medios. Pero no puedes olvidar la moralidad ¿verdad? Te dices voy a decir la verdad y que lo acepte. Al principio me odiara pero mas adelante me lo agradecerá. Esto si que es falso (ademas de iluso). A nadie le gusta que le digan claramente los fallos que ha cometido en el trabajo pero a todo el mundo le gusta QUE LE MARQUEN EN CAMINO. Y eso es lo que estas haciendo. Solo tienes que decir la frase anterior (la frase de decierle suavente que no sabe afrontar situaciones de estres) como una directriz de como puede conseguirlo.


domingo, 15 de febrero de 2015

Y cuando descubres que tienes que mandar

Cuando te asignan un grupo de programadores para acometer un desarrollo, te das cuanta de muchas factores que no parecen tener con el propio trabajo en si (con el software):

  • Puede que te hagan caso y puede que no
  • Que hacer cuando le dices a alguien que haga una tarea, lo hace y el resultado no es lo que quieres y te dicen que si lo es.
  • Que hacer si ves que claramente no esta al nivel que necesita el proyecto
  • Puede que todo empiece bien y se vaya degradando aspectos como el interes, la intensidad, etc..
  • Y si no cumplen su horario
  • Y si les llamas la atencion por algo y se nota que no les ha gustado porque piensan algo como: Siempre yo. Es que este no hace nada. 
  • Y si tienen temas sindicales que les hacen hacer mal su trabajo
  • Etc...
No hay una receta mágica para estas situaciones y desde luego no hay receta que dure desde el principio hasta el final del desarrollo de una aplicación software. Debes pensar en desarrollo como en un castillo de piezas de distintas formas que estan unas encima de otras manteniendo un equilibrio:




A medida que avance el desarrollo, los distintos factores que he indicado al principio ejercen presión sobre las piezas y si no se actua contra esos factores pasara lo siguiente:



Algunas piezas seguirán en pie, otras seguirán en equilibrio ellas solas, otras estarán a punto de caer,etc... en general un desastre ingobernable. 

A las conclusiones que he llegado para  que no suceda un desastre ingobernable y se mantenga el equilibrio hasta el final son las siguientes:

  • Nunca acometas una acción intimidatoria si no estas seguro de que la respuesta va a ser favorable. Desde una simple llamada de atención hasta una bronca delante de todo el equipo, si no estas seguro de que es útil y de que va a acabar bien mejor no lo hagas y espera el momento oportuno.
  • Nunca dejes la parte tecnica de lado completamente. Recuerda que al fin y al cabo estas mandando lo que se tiene que programar y como se tiene que programar. Si tus programadores no ven que al menos estas a un nivel aceptable entonces no respetaran tus decisiones tecnicas,
  • Establece las metricas que consideres oportunas para el seguimiento y mejora y se constante en ellas. Si las abandonas que sea por decision propio y no por la desidia de tus programadores. 

jueves, 5 de febrero de 2015

Diseño. Cuando modular y cuando no

A la hora de diseñar cualquier tarea se debe de plantear dos cosas:
  •           Ya existe algo que lo pueda hacer
  •           Si no existe, hacer algo que sirva para solucionar esta tarea y una problemática igual en otro sistema.


Hacer algo genérico para resolver tu problema (tu tarea) siempre es la mejor solución pero en teoría. Si tenemos en cuenta aspectos prácticos como rendimiento, líneas de código, sostenibilidad, etc… La regla es:
  •           Si la solución es exactamente igual para todos los sistemas si se debe algo genérico para todos.
  •           Si casi todo es igual pero hay pequeños cambios pero muy significativos entonces lo mejor es buscar una única solución si pero que se implemente como se necesite en cada sistema.


sábado, 3 de enero de 2015

Cuando todo fallo

El fin de año es una época para hacer balance de como ha ido el proyecto  desarrollo de software. Podemos pensar en todo lo que hemos hecho, en todas las decisiones que hemos tomado, en como hemos afrontado los problemas, etc..

si todo ha ido genial entonces hasta el próximo post.

Si todo no ha ido tan genial entonces sigue leyendo.
Ahora que se hace resumen, me doy cuenta de cosas, aspectos, decisiones, etc… (métodos en general) que debería haber sido de otra manera. Somos humanos y todo el mundo se puede equivocar. Lo realmente complicado de interpretar es que pasa con las cosas, aspectos, decisiones, etc… que fueron correctas en su momento, que ahora razonas y sigues pensado que fueron lo mejor que se podía hacer… pero aun asi fallaron o no fueron suficiente. Se pueden tomar de dos maneras:

  • Puedes hacer lo mismo de otra manera. Aunque pienses que tu forma de hacer las cosas es la correcta puede que existan factores (como que tu equipo no asimila tus métodos o que tu proyecto software no tenga una arquitectura que se adapte a tus métodos) que lleven tus métodos al fracaso. Por lo que tendrás que adaptar tus métodos aunque no te parezca lo mas correcto,
  • Puedes hacer otras cosas. Seguro que hay muchos métodos que no has probado y que pueden ser un revulsivo perfecto.


En general, probar otras cosas suele ser lo mejor. Sobre todo si el equipo de desarrollo ya ha manifestado ser contrario a tus métodos o ha mostrado indiferencia.