У 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
У цій вправі ми розробимо просту систему керування ядерним реактором.
Щоб реактор виробляв потужність, він має перебувати в стані критичності. Якщо стан реактора нижчий за критичність, він може зазнати пошкоджень. Якщо стан реактора перевищує критичність, він може перевантажитися, що призведе до розплавлення. Ми хочемо зменшити ймовірність розплавлення і навчитися правильно керувати станом реактора.
Наступні три завдання повʼязані з написанням коду для підтримання ідеального стану реактора.
Система керування насамперед має перевіряти, чи збалансований реактор за критичністю. Реактор називають критичним, якщо він задовольняє такі умови:
Реалізуйте метод Reactor.criticality_balanced?, який приймає temperature, виміряну в кельвінах, і neutrons_emitted як параметри, та повертає true, якщо умови критичності виконано, і false, якщо ні.
Reactor.criticality_balanced?(750, 600)
# => true
Коли реактор починає виробляти потужність, потрібно визначити його ефективність. Ефективність можна поділити на 4 діапазони:
green -> ефективність 80% або більше,orange -> ефективність менша за 80%, але щонайменше 60%,red -> ефективність нижча за 60%, але все ще 30% або більше,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"
Ваше останнє завдання - створити механізм безпечної відмови, щоб уникнути перевантаження і розплавлення. Цей механізм визначатиме, чи реактор перебуває нижче, на рівні або вище ідеального порогу критичності. Після цього критичність можна підвищити, знизити або зупинити, вставляючи (або виймаючи) керувальні стрижні в реактор.
Реалізуйте метод 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"
Зареєструйтеся на Exercism, щоб вивчати й опановувати Crystal, а також 26 концепцій142 вправи та справжнє наставництво від людей, і все це безкоштовно.