Mide el desempeño de tu equipo

Hoy en día con la digitalización, todas las actividades humanas van dejando una traza de cómo se desarrollo la historia y son los Data Scientists los encargados de leer esta traza y poder así contar una historia cuantificada y neutra.

Una de las cosas más difíciles de medir es el desempeño de las personas, para esto, la mejor práctica es poner metas medibles y alcanzables (metas S.M.A.R.T.), pero esto muchas veces puede no ser práctico, en especial cuando hay mucho trabajo en equipo.

En el desarrollo de software, se utiliza una herramienta llamada GIT para llevar el versionamiento del código de software escrito, al ir guardando un registro de las modificaciones en el código fuente del software, al hacer esto, también estamos guardando una traza de cuantas lineas se han escrito, lo que podría tener una alta correlación con el aporte al software desarrollado por el equipo.

En este artículo veremos un ejemplo de como realizar estas mediciones usando R.

Primero vamos a explicar la idea:
si entramos a un repositorio GIT podemos usar el git log para extraer información de los cambios realizados>

 ~/Documents/anasac/corp_fact_ventas_v2  master  git log                                                                     ✔  21:48:50 
commit 22049b2cfefac3aa42d83d942e836d8f79013cbf (HEAD -> master, origin/master, origin/HEAD)
Author: Daniel Fischer <dfischer@anasac.cl>
Date:   Sat Mar 5 02:13:28 2022 +0000

    fvfddffd

commit 0e16e038f0816088450d2a5fb211adda0db5bd92
Author: Daniel Fischer <dfischer@anasac.cl>
Date:   Sat Mar 5 02:09:58 2022 +0000

    disale index

commit 855344eec9231706d56906aeb3853e940a2acef0
Author: Daniel Fischer <dfischer@anasac.cl>
Date:   Sat Mar 5 01:13:29 2022 +0000

    col ano para particion

commit 0cdfe0029730dbbfe6188f3ae097f6ced73762cb
Author: Daniel Fischer <dfischer@anasac.cl>
Date:   Fri Mar 4 21:45:24 2022 +0000

    id_pedido_venta

commit aaa15bee0f906e100e554c951658595b51900870
Author: Valentina <vcastro@anasac.cl>
Date:   Wed Mar 2 19:28:23 2022 +0000

    fix fecha

commit 5cd1314b6e47901925c27cdcdfd9b25ca257aa1b
Author: Daniel Fischer <dfischer@anasac.cl>
Date:   Wed Mar 2 18:54:33 2022 +0000

Pero ese es un formato un poco, incomodo, por suerte git log, nos permite seleccionar el formato de salida del log, en este caso le pediremos que nos de el log en formato CSV con las sigueintes columnas:
id del cambio o hash, fecha del cambio, usuario o desarrollador y por ultimo el comentario del commit


~/Documents/anasac/corp_fact_ventas_v2  master  git log --date=format:'%Y-%m-%d' --pretty='%H;%ad;%al;%s'                   ✔  21:48:56 
22049b2cfefac3aa42d83d942e836d8f79013cbf;2022-03-05;dfischer;fvfddffd
0e16e038f0816088450d2a5fb211adda0db5bd92;2022-03-05;dfischer;disale index
855344eec9231706d56906aeb3853e940a2acef0;2022-03-05;dfischer;col ano para particion
0cdfe0029730dbbfe6188f3ae097f6ced73762cb;2022-03-04;dfischer;id_pedido_venta
aaa15bee0f906e100e554c951658595b51900870;2022-03-02;vcastro;fix fecha
5cd1314b6e47901925c27cdcdfd9b25ca257aa1b;2022-03-02;dfischer;relleno fcast
4bf9db5250fe688348d58c602082e089fdaa32c7;2022-03-02;dfischer;fixes
370b760d3e58428ce328ad5aa281146fc6aefec1;2022-03-02;dfischer;pasado forecasts
24140747f0236b812c7b7a68df1fb33a2b3090c4;2022-03-02;dfischer;fix ppto
22ed8b64d58c1164b1119d6371913cbcd2c7b60b;2022-03-01;vcastro;ventas smk
bae35b891d9c91d0941104c9ad53725e91a953f2;2022-03-01;vcastro;ventas en usd
6f29aad5a5738d2e6a6235764767ac04e81b0503;2022-03-01;vcastro;ventas en usd
ca1201cb7984778affc6d24e33e2c2098973f383;2022-03-01;dfischer;corr an02
2e534c9e72c892274619497f4fa131bb059c9776;2022-03-01;dfischer;Merge branch 'master' of bitbucket.org:anasac-analytics/corp_fact_ventas_v2
64a57e1acbeb76be05b9d9ee34429cf3db3cee6a;2022-03-01;dfischer;pedido_venta
4d6874c9c177c8c385ef7211c006a451bc42f64c;2022-02-24;vcastro;inicial todas las filiales
e0342bafd7c4cb50f58ecbce87ff2dfb9034b94b;2022-02-23;dfischer;cambio fecha
26e9fb44d7d5d833b75691671e27da83946780d2;2022-02-23;dfischer;checkpint
bd3f10a03d726d7f8a9341de34ef17f01a6c9ea6;2022-02-23;dfischer;cantidad mat pedido
05c3b87b411fc46bcfd893d1b7f7defdb4df14c1;2022-02-23;dfischer;fix
2def3cee8dc2a6a3866004387fea260b96f7e7d6;2022-02-23;dfischer;fix
7f0e52b4f1cb57ccb9aa7578714675f609cbf18b;2022-02-23;dfischer;cantidad al costo
528342724ea6be43f7254f96fa58c1ea94c4d980;2022-02-23;dfischer;material inac
7e17a96bf632c61fd146eaa3511c06ea8fd00e7a;2022-02-23;dfischer;incompletos
7e267729d078e8b37efd8369cf9578ff85a58572;2022-02-22;dfischer;vta_int
f25f2cde9be373b5a405fab9eac91a3f0303fefb;2022-02-22;dfischer;NC a libro diario
ecb747106321459463aa29220d3f87984650829f;2022-02-22;dfischer;cantidad de material en ingreso
bd0e5842d76841bb785c13f24660d1dc22dbcf8a;2022-02-21;dfischer;nc out

