Sphinx - Vlada Rapaport#23
Conversation
…ave 5 but haven't completed it yet
…ategory_reordered()
kelsey-steven-ada
left a comment
There was a problem hiding this comment.
Great work! I've left a mix of suggestions and questions to consider for feedback. Please reply here on Github or reach out on Slack if there's anything I can clarify =]
| - Importing modulesWave 5 | ||
| In Wave 5 we will create three additional modules with three additional classes. | ||
|
|
||
| Our new modules should be defined as follows: | ||
|
|
||
| Clothing | ||
|
|
||
| Has an attribute id that is by default a unique integer | ||
| Has an attribute fabric that is by default the string "Unknown" | ||
| This attribute describes what fabric the clothing is made from; some example values might be "Striped", "Cotton", or "Floral" | ||
| When we instantiate an instance of Clothing, we can optionally pass in a string with the keyword argument fabric | ||
| Has a function get_category that returns "Clothing" | ||
| Has a stringify method that returns "An object of type Clothing with id <id value>. It is made from <fabric value> fabric." | ||
| For example, if we had a Clothing instance with an id of 123435 and a fabric attribute that holds "Wool", its stringify method should return "An object of type Clothing with id 12345. It is made from Wool fabric." | ||
| Decor | ||
|
|
||
| Has an attribute id that is by default a unique integer | ||
| Holds 2 integer attributes width and length | ||
| Both of these values should be 0 by default | ||
| When we instantiate an instance of Decor, we can optionally pass in integers with the keyword arguments width and length | ||
| Has a function get_category that returns "Decor" | ||
| Has a stringify method that returns "An object of type Decor with id <id value>. It takes up a <width value> by <length value> sized space." | ||
| For example, if we had a Decor instance with an id of 123435, width of 3, and length of 7, its stringify method should return "An object of type Decor with id 12345. It takes up a 3 by 7 sized space." | ||
| Electronics | ||
|
|
||
| Has an attribute id that is by default a unique integer | ||
| Has an attribute type that is by default the string "Unknown" | ||
| This attribute describes what kind of electronic device this is. Some example values might be “Kitchen Appliance”, “Game Console”, or “Health Tracker” | ||
| When we initialize an instance of Electronics, we can optionally pass in a string with the keyword argument type | ||
| Has an function get_category that returns "Electronics" | ||
| Has a stringify method that returns "An object of type Electronics with id <id value>. This is a <type value> device." | ||
| For example, if we had an Electronics instance with an id of 123435 and type attribute of "Mobile Phone", its stringify method should return "An object of type Electronics with id 12345. This is a Mobile Phone device." | ||
| All three new classes and the Item class have an attribute called condition, which can be optionally provided in the initializer. The default value should be 0 | ||
|
|
||
| All three new classes and the Item class have an instance method named condition_description, which should describe the condition in words based on the value, assuming they all range from 0 to 5. | ||
|
|
||
| These can be basic descriptions (eg. 'mint', 'heavily used') but feel free to have fun with these (e.g. 'You probably want a glove for this one..."). | ||
| The one requirement is that all the classes share the same condition_description behavior. | ||
| Using Inheritance | ||
| Now, we may notice that these three classes hold the same types of state and have the same general behavior as Item. That makes this is a great opportunity to use inheritance! If you haven't already, go back and implement the Clothing, Decor, and Electronics classes so that they inherit from the Item class. This should eliminate repetition in your code and greatly reduce the total number of lines code in your program! | ||
|
|
||
| Tip: Importing Item | ||
| You'll need to refer to Item in order to declare it as a parent. To reference the Item class from these modules, try this import line: | ||
|
|
||
| from swap_meet.item import Item |
There was a problem hiding this comment.
I don't know the exact cause of the Wave 5 instructions being added to the top of the README, but this could indicate that there is an opportunity to use git status more often or practice committing files one at a time to ensure only the files we want to change are included in a PR.
If we missed that we included something we didn't mean to while developing, when we go to create a PR, GitHub will list out the changes so we can review the files included before we officially create the PR. This is a great opportunity to check our work and ensure that we only see intended changes before starting the review process.
| def __str__(self): | ||
| return f"An object of type {self.category} with id {self.id}. It is made from {self.fabric} fabric." | ||
|
|
||
| # def condition_description(self): |
There was a problem hiding this comment.
Love seeing that the child classes are inheriting condition_description from Item!
| # def condition_description(self): | ||
| # if self.condition == 0: | ||
| # return "Brand new" | ||
| # elif self.condition ==1: | ||
| # return "Gently used" | ||
| # elif self.condition == 2: | ||
| # return "Used" | ||
| # elif self.condition == 3: | ||
| # return "Well used" | ||
| # elif self.condition == 4: | ||
| # return "Heavily used" | ||
| # elif self.condition == 5: | ||
| # return "Heavily worn" | ||
|
|
||
| # return "Unknown condition" No newline at end of file |
There was a problem hiding this comment.
When we refactor, we should delete code that is no longer necessary. If we are making regular commits in git, we can use the git history to look back on previous work. In GitHub, if you go to the "Commits" tab on a repo, you can view the source code at any of the commits.
| self.condition = condition | ||
|
|
||
| def __str__(self): | ||
| return f"An object of type {self.category} with id {self.id}." |
There was a problem hiding this comment.
Every child class starts with a sentence of this exact form. A child class can call their parent's functions using super.
How could we share this function with the child classes to reduce similar or repeated code in their __str__ functions?
| if self.condition == 0: | ||
| return "Brand new" | ||
| elif self.condition ==1: | ||
| return "Gently used" | ||
| elif self.condition == 2: | ||
| return "Used" | ||
| elif self.condition == 3: | ||
| return "Well used" | ||
| elif self.condition == 4: | ||
| return "Heavily used" | ||
| elif self.condition == 5: | ||
| return "Heavily worn" |
There was a problem hiding this comment.
We don't test for this, and it isn't a requirement, but something to consider:
- In the Wave 5 description the condition can be 0-5, so what happens if the condition is a decimal rather than an integer?
- How could we update the function to handle both types?
|
|
||
| # assume the first item is the best one | ||
| best_item = items[0] | ||
| for item in items[1:]: |
There was a problem hiding this comment.
There is a tradeoff happening here: by using slicing we're creating a new list in memory, making the function O(n) for space complexity to save making one extra comparison for the first item. If we want to iterate over a specific range of a list, we could use a for loop with the range function instead to keep our space complexity O(1).
|
|
||
|
|
There was a problem hiding this comment.
The PEP8 convention for blank lines is to use a single blank line to separate methods inside of a class. More info here: https://peps.python.org/pep-0008/#blank-lines
Not all projects you see as examples may follow PEP8, but the most important thing is to use whitespace consistently across a project so that readers can understand what different amounts of space mean.
| # ********************************************************************* | ||
| # ****** Complete Assert Portion of this test ********** | ||
| # ********************************************************************* | ||
| assert result == False No newline at end of file |
There was a problem hiding this comment.
Something to consider, if the function returns False does that guarantee the function did not alter the inventory? Checking the vendor.inventory contents as well would confirm there are no unintended side effects.
- What could that look like?
| assert item_b in fatimah.inventory | ||
| assert nobodys_item not in jolie.inventory | ||
| assert jolie.inventory == [] | ||
| assert fatimah.inventory == [item_a, item_b, item_c] |
There was a problem hiding this comment.
We could remove the assertion on line 138. If we check that jolie.inventory is an empty list, then we don't need to check if nobodys_item is in jolie.inventory - It can't be present if the list is empty.
Similarly, we could remove the assertion on line 137, since below we check all the contents of fatimah.inventory.
| assert item_f in tai.inventory | ||
| assert item_c in jesse.inventory | ||
| assert item_c not in tai.inventory | ||
| assert item_f not in jesse.inventory |
There was a problem hiding this comment.
What other checks could we add to confirm that there were no unintended changes to the other items in the inventories?
No description provided.