dimanche 30 mars 2008

Jeu de Nim en Fortran

Vous connaissez peut-être le jeu de Nim sous le nom de "jeu des allumettes"... Version Frotran 90 "sale" ("Goto statement considered harmfull", non respect des normes actuelles...) en mode console. Au passage, je teste l'outil de conversion html de (g)Vim (f*ck it ça passe pas...)... Got a problem homie ? Just tell me (give my money and buy my medecine...). Version collée chez Pastie pour plus de lisibilité (lignes trop longues, etc...) : goto ICI.

Ze code :
(compilé avec GFortran (fortran 90) sous Windows)


Program Jeu_de_Nim
IMPLICIT NONE

integer :: nbre_allum, ordre, choix, scorePC, scoreHumain, nb_parties, i, aleas
logical :: PC_first, tournoi


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! BIENVENUE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

print*, "!!!!!!!!!!!!!!!"
print*, "JEU DE NIM v2.0"
print*, "!!!!!!!!!!!!!!!"
print*, "Bienvenue dans ce petit jeu de Nim."

print*, "A chaque tour, le joueur ou le PC doivent prendre 1, 2 ou 3 allumettes."
print*, "Celui qui prend la derniere allumette a perdu. Bonne chance."
print*, " "

scorePC = 0
scoreHumain = 0
tournoi = .FALSE.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! MENU

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
111 print*, "Entrez votre choix :"
print*, "[0] : Nouvelle Partie"
print*, "[1] : Nouveau Tournoi"
print*, "[2] : Afficher Scores"

print*, "[3] : Reinitialiser les Scores"
print*, "[4] : Quitter"
read*, choix

SELECT CASE (choix)
CASE (0)
GOTO 222
CASE (1)
tournoi = .TRUE.
scorePC = 0
scoreHumain = 0
11 print*, "Tournoi en combien de parties ?"

read*, nb_parties
if (nb_parties < 1) then
print*, "Tssss... Trop drole..."
GOTO 11
end if

aleas = 2*rand()

PC_first = .TRUE.
IF (aleas == 1) PC_first = .FALSE.
i = 0
10 i = i+1
print*, "PARTIE numero : ", i
call Afficher_scores(scorePC, scoreHumain)
IF (i > nb_parties) then
call Afficher_scores(scorePC, scoreHumain)
if (scorePC > scoreHumain) print*, "LE PC GAGNE LE TOURNOI !!!"

if (scorePC == scoreHumain) print*, "EGALITE !!! INCROYABLE !!!"
if (scorePC < scoreHumain) print*, "VOUS GAGNEZ LE TOURNOI !!! BRAVO !!!"
GOTO 111
END IF


nbre_allum = 50*rand() + 1
PC_first = .NOT.PC_first
GOTO 223

CASE (2)
call Afficher_scores(scorePC, scoreHumain)
GOTO 111

CASE (3)
scorePC = 0
scoreHumain = 0
GOTO 111

CASE (4)
GOTO 666

CASE DEFAULT

print*, "Mauvais choooooooooooix......"
GOTO 111

END SELECT

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! PARTIE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

222 print*, "Combien d'allumettes pour la partie ? (0 pour un nombre au hasard)"
read*, nbre_allum
if (nbre_allum == 0) nbre_allum = 50*rand()+1
if (nbre_allum < 0) then
print*, "Hummmmmm... Pas beaucoup ca..."
GOTO 222
end if
print*, "Qui joue en premier ?"

print*, "[1] : PC"
print*, "[2] : Humain"
print*, "[3] : Au hasard"
read*, ordre

SELECT CASE (ordre)
CASE (1)
PC_first = .TRUE.
print*, "Le PC commence."

CASE (2)
PC_first = .FALSE.
print*, "L'humain commence."
CASE (3)
aleas = 2*rand()
PC_first = .TRUE.
IF (aleas > 1) PC_first = .FALSE.
CASE DEFAULT

PC_first = .TRUE.
print*, "Apprends a taper cono !"
print*, "Du coup le PC commence..."
END SELECT

223 IF (PC_first) THEN

do while (nbre_allum > 0)
call Tour_de_jeu_PC(nbre_allum,scoreHumain)
IF (nbre_allum > 0) call Tour_de_jeu_Humain(nbre_allum,scorePC)
end do
ELSE
do while (nbre_allum > 0)
call Tour_de_jeu_Humain(nbre_allum,scorePC)
IF (nbre_allum > 0) call Tour_de_jeu_PC(nbre_allum,scoreHumain)
end do
END IF

IF (tournoi) GOTO 10

