From 59013dad0405ced6561c6ca1a5f4a3599ea7f0eb Mon Sep 17 00:00:00 2001 From: JasonHomeWorkstationUbuntu Date: Tue, 8 Sep 2020 14:55:58 +1000 Subject: [PATCH] Finished Chapter 9 --- chap9_classes.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++- src/car.py | 30 ++++++++-- 2 files changed, 171 insertions(+), 7 deletions(-) diff --git a/chap9_classes.md b/chap9_classes.md index 7c055e8..ccb79f9 100644 --- a/chap9_classes.md +++ b/chap9_classes.md @@ -201,7 +201,153 @@ class ElectricCar(Car): ### Instance as Attributes -Sometimes we can use an instance of an class (object) as an attribute of another class. +Sometimes we can use an instance of an class (i.e. an object) as an attribute of another class. e.g. After grouping multiple all battery related attributes/method into a new class +```python +class ElectricCar(Car): + """Represent aspects of a car, specific to electric vehicles.""" + + def __init__(self, make, model, year): + """ + Initialize attributes of the parent class. + Then initialize attributes specific to an electric car. + """ + super().__init__(make, model, year) + self.battery = Battery() + ... + +class Battery: + """A simple attempt to model a battery for an electric car""" + + def __init__(self, battery_size=75): + """initialize the battery's attributes""" + self.battery_size = battery_size + + def describe_battery(self): + """Print a statement describing the battery size""" + print(f"This car has {self.battery_size}-kWh battery.") + + def get_range(self): + """Print a statement about the range this battery provides""" + if self.battery_size == 75: + range = 260 + elif self.battery_size == 100: + range = 315 + + print(f"This car can go about {range} miles on a full charge.") +``` + +Calling these functions are also simple + +```python +print(my_tesla.get_descriptive_name()) +print(my_tesla.battery.describe_battery()) +print(my_tesla.battery.get_range()) +``` + +### Modeling Real-World Objects + +Question: `get_range()` is this property of battery or car? Need think on higher-level. + +ANS: No right or wrong approach. Sometimes it's more efficient, sometimes not. + +## Importing Classes + +Python lets you store classes in modules and then import the classes you need into your main program. + +### Importing a Single Class + +e.g. + +1. after separating `Car` class into a python script `car.py` (i.e. **modules**) +2. New python script can reuse class + +```python +from car import Car +my_new_car = Car('audi', 'a4', 2019) +print(my_new_car.get_descriptive_name()) +``` + +### Storing Multiple Classes in a Module + +A module (.py script) can stores as many classes as it can. Although these classes should be related. + +e.g. + +1. add `ElectricCar(Car)` & `Battery` into `car.py` module script +2. New python script can reuse these classes + +```python +from car import ElectricCar + +my_tesla = ElectricCar('tesla', 'model s', 2019) + +print(my_tesla.get_descriptive_name()) +my_tesla.battery.describe_battery() +my_tesla.battery.get_range() +``` + +### Importing Multiple Classes from a Module + +```python +from car import Car, ElectricCar + +my_beetle = Car('volkswagen', 'beetle', 2019) +print(my_beetle.get_descriptive_name()) +``` + +### Importing an Entire Module + +```python +import car + +my_beetle = car.Car('volkswagen', 'beetle', 2019) +``` + +### Importing All Classes from a Module + +```python +from module_name import * +``` + +### Importing a Module into a Module + +```python +from car import Car + +... +``` + +### Using Aliases + +Using Aliases can make coding easier (less wordy) + +```python +from electric_car import ElectricCar as EC +``` + +### Finding Your Own Workflow + +* Keep project simple/flat +* When start out, keep code structure simple. + * Try doing everything in one file and moving classes to separate modules once everything is working. + +## Python Standard Library + +Python has modules in python std library for use. Use them just like normal customized library + +```python +from random import randint +randint(1,6) +``` + +## Styling Classes + +Following PEP-8: + +* Class names should be written in *CamelCase* +* Every class should have a docstring immediately following the class definition. +* Use blank lines to organize code, but don't over-use them. +* Sequence of importing modules: Python Standard Library + blanklines + customized modules \ No newline at end of file diff --git a/src/car.py b/src/car.py index e1f1a7d..8678f2a 100644 --- a/src/car.py +++ b/src/car.py @@ -35,20 +35,38 @@ class ElectricCar(Car): Then initialize attributes specific to an electric car. """ super().__init__(make, model, year) - self.battery_size = 75 - - def describe_battery(self): - """Print a statement describing the battery size.""" - print(f"This car has a {self.battery_size}-kWh battery.") + self.battery = Battery() def fill_gas_tank(self): """Electric cars don't have gas tanks""" print("This car doesn't need gas tank!") +class Battery: + """A simple attempt to model a battery for an electric car""" + + def __init__(self, battery_size=75): + """initialize the battery's attributes""" + self.battery_size = battery_size + + def describe_battery(self): + """Print a statement describing the battery size""" + print(f"This car has {self.battery_size}-kWh battery.") + + def get_range(self): + """Print a statement about the range this battery provides""" + if self.battery_size == 75: + range = 260 + elif self.battery_size == 100: + range = 315 + + print(f"This car can go about {range} miles on a full charge.") + my_new_car = Car('audi', 'a4', 2019) print(my_new_car.get_descriptive_name()) my_new_car.update_odometer(23) my_new_car.read_odometer() my_tesla = ElectricCar('telsa', 'model s', 2019) -print(my_tesla.get_descriptive_name()) \ No newline at end of file +print(my_tesla.get_descriptive_name()) +print(my_tesla.battery.describe_battery()) +print(my_tesla.battery.get_range()) \ No newline at end of file