20 marzo 2023

Piensas una cosa, haces otra - Disonancia cognitiva

Leyendo artículos sobre comportamiento me topé -de nuevo- con el concepto de disonancia cognitiva. Cada vez que leo sobre ello me doy cuenta de que si no tenemos presente qué es y cómo se manifiesta, tendemos a comportarnos de ese modo, incoherente e incómodo.

Imagina que eres una persona muy preocupada por el medio ambiente, y siempre tratas de llevar un estilo de vida sostenible y respetuoso con la naturaleza. Sin embargo, un día recibes una oferta para trabajar en una empresa que produce y vende productos de plástico desechable en grandes cantidades. Sabes que el plástico es uno de los materiales más contaminantes y dañinos para el planeta, pero la oferta de trabajo es tentadora y te pagarían un salario muy atractivo.

La disonancia cognitiva es un fenómeno psicológico que ocurre cuando tenemos dos pensamientos, creencias o actitudes que son contradictorios o incompatibles entre sí. Es una teoría que propuso el psicólogo Leon Festinger en 1957 y que permite detectar cuándo "se dice una cosa, pero se piensa otra".
El conflicto que produce este comportamiento nos genera una sensación de malestar y puede afectar negativamente a nuestra salud mental, ya que puede provocarnos desde estrés hasta depresión. De ahí la importancia de estar alerta para detectarla y poder actuar a nuestro favor.

Hay algunos puntos que hacen saltar las alarmas, tanto si los vemos en otras personas como en nuestro propio comportamiento. Está claro que hay disonancia cognitiva cuando:
  • Minimizas la importancia del problema
  • Tratas de justificar tu decisión
  • Cuando te dan información nueva, la evitas o te bloqueas
  • Hablas de la perspectiva de los demás de forma imprecisa
  • Malinterpretas las opiniones o preguntas sobre el tema
  • Ajustas tus criterios para evaluar una misma situación que ocurre en dos momentos/lugares separados
  • Te enfadas o gritas
  • Atacas la personalidad de la otra persona, en vez de el problema sí, porque te quedas sin argumentos
  • Te alejas de las personas que hablen del conflicto

El uso de estas estrategias no será consciente en la mayoría de los casos. Son estrategias que usa nuestro cerebro para reducir el conflicto. Pero estas estrategias también las verás en personas que saben que no están diciendo la verdad, que saben que están dando información imprecisa o que saben que están ocultando información, y eso es porque hay disonancia entre lo que dicen y lo que saben (muy visto entre las personas de la política gubernamental).

Para evitar que exista la disonancia cognitiva, en cambio, se recomiendan las siguientes estrategias:

Cambiar una de las cosas que generan el conflicto y estar "en paz" con el cambio
Esto implica ajustar tus creencias y valores para que se adapten a tus acciones, o tratar de cambiar tus acciones para que se alineen mejor con tus creencias y valores.

Buscar información objetiva y contrastada sobre los temas que nos generan conflicto
Aprender más sobre lo que entra en conflicto puede ayudarnos a estar "en paz" con las acciones que hacemos y nos hace conscientes de qué pros y contras tiene cada parte. De esa forma podemos ser honestos con nosotros mismos y reconocer nuestras contradicciones e inconsistencias.

Además de estrategia, es muy saludable estar abiertos al cambio y al aprendizaje continuo, ser flexibles y tolerar que otras personas pueden tener otras opiniones y, por supuesto, buscar ayuda profesional si no podemos resolver el conflicto por nuestros medios.
Ser conscientes de nuestro comportamiento nos ayudará a estar más saludables, cultivar mejores relaciones y a ser más felices.
Para finalizar, adapto una historia sobre cómo sacar partido de la disonancia cognitiva (fuente Coursera, más abajo):

Un hombre muy bajito monta una tienda cerca de una escuela. Un grupo de niños que pasaba cada día frente a su tienda, camino a la escuela, le comenzó a llamar "¡Enano! ¡Enano!".
Un día el hombre les espera en la puerta de la tienda y les dice que a cada uno que le llame enano, le dará cinco céntimos, porque le gusta que le llamen enano.
Dos días seguidos pasaron gritando "¡Enano! ¡Enano!", y dos días seguidos el hombre bajito da cinco céntimos a cada niño. Pero al tercer día, el hombre les da dos céntimos a cada uno, bajo el pretexto de que no ha habido mucho negocio en la tienda. Y al cuarto día, cuando le gritaron "¡Enano! ¡Enano!", el hombre sólo les dió un céntimo a cada uno y nuevamente les dijo que no había mucho negocio. Al quinto día los niños no le gritaron, porque no iban a hacerlo sólo a cambio de un céntimo. Problema resuelto.

¿Por qué le acosaban gratis, pero no por un céntimo?

El cerebro tiende a reducir o evitar la inconsistencia psicológica, de modo que cuando el tendero dice que está contento con que le llamen "Enano" y cambia el juego de acoso a recompensa económica crea en los acosadores una inconsistencia y una disonancia en el acoso sin suficiente compensación económica. Muy parecido con el ejemplo del principio de este post.

¿Cambian nuestros principios si nos dan suficiente compensación económica? ¿Estamos en paz con ello?

Tú piensa.

Fuentes:
AIs: Bing's Sidney, OpenAI

05 diciembre 2017

Testing Python vs C# - Read CSV file

Es inevitable que quiera hacer esto mientras aprendo un lenguaje.

Python C#

No he aplicado nada de refactorización en Python, pero sí en C# para intentar ahorrar tiempo.
Seguro que habrá todavía margen de mejora en ambos lenguajes, pero ya había pasado el tiempo razonable dedicado a refactorizar.

