Python Learningاز صفر تا نوشتن پروژه از حفظ
درس ۱۷ · استادی

زیباتر و حرفه‌ای‌تر کردن برنامه

حدود ۷۵ دقیقه۳ تمرین۵ سؤال آزمون
بعد از این درس می‌توانی:
  • با ttk.Style ظاهر برنامه را عوض کنی
  • عددها را در جدول با جداکننده‌ی هزارگان نشان دهی (و باگ بعدش را درست کنی)
  • کالاهای کم‌موجود را رنگی کنی و برای حذف تأیید بگیری
  • قابلیت‌های جدید مثل خروجی CSV و گزارش سود اضافه کنی
حواست باشد

قبل از تغییر، از shop_manager.py یک کپی بگیر (مثلاً shop_manager_v1.py). هر تغییر را جدا اضافه کن و اجرا کن.

۱. پوسته و فونت

بعد از root = tk.Tk()
style = ttk.Style()
style.theme_use('clam')                     # پوسته‌های دیگر: 'alt', 'default', 'vista'
style.configure('.', font=('Tahoma', 10))
style.configure('TButton', padding=(10, 6))
style.configure('Treeview', rowheight=26)
style.configure('Treeview.Heading', font=('Tahoma', 10, 'bold'))
root.minsize(700, 500)

۲. عدد با جداکننده در جدول

در refresh
table.insert('', 'end', values=(name, f"{p['buy']:,.0f}", f"{p['sell']:,.0f}", p['qty']))
حواست باشد

باگ پنهان! حالا وقتی روی ردیف کلیک می‌کنی، جعبه‌ی قیمت 1,500 می‌گیرد و float('1,500') خطا می‌دهد. درمان: در values() قبل از تبدیل، کاماها را حذف کن.

تمرین

تبدیل عدد با کاما

تابع to_float(text) بنویس که '1,500' و '1500' و ' 2,500.5 ' را درست به عدد تبدیل کند.

Ctrl + Enter
دیدن راه‌حل (اول خودت تلاش کن)
def to_float(text):
    return float(text.replace(',', '').strip())

۳. رنگ برای موجودی کم

Python
table.tag_configure('low', background='#ffe4e4')

# داخل refresh:
tags = ('low',) if p['qty'] < 3 else ()
table.insert('', 'end', values=(...), tags=tags)

۴. تأیید قبل از حذف

Python
def delete():
    name = fields['name'].get().strip()
    if not messagebox.askyesno('حذف کالا', f'«{name}» حذف شود؟'):
        return
    shop.delete(name)

۵. کلید Enter و دکمه‌ی پاک کردن فرم

Python
def clear_form():
    for entry in fields.values():
        entry.delete(0, tk.END)

root.bind('<Return>', lambda event: run(add))
# و ('پاک کردن فرم', clear_form) را به لیست buttons اضافه کن

۶. قابلیت جدید: گزارش سود

تمرین

سود هر کالا

تابع profit_report(products) بنویس که دیکشنری {نام: سود کل موجودی} برگرداند؛ سود = (sell - buy) * qty. بعداً می‌توانی آن را به متد کلاس Shop و یک دکمه تبدیل کنی.

Ctrl + Enter
دیدن راه‌حل (اول خودت تلاش کن)
def profit_report(products):
    return {name: (p['sell'] - p['buy']) * p['qty'] for name, p in products.items()}

۷. قابلیت جدید: خروجی Excel (CSV)

فایل CSV با Excel باز می‌شود. ماژول csv پایتون آن را می‌سازد. utf-8-sig باعث می‌شود Excel فارسی را درست نشان دهد.

تمرین

ساختن CSV

تابع export_csv(products, path) بنویس که یک ردیف عنوان name,buy,sell,qty و بعد برای هر کالا یک ردیف بنویسد. با open(path, 'w', newline='', encoding='utf-8-sig') و csv.writer.

Ctrl + Enter
دیدن راه‌حل (اول خودت تلاش کن)
import csv

def export_csv(products, path):
    with open(path, 'w', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)
        writer.writerow(['name', 'buy', 'sell', 'qty'])
        for name, p in products.items():
            writer.writerow([name, p['buy'], p['sell'], p['qty']])

قدم‌های بعدی

آزمون این درس

برای گذراندن این درس حداقل ۸۰٪ جواب درست لازم است. هر چند بار خواستی می‌توانی دوباره امتحان بدهی.

۱. style.theme_use('clam') چه می‌کند؟
۲. بعد از نمایش 1,500 در جدول، چه باگی پیش می‌آید؟
۳. messagebox.askyesno چه برمی‌گرداند؟
۴. root.bind('<Return>', lambda event: run(add)) چه می‌کند؟
۵. چرا CSV با utf-8-sig ذخیره می‌شود؟