Crystal-এ কন্ট্রোল এক্সপ্রেশন নামে পরিচিত জিনিস রয়েছে, এগুলো দিয়ে প্রোগ্রাম কীভাবে চলবে তা নিয়ন্ত্রণ করা হয় এবং এগুলো একটি ট্রুথি বা ফলসি মান নেয়। কিছু অপারেটর আছে যেগুলো দিয়ে ট্রুথি বা ফলসি মান তৈরি করা যায়, এগুলোকে সমতা ও তুলনা অপারেটর বলা হয়।
দুটি প্রধান কন্ট্রোল এক্সপ্রেশন আছে যেগুলো দিয়ে নিয়ন্ত্রণ করা হয় কোন কোডটি চলবে আর কোনটি চলবে না। অর্থাৎ কোন নির্দিষ্ট শাখাটি চলবে তাও এগুলোই ঠিক করে।
এই দুটি হলো: if এবং unless এক্সপ্রেশন।
তুলনা অপারেটর দিয়ে মানগুলো তুলনা করা হয় এবং একটি true বা false মান রিটার্ন করা হয়।
এই অপারেটরগুলো দিয়ে তুলনা করতে একই টাইপের দুটি মান লাগে।
মানগুলো একই টাইপের না হলে কম্পাইলার একটি এরর দেবে।
এখানে তুলনা অপারেটরগুলোর একটি তালিকা আর কখন সেগুলো true মান দেয় তার একটি উদাহরণ দেওয়া হলো:
| Method | Description | Example |
|---|---|---|
| < | less than | 4 < 5 |
| <= | less than or equal | 4 <= 4 |
| > | greater than | 3 > 1 |
| >= | greater than or equal | 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 স্টেটমেন্টের সাথে একসাথে ব্যবহার করা যায়।
if শাখা বা unless শাখা চালানো না হলে else স্টেটমেন্ট চালানো হবে।
এমনকি `unless,`-এর সঙ্গেও একটি `else` শাখা ব্যবহার করা গেলেও, তা করতে নিরুৎসাহিত করা হয় কারণ এতে পড়ার সহজতা নষ্ট হয়।
বরং `else` শাখাসহ `if !condition` ব্যবহার করার পরামর্শ দেওয়া হয়।
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 স্টেটমেন্টের সাথে একসাথে ব্যবহার করা যায়।
if শাখাটি চালানো না হলে এবং elsif স্টেটমেন্টের শর্তটি ট্রুথি হলে elsif স্টেটমেন্ট চালানো হবে।
elsif স্টেটমেন্টগুলো একসাথে শৃঙ্খলাবদ্ধ করা যায় এবং প্রথম ট্রুথি শর্তটিই চালানো হবে।
if স্টেটমেন্টের শেষে একটি 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
চুল্লি পাওয়ার উৎপাদন শুরু করলে তার দক্ষতা নির্ণয় করতে হবে। দক্ষতাকে ৪টি ব্যান্ডে ভাগ করা যায়:
green -> ৮০% বা তার বেশি দক্ষতা,orange -> ৮০%-এর কম কিন্তু অন্তত ৬০% দক্ষতা,red -> ৬০%-এর কম কিন্তু ৩০% বা তার বেশি দক্ষতা,black -> ৩০%-এর কম দক্ষতা।শতকরা মান (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() নামের মেথডটি বাস্তবায়ন করুন, যা ৩টি প্যারামিটার নেয়: কেলভিনে মাপা temperature, neutrons_produced_per_second এবং threshold, আর চুল্লির জন্য একটি স্ট্যাটাস কোড আউটপুট দেয়।
যদি temperature * neutrons_produced_per_second-এর মান threshold-এর ৯০%-এর কম হয়, তাহলে "LOW" স্ট্যাটাস কোড আউটপুট দিন, যা বোঝায় পাওয়ার উৎপাদনের জন্য কন্ট্রোল রড বের করে আনতে হবে।
যদি temperature * neutrons_produced_per_second-এর মান 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টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।