Si tenéis sugerencias para reducir el tiempo de ejecución, genial, así aprendemos todos.

En la red podéis encontrar comparaciones más profundas de ambos lenguajes. Aquí dos de ellas:
https://www.slant.co/versus/110/115/~python_vs_c
http://onstartups.com/tabid/3339/bid/128/Python-vs-C-Business-and-Technology-Tradeoffs.aspx

Los resultados que obtuve son estos:

Read CSV file - 23865 rows, filter year 2015, sum values from one column

--- Excel
62683287355
62.683.287.355
62.683 million persons

--- Python
Rows after first filter: 274
Rows after second filter: 272

World population in 2015: 62683.287355 million persons
Read CSV file - 23865 rows, filter year 2015, sum values from one column
Execution time: 18.53711571297298ms

--- C#
Rows after first filter: 274
Rows after second filter: 272

World population in 2015: 62683,287355 million persons
Read CSV file - 23865 rows, filter year 2015, sum values from one column
Execution time: 24ms


PYTHON CODE

import pandas as pd
import timeit
import numbers

"""Read CSV file, filter year 2015, sum all results"""

def getDataFrameFromCsv(csvFileName):
    """Read CSV file"""
    worldPopulation = pd.read_csv(csvFileName, sep = ',')
    return worldPopulation

def filterColumn(dataFrame, columnName, columnValue):
    """Filter dataFrame by year columns"""
    dataFrameFilter = dataFrame[columnName] == columnValue
    filterResult = dataFrame[dataFrameFilter]
    print("Rows after first filter: " + str(len(filterResult)))
    return filterResult

def filterIntsInColumn(dataFrame, columnName):
    """Filter int values in column"""
    dataFrameFilter = dataFrame[columnName] >= 0
    filterResult = dataFrame[dataFrameFilter]
    print("Rows after second filter: " + str(len(filterResult)))
    return filterResult
  
def sumColumn(dataFrame, columnName):
    """Sum column"""  
    result = sum(dataFrame[columnName])
    return result

def mainProgram():
    year = 2015
    yearColumnName = 'Year'
    populationColumnName = 'Medium Projection (UN Population Division (2015 revision)) (people)'
    fileName = 'world-population-1750-2015-and-un-projection-until-2100.csv'
  
    csvContent = getDataFrameFromCsv(fileName)
    contentFilteredByYear = filterColumn(csvContent, yearColumnName, year)
    contentFilteredByYear = filterIntsInColumn(contentFilteredByYear, populationColumnName)
    worldPopulation = sumColumn(contentFilteredByYear, populationColumnName)

    millionUnits = 10**6
    print("\nWorld population in " + str(year) + ": " + str(worldPopulation/millionUnits) + " million persons")

executionTimeInSecs = timeit.timeit(mainProgram, number=1)
print("Read CSV file - 23865 rows, filter year 2015, sum values from one column")
print("Execution time: " + str(executionTimeInSecs * 1000) + "ms")



C# CODE

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace SumCsvColumn
{
    class Program
    {
        static void Main(string[] args)
        {
            long elapsedMs = MeasureMainProgram();
            PrintResults(elapsedMs);
        }

        private static long MeasureMainProgram()
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();

            MainProgram();

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;
            return elapsedMs;
        }

        private static void PrintResults(long elapsedMs)
        {
            Console.WriteLine("Read CSV file - 23865 rows, filter year 2015, sum values from one column");
            Console.WriteLine("Execution time: " + elapsedMs.ToString() + "ms");
            Console.ReadLine();
        }

        private static void MainProgram()
        {
            var year = 2015;
            string[] columnNames = null;

            var yearColumnName = "Year";
            var yearColumnIndex = 0;

            var populationColumnName = "Medium Projection (UN Population Division (2015 revision)) (people)";
            var populationColumnIndex = 0;

            long worldPopulation = 0;
            double millionUnits = Math.Pow(10, 6);

            string[] csvContent = LoadCsvFile();
            IEnumerable<string[]> rowsSplitted = SplitRowsIntoColumns(csvContent);

            columnNames = rowsSplitted.First();
            yearColumnIndex = Array.IndexOf(columnNames, yearColumnName);
            populationColumnIndex = Array.IndexOf(columnNames, populationColumnName);

            rowsSplitted = FilterColumn(rowsSplitted, yearColumnIndex, year);
            worldPopulation = SumColumn(rowsSplitted, populationColumnIndex);

            Console.WriteLine("\nWorld population in " + year.ToString() + ": " + (worldPopulation / millionUnits).ToString() + " million persons");
        }

        private static string[] LoadCsvFile()
        {
            string fileName = "world-population-1750-2015-and-un-projection-until-2100 - CS.csv";
            String[] csvContent = GetArrayFromCsv(fileName);
            return csvContent;
        }

        private static long SumColumn(IEnumerable<string[]> rows, int columnIndex)
        {
            long sumResult = 0;

            foreach (var row in rows)
                sumResult += GetNumberFromString(row[columnIndex]);

            return sumResult;
        }

        private static long GetNumberFromString(string value)
        {
            return long.TryParse(value, out long longResult) ? longResult : 0;
        }

        private static IEnumerable<string[]> FilterColumn(IEnumerable<string[]> rows, int columnIndex, int columnValue)
        {
            var columnValueToString = columnValue.ToString();
          
            var filteredResult = rows.Where(row => row[columnIndex] == columnValueToString).ToList();

            Console.WriteLine("Rows after first filter: " + filteredResult.Count().ToString());
            return filteredResult;
        }
      
        private static IEnumerable<string[]> SplitRowsIntoColumns(string[] csvContent)
        {
            return csvContent.Select(row => row.Split(',')).ToList();
        }

        private static String[] GetArrayFromCsv(string fileName)
        {
            String[] values = File.ReadAllText(fileName).Split('\r');

            return values;
        }
    }
}

