مسیرها
/
jq
jq
/
تمرین‌ها
/
خرید خودرو
خرید خودرو

خرید خودرو

تمرین یادگیری

مقدمه

مقایسه

مقایسه‌ی اعداد

در jq می‌توان اعداد را با عملگرهای رابطه‌ای و برابری زیر مقایسه کرد.

مقایسه عملگر
بزرگ‌تر از a > b
بزرگ‌تر یا مساوی a >= b
کوچک‌تر از a < b
کوچک‌تر یا مساوی a <= b
مساوی a == b
نامساوی a != b

نتیجه‌ی مقایسه همیشه یک مقدار منطقی است، یعنی یا true یا false.

1 < 3,      # => true
2 != 2,     # => false
1 == 1.0    # => true
            # All numbers are floating-points, so this is different syntax
            # for the exact same value.

مقایسه‌ی رشته‌ها

از عملگرهای مقایسه‌ی بالا می‌توان برای مقایسه‌ی رشته‌ها هم استفاده کرد. در این حالت، ترتیبی واژه‌نامه‌ای (لغت‌نامه‌ای) اعمال می‌شود. این ترتیب بر اساس مقدار کدپوینت یونیکد است.

"Apple" > "Pear",   # => false
"a" < "above",      # => true
"a" == "A"          # => false

وقتی دو متغیری را مقایسه می‌کنید که به نظر می‌رسد مقدار عددی دارند اما از نوع رشته‌اند، باید مراقب باشید. به دلیل ترتیب واژه‌نامه‌ای، نتیجه با مقایسه‌ی مقادیر از نوع عدد یکسان نخواهد بود.

10 < 2,     # => false
"10" < "2"  # => true (because "1" comes before "2")

برابری «سخت‌گیرانه»

عملگر == در jq شبیه === در JavaScript است، به این معنا که مقادیری که «شبیه» هم به نظر می‌رسند اما از نوع‌های متفاوتی هستند، برابر نیستند.

"3" == 3    # => false
            # the value on the left has type string,
            # the value on the right has type number.

مقایسه‌ی آرایه‌ها

دو آرایه زمانی برابرند که همه‌ی عناصر متناظرشان برابر باشند.

[1, 2, 3] == [1, 2, 3]      # => true
[1, 2, 3] == [1, 3, 2]      # => false, different order
[1, 2, 3] == [1, 2, "3"]    # => false, different types

مقایسه‌ی اشیا

دو شیء زمانی برابرند که جفت‌های کلید-مقدار یکسانی داشته باشند.

{name: "Joe", age: 42} == {age: 42, name: "Joe"}                # => true
{name: "Joe", age: 42} == {age: 42, name: "Jane"}               # => false
{name: "Joe", age: 42} == {age: "42", name: "Joe"}              # => false
{name: "Joe", age: 42} == {age: 42, name: "Joe", height: 175}   # => false

# comparisons will drill down as deeply as required
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2]}}}                  # => true
{a: {b: {c: [1, 2]}}} == {a: {b: {c: [1, 2, 3]}}}               # => false

شرط‌ها

عبارت if

عبارت شرطی در jq به شکل if A then B else C end است.

if-then-else مانند همه‌ی توابع درونی jq یک «فیلتر» است: ورودی می‌گیرد و خروجی تولید می‌کند.

اگر عبارت A مقداری «درست‌نما» تولید کند، فیلتر if عبارت B را ارزیابی می‌کند. در غیر این صورت C را ارزیابی می‌کند. ورودی فیلتر if به B یا C داده می‌شود.

42 | if . < 50 then "small" else "big" end      # => "small"
5 | if . % 2 == 0 then . / 2 else . * 4 end     # => 20
Note

بند else اختیاری است؛ دو دستور زیر معادل یکدیگرند.

if A then B else . end
if A then B end

دستورهای if تودرتو

با elif می‌توان شرط‌های بیشتری افزود.

42 | if . < 33 then "small"
     elif . < 66 then "medium"
     else "big"
     end
# => "medium"

هر تعداد بند elif که لازم دارید استفاده کنید.

درست‌نمایی

تنها مقادیر «غلط» در jq این‌ها هستند: false و null. همه‌ی مقادیر دیگر «درست» هستند، حتی عدد صفر و رشته‌ی خالی، آرایه‌ی خالی و شیء خالی.

