المسارات
/
Scala
Scala
/
التمارين
/
عدّ النوكليوتيدات
عدّ النوكليوتيدات

عدّ النوكليوتيدات

متوسط

التعليمات

كلٌّ منا يرث من والديه البيولوجيين مجموعة من التعليمات الكيميائية المعروفة باسم DNA، وهي التي تؤثر في كيفية بناء أجسامنا. تعتمد كل أشكال الحياة المعروفة على DNA!

ملاحظة: لا تحتاج إلى فهم أي شيء عن النيوكليوتيدات أو عن DNA لإكمال هذا التمرين.

يتكوّن DNA من تسلسل طويل من مواد كيميائية أخرى، وأهمّها النيوكليوتيدات الأربعة: الأدينين والسيتوزين والغوانين والثايمين. يمكن أن يحتوي تسلسل DNA واحد على مليارات من هذه النيوكليوتيدات الأربعة، وترتيب ظهورها مهم! نسمّي ترتيب هذه النيوكليوتيدات في جزء من DNA «تسلسل DNA».

نمثّل تسلسل DNA كمجموعة مرتّبة من هذه النيوكليوتيدات الأربعة، والأسلوب الشائع لذلك هو استخدام سلسلة نصية من المحارف مثل «ATTACG» لتسلسل DNA مكوّن من 6 نيوكليوتيدات. حيث 'A' للأدينين، و'C' للسيتوزين، و'G' للغوانين، و'T' للثايمين.

بالنظر إلى سلسلة نصية تمثّل تسلسل DNA، احسب عدد كل نيوكليوتيد موجود فيها. إذا احتوت السلسلة النصية على محارف ليست A أو C أو G أو T، فهي غير صالحة، وعليك الإشارة إلى خطأ.

على سبيل المثال:

"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2
"INVALID" -> error

من الاستخدامات الشائعة لـ Either الإشارة إلى عملية حسابية قد ينتج عنها خطأ (وإذا لم يكن الخطأ الفعلي مهمًا، فقد يكون النوع الأبسط Option خيارًا أفضل). وعند غياب الخطأ تكون النتيجة عادةً Right (للتذكير: القيمة «الصحيحة»)، بينما يكون الخطأ Left، مثل Left[String] الذي يحمل رسالة خطأ. لاحظ أن Either في Scala 2.12 متحيّز إلى اليمين افتراضيًا، لذا يعمل كما هو متوقع مع عمليات مثل filter وmap وflatMap أو داخل for-comprehension. وإذا لم تكن على دراية بـ Either فيمكنك قراءة هذا الدرس التعليمي، لكن انتبه إلى أن هذا الدرس يتناول إصدارات Scala السابقة للإصدار 2.12. أما في Scala 2.12 فيمكنك تجاهل RightProjection وإسقاط .right بأمان. وEither هو ما يُعرف بـ الموناد، وهو يغطي «جانبًا حسابيًا»، وهنا معالجة الأخطاء. والاستخدام الصحيح للمونادات قد يُنتج كودًا موجزًا جدًا مع أنه أنيق ومقروء، أما الاستخدام الخاطئ فقد يؤدي بسهولة إلى العكس. شاهد هذا الفيديو لتتعلّم المزيد.

أخطاء شائعة يجب تجنّبها

هناك بعض القواعد العامة لـ Either:

  1. إذا لم تكن بحاجة إليه فلا تستخدمه. فبدلًا من
def add1(x: Int): Either[String, Int] = Right(x + 1)

من الأفضل أن تكتب

def add1(x: Int): Int = x + 1

(فهناك Either.map لتطبيق مثل هذه الدوال البسيطة، فلا حاجة إلى إثقالها بـ Either).

  1. لا «تفكّ» الغلاف إن لم تكن بحاجة حقيقية إلى ذلك. فغالبًا ما توجد دوال مدمجة تخدم غرضك. ومن مؤشرات فكّ الغلاف المتسرّع isLeft/isRight أو مطابقة الأنماط. فمثلًا، بدلًا من
val x: Either[String, Int] = ...

if (x.isRight) x.right.get + 1 else x.left.get
// or
x match {
  case Right(n) => n + 1
  case Left(s) => s
}

من الأفضل أن تكتب

x fold (identity, _ + 1)
  1. يمكن استخدام المونادات داخل for-comprehension، وهذا أمر رائع. وهذا مستحسن عندما تريد «تركيب» عدة نسخ من Either. فبدلًا من
val xo: Either[String, Int] = ...
val yo: Either[String, Int] = ...
val zo: Either[String, Int] = ...

xo.flatMap(x =>
  yo.flatMap(y =>
    zo.map(z =>
	    x + y + z)))

من الأفضل أن تكتب

for {
  x <- xo
  y <- yo
  z <- zo
} yield x + y + z
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Scala Exercism

مستعد لبدء عدّ النوكليوتيدات؟

سجّل في Exercism لتتعلّم وتتقن Scala عبر 95 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.