diff --git a/chap8_functions.md b/chap8_functions.md new file mode 100644 index 0000000..da8bad2 --- /dev/null +++ b/chap8_functions.md @@ -0,0 +1,103 @@ +# Chapter 8. Functions + +## Passing an Arbitrary Number of Arguments + +* Function uses `*arg_name` to collects arbitrary number of arguments. +* `*` in parameter tells Python to make an empty tuple called `arg_name` and pack whatever values it receives into this tuple + +NOTE: `*args` is open used as **generic parameter** name + +```python +def make_pizza(*toppings): + """Summarize the pizza we are about to make.""" + print("\nMaking a pizza with the following toppings:") + for topping in toppings: + print(f"- {topping}") + +make_pizza('pepperoni') +make_pizza('mushrooms', 'green peppers', 'extra cheese') +``` + +## Mixing Positional and Arbitrary Arguments + +* If function accept different kinds of arguments, Arbitrary Arguments must be placed at last. + +```python +def make_pizza(size, *toppings): + """Summarize the pizza we are about to make.""" + print(f"\nMaking a {size}-inch pizza with the following toppings:") + for topping in toppings: + print(f"- {topping}") + +make_pizza(16, 'pepperoni') +make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') +``` + +## Using Arbitrary Keyword Arguments + +* Function can use double asterisks `**` to cause Python to create an empty dictionary called **user_info** and pack whatever name-value pairs. + +```python +def build_profile(first, last, **user_info): + """Build a dictionary containing everything we know about a user.""" + user_info['first_name'] = first + user_info['last_name'] = last + return user_info + + +user_profile = build_profile('albert', 'einstein', + location='princeton', + field='physics') +print(user_profile) + +{'location': 'princeton', 'field': 'physics', +'first_name': 'albert', 'last_name': 'einstein'} +``` + +## Storing Your Functions in Modules + +Functions can be stored in different modules (python scripts) for better management. + +### Importing an Entire Module + +```python + import pizza + +pizza.make_pizza(16, 'pepperoni') +pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') +``` + +### Importing Specific Functions + +```python +from module_name import function_name +``` + +### Using as to Give a Function an Alias + +```python +from module_name import function_name as fn +``` + +### Using as to Give a Module an Alias + +```python +import pizza as p + +p.make_pizza(16, 'pepperoni') +p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') +``` + +### Importing All Functions in a Module + +```python +from module_name import * +``` + +## Styling Functions + +* Functions should have descriptive names, and function names should be lowercase letters and underscores. +* Every function should have a comment that explain concisely what the function does. +* If specify a default value, no space separation `def function_name(parameter_0, parameter_1='default value')` + +Generally follow PEP8 \ No newline at end of file diff --git a/chap9_classes.md b/chap9_classes.md new file mode 100644 index 0000000..dc3db37 --- /dev/null +++ b/chap9_classes.md @@ -0,0 +1,134 @@ +# Chapter 9. Classes + +Objectives: + +* Making an object from a class is called **instantiation**, and you work with **instances of a class**. +* In this chapter you’ll write classes and create instances of those classes. +* You’ll specify the kind of information that can be stored in instances, and you’ll define actions that can be taken with these instances. +* You’ll also write classes that extend the functionality of existing classes, so similar classes can share code efficiently. +* You’ll store your classes in modules and import classes written by other programmers into your own program files. + +## Creating and using a class + +```python +class Dog: + """A Simple attempt to model a dog""" + + def __init__(self, name, age): + """Initialize name and age attributes.""" + self.name = name + self.age = age + + def sit(self): + """Simulate a dog sitting in response to a command.""" + print(f"{self.name} is now sitting.") + + def roll_over(self): + """Simulate rolling over in response to a command""" + print(f"{self.name} rolled over!") +``` + +### __init__() method + +* A special method python run automatically whenever we create a new instance. +* `self` in parameters is required in method definition, always come first + * So method call will automatically pass the `self` argument, it's a reference to itself. + +### Making an Instance from a Class + +```python +my_dog = Dog('Willie', 6) + +(f"My dog's name is {my_dog.name}.") +print(f"My dog is {my_dog.age} years old.") +``` + +### Accessing Attributes + +```python +my_dog.name +``` + +### Calling Methods + +```python +class Dog: + --snip-- + +my_dog = Dog('Willie', 6) +my_dog.sit() +my_dog.roll_over() +``` + +### Creating Multiple Instances + +```python +class Dog: + --snip-- + +my_dog = Dog('Willie', 6) +your_dog = Dog('Lucy', 3) + +print(f"My dog's name is {my_dog.name}.") +print(f"My dog is {my_dog.age} years old.") +my_dog.sit() + +print(f"\nYour dog's name is {your_dog.name}.") +print(f"Your dog is {your_dog.age} years old.") +your_dog.sit(); +``` + +## Working with Classes and Instances + +After we create class, we can edit object + +* need write **getter/setter functions** to access attributes +* may need default value for attribute + +```python +class Car: + """A simple attempt to represent a car.""" + + def __init__(self, make, model, year): + """Initialize attributes to describe a car.""" + self.make = make + self.model = model + self.year = year + self.odometer_reading = 0 + + def get_descriptive_name(self): + """Return a neatly formatted descriptive name.""" + long_name = f"{self.year} {self.make} {self.model}" + return long_name.title() + + def read_odometer(self): + """Print a statement showing the car's mileage.""" + print(f"This car has {self.odometer_reading} miles on it.") + + def update_odometer(self, mileage): + """Set the odometer reading to the given value.""" + self.odometer_reading = mileage + +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() +``` + +* `get_descriptive_name()` is a getter function, so we can get private attributes +* `odometer_reading` has default value as 0 + +## Inheritance + +Use **inheritance** when the class is a specialized version of another class. + +* When one class *inherits* from another, it takes on the attributes and methods of the first class. +* Original class is called **parent class**, New class is called **child class** +* Child class can define new attributes/methods + +### __init__() for a Child Class + +Creating a `__init__()` of a child class: + +1. Call `__init__()` from parent class, to initialize parent's attributes +2. \ No newline at end of file diff --git a/src/car.py b/src/car.py new file mode 100644 index 0000000..dad4990 --- /dev/null +++ b/src/car.py @@ -0,0 +1,27 @@ +class Car: + """A simple attempt to represent a car.""" + + def __init__(self, make, model, year): + """Initialize attributes to describe a car.""" + self.make = make + self.model = model + self.year = year + self.odometer_reading = 0 + + def get_descriptive_name(self): + """Return a neatly formatted descriptive name.""" + long_name = f"{self.year} {self.make} {self.model}" + return long_name.title() + + def read_odometer(self): + """Print a statement showing the car's mileage.""" + print(f"This car has {self.odometer_reading} miles on it.") + + def update_odometer(self, mileage): + """Set the odometer reading to the given value.""" + self.odometer_reading = mileage + +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() \ No newline at end of file diff --git a/src/dog.py b/src/dog.py new file mode 100644 index 0000000..fcd7b55 --- /dev/null +++ b/src/dog.py @@ -0,0 +1,16 @@ +class Dog: + """A Simple attempt to model a dog""" + + def __init__(self, name, age): + """Initialize name and age attributes.""" + self.name = name + self.age = age + + def sit(self): + """Simulate a dog sitting in response to a command.""" + print(f"{self.name} is now sitting.") + + def roll_over(self): + """Simulate rolling over in response to a command""" + print(f"{self.name} rolled over!") + diff --git a/src/pizza.py b/src/pizza.py new file mode 100644 index 0000000..c8c7861 --- /dev/null +++ b/src/pizza.py @@ -0,0 +1,3 @@ +def make_pizza(*toppings): + """Print the list of toppings that have been requested.""" + print(toppings) \ No newline at end of file