mercoledì 20 maggio 2009

Deep dynamics

Ad un incontro con xp ug di Milano ho parlato per un'oretta di quanto mi ricordavo di "Deep Dynamics of agile teams".

Gli argomenti sono stati:

identità individuale

"mainstream flow, cambiamenti/turbolenze", metafora del fiume, e degli affluenti,
conversazioni difficili,
B.A.T.N.A.: best alternative to negotiation agreement,

intento e impatto di un messaggio

"yes, and..." vs. "yes, but...",

gestire la polarizzazione tra due tesi contrapposte, (*)
conflitto, soluzioni win win. (cooperazione rispetto a compromesso o resa/vittoria)

ribaltare una "accusa" ("tu sei X". "Se per X intendi .... allora si' d'accordo con te")
"temperatura" come stato: confort, un-confort, panic

learning culture vs blaming culture

mindset preconvenzionale, convenzionale, postconvenzionale.
social rank, legitimate rank, personal rank.

Mi è stato chiesto qualche riferimento bibliografico, e sono rimasto spiazzato.
Mi sono ricordato di “Project Retrospectives” di Norman Kerth, ma in realtà era faceva parte dei testi consigliati in un altro corso di Joseph, quello di Scrum. Forse alla fine una bibliografia non ci fu data. Si tratta in effetti di un mix di argomenti mutuati dalla psicologia applicati alle interazioni interne ad un team.

"Difficult Conversations"

Ho pensato a quali libri io avrei considerato vagamente correlati all'argomento, e mi sono venuti in mente:
"Calcoli Morali - Lazlo Mero "
"Nexus. Perché la natura, la società, l'economia, la comunicazione funzionano allo stesso modo - Buchanan Mark"
"Creatività e pensiero laterale -E. De Bono"


Avrei anche aggiunto, ma un po' più, alla lontana
"Verso un'ecologia della mente. G. Bateson"
"La società della mente - Marvin Minsky"

lunedì 18 agosto 2008

Il cavaliere oscuro e il dilemma del prigioniero

Attenzione, questo post contiene spoiler del film "Il cavaliere oscuro".

In una scena del film "il cavaliere oscuro" si presenta una variante del dilemma del prigioniero.

Un gruppo di persone si trova in una nave. Esse hanno accesso ad un detonatore che puo' far saltare in aria una seconda nave nella quale vi sono altre persone, ed un altro detonatore, che può far saltare in aria la prima nave.
Se nessuno dei due detonatori verra' premuto, il Joker dice che fara' saltare in aria entrambe le navi.

La cosa si puo' schematizzare nel seguento modo:

ci sono un ostaggio A in una nave ed un ostaggio B in un'altra nave.

L'ostaggio A puo' raggiungere in un certo tempo T_A il detonatore in grado di far saltare in aria la nave su cui si trova l'ostaggio B.
l'ostaggio B puo' raggiungere in un certo tempo T_B il detonatore in grado di far saltare in aria la nave su cui si trova l'ostaggio A.
Ad entrambi e' stato fatta la minaccia che se ne' l'uno ne' l'altro premera' il detonatore entro una certa ora, allora saranno uccisi entrambi.

Non e' noto se il tempo per raggiungere il detonatore sia piu' basso per A o per B, quindi la probabilita' che ci metta piu' tempo A o piu' tempo B sono da considerare pari al 50%.

Se l'obiettivo e' solo di salvare il massimo numero di vite umane (una o nessuna), la strategia migliore e' quella di raggiungere il detonatore e premerlo. In questo caso almeno uno dei due si salva, cioe' quello che arriva prima al detonatore.

Ma possono influire anche altri fattori, come il non essere in grado di risolvere il dilemma morale che la scelta comporta, o anche il considerare la possibilita' che il Joker non mettera' in atto la sua minaccia, rendendo un sacrificio inutile l'aver premuto il detonatore.

Se si fosse sicuri che anche l'altro ostaggio ha deciso di premerlo, allora si puo' legittimare la scelta di farlo a propria volta, per "difendersi".

Abbiamo un mix dei seguenti principi, a determinare la scelta:
premere il detonatore e' accettabile in caso di "leggittima difesa preventiva", cioe' se si e' sufficientemente sicuri che l'altro ha deciso di farlo a sua volta.
Premerlo può comportare un sacrificio inutile, se il Joker non mettera' in atto la sua minaccia di far saltare in aria entrambi qualora nessuno dei due dovesse premerlo.

Al di là del Joker, ponendo che l'unica motivazione per premere il bottone è di difendersi preventivamente.


A si dirige verso il detonatore e lo raggiunge.
A è ancora vivo, quindi pensa che B non ha ancora raggiunto il detonatore oppure ha deciso di non premerlo.

