3.2 Table de multiplication
3.3 Lecture d'un fichier QCM
|
tcl est un langage de commandes, disponible sous
Unix et sous
Dos, Windows, NT...
Il est interprété et utilise beaucoup de listes, chaines, tableaux.
Ses primitives sont dérivées de fonctions unix standard.
Couplé à tk, il permet d'écrire rapidement des interfaces utilisateurs
simples avec des boites, des fenêtres etc.
Couplé à tix, il fournit
des interfaces encore plus sophistiquées.
L'intérêt de tcl est d'être "petit", gratuit, multi-plateforme.
Il est assez facile à apprendre, sans trop de subtilité, un peu
long à écrire, assez pénible à débogger mais c'est une façon simple
de permettre à des programmes sans interface graphique
(dbase, dos,awk, perl...) de communiquer avec des fenêtres windows et X-window...
|
|
Une instruction se termine par une fin de ligne ou un point-virgule. Un commentaire
commence par un dièse (#). Il faut écrire un point-virgule avant un dièse
si on veut mettre un commentaire sur la même ligne qu'une instruction. Ainsi
set somDiv 1 # on a toujours 1 comme diviseur
est incorrect. Il faut mettre
set somDiv 1 ; # on a toujours 1 comme diviseur
Si une ligne est trop longue, on peut mettre un \
pour indiquer que l'instruction se termine.
Tout appel de fonction tcl requiert les délimiteurs [ et ].
Un bloc se délimite par { et }.
Utiliser des " déclenche une interprétation des variables.
|
|
L'affectation se fait par set mais d'autres commandes affectent aussi,
comme append (pour concaténer des chaines de caractères).
Un calcul doit utiliser l'instruction expr. La plupart des fonctions mathématiques
de base existent déjà et sont accessibles
via expr. On donne le nom de la variable après set.
Toute référence à une variable doit par contre être précédée de $.
Exemples d'affectation :
set somDiv 0
set maDate [ clock format [clock seconds] \
-format " Le %d/%m/%y vers %H:%M" ]
set debInt [ expr (exp(1.0)) ]
set a [incr a 3] ; # met 3 de plus dans a
set a [expr $a + 3] ; # met 3 de plus dans a
set msgTxt "bon" ; # met bon dans msgTxt
append msgTxt "jour" ; # met bonjour dans msgTxt
set txtMsg "$msgTxt !" ; # met bonjour ! dans txtMsf
On peut désaffecter par unset. C'est surtout utile pour les tableaux.
les tableaux utilisent des références parenthésées dont les indices ne sont
pas limités à des entiers.
Exemples :
set nbl(0) 12
set tmp($i) [expr 1 + $nb(0)]
set tab($i,$j) 0
set prenom "Pierre"
set valeur "Pierre"
set ref($prenom) $valeur
set num($valeur) $prenom
|
|
Une boucle "tant_que" se définit par while. On peut ainsi
écrire la boucle "pour" traditionnelle de 1 à n par
set i 1
while { $i <= $n } {
...
set i [incr i]
} ; # fin tant que sur i
La boucle "for" existe et elle a même un dérivé nommé foreach
pour le passage en revue de structure.
for { set i 1 } { $i <= $n } { set i [incr i] } {
...
} ; # fin pour
foreach nomBre { 1998 2000 2025 } {
...
maCommande $nomBre
}; # fin pour chaque
|
|
Un test se fait avec l'instruction if. Compte-tenu de
l'interprétation des variables, il faut parfois utiliser des
comparaisons de chaines pour garantir le résultat.
On peut utiliser else et elsif en option.
L'instruction switch gère les structures de cas
multiples. Elle admet les paramètres --,
-exact, -regexp, glob
pour tester des expressions "globales", "régulières"
(comme *.*, [a|A]mis? etc.).
|
|
On écrit avec puts et on lit avec gets. De nombreux formats
sont possibles (voir plus bas les exemples complets).
tcl a de nombreuses fonctions pour les listes, les chaines et les fichiers
Citons :
list lindex llength lrange lappend linsert
lreplace lsearch lsort concat join split
(string) compare first index last length match
range tolower toupper trim wordend wordstart
(file) readable isdirectory atime attributes copy delete
dirname executable exists extension isfile join
lstat mkdir mtime owned rename size
|
|
Un sous-programme se définit par proc. Il admet des
paramètres en nombre variable, avec des valeurs par défaut.
On met avec global définir des variables globales.
L'instruction catch permet de récupérer une
erreur éventuelle. Il y a de nombreuses variables prédéfinies
comme $tcl_platform(os).
|
# on demande le prénom, on le traduit en majuscules,
# et on affiche aussi la date et l'heure
puts " Bonjour (en tcl) ; votre prenom ? "
set pren [gets stdin]
set p " \"bel inconnu\" ! "
if { [string length $pren] > 0 } { set p [string toupper $pren] }
set h [ clock format [clock seconds] -format " Le %d/%m/%y a %H:%M" ]
puts " $h au revoir, $p."
Affichage de l'exécution sous Dos/Windows :
|
L:\GH\MMM\POURTCL>tcl bonjour.tkl
Bonjour (en tcl) ; votre prenom ?
gilles
Le 30/09/98 a 16:42 au revoir, GILLES.
|
Affichage de l'exécution sous Unix/Linux :
|
@vega~/Tmp|(~gH)> wish bonjour.tkl
Bonjour (en tcl) ; votre prenom ?
gilles
Le 30/09/98 a 16:43 au revoir, GILLES.
|
puts "\nCeci est un programme tcl $tcl_version sous : "
puts "$tcl_platform(os) $tcl_platform(osVersion)\n"
if { ($argc > 0)} { set n $argv } else {
puts " syntaxe : tcl table Nombre "
puts " exemple : tcl table 5 "
exit
} ; # fin de si
puts " table de Multiplication de n = $n (passé en paramètre) \n"
for { set i 1 } { $i <= 10 } { incr i } {
puts [ format " %7d fois %7d = %7d " $i $n [expr $i*$n] ]
} ; # fin de pour
Affichage de l'exécution sans paramètre sous Dos/Windows :
|
+++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Ceci est un programme tcl 8.0 sous : +
+ Windows NT 4.0 +
+ +
+ syntaxe : tcl table Nombre +
+ exemple : tcl table 5 +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++
|
Affichage de l'exécution avec le paramètre 1998 sous Dos/Windows :
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Ceci est un programme tcl 8.0 sous : +
+ Windows NT 4.0 +
+ +
+ table de Multiplication de n = 1998 (passe en parametre) +
+ +
+ 1 fois 1998 = 1998 +
+ 2 fois 1998 = 3996 +
+ 3 fois 1998 = 5994 +
+ 4 fois 1998 = 7992 +
+ 5 fois 1998 = 9990 +
+ 6 fois 1998 = 11988 +
+ 7 fois 1998 = 13986 +
+ 8 fois 1998 = 15984 +
+ 9 fois 1998 = 17982 +
+ 10 fois 1998 = 19980 +
+ +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
Affichage de l'exécution sans paramètre sous Unix/Linux :
|
++++++++++++++++++++++++++++++++++++++++++
+ +
+ Ceci est un programme tcl 7.6 sous : +
+ Linux 2.0.35 +
+ +
+ syntaxe : tcl table Nombre +
+ exemple : tcl table 5 +
+ +
++++++++++++++++++++++++++++++++++++++++++
|
Affichage de l'exécution avec le paramètre 1998 sous Unix/Linux :
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ Ceci est un programme tcl 7.6 sous : +
+ Linux 2.0.35 +
+ +
+ table de Multiplication de n = 4 (pass' en paramStre) +
+ +
+ 1 fois 4 = 4 +
+ 2 fois 4 = 8 +
+ 3 fois 4 = 12 +
+ 4 fois 4 = 16 +
+ 5 fois 4 = 20 +
+ 6 fois 4 = 24 +
+ 7 fois 4 = 28 +
+ 8 fois 4 = 32 +
+ 9 fois 4 = 36 +
+ 10 fois 4 = 40 +
+ +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
################################
# #
# programme litexo.tcl #
# #
################################
proc queueDe { LaL } {
set lR ""
set mc 0
foreach mot $LaL {
incr mc ; if { $mc > 1 } { append lR $mot " " }
} ; # fin de pour chaque
return $lR
} ; # fin de proc queueDe
proc litex { nic } {
# exemple de format du fichier
## #
## +------------------------------------------------------------+ #
## ! ! #
## ! # exo_01 : compréhension de la notion d'union d'ouverts ! #
## ! TROU ! #
## ! Question Complétez la phrase avec LE bon mot ! #
## ! Début Une intersection ! #
## ! Fin d'ouverts est un ouvert. ! #
## ! Réponse 0.5 finie ! #
## ! Commentaire c'est vrai, mais ce n'est pas suffisant. ! #
## ! Réponse 0 continue ! #
## ! Commentaire mais... cela n'a aucun sens ! ! #
## ! Réponse 1 quelconque ! #
## ! Commentaire très bien. ! #
## ! ! #
## +------------------------------------------------------------+ #
set nbrep 0
set nbcmt 0
set fic [ open $nic r]
set lexo { }
while { [eof $fic] ==0 } {
gets $fic ligne
# puts " LIGNE LUE $ligne "
set nbmots [expr [llength $ligne]]
if {$nbmots > 2} {
set prem [ lindex $ligne 0 ]
set deuz [ lindex $ligne 1 ]
set troz [ lindex $ligne 2 ]
# puts " avec $nbmots élément(s), le premier étant $prem"
if {$prem == "Question"} {
set texte [ queueDe $ligne] ; set lexo [ lappend lexo $texte] }
if {$prem == "Début"} {
set debut [ queueDe $ligne] ; set lexo [ lappend lexo $debut] }
if {$prem == "Fin"} {
set fin [ queueDe $ligne]
set lexo [ lappend lexo $fin] }
if {$prem == "Réponse"} {
incr nbrep
set larep $deuz
set lexo [ lappend lexo $larep]
set larep $troz
set lexo [ lappend lexo $larep]
} ; # fin de si
if {$prem == "Commentaire"} {
incr nbcmt
set lecmt [ queueDe $ligne]
set lexo [ lappend lexo $lecmt]
} ; # fin de si
} ; # fin de si
}; # fin de while
return $lexo
} ; # fin de proc litex