Introduction to Programming with Pythonipp201/wiki.files/from_ipp191/V...Iterator Design Pattern A Design Pattern is a general reusable solution to a commonly occurring problem (Wikipedia).

Post on 21-Jul-2020

10 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

Transcript

Lecture 10: Inheritance

1

Introduction to Programming

with Python

Object Oriented Programming

2

• Classes represent new data types

• Classes have attributes and methods

• Objects are instances of a class

• Design program by objects interaction

• Encapsulation

• Polymorphism

• Operator overloading

Last session

Defining Rational numbers:

• Attributes, methods, constructor

• Encapsulation

• Define operators as method

• Method overloading

• Polymorphism

• Automatic type conversion

• Fractions (already in Python)

Defining Operators• Why not use natural arithmetic operators?

• Operator precedence will be kept

• All operations are method calls

From the book Programming in Scala

Characteristics of the

Object-Oriented Paradigm

Today

6

• Inheritance

• Iterator design pattern

Use Case: CIA

U.S. Central Intelligence Agency (CIA) wishes

that you develop a system to manage its secret

agents over the world

You agreed...

7

CIA Requirements (I)

An agent has:

1. Name

2. Age

3. List of visas to enable travel

4. Current location (Headquarters as default)

The CIA wishes to send agents to places all over

the world, given that they can enter these countries

(if has visa).

That will be all..

8

Class agent - Design

• Attributes: name, age, visas list, location

• Default location: headquarters (HQ).

• Constructor: given name and age.

• Methods:

1. add_visa(self, country): add country to the list of

visas in case it is not already there.

2. send_to(self, country): check if agent can be sent

to country. If so, change location and return True.

Otherwise, return False.

3. __repr__(self)

Class Agent - Implementation

Using the class Agent

Is that all?

• Create an agent.

• Test representation string.

• Add visas.

• Send between countries.

• Send to and from HQ

Sending an agent to HQ is always valid!

Adding return to HQ

CIA Requirements (II)

Some agents are Special Agents:

• Special agents have a rank. (attribute)

• Special agents can be promoted. (method)

(Regular agents: no rank)

Solution 1: Dummy Attributes

• Add attribute rank to class Agent

• Assign dummy value (-1) for regular agents

• Verify rank validity before every access to it

For example:

def promote(self):

if self.rank < 0:

raise Exception("...")

self.rank += 1

15

Dummy Attributes

Pros

• Easy to implement

Cons

• Add code to check validity of rank

• What happens if more attributes are added?

• Bad design

Solution 2:

New Class with Duplicated Code

• Create a new class called SpecialAgent

1. Copy all code from Agent Class

2. Then:

• Add rank attribute

• Update __repr__ method

• Add promote method

Class Special Agent (1)

18

Special Agent Demo

19

Code Duplication

SpecialAgent class is almost an identical copy of

class Agent. Only 3 lines are added to support

the rank functionality.

Pros

• Very easy to implement

Cons

• Maybe the worst thing a programmer can do…

20

CIA Rejects

• Please change the word “now” to “currently”:>>> a = Agent(“Stan”, 30)

>>> a

Stan, 30

[]

Currently in: HQ

21

change

here

Encapsulation - Reminder

All implementation details are hidden inside the

class.

The CIA will not change the way they use the classes.

So, no problem. We just need to change Agent class and

update its __repr__ method.

Is it enough?

22

Testing New Agent __repr__ Method

>>> a = Agent(“Stan”, 40)

>>> a

Stan, 40

[]

Currently in: HQ

23

Code Duplication Problem

>>> sa = SpecialAgent(“Jonathan”, 40, 9)

>>> sa

Jonathan, 40

[]

Now in: HQ

Level: 9

24

Wrong!!

Code Duplication vs. Reuse

• Duplication : hard to maintain code

• Fixing bugs: in several places

• Adding new features: in several places

• Code reuse makes software development easier:

• Code is written once

• Bugs are fixed in one place only

• Features are added in one place

• Code is easier to understand

But:

how to accomplish

this with objects?

Class relationship: is-a

• A special agent is a specific type of an agent.

• A special agent is-an agent.

called: an is-a relationship

• Set of special agents is a subset of set of agents.

• Not all classes relate likewise:

• A car is not an agent

• A dolphin is not an agent (well, not always…) 26

class

extension

Implementation: Class Inheritance

Class B extends class A:

• Class B inherits from class A

• Class A is said to be a base class

• Class B is said to be a derived class

Inheritance is commonly used to reflect is-a

relationship between classes

B is a subtype of A.

Python Inheritance

class SpecialAgent(Agent):

pass

SpecialAgent is a derived class of Agent.

Base ClassDerived Class

addition:

“empty”

Code Reuse

