Thursday, April 4, 2013

Recettes de chiffrages de projet informatique

 Le chiffrage d'un projet en informatique se révèle souvent être une tâche ardue que ce soit dans la définition des besoins ou dans l'évaluation du temps de réalisation. Ceci a pour conséquence que le chiffrage se base souvent sur des paramètres assez subjectifs.

Dans cette idée, je me suis amusé à imaginer quelques techniques permettant de faire du chiffrage. Toutes ressemblances a des faits réels n'est que pure coïncidence ;).

Le compteligne

Cette technique prend en compte le nombre de ligne et la structure du document fournis par le client.

Etapes:
  1. Découper le projet à chiffrer en tâches très macros. Le découpage revient souvent à reprendre les paragraphes de l'expression de besoin du client c.a.d 1 tâche égale 1 paragraphe ou 1 chapitre.
  2. Prendre le nombre de ligne de chaque tâche et le multiplier par un autre coeff en fonction de ce que vous avez compris de la tâche à réaliser. Plus la tâche vous parait incompréhensible, plus le coeff doit augmenter.  
  3. Ainsi vous obtenez un certain nombre de jours/homme. 
  4. Adapter le chiffrage en fonction des remords suscités par ce dernier.


Exemple: Une expression de besoin faisant 3 chapitres

1er chapitre: 3 lignes
 Compréhension du chapitre: je n'ai rien compris => 3
2e chapitre: 5 lignes
Compréhension du chapitre: ca me paraît clair => 2
3e chapitre: 10 lignes
Compréhension du chapitre: J'ai tout compris =>1

Nombre de jour/homme = 3 x 3 + 5 x 2 + 10 x 1 = 29 jrs/homme
Nombre de jour/homme après remords = 24 jrs/homme

 Le comptemot (compteligne police proof)


Cette technique est une variante du compteligne mais a l'avantage de ne pas être sensible à la police. En effet le nombre de mot est pris en compte à la place du nombre de ligne.

Le mathétique


Cette technique est réservée aux psychopathes des mathématiques et aux fanas de préjugés.

Etapes:
  1. Découper méticuleusement chaque besoin afin d'en faire des tâches très micros de l'ordre d'1j/h.
  2. Avoir au préalable calculé la productivité de chacun de ses devs après une longue observation, en déduire des données en fonction de préjugés: Temps effectif devant le poste, temps passé à surfer sur le net, âge des développeurs, nombre de dev en couple, nombre de femmes etc. 
  3. Prendre le résultat de ces calculs et le corréler aux tâches à réaliser.
  4. Savourer le chiffrage obtenu avec un rire sadique.
Exemple:
Découpage du projet en 1101 micro-tâches d'1j/h. Dans l'équipe, il y a trois devs, deux hommes et 1 femme.
Un homme est marié, ce qui fait de lui un dev avec des obligations => 75 % de dev,
L'autre est célibataire à tendance nolife et à l'avantage d'être barbu => 120 % de dev,
La femme a un beau physique => 50% de dev car pour ce type de chifffreur, elle n'est qu'un demi développeur.

Résultat: 1101 * 125 / 100 * 80/100 * 150/100 = 1651.5 j/h
Résultat en prenant en compte les jours de maladies potentiels: 1651.5 * 110 % = 1816.65 j/h

Le coffreur


Cette technique est réservé aux chiffreurs codeurs et très simple à réaliser. A adapter selon le langage préféré du geek.

Etapes:
  1. Découpage des tâches aléatoire.
  2. En fonction de la compléxité ressentie, choisir un nombre de jour max.
  3. Coder un algo du genre  Math.random() * nombre de j/h max.
  4. Obtenez votre résultat.

Le lancé de dés


Cette technique est équivalente au coffreur mais à l'avantage d'être utilisable par n'importe qui sachant lancer des dés.

Etapes:
  1. Découpage des tâches aléatoire.
  2. En fonction de la compléxité ressentie, changer le nombre de dés.
  3. Lancer les dés.
  4. Obtenez votre résultat.

Le souk ou marchandage de tapis


Cette technique consiste à ne pas prendre en considération le besoin, mais uniquement à marchander avec le client.

Etapes:
  1. Tenter de connaître la fourchette attendue par le client
  2. Si la fourchette est connue, alors rendre un chiffre aléatoire contenu dans la fourchette.
  3. Si la fourchette n'est pas connue, alors présenter plusieurs chiffrages successivement au client en prenant soin de temporiser avant chaque présentation. Si le client dit "c'est trop cher" alors rendre un chiffrage inférieur . Si le client dit "vous avez surement oublié quelque chose" alors gonfler le chiffrage. Réitérer jusqu'à ce que le client dise "Ok".
  4. Le chiffrage est prêt.

Si vous avez d'autres idées, n'hésitez pas à m'en faire part.


Friday, June 15, 2012

Simply iterate over a map

I often saw iteration in a map that based on the entries, for example:

Map<String, String> map = new HashMap<String, String>();