C'è la possibilità che B ha deciso di non premere il detonatore, e allora A decide di non farlo a sua volta.

Questa possibilità con un ragionamento fallace può essere considerata al 50%, come per esempio.

Se B avesse voluto premere il detonatore, avrebbe avuto tempo D_B, per premerlo, e la probabilita' che D_B sia inferiore D_A e' stimata al 50%.
A non e' saltato in aria, e quindi o B non ha ancora raggiunto il detonatore (50% di probabilita') oppure ha deciso di non premerlo (con la restante probabilita' del 50%).

Se B fa lo stesso ragionamento nessuno dei due lo premera'.

Il ragionamento pero' per essere completo avrebbe bisogno di ulteriori informazioni, cioe' le probabilita' a priori, e l'uso della regola di Bayes, che cambiano considerevolmente questa stima del 50%.
Poniamo per esempio che la probabilita' a priori che B voglia premere il detonatore sia del 90%, abbiamo i seguenti casi:

P(B vuole premere il detonatore) = 0.9
P(B non vuole vuole premere il detonatore) = 0.1
P(B preme il detonatore) = P(B vuole premerlo e D_B<D_A) = P(B vuole premerlo)*P(D_B<D_A) = 0.45
P(B non preme il detonatore) = P(B vuole premerlo e D_B>D_A) oppure P(non vuole premerlo) = 0.45+0.10

A arriva vivo al detonatore, e vuole sapere questo fatto quanto cambiano le cose, cioe' quanto vale la probabilita' che B vuole premere il detonatore dato che A e' arrivato vivo al detonatore.

La probabilita' dell'evento contrario (che B non vuole premere il detonatore dato che A e' arrivato vivo) e':
P(B non vuole premere il detonatore | A arrivato vivo al detonatore) = P(A arrivato vivo al detonatore | B non vuole premere) P(B non vuole premere)
P(A arrivato vivo al detonatore | B non vuole premere)* P(B non vuole premere) + P (A vivo davanti al detonatore | B vuole premere)*P(B vuole premere) = (1*0.1)/(0.1 + 0.5*0.9) = 0.18

P(B vuole premere | A arrivato vivo al detonatore) = 0.82.

Tutto dipende dalla probabilita' a priori che P voglia premere il detonatore, che e' un problema di mindset di attidudine mentale/morale che A ha di B.

Infatti, proprio nel film, si mostra chiaramente che questi ipotetici sistemi di riferimento morale sono presumibilmente diversi:
in A vi sono cittadini comuni, in B dei carcerati.

riferimenti:
dilemma del prigioniero: http://it.wikipedia.org/wiki/Dilemma_del_prigioniero,
regola di Bayes: http://it.wikipedia.org/wiki/Teorema_di_Bayes,
si e' vagamente accennato a problemi di decisione che possono essere chiamati dilemmi morali. Per saperne di piu': http://en.wikipedia.org/wiki/Trolley_problem
Altro blog: http://www.quantitativepeace.com/blog/2008/07/the-dark-knight.html


sabato 29 marzo 2008

politiche economiche e fiscali for dummies

Della serie: "Io sono di parte, ma le cifre no!"
Bel lavoro!

venerdì 22 febbraio 2008

yaari spam (capitato anche a me)

Mi sono iscritto a questo sito di social network (yaari) causa di un "invito" arrivatomi via mail presumibilmente da una persona che conosco.
Effettivamente i dati coincidevano quasi.
Errore: dopo che mi sono iscritto, sono partiti altrettanti falsi inviti a mio nome verso indirizzi presi dalla mia rubrica (tra cui un mio secondo account).

A quel punto mi sono disiscritto (o almeno spero) ed ho invitato i miei amici a cestinare questo tipo di inviti.

Probabilmente anche io sono incappato nel problema quanto descritto da questo articolo.

Ovviamente cercano di fare piu' utenti possibili, ma questa politica scredita i siti di social network (anche quelli piu' seri), e poi non so fino a che punto funzioni davvero.

Immagino che le segnalazioni anti-spam ed anti-abuse che ne seguono finiscano per far aggiornare i filtri anti-spam dei vari providers, in modo da filtrare gli inviti provenienti da quel sito, compresi quelli leciti (volontari).

(p.s. pero' una cosa buona come conseguenza e' capitata: l'invito involontario e' arrivato a persone che non sentivo da anni, le quali, pur declinando, hanno sentito il bisogno di rispondere, insomma ho avuto occasione per riallacciare dei contatti ;-) )

lunedì 18 febbraio 2008

Bash: come capire quale .jar contiene una certa classe

Se sei nella directory contenente i jar da cercare:

for i in `ls *.jar`; do echo $i; jar -tvf | grep eventuale.package.NomeCasse; done;

Se i jar possono essere in diverse sottodirectory a partire dalla directory corrente:

