نوشتن از حفظ
- نقشهی ذهنی ۸ بخش برنامه را داشته باشی
- تکههای سخت را با تمرین جای خالی و مرتبسازی حفظ کنی
- با برنامهی تکرار فاصلهدار، حفظ را ماندگار کنی
- کل برنامه را در کمتر از ۳۰ دقیقه بدون نگاه بنویسی
حفظ کردن کد با فهمیدن شروع میشود
کد را مثل شعر حفظ نکن. اگر بدانی چرا هر خط آنجاست، خط بعدی خودش یادت میآید. روش این درس چهار قدم دارد:
۱. نقشه: ترتیب بخشها را بدون کد بلد باش.
۲. اسکلت: اول فقط امضای تابعها و متدها را بنویس، بعد داخلشان را پر کن.
۳. یادآوری فعال: بدون نگاه بنویس، بعد مقایسه کن. خواندن دوباره حفظ نمیکند؛ به یاد آوردن حفظ میکند.
۴. تکرار فاصلهدار: تمرین را با فاصلههای بیشتر و بیشتر تکرار کن.
۱. نقشهی برنامه
| # | بخش | جملهی یادآور |
|---|---|---|
| ۱ | ورودیها و FILE | «چهار import و مسیر فایل کنار برنامه» |
| ۲ | __init__، save، load | «خالی بساز، از فایل بخوان؛ هر تغییر را بنویس» |
| ۳ | add، edit، delete | «چک کن، تغییر بده، ذخیره کن» |
| ۴ | sell، report | «سه چک، کم کن، ثبت کن؛ دو sum» |
| ۵ | shop، root، فرم | «شیء، پنجره، چهار برچسب و جعبه» |
| ۶ | values، run، شش تابع دکمه | «بخوان و تبدیل کن؛ امن اجرا کن؛ هر دکمه یک خط» |
| ۷ | refresh، choose | «خالی کن و پر کن؛ ردیف را به فرم ببر» |
| ۸ | دکمهها، جدول، mainloop | «قاب و lambda، چهار ستون، bind، وزن، refresh، mainloop» |
ترتیب بخشها
اینها خطهای کلیدی هر بخش هستند. به ترتیبی که در فایل میآیند مرتبشان کن.
FILE = os.path.join(...)root.mainloop()def run(action):def refresh(query=''):table = ttk.Treeview(...)def sell(self, name, qty):def add(self, name, buy, sell, qty):class Shop:root = tk.Tk()
۲. اسکلت
اسکلت کلاس
فقط اسکلت را بنویس: کلاس Shop با ۸ متد (__init__، save، load، add، edit، delete، sell، report) با پارامترهای درست و بدنهی pass.
دیدن راهحل (اول خودت تلاش کن)
class Shop: def __init__(self): pass def save(self): pass def load(self): pass def add(self, name, buy, sell, qty): pass def edit(self, name, buy, sell, qty): pass def delete(self, name): pass def sell(self, name, qty): pass def report(self): pass
۳. خطهای سخت
این خطها طولانیاند یا آرگومانهای زیاد دارند. چند بار پرشان کن تا بدون فکر بنویسیشان.
مسیر فایل
خط ۶:
FILE = os.path.(os.path.(os.path.()), 'shop_data.json')
ذخیره
بدنهی save:
with open(FILE, '', encoding='utf-8') as f:
json.dump({'products': self., 'sales': self.}, f, =False, =2)
چک عدد
خط ۳۱:
if not (0 <= x < float('') for x in (buy, sell, qty)):
رکورد فروش
خط ۵۹:
self.sales.({'name': name, 'qty': qty, 'total': qty * product['']})
برچسب فرم
خط ۷۲:
ttk.Label(root, text=label).grid(row=, column=, padx=8, pady=5, sticky='')
run
بدنهی run:
try:
action()
if action search: refresh()
except (, ) as exc:
messagebox.('خطا', str(exc))
except as exc:
messagebox.showerror('خطای فایل', str(exc))
پیام گزارش
خط ۱۱۱:
messagebox.('گزارش فروش', f'تعداد فروختهشده: {count}\nدرآمد کل فروش: {income:}')
ردیف جدول
خط ۱۱۸:
table.insert(, '', values=(name, p['buy'], p['sell'], p['qty']))
دکمهها
خط ۱۳۴:
ttk.Button(frame, text=label, command=lambda : run(a)).grid(row=i 4, column=i 4, padx=4, pady=4)
جدول
خط ۱۳۷ و ۱۴۲:
table = ttk.(root, columns=columns, show='', height=13)
table.('<<>>', choose)
۴. مرتب کردن متدها
load
متد load:
try:data = json.load(f)self.products, self.sales = {}, []self.products = data.get('products', {})if os.path.exists(FILE):except (OSError, json.JSONDecodeError, AttributeError):self.sales = data.get('sales', [])def load(self):with open(FILE, 'r', encoding='utf-8') as f:
sell
متد sell:
def sell(self, name, qty):raise ValueError('کالا پیدا نشد')raise ValueError('موجودی کافی نیست')if qty <= 0:raise ValueError('تعداد باید مثبت باشد')self.sales.append({'name': name, 'qty': qty, 'total': qty * product['sell']})product = self.products[name]self.save()product['qty'] -= qtyif qty > product['qty']:if name not in self.products:
choose
تابع choose:
selection = table.selection()fields[key].insert(0, value)if not selection:name, buy, sell_price, qty = table.item(selection[0], 'values')fields[key].delete(0, tk.END)def choose(event):returnfor key, value in [('name', name), ('buy', buy), ('sell', sell_price), ('qty', qty)]:
۵. نوشتن کامل از حفظ
کلاس Shop از حفظ (تکرار کن)
این همان تمرین آخر درس ۱۳ است. هر بار که به این درس برمیگردی، کادر را با «از اول» خالی کن و دوباره بنویس.
دیدن راهحل (اول خودت تلاش کن)
import json import os FILE = 'shop_data.json' # در VS Code: مسیر کنار برنامه با __file__ class Shop: def __init__(self): self.products = {} self.sales = [] self.load() def save(self): with open(FILE, 'w', encoding='utf-8') as f: json.dump({'products': self.products, 'sales': self.sales}, f, ensure_ascii=False, indent=2) def load(self): if os.path.exists(FILE): try: with open(FILE, 'r', encoding='utf-8') as f: data = json.load(f) self.products = data.get('products', {}) self.sales = data.get('sales', []) except (OSError, json.JSONDecodeError, AttributeError): self.products, self.sales = {}, [] def add(self, name, buy, sell, qty): if not name or name in self.products: raise ValueError('نام خالی یا کالای تکراری است') if not all(0 <= x < float('inf') for x in (buy, sell, qty)): raise ValueError('عدد منفی یا نامعتبر مجاز نیست') self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty} self.save() def edit(self, name, buy, sell, qty): if name not in self.products: raise ValueError('کالا پیدا نشد') if not all(0 <= x < float('inf') for x in (buy, sell, qty)): raise ValueError('عدد منفی یا نامعتبر مجاز نیست') self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty} self.save() def delete(self, name): if name not in self.products: raise ValueError('کالا پیدا نشد') del self.products[name] self.save() def sell(self, name, qty): if name not in self.products: raise ValueError('کالا پیدا نشد') if qty <= 0: raise ValueError('تعداد باید مثبت باشد') product = self.products[name] if qty > product['qty']: raise ValueError('موجودی کافی نیست') product['qty'] -= qty self.sales.append({'name': name, 'qty': qty, 'total': qty * product['sell']}) self.save() def report(self): return sum(s['qty'] for s in self.sales), sum(s['total'] for s in self.sales)
برنامهی تکرار
هر روز یک بار کل برنامه را در یک فایل خالی در VS Code بنویس، اجرا کن و با چکلیست درس قبل تست کن. زمانت را یادداشت کن. بعد از ۵ روز، فاصلهها را بیشتر کن.
آزمون این درس
برای گذراندن این درس حداقل ۸۰٪ جواب درست لازم است. هر چند بار خواستی میتوانی دوباره امتحان بدهی.