{
  "assessmentTests": {
    "python_test": {
      "name": "تست پایتون",
      "desc": "30 سؤال سناریویی درباره نحو، توابع، ساختارهای داده و رفتار اشیاء — مشخص کنید آیا دانش پایتون شما با آنچه یک آگهی شغلی منظور دارد تطابق دارد.",
      "recommendation": "پروفایل مهارت های پایتون شما",
      "results": {
        "beginner": {
          "name": "مبتدی",
          "desc": "شما می‌توانید یک اسکریپت کوتاه را دنبال کنید و مقادیر درون آن را تغییر دهید، اما سؤالاتی که از دست دادید حول رفتار خاص خود زبان متمرکز هستند نه منطق عمومی — یک آرگومان پیش‌فرض که یک بار ساخته می‌شود و در بین فراخوانی‌ها مجدداً استفاده می‌شود، is در مقابل == روی دو لیست مشابه، یک متغیر که همان لحظه محلی می‌شود که در هر جای تابع به آن مقدار نسبت داده شود. این موارد هیچ‌کدام درباره برنامه‌نویسی ضعیف نیست؛ این قوانین خاص پایتون هستند که افراد آمده از زبان‌های دیگر را به همان اندازه برنامه‌نویسان مبتدی سردرگم می‌کنند. در محل کار اهمیت دارند زیرا هرکدام جایی است که باگ در کدی که در نگاه اول صحیح به نظر می‌رسد، نهفته است.",
          "recommendation": "با سه چیز شروع کنید، به این ترتیب: آرگومان‌های پیش‌فرض تغییرپذیر (چرا basket=[] خطرناک است)، تفاوت بین is و ==، و نحوه کار دامنه متغیرها در یک تابع. مستندات رسمی پایتون در docs.python.org هر سه را مستقیماً پوشش می‌دهد، و عبارت «Python gotchas» نمونه‌های کار‌شده هرکدام را نشان می‌دهد."
        },
        "intermediate": {
          "name": "متوسط",
          "desc": "شما با برنامه‌نویسی روزمره راحت هستید — ساختارهای داده، جریان کنترل، توابع ساده — و در کار نگهداری روتین یا یک ویژگی کوچک روی یک کدبیس موجود کند نمی‌شوید. شکاف بین اینجا و سطح Advanced بیشتر درباره آنچه اتفاق می‌افتد وقتی ویژگی‌های راحتی پایتون با یکدیگر تعامل دارند: یک کپی سطحی که داده‌های تو‌در‌تو را مشترک ترک می‌کند وقتی انتظار داشتید تکراری شود، بازده یک generator که به‌آرامی بخشی از خروجی نمی‌شود، decorators که به ترتیبی انباشته می‌شوند که درک آن آسان است اشتباه می‌روند. این نوع باگ‌هایی است که یک بازبین ارشد در ده ثانیه پرچمی‌گذاری می‌کند و بقیه اوقات یک ساعت را تعقیب می‌کنند.",
          "recommendation": "روی داخلی‌های شیء و تکرار متمرکز شوید: کپی سطحی در مقابل کپی عمیق، آنچه یک generator واقعاً با return انجام می‌دهد، و نحوه کار ترتیب انباشتگی decorator. سپس اصول کلاس‌ای که اکثر آموزش‌ها از آنها می‌گذرند — برابری پیش‌فرض بدون __eq__، و چرا یک ویژگی کلاس تغییرپذیر در بین هر instance مشترک است."
        },
        "advanced": {
          "name": "پیشرفته",
          "desc": "این سطحی است که اکثر آگهی‌های شغلی منظور دارند با «پایتون قوی». شما برای ابزار درست بدون جستجو دست می‌برید، می‌دانید چرا یک بخش از state مشترک تغییر کرده نه فقط آنکه تغییر کرده، و می‌توانید تابع کسی دیگر را بخوانید و خروجی‌اش را به‌درستی پیش‌بینی کنید. آنچه این باند را از بالا جدا می‌کند سمت دفاعی کار است: دانستن اینکه کدام یک از دو رویکرد درست‌به‌نظر‌رسان وقتی یک ویژگی کلاس، یک آرگومان فقط‌به‌صورت‌کلیدی، یا یک سلسله‌مراتب استثنا درگیر است، بدرفتاری خواهد کرد.",
          "recommendation": "به بخش‌هایی وارد شوید که یک کدبیس محافظت می‌کنند که افراد دیگر نیز لمس می‌کنند: آرگومان‌های فقط‌به‌صورت‌کلیدی به‌عنوان یک انتخاب طراحی API بجای یک کنجکاوی نحوی، سلسله‌مراتب استثنا (بنابراین جملات except خانواده صحیح خطا را می‌گیرند، نه فقط یک کلاس)، و context managers به‌عنوان روش استاندارد تضمین cleanup. مقالات عمیق Real Python نقطه شروع خوبی برای هر سه هستند."
        },
        "expert": {
          "name": "متخصص",
          "desc": "شما در بالاترین نقطه هر بخش — نحو اصلی، توابع و دامنه، ساختارهای داده، و اصطلاحات شیء‌گرا — امتیاز دادید. در عمل، این بدان معناست که می‌توانید یک فایل غریبه را دریافت کنید و توضیح دهید چرا خروجی‌ای را تولید می‌کند، نه فقط آنکه نحو چه می‌گویند باید انجام دهد، که مهارت سخت‌تر و ارزشمندتر است. در این سطح زبان خام به‌ندرت عامل محدود‌کننده در کار شما است؛ محدودیت معمولاً سایز یا شکل سیستم اطراف کد است.",
          "recommendation": "اکنون بازگشت‌ها در ابزارها و بازبین هستند: بررسی نوع استاتیکی با mypy یا pyright، پروفایل کردن قبل از بهینه‌سازی بجای حدس، و خواندن pull requestهای دیگر برای دقیقاً این دسته از باگ — آن‌هایی که هر تست را پاس می‌کنند و هنوز کار اشتباه را تحت یک ورودی خاص انجام می‌دهند. اگر برای نقش غربالگری می‌شوید، باگی مانند این را توصیف کنید که پیدا کردید بجای نام‌بردن ویژگی‌های زبان — استدلال را نشان می‌دهد، نه فقط واژگان."
        }
      },
      "questions": [
        {
          "question": "شما def add_item(item, basket=[]): basket.append(item); return basket را می‌نویسید، سپس add_item('a') و add_item('b') را فراخوانی می‌کنید، هر دو بار basket را حذف می‌کنید. فراخوانی دوم چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "['b'] — هر فراخوانی یک لیست خالی تازه‌ای به‌عنوان پیش‌فرض می‌گیرد"
            },
            {
              "icon": "",
              "label": "TypeError — شما باید آرگومان basket را فراهم کنید"
            },
            {
              "icon": "",
              "label": "['a', 'b'] — لیست پیش‌فرض یک بار ساخته می‌شود و در بین فراخوانی‌ها مجدداً استفاده می‌شود"
            },
            {
              "icon": "",
              "label": "['a'] سپس ['b'] به‌عنوان دو لیست منفرد مستقل"
            }
          ]
        },
        {
          "question": "a = [1, 2, 3] و b = [1, 2, 3]. a == b چه برمی‌گرداند، و a is b چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "True برای هردو — لیست‌های یکسان همیشه یک شیء هستند"
            },
            {
              "icon": "",
              "label": "True برای ==، False برای is — محتویات برابر اما اشیاء متفاوت در حافظه"
            },
            {
              "icon": "",
              "label": "False برای هردو — لیترال‌های جدا هرگز در پایتون برابر نیستند"
            },
            {
              "icon": "",
              "label": "True برای is، False برای == — is برابری مقدار را برای لیست‌ها بررسی می‌کند"
            }
          ]
        },
        {
          "question": "در Python 3، 7 / 2 به چه تقدیر حاصل می‌شود، و 7 // 2 به چه تقدیر حاصل می‌شود؟",
          "options": [
            {
              "icon": "",
              "label": "3.5، سپس 3 — / همیشه float برمی‌گرداند، // نتیجه را floor می‌کند"
            },
            {
              "icon": "",
              "label": "3، سپس 3.5 — / truncate می‌کند و // float برمی‌گرداند"
            },
            {
              "icon": "",
              "label": "3.5، سپس 3.5 — هردو عملگر در Python 3 float برمی‌گردانند"
            },
            {
              "icon": "",
              "label": "3، سپس 3 — هردو عملگر نتیجه را در Python 3 floor می‌کنند"
            }
          ]
        },
        {
          "question": "s = 'hello'، سپس s[0] = 'H' را اجرا می‌کنید. چه اتفاقی می‌افتد؟",
          "options": [
            {
              "icon": "",
              "label": "s به‌عنوان 'Hello' تبدیل می‌شود"
            },
            {
              "icon": "",
              "label": "s به‌عنوان 'Hhello' تبدیل می‌شود زیرا کاراکتر درج می‌شود، جایگزین نمی‌شود"
            },
            {
              "icon": "",
              "label": "TypeError — رشته‌ها تغییرناپذیر هستند و از تخصیص item پشتیبانی نمی‌کنند"
            },
            {
              "icon": "",
              "label": "چیزی نیست — تخصیص به‌آرامی نادیده گرفته می‌شود و s به‌عنوان 'hello' باقی می‌ماند"
            }
          ]
        },
        {
          "question": "x = [10, 20, 30, 40, 50]. x[1:4] چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "[20, 30, 40, 50]"
            },
            {
              "icon": "",
              "label": "[10, 20, 30, 40]"
            },
            {
              "icon": "",
              "label": "[20, 30, 40]"
            },
            {
              "icon": "",
              "label": "[30, 40]"
            }
          ]
        },
        {
          "question": "name = 'Ana' و age = 30. f'{name} is {age}' چه تولید می‌کند؟",
          "options": [
            {
              "icon": "",
              "label": "{name} is {age}"
            },
            {
              "icon": "",
              "label": "Ana is 30"
            },
            {
              "icon": "",
              "label": "name is age"
            },
            {
              "icon": "",
              "label": "TypeError، زیرا f-strings نیاز به روش format() دارند"
            }
          ]
        },
        {
          "question": "1 < 2 < 3 به چه تقدیر حاصل می‌شود؟",
          "options": [
            {
              "icon": "",
              "label": "True — پایتون مقایسه‌ها را به‌صورت (1 < 2) and (2 < 3) زنجیره‌ای می‌کند"
            },
            {
              "icon": "",
              "label": "False — مقایسه‌های زنجیره‌ای از چپ به راست بدون کوتاه‌کردن ارزیابی می‌شوند، 1 < 2 < 3 -> 1 < True -> False می‌دهد"
            },
            {
              "icon": "",
              "label": "SyntaxError — مقایسه‌ها نمی‌توانند زنجیره‌ای باشند"
            },
            {
              "icon": "",
              "label": "3 — پایتون آخرین مقدار در زنجیره را برمی‌گرداند"
            }
          ]
        },
        {
          "question": "bool([]) چه برمی‌گرداند، و bool([0]) چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "False، سپس False — هر لیست‌ای که فقط شامل مقادیر falsy باشد، falsy است"
            },
            {
              "icon": "",
              "label": "False، سپس True — لیست خالی falsy است، لیست‌ای که شامل یک عنصر باشد (حتی 0) truthy است"
            },
            {
              "icon": "",
              "label": "True، سپس True — اشیایی که None نیستند همیشه truthy هستند"
            },
            {
              "icon": "",
              "label": "True، سپس False — لیست فقط وقتی خالی است truthy است"
            }
          ]
        },
        {
          "question": "یک count = 0 در سطح ماژول وجود دارد. درون def increment(): count += 1; return count، شما increment() را فراخوانی می‌کنید. چه اتفاقی می‌افتد؟",
          "options": [
            {
              "icon": "",
              "label": "UnboundLocalError — تخصیص به count در هر جای تابع آن را محلی می‌کند، بنابراین count += 1 سعی می‌کند یک متغیر محلی را قبل از تخصیص بخواند"
            },
            {
              "icon": "",
              "label": "1 را برمی‌گرداند و count سطح ماژول را به 1 افزایش می‌دهد"
            },
            {
              "icon": "",
              "label": "1 را برمی‌گرداند اما count سطح ماژول را در 0 می‌ماند"
            },
            {
              "icon": "",
              "label": "NameError را ایجاد می‌کند زیرا count هرگز درون تابع اعلان نشده است"
            }
          ]
        },
        {
          "question": "def f(*args, **kwargs): return args, kwargs. f(1, 2, x=3) چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "([1, 2], {'x': 3})"
            },
            {
              "icon": "",
              "label": "((1, 2), {'x': 3})"
            },
            {
              "icon": "",
              "label": "(1, 2, {'x': 3})"
            },
            {
              "icon": "",
              "label": "TypeError — آرگومان‌های موضعی و کلیدی نمی‌توانند در یک فراخوانی مخلوط شوند"
            }
          ]
        },
        {
          "question": "شما funcs = [lambda: i for i in range(3)] را در یک حلقه ساخته‌اید. [f() for f in funcs] چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "[2, 2, 2] — هر lambda وقتی فراخوانی شود i را جستجو می‌کند، و در آن زمان حلقه با i برابر 2 تمام شده است"
            },
            {
              "icon": "",
              "label": "[0, 1, 2] — هر lambda مقدار i را در زمان ایجاد آن ضبط می‌کند"
            },
            {
              "icon": "",
              "label": "[0, 0, 0] — lambdas همیشه اولین مقدار اختصاص داده شده به یک متغیر را ضبط می‌کنند"
            },
            {
              "icon": "",
              "label": "NameError، زیرا i بعد از پایان حلقه دیگر وجود ندارد"
            }
          ]
        },
        {
          "question": "یک تابع با @a مستقیماً بالای @b تعریف می‌شود، که مستقیماً بالای def f(): pass قرار دارد. decorators به f در چه ترتیبی اعمال می‌شوند؟",
          "options": [
            {
              "icon": "",
              "label": "b ابتدا f را پیچش می‌دهد، سپس a نتیجه b را پیچش می‌دهد — decorator نزدیک‌تر به تابع ابتدا اجرا می‌شود"
            },
            {
              "icon": "",
              "label": "a ابتدا f را پیچش می‌دهد، سپس b نتیجه را پیچش می‌دهد — decorators از بالا به پایین اعمال می‌شوند"
            },
            {
              "icon": "",
              "label": "هردو decorator به‌طور مستقل f را پیچش می‌دهند و تنها آخرین یک تعریف‌شده تأثیر می‌گذارد"
            },
            {
              "icon": "",
              "label": "این بستگی به ترتیب import decorators دارد، نه موقعیتشان در کد"
            }
          ]
        },
        {
          "question": "def f(a, *, b): return a + b. کدام یک از این فراخوانی‌ها کار می‌کند؟",
          "options": [
            {
              "icon": "",
              "label": "f(1, b=2) — b باید با کلید پاس داده شود زیرا بعد از bare * در signature قرار دارد"
            },
            {
              "icon": "",
              "label": "f(1, 2) — آرگومان‌های موضعی پارامترها را از چپ به راست پر می‌کنند صرف‌نظر از *"
            },
            {
              "icon": "",
              "label": "f(a=1, 2) — آرگومان‌های کلیدی باید ابتدا بیایند"
            },
            {
              "icon": "",
              "label": "f(1) — b اختیاری است زیرا بعد از * می‌آید"
            }
          ]
        },
        {
          "question": "یک generator function 1 را yield می‌کند، سپس 2 را yield می‌کند، سپس return 99 انجام می‌دهد. list(the_generator()) چه شامل می‌شود، و 99 با چه اتفاقی می‌افتد؟",
          "options": [
            {
              "icon": "",
              "label": "[1, 2, 99] — return درون یک generator مانند یک yield دیگر است"
            },
            {
              "icon": "",
              "label": "[99] — return بلافاصله مقادیر از قبل yield‌شده را لغو می‌کند"
            },
            {
              "icon": "",
              "label": "[1, 2] — بازده یک generator مقدار پیوست‌شده به StopIteration که ایجاد می‌کند می‌شود، yield نمی‌شود"
            },
            {
              "icon": "",
              "label": "RuntimeError، زیرا generators نمی‌توانند حاوی دستور return باشند"
            }
          ]
        },
        {
          "question": "در یک outer() تابع، x = 1 تنظیم می‌شود، سپس یک nested inner() آن nonlocal x; x += 1 انجام می‌دهد، و outer() قبل از برگرداندن x، inner() را فراخوانی می‌کند. outer() چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "1 — inner() روی یک کپی محلی خود x کار می‌کند، بنابراین تغییر ماندگار نیست"
            },
            {
              "icon": "",
              "label": "UnboundLocalError، زیرا x قبل از دستور nonlocal درون inner() اعلان نشده است"
            },
            {
              "icon": "",
              "label": "SyntaxError — nonlocal تنها می‌تواند درون کلاس‌ها استفاده شود"
            },
            {
              "icon": "",
              "label": "2 — nonlocal اجازه می‌دهد inner() x تابع خارجی را اصلاح کند بجای ایجاد یک متغیر محلی جدید"
            }
          ]
        },
        {
          "question": "d = {'a': 1, 'b': 2}. d.get('c', 0) چه برمی‌گرداند، و آیا 'c' را به فرهنگ اضافه می‌کند؟",
          "options": [
            {
              "icon": "",
              "label": "0، و نه — get() پیش‌فرض را بدون درج کلید برمی‌گرداند"
            },
            {
              "icon": "",
              "label": "0، و بله — get() کلید را با مقدار پیش‌فرض درج می‌کند"
            },
            {
              "icon": "",
              "label": "KeyError، زیرا 'c' وجود ندارد"
            },
            {
              "icon": "",
              "label": "None، و بله — get() همیشه کلیدهای گمشده را با مقدار None اضافه می‌کند"
            }
          ]
        },
        {
          "question": "t = (1, 2, [3, 4]). آیا می‌توانید t[2].append(5) را اجرا کنید، و آیا می‌توانید t[0] = 10 را اجرا کنید؟",
          "options": [
            {
              "icon": "",
              "label": "هردو کار می‌کند — تو درتو کردن یک لیست درون یک tuple کل tuple را تغییرپذیر می‌کند"
            },
            {
              "icon": "",
              "label": "هردو TypeError ایجاد می‌کند — هیچ‌چیزی درون یک tuple هرگز نمی‌تواند تغییر کند"
            },
            {
              "icon": "",
              "label": "t[2].append(5) TypeError ایجاد می‌کند، اما t[0] = 10 کار می‌کند زیرا tuples اجازه بازنسازی عنصر اول خود را می‌دهند"
            },
            {
              "icon": "",
              "label": "t[2].append(5) کار می‌کند زیرا لیست درون تغییرپذیر است؛ t[0] = 10 TypeError ایجاد می‌کند زیرا خود tuple تغییرناپذیر است"
            }
          ]
        },
        {
          "question": "کدام یک از این‌ها یک iterator برمی‌گرداند که مقادیر را به‌آرامی محاسبه می‌کند بجای ساخت تمام دنباله در حافظه: [x*x for x in range(1000000)] یا (x*x for x in range(1000000))؟",
          "options": [
            {
              "icon": "",
              "label": "آن‌ای با پرانتز، (x*x for x in range(1000000)) — این یک generator expression است"
            },
            {
              "icon": "",
              "label": "آن‌ای با bracket — list comprehensions همیشه به‌آرامی در Python 3 هستند"
            },
            {
              "icon": "",
              "label": "هردو به‌آرامی هستند — تنها تفاوت نوع برگردانده‌شده در انتها است"
            },
            {
              "icon": "",
              "label": "هیچ‌کدام — هردو دنباله کامل را بلافاصله در حافظه می‌سازند"
            }
          ]
        },
        {
          "question": "یک try block تقسیم بر صفر انجام می‌دهد، جملهٔ except ZeroDivisionError 'a' را چاپ می‌کند، و جملهٔ finally 'b' را چاپ می‌کند. چه چاپ می‌شود، و به چه ترتیب؟",
          "options": [
            {
              "icon": "",
              "label": "b سپس a — finally همیشه قبل از هر جملهٔ except اجرا می‌شود"
            },
            {
              "icon": "",
              "label": "a سپس b — جملهٔ except منطبق ابتدا اجرا می‌شود، و finally همیشه بعد‌اً صرف‌نظر از اینکه اجرا می‌شود"
            },
            {
              "icon": "",
              "label": "تنها b — استثنا واقعاً گرفتار نمی‌شود، بنابراین 'a' هرگز چاپ نمی‌شود"
            },
            {
              "icon": "",
              "label": "تنها a — finally یک بار استثنا قبلاً مدیریت شده است نادیده گرفته می‌شود"
            }
          ]
        },
        {
          "question": "import copy; a = [[1, 2], [3, 4]]; b = copy.copy(a); b[0].append(99). آیا a[0] نیز تغییر می‌کند؟",
          "options": [
            {
              "icon": "",
              "label": "نه — copy.copy() همیشه اشیای تو درتو را نیز تکرار می‌کند"
            },
            {
              "icon": "",
              "label": "نه — append کردن به b[0] یک لیست کاملاً جدید برای تنها b[0] ایجاد می‌کند"
            },
            {
              "icon": "",
              "label": "بله، اما فقط زیرا copy.copy() بدون آرگومان deepcopy فراخوانی شد"
            },
            {
              "icon": "",
              "label": "بله — copy.copy() یک shallow copy می‌سازد، بنابراین لیست‌های تو درتو هنوز بین a و b مشترک هستند"
            }
          ]
        },
        {
          "question": "d = {'x': 1, 'y': 2}. آیا 'x' in d علیه کلیدها، مقادیر، یا هردو بررسی می‌کند؟",
          "options": [
            {
              "icon": "",
              "label": "مقادیر — `in` بررسی می‌کند که 1 یا 2 برابر 'x' هستند"
            },
            {
              "icon": "",
              "label": "هردو کلیدها و مقادیر بررسی می‌شوند"
            },
            {
              "icon": "",
              "label": "هیچ‌کدام — `in` روی یک dict همیشه TypeError ایجاد می‌کند"
            },
            {
              "icon": "",
              "label": "کلیدها — `in` روی یک فرهنگ عضویت بین کلیدهایش را بررسی می‌کند، نه مقادیرش"
            }
          ]
        },
        {
          "question": "names = ['Al', 'Bo'] و scores = [10, 20]. list(zip(names, scores)) چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "[('Al', 'Bo'), (10, 20)]"
            },
            {
              "icon": "",
              "label": "['Al', 10, 'Bo', 20]"
            },
            {
              "icon": "",
              "label": "[('Al', 10), ('Bo', 20)]"
            },
            {
              "icon": "",
              "label": "ValueError، زیرا zip به سه یا بیشتر آرگومان نیاز دارد"
            }
          ]
        },
        {
          "question": "class Dog: tricks = [] یک لیست سطح کلاس نگه می‌دارد، و add_trick به self.tricks اضافه می‌کند. d1 = Dog() و d2 = Dog() هردو ایجاد می‌شوند، سپس d1.add_trick('sit') اجرا می‌شود. d2.tricks چه شامل می‌شود؟",
          "options": [
            {
              "icon": "",
              "label": "[] — هر instance کپی مستقل خود tricks را می‌گیرد"
            },
            {
              "icon": "",
              "label": "['sit'] — tricks یک لیست سطح کلاس است که توسط هر instance مشترک است، بنابراین تغییر d1 روی d2 نیز قابل‌مشاهده است"
            },
            {
              "icon": "",
              "label": "TypeError — instances نمی‌توانند به یک ویژگی کلاس اضافه کنند"
            },
            {
              "icon": "",
              "label": "['sit'] تنها بعد از بازاجرای d2 = Dog()"
            }
          ]
        },
        {
          "question": "class A دارای def greet(self): return 'A' است. class B(A) دارای def greet(self): return 'B' + super().greet() است. B().greet() چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "'AB' — super() همیشه قبل از کد خود subclass اجرا می‌شود"
            },
            {
              "icon": "",
              "label": "'B' — super().greet() نادیده گرفته می‌شود زیرا B قبلاً greet را override می‌کند"
            },
            {
              "icon": "",
              "label": "'BA' — super().greet() روش A را فراخوانی می‌کند و نتیجه‌ای آن به 'B' الحاق می‌شود"
            },
            {
              "icon": "",
              "label": "AttributeError، زیرا A روش greet قابل‌دسترسی به B ندارد"
            }
          ]
        },
        {
          "question": "class Point، self.x را در __init__ ذخیره می‌کند و روش دیگری تعریف نمی‌کند. p1 = Point(1) و p2 = Point(1). به‌طور پیش‌فرض p1 == p2 چه برمی‌گرداند؟",
          "options": [
            {
              "icon": "",
              "label": "True — پایتون به‌طور پیش‌فرض تمام ویژگی‌های منطبق را مقایسه می‌کند"
            },
            {
              "icon": "",
              "label": "False — بدون یک __eq__ custom، == به مقایسه identity بازمی‌گردد، و p1 و p2 اشیای متفاوت هستند"
            },
            {
              "icon": "",
              "label": "True، اما تنها زیرا هردو شیء با یک آرگومان یکسان ایجاد شدند"
            },
            {
              "icon": "",
              "label": "TypeError، زیرا Point __eq__ را تعریف نمی‌کند"
            }
          ]
        },
        {
          "question": "کدام جملهٔ except زیر نیز یک ZeroDivisionError را می‌گیرد: except ArithmeticError، except ValueError، یا except KeyError؟",
          "options": [
            {
              "icon": "",
              "label": "except ValueError — خطاهای division به‌عنوان مقادیر نامعتبر در نظر گرفته می‌شوند"
            },
            {
              "icon": "",
              "label": "except KeyError — هر خطای runtime نه‌ای که به یک نوع خاص گره خورده است به KeyError برمی‌گردد"
            },
            {
              "icon": "",
              "label": "هیچ‌کدام — تنها except ZeroDivisionError خود می‌تواند آن را بگیرد"
            },
            {
              "icon": "",
              "label": "except ArithmeticError — ZeroDivisionError یک subclass ArithmeticError است"
            }
          ]
        },
        {
          "question": "شما یک فایل را با open('data.txt') as f: باز می‌کنید و یک استثنا هنگام خواندن درون block ایجاد می‌شود. آیا فایل هنوز بسته می‌شود؟",
          "options": [
            {
              "icon": "",
              "label": "نه — فایل باز می‌ماند زیرا block به‌طور معمولی تمام نشد"
            },
            {
              "icon": "",
              "label": "تنها اگر شما نیز یک جملهٔ finally دور with statement اضافه کنید"
            },
            {
              "icon": "",
              "label": "بله — with statement روش __exit__ فایل را فراخوانی می‌کند، که آن را می‌بندد، حتی اگر یک استثنا درون block رخ دهد"
            },
            {
              "icon": "",
              "label": "این بستگی به نوع استثنا دارد — تنها استثناهای گرفتار‌شده در جای دیگر cleanup را تریگر می‌کنند"
            }
          ]
        },
        {
          "question": "x = [3, 1, 2] و y = x.sort(). y چه نگه می‌دارد؟",
          "options": [
            {
              "icon": "",
              "label": "[1, 2, 3] — sort() لیست مرتب‌شده تازه‌ای را برمی‌گرداند"
            },
            {
              "icon": "",
              "label": "None — list.sort() در جای خود مرتب می‌کند و None برمی‌گرداند؛ خود x به‌عنوان [1, 2, 3] تبدیل می‌شود"
            },
            {
              "icon": "",
              "label": "[3, 1, 2] — sort() لیست اصلی نامرتب‌شده را برمی‌گرداند و تنها ترتیب درونی x را تغییر می‌دهد"
            },
            {
              "icon": "",
              "label": "TypeError، زیرا sort() نمی‌تواند به یک متغیر نسبت داده شود"
            }
          ]
        },
        {
          "question": "وقتی 'Score: ' + 42 را اجرا می‌کنید چه اتفاقی می‌افتد؟",
          "options": [
            {
              "icon": "",
              "label": "'Score: 42' — پایتون عدد را به‌طور خودکار درون یک عبارت + تبدیل می‌کند"
            },
            {
              "icon": "",
              "label": "'Score: ' — عدد به‌آرامی حذف می‌شود"
            },
            {
              "icon": "",
              "label": "42 — رشته به یک عدد تبدیل می‌شود و اضافه می‌شود"
            },
            {
              "icon": "",
              "label": "TypeError — نمی‌توانید یک str و int را مستقیماً الحاق کنید، 42 باید با str() ابتدا تبدیل شود"
            }
          ]
        },
        {
          "question": "شما باید بررسی کنید که یک لیست به‌نام results خالی است. کدام یک روش idiom پایتون است: if results == []: ، if len(results) == 0: ، یا if not results: ؟",
          "options": [
            {
              "icon": "",
              "label": "if results == []: — این تنها راه معتبر برای تشخیص لیست خالی است"
            },
            {
              "icon": "",
              "label": "if len(results) == 0: — این لازم است زیرا لیست‌های خالی در پایتون truthy هستند"
            },
            {
              "icon": "",
              "label": "هر سه هرگز در عمل استفاده نمی‌شوند؛ رویکرد استاندارد if results is None: است"
            },
            {
              "icon": "",
              "label": "if not results: — idiom پایتون روی truthiness تکیه دارد، و لیست خالی falsy است"
            }
          ]
        }
      ],
      "optionOrderVersion": "92945565db6c55da"
    }
  }
}
