3. Adding, editing and deleting products¶
Lines 28–48
The next three methods change the products dictionary. All three follow the same pattern: validate the input and stop with raise ValueError if something is wrong, make the change, then call save to write everything to disk.
Code for this part¶
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()
Click a line number to jump to its explanation; click “line …” in an explanation to highlight that line in the code.
Line by line¶
- line 28
def add(self, name, buy, sell, qty):¶ addtakes four arguments: name, purchase price, sale price and quantity. It is called from the module-level functionadd(line 94).- line 29
if not name or name in self.products:¶ - Two conditions joined by
or: the name is empty, or it is already in the dictionary. An empty string is falsy in Python, sonot nameisTruefor an empty name. - line 30
raise ValueError('نام خالی یا کالای تکراری است')¶ - Raises a
ValueErrorwhose message says the name is empty or already used.raiseends the method right here, so nothing is added. The error is caught inrun(line 88) and shown to the user. - line 31
if not all(0 <= x < float('inf') for x in (buy, sell, qty)):¶ allisTrueonly if the condition holds for every item. Each of the three numbers must lie between zero and infinity:0 <= x < float('inf'). This rejects negative numbers, infinity (inf) and not-a-number (nan).floathappily converts the stringsnanandinf, and every comparison withnanis false, so0 <= nanfails and the value is rejected.notflips the result: if any value is invalid, raise an error.- line 32
raise ValueError('عدد منفی یا نامعتبر مجاز نیست')¶ - Raises the error “negative or invalid numbers are not allowed”.
- line 33
self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}¶ - If everything is valid, stores the product under its name, with a three-item dictionary as the value.
- line 36
def edit(self, name, buy, sell, qty):¶ edittakes the same four arguments and is called from the module-level functionedit(line 97).- line 39
if not all(0 <= x < float('inf') for x in (buy, sell, qty)):¶ - The same number check as line 31.
- line 40
raise ValueError('عدد منفی یا نامعتبر مجاز نیست')¶ - Raises “negative or invalid numbers are not allowed”.
- line 41
self.products[name] = {'buy': buy, 'sell': sell, 'qty': qty}¶ - Replaces the product's whole dictionary with the new values. Because the name is the dictionary key, this method cannot rename a product: if you change the name in the form, line 37 reports that the product was not found.
- line 44
def delete(self, name):¶ deletetakes only the name. It is called from the module-level functiondelete(line 100).
Note
add and edit are almost identical; only the first check differs (the product must not exist / must exist). The number check (line 31 and line 39) is duplicated and could live in a helper method. An earlier version used if min(buy, sell, qty) < 0:, which accepted nan and inf: typing nan as a price stored NaN in the file, which is not valid standard JSON.
How it connects to the rest of the code¶
See also
Shop.add- The “add product” button: button line 134 →
runline 84 → functionaddline 93 →shop.add(*values())line 94. Shop.edit- The “edit product” button: function
editline 96 → line 97. Shop.delete- The “delete product” button: function
deleteline 99 → line 100. Not to be confused withtable.deleteon line 115, which only removes a table row. ValueError- Every
raisein this part is caught on line 88 and shown withmessagebox.showerroron line 89. values()- Returns
name, buy, sell, qtyin exactly the order of the parameters ofaddandedit(line 82).
Check your understanding¶
Try to answer each question before opening it.
Why does
not nameon line 29 catch an empty name?Show answer
An empty string is falsy, so
not ''isTrue.The user types
nanas the purchase price. Which line stops it, and why?Can
editrename a product?Show answer
No. The name is the dictionary key; a new name is not found on line 37, so
editraises “product not found”.After a product is deleted, does the sales report change?
Show answer
No. line 47 only removes it from
self.products; its sales stay inself.sales.