تحتوي 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 إذا كان الشرط خاطئًا.
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
يمكن استخدام جملة elsif مع جملة if.
وتُنفَّذ جملة elsif إذا لم يُنفَّذ فرع if وكان شرط جملة elsif صحيحًا.
ويمكن ربط جمل elsif ببعضها، وسيُنفَّذ أول شرط صحيح.
ويمكن أيضًا وجود جملة else في نهاية جملة if، وستُنفَّذ إذا لم يكن أي من الجمل السابقة صحيحًا.
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 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.