Parcours
/
Crystal
Crystal
/
Exercices
/
Atténuation de la fusion
Atténuation de la fusion

Atténuation de la fusion

Exercice d'apprentissage

Introduction

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.

Opérateurs de comparaison

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

Opérateurs d'égalité

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.

L'instruction 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

L'instruction 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

L'instruction 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

Les instructions if en cascade

L'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

Les types avec les conditions

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

L'opérateur ternaire

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

Instructions

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.

1. Vérifie la criticité

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 :

  • La température est inférieure à 800 K.
  • Le nombre de neutrons émis par seconde est supérieur à 500.
  • Le produit de la température et des neutrons émis par seconde est inférieur à 500000.

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

2. Détermine la plage de puissance de sortie

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 :

  1. green -> un rendement de 80 % ou plus,
  2. orange -> un rendement inférieur à 80 % mais d'au moins 60 %,
  3. red -> un rendement inférieur à 60 %, mais toujours d'au moins 30 %,
  4. 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"

3. Mécanisme à sécurité intégrée

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"
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
Crystal Exercism

Prêt à commencer Atténuation de la fusion ?

Inscris-toi sur Exercism pour apprendre et maîtriser Crystal avec 26 concepts142 exercices, et un vrai mentorat humain, le tout gratuitement.