المسارات
/
Elixir
Elixir
/
التمارين
/
حاسبة المطبخ
حاسبة المطبخ

حاسبة المطبخ

تمرين تعلّمي

مقدمة

الصفوف

الصف في Elixir بنية بيانات تنظّم البيانات، وتحتوي على عدد ثابت من العناصر من أي نوع، لكن دون أسماء صريحة لكل عنصر. كثيرًا ما تُستخدم الصفوف في Elixir في العمليات كثيفة القراءة من الذاكرة، لأن الوصول للقراءة إلى عنصر ما عملية ذات زمن ثابت. وعادةً لا تُستخدم عندما قد يلزم إضافة العناصر أو حذفها ديناميكيًا، لأن الصف لا يُعدَّل، بل يُنشأ صف جديد يتطلب تخصيص الذاكرة مسبقًا.

عمليًا، تُنشأ الصفوف في Elixir باستخدام الأقواس المعقوفة. ويمكن الوصول إلى عناصر الصف كلٌّ على حدة باستخدام الدالة elem/2 بفهرسة تبدأ من الصفر:

empty_tuple = {}
one_element_tuple = {1}
multiple_element_tuple = {1, :a, "hello"}

elem(multiple_element_tuple, 2)
# => "hello"

الصفوف كمعلومات مجمّعة

كثيرًا ما تُستخدم الصفوف عمليًا لتمثيل معلومات مجمّعة.

Float.ratio(0.25)
# => {1, 4} indicating the numerator and denominator of the fraction ¼

مطابقة الأنماط

مطابقة الأنماط هي السائدة في كود Elixir الأصيل والحاسم. قد تتذكر أن =/2 يُوصف بأنه عامل مطابقة وليس عامل إسناد. وعند استخدام عامل المطابقة، إذا طابق النمط الموجود على اليسار الجانب الأيمن، تُربط أي متغيرات على اليسار، وتُرجَع قيمة الجانب الأيمن. ويُطلَق استثناء MatchError إذا لم تحدث مطابقة.

2 = 2
# => 2
# Literals can be matched if they are the same

2 = 3
# => ** (MatchError) no match of right hand side value: 3

{_, denominator} = Float.ratio(0.25)
# => {1, 4}
# the variable `denominator` is bound to the value 4

تذكّر أن المطابقات تحدث من الجانب الأيمن إلى الجانب الأيسر.

في المثال الأخير، إذا لم نحتج إلى متغير في مطابقة النمط، يمكننا التخلص منه بالإشارة إلى _. وأي متغير يبدأ بـ _ لا يتتبعه وقت التشغيل.

مطابقة الأنماط في الدوال المسماة

مطابقة الأنماط أداة مفيدة أيضًا عند إنشاء عدة بنود للدالة. ويمكن استخدام مطابقة الأنماط على وسائط الدوال، وهو ما يحدد بند الدالة الذي سيُنفَّذ، بدءًا من أعلى الملف نزولًا حتى أول مطابقة. وقد تُربط المتغيرات في رأس الدالة وتُستخدم في جسم الدالة.

defmodule Example do
  def named_function(:a = variable_a) do
    {variable_a, 1}
  end

  def named_function(:b = variable_b) do
    {variable_b, 2}
  end
end

Example.named_function(:a)
# => {:a, 1}

Example.named_function(:b)
# => {:b, 2}

Example.named_function(:c)
# => ** (FunctionClauseError) no function clause matching in Example.named_function/1

التعليمات

أثناء استعدادك لخبز البسكويت لأصدقائك، اكتشفت أنك بحاجة إلى تحويل بعض القياسات المستخدمة في الوصفة. وبما أنك لا تعرف سوى النظام المتري، فأنت بحاجة إلى إيجاد طريقة لتحويل قياسات الخبز الأمريكية الشائعة إلى ملليلترات (mL) لتسهيل الأمر عليك.

استخدم جدول التحويل التالي في حلّك:

الوحدة المراد تحويلها الحجم بالمليلتر (mL)
mL 1 1
كوب أمريكي 1 240
أونصة سائلة أمريكية 1 30
ملعقة صغيرة أمريكية 1 5
ملعقة كبيرة أمريكية 1 15

ولأنك مبرمج موهوب لا يزال في طور التدريب، تقرر استخدام الملليلترات كوحدة انتقالية لتسهيل التحويل من أي وحدة مدرجة إلى أي وحدة أخرى (حتى إلى نفسها).

1. الحصول على المكوّن العددي من زوج الحجم

نفّذ الدالة KitchenCalculator.get_volume/1. عند تمرير زوج حجم إليها، يجب أن تُرجع المكوّن العددي فقط.

KitchenCalculator.get_volume({:cup, 2.0})
# => 2.0

2. تحويل زوج الحجم إلى ملليلترات

نفّذ الدالة KitchenCalculator.to_milliliter/1. عند تمرير زوج حجم إليها، يجب أن تحوّل الحجم إلى ملليلترات باستخدام جدول التحويل.

استخدم عدة بنود للدالة ومطابقة الأنماط لإنشاء دوال لكل وحدة. الذرات المستخدمة للدلالة على كل وحدة هي: :cup، :fluid_ounce، :teaspoon، :tablespoon، :milliliter. ويجب أن تُرجع نتيجة التحويل ملفوفة في زوج.

KitchenCalculator.to_milliliter({:cup, 2.5})
# => {:milliliter, 600.0}

3. تحويل زوج الحجم بالمليلتر إلى وحدة أخرى

نفّذ الدالة KitchenCalculator.from_milliliter/2. عند تمرير زوج حجم والوحدة المطلوبة إليها، يجب أن تحوّل الحجم إلى الوحدة المطلوبة باستخدام جدول التحويل.

استخدم عدة بنود للدالة ومطابقة الأنماط لإنشاء دوال لكل وحدة. الذرات المستخدمة للدلالة على كل وحدة هي: :cup، :fluid_ounce، :teaspoon، :tablespoon، :milliliter

KitchenCalculator.from_milliliter({:milliliter, 1320.0}, :cup)
# => {:cup, 5.5}

4. التحويل من أي وحدة إلى أي وحدة

نفّذ الدالة KitchenCalculator.convert/2. عند تمرير زوج حجم والوحدة المطلوبة إليها، يجب أن تحوّل الحجم المعطى إلى الوحدة المطلوبة.

KitchenCalculator.convert({:teaspoon, 9.0}, :tablespoon)
# => {:tablespoon, 3.0}
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Elixir Exercism

مستعد لبدء حاسبة المطبخ؟

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