GOTO 111

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! EXIT
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
666 print*, "MERCI, A BIENTOT !"

End Program Jeu_de_Nim

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! AFFICHAGE DES SCORES
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Afficher_scores(scPC, scHuman)
integer, intent(in) :: scPC, scHuman

print*, "!!!!! SCORE !!!!!"

print*, "PC : ", scPC
print*, "Humain : ", scHuman

End Subroutine Afficher_scores

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! TOUR PC
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Tour_de_jeu_PC(nb_al, scHuman)
integer, intent(inout) :: nb_al, scHuman
integer :: reste, prise

print*, "Il y a ", nb_al, "allumettes."

reste = MOD(nb_al,4)

if (nb_al == 1) then
prise = 1
else
SELECT CASE (reste)
CASE (1)
prise = 3*rand()+1
CASE (2)
prise = 1
CASE (3)
prise = 2
CASE (0)
prise = 3
CASE DEFAULT

print*, "Erreur : module inconsistant"
print*, "Module = ", reste
STOP
END SELECT
end if

nb_al = nb_al - prise
print*, "Le PC prend ", prise, " allumettes."

print*, "Il reste : ", nb_al, "allumettes."

if (nb_al == 0) then
print*, "VOUS AVEZ GAGNE !!!!! FELICITATIONS !!!!"
scHuman = scHuman + 1
end if

End Subroutine Tour_de_jeu_PC


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! TOUR HUMAIN
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Tour_de_jeu_Humain(nb_al, scPC)
integer, intent(inout) :: nb_al, scPC
integer :: prise

print*, "Il y a ", nb_al, "allumettes."

print*, "Combien souhaitez vous en prendre ? (1, 2 ou 3)"
999 read*, prise

if ((prise > 3).OR.(prise < 1).OR.(prise > nb_al)) then
print*, "Nombre saisi incorrect : veuillez recommencer."
GOTO 999
end if

nb_al = nb_al - prise
print*, "Vous avez pris ", prise, " allumettes."

print*, "Il reste : ", nb_al, "allumettes."

if (nb_al == 0) then
print*, "VOUS AVEZ PERDU !!!!!"
scPC = scPC + 1
end if

End Subroutine Tour_de_jeu_Humain

mercredi 26 mars 2008

Google Summer Of Code

Cette année encore, Google organise le Summer of Code (abrégé en SoC) : il s'agit d'une opération permettant à des étudiants du monde entier de s'investir dans un grand projet libre le temps de l'été. Pour en savoir plus :

Plutôt que de plagier cette dernière news très bien faite, je vais juste apporter quelques remarques.

Beaucoup de projets impliqués ; Un grand absent ?

De mes petits yeux fatigués, j'ai compté 177 projets libres participant au programme. C'est énorme. Chacun profitant de l'engagement de plusieurs étudiants, à temps plein, pendant 2 mois complets, il faut se figurer le bénéfice que cela génère pour le monde du libre ! Sans compter les 4500 $ pour l'étudiant et 500 $ pour le projet en cas de succès...

