Reac2

 

David Cobac 15/01/2005 Reac2 est un petit logiciel qui teste le temps de réaction de manipulation de la souris ou de tout autre solution de pointage.

Il a été développé (fin 2003) pour un livre du CRDP de Lille [1] paru début janvier 2005. Il est composé d'une interface pour le prof qui conçoit un exercice et d'une interface élève. Le logiciel peut concatèner ensuite les résultats des élèves pour une exploitation statistique dans un tableur.

Voici le module professeur :

et le module élève :

Voici les code correspondants :

Pour le module prof :

 #!/bin/sh
 # the next line restarts using wish \
 exec wish8.4 "$0" "$@"

 # Reac2-prof.tcl

 # version du 29 octobre

 # Logiciel de test de raction  l'apparition d'un bouton, il produit
 # 10 rsultats enregistrs dans un fichier cumulable ; ces rsultats sont
 # alors exportables vers un chemin donn dans la seule ligne du fichier
 # Reac_cheminServeur.ini
 #
 # Licence GNU/GPL

 # auteur : david cobac
 # septembre/octobre 2003

 # test sous linux mdk 9.1
 # avec :
 #     - Tcl/Tk version 8.4 et ActiveTcl version 8.4.3.0

 namespace eval reac {
     global tcl_platform

     variable dimXCanvas 400
     variable FormeEcran 0
     variable quad 0
     variable quadNb 30
     variable nbExp 10
     variable AvecD
     variable nbSeries 5
     variable nomSauveLocal Reac2_resultats.csv
     variable nomSauveServeur Reac2_resultats_$tcl_platform(user).csv
     variable nomSauveGroupe Reac2_Resultats_Groupe.csv
     variable nomIni Reac2_cheminServeur.ini
     variable nomIniExercice Reac2_reglages_prof.ini
     variable nomCheminSauvegarde
     variable cheminServeur
 }

 proc reac::gui { } {
     font create bouton -family helvetica -size 10 -weight bold
     font create moi -family times -size 14 -weight bold

     # la frame des choix de chemins
     set f .f3
     labelframe $f -labelanchor nw -text "Les rpertoires"
     label $f.l -text "Chemin vers serveur\nReac2_nomServeur.ini (pour lves)"
     entry $f.e -width 40
     button $f.b -text "..." -command "reac::choixchemin $f.e"
     grid $f.l -row 1 -column 1
     grid $f.e -row 1 -column 2
     grid $f.b -row 1 -column 3

     label $f.l2 -text "Chemin vers sauvegarde"
     entry $f.e2 -width 40
     button $f.b2 -text "..." -command "reac::choixchemin $f.e2"
     grid $f.l2 -row 2 -column 1
     grid $f.e2 -row 2 -column 2
     grid $f.b2 -row 2 -column 3

     pack .f3 -fill x -pady 5 -padx 3

     # la partie des options
     pack [frame .f]
     frame .f.f
     label .f.f.l -text "Nb sries de 10 exp." -justify left
     spinbox .f.f.s -textvariable reac::nbSeries -relief groove -width 2\
 	-from 1 -to 10 -increment 1
     pack .f.f.l .f.f.s -side left

     frame .f.fx
     label .f.fx.l -text "Largeur de zone" -justify left
     set largeur {600 500 400 300 200 100}
     eval tk_optionMenu .f.fx.o reac::dimXCanvas $largeur
     pack .f.fx.l .f.fx.o -side left

     checkbutton .f.c3 -text "Format 4/3"\
 	-variable reac::FormeEcran -onvalue 1 -font bouton
     checkbutton .f.c4 -text "Distances"\
 	-variable reac::AvecD -onvalue 1 -font bouton
     set f .f.f1;frame $f
     checkbutton $f.c4 -text "Rseau"\
 	-variable reac::quad -onvalue 1 -font bouton
     entry $f.e -width 3
     $f.e insert end $reac::quadNb
     pack $f.c4 $f.e -side left
     pack .f.f .f.fx .f.c3 .f.c4 .f.f1 -side left -expand 1 -fill x -padx 3
     pack .f -fill x -pady 5

     # la partie des boutons  invoquer
     frame .f2
     button .f2.b0 -text "Quitter" -command exit -font bouton
     button .f2.b2 -text "Crer"\
 	-command "reac::CreerFichiers" -font bouton
     button .f2.b1bis -text "Rsultats" -command reac::verifRes\
 	-font bouton
     button .f2.b3 -text "Concatner" -font bouton \
 	-command "reac::concatene"
     button .f2.b4 -text Info -command reac::info -font bouton
     canvas .f2.moi  -relief groove -width 15 -height 18
     set logo {
 	2 1 D {-anchor nw}
 	4 2 C {-anchor nw  -font moi -fill red}
     }
     foreach {x y t opt} $logo {
 	eval .f2.moi create text $x $y -text $t $opt
     }
     bind .f2.moi <1> {tk_messageBox -message "un script Tcl/Tk par
 David Cobac (cobac@free.fr)\nMthodes en pratique - 2nde"\
  -title "information Reac2" -type ok}
     pack .f2.b0  .f2.b2 .f2.b1bis .f2.b3 .f2.b4\
         -side left -expand 1 -fill x -padx 3
     pack .f2.moi  -side left -expand 1
     pack .f2 -fill x

     # le titre de l'appli
     set titre "Reac2-prof : Module pour le professeur "

     wm title . $titre
     wm resizable . false false
     bind . <Control-q> "exit"
     bind . <Control-c> "exit"
     bind . <Control-h> "reac::info"
 }

 proc reac::choixchemin { entree } {
     set choix [tk_chooseDirectory]
     $entree delete 0 end
     $entree insert end $choix
 }

 proc reac::concatene { } {
     set path [pwd]
     if [catch {cd $reac::nomCheminSauvegarde}] {
 	tk_messageBox -message "Impossible de joindre le chemin\
 vers le serveur.\nConcatnation impossible." -title "Attention !"\
 	-icon warning
 	return
     }
     if [catch {set id [open $reac::nomSauveGroupe w]}] {
 	tk_messageBox -message "Cration du fichier de groupe impossible.
 Vrifier vos droits d'criture sur ${reac::nomCheminSauvegarde}." -title "Attention !"\
 	-icon warning
 	cd $path
 	return
     }
     set liste [glob Reac2_resultats_*]
     foreach f $liste {
 	if [catch {set id_f [open $f r]}] {
 	    tk_messageBox -message "Ouverture du fichier $f impossible.
 Vrifier vos droits de lecture sur ce fichier." -title "Attention !"\
 	-icon warning
 	continue
 	}
 	set contenu [read $id_f]
 	close $id_f
 	puts -nonewline $id $contenu
     }
     close $id
     cd $path
 }

 proc reac::verifRes { } {
     set path [pwd]
     if [catch {cd $reac::nomCheminSauvegarde}] {
 	tk_messageBox -message "Impossible de joindre le chemin\
 de sauvegarde. Avez-vous cr l'exercice ?" -title "Attention !"\
 	-icon warning
 	return
     }
     set liste [glob Reac2_resultats_*]
     foreach e $liste {
 	regexp {Reac2_resultats_(.*).csv} $e fichier poste
 	catch {lappend listenom $poste}
     }
     set nb [llength $listenom]
     cd $path
     tk_messageBox -message "$nb rsultats sont arrivs : $listenom" -icon info\
 	-title "Arrive des rsultats dans $reac::nomCheminSauvegarde"
 }

 proc reac::CreerFichiers {} {
     set reac::cheminServeur [.f3.e get]
     set reac::nomCheminSauvegarde [.f3.e2 get]

     if {$reac::cheminServeur==""} {set reac::cheminServeur [pwd]}
     if {$reac::nomCheminSauvegarde==""} {set reac::nomCheminSauvegarde [pwd]}

     # cration du fichier pour les lves
     if [catch {set id [open $reac::nomIni w]}] {
 	tk_messageBox -message "Impossible d'crire sur $reac::nomIni ! \
 Vrifier vos droits d'criture sur le fichier ou l'existence du rpertoire"\
 	    -title "Attention !" -icon warning
 	return
     }
     puts $id $reac::cheminServeur
     close $id
     tk_messageBox -message "Le fichier $reac::nomIni a t cr dans le rpertoire de
 Reac2-prof.  vous de le distribuer aux lves." -title "Reac2 : Cration d'un fichier" -icon info

     # cration de l'exercice
     if $reac::quad {set reso oui} else {set reso non}
     if $reac::AvecD {set couple oui} else {set couple non}
     if $reac::FormeEcran {set qtiers oui} else {set qtiers non}
     if [catch {set id [open [file join $reac::cheminServeur $reac::nomIniExercice] w]}] {
 	tk_messageBox -message "Impossible d'crire sur \
 [file join $reac::cheminServeur $reac::nomIniExercice] !\
 Vrifier vos droits d'criture..." -title "Attention !" -icon warning
 	return
     }
     puts $id "cheminsauvegarde = $reac::nomCheminSauvegarde"
     puts $id "nombreseries = $reac::nbSeries"
     puts $id "voirquadrillage = $reso"
     puts $id "dimquadrillage = $reac::quadNb"
     puts $id "ajouterdistances = $couple"
     puts $id "format4/3 = $qtiers"
     puts $id "dimzone = $reac::dimXCanvas"
     close $id
    tk_messageBox -message "Le fichier $reac::nomIniExercice a t cr dans le rpertoire
 $reac::cheminServeur. Vous n'avez rien  faire de plus." -title "Reac2 : Cration d'un fichier"\
 -icon info
 }

 proc reac::info { } {
 set texte "\tReac2 est un logiciel dvelopp pour le livre Mthodes\
 en pratique du niveau seconde.
 \n\tIl a pour objectif de fournir des donnes chiffres\
 sur une exprience. L'utilisateur doit cliquer sur des\
 boutons ou sur les cases d'un rseau mesurant ainsi son\
 temps de raction  une apparition vnementielle.
 Ce test permet aussi de comparer pour un utilisateur\
 donn sa dextrit suivant le dispositif de pointage\
 utilis (souris, touchpad etc.).
 \n\tAppuyer sur le bouton << Nouvelle exprience >>\
 commence une srie de mesures sur votre temps de raction.
 \n\tLes diverses options permettent de mieux analyser\
 la stratgie (avec l'option trace de souris), de simuler\
 un cran d'ordinateur (traditionnellement au format 4/3)\
 ou encore d'utiliser un quadrillage permettant de mesurer\
 votre prcision de pointage."

     destroy .info
     toplevel .info
     wm resizable .info false false
     wm title .info "Reac2 Informations"
     set f .info.f;frame $f
     text $f.t -bg white -yscrollcommand "$f.s set" -wrap word\
        -width 60 -font bouton
     $f.t insert end $texte
     $f.t  configure -state disabled
     scrollbar $f.s -orient vertical -command "$f.t yview"
     pack $f.t -side left -expand 1 -fill x
     pack $f.s -side left -expand 1 -fill both
     pack $f

     set f .info.g;frame $f
     button $f.b -text "OK" -width 20 -command "destroy .info"
     pack $f.b -expand 1
     pack $f -pady 10
     grab  .info

 }

 reac::gui

et le module élève :

 #!/bin/sh
 # the next line restarts using wish \
 exec wish "$0" "$@"

 # Reac2.tcl

 # version du 21 octobre

 # Logiciel de test de raction  l'apparition d'un bouton, il produit
 # 10 rsultats enregistrs dans un fichier cumulable ; ces rsultats sont
 # alors exportables vers un chemin donn dans la seule ligne du fichier
 # Reac_cheminServeur.ini
 #
 # Licence GNU/GPL

 # auteur : david cobac
 # septembre/octobre 2003

 # test sous linux mdk 9.1
 # avec :
 #     - Tcl/Tk version 8.4 et ActiveTcl version 8.4.3.0

 namespace eval reac {
     global tcl_platform

     variable dimXCanvas 400
     variable FormeEcran 0
     variable quad 0
     variable quadNb 30
     variable nbExp 10
     variable nbSeries
     variable Dist
     variable D
     variable AvecD 0
     variable ajout
     variable souris
     variable TempsReaction
     variable stop
     variable t0
     variable R
     variable i
     variable nbseries 0
     variable nomSauveLocal Reac2_resultats.csv
     variable nomSauveServeur Reac2_resultats_$tcl_platform(user).csv
     variable nomIni Reac2_cheminServeur.ini
     variable nomIniExercice Reac2_reglages_prof.ini
     variable nomCheminSauvegarde
     variable cheminServeur
 }

 proc reac::gui { } {
     font create bouton -family helvetica -size 10 -weight bold
     font create moi -family times -size 14 -weight bold

     # le canvas & le bouton qu'on utilise
     set f .finit;frame $f -relief groove -bg black
     canvas $f.c -width $reac::dimXCanvas	-height $reac::dimXCanvas -bg grey50
     button $f.c.b -text Ici\ ! -command reac::callbackBouton -bg red -width 1
     pack $f.c -padx 2 -pady 2
     pack $f

     # la partie des rsultats
     frame .f0
     label .f0.l -relief groove -width 40
     label .f0.l1 -relief groove -text "Nb. sries : 0" -justify left
     bind .f0.l1 <1> "reac::afficheResPre %X %Y"
     menu .monmenu -tearoff 0
     pack  .f0.l1 .f0.l -side left -fill x -expand 1 -padx 3
     pack .f0 -fill x -pady 5

     # la frame du bouton de lancement
     frame .f3
     button .f3.b1 -text "Nouvelle exprience" -command reac::Experience\
 	-state disabled -font bouton -bg darkred -activebackground red
     pack .f3.b1 -fill x -padx 3
     pack .f3 -fill x -pady 5

     # la partie des options
     frame .f
     checkbutton .f.c -text "Cumuler"\
 	-variable reac::ajout -onvalue 1 -font bouton
     checkbutton .f.c2 -text "Trace souris"\
 	-variable reac::souris -onvalue 1 -font bouton
     #checkbutton .f.c3 -text "Format 4/3"\
 	-variable reac::FormeEcran -onvalue 1 -font bouton\
 	-command "reac::changeCanvas;reac::quadrillage2"
     #checkbutton .f.c4 -text "Distances"\
 	-variable reac::AvecD -onvalue 1 -font bouton
     #set f .f.f0;frame $f -width 0
     #set nb {1 2 3 4 5 6 7 8 9 10}
     #eval tk_optionMenu $f.o reac::nbExp $nb
     # pack $f.o
     #set f .f.f1;frame $f
     #checkbutton $f.c4 -text "Rseau"\
 	-variable reac::quad -onvalue 1 -font bouton\
 	-command reac::quadrillage2
     #entry $f.e -width 3
     #$f.e insert end $reac::quadNb
     #pack $f.c4 $f.e -side left
     pack .f.c .f.c2  -side left -expand 1 -fill x -padx 3
     pack .f -fill x -pady 5

     # la partie des boutons  invoquer
     frame .f2
     button .f2.b0 -text "Quitter" -command exit -font bouton
     button .f2.b1bis -text "Effacer" -command reac::Effacement\
 	-font bouton
     button .f2.b2 -text "Envoyer"\
 	-command "reac::transfert" -font bouton
     button .f2.b4 -text Info -command reac::info -font bouton
     canvas .f2.moi  -relief groove -width 15 -height 18
     set logo {
 	2 1 D {-anchor nw}
 	4 2 C {-anchor nw  -font moi -fill red}
     }
     foreach {x y t opt} $logo {
 	eval .f2.moi create text $x $y -text $t $opt
     }
     bind .f2.moi <1> {tk_messageBox -message "un script Tcl/Tk par
 David Cobac (cobac@free.fr)\nMthodes en pratique - 2nde"\
  -title "information Reac2" -type ok}
     pack .f2.b0 .f2.b1bis .f2.b2 .f2.b4\
         -side left -expand 1 -fill x -padx 3
     pack .f2.moi  -side left -expand 1
     pack .f2 -fill x

     # le titre de l'appli
     #set titre "Reac2 (Mthodes en pratique 2nde) "
     set titre "Chemin serveur : "

     if ![file exists $reac::nomIni] {
        tk_messageBox -message "Le fichier $reac::nomIni n'est pas\
 trouvable !\nVous ne pourrez pas exporter vos rsultats."\
  -title "Attention !"\
 	-icon warning
         set id_serveur 0
         .f2.b2 configure -state disabled
         append titre "pas d'envoi possible !"
     } else {
         set id_serveur [open $reac::nomIni r]
         gets $id_serveur reac::cheminServeur
         close $id_serveur
         append titre "$reac::cheminServeur"
     }

     wm title . $titre
     wm resizable . false false
     bind . <Control-q> "exit"
     bind . <Control-c> "exit"
     bind . <Control-h> "reac::info"
 }

 # procdure de callback appui bouton
 proc reac::callbackBouton {} {

     set reac::stop 1
     set elapsedMS [expr {[clock clicks -milliseconds] - $reac::t0}]
     set reac::TempsReaction [format "%.2f" [expr {double($elapsedMS)/1000}]]
     lappend reac::R $reac::TempsReaction
     lappend reac::D $reac::Dist
     .f0.l configure -text $reac::R -font bouton

     if $reac::souris {
 	set c [.finit.c coords bout]
 	set x [lindex $c 0]
 	set y [lindex $c 1]
 	set rayon 9
 	.finit.c create oval [expr {$x-$rayon}] [expr {$y-$rayon}]\
 	     [expr {$x+$rayon}] [expr {$y+$rayon}] -outline red\
 	    -tags numero -width 3
 	.finit.c create text $x $y -text $reac::i -tags numero \
 	    -fill red
 	.finit.c raise numero
     }
     if !$reac::quad {
 	.finit.c delete bout
     } else {
 	.finit.c itemconfigure cible -fill blue
 	.finit.c bind cible <1> ""
 	.finit.c addtag touche withtag cible
 	.finit.c dtag current cible
     }
 }

 # cration du bouton et appel de l'attente
 proc reac::cree { canevas } {
     if !$reac::quad {
 	set x [expr {[$canevas cget -width]-10}]
 	set y [expr {[$canevas cget -height]-10}]
 	set xalea [expr {rand()*$x+5}]
 	set yalea [expr {rand()*$y+5}]
 	.finit.c create window  $xalea $yalea  -window .finit.c.b -tags bout
 	.finit.c.b configure -text $reac::i
     } else {
 	set xalea [expr {int(rand()*$reac::quadNb)}]
 	set yalea [expr {int(rand()*$reac::quadNb)}]
 	.finit.c itemconfigure q${xalea}-${yalea} -fill red
 	.finit.c addtag cible withtag q${xalea}-${yalea}
 	.finit.c bind cible <1> reac::callbackBouton
     }
     set reac::t0 [clock clicks -milliseconds]
     set reac::stop 0
     set reac::Dist [reac::distance $xalea $yalea]
     reac::temps
 }

 # gnre une attente alatoire de dpart
 proc reac::init { max {premier encours} } {
     set att 0
     set alea [expr {int(rand()*$max)}]
     if {$premier=="debut"} {
 	after $alea "set att 1"
     } else {
 	after $alea "set att 1;reac::cree .finit.c"
     }
     vwait att
 }

 # attente
 proc reac::temps { } {
     if {$reac::stop} {return}
     after 50 reac::temps
 }

 proc reac::transfert { } {
     set nom [file join $reac::nomCheminSauvegarde $reac::nomSauveServeur]
     if [catch {file copy -force $reac::nomSauveLocal $nom}] {
 	tk_messageBox -message "Transfert impossible vers le chemin\
 spcifi dans $reac::nomIni\nVrifier le chemin inscrit dans ce fichier\
 et/ou vos droits d'criture sur ce chemin." -title "Attention !"\
 	-icon warning
     }
 }

 proc reac::moyenne {liste} {
     set s 0
     set nb [llength $liste]
     foreach e $liste {
 	set s [expr {$s+$e}]
     }
     return [expr {$s*1.0/$nb}]
 }

 proc reac::maximum {liste} {
     return [lindex [lsort -decreasing -real $liste] 0]
 }

 proc reac::minimum {liste} {
     return [lindex [lsort -increasing -real $liste] 0]
 }

 # x et y sont les coords de l'objet  atteindre
 proc reac::distance { x y } {
     set xsouris [winfo pointerx .];set ysouris [winfo pointery .]
     set xcanvas [winfo rootx .finit.c];set ycanvas [winfo rooty .finit.c]
     set xecran [expr {$x+$xcanvas}];set yecran [expr {$y+$ycanvas}]
     set deltax [expr {$xecran-$xsouris}]
     set deltay [expr {$yecran-$ysouris}]
     return [expr {round(sqrt(pow($deltax,2)+pow($deltay,2)))}]
 }

 proc reac::Experience { } {

     if $reac::quad {set reac::souris 0}

     .f.c  configure -state disabled
     .f.c2  configure -state disabled
     #.f.c3 configure -state disabled
     #.f.c4 configure -state disabled
     .f3.b1 configure -state disabled
     .f2.b1bis configure -state disabled
     .f2.b2 configure -state disabled
     #.f.f1.c4 configure -state disabled

     .finit.c delete pret trace stats numero touche

     .f3.b1 configure -text "Exprience en cours"

     # on remet  zro si ncessaire
     if !$reac::ajout {
 	set reac::nbseries 0
 	.f0.l1 configure  -text "Nb. sries : 0"
     }

     # on attend que l'utilisateur soit prt
     set reac::stop 1
     .finit.c create text [expr {[.finit.c cget -width]/2}] [expr {[.finit.c cget -height]/2}] \
 	-text "Cliquez ici si\nvous tes prts !" -tags pret \
 	-font "Helvetica 12 bold" -justify center
     .finit.c bind pret <1> ".finit.c delete pret;set reac::stop 0"
     vwait reac::stop

     # on initialise
     set reac::TempsReaction 0
     set reac::R ""
     set reac::D ""
     set reac::i 0

     # trace de la souris
     if $reac::souris {
 	bind .finit.c <Motion> ".finit.c create rectangle %x %y %x %y -tags trace"
     }

     .f.c2  configure -state disabled

     ######################################################
     reac::init 3000 debut
     for {set reac::i 1} {$reac::i<=$reac::nbExp} {incr reac::i} {
 	reac::init 2000
 	vwait reac::stop
     }
     ######################################################

     set R [regsub -all {\.} $reac::R ,]
     if !$reac::AvecD {
 	set res_anoter [string map {\  \\n} $R]
     } else {
 	set a ""
 	for {set i 0} {$i<$reac::nbExp} {incr i} {
 	    append res_anoter "[lindex $reac::D $i];[lindex $R $i]"
 	    if {$i!=$reac::nbExp-1} {append res_anoter \n}
 	}
     }

     # fichier  enregistrer
     if $reac::ajout {
 	set mode a
     } else {
 	set mode w
     }
     if [catch {set id_file [open $reac::nomSauveLocal $mode]}] {
 	tk_messageBox -icon error -title "criture impossible"\
 	    -message "Impossible d'ouvrir le fichier $reac::nomSauveLocal
 Vrifier vos droits sur le rpertoire."
 	exit
     }

     eval puts $id_file \"$res_anoter\"
     close $id_file

     # dsactivation trace souris
     if $reac::souris {
 	bind .finit.c <Motion> ""
     }

     if !$reac::nbseries {
 	incr reac::nbseries
     }

     if $reac::ajout {
 	incr reac::nbseries
     }
     .f0.l1 configure -text "Nb. Sries : $reac::nbseries"

     # affichage des rsultats
     .finit.c create text  [expr {[.finit.c cget -width]/2}] [expr {[.finit.c cget -height]/2}] \
 	-text "Moyenne de vos temps : [reac::moyenne $reac::R] seconde(s)
 Maximum de vos temps : [reac::maximum $reac::R] seconde(s)
 Minimum de vos temps : [reac::minimum $reac::R] seconde(s)"  -tags stats\
 	-font "Helvetica 14 bold" -justify left -fill white

     if {$reac::nbseries>=$reac::nbSeries} {
         reac::transfert
 	tk_messageBox -icon info -title "Exercice termin"\
 	    -message "Voil, les expriences sont finies, les rsultats\
 ont t envoys. L'application va se terminer."
     exit
     }

     .f.c  configure -state normal
     .f.c2  configure -state normal
     #.f.c3 configure -state normal
     #.f.c4 configure -state normal
     .f3.b1 configure -state normal
     .f2.b1bis configure -state normal
     .f2.b2 configure -state normal
     #.f.f1.c4 configure -state normal
     .f3.b1 configure -text "Nouvelle exprience"
 }

 proc reac::Effacement { } {
     file delete $reac::nomSauveLocal
     set reac::nbseries 0
     .f0.l1 configure -text "Nb. sries : 0"
 }

 proc reac::afficheResPre { x y } {
     if [catch {set id_file [open $reac::nomSauveLocal r]}] {
 	return
     }
     .monmenu delete 0 end
     # soit valeur soit distance valeur
     set type [regexp {;} [gets $id_file]]
     seek $id_file 0 start
     set contenu [split [read $id_file] \n]
     if {$type==1} {
 	set c $contenu
 	set contenu ""
 	foreach e $c {
 	    regexp {[0-9]+;(.*)} $e ligne t
 	    lappend contenu $t
 	}
     }

     for {set i 1} {$i<=$reac::nbseries} {incr i} {
 	set entree($i) [lrange $contenu 0 [expr {$reac::nbExp - 1}]]
 	set contenu [lrange $contenu $reac::nbExp end]
 	.monmenu add command -label $entree($i)
     }

     close $id_file

     tk_popup .monmenu $x $y
 }

 # proc reac::lectureFichier {  } {
 #     if [catch {set id_file [open $reac::nomSauveLocal r]}] {
 # 	set reac::nbseries 0
 # 	return
 #     }
 #     set contenu [read $id_file]
 #     close $id_file
 #     set nbEntrees [regexp -all {,} $contenu]
 #     set reac::nbseries [expr {$nbEntrees/$reac::nbExp}]
 #     .f0.l1 configure  -text "Nb. sries : $reac::nbseries"
 # }

 proc reac::lectureFichier { } {
     file delete  $reac::nomSauveLocal
 }

 proc reac::lectureFichiersIni { } {
     if [catch {set id_reglage [open $reac::cheminServeur/$reac::nomIniExercice r]}] {
 	 tk_messageBox -message "Le fichier $reac::nomIniExercice ne peut\
 tre lu !\nVous ne pouvez pas faire l'exercice :-("\
  -title "Attention !"\
 	-icon warning
 	return
     }

     while {[eof $id_reglage]==0} {
 	gets $id_reglage ligne
 	regexp {(.*) = (.*)} $ligne corGlobale cle valeur
 	if {$valeur=="" || $valeur=="non"} {set valeur 0}
 	if {$valeur=="oui"} {set valeur 1}
 	regsub {\ } $valeur {\\ } valeur
 	set tab($cle) $valeur
     }
     close $id_reglage
     set liste [list cheminsauvegarde reac::nomCheminSauvegarde \
 		   nombreseries reac::nbSeries \
 		   voirquadrillage reac::quad \
 		   dimquadrillage reac::quadNb \
 		   ajouterdistances reac::AvecD \
 		   format4/3 reac::FormeEcran \
 		   dimzone reac::dimXCanvas
 	      ]
     foreach {c v} $liste {
 	eval set $v $tab($c)
     }
 }

 proc reac::appliqueExercice {} {
     reac::changeCanvas
     if $reac::quad reac::quadrillage2
 }

 proc reac::changeCanvas { } {
     if $reac::FormeEcran {
 	# videmment tout ne tombe pas juste  donc on ne fait pas du
 	# tout du 4/3 mais on fait en sorte que le quadrillage conviendra
 	# parfaitement... c'est un choix !
 	set h [expr {round($reac::dimXCanvas/(1.33333*$reac::quadNb))\
 			 *$reac::quadNb}]
     } else {
 	set h $reac::dimXCanvas
     }
     .finit.c configure -width $reac::dimXCanvas\
     -height $h
 }

 proc reac::quadrillage2 { } {
     .finit.c delete quadrillage
     # if !$reac::quad {
 # 	.f.f1.e configure -state normal
 # 	.f.c2 configure -state normal
 # 	return
 #    }
     # on dsactive la trace de souris
     set reac::souris 0
     .f.c2 configure -state disabled

     #set choix [.f.f1.e get]
     set choix $reac::quadNb
     set l [.finit.c cget -width]
     set L [.finit.c cget -height]
     # on vrifie le choix du rseau
     if ![regexp {[0-9]+} $choix] {
 	return
     }
     if {$choix<=1 || $choix >= $l/3.0 || $choix >=$L/3.0} {
 	return
     }
     set reac::quadNb [expr {round($choix)}]
     #.f.f1.e delete 0 end
     #.f.f1.e insert end $reac::quadNb
     # on dfinit les rectangles
     set lpitch [expr {$l*1.0/$reac::quadNb}]
     set Lpitch [expr {$L*1.0/$reac::quadNb}]
     for {set i 0} {$i<$reac::quadNb} {incr i} {
 	for {set j 0} {$j<$reac::quadNb} {incr j} {
 	    .finit.c create rectangle [expr {$i*$lpitch}] [expr {$j*$Lpitch}]\
 		[expr {($i+1)*$lpitch}] [expr {($j+1)*$Lpitch}]\
 		-tags [list quadrillage q${i}-${j}] -fill grey50
 	}
     }
     .finit.c bind quadrillage <Enter> {
 	if ![regexp {touche|cible} [.finit.c gettags current]] {
 	    .finit.c itemconfigure current -fill darkred
 	}
     }
     .finit.c bind quadrillage <Leave> {
 	if {[.finit.c itemcget current -fill]=="darkred"} {
 	    .finit.c itemconfigure current -fill grey50
 	}
     }
     .finit.c lower quadrillage
     #.f.f1.e configure -state disabled
 }

 proc reac::presentation { w mot } {
     $w delete pres
     $w create text [expr {[$w cget -width]/2}] [expr {[$w cget -height]/2}]\
 	-text $mot -font "Helvetica 1 bold" -tags pres -justify center\
 	-fill darkred
         for {set i 1} {$i<=50} {incr i} {
 	    $w itemconfigure pres -font "Times $i bold"
 	    update
 	}
 }

 # proc reac::animation_boutons { w } {
 #     set x [expr {[$w cget -width]-10}]
 #     set y [expr {[$w cget -height]-10}]

 #     for {set i 1} {$i<=100} {incr i} {
 # 	set xalea [expr {rand()*$x+5}]
 # 	set yalea [expr {rand()*$y+5}]
 # 	catch {button .finit.c.b$i -width 5}
 # 	$w create window  $xalea $yalea  -window .finit.c.b$i -tags a_bout
 # 	.finit.c.b$i configure -text Reac2
 # 	update
 #     }
 #     .finit.c delete a_bout
 # }

 # proc reac::ecrire_ecran { w phrase position} {
 #     eval $w create text $position -tags phr -anchor nw\
 # 	-font \{Helvetica 12 bold\}
 #     set long [string length $phrase]
 #     for {set i 0} {$i<$long} {incr i} {
 # 	set partie [string range $phrase 0 $i]
 # 	$w itemconfigure phr -text $partie
 # 	update
 # 	set att 0
 # 	after 80 "set att 1"
 # 	vwait att
 #     }
 # }

 proc reac::info { } {
 set texte "\tReac2 est un logiciel dvelopp pour le livre Mthodes\
 en pratique du niveau seconde.
 \n\tIl a pour objectif de fournir des donnes chiffres\
 sur une exprience. L'utilisateur doit cliquer sur des\
 boutons ou sur les cases d'un rseau mesurant ainsi son\
 temps de raction  une apparition vnementielle.
 Ce test permet aussi de comparer pour un utilisateur\
 donn sa dextrit suivant le dispositif de pointage\
 utilis (souris, touchpad etc.).
 \n\tAppuyer sur le bouton << Nouvelle exprience >>\
 commence une srie de mesures sur votre temps de raction.
 \n\tLes diverses options permettent de mieux analyser\
 la stratgie (avec l'option trace de souris), de simuler\
 un cran d'ordinateur (traditionnellement au format 4/3)\
 ou encore d'utiliser un quadrillage permettant de mesurer\
 votre prcision de pointage."

     .f2.b4 configure -state disabled
     .f3.b1 configure -state disabled

     destroy .info
     toplevel .info
     wm resizable .info false false
     wm title .info "Reac2 Informations"
     set f .info.f;frame $f
     text $f.t -bg white -yscrollcommand "$f.s set" -wrap word\
        -width 60 -font bouton
     $f.t insert end $texte
     $f.t  configure -state disabled
     scrollbar $f.s -orient vertical -command "$f.t yview"
     pack $f.t -side left -expand 1 -fill x
     pack $f.s -side left -expand 1 -fill both
     pack $f

     set f .info.g;frame $f
     button $f.b -text "OK" -width 20 -command "destroy .info"
     pack $f.b -expand 1
     pack $f -pady 10
     grab  .info

     .f2.b4 configure -state normal
     .f3.b1 configure -state normal

 }

 reac::gui
 reac::lectureFichier
 reac::lectureFichiersIni
 reac::appliqueExercice
 reac::presentation .finit.c Mathmatiques
 reac::presentation .finit.c Mthodes\nen\npratique
 reac::presentation .finit.c Classe\nde\ \Seconde
 .finit.c delete pres
 .f3.b1 configure -state normal