Skip to content
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

Scissors - Ivana #67

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions swap_meet/clothing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from .item import Item

class Clothing(Item):
"""Class `Item`'s Child class.

Starts with default values for `condition` and `age`.
Initializes with a named attribute for its type, `"Clothing"`.
"""

def __init__(self, condition=0, age=0):
super()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually doing anything as its written here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I get super() now! finallyyyy

self.category = "Clothing"
self.condition = condition
self.age = age
Comment on lines +12 to +14

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This totally works but there is a tiny opportunity to DRY up your code a little but calling super().__init__() with these parameters from the child classes instead. It would be worth trying to rewrite these to utilize that if you can

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do that!


def __str__(self):
return "The finest clothing you could wear."

17 changes: 17 additions & 0 deletions swap_meet/decor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .item import Item

class Decor(Item):
"""Class `Item`'s Child class.

Starts with default values for `condition` and `age`.
Initializes with a named attribute for its type, `"Decor"`.
"""

def __init__(self, condition=0, age=0):
super()
self.category = "Decor"
self.condition = condition
self.age = age

def __str__(self):
return "Something to decorate your space."
17 changes: 17 additions & 0 deletions swap_meet/electronics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .item import Item

class Electronics(Item):
"""Class `Item`'s Child class.

Starts with default values for `condition` and `age`.
Initializes with a named attribute for its type, `"Electronics"`.
"""

def __init__(self, condition=0, age=0):
super()
self.category = "Electronics"
self.condition = condition
self.age = age

def __str__(self):
return "A gadget full of buttons and secrets."
47 changes: 47 additions & 0 deletions swap_meet/item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class Item:
"""Represents an item. Parent class for `Clothing`, `Decor`, and `Electronics` child classes. `Vendor` instances can have `Item` instances in their `inventory`.

Attributes:
condition (int): An optional attribute that defaults to 0 when not
passed into an `Item` object instance. Used to reference an item's
description based in values that range from 0 to 5, where 0
describes an item in "Poor" condition, and 5 describes an item
that is "Like New".

category (str): An empty string by default. Represents the category
of an item. Instances can optionally pass in a string with the
keyword argument `category`.
"""

def __init__(self, category=""):
self.condition = 0
self.category = category
self.age = 0

# Wave 5

def condition_description(self):
"""Instance method that describes the condition of an item in words based on its `condition`, in a range from 0 to 5.

Child classes inherit this method as-is, but are able to override it if necessary. The one requirement is that the `condition_description` for all three classes above have the same behavior.

Returns:
[type]: [description]
"""

descriptions = {
5: "Like New",
4: "Mint",
3: "Very Good",
2: "Good",
1: "Fair",
0: "Poor"
}

if self.condition not in descriptions:
return None
return descriptions[self.condition]
Comment on lines +32 to +43

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever!


def __str__(self):
"""Printable string representation of an Item instance."""
return "Hello World!"
201 changes: 201 additions & 0 deletions swap_meet/vendor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
from .item import Item

class Vendor:
"""Creates instances of a vendor and their list of items.

If a Vendor object is instantiated without arguments, it's attributes will have default values.

Attributes:
inventory: An empty list by default. Instances can optionally pass in
a list with the keyword argument `inventory`.
"""

def __init__(self, inventory=None):
if inventory is None:
self.inventory = []
else:
self.inventory = inventory

def add(self, item):
"""Adds the `item` to the `inventory`.

Args:
item (str): The item to be added.

Returns:
item (str): The item that was added.
"""

self.inventory.append(item)
return item

def remove(self, item):
"""Removes the matching `item` from the `inventory`.

Args:
item (str): The item that will be removed.

Returns:
item (str): The item that was removed. If there is no matching item
in the `inventory`, returns `False`.
"""

if item in self.inventory:
self.inventory.remove(item)
return item
return False

def get_by_category(self, category):
"""Iterates over the `inventory` to find the categories of the items in that list.

Args:
category (str): Represents the `category` of the items.

Returns:
same_category_items: A list of `Item`s in the `inventory` with that
`category`.
"""

same_category_items = []
for item in self.inventory:
if item.category == category:
same_category_items.append(item)
return same_category_items

def swap_items(self, friend, my_item, their_item):
"""Removes `my_item` from this `Vendor`'s `inventory` and adds it to the `friend`'s `inventory`.

Args:
friend (object): An instance of another `Vendor`, representing the
friend that this `Vendor` instance is swapping with.

my_item (str): Represents the item this `Vendor` instance plans to
give.

their_item (str): Represents the item the `friend` plans to give.

Returns:
bool: If this `Vendor`'s `inventory` doesn't contain `my_item` or
the `friend`'s `inventory` doesn't contain `their_item`,
returns `False`; otherwise, returns `True`.
"""

if my_item in self.inventory and their_item in friend.inventory:
self.remove(my_item)
friend.add(my_item)
friend.remove(their_item)
self.add(their_item)
return True
return False

def swap_first_item(self, friend):
"""Swaps the first item in this `Vendor`'s `inventory` with the first item in the `friend`'s `inventory`.

Args:
friend (object): An instance of another `Vendor`, representing the
friend that this `Vendor` instance is swapping with.

Returns:
bool: If either itself or the `friend` have an empty `inventory`,
returns `False`. Otherwise, returns True.
"""