On retrouve beaucoup de noms très connus du monde libre : Apache, The GIMP, Wikimedia, Linux, Mozilla... ( Mais aussi certains un peu moins célèbres qui m'ont fait plaisir comme Battle for Wesnoth).

Mais il en manque certains, dont un qui saute aux yeux : OpenOffice.org. Pourquoi ? Vraiment là, je donne ma langue au chat... (Mauvaises relations avec Google ?).
J'ai aussi noté l'absence totale de logiciel de P2P (Azureus et Bittorrent sont eux aussi libres). Là en revanche, ça peut s'expliquer plus simplement vu l'utilisation souvent approximativement légale de ce type d'application. Quoique. A ce compte là, on pourrait exclure tous les projets de langage de prog' : on peut potentiellement en faire mauvais usage...

Les langages ? (Ruby ?)

Question essentielle s'il en est... On en retrouve un nombre considérable : C, C++ et Java bien sûr. Mais pas seulement. La plupart des langages de script sont là : PHP, Perl, Python, Ruby, Javascript, Groovy, Scheme... Et aussi du fonctionnel pour les durs : LISP (CommonLISP et Scheme notamment) et Haskell au moins. Et puis des langages de grognards : Fortran et Ada notamment sur GCC.
Au passage, je trouve vraiment exceptionnel de pouvoir participer, en tant qu'étudiant, au développement d'un "grand" langage via ce programme : LISP, PHP, Perl... Geeky !

Et le Ruby ? On le retrouve sur différents projets, et pas forcément ceux auxquels on pouvait s'attendre...
Certes, il y a Ruby Central dont les propositions de sujet sont très axées sur Merb et sur la collaboration avec d'autres langages (Python et Java notamment) ou d'autres interpréteurs (JRuby et Rubinius).
On retrouve ensuite Ruby dans les projets Codehaus (JRuby) et... NESCent : le "National Evolutionary Synthesis Center" sur le projet Bio* (Bio_ : Perl, Python, Ruby, SQL, Java...) dans le domaine de la bio-informatique. Ruby en science ?

Triple-win ? (Winwinwin...)

Vous l'aurez compris, je suis très favorable à ce type d'opération qui semble profitable aux trois protagonistes :
  • Pour les étudiants : de l'expérience (très valorisable) et potentiellement une rétribution non négligeable.
  • Pour les projets : 2 mois de travail par étudiant (+ 500 $ ?), un peu de pub, et potentiellement un nouveau contributeur régulier avec de l'expérience.
  • Pour Google : de la pub ciblant plus particulièrement le monde du libre. Mais aussi une grosse manœuvre RH de pré-recrutements éventuels.
Pourquoi je pose cette question ?

Parce qu'il est toujours bon de savoir pourquoi l'on reçoit de l'aide ou de l'argent. J'apprécie Google pour différentes raisons et différents produits. Mais si les pratiques de cette entreprise me paraissent bien plus correctes que d'autres (là je pense très fort à la petite boîte de Bill le portail, mais aussi au principal concurrent de Google pour la recherche en ligne, et malheureusement parfois à l'autre pomme...), elle n'en reste pas moins une entreprise comme une autre (peut être plus riche, certes...).
S'il serait dommage de tomber dans la paranoïa libriste extrémiste malheureusement trop courante, il faut néanmoins que le monde du libre sache clairement garder son indépendance et ses valeurs, tout en s'ouvrant davantage sur le monde de l'entreprise. Cela semble être le cas ici.

En bref...

Si contrairement à votre serviteur vous êtes (encore) étudiant et vous avez un poil de talent (l'acharnement marche aussi parfois...) : allez (re-)jeter un coup d'œil sur la page du SoC 2008...


jeudi 20 mars 2008

Matrices en Ruby : 3 - Linalg !

Les matrices sont assez mal gérées de base en Ruby (cf articles précédents : [1] et [2]). Heureusement, il existe une bonne bibliothèque basée sur LAPACK (Linear Algebra PACKage, bien connue en Fortran) :

Comme indiqué dans sa doc, cette lib permet pas mal de choses : gestion simple et fiable des matrices, opérations classiques (déterminant, trace, valeurs propres...), décompositions diverses (LU, Cholesky...) et différentes autres méthodes.

L'installation est simple. Ensuite un simple require 'linalg' suivi de include Linalg, et c'est parti ! La doc contient un bon petit tuto (recopié dans le README) d'introduction pour faire tour avec irb.

Deux petits exemples d'utilisations :

Problème N-corps :

N corps interagissent gravitationnellement selon la loi de Newton. Dans cet exemple, j'utilise Linalg uniquement pour la structure de mes vecteurs position et vitesse. Code crade et valeurs mal choisies...


Convection-diffusion :

Ici, il s'agit de la résolution 1D par la méthode des différences finies de l'équation d'advection-diffusion d'un scalaire passif (exemples : polluant en rivière, transfert de chaleur...). La méthode mathématique a été écrite rapidement... j'ai essayé de faire en finesse : la partie diffusive est centrée, et la partie advective décentrée. Mais du coup, j'ai pas pris le temps de faire de calculs de conditionnement et de condition CFL, ni de faire un schéma en temps moins brutal que du pur explicite... Je me suis cependant autorisé la possibilité de faire varier le champs de vitesse au cours du temps (utile par exemple pour coupler avec un modèle de calcul de champs de vitesses : Saint Venant pour de l'hydraulique ?). Par contre, ici aussi, les valeurs proposées sont assez mauvaises (pas de diffusion notamment !) : n'hésitez pas à tester avec d'autres !


Toute question, remarque ou commentaire est le bienvenu !

mercredi 19 mars 2008

Quelle que soit la casse

Une petite fonction récursive pour générer toute les casses possibles d'un mot. A toutes fins utiles...



def evocate str
if str.size == 1 then
return [str.downcase, str.upcase]
else
a = []
evocate(str[1...str.size]).each do |tail|
a.push(str[0].chr.downcase + tail, \\
str[0].chr.upcase + tail)
end
return a
end
end

test = evocate("toto")
p test
#=>["toto", "Toto", "tOto", "TOto", "toTo", "ToTo",
# "tOTo", "TOTo", "totO", "TotO", "tOtO", "TOtO",
# "toTO", "ToTO", "tOTO", "TOTO"]

samedi 15 mars 2008

Benchmark sur collect

Juste pour tester la méthode collect, suite à un article sur Ruby's Cube...

Le code :
(testé sous Windows XP ; Ruby 1.8.6)



# Benchmark for using collect
#or naive method on enumerable.

users = ["toto", "titi", "tartempion"]

# Naive method
def meth1(users)
names = ""

for user in users
names << "#{user} "
end
return names.chomp
end

# Collect is flashy !
def meth2(users)
names = users.collect { |user| user}
return names.join(' ')
end

# Benchmark
require 'benchmark'

Benchmark.bm(15) do |timer|
timer.report('Barbarian method') {
for i in (0...1000)
meth1 users
end

}
timer.report("Ruby's finest...") {
for i in (0...1000)
meth2 users
end
}
end

#~ user system total real
#~ Barbarian method 0.016000 0.000000 0.016000 ( 0.016000)
#~ Ruby's finest... 0.000000 0.000000 0.000000 ( 0.000000)

jeudi 13 mars 2008

Un générateur de MIDI en Ruby

Giles Bowkett est un étonnant programmeur Californien qui a développé un générateur de MIDI, en Ruby : Archaeopterix. Pour rappel, le MIDI est une interface audio électronique. Manifestement, il utilise pour cela le logiciel Reason, bien connu dans ce domaine...


Des liens en vrac sur le sujet :


Voilà, c'est fait, j'ai parlé musique... Et au passage, c'est une application originale et relativement inattendue pour un langage de programmation, et le Ruby en particulier.

Relativement, car Ada Lovelace, scientifique du XIXème ayant donné son nom au langage Ada avait avancé, aux alentours de 1840, que, je cite : "La machine [- son anticipation de l'ordinateur, de fait -] pourrait composer de manière scientifique et élaborée des morceaux de musique de n'importe quels longueur ou degré de complexité.". Etonnant, non ? Qu'on ne vienne plus me parler de SF après ça... et pour ceux qui veulent un de vrai musique, c'est par là, chez un escroc notoire.

mardi 11 mars 2008

Débutons en Ada

En Ada 95 plus précisément... Deux docs et un livre :


Les deux premiers docs sont idéaux (et non pas "idéals"...) pour attaquer Ada en ayant déjà des connaissances en programmation, mais ne creusent pas nécessairement certains aspects très particuliers ou avancés du langage... Le livre de Barnes est en revanche très complet, et part du (tout) début : plutôt clair en général.
Une bonne base pour attaquer.

dimanche 9 mars 2008

Work World Whores


Big Billou soit loué ! Jason Calcanis, fondateur de Mahalo (un moteur de recherche moyen mais pas trop...), vient de publier sur son blog une liste d'astuces pour économiser de l'argent pour une start-up (trouvé via techcrunch / techcrunch en français). Alors bon, c'est un peu en décalage par rapport aux sujets habituels de ce blog, mais je vais me permettre de commenter un peu ses "astuces". D'abord parce qu'elles ne sont pas toutes immondes. Ensuite parce qu'elles ne se limitent absolument pas au monde psychédélique des start-up.

How to save money running a start-up, by J. Calcanis.

Passons en revue ces 18 points :

  1. Achetez des Macs. Tu es sur la bonne voix pitchoune : une licence MacOS X.5 coûte effectivement moins cher qu'une Vista et est meilleure. Mais pourquoi s'arrêter en si bon chemin ? Même avec des macs, il me paraît illusoire de croire que l'on peu complètement s'affranchir des frais d'une équipe d'assistance ou réseau. A ce compte là, autant passer sur un OS libre, gratuit et efficace. Bien sûr, je pense à Linux. OpenSolaris aussi. Dans certains domaines, comme les sciences et/ou avec une dose importante de développement informatique, je ne comprends pas qu'on investisse dans autre chose...
  2. Achetez un second écran pour chaque employé. Oh god damn' yes ! Je prends. Win-win.
  3. "Pas de réunion" : faites vos réunions pendant les repas. Oui et non. Il faut aussi couper la journée. Tojo ! Pourquoi pas des entretiens aux toilettes ?
  4. Achetez des tables "cheap" et de très bonnes chaises. Tout à fait d'accord, mais pas pour les mêmes raisons. Qui se soucie de bosser sur un bureau à 3000 quand il a le postérieur éclaté sur une chaise pourrave ? Idem : de bons écrans/claviers/souris sont plus importants qu'une unité centrale esthétique.
  5. Pas de système de téléphones : utilisez IRC ou autre. Pourquoi pas, mais : si les PC / le réseau plante(nt), comment tu préviens l'assistance ? A voir.
  6. Louez vos bureaux en trop. Bof bof...
  7. Outsource et RH... No comment.
  8. N'achetez que quelques licences Microsoft Office et utilisez Google Docs. Nan. Achetez UNE licence MS Office complète (avec PDF converter) et n'utilisez QUE Open Office. Bannissez le .doc. C'est mal.
  9. Ne payez pas pour un serveur d'échange, utilisez GMail. Oui, mais il manque quand même des fonctionnalités.
  10. Payez des PC à ceux qui bossent le plus pour qu'ils continuent à la maison. On te pendra avec tes tripes.
  11. Virez ceux qui ne sont pas des workaholics ("fous de travail"). Augmente tes salaires tojo ! (On te pendra quand même, et en plus on va te châtier. Grave.)
  12. Achetez de la bouffe et une très bonne machine à café pour garder les employés au bureau. C'est vicelard, mais il faut reconnaître que c'est pas forcément désagréable. D'autant que payer à la machine à café, au taf (payer - au taf), c'est très désagréable. Win-win.
  13. Pareil avec des sodas. Idem donc.
  14. Autoriser les gens à faire les horaires qu'ils souhaitent (arrivée et départ, hein !). Oui : win-win. Non, quand celui qui se pointe à 11H fait rester celui qui est là depuis 8H le soir à 20H pour une release naze.
  15. Négocier des prix de gros. Incroyable ! Innovant ! Personne n'y avait pensé !!!
  16. Ne perdez pas d'argent avec des recruteurs, utilisez FaceBook. Hahahaha !!! Quel cou1llon ! Tu vas engager qui ? Celui qui a le plus de potes ? Celui qui lance le plus de moutons ? Ou celui qui a reçu comme "gift" un caleçon à cœur ? Cela dit, il existe des méthodes alternatives efficaces, comme la cooptation.
  17. Prendre un consultant plutôt qu'un contrat avec une PR firm. A voir... différences entre les USA et la France à ce niveau ?
  18. Outsource to Middle America. Comme nous en Inde ? Touss touss...

Bref, vous l'aurez compris : un employé prend en moyenne 15 minutes par jour pour déféquer : 15 min * 218 jours par an donnent environ 37 H, soit près d'une semaine de travail perdu dans les toilettes.

EMPLOYES ! PRENEZ SUR VOUS ! NE CH1EZ PLUS !


lundi 3 mars 2008

On ne parle pas assez à son clavier...

Un bon clavier pour geek donc, qui m'a fait penser à un article de Why's the Lucky Stiff sur les vieux claviers bizarres... à voir, surtout pour les suppôts de VI !

Quelques uns marrants trouvés sur le web : médical (paraît-il...), "funky-lighted" et hébreux (?).

dimanche 2 mars 2008

Travail, travail...

Dans la vie, on fait pas toujours ce qu'on veut : Scheme va devoir un peu attendre... j'ai trouvé du taf :
Du coup, la fréquence de publication sur ce blog devrait baisser sensiblement dans les prochaines semaines. Je n'abandonne cependant pas ni ce blog, ni les petits langages que j'aime : en cas de disette, je posterai des vieux codes rigolos sortis des placards, en Fortran ou Ruby notamment. Je reste à l'affut sur le SDZ également.

Pour parler prog', j'avais cité Ada l'autre jour, et je l'attaque donc pour le boulot. Je ne suis pas persuadé de pouvoir "blogger" là-dessus tout de suite : il s'agit d'un langage assez particulier. OO dans sa version 95, mais avec de grosses séquelles de son origine procédurale. Il est souvent préféré au C dans le cadre d'applications critiques (pour systèmes embarqués notamment) pour sa rigueur imposée, sa meilleure (à priori) gestion des tableaux (et des problèmes d'indices), et sa capacité à ajouter des "règles" (contraintes) supplémentaires au compilateur : le tout dans un soucis permanent de fiabilité de l'exécutable. Exécutable plus volumineux qu'en C en revanche, mais (selon certaines sources) d'une vitesse (notion importante en temps réel) comparable au C++. Correct donc. Que dire d'autre, sinon qu'Ada possède un compilateur libre du projet GNU : GNAT (la référence, existant en version "pro" avec IDE et services associés) et que ce langage gère "nativement" la programmation concurrente ?

J'espère pouvoir vous en donner quelques exemples bientôt...