۳. افزودن، ویرایش و حذف کالا¶
خط ۲۸ تا ۴۸
سه متد بعدی کلاس، دیکشنری کالاها را تغییر میدهند. الگوی هر سه یکی است: اول ورودی بررسی میشود و اگر ایرادی داشت با raise ValueError متوقف میشود، بعد تغییر انجام میشود و در آخر save همهچیز را در فایل مینویسد.
کد این بخش¶
28 def add(self, name, buy, sell, qty):29 if not name or name in self.products:30 raise ValueError('نام خالی یا کالای تکراری است')31 if not all(0 <= x < float('inf') for x in (buy, sell, qty)):32 raise ValueError('عدد منفی یا نامعتبر مجاز نیست')33 self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}34 self.save()35 36 def edit(self, name, buy, sell, qty):37 if name not in self.products:38 raise ValueError('کالا پیدا نشد')39 if not all(0 <= x < float('inf') for x in (buy, sell, qty)):40 raise ValueError('عدد منفی یا نامعتبر مجاز نیست')41 self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}42 self.save()43 44 def delete(self, name):45 if name not in self.products:46 raise ValueError('کالا پیدا نشد')47 del self.products[name]48 self.save()
روی شمارهی هر خط بزن تا به توضیحش بروی؛ روی «خط …» در توضیح بزن تا همان خط در کد روشن شود.
توضیح خط به خط¶
- خط ۲۸
def add(self, name, buy, sell, qty):¶ - متد
addبا چهار ورودی: نام، قیمت خرید، قیمت فروش و تعداد. این متد از تابعaddبیرون کلاس (خط ۹۴) صدا زده میشود. - خط ۲۹
if not name or name in self.products:¶ - دو شرط با
or: نام خالی است، یا این نام از قبل در دیکشنری هست. رشتهی خالی''در پایتون «نادرست» حساب میشود، پسnot nameبرای نام خالیTrueاست. - خط ۳۰
raise ValueError('نام خالی یا کالای تکراری است')¶ - یک خطای
ValueErrorبا پیام فارسی «پرتاب» میکند. باraiseاجرای متد همینجا تمام میشود و هیچ کالایی اضافه نمیشود. این خطا در تابعrun(خط ۸۸) گرفته و به کاربر نشان داده میشود. - خط ۳۱
if not all(0 <= x < float('inf') for x in (buy, sell, qty)):¶ allوقتیTrueاست که شرط برای همهی اعضا درست باشد. اینجا هر سه عدد باید بین صفر و بینهایت باشند:0 <= x < float('inf'). این شرط سه چیز را رد میکند: عدد منفی، بینهایت (inf) و «نهعدد» (nan).floatمتنهایnanوinfرا بدون خطا به عدد تبدیل میکند و هر مقایسهای باnanنادرست است، پس0 <= nanهم نادرست است و رد میشود.notنتیجه را برعکس میکند: اگر یکی نامعتبر بود، خطا بده.- خط ۳۳
self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}¶ - اگر همهچیز درست بود، کالا با نامش بهعنوان کلید و یک دیکشنری سهتایی بهعنوان مقدار ثبت میشود.
- خط ۳۶
def edit(self, name, buy, sell, qty):¶ - متد
editهمان چهار ورودی را دارد و از تابعeditبیرون کلاس (خط ۹۷) صدا زده میشود. - خط ۳۹
if not all(0 <= x < float('inf') for x in (buy, sell, qty)):¶ - همان بررسی عدد نامعتبر، مثل خط ۳۱.
- خط ۴۱
self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}¶ - کل دیکشنری کالا با مقدارهای جدید جایگزین میشود. چون نام کلید دیکشنری است، با این متد نمیشود نام کالا را عوض کرد؛ اگر نام را در فرم تغییر دهی، خط ۳۷ خطا میدهد.
- خط ۴۴
def delete(self, name):¶ - متد
deleteفقط نام را میگیرد. از تابعdeleteبیرون کلاس (خط ۱۰۰) صدا زده میشود.
یادداشت
add و edit تقریباً یکساناند؛ تنها فرقشان شرط اول است (کالا نباید باشد / باید باشد). بررسی عدد (خط ۳۱ و خط ۳۹) تکرار شده و میشد آن را در یک متد کمکی گذاشت. در نسخهی قبلی این خط if min(buy, sell, qty) < 0: بود که nan و inf را میپذیرفت؛ با نوشتن nan در قیمت، کالا ثبت میشد و NaN در فایل ذخیره میشد که JSON استاندارد نیست.
ارتباط با بقیهی کد¶
همچنین ببینید
Shop.add- با دکمهی «افزودن کالا»: دکمه خط ۱۳۴ ←
runخط ۸۴ ← تابعaddخط ۹۳ ←shop.add(*values())خط ۹۴. Shop.edit- با دکمهی «ویرایش کالا»: تابع
editخط ۹۶ ← خط ۹۷. Shop.delete- با دکمهی «حذف کالا»: تابع
deleteخط ۹۹ ← خط ۱۰۰. باtable.deleteدر خط ۱۱۵ که فقط یک ردیف جدول را پاک میکند اشتباه نشود. ValueError- همهی
raiseهای این بخش در خط ۸۸ گرفته میشوند و باmessagebox.showerrorدر خط ۸۹ نمایش داده میشوند. values()- چهار مقدار
name, buy, sell, qtyرا دقیقاً به همان ترتیب پارامترهایaddوeditبرمیگرداند (خط ۸۲).
سؤالهای تمرینی¶
اول خودت جواب بده، بعد جواب را باز کن.
چرا
not nameدر خط ۲۹ نام خالی را تشخیص میدهد؟نمایش جواب
رشتهی خالی «نادرست» حساب میشود، پس
not ''برابرTrueاست.کاربر در قیمت خرید
nanتایپ میکند. کدام خط جلویش را میگیرد و چرا؟آیا با
editمیشود نام کالا را عوض کرد؟نمایش جواب
نه. نام کلید دیکشنری است؛ نام جدید در خط ۳۷ پیدا نمیشود و
editخطای «کالا پیدا نشد» میدهد.بعد از حذف یک کالا، گزارش فروش تغییر میکند؟
نمایش جواب
نه. خط ۴۷ فقط آن را از
self.productsپاک میکند و فروشهایش درself.salesمیمانند.