02 diciembre 2017

Ishikawa

"Es muy difícil saber qué sucederá dentro de un minuto.

Podemos crear todas las condiciones para que suceda lo que esperamos: mover una taza, dibujar una línea, abrir una ventana, pero no es posible saber con exactitud qué sucederá.

La causalidad encadena un acontecimiento tras otro hasta el efecto final. Ni siquiera los primeros principios - esos irrefutables - son primeros.

Pero sí debemos responsabilizarnos por nuestras acciones - nuestros primeros principios - los que nos han llevado hasta donde estamos. No hay que sufrir, no hay que resistirse a lo que es.

Hay que aceptar que estamos aquí por lo que hemos hecho, pero tenemos que saber qué hemos hecho para estar aquí. Así, más adelante sabremos a dónde nos llevarán esas mismas acciones.

Por desgracia, a las personas se nos olvida pronto todo lo que no nos impacta de un modo irreparable. Y aún de aquellas situaciones que nos han afectado mucho no sabemos encontrar la causa. Así vamos, ciegos paso tras paso, sin saber qué sucederá dentro de un minuto."

En ciclo de vida del software cobra cada vez más importancia analizar que medir. No quiere esto decir pensar dos veces y hacer una, sino que va más relacionado con la observación.

En esto nos pueden ayudar los diagramas causales, como parte de las retrospectivas y acciones de mejora. (Ver Ishikawa)
  • Coger un problema que puede repetirse.
  • Colgar de él una línea central.
  • Colgar los principales actores de esa línea central.
  • Colgar de los actores las principales acciones (causas) que pueden contribuir a el problema
  • Colgar de esas acciones otras acciones que han influido a que esa acción suceda.
Diagrama-general-de-causa-efecto.svg
De VARGUX - Trabajo propio, GFDL, Enlace

Si minimizamos las acciones que han contribuido a llegar a este problema, es posible no repetirlo y que nuestro próximo intento termine en un escenario positivo para nuestros equipos y nuestros clientes.

Ahí os lo dejo.

12 noviembre 2015

Autoridad y Liderazgo

Back again sharing my thoughts!

La última reunión que tuvimos en Agile Norte de nuevo me ha dado energía para compartir lo que he escuchado, compartido y aprendido con los que asistimos a ella. El formato se hizo en forma de taller, guiado por Joserra Díaz, que siempre nos da cancha para discutir sobre nuestras experiencias y compararlas con las ideas que nos expone.

Taller de Liderazgo de Equipos Ágiles

Joserra nos preparó con un ejercicio de calentamiento tipo "follow the leader" del que terminamos discutiendo si nos sentíamos más cómodos siguiendo una mano o haciendo que la otra persona la siguiese y también del porqué habíamos accedido a hacer el ejercicio.


https://twitter.com/agileNorte/status/664183174910648320


Algunos se sentían más cómodos siguiendo, otros haciendo que siguieran su mano, pero al final lo que quedó claro es que le habíamos dado "autoridad" a Joserra para que nos indicara qué ejercicio hacer. Autoridad formal, que no informal. Formal porque confiamos en que por su experiencia sabría lo que hacía y por qué. No la autoridad informal porque debía ganársela durante la charla. Es decir, era autoridad, no liderazgo.


https://twitter.com/fcnatra/status/664154326898733056


Llevándolo al entorno ágil todos expusimos nuestra opinión sobre qué autoridad formal o informal tienen (o deben tener) a los roles básicos en un marco de trabajo Scrum y está claro que al discutirlo ninguno nos sentimos demasiado cómodos y menos aún al exponer las características que debía tener un "buen seguidor".


Quedó claro que un la elección de una líder raramente es formal, ya que cada persona puede cambiar de rol - de seguidor a líder o viceversa - dependiendo de la situación. Esta selección de la persona que creemos nos puede representar, ayudar o guiar en determinado momento a resolver un conflicto o salir de un problema es casi inconsciente. Para cada conflicto, reto o mejora 
una persona diferente puede erigirse como líder en una transición imperceptible. Yo me atrevería a decir que más que "puede", debería suceder así.


https://twitter.com/fcnatra/status/664160935368630272


¿Un líder nace o se hace?

Es indudable que hay personas que nacen con habilidades de liderazgo y que al parecer son "buenos en todo", pero es común que con el tiempo salgan a la luz las fortalezas o carencias en determinadas situaciones. Normalmente estas personas son más identificadas con la autoridad.

Habilidades de comunicación y motivación ayudan mucho a identificar a una persona como líder, además de sus conocimientos sobre cómo hay que afrontar los problemas a los que hay que poner solución, pero es más su actitud ante los problemas lo que le erige como tal ante determinadas situaciones.

Principalmente son estas características las que dotan de liderazgo a una persona:

- Generar un proceso de movilización: Un líder no es líder si nadie le sigue. No es que necesite hacerse de seguidores (lo que es la autoridad, el "jefe" que todos conocemos) sino que las personas deben percibir que su trabajo tiene un objetivo que claramente mejorará la situación actual.

- Afrontar una "realidad incierta": Pisar terreno firme es sencillo. Un líder se arriesga. No es que no tenga cabeza, es que tiene claro que no hay cambio sin riesgo y no hay mejora sin cambio.

