Треки
/
Crystal
Crystal
/
Вправи
/
Запобігання розплаву
Запобігання розплаву

Запобігання розплаву

Навчальна вправа

Вступ

У Crystal є так звані керуючі вирази. Вони визначають, як виконуватиметься програма, і приймають істинне або хибне значення. Існують оператори, за допомогою яких можна отримати істинні або хибні значення, їх називають операторами рівності та порівняння.

Є два основні керуючі вирази, які визначають, який код виконається, а який ні. Інакше кажучи, яка саме гілка спрацює.

Це if і unless.

Оператори порівняння

Оператори порівняння порівнюють значення й повертають true або false. Щоб порівняти два значення, вони мають бути одного типу. Якщо типи значень різняться, компілятор видасть помилку. Ось список операторів порівняння та приклади, коли вони дають true:

Метод Опис Приклад
< менше ніж 4 < 5
<= менше ніж або дорівнює 4 <= 4
> більше ніж 3 > 1
>= більше ніж або дорівнює 2 >= 2

Оператори рівності

Оператори рівності схожі на оператори порівняння, але вони перевіряють, чи два значення рівні.

Оператор == перевіряє, чи два значення рівні, враховуючи й тип значення. Якщо значення однакові, він поверне true, інакше поверне false. Оператор == може порівнювати значення будь-якого типу зі значенням будь-якого іншого типу. Оператор != працює так само, але повертає true, якщо значення не рівні, і false, якщо рівні.

Умовна конструкція if

Умовна конструкція if перевіряє, чи задана умова істинна або хибна. Якщо умова істинна, код усередині конструкції if виконається. Конструкція if завершується ключовим словом 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

Умовна конструкція unless працює майже так само, як if, але виконує код усередині, якщо умова хибна.

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

Конструкцію else можна поєднувати з if і unless. Гілка else виконається, якщо гілка if або unless не виконалася.

Хоча гілку `else` можна поєднувати з `unless,` робити так не варто, бо це погіршує читабельність.
Натомість радимо використовувати `if !condition` із гілкою `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

Конструкцію elsif можна поєднувати з конструкцією if. Гілка elsif виконається, якщо гілка if не виконалася, а умова elsif істинна. Конструкції elsif можна обʼєднувати в ланцюжок, і виконається перша умова, що виявиться істинною. Наприкінці можна також додати else, який виконається, якщо жодна з попередніх умов не була істинною.

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

Типи в умовних конструкціях

Якщо в різних гілках змінній присвоюються значення різних типів, вона матиме обидва типи. Так стається, бо компілятор не знає, яка гілка виконається. Це множинне присвоєння, яке також називають обʼєднанням типів, пояснять у наступних концепціях. Це видно в такому прикладі:

if 1 == 1
  a = 1
else
  a = "1"
end

typeof(a) # => Int32 | String

Тернарний оператор

У Crystal є тернарний оператор, однорядковий запис умови if-else: 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

Вказівки

У цій вправі ми розробимо просту систему керування ядерним реактором.

Щоб реактор виробляв потужність, він має перебувати в стані критичності. Якщо стан реактора нижчий за критичність, він може зазнати пошкоджень. Якщо стан реактора перевищує критичність, він може перевантажитися, що призведе до розплавлення. Ми хочемо зменшити ймовірність розплавлення і навчитися правильно керувати станом реактора.

Наступні три завдання повʼязані з написанням коду для підтримання ідеального стану реактора.

1. Перевірка критичності

Система керування насамперед має перевіряти, чи збалансований реактор за критичністю. Реактор називають критичним, якщо він задовольняє такі умови:

  • Температура менша за 800 K.
  • Кількість нейтронів, що випромінюються за секунду, більша за 500.
  • Добуток температури та кількості нейтронів, що випромінюються за секунду, менший за 500000.

Реалізуйте метод Reactor.criticality_balanced?, який приймає temperature, виміряну в кельвінах, і neutrons_emitted як параметри, та повертає true, якщо умови критичності виконано, і false, якщо ні.

Reactor.criticality_balanced?(750, 600)
# => true

2. Визначення діапазону вихідної потужності

Коли реактор починає виробляти потужність, потрібно визначити його ефективність. Ефективність можна поділити на 4 діапазони:

  1. green -> ефективність 80% або більше,
  2. orange -> ефективність менша за 80%, але щонайменше 60%,
  3. red -> ефективність нижча за 60%, але все ще 30% або більше,
  4. black -> ефективність менша за 30%.

Відсоткове значення можна обчислити як (generated_power/theoretical_max_power)*100, де generated_power = voltage * current. Зверніть увагу, що відсоткове значення зазвичай не є цілим числом, тому обовʼязково врахуйте правильне використання порівнянь < і <=.

Реалізуйте метод Reactor.reactor_efficiency із трьома параметрами: voltage, current і theoretical_max_power. Ця функція має повертати діапазон ефективності реактора: "green", "orange", "red" або "black".

Reactor.reactor_efficiency(200,50,15000)
# => "orange"

3. Механізм безпечної відмови

Ваше останнє завдання - створити механізм безпечної відмови, щоб уникнути перевантаження і розплавлення. Цей механізм визначатиме, чи реактор перебуває нижче, на рівні або вище ідеального порогу критичності. Після цього критичність можна підвищити, знизити або зупинити, вставляючи (або виймаючи) керувальні стрижні в реактор.

Реалізуйте метод Reactor.fail_safe(), який приймає 3 параметри: temperature, виміряну в кельвінах, neutrons_produced_per_second і threshold, та видає код стану реактора.

  • Якщо temperature * neutrons_produced_per_second < 90% від threshold, видайте код стану "LOW", що означає, що для вироблення потужності потрібно вийняти керувальні стрижні.

  • Якщо temperature * neutrons_produced_per_second перебуває в межах плюс-мінус 10% від threshold, реактор у стані критичності, і потрібно видати код стану "NORMAL", що означає, що реактор перебуває в оптимальному стані, а керувальні стрижні - в ідеальному положенні.

  • Якщо temperature * neutrons_produced_per_second не потрапляє в зазначені вище діапазони, реактор іде до розплавлення, і потрібно передати код стану "DANGER", щоб негайно зупинити реактор.

temperature = 1000
neutrons_produced_per_second = 30
threshold = 5000
Reactor.fail_safe(temperature, neutrons_produced_per_second, threshold)
# => "DANGER"
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Crystal Exercism

Час розпочати Запобігання розплаву?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Crystal, а також 26 концепцій142 вправи та справжнє наставництво від людей, і все це безкоштовно.