منطق ایجنت‌ها › M4 — مرزها و راستی‌آزمایی
۴.۵ پایدار تدریسی ~۴۰ دقیقه

راستی‌آزمایی وقتی کد بلد نیستی

قبل از این فصل: فصل ۴.۴

در یک نگاه

۴.۵.۱

چرا خروجی را نباید باور کرد

در فصل ۴.۴ دیدیم سه حالت شکست بی‌صدا هستند. یعنی اگر فعالانه نگردی، پیدایشان نمی‌کنی.

و مشکل عمیق‌تری هم هست: خروجیِ مرتب، حسِ درستی می‌دهد. جدولِ منظم و لحنِ مطمئن باعث می‌شوند مغز آدم بررسی را رها کند — همان چیزی که در فصل ۰.۲ گفتیم، «خواندن با حالتِ تحسین به‌جای حالتِ بازبینی».

پس قاعده‌ی این فصل: خروجی را با «چقدر خوب به نظر می‌رسد» نسنج. با «چه چیزی را باید درست انجام می‌داد و آیا داد» بسنج.

و خبر خوب: هیچ‌یک از چهار روش این فصل، کد خواندن لازم ندارد. همه‌شان روی خروجی کار می‌کنند، نه روی راهی که به آن رسیده.

۴.۵.۲

روش ۱: ورودی‌ای که جوابش را می‌دانی

قوی‌ترین روش، و ساده‌ترین. یک نمونه بردار که جوابش را از قبل می‌دانی — چون خودت دستی حسابش کرده‌ای، یا از دفعه‌ی قبل داری‌اش.

اگر روی آن نمونه جوابِ درست را داد، به بقیه اعتماد بیشتری می‌کنی. اگر نداد، همان‌جا فهمیدی — قبل از اینکه روی داده‌ی واقعی اجرا کنی.

و این دقیقاً همان چیزی است که در فصل ۲.۴.۳ برای تعریف «تمام شد» ساختیم. اگر آن spec را نوشته باشی، این آزمون از قبل آماده است.

معیار یک نمونه‌ی خوب — و منبع رسمی هم همین را می‌گوید: معیار موفقیت باید مشخص و قابل‌اندازه‌گیری باشد، نه «عملکرد خوب». پس:

و از همان منبع، یک قاعده‌ی مهم: آزمون‌ها را طوری بساز که کارِ واقعی را بازتاب دهند — و حالت‌های لبه را از قلم نینداز. که موضوع بخش بعدی است.

۴.۵.۳

روش ۲: حالت‌های لبه

یک ابزار که روی داده‌ی معمولی کار می‌کند، لزوماً روی داده‌ی غیرمعمولی کار نمی‌کند. و داده‌ی واقعی همیشه غیرمعمولی می‌شود.

پنج حالت لبه که همیشه ارزش امتحان دارند:

منبع رسمی هم فهرست مشابهی می‌دهد و یکی را اضافه می‌کند که ارزش گفتن دارد: حالت‌های مبهم — جایی که حتی دو آدم هم به یک نتیجه نمی‌رسند. برای آن‌ها جوابِ درست این است که ابزار بگوید مبهم است، نه اینکه یک طرف را انتخاب کند. همان چیزی که در فصل ۰.۲ از آن دو ردیفِ مشکوک خواستیم.

به‌خاطر بسپار فایل نمونه‌ها/داده/فروش-۱۴۰۵.csv این دوره عمداً هر پنج حالت را دارد. برای امتحان‌کردنِ هر ابزاری که می‌سازی، لازم نیست داده‌ی خراب بسازی — همان فایل را بده.

۴.۵.۴

روش ۳: «این را برایم توضیح بده»

روش سوم غیرمستقیم است ولی عجیب مؤثر: بخواه توضیح بدهد چه کار کرده.

چرا کار می‌کند؟ چون توضیح‌دادن، فرض‌ها را بیرون می‌کشد. جمله‌هایی مثل «مرجوعی‌ها را کم کردم» یا «ردیف‌های بدون تاریخ را کنار گذاشتم» — هر کدام یک تصمیم است که تو نگفته بودی و او گرفته.

سه شکل که خوب جواب می‌دهند:

و مهم: خودِ توضیح را هم باور نکن. توضیح، جاهایی را که باید بگردی نشانت می‌دهد — راستی‌آزمایی نمی‌کند. اگر گفت «مرجوعی‌ها را کم کردم»، برو ببین واقعاً کم شده‌اند.

۴.۵.۵

روش ۴: شمردن و نمونه‌گیری

ساده‌ترین روش، و آن که همه از قلم می‌اندازند.

شمردن. اگر ورودی ۸۰۰ ردیف داشت، خروجی چند ردیف را حساب کرده؟ اگر ۷۹۰ بود، ده ردیف کجا رفتند؟ این یک سؤال است و بیشتر خطاهای بی‌صدا را می‌گیرد.

عددهایی که همیشه ارزش شمردن دارند: تعداد ردیف ورودی و خروجی · تعداد موردهایی که خواسته بودی (فصل ۴.۴.۴) · تعداد ردیف‌های کنارگذاشته‌شده.

نمونه‌گیری. نمی‌توانی ۸۰۰ ردیف را چک کنی — ولی می‌توانی پنج تا را. و انتخابشان مهم است:

پنج نمونه از ۸۰۰ ردیف، دو دقیقه وقت می‌گیرد و بیشترِ خطاهای سیستماتیک را نشان می‌دهد — چون خطای سیستماتیک در همه‌ی ردیف‌ها هست، نه در یکی.

۱ جوابِ معلوم نمونه‌ای که جوابش را می‌دانی ۲ حالت‌های لبه خالی، تکراری، ناقص، بزرگ، نامعتبر ۳ توضیح بخواه فرض‌های نگفته را بیرون می‌کشد ۴ بشمار و نمونه بگیر ۸۰۰ ردیف رفت، ۷۹۰ برگشت؟ قوی‌تر · نیاز به آماده‌سازی سریع‌تر · همیشه ممکن هیچ‌کدام کد خواندن لازم ندارد — همه روی خروجی کار می‌کنند. روش ۴ را همیشه انجام بده؛ دو دقیقه است. روش ۱ را برای هر چیزی که قرار است تکرار شود، یک بار بساز.
چهار روش راستی‌آزمایی. از راست، قوی‌ترین؛ از چپ، سریع‌ترین.
۴.۵.۶

چک‌لیست راستی‌آزمایی

این را نگه دار — تا آخر دوره لازمش داری، و در ماژول ۸ برای هر اتوماسیونی که می‌سازی به کارش می‌بری.

  1. بشمار. ورودی چند بود، خروجی چند؟ چند مورد خواسته بودم، چند تا آمد؟
  2. پنج نمونه چک کن. اولی، آخری، بزرگ‌ترین، کوچک‌ترین، یکی تصادفی.
  3. روی نمونه‌ی معلوم امتحان کن. اگر داری‌اش.
  4. حالت‌های لبه را بده. حداقل «خالی» و «ناقص».
  5. بپرس چه فرض‌هایی گذاشته — و آن فرض‌ها را چک کن.
  6. بپرس عددها را چطور حساب کرده — با ابزار یا خودش؟ (فصل ۴.۱.۱)
  7. برای فارسی: یکسان‌سازی شده؟ (فصل ۴.۲.۴)

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

و صادقانه‌ترین جمله‌ی این ماژول: راستی‌آزمایی اطمینان کامل نمی‌دهد. منبع رسمیِ همان روش‌های ضدتوهم هم صریح می‌گوید این تکنیک‌ها توهم را حذف نمی‌کنند، فقط کم می‌کنند — و برای تصمیم‌های پرریسک باید اطلاعات را مستقل چک کنی. کاری که این چک‌لیست می‌کند این است که احتمال خطای بی‌صدا را از «نمی‌دانم» به «کم» می‌رساند.

نکته‌ی طلایی برای هر کاری که قرار است تکرار شود، یک بار یک نمونه‌ی معلوم بساز و نگهش دار — یک فایل کوچک با جوابِ نوشته‌شده. هر بار که ابزارت را عوض کردی، اول روی همان اجرا کن. سی ثانیه وقت می‌گیرد و همان چیزی است که در ماژول ۸ جلوی «شکست بی‌صدا» را می‌گیرد.
ضدالگو راستی‌آزمایی با پرسیدن «مطمئنی درست است؟». جوابش تقریباً همیشه «بله» است، و هیچ اطلاعاتی به تو نمی‌دهد — چون همان مکانیزمی که خروجی را ساخت، این جواب را هم می‌سازد. سؤال‌های این فصل عمداً همه بررسی‌پذیراند: شمردن، مقایسه با جوابِ معلوم، دیدنِ فرض‌ها.

تمرین (فکری)

این خروجی یک ایراد پنهان دارد. پیدایش کن و بگو از چه راهی فهمیدی.

ورودی: همان نمونه‌ها/داده/فروش-۱۴۰۵.csv با ۱۱ ردیف. خروجیِ گرفته‌شده:

جمع فروش به تفکیک محصول ← محصول A: ۶ ردیف · محصول B: ۴ ردیف · محصول C: ۲ ردیف

راهنمایی: از روش ۴ شروع کن. لازم نیست عددهای ریالی را حساب کنی.

پاسخنامه — ایراد و راهِ پیدا کردنش

ایراد: جمع ردیف‌ها ۱۲ است (۶ + ۴ + ۲)، ولی فایل ۱۱ ردیف دارد. یک ردیف اضافه شمرده شده.

از چه راهی: «روش ۴ — شمردن. لازم نبود هیچ عددِ ریالی را چک کنم؛ فقط جمع تعدادها را با تعداد ردیف‌های فایل مقایسه کردم.»

علتش: «فایل را باز کردم. آن ردیفِ 1405/1/18 که قیمتش با کاما نوشته شده، ساختارش شکسته و ۷ ستون دارد. به‌احتمال زیاد یک بار به‌عنوان محصول A شمرده شده و یک بار هم تکه‌ی سرریزشده‌اش جدا حساب شده.»

حالت شکست: «جوابِ مطمئنِ غلط (۴.۴.۵) — هیچ نشانه‌ای نداشت. خروجی مرتب بود و اگر جمع نمی‌زدم، هیچ‌وقت نمی‌فهمیدم.»

چرا این جواب خوب است: با ارزان‌ترین روش پیدا شده — یک جمعِ سرانگشتی — و بعد علت در خودِ فایل ردیابی شده. این همان الگویی است که در ماژول ۸ برای هر اتوماسیونی تکرار می‌شود: اول بشمار، بعد بگرد.

برای عمق بیشتر

ذخیره شد