- Desarrollar en el entorno nuevas capacidades de adaptación: No todos los cambios propuestos llegan a buen puerto, pero en cada intento hay aprendizaje y con cada pequeño logro se mejora la capacidad de las personas que han participado en él y del entorno para adaptarse a nuevas situaciones.

- Tener como propósito el progreso y el bienestar del grupo que lidera: Aquí también hablamos sobre si un líder es en realidad un manipulador. Una cosa quedó clara: un líder sí manipula al entorno para conseguir su propósito (genera un proceso de movilización a través de acciones que hagan a las personas percibir un objetivo de mejora) pero también el propósito del líder es el progreso y el bienestar. Aunque se consiga generar un proceso de movilización, tarde o temprano se verá si el propósito es el adecuado o no.

Y por último comentamos un tema que fue el colofón del taller: si se tira mucho de la cuerda, ésta se rompe y el entorno ya no tomará en serio las propuestas, y si se afloja mucho la cuerda nadie escuchará las propuestas que se hacen o éstas caerán en saco roto. Lo ideal está en el medio, en no cejar, en forzar la máquina pero no demasiado. - Y Joserra nos lo dijo en unas palabras que calaron en todos: "El líder mantiene el desequilibrio y el conflicto, porque el conflicto genera adaptación y aprendizaje".


https://twitter.com/fcnatra/status/664163476533833728


La zona de aprendizaje está justo en el medio, en no dar mucho la tabarra, pero no dejar de hacerlo, NUNCA.

No te rindas.

24 junio 2015

Hackeando Agile - De vuelta a los principios ágiles

Acabo de llegar de la Agile Open Spain 2015 y, como siempre, me traigo ideas nuevas para trabajar.

En esta edición hemos discutido sobre relación con el cliente, equipos, eficiencia, hemos traído nuestros problemas y retos y los hemos presentado a los demás, pero también hemos hackeado Agile con el Dojo de #NoIfs y con las discusiones #NoProjects #NoEstimates #NoTeams #NoProductOwner.

De todas las AOS, en mi bolsa de ideas, siempre reservo la "caja del tesoro" para lo que más me ha llamado la atención. En esa caja me traje el año pasado el cómo aborda Diego Rojas el coaching, para mí el descubrimiento del año.

Este año han sido Joserra Díaz y Jorge Uriarte los que me han hecho pensar en qué estamos haciendo mal para que a tantas empresas les cueste tanto aplicar correctamente las prácticas ágiles.

https://twitter.com/aos2k15/status/612211994708606976

Jorge nos lanzó la pregunta de en qué punto creemos que se encuentra la adopción de los marcos ágiles de trabajo - en nuestro entorno laboral -. Hubo diversas opiniones, desde quienes piensan que estamos al inicio de la curva de adopción hasta los que opinan que estamos en la cima.

 New Product Adoption

Pero un punto nos quedó claro: muchas empresas lo intentan más de una vez y desisten del intento, otras implantan prácticas ágiles de modo incorrecto no consiguiendo el objetivo de la práctica en sí y son muy pocas las que consiguen tener un marco de trabajo ágil correcto, con lo que he aquí la pregunta: ¿Debemos aceptar el fracaso ágil?

Como juego para hackear Agile, este título no es más que un reto para que nos preguntemos qué está pasando.

Con las opiniones de unos y otros y las muy valiosas de Xavier Gost, que es un exponente claro de la base sólida Agile, fuimos desgranando los motivos de por qué estamos donde estamos...

Intentamos aplicar las prácticas de Agile olvidándonos de que esas prácticas se basan en los principios Agile

Y es cierto.

¿Cuántas veces escuchamos hablar sobre Scrum, Lean, Kanban, TDD, Clean Code, Inceptions, Motivation, GTD, Pomodoro, Retrospectives y muchas otras prácticas para mejorar en eficiencia, comunicación, desarrollo, entregas y cuántas otras veces escuchamos a alguien mencionar los doce principios que promueve el Manifiesto Ágil?

La verdad es que no necesitamos hacer TDD, necesitamos ser capaces de hacer desarrollos simples que funcionen, "maximizar la cantidad de trabajo NO hecho".

No necesitamos Scrum, necesitamos entregar frecuentemente software que funcione.

De hecho, no necesitamos entregar por entregar, sino entregar software que tenga valor para el cliente porque nuestra máxima prioridad es satisfacerle.