con la tabla anterior ya tendríamos una metrica sobre cuantos commit hizo cada desarrollador, pero no todos los commit son iguales, con el id/hash del commit podemos acceder al detalle de este.

La primera columna es el numero de lineas agregadas, la segunda es el numero de lineas borradas y la ultima es el archivo modificado, en el ejemplo a continuación podemos ver claramente que hay commits que tienen más trabajo que otros, por lo que lo mejor es contar las lineas agregadas.

 ~  git -C /home/dfischer/Documents/anasac/acl_etl show --numstat e7040035cf5bc4bdf3eaa75e9371a31de00bff30                ✔  22:27:05 
commit e7040035cf5bc4bdf3eaa75e9371a31de00bff30 (HEAD -> master, origin/master, origin/HEAD)
Author: cinostroza <cinostroza@anasac.cl>
Date:   Fri Apr 8 20:31:08 2022 +0000

    extraccion fm clientes

93      57      preprocessing/fm.clientes.py
3       0       run.sh

Por último, un equipo puede estar trabajando en varios proyectos a la vez por lo que además de sacar las métricas para cada commit, se deben sacar para cada repositorio.

Lo primero es Clonar todos los repositorios en los que se esta trabajando en una carpeta, tal como en la foto a continuación:
file

y ejecutaremos el siguiente Script de R:

cabecera = data.frame()
for(g in gits){
  # g = gits[5]
  cab = system(paste("git -C",g,"log --date=format:'%Y-%m-%d %H:%M:%S' --pretty='%H\t%ad\t%al\t%s'"),intern = T)
  cab = do.call(rbind,str_split(cab,"\t")) %>% data.frame() %>% select(1:4)
  colnames(cab) = c("hash","date","user","comment")
  cab$date = ymd_hms(cab$date)
  cab$repo = basename(g)
  cabecera = bind_rows(cabecera,cab)
}

detalle = list
for(n_cab in 1:nrow(cabecera)){
  # n_cab = 1
  cab = cabecera[n_cab,]
  # ant = cabecera[n_cab + 1,]
  # print(cab)
  try({
    det = system(paste0("git -C ",git_path,cab$repo," show --numstat ",cab$hash),intern = T)
    det = det[-1:-6]
    det = do.call(rbind,str_split(det,"\t")) %>% data.frame() %>% select(1:3)
    # print(det)
    colnames(det) = c("added","removed","filename")
    det = det %>% mutate(
      repo = cab$repo,
      hash = cab$hash,
      added = as.numeric(added),
      removed = as.numeric(removed)
    )
    det$repo = cab$repo
    det$hash = cab$hash
    # detalle = bind_rows(detalle,det)
    detalle = append(detalle,det)
  })
}
detalle = bind_rows(detalle)

dataset = cabecera %>% inner_join(detalle, by =c("hash","repo"))

#eliminamos los hash duplicados por forks
dataset = dataset %>% group_by(hash) %>% 
  filter(row_number() == 1) %>% 
  ungroup()

obteniendo una tabla del siguiente modo:
file

con este podemos construir métricas como:

Cuales son los proyectos que mas han recibido trabajo:

> dataset %>% 
+   group_by(repo) %>% 
+   summarise(added = sum(added,na.rm = T),.groups = "drop") %>% 
+   arrange(desc(added)) %>% 
+   print(n=100) %>% 
+   View()

file

Que repositorios han recibido la mayor cantidad de trabajo en los últimos 2 meses:
file

por ultimo, quienes son los usuarios que mas han colaborado a cada repositorio en los ultimos 2 meses (nombre de desarrollador tapado):

> dataset %>% 
+   filter(date>=as.Date("2022-01-01"), !repo %in% c("backup_tabla_manual","mantencion_atenea","script_configuracion","sandobox_dfischer")) %>%
+   group_by(user,repo) %>% 
+   summarise(added = sum(added,na.rm = T),.groups = "drop") %>% 
+   arrange(desc(added)) %>% 
+   spread(user,added) %>% 
+   print(n=100) %>%
+   View()

file

y así se pueden crear infinitas métricas.

como bonus les dejo el siguiente script en python para actualizar todos los repositorios de una carpeta

#!/bin/python3
import os

dirs = os.listdir()
path = os.getcwd()

repos = [path + "/" + d for d in dirs if d[0] != '.']

for r in repos:
    if os.path.isdir(r):
        print(r)
        os.chdir(r)
        os.system("git pull")

Saludos!

como siempre el repositorio con el codigo en git:
https://github.com/danielfm123/git-metrics

Print Friendly, PDF & Email