عملگرهای منطقی

از عملگرهای منطقی and و or می‌توان برای ساختن کوئری‌های پیچیده استفاده کرد.

42 | if . < 33 or . > 66 then "big or small"
     else "medium"
     end

برای نقیض کردن، از not استفاده کنید. این یک فیلتر است، نه یک عملگر.

42 | if (. < 33 or . > 66 | not) then "medium"
     else "big or small"
     end

عملگر جایگزین

عملگر جایگزین به شما امکان می‌دهد در صورتی که یک عبارت false یا null باشد، یک مقدار «پیش‌فرض» تعیین کنید.

A // B

# This is identical to
if A then A else B end

برای نمونه:

[3, 5, 18] | add / 2       # => 13
[]         | add / 2       # => error: null (null) and number (2) cannot be divided
[]         | add // 0 / 2  # => 0

دستورالعمل‌ها

در این تمرین، کدی می‌نویسید که به شما در آماده شدن برای خرید خودرو کمک می‌کند.

سه کار پیش رو دارید: تعیین کنید که آیا به گواهینامه نیاز دارید؛ بین دو خودرو انتخاب کنید؛ و قیمت منصفانه‌ی یک خودروی دست‌دوم را تخمین بزنید.

1. تعیین کنید که آیا به گواهینامه‌ی رانندگی نیاز دارید

برخی از انواع خودروها برای راندن به گواهینامه‌ی رانندگی نیاز دارند. فرض کنید فقط انواع "car" و "truck" به گواهینامه نیاز دارند؛ بقیه را می‌توان بدون گواهینامه راند.

تابع needs_license را پیاده‌سازی کنید که نوع خودرو را می‌گیرد و یک مقدار «منطقی» برمی‌گرداند که نشان می‌دهد آیا برای آن نوع خودرو به گواهینامه نیاز دارید یا نه.

"car" | needs_license
# => true

"bike" | needs_license
# => false

2. انتخاب بین دو خودرویی که می‌توانید بخرید

گزینه‌های خودروهای در دسترس را بررسی کرده‌اید. توانسته‌اید آن‌ها را به دو گزینه محدود کنید، اما برای گرفتن تصمیم نهایی به کمک نیاز دارید. تابع choose_vehicle را پیاده‌سازی کنید که آرایه‌ای از دو خودرو را به‌عنوان ورودی می‌گیرد و یک تصمیم را برمی‌گرداند: گزینه‌ای که در ترتیب واژه‌نامه‌ای اول می‌آید.

["Wuling Hongguang", "Toyota Corolla"] | choose_vehicle
# =>  "Toyota Corolla is clearly the better choice."

["Volkswagen Beetle", "Volkswagen Golf"] | choose_vehicle
# =>  "Volkswagen Beetle is clearly the better choice."

3. تخمین قیمت یک خودروی دست‌دوم را محاسبه کنید

حالا که تصمیم‌تان را گرفته‌اید، می‌خواهید مطمئن شوید که در نمایندگی خودرو را با قیمت منصفانه می‌خرید. چون می‌خواهید یک خودروی دست‌دوم بخرید، قیمت به سن خودرو بستگی دارد. برای یک تخمین تقریبی، فرض کنید اگر خودرو کمتر از ۳ سال سن داشته باشد، قیمتش ۸۰٪ قیمت اصلی آن هنگام نو بودن است. اگر بیش از ۱۰ سال سن داشته باشد، ۵۰٪. اگر خودرو حداقل ۳ سال سن داشته باشد اما بیشتر از ۱۰ سال نباشد، ۷۰٪ قیمت اصلی است.

تابع resell_price را پیاده‌سازی کنید که این منطق را با استفاده از if، elif و else اعمال می‌کند. این تابع شیئی را می‌گیرد که قیمت اصلی و سن خودرو را در خود دارد و قیمت تخمینی در نمایندگی را برمی‌گرداند.

{"original_price": 1000, "age": 1} | resell_price
# => 800

{"original_price": 1000, "age": 5} | resell_price
# => 700

{"original_price": 1000, "age": 15} | resell_price
# => 500
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
jq Exercism

آماده‌اید خرید خودرو را شروع کنید؟

در Exercism ثبت‌نام کنید تا jq را همراه با 12 مفهوم75 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.