سرنخ — خودآموز برنامه‌نویسی برای هوش مصنوعی (مقدماتی)

فصل ۱۰ از ۱۱

پیشرفت ترم
۰٪

ترم ۱ · پایتون از صفر، داخلِ Colab

چرا نوت‌بوک دروغ می‌گوید

فصل ۱۰پیش‌نمایش رایگان

در این فصل چه یاد می‌گیری#

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

دو ستونِ کنارِ هم از قاب‌های شماره‌دار: در یکی ترتیب پیوسته است و در دیگری شماره‌ها درهم و یک قاب خالی جا افتاده

آخر این فصل می‌توانی:

  • بگویی «حالتِ پنهان» یعنی چه و چطور ساخته می‌شود
  • عددِ کنارِ سلول را بخوانی و بگویی نوت‌بوک با چه ترتیبی اجرا شده
  • تنها آزمونِ صداقتِ یک نوت‌بوک را انجام بدهی
  • خطای ناشی از سایه‌انداختن روی نامِ داخلیِ پایتون را تشخیص بدهی و رفعش کنی
  • با import از کتابخانه‌های آماده استفاده کنی و فایلِ خودت را وارد Colab کنی

قبل از شروع#

از فصل ۱: عددِ داخلِ کروشه کنارِ هر سلول می‌گوید چندمین سلولی است که اجرا کرده‌ای.

از فصل ۸: خواندنِ traceback از خطِ آخر.

📓 نوت‌بوک: نوت‌بوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و به‌ترتیب داخلش هست.

۱. حافظه‌ای که زیرِ صفحه زنده است#

نوت‌بوک دو چیزِ جداست که به‌سادگی یکی به‌نظر می‌رسند: متنی که می‌بینی و حافظه‌ای که کد در آن اجرا می‌شود. آن حافظه — که runtime نامیدیمش — بینِ سلول‌ها مشترک است و بینِ اجراها زنده می‌ماند.

این سلول را اجرا کن، و بعد یک بار دیگر اجرایش کن:

counter = 0
counter = counter + 1
print(counter)
1

اینجا هر بار 1 می‌گیری، چون خطِ اول هر بار counter را از نو صفر می‌کند. حالا خطِ اول را پاک کن و فقط دو خطِ بعدی را نگه دار، و سلول را چند بار اجرا کن: 2، 3، 4… هر اجرا روی نتیجهٔ اجرای قبلی سوار می‌شود.

این «حافظهٔ زنده» همان چیزی است که نوت‌بوک را قدرتمند می‌کند: یک بار فایلِ بزرگ را می‌خوانی و ده‌ها بار رویش آزمایش می‌کنی، بدونِ خواندنِ دوباره. ولی همین است که دروغ را ممکن می‌کند.

۲. حالتِ پنهان: متغیری که کدش دیگر وجود ندارد#

این سناریو را تصور کن — و اگر مدتی با نوت‌بوک کار کنی، حتماً برایت پیش می‌آید:

  1. در سلولِ ۱ می‌نویسی tax_rate = 0.09 و اجرا می‌کنی.
  2. جلوتر ده سلول کد می‌نویسی که همه از tax_rate استفاده می‌کنند و درست کار می‌کنند.
  3. سلولِ ۱ را پاک می‌کنی، چون فکر می‌کنی دیگر لازم نیست.
  4. همه‌چیز هنوز کار می‌کند — چون tax_rate در حافظه زنده است، هرچند کدش دیگر در نوت‌بوک نیست.
  5. فردا نوت‌بوک را باز می‌کنی و از سلولِ اول اجرا می‌کنی: NameError: name 'tax_rate' is not defined.

به این می‌گویند حالتِ پنهان (hidden state): چیزی در حافظه که هیچ کدی روی صفحه آن را نمی‌سازد. دیروز کار می‌کرد، امروز نه، و هیچ‌چیز عوض نشده — جز اینکه حافظه پاک شده.

همین اتفاق در حالتِ ملایم‌ترش خیلی رایج‌تر است: کدِ داخلِ یک سلول را عوض می‌کنی ولی دوباره اجرایش نمی‌کنی، و سلول‌های بعدی همچنان با نسخهٔ قدیمی کار می‌کنند. خروجی‌ای که می‌بینی مالِ کدی است که دیگر روی صفحه نیست.

قبل از ادامه، جواب بده: یک نوت‌بوک باز کرده‌ای و همهٔ سلول‌ها خروجیِ درست نشان می‌دهند. آیا این یعنی نوت‌بوک کار می‌کند؟ جواب: نه. آن خروجی‌ها ذخیره‌شده‌اند و می‌توانند مالِ نسخه‌های قبلیِ کد یا ترتیبِ دیگری از اجرا باشند. تنها راهِ فهمیدن، اجرای دوباره از صفر است.

