martedì 12 giugno 2012

Il periodo più favorevole ai dirigenti Italiani?

Quanti di voi hanno la sventura di aver assistito (o subìto) una discussione tra un dirigente (D) e un suo sottoposto (S) che, più o meno, ricalca i ritmi indicati di seguito?

D : "Se tu mi avessi informato prima dei problemi con l'altra area, io sarei intervenuto in modo decisivo per risolverli"
S : "In verità l'ho fatto, ti ho inviato due email a riguardo diversi mesi fa"
D : "Sì, vero, ma se tu fossi stato più chiaro nell'email, io avrei capito la criticità e sarei intervenuto"
S : "Pensavo che, durante la riunione che hai indetto a seguito della seconda email, il problema fosse stato ben analizzato e compreso da tutti noi"
D : "Se fosse stato ben analizzato e compreso da tutti noi, come sostieni tu, io l'avrei gestito!"

...e così la colpa ricade sul sottoposto oppure, se il Dirigente ha un minimo di dignità, il problema viene ridefinito come "di comunicazione", attribuendolo quindi a una entità impersonale.

Dopo aver assistito a molte conversazioni simili, sono giunto alla conclusione che il periodo più favorevole ai dirigenti italiani è quello "ipotetico del terzo tipo o dell'immpossibilità"!

Cosa è un periodo ipotetico del terzo tipo? E perché è quello più favorevole ai dirigenti italiani?

Il periodo ipotetico (da Wikipedia) è una struttura sintattica composta da una proposizione subordinata condizionale (detta anche protasi) e dalla sua reggente (detta anche apodosi). La subordinata è introdotta dalla congiunzione se ed esprime la premessa, cioè la condizione da cui dipende quanto predicato nella reggente; la reggente indica la conseguenza che deriva o deriverebbe dal realizzarsi della condizione espressa dalla proposizione subordinata.

Il periodo ipotetico viene tradizionalmente distinto in tre tipi, a seconda del grado di probabilità dei fatti indicati nella condizionale. Si parla allora di periodo ipotetico
  1. di primo tipo o della realtà quando l'ipotesi è presentata come un fatto reale o sicuro; 
  2. di secondo tipo o della possibilità quando l'ipotesi è presentata come un fatto non sicuro ma probabile;
  3. di terzo tipo o della impossibilità quando l'ipotesi è presentata come un fatto impossibile;

In particolare nel periodo ipotetico di terzo tipo la protasi è al congiuntivo trapassato e l'apodosi è al condizionale passato.

L'uso del congiuntivo trapassato fa ben capire che l'azione indicata nella premessa non è più realizzabile. Ma proprio essendo oramai irrealizzabile, questo costrutto linguistico presenta un vantaggio per il dirigente non da poco: è difficile da confutare!

venerdì 8 giugno 2012

Usare JAXB con StAX+XPath per prestazioni e comodità d'uso (1)

Una delle tecnologie Oracle per l'elaborazione di documenti XML è Java Architecture for XML Binding (JAXB).

Questo framework permette di effettuare il collegamento tra Java e XML; in particolare JAXB fornisce la possibilità di serializzare oggetti Java in XML (marshalling) e di effettuare l'operazione inversa (unmarshalling).

Immagine dal sito Oracle
Il collegamento Java-XML può essere effettuato a partire dallo Schema Xml che rappresenta il modello di documento da elaborare. Il compilatore JAXB produce le classi Java da utilizzare nell'applicazione per effettuare il marshalling e l'unmarshalling dei documenti istanza.

Supponiamo di avere il seguente documento e il relativo Schema Xml.

<root xmlns="http://ict-tic.blogspot.com">
  <elements
   <mrSneerObj><!--other xml content--></mrSneerObj>
   <mrSneerObj><!--other xml content--></mrSneerObj>
   <mrSneerObj><!--other xml content--></mrSneerObj>
   <mrSneerObj><!--other xml content--></mrSneerObj>
   <mrSneerObj><!--other xml content--></mrSneerObj>
   <mrSneerObj><!--other xml content--></mrSneerObj>  
  </elements>  
</root>

L'approccio classico di JAXB prevede, dopo la generazione delle classi a partire dallo Schema, la creazione di un contesto JAXB relativo al package prodotto dal compilatore JAXB e del relativo Unmarshaller.

L'Unmarshaller può quindi essere usato per produrre gli oggetti Java che rappresentano il documento XML. L'invocazione del metodo unmarshal accetta diverse rappresentazioni del documento XML di input. Di seguito è mostrata l'invocazione usando un reader StAX come parametro.