if not self.inventory or not friend.inventory:
return False
else:
my_item = self.inventory.pop(0)
self.add(friend.inventory.pop(0))
friend.add(my_item)
return True
Comment on lines +103 to +109

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a lot like the code in the method above. It may be worth seeing if you can revisit this to DRY up your code by calling the other method from this one

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it took me a while to understand how I could be able to use the swap here, in the beginning it seemed that it wouldn't do exactly what I wanted until I figured out (with the help of my tutor) that I should just index the first item in each vendors' lists on method call :)) will change this!


def get_best_by_category(self, item_category):
"""Gets the item with the best `condition` in a certain `category`.

Args:
item_category (str): Represents the `category` of the items.

Returns:
best_item: A single item, even if there are duplicates (two or more
of the same item with the same `condition`). If there are no
items in the `inventory` that match the `category`, returns `None`.
"""

best_cond = 0
best_item = None

for item in self.get_by_category(item_category):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great use of an existing method!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you!

if item.condition > best_cond:
best_item = item
best_cond = item.condition
return best_item

def swap_best_by_category(self, other, my_priority, their_priority):
"""Swaps the best item of certain categories with another `Vendor`.

Args:
other (object): Represents another `Vendor` instance to trade with.

my_priority (str): Represents a `category` that this `Vendor`
instance wants to receive.

their_priority (str): Represents a `category` that `other` wants
to receive.

Returns:
bool: If any of both `Vendor` instances doesn't have an item that
matches a desired `category`, returns `False`; otherwise,
returns True.
"""

mine = self.get_best_by_category(their_priority)
theirs = other.get_best_by_category(my_priority)
if not mine or not theirs:
return False
else:
return self.swap_items(other, mine, theirs)
Comment on lines +150 to +155

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!


def get_by_newest(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love that you were able to do this optional and that you created this helper method rather than trying to do all the work in swap_by_newest!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glad I managed to DRY this part properly!

"""`swap_by_newest`s helper method.
This is an instance method, so any instance can access to get the first newest `item` in their `inventory`.

TODO:
- Implement this method in a way that it also checks the categories
or conditions of the items.
- Have a special class for Vintage Items.

Returns:
newest_item: A single `item`, even if there are duplicates (two or
more of the same item with the same `condition`).
If there are no items in the `inventory` that match the `category`, returns `None`.
"""

if self.inventory:
newest_item = self.inventory[0]
min_age = newest_item.age

for item in self.inventory:
if item.age < min_age:
newest_item = item
min_age = item.age
return newest_item
return None

def swap_by_newest(self, friend):
"""Swaps the newest item in the inventory with another `Vendor`.

Args:
friend (object): An instance of another `Vendor`, representing the
friend that this `Vendor` instance is swapping with.

Returns:
bool: If any of both `Vendor` instances doesn't have an item in
their inventory, the swap does not occur; otherwise, returns True.
"""

my_newest_item = self.get_by_newest()
their_newest_item = friend.get_by_newest()

if not my_newest_item or not their_newest_item:
return False
else:
self.swap_items(friend, my_newest_item, their_newest_item)
77 changes: 77 additions & 0 deletions tests/test_wave_07_NEW.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import pytest

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OMG And you wrote tests?!?!~~

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests look great!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you SO much for this feedback, Jared! I'm sorry for taking so long to answer, I'll implement the changes as you suggested. Thanks again and have a great weekend!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ivana, I love that you took the time to respond to this feedback! You are definitely welcome to update your code with the suggestions I offered but I want to make sure you know you aren't expected or required to.
The feedback is first and foremost feedback for you to incorporate in future code submissions. :)

from swap_meet.vendor import Vendor
from swap_meet.item import Item
from swap_meet.clothing import Clothing
from swap_meet.decor import Decor
from swap_meet.electronics import Electronics


def test_get_by_newest():
item_a = Clothing(age=2)
item_b = Decor(age=2)
item_c = Clothing(age=4)
item_d = Decor(age=5)
item_e = Clothing(age=1)
tai = Vendor(
inventory=[item_a, item_b, item_c, item_d, item_e]
)

newest_item = tai.get_by_newest()

# get_by_newest(self, friend)
assert newest_item == item_e


def test_swap_by_newest_no_matches_is_none():
item_a = Decor(age=2.0)
item_b = Decor(age=1.0)
item_c = Decor(age=4.0)
item_d = Decor(age=8.0)

tai = Vendor(
inventory=[item_a, item_b, item_c]
)
ta = Vendor(
inventory=[item_d]
)
is_swap = tai.swap_by_newest(ta)

assert is_swap is not False
assert item_d in tai.inventory
assert item_b in ta.inventory
assert item_a not in ta.inventory




def test_swap_by_newest_with_duplicates():
item_a = Clothing(age=2)
item_d = Clothing(age=2)
tai = Vendor(
inventory=[item_a]
)
ta = Vendor(
inventory=[item_d]
)
is_swap = tai.swap_by_newest(ta)

assert item_a in ta.inventory
assert is_swap is not False

def test_swap_by_newest_returns_false():
tai = Vendor(
inventory=[]
)

item_d = Clothing(age=2)
item_e = Decor()
item_f = Clothing(age=5)
jesse = Vendor(
inventory=[item_d, item_e, item_f]
)

result = tai.swap_by_newest(
jesse
)

assert result is False