Es más, implantar estas técnicas "desde las trincheras" como hemos hecho muchas veces, nos lleva a esta situación en la que podemos practicar, pero no conseguir un paso constante, seguro e interiorizado de las prácticas ágiles, porque para que funcionen las personas de negocio y las de desarrollo deben trabajar juntos y a diario en los proyectos (o en un #NoProject ;)

Quizá nos convendría poner en un mapa estos doce principios y asociar cada técnica que empleamos al principio en el que se basa, para que no olvidemos el por qué queremos usar esa técnica... ese "SO THAT" en que hacemos tanto hincapié.

Eso me he traído esta vez en mi caja del tesoro. Ahora que la he abierto estoy venga a jugar con esas ideas.
Jmmm...

06 febrero 2014

Productividad - Compartiendo experiencias

El pasado 22 de enero de 2014 nos juntamos varias personas para compartir un poco nuestras experiencias - buenas o malas - sobre la productividad

Formamos un par de equipos que participaron en el juego de terminar un dibujo en tres pequeñas iteraciones, sin que el currela/dibujante/víctima supiera lo que se cocía a su alrededor… uno de los equipos tenía un ladrón del tiempo entre ellos, previamente pactado.



Aunque para algunos fue un poco pesado tener que esperar solos a que explicáramos el juego a los implicados - cosa que tendré que mejorar la próxima vez -, el resultado del juego nos dio pie para comenzar a discutir sobre la importancia de los agentes externos en la productividad y cómo no nos damos cuenta de todo aquello que nos roba tiempo y concentración de las tareas más importantes que tenemos que terminar.


Ya metidos en el ajo, todos aportamos nuestro granito de arena sobre cómo sacar más partido del tiempo y los recursos para obtener determinados resultados (más resultados o de mejor calidad, depende de cómo se mire), pero sobre todo, hablamos de cómo conseguir estar un poco más en paz con la avalancha de trabajo que se nos viene encima cada día.

Estos son algunos de los temas de los que hablamos:
  • Foco sobre la tarea que queremos abordar
  • Aprender a decir “NO”
  • Listas, Organizar, Priorizar
  • Técnica Pomodoro
  • Evitar distracciones
  • Gestionar interrupciones
  • Productividad a nivel de equipo
  • Gestión del correo electrónico
  • Técnica GTD (Getting Things Done)
De todo lo que hablamos dedicamos bastante tiempo a cómo conseguir dedicar períodos de tiempo en los que centrar la dedicación a una sola tarea y para ello, claro está, la técnica Pomodoro es ideal, así fue tema recurrente bastantes veces y al parecer, caló entre los asistentes.

- sketching de @iceoverflow
 





- comentario de @joruus


Sólo con haber conseguido que uno de los puntos cale hondo debemos sentirnos satisfechos con haber participado de este encuentro. Gracias a la colaboración de Consultec S.L. (@ConsultecSL) por facilitar el sitio donde juntarnos y a Agile Norte (@agileNorte) por promover este tipo de eventos.

La guía de la reunión la encontraréis en: http://bit.ly/fcnatraProductivityTips

Aprender es más fácil compartiendo experiencias. Gracias por venir!

20 agosto 2013

Caso de Éxito: Scrum en un proyecto de 3 meses

Me habían pedido muchas veces que publicara cómo hicimos para que este proyecto tuviera un principio y final felices y aquí va mi retrospectiva personal.

Proyecto: Proyecto de software para industria.

Cliente: Familiarizado con las tecnologías de software, había oído hablar de Scrum, pero nunca lo había usado como marco de trabajo.

Equipo: Tres personas. Dos de ellas habían trabajado con Scrum, otra no lo conocía. Las tres personas tenían una velocidad de trabajo diferente.

Mi empresa: Nos da la libertad de gestionar el proyecto siempre que se obtengan los resultados esperados, según mi opinión, en este orden:
  1. Calidad: la máxima posible, intentando no afectar las fechas planificadas
  2. Fechas: lo más cercano a las planificadas, intentando no afectar los requisitos
  3. Requisitos: los acordados con el cliente al principio del proyecto o los que se acuerden a lo largo del proyecto

Inicio del proyecto


Los requisitos, las fechas y el presupuesto ya estaban pactados con el Cliente, pero como hago siempre, reviso de nuevo los requisitos y vuelvo a realizar una estimación predictiva con al menos uno de los miembros del equipo que va a formar el proyecto para hacerme una idea de la presión que vamos a tener. En este caso, preveía una desviación de aproximadamente un 20%.

Decidimos – el Equipo de Desarrollo – hablar con el Cliente para volver a analizar en profundidad todos los requisitos y de paso construir el Product Backlog. Para ello, sin usar términos de Scrum, le comentamos que queríamos reunirnos con ellos para analizar todos los requisitos.

Mi idea era realizar parte de una Inception, que me permitiera dejar claro a todos las partes del proyecto qué es lo que íbamos a hacer y cómo lo haríamos.

¿Por qué no toda la Inception? Pues porque era la primera vez que iba a jugar con esta técnica y porque se supone que ya estábamos consumiendo horas del proyecto en la que no se había presupuestado tiempo para esto. De modo que seleccioné aquellas preguntas que creí me permitirían acotar mejor el proyecto:
  • Definir el proyecto en una explicación corta y concisa
  • Definir qué NO es este proyecto
  • Comentar qué podría quitarnos el sueño durante el desarrollo de este proyecto
  • Conocer a los vecinos – esa lista de implicados, sean personas o no, a los que afectará el proyecto

De estos puntos lo que más nos ayudó, sin ninguna duda, fue definir “Qué podría quitarnos el sueño”. Fue lo que más nos ayudó con diferencia. Y en orden, saber “qué no es este proyecto”, luego alguna vez recurrimos a la definición del proyecto y por último, para las Historias de Usuario y definición de la seguridad, a la lista de vecinos. El haber hecho estas preguntas fue decisivo para que el proyecto llegara a buen puerto.

Luego, en un par de jornadas duras escribimos las Historias de Usuario del Product Backlog, de modo que el cliente quedó contento porque reflejaban de forma clara qué se quería hacer, para quién y por qué, aunque no estaba reflejado el cómo. Cada vez que escribíamos una, comentábamos brevemente, junto con el equipo, sobre la dificultad de la historia de usuario y le asociábamos un valor que representaba ese esfuerzo. Habiendo explicado muy rápido cómo definíamos ese valor, por qué usábamos puntos y no horas y por qué mientras más esfuerzo más separación había entre un valor de esfuerzo y el siguiente, no hubo problemas.

Cabe decir que para escribir las Historias de Usuario leímos más de una vez la oferta formal que se hizo para la contratación del proyecto, pero salieron muchas cosas que no estaban escritas en la oferta, de modo que la satisfacción estaba asegurada para todos. Así llegamos a completar la lista inicial del producto y nos hicimos una idea de cuánto esfuerzo nos llevaría desarrollar todo lo que se quería.

Una vez conocido el esfuerzo total (recalco: inicial) – hicimos un cálculo muy sencillo:
  • Explicamos al cliente que el equipo tenía una velocidad de trabajo de N puntos diarios y que esos puntos reflejaban:
    • la cantidad de trabajo que el equipo era capaz de sacar adelante cada día, es decir, la capacidad diaria de trabajo
    • que esa capacidad diaria (N puntos) es equiparable a los puntos de esfuerzo asignado a las tareas
  • Luego, teniendo la fecha límite para la entrega del producto, contamos los días laborables y determinamos la capacidad de trabajo total - aproximada- hasta la fecha de entrega y vimos que no coincidían, como casi nunca coincidirán. Para desarrollar todas las historias de usuario se necesitaba más esfuerzo que capacidad tenía el equipo.
Viendo esto, le explicamos que eso sucede en la gran mayoría de los proyectos y es por eso que se entregan fuera de plazos, con poca calidad y muchos errores, y que para evitar eso, lo que nos aseguraba la calidad era la priorización de tareas por períodos de tiempo de 15 a 20 días y la entrega, demostración e instalación del producto al final de cada período.


image
Es en este punto donde se produce un problema de negociación importante. Es en este punto clave donde hay que explicar bien, si no cabe todo, por qué no cabe y qué consecuencias traería intentar desarrollar todo con los mismos recursos en el mismo tiempo. Es en este punto – el más importante de la negociación del tan famoso triángulo de compensación – donde se va a definir qué se mueve de los pilares del proyecto: Coste/Recursos, Tiempo/Fechas o Alcance/Funcionalidades. Nosotros conseguimos explicarnos bien y he de reconocer que teníamos un cliente que comprendía las consecuencias de una decisión incorrecta – decidimos que variarían las funcionalidades a desarrollar y que las menos importantes, que quedarían fuera del desarrollo, se realizarían en fases posteriores.



Cuando hay funcionalidades que se quedan fuera de alcance la mayoría de las veces se recomienda – en este orden:
  • [Alcance] Dejar fuera aquellas funcionalidades menos importantes del proyecto, para futuras fases, después de probar, entregar y facturar lo que se ha desarrollado – Esto es sencillo si se prioriza bien al principio de cada Sprint.
  • [Coste] Ampliar el equipo hasta donde lo permita el proyecto y abordar más funcionalidades. Esto requiere una ampliación del presupuesto y requiere que la empresa cuente con personas capaces de integrarse en el equipo existente. – Dos opciones difíciles de conseguir.
  • [Tiempo] Como opción última y menos recomendable, mover la fecha de entrega final. Esta opción también requiere variar el presupuesto, porque a más tiempo de desarrollo, más costes para el proyecto – y este es un punto de muy difícil negociación una vez firmada la oferta.
    • Hay que intentar por todos los medios no mover la fecha de entrega final, porque será el comienzo de una fecha de entrega cambiante que alargará indefinidamente el tiempo de desarrollo y los costes del proyecto.
Nosotros decidimos optar por la primera opción (dejar fuera aquellas funcionalidades menos importantes) ya que ampliar el presupuesto para ampliar el equipo no estaba en los planes. Casi siempre es la opción escogida.

Y dicho esto, ¡comenzamos con el primer Sprint!

Inicio de cada Sprint


Ya en las reuniones de inicio del proyecto le explicamos al cliente que para obtener el producto que él necesitaba, nosotros, el equipo, necesitaríamos compromiso por su parte y que era imprescindible que estuviera al principio y al final de cada Sprint para validar que el trabajo que íbamos a hacer era el que él necesitaba.

De modo que habiendo llegado a un acuerdo, antes de iniciar cada Sprint hacíamos, junto con el cliente, una selección de Historias de Usuario.

¿Cómo las seleccionábamos?

La primera vez fue un poco duro porque nuestro Product Backlog no estaba priorizado, de modo que comenzamos por priorizarlo todo. Nuestra técnica para priorizar fue la siguiente:
  • Decidimos priorizar asignando valores de 1 a 100.
  • Aquellas Historias de Usuario con una prioridad de más de 75 puntos quedarían fuera del alcance de nuestro desarrollo y podrían abordarse en fases posteriores. Es importante matizar esto para evitar la idea de que esas funcionalidades nunca se van a hacer.
  • Comenzamos por la primera Historia y le asignamos una prioridad.
  • Pasamos a la segunda Historia y le asignamos una prioridad respecto a la primera Historia priorizada con una pregunta muy sencilla – “¿esta Historia es más o menos importante que esta otra?” – y luego, sabiendo si era más o menos importante, teníamos un valor de referencia para priorizarla.
  • Pasamos a la tercera historia y la priorizamos respecto a las dos Historias ya priorizadas, usando la misma pregunta.
  • A partir de la cuarta Historia teníamos varias referencias para priorizar y era mucho más sencillo decidir cuándo se debía hacer esa Historia, si antes o después de otra.
  • Si no teníamos claro el orden en que debíamos poner dos Historias de Usuario podíamos darles la misma prioridad o cambiar algún valor de prioridad que habíamos dado anteriormente a otra Historia.
  • Al Product BackLog podían entrar nuevas Historias de Usuario en cualquier momento. Al inicio del siguiente Sprint les asignábamos un esfuerzo y las priorizábamos.
Al saber cuánta capacidad de desarrollo teníamos hasta la fecha de entrega y tener priorizadas –ordenadas- las Historias, sabíamos qué se quedaba fuera cada vez que entraba una nueva historia. Eso permitía al cliente ver, en todo momento, las consecuencias de los nuevos requisitos y priorizar mejor, porque la prioridad indicaba qué entraba y qué no entraba en cada versión del producto final.

Y una vez priorizadas, seleccionamos las Historias de Usuario del Sprint por comenzar. Para seleccionarlas, en vez de decidir primero los días que iba a tener el Sprint, seleccionábamos un grupo de ellas que ocuparan de 15 a 20 días de desarrollo – las más importantes. Los pasos que hacíamos eran:
  • Seleccionar las Historias más importantes, según su prioridad, de modo que la suma del esfuerzo ocupara de 15 a 20 días de desarrollo, atendiendo a la velocidad del equipo de desarrollo.
    • Si ya el cliente había probado una versión anterior del producto:
      • Hablamos de los cambios que deseaba incluir o las incidencias que había encontrado.
      • Los cambios ya sabemos cómo los tratamos: incluimos y priorizamos antes de comenzar la selección.
      • Las incidencias son la mayoría de las veces responsabilidad nuestra y tenemos que resolverlas como primeras tareas del siguiente Sprint, suman tiempo al Sprint, tiempo que debe asumir el equipo y que no suele ser facturable.
    • Si se habían incluido Historias de Usuario – cambios – durante el desarrollo del Sprint anterior, se priorizaban antes de comenzar la selección.
  • Definíamos en presencia del cliente las Tareas a realizar por cada Historia de Usuario y le asignábamos el tiempo de desarrollo a las tareas, esta vez en horas. Comprobábamos que la suma horas de las tareas se correspondía con el esfuerzo que habíamos asignado a la Historia de Usuario contra la Velocidad de trabajo. Si no se correspondía, modificábamos el esfuerzo de la Historia, para ser realistas.
    • En cada tarea poníamos, junto con el cliente, lo mejor que sabíamos, los criterios de aceptación
    • Dentro de las tareas de cada Historia, como costumbre personal, incluimos la de actualizar la Guía de Usuario y la Guía de Instalación, de modo que con cada entrega tuviésemos actualizada la documentación a entregar – por cada tarea. Esto me ha demostrado un ahorro de tiempo considerable.
  • Por último, definíamos los días que ocuparía el Sprint y la fecha de la próxima reunión, donde realizaríamos la demo y entregaríamos al cliente el desarrollo realizado para que lo instalase en los servidores, junto con la documentación que le permitiría instalar y trabajar con el producto.
Me gustaría recalcar dos puntos que considero muy importantes:
  • En el primer Sprint incluimos todas las tareas necesarias para montar la arquitectura inicial del proyecto. Esas tareas las incluimos delante del cliente, de modo que viera que “eso” también lleva tiempo. No hubo problemas con la asignación de tiempo para ello.
  • En el primer y segundo Sprints decidimos incluir todas aquellas funcionalidades relacionadas con “aquello que nos quita el sueño” y que hablamos en la Inception. Esta decisión nos quitó muchísimas preocupaciones de encima a lo largo del proyecto, ya que todos los problemas que podían surgir se solucionaron en la primera mitad del proyecto, consiguiendo el final feliz que todos queríamos.

Reuniones de planificación, seguimiento, entrega y todas (y sólo) las que sean necesarias


Respetar el tiempo de los demás es primordial para que las reuniones sean efectivas y no se vean como innecesarias o como un retraso en el trabajo.

Para ello, es muy importante al realizar una convocatoria poner bien claro de qué se va a hablar en la reunión y poner una duración realista para que todos sepan de antemano a qué se va y cuánto tiempo se va a estar.
Por lo demás, hay mucha documentación que ayuda a mantener reuniones efectivas. De modo que no comentaré este punto.

Durante todo el proyecto intentamos, por todos los medios, mantener las reuniones que recomienda Scrum y lo conseguimos. Nos reuníamos tanto de forma presencial como en remoto.

No sólo nos juntábamos en el momento de la reunión, sino que cuando hizo falta, hicimos pair-programming aunque tenemos que mejorar en las técnicas a emplear y cualquier otra vez que lo necesitábamos, nos juntábamos para comentar cómo abordar un determinado detalle del proyecto. – Nunca nos pareció que nos juntásemos más de la cuenta, la verdad, y cuando pensábamos que nos estábamos enrollando mucho cualquiera de nosotros lo decía y decidíamos lo que fuese – o seguir o cambiar o arrancar a desarrollar de nuevo.

Es responsabilidad de todo el equipo – incluyendo al cliente, claro está – el no malgastar el tiempo. De cualquier modo, cuando tenemos las tareas ahí, frente a la cara, esperando para ser desarrolladas y un tiempo con el que nos hemos comprometido, sabemos que hay que trabajar porque es nuestra palabra el entregar en tiempo y forma lo que hemos dicho.

Y no sé qué más contaros… ah sí, una cosa, en el último Sprint decidimos “probar” a no actualizar las guías de usuario y de instalación en cada tarea, sino actualizarlas al final, como última tarea, antes de la demo con el cliente. Resultado? – Esa vez no pudimos entregarlos porque nos concentramos en terminar otras cosas más importantes.

Post-Proyecto


Una vez entregado el último paquete del producto nos cogimos un par de semanas por nuestra cuenta para probar bien el producto e ir solucionando aquello que no funcionase bien. Esto nos lo pudimos permitir por la carga de trabajo de ese momento. Por lo general ese tiempo debe estar planificado dentro del proyecto, desde el inicio, y casi nunca se hace para abaratarlo. No debería haber problemas si se desarrolla bien, pero eso es casi una quimera.

El cliente no nos reportó prácticamente ninguna incidencia y las que encontramos por nuestra cuenta las resolvimos e hicimos una última entrega.

Ya que el cliente planeaba continuar ampliando por su cuenta el producto, pero quería realizarnos consultas o solicitarnos pequeños desarrollos se le propuso una bolsa de horas en las que nos pudiera solicitar cualquier desarrollo sobre el mismo u otro producto y las consultas que necesitase y fue aceptada.

El cliente nos envió un mensaje contándonos lo cómodo que estuvo durante el tiempo de desarrollo y su satisfacción con el producto final.

Nosotros aprendimos a valorar – yo una vez más – la comodidad del trabajo con Scrum.

Hay muchos más detalles sobre el trabajo de desarrollo día a día, pero cada uno de ellos merece ser explicado con calma.

Espero que esta historia os sirva para algo y si hacéis otras cosas que nos permitan mejorar el trabajo y sentirnos más cómodos al abordar un proyecto, estaré encantado de que me lo contéis.

27 junio 2013

Pon un hobby en tu vida, que te guste y que te ayude

Sí, un hobby, no un hobbit.

Tenemos toda la libertad del mundo para escoger qué hacer con nuestro tiempo libre: ver la tele, ir al cine, ayudar a otros, leer un libro, practicar un deporte o un juego de mesa, o salir con nuestras amistades, pero ese hobby ¿lo hemos elegido nosotros o es él quien nos ha elegido? ¿Hemos probado otras opciones que podrían mejorar nuestra vida de forma significativa? A veces nos dejamos llevar y terminamos dedicando nuestro tiempo libre a algo que nos entretiene, pero que no nos aporta nada.

Elegir un hobby que nos permita llevar una vida personal y profesional mejor va a incidir en nuestra calidad de vida en... ¿cuánto?... mucho, sin duda. Eso sí, la elección no es tarea sencilla. Bueno, escoger sí, acertar con uno que además de ayudarnos, nos guste, quizá no tanto.



Uno bien seleccionado nos ayudará a afrontar mejor los problemas, porque mientras lo practicamos nuestro cerebro y nuestro cuerpo también practican y eso nos moverá a tener otros puntos de vista, mejor humor y más paciencia. He probado los efectos positivos de un buen hobby y los hecho mucho de menos cuando no lo practico.

El hecho de sentirnos cómodos con lo que hacemos en nuestro tiempo libre nos hace dudar ante la idea de cambiar la forma de aprovechar ese tiempo. Salirnos de nuestra “zona de confort” siempre nos da pereza y miedo, pero una vez que nos lanzamos se abre ante nosotros un mundo nuevo de experiencias. De hecho, no es imprescindible cambiar nuestros pasatiempos, sino que lo verdaderamente interesante es explorar más allá de lo que conocemos.


Por ejemplo, un deporte nos traerá consigo beneficios físicos y efectos mentales positivos. Al practicar ejercicio físico nuestro cuerpo genera endorfinas que nos producen bienestar, vitalidad y alegría y que tienen un efecto analgésico. He tirado de la wikipedia y de endorfina salté a opiáceos y de ahí a narcóticos... entonces paré... No en balde dicen muchos que ciertos deportes son como una droga... te enganchan.


Si el hobby que practicamos es de trabajo en equipo, mejorará tus habilidades de comunicación, te ayudará relacionarte y a sentir más empatía por quienes te rodean. Esto nos hará la vida más fácil en el mundo laboral.


Lo que sí es importante es que ese hobby no sea la misma tarea que realizas en el trabajo, porque eso no abre tu campo de mejora personal, no relaja tu mente, no te ayuda a cambiar el chip ni a resolver los problemas "retos ;)" que se presenten, porque sólo tienes una perspectiva para afrontarlos. 


En mi opinión, el objetivo no debería ser encontrar el hobby ideal (que nos guste y nos ayude personal y profesionalmente) - aunque si lo encontramos, mejor -. Lo más importante de todo es, como en todas las facetas de la vida, explorar nuevos caminos. Es en esa búsqueda donde creceremos de verdad.



Caminante, no hay camino, se hace camino al andar

Y ya que os incito a tener un hobby os digo el mío, el que me gusta y me ayudó a crecer mucho, y que tengo un poco abandonado: es el Mugendo. Espero retomarlo pronto.

09 julio 2012

Auto-conversación (¿salario = valor que aportamos?)

- ... ¿y si nuestro salario lo definiese el valor que fuésemos capaces de aportar? - una media del valor que aportamos, por ejemplo. Sería todo más justo, ¿no?

- Estaría bien, pero... ¿qué empresa puede decir con certeza que es capaz de "medir" el valor que aporta cada persona? ¿cómo se podría medir el valor que aporta un scrum master, un director de departamento o un comercial?,  ¿ventas, reuniones? ¿cómo se mide la motivación que has creado, el conocimiento que has transmitido, la organización que has conseguido implantar? - ¿encuestas, velocidad de programación?

- Al final, el valor que se aporta no siempre va alineado con el valor que necesita la empresa que aportes, pero en ese caso, ya sabemos qué hay que hacer: poner a cada persona en el sitio en el que más valor aporte. La medición del valor aportado sacaría a la luz que no estamos dando lo que se necesita en el puesto en el que estamos. Quizá yo sea mejor programador que jefe de proyectos, o viceversa.

- Volvemos a una premisa fundamental: todo pasa por medir. Algunas empresas lo hacen mediante falsas evaluaciones del desempeño. Digo falsas porque no se basan en medidas claras, muchos de sus puntos se basan en opiniones y, lo más grave, en muchísimas empresas no hay suficiente confianza como para hacer evaluaciones de 360 grados.