مسیرها
/
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)
میلی‌لیتر ۱ ۱
پیمانه‌ی آمریکایی ۱ ۲۴۰
اونس مایع آمریکایی ۱ ۳۰
قاشق چای‌خوری آمریکایی ۱ ۵
قاشق غذاخوری آمریکایی ۱ ۱۵

چون برنامه‌نویسی مستعد و در حال آموزش هستید، تصمیم می‌گیرید میلی‌لیتر را به عنوان واحد واسط به کار ببرید تا تبدیل از هر واحد فهرست‌شده به واحد دیگر (حتی به خودش) آسان‌تر شود.

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 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.