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

C18 Lions ADSF #102

Open
wants to merge 10 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
75 changes: 37 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,43 +61,42 @@ At submission time, no matter where you are, submit the project via Learn.
### Wave 1

In Wave 1 we will create the `Vendor` class.

<!--
- There is a module (file) named `vendor.py` inside of the `swap_meet` package (folder)
- Inside this module, there is a class named `Vendor`
- Each `Vendor` will have an attribute named `inventory`, which is an empty list by default
- When we instantiate an instance of `Vendor`, we can optionally pass in a list with the keyword argument `inventory`


- When we instantiate an instance of `Vendor`, we can optionally pass in a list with the keyword argument `inventory` -->
<!--
- Every instance of `Vendor` has an instance method named `add`, which takes in one item
- This method adds the item to the `inventory`
- This method returns the item that was added
- This method returns the item that was added -->

- Similarly, every instance of `Vendor` has an instance method named `remove`, which takes in one item
<!-- - Similarly, every instance of `Vendor` has an instance method named `remove`, which takes in one item
- This method removes the matching item from the `inventory`
- This method returns the item that was removed
- If there is no matching item in the `inventory`, the method should return `False`
- If there is no matching item in the `inventory`, the method should return `False` -->

### Wave 2

In Wave 2 we will create the `Item` class and the `get_by_category` method.
<!-- In Wave 2 we will create the `Item` class and the `get_by_category` method.

- There is a module (file) named `item.py` inside of the `swap_meet` package (folder)
- There is a module (file) named `item.py` inside of the `swap_meet` package (folder) -->

- Inside this module, there is a class named `Item`
- Each `Item` will have an attribute named `category`, which is an empty string by default
- When we initialize an instance of `Item`, we can optionally pass in a string with the keyword argument `category`
<!-- - Inside this module, there is a class named `Item` -->
<!-- - Each `Item` will have an attribute named `category`, which is an empty string by default -->
<!-- - When we initialize an instance of `Item`, we can optionally pass in a string with the keyword argument `category`
- Instances of `Vendor` have an instance method named `get_by_category`
- It takes one argument: a string, representing a category
- This method returns a list of `Item`s in the inventory with that category
- This method returns a list of `Item`s in the inventory with that category -->

### Wave 3

In Wave 3 we will write a method to stringify an `Item` using `str()` and write the method `swap_items`.
<!-- In Wave 3 we will write a method to stringify an `Item` using `str()` and write the method `swap_items`.

- When we stringify (convert to a string) an instance of `Item` using `str()`, it returns `"Hello World!"`
- This implies `Item` overrides its stringify method. We may need to research the `__str__` method for more details!
- This implies `Item` overrides its stringify method. We may need to research the `__str__` method for more details! -->

The remaining tests in wave 3 imply:
<!-- The remaining tests in wave 3 imply:

- Instances of `Vendor` have an instance method named `swap_items`
- It takes 3 arguments:
Expand All @@ -107,52 +106,52 @@ The remaining tests in wave 3 imply:
- It removes the `my_item` from this `Vendor`'s inventory, and adds it to the friend's inventory
- It removes the `their_item` from the other `Vendor`'s inventory, and adds it to this `Vendor`'s inventory
- It returns `True`
- If this `Vendor`'s inventory doesn't contain `my_item` or the friend's inventory doesn't contain `their_item`, the method returns `False`
- If this `Vendor`'s inventory doesn't contain `my_item` or the friend's inventory doesn't contain `their_item`, the method returns `False` -->

### Wave 4

In Wave 4 we will write one method, `swap_first_item`.
<!-- In Wave 4 we will write one method, `swap_first_item`.

- Instances of `Vendor` have an instance method named `swap_first_item`
- It takes one argument: an instance of another `Vendor`, representing the friend that the vendor is swapping with
- This method considers the first item in the instance's `inventory`, and the first item in the friend's `inventory`
- It removes the first item from its `inventory`, and adds the friend's first item
- It removes the first item from the friend's `inventory`, and adds the instances first item
- It returns `True`
- If either itself or the friend have an empty `inventory`, the method returns `False`
- If either itself or the friend have an empty `inventory`, the method returns `False` -->

### Wave 5

In Wave 5 we will create three additional modules with three additional classes:

- `Clothing`
<!-- - `Clothing`
- Has an attribute `category` that is `"Clothing"`
- Its stringify method returns `"The finest clothing you could wear."`
- `Decor`
- Its stringify method returns `"The finest clothing you could wear."` -->
<!-- - `Decor`
- Has an attribute `category` that is `"Decor"`
- Its stringify method returns `"Something to decorate your space."`
- `Electronics`
<!-- - Its stringify method returns `"Something to decorate your space."` -->
<!-- - `Electronics`

