-
Notifications
You must be signed in to change notification settings - Fork 110
Snow Leopards- Ja Hopkins #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
856770c
878a4b1
18baf51
52f2a3c
897a389
9c74236
042f6f4
a65eb5c
826c303
0608a44
6ed61d0
c2d2b26
a62ccca
56fe85a
62fa0bf
9e1d477
0fead23
fa98af6
39e96c1
9d0e08b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,10 @@ | ||
class Clothing: | ||
pass | ||
from swap_meet.item import Item | ||
|
||
class Clothing(Item): | ||
|
||
def __init__(self, condition = 0): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice job removing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically, for default values we leave the spaces off around the def __init__(self, condition=0): |
||
super().__init__(category = "Clothing", condition = condition) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Great use of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When calling methods with keyword arguments, we tend to avoid using spaces around the super().__init__(category="Clothing", condition=condition) |
||
|
||
|
||
def __str__(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
return ("The finest clothing you could wear.") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
class Decor: | ||
pass | ||
from swap_meet.item import Item | ||
|
||
class Decor(Item): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
def __init__(self, condition = 0): | ||
super().__init__(category = "Decor", condition = condition) | ||
|
||
def __str__(self): | ||
return ("Something to decorate your space.") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
class Electronics: | ||
pass | ||
from swap_meet.item import Item | ||
|
||
class Electronics(Item): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
def __init__(self, condition = 0): | ||
super().__init__(category = "Electronics", condition = condition) | ||
|
||
def __str__(self): | ||
return ("A gadget full of buttons and secrets.") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,22 @@ | ||
class Item: | ||
pass | ||
|
||
def __init__(self, category= "", condition = 0): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
self.category = category | ||
self.condition = condition | ||
|
||
def __str__(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 This being here mostly just proves that we can replace an implementation in child classes. |
||
return ("Hello World!") | ||
|
||
|
||
# conditional statements | ||
|
||
def condition_description(self): | ||
if self.condition == 5: | ||
description = "Perfect" | ||
elif 0 <= self.condition <= 2: | ||
description = "Used with minor flaws" | ||
elif 2.1 <= self.condition <= 3: | ||
description = "Used with little to no flaws" | ||
elif 3.1 <= self.condition <= 4.9: | ||
description = "Like New" | ||
return description | ||
Comment on lines
+13
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notice that the only lines not covered by tests are related to this function. Due to the explicit logic checks, we would need to add additional test cases to ensure that each of the possible descriptions is returned for each possible condition, since each condition could potentially have a bug in it. Explicitly writing the logic does give us the ultimate control over exactly under which situations a particular description should be used, but especially when we have a long list of chained checks that are very similar, we could try coming up with a way to represent it with data and use iteration. A basic example of this that would closely mirror your existing behavior (the ranges aren't exactly matched, and the existing implementation has a few gaps, such as at 3.05) could look like: # outside class definition
DESCRIPTIONS = (
"Used with minor flaws",
"Used with minor flaws",
"Used with minor flaws",
"Used with little to no flaws",
"Like New",
"Perfect",
)
from math import ceil
# in Item class definition
def condition_description(self):
return DESCRIPTIONS[ceil(self.condition)] We would still want to think about the edge case behavior (what if the condition is less than 0 or greater than 5), but we would have more general confidence that if this logic works for a particular condition, it's likely to work for all of them. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,68 @@ | ||
from swap_meet.item import Item | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 We don't need to import Item into this file since we never use it by name. Check out the Why Vendor Doesn't Need to Import Item for more about why. |
||
class Vendor: | ||
pass | ||
|
||
def __init__(self, inventory=None): | ||
# self.inventory = inventory | ||
if inventory is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Nice handling of the default inventory case. |
||
inventory = [] | ||
self.inventory = inventory | ||
|
||
def add(self, item): | ||
self.item = item | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 We don't need to store a reference to the And in general, we should avoid assigning to |
||
self.inventory.append(item) | ||
return item | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 Leave a blank line between methods. |
||
def remove(self, item): | ||
self.item = item | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 No need to store the |
||
if item in self.inventory: | ||
self.inventory.remove(item) | ||
return item | ||
return False | ||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer writing the error handling case as a guard clause first, which lets us then emphasize the main part of the code by not indenting it. if item not in self.inventory:
return False
self.inventory.remove(item)
return item We could also do this with a more EAFP approach by using |
||
|
||
# create get_by_cateogry instance method that takes in category argument | ||
|
||
def get_by_category(self, category): | ||
# # reutrn list of items by category | ||
self.category = category | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 Like the |
||
items_in_category = [] | ||
# instance from item class | ||
# item_category = Item(category=self.category) | ||
for item in self.inventory: | ||
# item_category = Item(category=self.category) | ||
# if item.category == item_category.category: | ||
if item.category == category: | ||
items_in_category.append(item) | ||
Comment on lines
+29
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be a great opportunity for a comprehension expression. We could write this as items_in_category = [item for item in self.inventory if item.category == category] |
||
return items_in_category | ||
|
||
def swap_items(self, vendor, my_item, their_item): | ||
self.vendor = vendor | ||
self.my_item = my_item | ||
self.their_item = their_item | ||
Comment on lines
+37
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 Like the |
||
my_items = Vendor(self.inventory) | ||
if my_item not in my_items.inventory or their_item not in vendor.inventory: | ||
return False | ||
my_items.remove(my_item) | ||
my_items.add(their_item) | ||
vendor.add(my_item) | ||
vendor.remove(their_item) | ||
Comment on lines
+40
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than building a new if my_item not in self.inventory or their_item not in vendor.inventory:
return False
self.remove(my_item)
self.add(their_item)
vendor.add(my_item)
vendor.remove(their_item) |
||
return True | ||
|
||
def swap_first_item(self, vendor): | ||
self.vendor = vendor | ||
if not self.inventory or not vendor.inventory: | ||
return False | ||
Comment on lines
+51
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Here, we do need to ensure that the lists aren't empty before trying to access index 0. And consider adding a blank line at the end of the condition block to help visually separate the the guard clause from the main logic. |
||
return self.swap_items(vendor, self.inventory[0], vendor.inventory[0]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Nice function reuse. Though notice that due to the remove calls in By taking a different approach with |
||
|
||
|
||
|
||
# items_in_category = [] | ||
# for i in self.inventory: | ||
# if i == Item(category=category): | ||
# items_in_category.append(i) | ||
|
||
# return items_in_category | ||
|
||
|
||
# Item.category | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,8 @@ | |
from swap_meet.vendor import Vendor | ||
from swap_meet.item import Item | ||
|
||
@pytest.mark.skip | ||
@pytest.mark.integration_test | ||
# @pytest.mark.skip | ||
# @pytest.mark.integration_test | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The integration test decorator should not have been commented out. This mark affects the order that tests are run, as well as how the code coverage is calculated. |
||
def test_integration_wave_01_02_03(): | ||
# make a vendor | ||
vendor = Vendor() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,12 @@ | |
import pytest | ||
from swap_meet.vendor import Vendor | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_vendor_has_inventory(): | ||
vendor = Vendor() | ||
assert len(vendor.inventory) == 0 | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_vendor_takes_optional_inventory(): | ||
inventory = ["a", "b", "c"] | ||
vendor = Vendor(inventory=inventory) | ||
|
@@ -16,7 +16,7 @@ def test_vendor_takes_optional_inventory(): | |
assert "b" in vendor.inventory | ||
assert "c" in vendor.inventory | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_adding_to_inventory(): | ||
vendor = Vendor() | ||
item = "new item" | ||
|
@@ -27,7 +27,7 @@ def test_adding_to_inventory(): | |
assert item in vendor.inventory | ||
assert result == item | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_removing_from_inventory_returns_item(): | ||
item = "item to remove" | ||
vendor = Vendor( | ||
|
@@ -40,7 +40,7 @@ def test_removing_from_inventory_returns_item(): | |
assert item not in vendor.inventory | ||
assert result == item | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_removing_not_found_is_false(): | ||
item = "item to remove" | ||
vendor = Vendor( | ||
|
@@ -49,7 +49,8 @@ def test_removing_not_found_is_false(): | |
|
||
result = vendor.remove(item) | ||
|
||
raise Exception("Complete this test according to comments below.") | ||
# raise Exception("Complete this test according to comments below.") | ||
# ********************************************************************* | ||
# ****** Complete Assert Portion of this test ********** | ||
# ********************************************************************* | ||
assert result == False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 While we wouldn't typically compare directly with Personally, I don't like the design the description asks for (I'd rather it either return |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,12 @@ | |
from swap_meet.vendor import Vendor | ||
from swap_meet.item import Item | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_items_have_blank_default_category(): | ||
item = Item() | ||
assert item.category == "" | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_get_items_by_category(): | ||
item_a = Item(category="clothing") | ||
item_b = Item(category="electronics") | ||
|
@@ -23,7 +23,7 @@ def test_get_items_by_category(): | |
assert item_c in items | ||
assert item_b not in items | ||
|
||
@pytest.mark.skip | ||
# @pytest.mark.skip | ||
def test_get_no_matching_items_by_category(): | ||
item_a = Item(category="clothing") | ||
item_b = Item(category="clothing") | ||
|
@@ -34,7 +34,13 @@ def test_get_no_matching_items_by_category(): | |
|
||
items = vendor.get_by_category("electronics") | ||
|
||
raise Exception("Complete this test according to comments below.") | ||
# raise Exception("Complete this test according to comments below.") | ||
|
||
assert items == [] | ||
assert len(items) == 0 | ||
assert item_a not in items | ||
assert item_b not in items | ||
assert item_c not in items | ||
Comment on lines
+39
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 The comparison against the empty list is really all we need. If the list is empty, none of those items can possibly be in it. As before, we usually don't explicitly check for an empty collection like this, but since the unit test is confirming the specified behavior, which was to return a list (not just something falsy), we can write it this way. |
||
# ********************************************************************* | ||
# ****** Complete Assert Portion of this test ********** | ||
# ********************************************************************* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Since we are inheriting from
Item
, which requires us to get theItem
name from theitem
module, we need to import this.