۳. عددِ کنارِ سلول: کارآگاهِ تو#

آن عددِ داخلِ کروشه — [7] — می‌گوید این هفتمین سلولی است که در این نشست اجرا شده، نه اینکه هفتمین سلولِ صفحه است.

پس اگر از بالا تا پایینِ نوت‌بوک نگاه کنی و ببینی شماره‌ها [1] [2] [5] [3] [9] هستند، می‌دانی که با ترتیبِ صفحه اجرا نشده. و اگر سلولی [ ] خالی باشد، یعنی از آخرین راه‌اندازیِ حافظه اصلاً اجرا نشده.

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

۴. تنها آزمونِ صداقت#

Runtime → Restart session and run all

این دستور حافظه را کاملاً پاک می‌کند و بعد همهٔ سلول‌ها را از بالا تا پایین، به‌ترتیبِ صفحه، اجرا می‌کند. اگر بی‌خطا تا آخر رفت، نوت‌بوکِ تو واقعاً کار می‌کند. اگر نرفت، نمی‌کند — هر چه روی صفحه دیده می‌شود بازمانده‌ای از حالتی است که دیگر وجود ندارد.

سه قاعدهٔ عملی که از همین‌جا با تو می‌آیند:

  1. همیشه از بالا به پایین بنویس و اجرا کن. اگر سلولی به چیزی نیاز دارد که پایین‌تر ساخته می‌شود، ترتیبت غلط است، نه پایتون.
  2. قبل از هر تحویل، یک بار Restart and run all. قبل از اشتراک‌گذاری، قبل از نتیجه‌گیری، قبل از هر عددی که می‌خواهی به کسی بگویی.
  3. وقتی کد را عوض کردی، سلول‌های وابسته را هم دوباره اجرا کن. یا ساده‌تر: عادت کن بعد از هر تغییرِ مهم، کلِ نوت‌بوک را از نو بدوانی.

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

۵. یک خطای واقعی: سایه انداختن روی نامِ داخلی#

این یکی مخصوصِ نوت‌بوک است، چون اثرش در حافظه می‌ماند و ممکن است ده سلول بعد خودش را نشان بدهد.

list = [3, 1, 2]
print(list)
[3, 1, 2]

هیچ خطایی نگرفتی. ولی list نامِ یکی از توابعِ داخلیِ خودِ پایتون بود و تو رویش یک فهرست گذاشتی. حالا آن تابع در این نشست دیگر در دسترس نیست. چند سلول بعد، وقتی طبیعی‌ترین کارِ دنیا را بکنی:

numbers = list(range(5))
TypeError: 'list' object is not callable

«شیءِ list قابلِ صدا زدن نیست» — چون list دیگر یک تابع نیست، یک فهرست است. و بدترین بخشش این است که خطا در سلولی رخ می‌دهد که هیچ ربطی به سلولِ مقصر ندارد، شاید ده دقیقه بعد.

رفعش ساده است: متغیر را از حافظه پاک کن تا نامِ اصلی برگردد.

del list
numbers = list(range(5))
print(numbers)
[0, 1, 2, 3, 4]

نام‌هایی که هرگز نباید روی متغیر بگذاری: list، dict، str، int، set، type، sum، max، min، id، input، print. اگر شک داری، اسمِ دقیق‌تری انتخاب کن — word_list به‌جای list هم خواناتر است و هم امن.

چک کن: بعد از del، خروجیِ سلولِ آخر باید [0, 1, 2, 3, 4] باشد. اگر همچنان TypeError می‌گیری، یعنی سلولِ del را اجرا نکرده‌ای — و این خودش دقیقاً همان درسِ فصل است: در نوت‌بوک، نوشتنِ یک اصلاح کافی نیست؛ باید اجرایش هم بکنی.

🔧 اگر کار نکرد: اگر del هم گیجت کرد یا چند نامِ داخلی را همزمان خراب کرده‌ای، مطمئن‌ترین کار Restart session است. حافظه از صفر پاک می‌شود و همه‌چیز به حالتِ سالم برمی‌گردد. در نوت‌بوک، راه‌اندازیِ دوباره ارزان است — از دنبالِ باگ گشتن خیلی ارزان‌تر.

📏 اندازه بگیر: یک عادتِ عملی که بعداً خیلی به‌کارت می‌آید: هر وقت نتیجه‌ای گرفتی که قرار است رویش تصمیم بگیری، قبل از باور کردنش یک بار Restart and run all بزن و ببین همان عدد دوباره درمی‌آید. اگر درنیامد، عددت مالِ حالتی بوده که دیگر وجود ندارد. این ارزان‌ترین وارسیِ کلِ دوره است.

۶. سه چیزی که با پاک‌شدنِ حافظه از دست می‌روند#

