Skip to content

Commit

Permalink
Merge pull request #59 from nashville-software-school/bn-inheritance2…
Browse files Browse the repository at this point in the history
…-edit

corrected import statement
  • Loading branch information
BryanNilsen authored Jul 22, 2020
2 parents 4d4c4a5 + 850939b commit 45cc4e2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ Next, import that module into the index.py module, create a new attraction, and
```py
from animals import Goose
from petting_zoo import PettingZoo
from attractions import PettingZoo


# Create a Goose
Expand Down
51 changes: 33 additions & 18 deletions book-1-orientation/chapters/CLASSES_08-DUCK_TYPING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Critters and Croquettes: Day 8

>You bolt awake, covered in a cold sweat. As you sigh in relief that it was all just a dream, you realize something almost as scary: it could really happen! Just yesterday you were testing your code and you put a goose in the petting zoo without a second thought. But geese belong in Critter Cove, not Varmint Village. Right now, there's no limit to the type of animals that get placed in an attraction.
>You bolt awake, covered in a cold sweat. As you sigh in relief that it was all just a dream, you realize something almost as scary: it could really happen! Just yesterday you were testing your code and you put an alligator in the petting zoo without a second thought. But alligators belong in Critter Cove, not Varmint Village. Right now, there's no limit to the type of animals that get placed in an attraction.
>
>In Python, lists can contain any combination of object types. A single list could contain an integer, a boolean, and a string. This means that the `animals` attribute of your attractions classes can contain **any** critter type, regardless of whether it belongs there.
>
Expand All @@ -14,7 +14,7 @@ You are going to see two ways to make sure that only walking animals can be adde
```py
from . import Attraction
from movements import Swimming
from movements import Walking

class PettingZoo(Attraction):

Expand All @@ -24,54 +24,69 @@ class PettingZoo(Attraction):
# Number 1: Duck typing check
def add_animal_pythonic(self, animal):
try:
if animal.swim_speed > -1:
if animal.walk_speed > -1:
self.animals.append(animal)
print(f"{animal} now lives in {self.attraction_name}")
except AttributeError as ex:
print(f'{animal} doesn\'t like to be petted, so please do not put it in the {self.name} attraction.')

# Number 2: Actual typing check
def add_animal_type_check(self, animal):
if isinstance(animal, Swimming):
if isinstance(animal, Walking):
self.animals.append(animal)
print(f"{animal} now lives in {self.attraction_name}")
else:
print(f'{animal} doesn\'t like to be petted, so please do not try to put it in the {self.name} attraction.')
```

Both methods stopped a goose from being added to a petting_zoo. One is more _Pythonic_ than the other, but both are effective. Our recommendation is to follow the guidance of the Python community and use _duck typing_, and exceptions to determine if an object can be used for any specific purpose.
Both methods stop an alligator from being added to a petting_zoo. One is more _Pythonic_ than the other, but both are effective. Our recommendation is to follow the guidance of the Python community and use _duck typing_, and exceptions to determine if an object can be used for any specific purpose.

> ### Duck Typing
>
> "If it looks like a duck, sounds like a duck, acts like a duck, and smells like a duck, then it can do all the things we want a duck to do. It's a duck."
>
> The idea is that it doesn't actually matter what type my data is - just whether or not I can do what I want with it.
Next, refactor your main logic to create a walking animal, like a llama, as well as a swimming animal, like a goose
Next, refactor your main logic to create a walking animal, like a llama, as well as a swimming animal, like an alligator

> #### `index.py`
```py
from animals import Goose, Llama
from animals import Llama
from animals import Alligator
from attractions import PettingZoo

varmint_village = PettingZoo("The Varmint Village", "critters that love to be pet!")

miss_fuzz = Llama("Miss Fuzz", "domesticated llama", "oats", "morning")
bob = Goose("Bob", "Canada goose", "Goose Chow")
# remember, some animals may require more arguments than others; e.g. shift
dolly = Llama("Dolly", "miniature llama", "morning", "hay", 1033)
snappy = Alligator("Snappy", "American Alligator", "fish", 1044)

varmint_village = PettingZoo("The Varmint Village")
varmint_village.add_animal_pythonic(bob)
varmint_village.add_animal_type_check(bob)
varmint_village.add_animal_pythonic(miss_fuzz)
varmint_village.add_animal_pythonic(dolly)
varmint_village.add_animal_type_check(dolly)
varmint_village.add_animal_pythonic(snappy)
```

After you try adding the animals you should see the following output:

```
Dolly the miniature llama now lives in The Varmint Village
Dolly the miniature llama now lives in The Varmint Village
Snappy the alligator doesn't like to be petted, so please do not put it in the The Varmint Village attraction.
```

Now you can check to see which animal(s) were added to that attraction's animal list

```
for animal in varmint_village.animals:
print(f'{animal} lives in Varmint Village.')
print(animal)
```

Now the output is different. You will see that only the llama was added to the petting zoo.
You will see that only the llama was added to the petting zoo (twice in this case).

```
Bob the goose doesn't like to be petted, so please do not try to put it in The Varmint Village attraction.
Bob the goose doesn't like to be petted, so please do not try to put it in The Varmint Village attraction.
Miss Fuzz the llama lives in The Varmint Village
Dolly the miniature llama
Dolly the miniature llama
```

## Practice: Birds of a Feather, Snakes of a Scale?
Expand Down

0 comments on commit 45cc4e2

Please sign in to comment.