for (Entry<String, String> entry : map.entrySet()) {
    if ("test".equals(entry.getValue())) {
       System.out.println(entry.getKey());
    }
}

This method is fast but it is verbose and the manipulation of the Entry object is not convenient.

It's easier and more readable to iterate over the keys and retrieve the value. Note that if you need to browse the big range of hashMap, this method is to avoid because the map.get will browse all the entries for each iteration, you'd better to use the first method :)
Example:

for(String key : map.keySet()){
    if ("test".equals(map.get(key))) {
       System.out.println(key);
    }
}

Thursday, June 14, 2012

Refactoring and code improvement examples

I will post a suite of refactoring examples in JAVA. I share you my experience about refactoring and quality improvements of real project.

Today I will start with a basic example.

Write an equals comparison with a constant (best practice)

It's usual in a project to compare a value to a constant for example:

myVar.equals(MY_CONSTANT)

What happen if myVar equals "null". So I have a  NullPointerException. In order to make your code NPE proof. You just have to inverse the test.

MY_CONSTANT.equals(myVar)

It ensures that the left part is never null.

Tuesday, February 7, 2012

camel create routes dynamically

Apache camel, create routes dynamically

Create camel routes dynamically

In this entry we'll create a camel route dynamically.
The route uses the camel-mail component that permits to connect to pop/imap/smtp mailboxs.

Dependencies

We use the version 2.9.0 of camel.

maven

  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-core</artifactId>
   <version>2.9.0</version>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-mail</artifactId>
   <version>2.9.0</version>
  </dependency>

ivy

 <dependency org="org.apache.camel" name="camel-core" rev="2.9.0"/>
 <dependency org="org.apache.camel" name="camel-mail" rev="2.9.0"/>

RouteBuilder

In order to create a new Route it is necessary to create a class that extends RouteBuilder.
After you have to implement the method configure() that permits to configure your route.

Example for an imap email route

 public class MailRouteBuilder extends RouteBuilder {
 
  private String login;
  private String password;
  private String host;

  public MailRouteBuilder(String login,String password,String host){
   this.login=login;
   this.password=password;
   this.host=host;
  }


  @Override
  public void configure() throws Exception {
   fromUri=String.format("imap://%s?username=%s&password=%s",host,login,password);
   from(fromUri).to("mock:myMock");
  }
 }


If you use a processor, don't forget to assign an id to the bean inside the camel spring context ex:

 from(fromUri).processRef("imapProcessor").to("mock:myMock");
 
 <bean id="imapProcessor" class="myPackage.MyProcessor" />

Ok, now we have a builder for the new route in a very easy way.
Now it is necessary to create a new spring bean that implements CamelContextAware.
If you use spring and annotation you can configure in a very easy way with the @Service annotation:

 @Service
 public class CamelRouteManager implements CamelContextAware { ...
  

If you don't use the annotation, so you have to edit the camel spring context:

 <bean id="camelRouteManager" class="myPackage.CamelRouteManager" />

The implementation of CamelContextAware need to implement the getter/setter for the camel context. It means you have to provide a camelContext field.

 protected CamelContext camelContext;

 public CamelContext getCamelContext() {
  return camelContext;
 }

 public void setCamelContext(CamelContext camelContext) {
  this.camelContext = camelContext;

 }

Now we can create a method named addMailRoute that creates a new imap route:

 public void addMailRoute(String login,String password,String host){
  MailRouteBuilder mailRouteBuilder=new MailRouteBuilder(login,password,host);
  this.camelContext.addRoutes(mailRouteBuilder); 
 }

If all is ok the route should start automatically.
Ok, but if I want to remove, stop or suspend a route, how can I do ?
Very easy, you have just to use:

camelContext.removeRoute(String routeId)
camelContext.stopRoute(String routeId)
camelContext.suspendRoute(String routeId)
Take care, for remove a route it is necessary to stop it before.

Ok, how can I retrieve the id of the route created dynamically ?

Just have to retrieve the routeDefinition object, go back in the MailRouteBuilder class:

 private RouteDefinition routeDefinition;

 
 @Override
 public void configure() throws Exception {
  fromUri=String.format("imap://%s?username=%s&password=%s",host,login,password);
  routeDefinition=from(fromUri).to("mock:myMock");
 }

 public RouteDefinition getRouteDefinition() {
  return routeDefinition;
 }

 

Now retrieve the routeDefinition object and extract the id in the CamelRouteManager class:

 public String addMailRoute(String login,String password,String host){
  MailRouteBuilder mailRouteBuilder=new MailRouteBuilder(login,password,host);
  this.camelContext.addRoutes(mailRouteBuilder);
  return mailRouteBuilder.getRouteDefinition().getId(); 
 }

It is also possible to create several routes in one shot. You can adapt the code to have a list of routeDefinition instead of a simple String

Now all is done, you can enjoy all your created routes.

In a future article, we'll see how we can persist these routes.

Reference

apache camel official site

Bayes algorithm with apache mahout