حافظه تنها چیزی نیست که با راه‌اندازیِ دوباره پاک می‌شود. کلِ دیسکِ آن ماشین هم پاک می‌شود — و این سه پیامدِ عملی دارد که از فصلِ بعد هر روز با آن‌ها کار داری.

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

import math
import statistics as stats

print(math.sqrt(144))
print(stats.median([3, 1, 4, 1, 5]))
12.0
3

import math کلِ کتابخانه را می‌آورد و از آن به بعد با math. به محتویاتش می‌رسی — همان نقطه‌ای که در x.append() دیدی. آن as stats هم فقط یک نامِ کوتاه‌تر می‌سازد؛ از فصلِ اولِ ترمِ ۲ می‌بینی که import numpy as np یک قراردادِ جهانی است و همه‌جا همین‌طور نوشته می‌شود.

دوم: بسته‌هایی که در Colab نیستند. بعضی کتابخانه‌ها از قبل نصب‌اند و بعضی نه. برای نصب، در یک سلولِ کد این را می‌زنی (علامتِ ! یعنی «این یک دستورِ سیستم است، نه کدِ پایتون»):

!pip install -q hazm==0.10.0

آن -q خروجیِ طولانیِ نصب را کوتاه می‌کند، و آن ==0.10.0 نسخه را سنجاق می‌کند. سنجاق‌کردن مهم است: بدونِ آن، Colab هر بار آخرین نسخه را نصب می‌کند و نوت‌بوکی که امروز کار می‌کند ممکن است شش ماهِ دیگر نکند. و چون دیسک پاک می‌شود، این نصب در هر جلسهٔ تازه دوباره لازم است — سلولِ نصب را بالای نوت‌بوک نگه دار، نه وسطش.

سوم، و مهم‌ترین: فایل‌های خودت. در این دوره بارها از تو خواسته می‌شود روی دادهٔ خودت کار کنی. سه راه برای رساندنِ یک فایل به Colab هست:

راه چطور کِی مناسب است
آپلودِ دستی نوارِ کناری، نشانِ 📁، دکمهٔ آپلود یک فایلِ کوچک، یک بار
از یک نشانیِ اینترنتی pd.read_csv("https://…") دادهٔ عمومی
اتصالِ Google Drive سلولِ زیر فایل‌هایی که مرتب لازمشان داری
from google.colab import drive

drive.mount("/content/drive")
# حالا فایل‌هایت اینجا هستند: /content/drive/MyDrive/<نام فایل>

فایلی که با آپلودِ دستی می‌گذاری، با پایانِ جلسه از بین می‌رود. فایلی که در Drive است نمی‌رود. برای همین اگر نتیجه‌ای تولید کردی که می‌خواهی نگه داری — یک جدولِ تمیزشده، یک مدل — آن را در Drive بنویس، نه در پوشهٔ موقتِ Colab.

⚠️ مواظب باش: drive.mount به نوت‌بوک اجازهٔ خواندن و نوشتن در کلِ Drive تو را می‌دهد. برای نوت‌بوکِ خودت مشکلی نیست؛ ولی نوت‌بوکی را که از جای دیگری گرفته‌ای و کدش را نخوانده‌ای، به Drive وصل نکن. همان قاعدهٔ فصلِ ۹ دربارهٔ کدِ نافهمیده، این بار با دسترسی به فایل‌هایت.

📏 اندازه بگیر: یک آزمونِ کوچک که ارزشش را دارد: نوت‌بوکت را ببند، Runtime → Disconnect and delete runtime بزن، و از صفر اجرایش کن. اگر نوت‌بوکی که سلولِ نصب و سلولِ خواندنِ فایل ندارد، همان‌جا می‌شکند — و بهتر است همین حالا بشکند تا وقتی که به کسِ دیگری داده‌ای.

واژه‌های تازهٔ این فصل#

کلمه تلفظ به حروف فارسی یعنی چه
hidden state هیدِن استِیت چیزی که در حافظه هست ولی کدی روی صفحه آن را نمی‌سازد
restart and run all ری‌استارت اند ران آل پاک‌کردنِ حافظه و اجرای همهٔ سلول‌ها از بالا — آزمونِ صداقتِ نوت‌بوک
shadowing شَدوئینگ گذاشتنِ نامِ یک چیزِ داخلیِ پایتون روی متغیرِ خودت
import ایمپورت آوردنِ یک کتابخانهٔ آماده به نوت‌بوک
library / module لایبرری / ماژول بسته‌ای از کدِ آماده که importش می‌کنی
pip install پیپ اینستال نصبِ بسته‌ای که از قبل در Colab نیست

تمرین‌ها

اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.

در فصل بعد#

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

به آخر این فصل رسیدی!

اگر ساختی و جواب داد، این دکمه مال توست.