for i in `find . -name | egrep ".*\.jar$"`; do echo $i; jar -tvf | grep eventuale.package.NomeCasse; done;


(Non ho provato su Windows)

martedì 12 febbraio 2008

martedì 5 febbraio 2008

Torneo Refactoring parte 2

Sempre a riguardo della prova relativa al torneo refactoring, provo a continuare con la mia proposta di soluzione, iniziata nel post precedente.

la prova03 evidenzia che nella classe printSlip la evaluate non sarebbe testabile perché usa lo standard output:
public void evaluate(Object aResource) {
System.out.println(((Resource)aResource).name());
System.out.println(((Resource)aResource).salary());
}
incidentalmente questa implementazione corrisponde al layout sintetico, descritto più avanti, che ha output tipo:
"Francesco\n1000.00\n"

Esiste anche un layout più dettagliato, che viene chiesto di implementare:
Il layout dettagliato della busta paga di una risorsa ha il seguente formato: "Nome: , Salario: \n". Per esempio, per Francesco con salario 1000 euro, il sistema produrrà: "Nome: Francesco, Salario: 1000.00\n"

Abbiamo due obiettivi:
1)rendere testabile la printSlip,
2)poter gestire più di un layout.

Per il n.1, astraggo sulla modalità di gestione dell'output, quindi la "stampa" userà un generico OutputStreamer (interfaccia che creiamo poi, che prescrive un unico metodo "print") e posso usare un mio OutputStreamer "fittizio" (mock) solo per i test.

Per il n.2, rendo astratta la classe PrintSlip stessa, delegandone la concreta implementazione della evaluate (sintetica o analitica), che implementeranno i due di layout:


public abstract class PrintSlip implements Block {

protected OutputStreamer outputStreamer = new OutputStreamer()
{
public void print(Object object) {
System.out.print(object);
}
};

public void setOutputStreamer(OutputStreamer outputStreamer) {
this.outputStreamer=outputStreamer;
}

public OutputStreamer getOutputStreamer() {
return outputStreamer;
}

public abstract void evaluate(Object aResource);

}


Implementazine "sintetica":


public class PrintSlipImplSyntetic extends PrintSlip {
public void evaluate(Object aResource) {
outputStreamer.print(((Resource)aResource).name());
outputStreamer.print("\n");
outputStreamer.print(((Resource)aResource).salary());
}
}



Implementazione "analitica":



public class PrintSlipAnalitic extends PrintSlip{
public void evaluate(Object aResource) {
outputStreamer.print("Nome:"+((Resource)aResource).name()+",Salario:"+((Resource)aResource).salary()+"\n");
}
}




Per testare queste due novità mocko la evaluate in modo che l'output sia diretto in una stringa:


@Test
public void testPrintSlip() {
Contract nov1 = new Contract(nov1st2005());

PrintSlip printSlip = new PrintSlipImplSyntetic();

printSlip.setOutputStreamer(
new OutputStreamer() {
public void print(Object object) {
result += object;
}
}
);

MockedEmployee employee1 = new MockedEmployee("Francesco", nov1);
employee1.setPrintSlip(printSlip);
employee1.printSlip();
String results = printSlip.getOutputStreamer().getResult();
assertEquals("Francesco\n1024.89",results);

}



@Test
public void testPrintSlipAnaliticWithFactory() {
Contract nov1 = new Contract(nov1st2005());

PrintSlipFactory factory = new PrintSlipFactory();
factory.setCurrentLayout(PrintSlipFactory.ANALYTIC);
PrintSlip printSlip = factory.getPrintSlipWithCurrentLayout();

printSlip.setOutputStreamer(
new OutputStreamer() {
public void print(Object object) {
result += object;
}
}
);

MockedEmployee employee1 = new MockedEmployee("Francesco", nov1);
employee1.setPrintSlip(printSlip);
employee1.printSlip();
String results = printSlip.getOutputStreamer().getResult();
assertEquals(results, "Nome:Francesco,Salario:1024.89\n");
}






Btw sia in questa prova (prova03) che in quella precedente sembra che si suggerisca di incapsulare le PrintSlip e InForce per rendere alcuni oggetti meno... "tristi"

Io le ho spostate entrambe in Resource:


abstract public class Resource {
protected Block printSlip = new PrintSlipImplSyntetic();

public boolean isInForce()
{
InForce inForce = new InForce();
return inForce.is(this);
}

public void setPrintSlip(PrintSlip printSlip)
{
this.printSlip=printSlip;
}

public Block getPrintSlip()
{
return printSlip;
}

public Resource(String name, Contract contract) {
_name = name;
_contract = contract;
}

abstract public double salary();

public Contract lastContract() {
// Semplifichiamo :) la ricerca dell'ultimo contratto
return _contract;
}

public String name() {
return _name;
}

public String toString() {
return _name + ":" + _contract + ".";
}

private String _name;
private Contract _contract;

public void printSlip() {
printSlip.evaluate(this);
}

}