- Has an attribute `category` that is `"Electronics"`
- Its stringify method returns `"A gadget full of buttons and secrets."`
- Its stringify method returns `"A gadget full of buttons and secrets."` --> -->

- All three 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 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 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 the `condition_description` for all three classes above have the same behavior.
- All three 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 the `condition_description` for all three classes above have the same behavior. -->

#### Using Inheritance
<!-- #### 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!

##### Hint: 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:

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: -->
<!--
```python
from swap_meet.item import Item
```
``` -->

### Wave 6
<!-- ### Wave 6

In Wave 6 we will write two methods, `get_best_by_category` and `swap_best_by_category`.

Expand All @@ -173,19 +172,19 @@ The remaining tests in wave 6 imply:
- The best item in my inventory that matches `their_priority` category is swapped with the best item in `other`'s inventory that matches `my_priority`
- It returns `True`
- If the `Vendor` has no item that matches `their_priority` category, swapping does not happen, and it returns `False`
- If `other` has no item that matches `my_priority` category, swapping does not happen, and it returns `False`
- If `other` has no item that matches `my_priority` category, swapping does not happen, and it returns `False` -->

### DRYing up the code
<!--
To further reduce the amount of repeated code in your project, consider how `swap_best_by_category` and `swap_first_item` might be able to make use of `swap_items`. Is there a way that these methods could incorporate a call to `swap_items` into the body of these methods? -->

To further reduce the amount of repeated code in your project, consider how `swap_best_by_category` and `swap_first_item` might be able to make use of `swap_items`. Is there a way that these methods could incorporate a call to `swap_items` into the body of these methods?

Try it out and see if the tests still pass! If you can't get them to pass with this refactor, you can always return to the most recent working commit before you submit the project!
<!-- Try it out and see if the tests still pass! If you can't get them to pass with this refactor, you can always return to the most recent working commit before you submit the project! -->

## Optional Enhancements

Should a project be completed before submission, and there is a desire for optional enhancements, consider this idea:

- `Item`s have age
- Add an `age` attribute to all `Item`s
<!-- - `Item`s have age
- Add an `age` attribute to all `Item`s -->
- Implement a `Vendor` method named `swap_by_newest`, using any logic that seems appropriate
- Write unit tests for `swap_by_newest`
13 changes: 11 additions & 2 deletions swap_meet/clothing.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
class Clothing:
pass
# from pyparsing import condition_as_parse_action
from swap_meet.item import Item

class Clothing(Item):

Choose a reason for hiding this comment

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

Excellent!

def __init__(self, condition=0, age=0):
category = 'Clothing'
super().__init__(category = category, condition=condition, age = age)


def __str__(self):
return 'The finest clothing you could wear.'
12 changes: 10 additions & 2 deletions swap_meet/decor.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
class Decor:
pass
from swap_meet.item import Item

class Decor(Item):

Choose a reason for hiding this comment

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

Excellent!

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


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

class Electronics(Item):

Choose a reason for hiding this comment

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

Excellent!

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


def __str__(self):
return "A gadget full of buttons and secrets."
25 changes: 24 additions & 1 deletion swap_meet/item.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,25 @@

# from attr import NOTHING

class Item:
pass
def __init__(self, category = "", condition=None, age = None):

Choose a reason for hiding this comment

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

Condition and age do not need to have None as the default, it can just be 0. We use None for things that are mutable, like lists and dictionaries. Integers are not mutable!

if not condition:
condition = 0.0
self.condition = condition
self.category = category
if not age:
age = 0
self.age = age


def __str__ (self):
return "Hello World!"

def condition_description(self):
if self.condition >= 0 and self.condition <=2:
return "Condition: imperfect"
elif self.condition >=3 and self.condition <=4:
return "Condition: gently used"
else:
return "Condition: like new"

98 changes: 97 additions & 1 deletion swap_meet/vendor.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,98 @@
# from pickle import FALSE
# from operator import invert
# from unittest import result
# from swap_meet import item
from operator import ne
from swap_meet.item import Item
Comment on lines +5 to +6

Choose a reason for hiding this comment

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

It looks like there were some imports that were accidentally added. It's good practice after you're done coding to make sure you only have the imports you need.

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, I 'll check them.
Actually, VSC added imports very often while I was doing my project.


class Vendor:
pass
""" Object: create a profile with the inventory and some features of each item"""
def __init__(self, inventory=None):

Choose a reason for hiding this comment

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

Excellent!

if not inventory:
inventory = []
self.inventory = inventory

def add(self, item):

Choose a reason for hiding this comment

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

Excellent!

""" Append new items to the current inventory"""
self.inventory.append(item)
return item

def remove(self, item):

Choose a reason for hiding this comment

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

Excellent!

""" Remove one item to the current inventory"""
if item in self.inventory:
self.inventory.remove(item)
return item
else:
return False

# wave_2
def get_by_category(self, category):

Choose a reason for hiding this comment

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

Excellent!

""" Get a list of items with the same category"""
items_list = []
for item in self.inventory:
if item.category == category:
items_list.append(item)
return items_list

# wave_3
def swap_items(self, swapping_other_vendor, my_item, their_item):
""" Swap items, remove items from the original inventory and add it to other person's inventory"""
if my_item in self.inventory and their_item in swapping_other_vendor.inventory:
self.remove(my_item)
swapping_other_vendor.remove(their_item)
self.add(their_item)
swapping_other_vendor.add(my_item)
return True
else:

Choose a reason for hiding this comment

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

This else is not necessary! Since the if has a return statement, we know that if the code keeps going past the if statement, we must be in the else. The else is implied.

return False

# Wave_4
def swap_first_item(self, swapping_other_vendor):

Choose a reason for hiding this comment

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

Excellent!

"""Swap the first item in the inventory"""
if self.inventory == [] or swapping_other_vendor.inventory == []:
return False

self.swap_items(swapping_other_vendor, self.inventory[0], swapping_other_vendor.inventory[0])
return True

# Wave_6

def get_best_by_category(self, category):

Choose a reason for hiding this comment

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

Excellent!

"""Return the item with the hightest condition per category"""
inventory_items_category = self.get_by_category(category) #list
if inventory_items_category == []:
return None

highest_item = inventory_items_category[0]
for item in inventory_items_category:
if item.condition >= highest_item.condition:
highest_item = item
return highest_item

def swap_best_by_category(self, other, my_priority, their_priority):
"""Swap the desire category items from the inventories """
if self.inventory == [] or other == []:

Choose a reason for hiding this comment

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

This if statement doesn't quite work because other cannot equal empty list. It's a class.

return False

my_priority_item = other.get_best_by_category(my_priority) # item
their_priority_item = self.get_best_by_category(their_priority) #item

if my_priority_item in other.inventory and their_priority_item in self.inventory:

Choose a reason for hiding this comment

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

We know for sure my_priority_item is in other.inventory because we search other.inventory for this item. We also know their_priority_item is in self.inventory. Here we are supposed to check if my_priority_item or their_priority_item are None. If the item is None, it will still return False if you check if it's in the inventory, but it's better to be clear about what we're checking here.

return self.swap_items(other, their_priority_item, my_priority_item)

return False

# Optional Enhancements

def get_newest(self):

Choose a reason for hiding this comment

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

Good try!

pass
if self.item.age == None:
return None

my_newest_item = min(self.inventory, key=lambda i:i[age])
return my_newest_item


def swap_by_newest(self, age):
pass

4 changes: 2 additions & 2 deletions tests/integration_tests/test_wave_01_02_03.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Choose a reason for hiding this comment

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

Please do NOT remove this. Pytest needs to know that this is an integration test. Only remove the skip one above.

def test_integration_wave_01_02_03():
# make a vendor
vendor = Vendor()
Expand Down
4 changes: 2 additions & 2 deletions tests/integration_tests/test_wave_04_05_06.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from swap_meet.decor import Decor
from swap_meet.electronics import Electronics

@pytest.mark.skip
@pytest.mark.integration_test
# @pytest.mark.skip
# @pytest.mark.integration_test
def test_integration_wave_04_05_06():
camila = Vendor()
valentina = Vendor()
Expand Down
23 changes: 23 additions & 0 deletions tests/unit_tests/newest_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
from swap_meet.vendor import Vendor
from swap_meet.clothing import Clothing
from swap_meet.decor import Decor
from swap_meet.electronics import Electronics
from swap_meet.item import Item

@pytest.mark.skip
def test_get_newest():

Choose a reason for hiding this comment

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

Good start on the test!

item_a = Item(age=10)
item_b = Item(age=40)
item_c = Item(age=6)

vendor = Vendor(
inventory=[item_a, item_b, item_c]
)

items = vendor.get_newest(vendor)

assert len(items) == 1
# assert item_a in items
# assert item_c in items
# assert item_b not in items
Loading