আপনার শরীর তৈরি কোষ দিয়ে, আর সেই কোষগুলোর ভেতরে থাকে DNA. এই কোষগুলো নিয়মিত পুরনো হয়ে যায় এবং বদলে ফেলা দরকার হয়, যা তারা কন্যা কোষে ভাগ হয়ে সম্পন্ন করে। আসলে, গড়ে একজন মানুষের শরীরে সারা জীবনে প্রায় ১০০ কোটি কোটি কোষ বিভাজন ঘটে!
কোষ বিভক্ত হলে তাদের DNA-ও প্রতিলিপিত হয়। কখনও কখনও এই প্রক্রিয়ার মধ্যেই ভুল ঘটে যায় এবং DNA-র একেকটি টুকরোয় ভুল তথ্য এনকোড হয়ে যায়। যদি আমরা DNA-র দুটি স্ট্র্যান্ডের তুলনা করি এবং তাদের মধ্যেকার পার্থক্য গুনে দেখি, তাহলে বোঝা যায় কতগুলো ভুল ঘটেছে। একেই বলা হয় "হ্যামিং দূরত্ব"।
হ্যামিং দূরত্ব শুধু জীববিজ্ঞানেই নয়, বিজ্ঞানের অনেক ক্ষেত্রেই কাজে লাগে, তাই শব্দটি চেনা থাকলে ভালো হয় :)
দুটি DNA স্ট্র্যান্ডের মধ্যে হ্যামিং দূরত্ব হিসাব করুন।
আমরা DNA পড়ি C, A, G আর T অক্ষর দিয়ে। দুটি স্ট্র্যান্ড দেখতে এমন হতে পারে:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
এদের মধ্যে ৭টি পার্থক্য আছে, তাই হ্যামিং দূরত্ব ৭।
হ্যামিং দূরত্ব শুধু সমান দৈর্ঘ্যের সিকোয়েন্সের ক্ষেত্রেই সংজ্ঞায়িত, তাই ভিন্ন দৈর্ঘ্যের সিকোয়েন্সের মধ্যে এটি হিসাব করার চেষ্টা কাজ করবে না।
Option এমন একটি গণনা বোঝাতে ব্যবহৃত হয়, যার কোনো কাজের ফলাফল নাও থাকতে পারে
(যেমন কোনো এরর বা ভুল ইনপুটের কারণে)।
আপনি যদি Option-এর সাথে অপরিচিত হন, তাহলে এই টিউটোরিয়ালটি পড়ে দেখতে পারেন।
Option হলো তথাকথিত একটি মোনাড, যা একটি "কম্পিউটেশনাল অ্যাসপেক্ট" সামলায়, এই ক্ষেত্রে একটি মান সম্ভবত অনুপস্থিত থাকা।
মোনাড সঠিকভাবে ব্যবহার করলে কোড খুব সংক্ষিপ্ত, তবুও সুন্দর
আর পাঠযোগ্য হতে পারে। ভুলভাবে ব্যবহার করলে সহজেই উল্টোটা হতে পারে।
আরও জানতে এই ভিডিওটি দেখুন।
Option-এর জন্য কয়েকটি সাধারণ নিয়ম আছে:
def add1(x: Int): Option[Int] = Some(x + 1)
বরং এভাবে লিখুন
def add1(x: Int): Int = x + 1
(এমন সাধারণ ফাংশন প্রয়োগ করার জন্য Option.map আছে,
তাই এগুলোকে Option দিয়ে জটিল করার দরকার নেই)।
2. সত্যিই দরকার না হলে "আনর্যাপ" করবেন না।
আপনার উদ্দেশ্য সাধনের জন্য প্রায়ই বিল্ট-ইন ফাংশন থাকে। সময়ের আগেই
আনর্যাপ করার লক্ষণ হলো isDefined/isEmpty বা প্যাটার্ন ম্যাচিং। এর বদলে
val x: Option[Int] = ...
if (x.isDefined) x.get + 1 else 0
// or
x match {
case Some(n) => n + 1
case None => 0
}
বরং এভাবে লিখুন
x map (_ + 1) getOrElse 0
Option ইনস্ট্যান্স "কম্পোজ" করতে চাইলে এটি করাই বাঞ্ছনীয়। এর বদলেval xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
বরং এভাবে লিখুন
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z
Exercism-এ সাইন আপ করুন, Scala ট্র্যাকের 95টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।