JAXBContext jc = JAXBContext.newInstance("it.mrsneer");
final Unmarshaller u = jc.createUnmarshaller();
JAXBElement<Root> obj = (JAXBElement<Root>) u.unmarshal(streamReader, Root.class);

L'oggetto restituito corrisponde al tag <root> e può essere navigato tramite i metodi getter come un normale POJO. Ovviamente in memoria, nella JVM, ci sarà un albero di oggetti Java collegati tra loro in modo da rappresentare tutti i nodi del documento XML di partenza.

giovedì 7 giugno 2012

E' possibile sostituire i dirigenti con un algoritmo? (1)

Osservando attentamente, per anni, il lavoro di diversi dirigenti (nel settore ICT in Italia, ma credo si possa generalizzare ben oltre questo contesto) ho riscontrato un modo di lavorare abbastanza omogeneo tra le diverse persone. Quasi come se tutti i dirigenti che ho incontrato avessero seguito lo stesso corso di "management"! Forse, semplicemente, i comportamenti da me notati sono quelli che più facilmente permettono di ottenere un avanzamento nella carriera. Credo che il modo con cui le organizzazioni selezionano il personale da promuovere alla carriera direttiva sia una delle maggiori cause della loro inefficienza.

Già dopo poco tempo di osservazione si è insinuato in me il dubbio... E' possibile sostituire questo tipo di dirigenti con un algoritmo? 

Lasciando l'analisi degli effetti di questo approccio a un prossimo post, di seguito provo a riportare i lineamenti dell'algoritmo che vorrei provare. In futuro penso di creare un progetto open source per implementare l'algoritmo (si cercano collaboratori). Il software si potrebbe validare in azienda utilizzando qualche dirigente reale come oracolo.

Il dirigente è modellato come un agent: reagisce a richieste che gli vengono sottoposte dall'esterno.

Request è la richiesta che perviene al dirigente. Una richiesta è caratterizzata da un mittente (from), una domanda a cui rispondere (question) e una data di scadenza opzionale (due_date).
 L'elaborazione delle richieste avviene nel metodo onRequest dove si innesca un ciclo in cui ciascuna iterazione si compone di due fasi (round). Durante la prima fase sono raccolte le opinioni dai propri collaboratori; mentre durante la seconda il dirigente cerca di raggiungere un consenso.

Il ciclo termina quando viene raggiunto il consenso ovvero quando il tempo a disposizione si esaurisce.

In grassetto le funzioni che saranno analizzate in un prossimo articolo.


Request : {
  from : senderDomain
  question : string;
  due_date : date;
}

onRequest(initial_req :
Request) { 
  try { 
    due_date = due_date != null ? 
             initial_req.due_date : determine_due_date(initial_req);

    priority = prioritize_request(initial_req.from, due_date);
 
    first_iteration = true;
     
    repeat {
      // first round : ask for candidate solutions
      if (first_iteration) {
        interpreted_req1 = new Request();

        interpreted_question = randomized_summarization(initial_req);
        interpreted_req1.question = ask_for_candidate_solution();
        interpreted_req1.priority = priority;
        interpreted_req1.due_date = calculate_due_date(priority, due_date);
      } else {
        interpreted_req1 = new Request();
        interpreted_req1.question = ask_for_new_candidate_solutions(response, most_frequent_res1);
        interpreted_req1.priority = priority;
        interpreted_req1.due_date = calculate_due_date(priority, due_date);
      }
         
      responses1 = send_request_and_collect_responses(team, interpreted_req1);
      most_frequent_res1 = randomized_mode_scoring(responses1);
         
      // second round : ask to to vote for the most common solution
      interpreted_req2 = new Request();
      interpreted_req2.question = proposal_with_default_on_due_date(most_frequent_res1);
      interpreted_req2.priority = priority;
      interpreted_req2.due_date = calculate_due_date(priority, due_date);
         
      responses2 = send_request_and_collect_responses(team, interpreted_req2);
      most_frequent_res2 = randomized_mode_scoring(responses2);
         
      // loop until convergence
      has_converged = most_frequent_res2 == YES;
    } until (has_converged);
     
   solution = most_frequent_res1;
  } catch (timeout) {
    // no convergence in allowed time-frame
    solution = randomized_select(most_frequent_res1, responses1);
  }
 
  reply(initial_req.from, team, solution); 

}