Aller au contenu

Initiation au Lua avec Scribunto/Structures de contrôle

Leçons de niveau 10
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Structures de contrôle
Icône de la faculté
Chapitre no 4
Leçon : Initiation au Lua avec Scribunto
Chap. préc. :Tables et fonctions
Chap. suiv. :Fonctions basiques

Exercices :

Sur les structures de contrôle
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Initiation au Lua avec Scribunto : Structures de contrôle
Initiation au Lua avec Scribunto/Structures de contrôle
 », n'a pu être restituée correctement ci-dessus.

Les structures de contrôle permettent :

  • soit de prendre une décision en fonction du contexte ;
  • soit de répéter une opération sur des objets différents ;
  • soit de répéter une opération tant que quelque chose est vrai ou jusqu'à ce que quelque chose soit réalisé.

Celles qui comportent une répétition sont appelées « boucles ».

La structure if..then..else

[modifier | modifier le wikicode]

Nous avons déjà étudié cette structure au premier chapitre car il est difficile de s'en passer puisqu'elle permet de prendre une décision en fonction d'une condition. Nous rappelons que, en français la structure if condition then instruction1 else instruction2 end signifie : Si une condition est remplie exécuter instruction1 sinon exécuter instruction2. Dans le Module:Balance, nous avons donné l'exemple suivant :

local p = {}

function p.alerte3(frame)
	local poids = tonumber(frame.args[1])
	local reponse
	if poids < 55 then
		reponse = "Votre poids est acceptable"
	else
		reponse = "Attention, vous commencez à grossir !"
	end
	return reponse
end

return p