In questo modo il test precedente può diviene:


@Test
public void testPrintSlipDefaultWithFactory() {
Contract nov1 = new Contract(nov1st2005());

PrintSlipFactory factory = new PrintSlipFactory();
factory.setCurrentLayout(PrintSlipFactory.SINTETIC);
PrintSlip printSlip = factory.getPrintSlipWithCurrentLayout();

printSlip.setOutputStreamer(
new OutputStreamer() {
public void print(Object object) {
result += object;
}
}
);

MockedEmployee employee1 = new MockedEmployee("Francesco", nov1);
employee1.setPrintSlip(printSlip);
employee1.printSlip();
String results = printSlip.getOutputStreamer().getResult();
assertEquals(results, "Francesco\n1024.89");

}


posto, comunque, che abbia preso come decisione di adottare una factory che consenta di settare un layout, e restituire poi la printSlip relativa al layout così settato:



public class PrintSlipFactory {
public static String SINTETIC="SINTETIC";
public static String ANALYTIC="ANALYTIC";
private OutputStreamer currentOutputStreamer= new OutputStreamer() {
public void print(Object object) {
System.out.print(object);
}
};

private String currentLayout="SINTETIC";

private static HashMap mapLayouts=new HashMap();
static {
mapLayouts.put("SINTETIC",PrintSlipImplSyntetic.class);
mapLayouts.put("ANALYTIC",PrintSlipAnalitic.class);
}

public void setCurrentLayout(String layout) {
this.currentLayout = layout;
}

public void setCurrentOutputStreamer(OutputStreamer outputStreamer)
{
this.currentOutputStreamer=outputStreamer;
}

public PrintSlip getPrintSlipWithCurrentLayout() {
try {
PrintSlip toReturn = (PrintSlip)((Class)mapLayouts.get(currentLayout)).newInstance();
toReturn.setOutputStreamer(currentOutputStreamer);
return toReturn;
} catch (Exception e)
{
// unable to set layout
}
// default
return new PrintSlipImplSyntetic();
}
}




Ultima cosa, in relazione alla gestione dell'output su file di testo, penso ad una logica che sfrutti l'outputStreamer pensato per gestire il mock, e faccio un test allo scopo per vedere se può funzionare:


@Test
public void testPrintSlipAnaliticWithFactoryFileTextOutputStreamer() {
Contract nov1 = new Contract(nov1st2005());

PrintSlipFactory factory = new PrintSlipFactory();
factory.setCurrentLayout(PrintSlipFactory.ANALYTIC);
PrintSlip printSlip = factory.getPrintSlipWithCurrentLayout();

final MockedEmployee employee1 = new MockedEmployee("Francesco", nov1);

printSlip.setOutputStreamer(
new OutputStreamer() {
public void print(Object object) {
try {
File outputFile = new File("./" + employee1.name());
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(((String) object).getBytes());
outputStream.flush();
outputStream.close();
}
catch (Exception e) {
fail(e.toString());
}
}
}
);

employee1.setPrintSlip(printSlip);
employee1.printSlip();

File file = new File("./" + employee1.name());
assertTrue(file.exists());
file.delete();

}




Infine arricchisco la classe department (che contiene una collezione di cui esegue la printSlip rispetto a tute le risorse in forza), in modo che questa stessa classe essa stessa possa gestire i layout e l'OutputStreamer:





public class Department {

private PrintSlipFactory printSlipFactory = new PrintSlipFactory();

public void setPrintSlipLayout(String layout) {
printSlipFactory.setCurrentLayout(layout);
}

public void setPrintSlipOutputStreamer(OutputStreamer outputStreamer) {
printSlipFactory.setCurrentOutputStreamer(outputStreamer);
}

public Department(List resources){
_resources = resources;
}

public void printSlips() {
new OrderedCollection(_resources).select(new InForce()).forEachDo(printSlipFactory.getPrintSlipWithCurrentLayout());
}

private List _resources;
}




Mancano la parte R5 ed R6 della prova03, ed infine la prova4.

Al prossimo post, magari.

Bye.

Informazioni personali

La mia foto
I have been coding from the old C64 times. Studied Computer Sciences at Milan University. I also worked there in technical operations. Many years of experiences in coding Java and C#, desktop and web applications, with practices like unit testing. I used to play with 3d graphics in architecture recently with Blender 3d. Now I look for support related to some projects I am working on, oriented in automation in tourism related services, using functional programming framework, specifically F# and Suave.IO. email
tonyx1 (at) gmail.com github https://github.com/tonyx