Crystal dispose de ce qu'on appelle des expressions de contrôle : elles servent à contrôler la façon dont le programme s'exécute et elles prennent une valeur vraie ou fausse. Il existe des opérateurs qui permettent de créer des valeurs vraies ou fausses : ce sont les opérateurs d'égalité et de comparaison.
Il existe deux expressions de contrôle principales qui déterminent quel code sera exécuté et lequel ne le sera pas. Autrement dit, quelle branche donnée sera exécutée.
Ces deux expressions sont if et unless.
Les opérateurs de comparaison servent à comparer des valeurs et renvoient une valeur true ou false.
Ces opérateurs exigent que les deux valeurs comparées soient du même type.
Si les valeurs ne sont pas du même type, le compilateur lèvera une erreur.
Voici une liste des opérateurs de comparaison, avec un exemple où ils renvoient true :
| Méthode | Description | Exemple |
|---|---|---|
| < | inférieur à | 4 < 5 |
| <= | inférieur ou égal à | 4 <= 4 |
| > | supérieur à | 3 > 1 |
| >= | supérieur ou égal à | 2 >= 2 |
Les opérateurs d'égalité sont semblables aux opérateurs de comparaison, mais ils servent à vérifier si deux valeurs sont égales ou non.
L'opérateur == vérifie si deux valeurs sont égales, en tenant compte de leur type.
Si les valeurs sont identiques, il renvoie true, sinon il renvoie false.
L'opérateur == peut comparer n'importe quel type de valeur à n'importe quel autre type de valeur.
L'opérateur != fonctionne de la même manière, mais il renvoie true si les valeurs sont différentes et false si elles sont égales.
if
L'instruction if sert à vérifier si une condition donnée est vraie ou fausse.
Si la condition est vraie, le code à l'intérieur de l'instruction if est exécuté.
Une instruction if se termine par le mot-clé end.
if 1 == 1
puts "1 is equal to 1"
end
# => 1 is equal to 1
if 1 > 2
puts "1 is greater than 2"
end
# => no output
unless
L'instruction unless fonctionne de façon très similaire à l'instruction if, mais elle exécute le code qu'elle contient si la condition est fausse.
unless 1 == 1
puts "1 is not equal to 1"
end
# => no output
unless 1 > 2
puts "1 is not greater than 2"
end
# => 1 is not greater than 2
else
L'instruction else peut être utilisée conjointement avec les instructions if et unless.
L'instruction else est exécutée si la branche if ou la branche unless n'est pas exécutée.
Même si une branche `else` peut être utilisée conjointement avec `unless,`, c'est déconseillé, car cela nuit à la lisibilité.
À la place, il est recommandé d'utiliser `if !condition` avec une branche else.
if 1 == 1
puts "1 is equal to 1"
else
puts "1 is not equal to 1"
end
# => 1 is equal to 1
unless 1 < 2
puts "1 is not greater than 2"
else
puts "1 is greater than 2"
end
# => 1 is greater than 2
if en cascadeL'instruction elsif peut être utilisée conjointement avec l'instruction if.
L'instruction elsif est exécutée si la branche if ne l'est pas et que la condition de l'instruction elsif est vraie.
Les instructions elsif peuvent être enchaînées, et la première condition vraie sera exécutée.
Une instruction else peut également figurer à la fin de l'instruction if : elle s'exécutera si aucune des instructions précédentes n'était vraie.
if 1 != 1
puts "1 is not equal to 1"
elsif 1 > 2
puts "1 is greater than 2"
else
puts "1 is not equal to 1 and 1 is not greater than 2"
end
# => 1 is not equal to 1 and 1 is not greater than 2
Quand elle reçoit des valeurs de types différents, la variable porte les deux types. C'est parce que le compilateur ne sait pas quelle branche sera exécutée. Cette affectation multiple, aussi appelée union, sera expliquée dans des concepts ultérieurs. L'exemple suivant l'illustre :
if 1 == 1
a = 1
else
a = "1"
end
typeof(a) # => Int32 | String
Crystal dispose d'un opérateur ternaire, une instruction if-else sur une seule ligne : condition ? expression_if_truthy : expression_if_falsey
1 == 1 ? puts("1 is equal to 1") : puts("1 is not equal to 1")
# => 1 is equal to 1
Dans cet exercice, on va développer un système de contrôle simple pour un réacteur nucléaire.
Pour qu'un réacteur produise de la puissance, il doit se trouver dans un état de criticité. Si le réacteur se trouve dans un état inférieur à la criticité, il peut s'endommager. Si l'état du réacteur dépasse la criticité, il peut surcharger et provoquer une fusion du cœur. On veut réduire les risques de fusion du cœur et gérer correctement l'état du réacteur.
Les trois tâches suivantes consistent toutes à écrire du code pour maintenir l'état idéal du réacteur.
La première chose que doit faire un système de contrôle est de vérifier si le réacteur est équilibré en criticité. On dit qu'un réacteur est critique s'il remplit les conditions suivantes :
Implémente la méthode Reactor.criticality_balanced? qui prend temperature mesurée en kelvin et neutrons_emitted comme paramètres, et qui renvoie true si les conditions de criticité sont remplies, false sinon.
Reactor.criticality_balanced?(750, 600)
# => true
Une fois que le réacteur a commencé à produire de la puissance, il faut déterminer son rendement. Le rendement peut être réparti en 4 plages :
green -> un rendement de 80 % ou plus,orange -> un rendement inférieur à 80 % mais d'au moins 60 %,red -> un rendement inférieur à 60 %, mais toujours d'au moins 30 %,black -> un rendement inférieur à 30 %.Le pourcentage peut se calculer ainsi : (generated_power/theoretical_max_power)*100, où generated_power = voltage * current.
Note que le pourcentage n'est généralement pas un nombre entier, alors fais attention au bon usage des comparaisons < et <=.
Implémente la méthode Reactor.reactor_efficiency, avec trois paramètres : voltage, current et theoretical_max_power.
Cette fonction doit renvoyer la plage de rendement du réacteur : "green", "orange", "red" ou "black".
Reactor.reactor_efficiency(200,50,15000)
# => "orange"
Ta dernière tâche consiste à créer un mécanisme à sécurité intégrée pour éviter la surcharge et la fusion du cœur. Ce mécanisme déterminera si le réacteur se situe en dessous, au niveau ou au-dessus du seuil de criticité idéal. On peut alors augmenter, diminuer ou arrêter la criticité en insérant (ou en retirant) des barres de contrôle dans le réacteur.
Implémente la méthode Reactor.fail_safe(), qui prend 3 paramètres : temperature mesurée en kelvin, neutrons_produced_per_second et threshold, et qui renvoie un code de statut pour le réacteur.
Si temperature * neutrons_produced_per_second < 90 % de threshold, renvoie un code de statut "LOW"
indiquant qu'il faut retirer les barres de contrôle pour produire de la puissance.
Si temperature * neutrons_produced_per_second se situe à plus ou moins 10 % du threshold,
le réacteur est en criticité et le code de statut "NORMAL" doit être renvoyé, indiquant que le
réacteur est dans des conditions optimales et que les barres de contrôle sont dans une position idéale.
Si temperature * neutrons_produced_per_second ne se trouve pas dans les plages indiquées ci-dessus, le réacteur
part en fusion du cœur et le code de statut "DANGER" doit être renvoyé pour arrêter immédiatement le réacteur.
temperature = 1000
neutrons_produced_per_second = 30
threshold = 5000
Reactor.fail_safe(temperature, neutrons_produced_per_second, threshold)
# => "DANGER"
Inscris-toi sur Exercism pour apprendre et maîtriser Crystal avec 26 concepts142 exercices, et un vrai mentorat humain, le tout gratuitement.