Dans une autre page, si nous écrivons {{#invoke:Balance|alerte3|57}}, nous obtenons : Attention, vous commencez à grossir !

Nous rajouterons, dans ce chapitre, qu’il est possible aussi d'emboîter les structures if..then..else. Par exemple, toujours dans le Module:Balance, nous avons écrit une quatrième fonction p.alerte4 ainsi :

local p = {}

function p.alerte4(frame)
	local poids = tonumber(frame.args[1])
	local reponse
	if poids < 55 then
		reponse = "Votre poids est acceptable"
	else
		if poids < 60 then
			reponse = "Attention, vous commencez à grossir !"
		else
			reponse = "Grosse vache !!"
		end
	end
	return reponse
end

return p

Qui présente l'avantage de fournir à l'utilisatrice une information plus complète[1].

Si l’on souhaite emboîter un très grand nombre de structures if..then..else, on peut le faire plus simplement en utilisant l'instruction elseif. Voir la fonction exemple, ci-dessous, qui nous confirme le nombre, rentré en argument, si celui-ci est compris entre 1 et 5 ou répond « Je ne sais pas » dans les autres cas :

local p = {}

function p.exemple(frame)
	local n = tonumber(frame.args[1])
	if n == 1 then
		return "Le nombre est un"
	elseif n == 2 then
		return "Le nombre est deux"
	elseif n == 3 then
		return "Le nombre est trois"
	elseif n == 4 then
		return "Le nombre est quatre"
	elseif n == 5 then
		return "Le nombre est cinq"
	else
		return "Je ne sais pas"
	end
end

return p

La structure while..do

[modifier | modifier le wikicode]

La structure while..do permet de répéter un ensemble d'instructions tant qu'une condition est vraie. Sa syntaxe générale est : while condition do instructions end, ce qui signifie, en français : Tant que condition faire instructions fin.

Prenons un exemple : écrivons un programme qui va écrire le plus petit nombre, supérieur à un nombre donné, s'écrivant comme somme des premiers nombres entiers. Par exemple le plus petit nombre, supérieur à 13, vérifiant cette condition, est 15 car 1 + 2 + 3 + 4 = 10 et 1 + 2 + 3 + 4 + 5 = 15. Dans le Module:Calcul nous écrirons :

local p = {}

function p.somme1(frame)
	local limite = tonumber(frame.args[1])
	local reponse = 0
	local entier = 1
	while reponse < limite do
		reponse = reponse + entier
		entier = entier + 1
	end
	return reponse
end

return p

Dans une autre page, si nous écrivons {{#invoke:Calcul|somme1|13}}, nous obtenons : 15

Dans cet exemple, nous voyons que la variable limite a pris la valeur 13. Et tant que reponse avait une valeur inférieure à 13, reponse a été incrémentée de la valeur se trouvant dans entier. Comme entier valait 1 au départ et a été incrémentée de 1 dans chaque passage dans la boucle, nous voyons que reponse a pris la valeur 1 au premier passage dans la boucle, puis a pris la valeur 1 + 2 = 3 au deuxième passage, puis la valeur 1 + 2 + 3 = 6 au troisième passage, puis 1 + 2 + 3 + 4 = 10 au quatrième passage, puis 1 + 2 + 3 + 4 + 5 = 15 au cinquième passage. À ce moment-là, la condition reponse < limite est devenue fausse et par conséquent nous sommes sortis de la boucle avec reponse contenant la valeur 15.

La structure repeat..until

[modifier | modifier le wikicode]

La structure : repeat..until permet de répéter un ensemble d'instructions jusqu'à ce qu'une condition soit vraie. Sa syntaxe générale est : repeat instructions until condition, ce qui signifie, en français : Répéter instructions jusqu'à condition.

Si nous essayons de réaliser une fonction réalisant la même chose qu'au paragraphe précédent, nous obtiendrons :

local p = {}

function p.somme2(frame)
	local limite = tonumber(frame.args[1])
	local reponse = 0
	local entier = 1
	repeat
		reponse = reponse + entier
		entier = entier + 1
	until reponse > limite
	return reponse
end

return p

Dans une autre page, si nous écrivons {{#invoke:Calcul|somme2|13}}, nous obtenons : 15

Dans ce nouvel exemple, nous voyons que la variable limite a pris la valeur 13. reponse a été incrémentée de la valeur se trouvant dans entier qui, comme dans l'exemple précédent, est incrémentée de 1 à chaque passage dans la boucle, ces deux opérations se renouvelant jusqu'à ce que reponse prenne une valeur supérieure à 13. Nous voyons que reponse a pris la valeur 1 au premier passage dans la boucle, puis a pris la valeur 1 + 2 = 3 au deuxième passage, puis la valeur 1 + 2 + 3 = 6 au troisième passage, puis 1 + 2 + 3 + 4 = 10 au quatrième passage, puis 1 + 2 + 3 + 4 + 5 = 15 au cinquième passage. À ce moment-là, la condition reponse > limite est devenue vraie et, par conséquent, nous sommes sortis de la boucle avec reponse contenant la valeur 15.

Ce qui différencie ce deuxième exemple du premier, c’est que l'exécution de la boucle aura lieu au moins une fois et reponse prendra donc au minimum la valeur 1. Si nous tapons {{#invoke:Calcul|somme2|0}}, nous obtiendrons 1 alors que dans l'exemple précédent {{#invoke:Calcul|somme1|0}} aurait donné 0.

Nous pouvons dire que, dans ce cas, l'exemple précédent est meilleur puisque donnant une réponse juste pour la valeur 0.

En général, tout ce qui est réalisable avec la structure while..do est aussi réalisable avec la structure repeat..until. La principale différence réside dans le fait que, dans la structure while..do, la condition est testée avant chaque exécution des instructions et dans la structure repeat..until, la condition est testé après chaque exécution des instructions. Ce qui, selon ce que l’on veut faire, va déterminer le choix entre les deux structures.

La structure for..do

[modifier | modifier le wikicode]

Nous avons vu, dans les deux paragraphes précédents, des structures où le nombre de passage dans la boucle n’est pas connu d'avance et dépend d'une condition qui doit rester vraie ou qui doit devenir vraie. Si l’on veut répéter une opération un certain nombre de fois bien précis connu avant l'entrée dans la boucle, on utilisera la structure for..do. La seule petite différence entre chaque exécution sera déterminée par une variable d'index qui pour chaque exécution prendra une valeur différente et qui pourra être éventuellement utilisée dans le corps de la boucle.

Dans le Lua, il existe deux formes de la boucle for.

Première forme de la boucle for

[modifier | modifier le wikicode]

La première forme de la boucle for se rédige sous la forme :

for index = m, n, p do
	instructions
end

m, n, p étant trois entiers. p est facultatif. Pour chaque passage dans la boucle, la variable index prendra toutes les valeurs de m à n en étant incrémentée, chaque fois, de la valeur de p.

Prenons des exemples.

Écrivons, toujours dans notre Module:Calcul, une fonction echo qui répétera un mot un certain nombre de fois, lui aussi entré en paramètre. Nous écrirons :

local p = {}

function p.echo(frame)
	local nom = frame.args[1]
	local occurence = tonumber(frame.args[2])
	local reponse = " "
	for i = 1, occurence do
		reponse = reponse.." "..nom
	end
	return reponse
end

return p

Dans une autre page, si nous écrivons {{#invoke:Calcul|echo|plouf|5}}, nous obtenons : plouf plouf plouf plouf plouf

Voyons, plus en détail, comment fonctionne cette boucle. Dans notre exemple, occurence prend la valeur 5. Par conséquent, notre boucle devient :

	for i = 1, 5 do
		reponse = reponse.." "..nom
	end

i = 1, 5 signifie que i doit prendre toutes les valeurs de 1 à 5 et la boucle s'exécutera pour chacune de ces valeurs. Nous aurons donc obligatoirement 5 passages dans la boucle. En français, on pourrait traduire cette exécution par : Pour i prenant toutes les valeurs de 1 à 5 faire instructions.

On peut faire plus sophistiqué en mettant un troisième nombre qui représentera de combien i doit être augmenté à chaque passage dans la boucle. Par exemple : i = 2, 11, 3 signifie que i, en démarrant de 2 devra aller jusqu'à 11 en étant augmenté de 3 à chaque passage dans la boucle. Par conséquent, nous aurons 4 passages dans la boucle avec i ayant, à chaque passage, respectivement les valeurs 2, 5, 8, 11.

Il est possible aussi de faire en sorte que i soit décrémenté à chaque passage dans la boucle. Par exemple, si l’on écrit : i = 17, 9, -2. Cela signifie que i va aller de 17 à 9 en étant décrémenté de 2 à chaque passage dans la boucle. i va donc prendre à chaque passage dans la boucle respectivement les valeurs 17, 15, 13, 11 et 9 et l’on aura donc 5 passages dans la boucle.

La boucle for..do est très pratique pour manipuler des tables. Nous allons faire un programme qui fait automatiquement pour tous les jours de la semaine ce que le programme du premier chapitre faisait pour un seul jour. Dans le Module:Traduit, nous rajoutons la fonction baratin2 ainsi rédigée :

local p = {}
local semaine = {"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
local week = {"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}

function p.baratin2(frame)
	local reponse = "<u>Traduction des jours de la semaine</u> <br />"
	for index = 1, 7 do
		reponse = reponse.."La traduction de "..semaine[index]..", en anglais, est "..week[index].."<br />"
	end
	return reponse
end

return p

En écrivant : {{#invoke:Traduit|baratin2}}, nous obtenons :

Traduction des jours de la semaine
La traduction de lundi, en anglais, est monday
La traduction de mardi, en anglais, est tuesday
La traduction de mercredi, en anglais, est wednesday
La traduction de jeudi, en anglais, est thursday
La traduction de vendredi, en anglais, est friday
La traduction de samedi, en anglais, est saturday
La traduction de dimanche, en anglais, est sunday

Nous remarquons que le wikicode est accepté puisque nous avons réussi à aller à la ligne avec <br /> et nous avons réussi à souligner le titre avec les balises <u></u>. Dans ce programme, nous avons commencé par déclarer la variable reponse en l'initialisant avec le titre. Nous avons ensuite utilisé une boucle for..do avec une variable d'index allant de 1 à 7. Cette variable d'index servant à accéder aux différentes cases du tableau. La boucle for..do s’avère donc être un excellent moyen pour manipuler la totalité des données se trouvant dans une table.

Deuxième forme de la boucle for

[modifier | modifier le wikicode]

Cette deuxième forme de la boucle for appelée aussi forme itérative de la boucle for est plus particulièrement adaptée aux tables. Elle se rédige sous la forme :

for clé, objet in fonction itérative, table, arrêt do
	instructions
end

Durant le parcours de la table, clé prend la valeur de la clé considérée et objet prend la valeur correspondante. fonction itérative est une fonction gérant le parcourt de la table, elle gère le parcourt des clés qui nous intéresses dans l’ordre qui nous intéresse. table est la table considérée et arrêt est la valeur qui stoppe le parcourt de la table, le plus souvent nil.

Exemple concernant les tables à clé numérique

Dans le Module:Iteratif, nous écrirons la fonction p.description accompagnée de la fonction suivant ainsi :

local souk = {"flute", "pipo", "manche à balaie", "serpière", "jeu de cartes", "coton tige", "tourne vis", "rateau", "stylo", "poupée"}

function suivant(tab,n)
	if n == nil then n = 0 end
	if tab[n+1] == nil then
		return nil,nil
	else
		return n+1,tab[n+1]
	end
end

function p.description()
	local reponse = " "
	for index, objet in suivant,souk,nil do
		reponse = reponse.."<br />à la clé numéro "..index.." se trouve l’objet "..objet.."."
	end
	return reponse
end

La fonction suivant est la fonction itérative qui gère le parcours de la table. Cette fonction retourne deux valeurs : la valeur de la clé suivante et l’objet correspondant. Ici, on se contente d'augmenter la clé d'une unité à chaque boucle. Cette fonction a deux entrées, la table considérée et la valeur de la clé précédente à partir de laquelle elle devra calculer la clé suivante. Au début, la valeur de la clé précédente n'existe pas et la valeur nil est fournie à la place. La fonction suivant voyant nil comme clé précédente devra fournir, comme clé suivante, la valeur de la première clé à considérer. Lorsque le parcours de la table sera achevé, la variable lue dans la table sera nil et la fonction retournera donc nil comme valeur de la clé suivante indiquant ainsi à la boucle for que le parcours de la table est terminé.

{{#invoke:iteratif|description}} nous retourne :
à la clé numéro 1 se trouve l’objet flute.
à la clé numéro 2 se trouve l’objet pipo.
à la clé numéro 3 se trouve l’objet manche à balaie.
à la clé numéro 4 se trouve l’objet serpière.
à la clé numéro 5 se trouve l’objet jeu de cartes.
à la clé numéro 6 se trouve l’objet coton tige.
à la clé numéro 7 se trouve l’objet tourne vis.
à la clé numéro 8 se trouve l’objet rateau.
à la clé numéro 9 se trouve l’objet stylo.
à la clé numéro 10 se trouve l’objet poupée.


Dans la pratique, le plus souvent, le parcours de la table commence à la clé 1 et s'opère ainsi en incrémentant d'une unité la valeur de la clé jusqu'à atteindre la clé de valeur la plus élevée comme dans l'exemple précédent. Par conséquent, pour simplifier, le Lua fournit, dans ce cas particulier, une fonction préprogrammée nommée ipairs qui retourne trois valeurs en sortie, à savoir la fonction itérative, la table, et la valeur nil. Grâce à la fonction ipairs, l'exemple précédent se simplifie ainsi :

local souk = {"flute", "pipo", "manche à balaie", "serpière", "jeu de cartes", "coton tige", "tourne vis", "rateau", "stylo", "poupée"}

function p.description()
	local reponse = " "
	for index, objet in ipairs(souk) do
		reponse = reponse.."<br />à la clé numéro "..index.." se trouve l’objet "..objet.."."
	end
	return reponse
end

Nous étudierons de façon plus approfondie la fonction ipairs dans le chapitre sur les fonctions basiques.

Exemple concernant les tables à clé quelconque

Nous avons vu, dans l'exemple précédent, comment parcourir une table à clé numérique en utilisant la deuxième forme de la boucle for. Supposons que nous voulions faire de même avec une table avec clé sous forme de chaîne de caractères. Le problème qui se pose est de savoir comment écrire la fonction itérative que nous avons appelée suivant dans l'exemple précédent. Comment passer d'une clé sous forme de chaîne de caractère à la suivante sans en oublier. Nous voyons que le problème n’est pas facile à résoudre. Pour nous faciliter la chose, le Lua fournit une fonction préprogrammée appelé next qui joue exactement le même rôle que la fonction suivant de l'exemple précédent, mais pour les clés sous forme de chaîne de caractères.

Prenons un exemple :

local p = {}

local fouillis = {["Nourriture"] = "Fromage", ["Boisson"] = "Limonade", ["Bestiole"] = "Cafard", ["Couvert"] = "Fourchette", ["Truc"] = "Machin chose"}

function p.farfouille()
	local reponse = " "
	for index, objet in next,fouillis,nil do
		reponse = reponse.."<br />à la clé "..index.." se trouve l’objet "..objet.."."
	end
	return reponse
end

return p


{{#invoke:iteratif|farfouille}} nous retourne :
à la clé Nourriture se trouve l’objet Fromage.
à la clé Boisson se trouve l’objet Limonade.
à la clé Couvert se trouve l’objet Fourchette.
à la clé Truc se trouve l’objet Machin chose.
à la clé Bestiole se trouve l’objet Cafard.


Comme pour les tables à clé numérique, le Lua nous facilite un peu les choses en fournissant aussi une fonction préprogrammée appelée pairs qui retourne trois valeurs : une fonction itérative, la table considérée, la valeur nil. Nous pouvons donc simplifier un peu le programme précédent en l'écrivant :

local p = {}

local fouillis = {["Nourriture"] = "Fromage", ["Boisson"] = "Limonade", ["Bestiole"] = "Cafard", ["Couvert"] = "Fourchette", ["Truc"] = "Machin chose"}

function p.farfouille()
	local reponse = " "
	for index, objet in pairs(fouillis) do
		reponse = reponse.."<br />à la clé "..index.." se trouve l’objet "..objet.."."
	end
	return reponse
end

return p

Cette fois, nous n'avons pas gagné grand-chose !

Opérateurs logiques

[modifier | modifier le wikicode]

Nous avons vu que certaines structures de contrôle dépendent d'une condition. Nous allons, dans ce paragraphe, étudier plus en détail la formulation de la condition.

Nous avons, jusqu'à maintenant, principalement vu que les variables pouvaient contenir deux types de données que l’on a appelés chaîne de caractères et nombre. Nous allons voir maintenant un nouveau type de donnée que l’on appelle booléen. Une variable de type booléen peut être affectée de deux façons, soit avec la valeur false, soit avec la valeur true. Si elle mémorise la valeur false, cela signifie qu'elle mémorise que quelque chose est faux. Si elle mémorise la valeur true, cela signifie qu'elle mémorise que quelque chose est vrai.

Pour indiquer qu'une variable est de type booléen, on peut l'initialiser avec les valeurs true ou false

Par exemple :

	local correct = true
	local panne = false

true et false sont des mots réservés du langage Lua.

Il est possible aussi de les initialiser avec quelque chose de vrai ou de faux :

	local correct = 2 > 1
	local panne = 2 < 1

Dans l'exemple ci-dessus, après initialisation, correct contiendra true et panne contiendra false

Les variables en Lua, peuvent devenir de type booléen après affectation, même si elles sont initialisées d'un autre type.

Par exemple, dans le Module:Logique, nous écrirons la fonction essai1 ainsi :

local p = {}

function p.essai1()
	local reponse = "Coucou, c’est moi !"
	reponse = 2 > 1
	return reponse
end

return p

En tapant : {{#invoke:Logique|essai1}}, nous obtenons : true

La variable reponse, qui était de type chaîne de caractère, est devenue de type booléen après affectation de 2 > 1 et a pris la valeur true car 2 est bien supérieur à 1


N'oublions pas que nous sommes dans le chapitre sur les structures de contrôle. Dans une structure de contrôle : if..then..else, while..do ou repeat..until, nous pouvons nous servir des variables de type booléen comme condition. Si la variable contient le booléen true, la condition sera considérée comme vraie. Si la variable contient le booléen false, la condition sera considérée comme fausse.

Par exemple, toujours dans le Module:Logique, écrivons une fonction essai2 ainsi :

local p = {}

function p.essai2()
	local condition = false
	if condition then
		return "La condition est vraie"
	else
		return "La condition est fausse"
	end
end

return p

En tapant : {{#invoke:Logique|essai2}}, nous obtenons : La condition est fausse


Il est possible de se servir d'autres variables ou valeurs comme condition dans les tests et boucles. Il suffit de savoir que toutes les variables ou valeurs différentes de nil sont assimilables à true. Seule une variable contenant nil ou une valeur égale à nil est assimilable à false

Par exemple, toujours dans le Module:Logique, écrivons une fonction essai4 ainsi :

local p = {}

function p.essai4()
	local condition = 0
	if condition then
		return "La condition est vraie"
    else
		return "La condition est fausse"
	end
end

return p

En tapant : {{#invoke:Logique|essai4}}, nous obtenons : La condition est vraie

Nous remarquons que 0 a été assimilé à true contrairement à d’autre langage, comme le langage C, où 0 est assimilé à false. Ceci procède d'une certaine logique car, en langage C, une fonction qui se déroule mal retourne, en principe, 0 pour indiquer que cela s'est mal passé alors qu'en Lua, si cela se passe mal, la fonction retourne nil. Nil n'existe pas en langage C, son équivalent est 0.


Autre exemple : toujours dans le Module:Logique, écrivons une fonction essai5 ainsi :

local p = {}

function p.essai5()
	local condition
	if condition then
		return "La condition est vraie"
    else
		return "La condition est fausse"
	end
end

return p

En tapant : {{#invoke:Logique|essai5}}, nous obtenons : La condition est fausse

la variable condition n'a pas été assignée, donc contient nil, et nous voyons que nil est assimilé à false.


De même que les variables de type nombre peuvent être combinées avec les opérateurs +, -, *, /, ^,

de même que les variables de type chaîne de caractères peuvent être combinées avec l'opérateur ..,

les variables de type booléen peuvent être combiné avec les opérateurs and, or, not.


L'opérateur and

[modifier | modifier le wikicode]

Soit a et b deux variables booléennes et soit l'affectation :

c = a and b

alors c sera vraie uniquement si les deux variables a et b sont toutes les deux vraies. Plus précisément, on peut faire un tableau, appelé table de vérité, donnant la valeur de c en fonction des valeurs de a et b, ainsi :

a b c
false false false
false true false
true false false
true true true


L'opérateur or

[modifier | modifier le wikicode]

Soit a et b deux variables booléennes et soit l'affectation :

c = a or b

alors c sera vraie si au moins l'une des deux variables a ou b est vraie. Plus précisément, on peut faire un tableau, appelé table de vérité, donnant la valeur de c en fonction des valeurs de a et b, ainsi :

a b c
false false false
false true true
true false true
true true true


L'opérateur not

[modifier | modifier le wikicode]

Soit a une variable booléenne et soit l'affectation :

c = not a

alors c sera vraie si a est fausse et sera fausse si a est vraie. Plus précisément, on peut faire un tableau, appelé table de vérité, donnant la valeur de c en fonction de la valeur de a, ainsi :

a c
false true
true false


Il est, bien sûr, possible d'opérer directement sur les conditions sans passer par des variables. Toujours dans le Module:Logique, considérons la fonction essai3 qui nous indique si l'argument entré est strictement compris entre 1 et 8 :

local p = {}

function p.essai3(frame)
	local n = tonumber(frame.args[1])
	if 1 < n and n < 8 then
		return "Le nombre est strictement compris entre 1 et 8"
	else
		return "Le nombre n’est pas strictement compris entre 1 et 8"
	end
end

return p

Si nous écrivons : {{#invoke:Logique|essai3|6}}, nous obtenons : Le nombre est strictement compris entre 1 et 8


Par contre, si nous écrivons :

local p = {}

function p.essai3(frame)
	local n = tonumber(frame.args[1])
	if 1 < n < 8 then
		return "Le nombre est strictement compris entre 1 et 8"
	else
		return "Le nombre n’est pas strictement compris entre 1 et 8"
	end
end

return p

nous obtenons une erreur de script !


Opérateurs externes

[modifier | modifier le wikicode]

Nous dirons qu'un opérateur est externe si le résultat de l'opération est d'un type différent de celui des objets sur lesquels s'effectue l'opération

Par exemple, nous avons écrit plus haut :

	local correct = 2 > 1
	local panne = 2 < 1

Ce qui nous montre que > et < sont des opérateurs externes car il effectue une opération entre les nombres 1 et 2 et le résultat de cette opération est un booléen qui sera affecté aux variables correct ou panne.


> est l'opérateur "strictement supérieur". Nous avons aussi l'opérateur "supérieur ou égal" qui se noterait >=.

< est l'opérateur "strictement inférieur". Nous avons aussi l'opérateur "inférieur ou égal" qui se noterait <=.


Nous avons aussi déjà utilisé l'opérateur == qui permet de comparer deux variables et qui retourne "true" si les variables sont égales ou "false" si les variables sont différentes. Nous avons aussi l'opérateur ~= qui compare aussi deux variables mais retourne "false" si les variables sont égales et "true" si les variables sont différentes.

  1. Si l'utilisatrice est en fait un utilisateur homme, il faut remplacer « Grosse vache ! » par « Gros patapouf ! ». Notons cependant que cela ne change rien à la logique de la programmation.