A derived class inherits all attributes and methods

from its base class:

>>> sa = SpecialAgent("Jonathan", 40)

>>> sa

Jonathan, 40

[ ]

Now in: HQ

29

SpecialAgent

behaves

like an Agent

Overriding Methods

In order to add the rank attribute we redefine the

constructor __init__ in SpecialAgent class:

class SpecialAgent(Agent):def __init__(self, name, age, rank):

self.name = nameself.age = ageself.visas = []self.location = "HQ"self.rank = rank

The new implementation overrides the

constructor __init__ in class Agent.30

Code Reuse and Overriding

The init method is still a duplicated code!

We can solve that by an explicit call to the base

class init method, along with additional code that

is relevant only for the derived class.

31

Special Agent Constructor

32

Special

Agent

Code

Explicit

call to

Agent init

class SpecialAgent(Agent):

Adding functionality

Derived classes can have additional attributes and

methods that base classes do not have.

For example, the SpecialAgent class will have a

method to promote an agent.

33

Rules for Subclass Constructor

Do one of the following:

1. Use previous constructor

• Don’t write any code

• previous constructor used automatically

2. Write a new constructor calling the previous one

• then add fields, changes, etc.

or:

add methods

(no pass)

Rules for Inherited Methods

Always use inherited methods when possible

Important: principle of code re-use

Call for Agent’s

class methods

also:

shorter than

bad example

Special Agent Demo

36

works

as before

Class Diagram

37

name: stringage: integer

visas: list of stringlocation: string

Agent

add_visa()

send_to()

rank: integer

SpecialAgent

promote()

Remember Polymorphism?

class Cat:

def talk(self):

return 'Meow!'

class Dog:

def talk(self):

return 'Woof! Woof!'

animals = [Cat(), Dog(), Cat()]

for anim in animals:

print(anim.talk())

Polymorphism Revisited

• All agents (including special) can be treated

the same way:

__repr__ method

overrides

inherited one

CIA Requirements (III)

• Some agents are Restricted Agents.

• Cannot have more than 5 visas

• How should we add this functionality?

Certainly, not by re-writing the class!!

40

Overriding: Different Behavior

Overriding can be used also to modify class

behavior or to change it completely

• rather than just to adding to it

still use

Agent’s method

Overriding: Example

Class Diagram

43

name: stringage: integer

visas: list of stringlocation: string

Agent

add_visa()

send_to()

rank: integer

SpecialAgent

promote()

RestrictedAgent

add_visa (override)

CIA Requirements (IV)

• Establish a task force of agents

• Several agent types can be in one task force

• All task force agents receive visas together

• All task force agents are sent together

44

Polymorphism:

The TaskForce Class

Special Agent Bond

send_to(state)

Special Agent English

send_to(state)

Agent Deadpool

send_to(state)

Restr. Agent Jason

send_to(state)

Task Force Class

All agent types have

send_to method

Using the TaskForce Class

CIA Requirements (V)

Given a TaskForce object, enumerate all agents

in a reverse manner

48

Solution: Do It On your Own!

• A CIA operator can always write this code:

49

But this is wrong!

• Encapsulation principle is violated

• What if we want to change implementation?

• Change the name of the list

• Map agent names to agent objects (instead of a list)

• Not easy for the user

50

Iterator Design Pattern

A Design Pattern is a general reusable solution

to a commonly occurring problem (Wikipedia).

The Iterator Design Pattern problem provides a

way to sequentially go over the elements of a

container, without exposing implementation

details.

51

Iterator Components

• Define an __iter__() method

• __iter__() returns object with a next method

• next iterates over the elements of the container

52

it = t.__iter__()

while true:

try:

i = it.next()

iteration block

except StopIteration:

break

What happens inside a for loop?

53

returns the next item each iteration

when StopIteration is raised, we know there

are no more items to iterator over, so we

terminate the loop with break

for i in t:

iteration block How does the

for loop work?

t is iterable.

__iter__() returns an iterator object

Iterable Task Force Class

54

Iterable Task Force Demo

55

Bug in Iteration

56

Where is a4?

Iterable Task Force Class

57

isinstance and issubclass• isinstance checks the type of an instance

• issubclass checks class inheritance

>>> a = Agent(“Ted”, 13)

>>> isinstance(a, Agent)

True

>>> isinstance(a, SpecialAgent)

False

>>> sa = SpecialAgent(“Omar”, 22, 20)

>>> isinstance(sa, Agent)

True

>>> isinstance(sa, SpecialAgent)

True

>>> isinstance(sa, RestrictedAgent)

False

>>> issubclass(SpecialAgent, Agent)

True 58

issubclass

Protecting the TaskForce

option 1:

continue…

Protecting the TaskForce – Option2

option 2:

more strict

top related