100% found this document useful (2 votes)
33 views

Download Complete Advanced Computer Programming in Python 1st Edition Karim Pichara PDF for All Chapters

The document provides links to various Python programming ebooks available for download on ebookgate.com, including titles like 'Advanced Computer Programming in Python' and 'Practical Programming: An Introduction to Computer Science Using Python.' It also outlines the contents of a programming book, covering topics such as object-oriented programming, data structures, functional programming, and more. The document serves as a resource for those looking to enhance their programming skills through these ebooks.

Uploaded by

rajunadabest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
33 views

Download Complete Advanced Computer Programming in Python 1st Edition Karim Pichara PDF for All Chapters

The document provides links to various Python programming ebooks available for download on ebookgate.com, including titles like 'Advanced Computer Programming in Python' and 'Practical Programming: An Introduction to Computer Science Using Python.' It also outlines the contents of a programming book, covering topics such as object-oriented programming, data structures, functional programming, and more. The document serves as a resource for those looking to enhance their programming skills through these ebooks.

Uploaded by

rajunadabest
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 78

Get the full ebook with Bonus Features for a Better Reading Experience on ebookgate.

com

Advanced Computer Programming in Python 1st


Edition Karim Pichara

https://ebookgate.com/product/advanced-computer-programming-
in-python-1st-edition-karim-pichara/

OR CLICK HERE

DOWLOAD NOW

Download more ebook instantly today at https://ebookgate.com


Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Practical programming An introduction to computer science


using Python Jennifer Campbell

https://ebookgate.com/product/practical-programming-an-introduction-
to-computer-science-using-python-jennifer-campbell/

ebookgate.com

OpenCV with Python blueprints design and develop advanced


computer vision projects using OpenCV with Python 1st
Edition Michael Beyeler
https://ebookgate.com/product/opencv-with-python-blueprints-design-
and-develop-advanced-computer-vision-projects-using-opencv-with-
python-1st-edition-michael-beyeler/
ebookgate.com

Ultimate Python Programming 1st Edition Deepali Srivastava

https://ebookgate.com/product/ultimate-python-programming-1st-edition-
deepali-srivastava/

ebookgate.com

Expert Python Programming 2nd Edition Jaworski

https://ebookgate.com/product/expert-python-programming-2nd-edition-
jaworski/

ebookgate.com
Python Programming 4th Edition Singh A.

https://ebookgate.com/product/python-programming-4th-edition-singh-a/

ebookgate.com

Black hat Python Python programming for hackers and


pentesters 1st Edition Seitz

https://ebookgate.com/product/black-hat-python-python-programming-for-
hackers-and-pentesters-1st-edition-seitz/

ebookgate.com

OpenCV Computer Vision with Python 1st Edition Howse

https://ebookgate.com/product/opencv-computer-vision-with-python-1st-
edition-howse/

ebookgate.com

Computer Programming 1st Edition E. Balagurusamy

https://ebookgate.com/product/computer-programming-1st-edition-e-
balagurusamy/

ebookgate.com

Practical Maya Programming with Python 1st Edition


Galanakis

https://ebookgate.com/product/practical-maya-programming-with-
python-1st-edition-galanakis/

ebookgate.com
Contents

Contents 5

1 Object Oriented Programming 9


1.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Aggregation and Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.5 Multiple Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.6 Abstract Base Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
1.7 Class Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.8 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

2 Data Structures 45
2.1 Array-Based Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.2 Node-based Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
2.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

3 Functional Programming 101


3.1 Python Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.2 Decorators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
3.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

4 Meta Classes 135


4.1 Creating classes dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
4.2 Metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
4.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
6 CONTENTS

5 Exceptions 147
5.1 Exception Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
5.2 Raising exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
5.3 Exception handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
5.4 Creating customized exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
5.5 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

6 Testing 163
6.1 Unittest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
6.2 Pytest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
6.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

7 Threading 185
7.1 Threading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7.2 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
7.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

8 Simulation 209
8.1 Synchronous Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
8.2 Discrete Event Simulation (DES) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
8.3 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

9 Handling Strings and Bytes 227


9.1 Some Built-in Methods for Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
9.2 Bytes and I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
9.3 bytearrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
9.4 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

10 I/O Files 245


10.1 Context Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
10.2 Emulating files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

11 Serialization 253
11.1 Serializing web objects with JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
11.2 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
CONTENTS 7

12 Networking 263
12.1 How to identify machines on internet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
12.2 Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
12.3 Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
12.4 Client-Server Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
12.5 Sending JSON data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
12.6 Sending data with pickle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
12.7 Hands-On Activities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

13 Web Services 277


13.1 HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
13.2 REST architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
13.3 Client-side Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
13.4 Server-side Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
13.5 Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
13.6 Request Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
13.7 Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
13.8 Other architectures for Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289

14 Graphical User Interfaces 291


14.1 PyQt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
14.2 Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
14.3 Events and Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
14.4 Sender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
14.5 Creating Custom Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
14.6 Mouse and Keyboard Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
14.7 QT Designer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308

15 Solutions for Hands-On Activities 315


15.1 Solution for activity 1.1: Variable stars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
15.2 Solution for activity 1.2: Geometric Shapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
15.3 Solution for activity 2.1: Production line of bottles . . . . . . . . . . . . . . . . . . . . . . . . 326
15.4 Solution for activity 2.2: Subway Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
15.5 Solution for activity 3.1: Patients in a Hospital . . . . . . . . . . . . . . . . . . . . . . . . . . 332
8 CONTENTS

15.6 Solution for activity 3.2: Soccer Team . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334


15.7 Solution for activity 3.3: Hamburger Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
15.8 Solution for activity 4.1: MetaRobot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
15.9 Solution for activity 5.1: Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
15.10 Solution for activity 6.1: Testing the encryptor . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
15.11 Solution for activity 6.2: Testing ATMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
15.12 Solution for activity 7.1: Godzilla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
15.13 Solution for activity 7.2: Mega Godzilla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
15.14 Solution for activity 8.1: Client queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
15.15 Solution for activity 8.2: GoodZoo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
15.16 Solution for activity 9.1: Fixing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
15.17 Solution for activity 9.2: Audio files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
15.18 Solution for activity 11.1: Cashiers’ data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

Bibliography 389
KARIM PICHARA – CHRISTIAN PIERINGER

ADVANCED COMPUTER PROGRAMMING IN PYTHON


ADVANCED COMPUTER PROGRAMMING IN PYTHON

Copyright © 2017 by Karim Pichara and Christian Pieringer


All rights reserved. This book or any portion thereof may not be reproduced or used in
any manner whatsoever without the express written permission of the publisher except
for the use of brief quotations in a book review.

ISBN: 9781521232385
To our wives and children
Preface

This book contains most of the relevant topics necessary to be an advanced computer programmer. The language used
in the book is Python 3. Besides the programming language, the reader will learn most of the backbone contents in
computer programming, such as object-oriented modeling, data structures, functional programming, input/output,
simulation, graphical interfaces, and much more. We believe that the best way to learn computer programming is to
work in hands-on activities. Practical exercises make the user get familiar with the main challenges that programming
brings, such as how to model a particular problem; or how to write good code and efficient routine implementation,
among others. Most of the chapters contain a set of hands-on activities (with proposed solutions) at the end. We
encourage the readers to solve all those assignments without previously checking the solution. Challenges may be hard
for initial programmers, but while going through this book, the activities will become more achievable for the reader.
This book contains most of the material used for the Advanced Python Programming course taught at PUC University
in Chile, by professors Karim Pichara and Christian Pieringer. The course is intended for Computer Science students
as well as any other affine career that can be benefited by computer programming knowledge. Of course, this book
is not enough to become a Software Engineer; there are other necessary courses that the reader must take to learn
more advanced concepts related to the development of bigger software projects. Some of the recommended courses
are Database Systems, Data Structures, Operating Systems, Compilers, Software Engineering, Testing, Software
Architecture, and Software Design, among others. The content of this book will prepare the reader to have the necessary
background for any of the next Software Engineering courses listed above. While using this book, readers should
follow along on their computers to be able to try all the examples included in the chapters. It will be necessary that
computers have already installed the required Python libraries.
3

Authors

Karim Pichara Baksai


Ph.D. in Computer Science,
Research Area: Machine Learning and Data Science applied to Astron-
omy
Associate Professor, Computer Science Department
Pontificia Universidad Católica de Chile (PUC)

Christian Pieringer Baeza


Ph.D. in Computer Science
Research Area: Computer Vision and Machine Learning
Adjunt Professor, Computer Science Department
Pontificia Universidad Católica de Chile (PUC)
4

Acknowledgments

This book was not possible without the constant help of the teaching assistants; they gave us invaluable feedback,
code and text editions to improve the book. The main collaborators who highly contributed are Belén Saldías, Ivania
Donoso, Marco Bucchi, Patricio López, and Ignacio Becker.

We would like also thank the team of assistants who worked in the hands-on activities: Jaime Castro, Rodrigo Gómez,
Bastián Mavrakis, Vicente Dominguez, Felipe Garrido, Javiera Astudillo, Antonio Gil, and José María De La Torre.

Belén Saldías Ivania Donoso Marco Bucci

Patricio López Ignacio Becker


Chapter 1

Object Oriented Programming

In the real world, objects are tangible; we can touch and feel them, they represent something meaningful for us. In the
software engineering field, objects are a virtual representation of entities that have a meaning within a particular context.
In this sense, objects keep information/data related to what they represent and can perform actions/behaviors using
their data. Object Oriented Programming (OOP) means that programs model functionalities through the interaction
among objects using their data and behavior. The way OOP represents objects is an abstraction. It consists in to create
a simplified model of the reality taking the more related elements according to the problem context and transforming
them into attributes and behaviors. Assigning attributes and methods to objects involves two main concepts close
related with the abstraction: encapsulation and interface.

Encapsulation refers to the idea of some attributes do not need to be visualized by other objects, so we can produce
a cleaner code if we keep those attributes inside their respective object. For example, imagine we have the object
Amplifer that includes attributes tubes and power transformer. These attributes only make sense inside
the amplifier because other objects such as the Guitar do not need to interact with them nor visualize them. Hence,
we should keep it inside the object Amplifier.

Interface let every object has a “facade” to protect its implementation (internal attributes and methods) and interact
with the rest of objects. For example, an amplifier may be a very complex object with a bunch of electronic pieces
inside. Think of another object such as the Guitar player and the Guitar that only interact with the amplifier
through the input plug and knobs. Furthermore, two or more objects may have the same interface allowing us to
replace them independently of their implementation and without change how we use them. Imagine a guitar player
wants to try a tube amplifier and a solid state amp. In both cases, amplifiers have the interface (knobs an input plug)
and offer the same user experience independently of their construction. In that sense, each object can provide the
10 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

suitable interface according to the context.

1.1 Classes

From the OOP perspective, classes describe objects, and each object is an instance of a class. The class statement
allow us to define a class. For convention, we name classes using CamelCase and methods using snake_case.
Here is an example of a class in Python:

1 # create_apartment.py
2

4 class Apartment:
5 '''
6 Class that represents an apartment for sale
7 value is in USD
8 '''
9

10 def __init__(self, _id, mts2, value):


11 self._id = _id
12 self.mts2 = mts2
13 self.value = value
14 self.sold = False
15

16 def sell(self):
17 if not self.sold:
18 self.sold = True
19 else:
20 print("Apartment {} was sold"
21 .format(self._id))

To create an object, we must create an instance of a class, for example, to create an apartment for sale we have to call
the class Apartment with the necessary parameters to initialize it:

1 # instance_apartment.py
2

3 from create_apartment import Apartment


1.1. CLASSES 11

5 d1 = Apartment(_id=1, mts2=100, value=5000)


6

7 print("sold?", d1.sold)
8 d1.sell()
9 print("sold?", d1.sold)
10 d1.sell()

sold? False
sold? True
Apartment 1 was sold

We can see that the __init__ method initializes the instance by setting the attributes (or data) to the initial values,
passed as arguments. The first argument in the __init__ method is self, which corresponds to the instance itself.
Why do we need to receive the same instance as an argument? Because the __init__ method is in charge of the
initialization of the instance, hence it naturally needs access to it. For the same reason, every method defined in the
class that specifies an action performed by the instance must receive self as the first argument. We may think of
these methods as methods that belong to each instance. We can also define methods (inside a class) that are intended
to perform actions within the class attributes, not to the instance attributes. Those methods belong to the class and do
not need to receive self as an argument. We show some examples later.

Python provides us with the help(<class>) function to watch a description of a class:

1 help(Apartment)

#output

Help on class Apartment in module create_apartment:

class Apartment(builtins.object)
| Class that represents an apartment for sale
| price is in USD
|
| Methods defined here:
|
| __init__(self, _id, sqm, price)
12 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

|
| sell(self)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)

1.2 Properties

Encapsulation suggests some attributes and methods are private according to the object implementation, i.e., they
only exist within an object. Unlike other programming languages such as C++ or Java, in Python, the private concept
does not exist. Therefore all attributes/methods are public, and any object can access them even if an interface exist.
As a convention, we can suggest that an attribute or method to be private adding an underscore at the beginning
of its name. For example, _<attribute/method name>. Even with this convention, we may access directly
to the attributes or methods. We can strongly suggest that an element within an object is private using a double
underscore __<attribute/method name>. The name of this approach is name mangling. It concerns to the
fact of encoding addition semantic information into variables. Remember both approaches are conventions and good
programming practices.

Properties are the pythonic mechanism to implement encapsulation and the interface to interact with private attributes
of an object. It means every time we need that an attribute has a behavior we define it as property. In other way, we are
forced to use a set of methods that allow us to change and retrieve the attribute values, e.g, the commonly used pattern
get_value() and set_value(). This approach could generate us several maintenance problems.

The property() function allow us to create a property, receiving as arguments the functions use to get, set and delete
the attribute as property(<setter_function>, <getter_function>, <deleter_function>).
The next example shows the way to create a property:

1 # property.py
2

3 class Email:
1.2. PROPERTIES 13

5 def __init__(self, address):


6 self._email = address # A private attribute
7

8 def _set_email(self, value):


9 if '@' not in value:
10 print("This is not an email address.")
11 else:
12 self._email = value
13

14 def _get_email(self):
15 return self._email
16

17 def _del_email(self):
18 print("Erase this email attribute!!")
19 del self._email
20

21 # The interface provides the public attribute email


22 email = property(_get_email, _set_email, _del_email,
23 'This property contains the email.')

Check out how the property works once we create an instance of the Email class:

1 m1 = Email("[email protected]")
2 print(m1.email)
3 m1.email = "[email protected]"
4 print(m1.email)
5 m1.email = "kp2.com"
6 del m1.email

[email protected]
[email protected]
This is not an email address.
Erase this email attribute!!

Note that properties makes the assignment of internal attributes easier to write and read. Python also let us to define
properties using decorators. Decorators is an approach to change the behavior of a method. The way to create a
14 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

property through decorators is adding @property statement before the method we want to define as attribute. We
explain decorators in Chapter 3.

1 # property_without_decorator.py
2

3 class Color:
4

5 def __init__(self, rgb_code, name):


6 self.rgb_code = rgb_code
7 self._name = name
8

9 def set_name(self, name):


10 self._name = name
11

12 def get_name(self):
13 return self._name
14

15 name = property(get_name, set_name)

1 # property_with_decorator.py
2

3 class Color:
4

5 def __init__(self, rgb_code, name):


6 self._rgb_code = rgb_code
7 self._name = name
8

9 # Create the property using the name of the attribute. Then we


10 # define how to get/set/delet it.
11 @property
12 def name(self):
13 print("Function to get the name color")
14 return self._name
15

16 @name.setter
17 def name(self, new_name):
1.3. AGGREGATION AND COMPOSITION 15

18 print("Function to set the name as {}".format(new_name))


19 self._name = new_name
20

21 @name.deleter
22 def name(self):
23 print("Erase the name!!")
24 del self._name

1.3 Aggregation and Composition

In OOP there are different ways from which objects interact. Some objects are a composition of other objects who
only exists for that purpose. For instance, the object printed circuit board only exists inside a amplifier
and its existence only last while the amplifier exists. That kind of relationship is called composition. Another kind
of relationship between objects is aggregation, where a set of objects compose another object, but they may continue
existing even if the composed object no longer exist. For example, students and a teacher compose a classroom, but
both are not meant to be just part of that classroom, they may continue existing and interacting with other objects
even if that particular classroom disappears. In general, aggregation and composition concepts are different from the
modeling perspective. The use of them depends on the context and the problem abstraction. In Python, we can see
aggregation when the composed object receive instances of the components as arguments, while in composition, the
composed object instantiates the components at its initialization stage.

1.4 Inheritance

The inheritance concept allows us to model relationships like “object B is an object A but specialized in certain
functions”. We can see a subclass as a specialization of its superclass. For example, lets say we have a class called
Car which has attributes: brand, model and year; and methods: stop, charge_gas and fill_tires.
Assume that someone asks us to model a taxi, which is a car but has some additional specifications. Since we already
have defined the Car class, it makes sense somehow to re-use its attributes and methods to create a new Taxi class
(subclass). Of course, we have to add some specific attributes and methods to Taxi, like taximeter, fares or
create_receipt. However, if we do not take advantage of the Car superclass by inheriting from it, we will have
to repeat a lot of code. It makes our software much harder to maintain.

Besides inheriting attributes and methods from a superclass, inheritance allows us to “re-write” superclass methods.
Suppose that the subclass Motorcycle inherits from the class Vehicle. The method called fill_tires from
16 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

Vehicle has to be changed inside Motorcycle, because motorcycles (in general) have two wheels instead of four.
In Python, to modify a method in the subclass we just need to write it again, this is called overriding, so that Python
understands that every time the last version of the method is the one that holds for the rest of the code.

A very useful application of inheritance is to create subclasses that inherit from some of the Python built-in classes, to
extend them into a more specialized class. For example, if we want to create a custom class similar to the built-in class
list, we just must create a subclass that inherits from list and write the new methods we want to add:

1 # grocery_list.py
2

4 class GroceryList(list):
5

6 def discard(self, price):


7 for product in self:
8 if product.price > price:
9 # remove method is implemented in the class "list"
10 self.remove(product)
11 return self
12

13 def __str__(self):
14 out = "Grocery List:\n\n"
15 for p in self:
16 out += "name: " + p.name + " - price: "
17 + str(p.price) + "\n"
18

19 return out
20

21

22 class Product:
23

24 def __init__(self, name, price):


25 self.name = name
26 self.price = price
27

28
1.5. MULTIPLE INHERITANCE 17

29 grocery_list = GroceryList()
30

31 # extend method also belongs to 'list' class


32 grocery_list.extend([Product("bread", 5),
33 Product("milk", 10), Product("rice", 12)])
34

35 print(grocery_list)
36 grocery_list.discard(11)
37 print(grocery_list)

Grocery List:

name: bread - price: 5


name: milk - price: 10
name: rice - price: 12

Grocery List:

name: bread - price: 5


name: milk - price: 10

Note that the __str__ method makes the class instance able to be printed out, in other words, if we call
print(grocery_list) it will print out the string returned by the __str__ method.

1.5 Multiple Inheritance

We can inherit from more than one class. For example, a professor might be a teacher and a researcher, so she/he
should inherit attributes and methods from both classes:

1 # multiple_inheritance.py
2

4 class Researcher:
5

6 def __init__(self, field):


7 self.field = field
18 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

9 def __str__(self):
10 return "Research field: " + self.field + "\n"
11

12

13 class Teacher:
14

15 def __init__(self, courses_list):


16 self.courses_list = courses_list
17

18 def __str__(self):
19 out = "Courses: "
20 for c in self.courses_list:
21 out += c + ", "
22 # the [:-2] selects all the elements
23 # but the last two
24 return out[:-2] + "\n"
25

26

27 class Professor(Teacher, Researcher):


28

29 def __init__(self, name, field, courses_list):


30 # This is not completetly right
31 # Soon we will see why
32 Researcher.__init__(self, field)
33 Teacher.__init__(self, courses_list)
34 self.name = name
35

36 def __str__(self):
37 out = Researcher.__str__(self)
38 out += Teacher.__str__(self)
39 out += "Name: " + self.name + "\n"
40 return out
41

42
1.5. MULTIPLE INHERITANCE 19

43 p = Professor("Steve Iams",
44 "Meachine Learning",
45 [
46 "Python Programming",
47 "Probabilistic Graphical Models",
48 "Bayesian Inference"
49 ])
50

51 print(p)

#output

Research field: Meachine Learning


Courses: Python Programming, Probabilistic Graphical Models,
Bayesian Inference
Name: Steve Iams

Multiple Inheritance Problems

In Python, every class inherits from the Object class, that means, among other things, that every time we in-
stantiate a class, we are indirectly creating an instance of Object. Assume we have a class that inherits from
several superclasses. If we call to all the __init__ superclass methods, as we did in the previous example
(calling Researcher.__init__ and Teacher.__init__), we are calling the Object initializer twice:
Researcher.__init__ calls the initialization of Object and Teacher.__init__ calls the initialization of
Object as well. Initializing objects twice is not recommended. It is a waste of resources, especially in cases where
the initialization is expensive. It could be even worst. Imagine that the second initialization changes the setup done by
the first one, and probably the objects will not notice it. This situation is known as The Diamond Problem.

The following example (taken from [6]) shows what happens in the context of multiple-inheritance if each subclass
calls directly to initialize all its superclasses. Figure 1.1 indicates the hierarchy of the classes involved.

The example below (taken from [6]) shows what happens when we call the call() method in both superclasses from
SubClassA.

1 # diamond_problem.py
2
20 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

Figure 1.1: The diamond problem

3 class ClassB:
4 num_calls_B = 0
5

6 def make_a_call(self):
7 print("Calling method in ClassB")
8 self.num_calls_B += 1
9

10

11 class LeftSubClass(ClassB):
12 num_left_calls = 0
13

14 def make_a_call(self):
15 ClassB.make_a_call(self)
16 print("Calling method in LeftSubClass")
17 self.num_left_calls += 1
18

19

20 class RightSubClass(ClassB):
21 num_right_calls = 0
1.5. MULTIPLE INHERITANCE 21

22

23 def make_a_call(self):
24 ClassB.make_a_call(self)
25 print("Calling method in RightSubClass")
26 self.num_right_calls += 1
27

28

29 class SubClassA(LeftSubClass, RightSubClass):


30 num_calls_subA = 0
31

32 def make_a_call(self):
33 LeftSubClass.make_a_call(self)
34 RightSubClass.make_a_call(self)
35 print("Calling method in SubClassA")
36 self.num_calls_subA += 1
37

38

39 if __name__ == '__main__':
40 s = SubClassA()
41 s.make_a_call()
42 print("SubClassA: {}".format(s.num_calls_subA))
43 print("LeftSubClass: {}".format(s.num_left_calls))
44 print("RightSubClass: {}".format(s.num_right_calls))
45 print("ClassB: {}".format(s.num_calls_B))

Calling method in ClassB


Calling method in LeftSubClass
Calling method in ClassB
Calling method in RightSubClass
Calling method in SubClassA
SubClassA: 1
LeftSubClass: 1
RightSubClass: 1
ClassB: 2

From the output, we can see that the upper class in the hierarchy (ClassB) is called twice, despite that we just directly
22 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

call it once in the code.

Every time that one class inherits from two classes, a diamond structure is created. We refer the readers to
https://www.python.org/doc/newstyle/ for more details about new style classes. Following the same example shown
above, if instead of calling the make_a_call() method we call the __init__ method, we would be initializing
Object twice.

Solution to the diamond problem

One possible solution to the diamond problem is that each class must call the initialization of the superclass that
precedes it in the multiple inheritance resolution order. In Python, the order goes from left to right on the list of
superclasses from where the subclass inherits.

In this case, we just should call to super(), because Python will make sure to call the parent class in the multiple in-
heritance resolution order. In the previous example, after the subclass goes LeftSubclass, then RightSubClass,
and finally ClassB. From the following output, we can see that each class was initialized once:

1 # diamond_problem_solution.py
2

3 class ClassB:
4 num_calls_B = 0
5

6 def make_a_call(self):
7 print("Calling method in ClassB")
8 self.num_calls_B += 1
9

10

11 class LeftSubClass(ClassB):
12 num_left_calls = 0
13

14 def make_a_call(self):
15 super().make_a_call()
16 print("Calling method in LeftSubClass")
17 self.num_left_calls += 1
18

19
1.5. MULTIPLE INHERITANCE 23

20 class RightSubClass(ClassB):
21 num_right_calls = 0
22

23 def make_a_call(self):
24 super().make_a_call()
25 print("Calling method in RightSubClass")
26 self.num_right_calls += 1
27

28

29 class SubClassA(LeftSubClass, RightSubClass):


30 num_calls_subA = 0
31

32 def make_a_call(self):
33 super().make_a_call()
34 print("Calling method in SubClassA")
35 self.num_calls_subA += 1
36

37 if __name__ == '__main__':
38

39 s = SubClassA()
40 s.make_a_call()
41 print("SubClassA: {}".format(s.num_calls_subA))
42 print("LeftSubClass: {}".format(s.num_left_calls))
43 print("RightSubClass: {}".format(s.num_right_calls))
44 print("ClassB: {}".format(s.num_calls_B))

Calling method in ClassB


Calling method in RightSubClass
Calling method in LeftSubClass
Calling method in SubClassA
SubClassA: 1
LeftSubClass: 1
RightSubClass: 1
ClassB: 1
24 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

Method Resolution Order

The mro method shows us the hierarchy order. It is very useful in more complex multiple-inheritance cases. Python
uses the C3 [3] algorithm to calculate a linear order among the classes involved in multiple inheritance schemes.

1 # mro.py
2

3 from diamond_problem_solution import SubClassA


4

5 for c in SubClassA.__mro__:
6 print(c)

<class ’diamond_problem_solution.SubClassA’>
<class ’diamond_problem_solution.LeftSubClass’>
<class ’diamond_problem_solution.RightSubClass’>
<class ’diamond_problem_solution.ClassB’>
<class ’object’>

The next example describes a case of an unrecommended initialization. The C3 algorithm generates an error because
it cannot create a logical order:

1 # invalid_structure.py
2

3 class X():
4 def call_me(self):
5 print("I'm X")
6

8 class Y():
9 def call_me(self):
10 print("I'm Y")
11

12

13 class A(X, Y):


14 def call_me(self):
15 print("I'm A")
16
1.5. MULTIPLE INHERITANCE 25

17

18 class B(Y, X):


19 def call_me(self):
20 print("I'm B")
21

22

23 class F(A, B):


24 def call_me(self):
25 print("I'm F")
26

27 # TypeError: Cannot create a consistent method resolution


28 # order (MRO) for bases X, Y

Traceback (most recent call last):


File "/codes/invalid_structure.py",
line 24, in <module>
class F(A, B):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases X, Y

A Multiple Inheritance Example

Here we present another case of multiple-inheritance, showing the wrong and the right way to call the initialization of
superclasses:

Wrong initialization of the superclass’ __init__ method

Calling directly to superclasses’ __init__ method inside the class Customer, as we show in the next example, is
highly not recommended. We could initiate a superclass multiple times, as we mentioned previously. In this example,
a call to object’s __init__ is done twice:

1 # inheritance_wrong.py
2

4 class AddressHolder:
5

6 def __init__(self, street, number, city, state):


26 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

7 self.street = street
8 self.number = number
9 self.city = city
10 self.state = state
11

12

13 class Contact:
14

15 contact_list = []
16

17 def __init__(self, name, email):


18 self.name = name
19 self.email = email
20 Contact.contact_list.append(self)
21

22

23 class Customer(Contact, AddressHolder):


24

25 def __init__(self, name, email, phone,


26 street, number, state, city):
27 Contact.__init__(self, name, email)
28 AddressHolder.__init__(self, street, number,
29 state, city)
30 self.phone = phone
31

32

33 if __name__ == "__main__":
34

35 c = Customer('John Davis', 'jp@g_mail.com', '23542331',


36 'Beacon Street', '231', 'Cambridge', 'Massachussets')
37

38 print("name: {}\nemail: {}\naddress: {}, {}"


39 .format(c.name, c.email, c.street, c.state))

name: John Davis


email: jp@g_mail.com
1.5. MULTIPLE INHERITANCE 27

address: Beacon Street, Massachussets

The right way: *args y **kwargs

Before showing the fixed version of the above example, we show how to use a list of arguments (*args) and keyword
arguments (**kwargs). In this case *args refers to a Non-keyword variable length argument list, where the
operator * unpacks the content inside the list args and pass them to a function as positional arguments.

1 # args_example.py
2

3 def method2(f_arg, *argv):


4 print("first arg normal: {}".format(f_arg))
5 for arg in argv:
6 print("the next arg is: {}".format(arg))
7

8 if __name__ == "__main__":
9 method2("Lorem", "ipsum", "ad", "his", "scripta")

first arg normal: Lorem


the next arg is: ipsum
the next arg is: ad
the next arg is: his
the next arg is: scripta

Similarly, **kwargs refers to a keyword variable-length argument list, where ** maps all the elements within the
dictionary kwargs and pass them to a function as non-positional arguments. This method is used to send a variable
amount of arguments to a function:

1 # kwargs_example.py
2

3 def method(arg1, arg2, arg3):


4 print("arg1: {}".format(arg1))
5 print("arg2: {}".format(arg2))
6 print("arg3: {}".format(arg3))
7

8
28 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

9 if __name__ == "__main__":
10 kwargs = {"arg3": 3, "arg2": "two"}
11 method(1, **kwargs)

arg1: 1
arg2: two
arg3: 3

Now that we know how to use *args and **kwargs, we can figure out how to properly write an example of
multiple inheritance as shown before:

1 # inheritance_right.py
2

4 class AddressHolder:
5

6 def __init__(self, street, number, city, state, **kwargs):


7 super().__init__(**kwargs)
8 self.street = street
9 self.number = number
10 self.city = city
11 self.state = state
12

13

14 class Contact:
15 contact_list = []
16

17 def __init__(self, name, email, **kwargs):


18 super().__init__(**kwargs)
19 self.name = name
20 self.email = email
21 Contact.contact_list.append(self)
22

23

24 class Customer(Contact, AddressHolder):


25
1.5. MULTIPLE INHERITANCE 29

26 def __init__(self, phone_number, **kwargs):


27 super().__init__(**kwargs)
28 self.phone_number = phone_number
29

30

31 if __name__ == "__main__":
32

33 c = Customer(name='John Davis', email='jp@g_mail.com',


34 phone_number='23542331', street='Beacon Street',
35 number='231', city='Cambridge', state='Massachussets')
36

37 print("name: {}\nemail: {}\naddress: {}, {}".format(c.name, c.email,


38 c.street, c.state))

name: John Davis


email: jp@g_mail.com
address: Beacon Street, Massachussets

As we can see in the above example, each class manage its own arguments passing the rest of the non-used arguments
to the higher classes in the hierarchy. For example, Customer passes all the non-used argument (**args) to
Contact and to AddressHolder through the super() function.

Polymorfism

Imagine that we have the ChessPiece class. This class has six subclasses: King, Queen, Rook, Bishop,
Knight, and Pawn. Each subclass contains the move method, but that method behaves differently on each subclass.
The ability to call a method with the same name but with different behavior within subclasses is called Polymorphism.
There are mainly two flavors of polymorphism:

• Overriding: occurs when a subclass implements a method that replaces the same method previously implemented
in the superclass.

• Overloading: happens when a method is implemented more than once, having a different number of arguments
on each case. Python does not support overloading because it is not really necessary. Each method can have a
variable number of arguments by using a keyworded o non-keyworded list of arguments. Recall that in Python
every time we implement a method more than once, the last version is the only one that Python will use. Other
30 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

programming languages support overloading, automatically detecting what method implementation to use
depending on the number of present arguments when the method is called.

The code bellow shows an example of Overriding. The Variable class represents data of any kind. The Income
class contains a method to calculate the representative value for it. In Income, the representative value is the average,
in City, the representative value is the most frequent city, and in JobTitle, the representative value is the job with
highest range, according to the _range dictionary:

1 # polymorfism_1.py
2

3 class Variable:
4 def __init__(self, data):
5 self.data = data
6

7 def representative(self):
8 pass
9

10

11 class Income(Variable):
12 def representative(self):
13 return sum(self.data) / len(self.data)
14

15

16 class City(Variable):
17 # class variable
18 _city_pop_size = {'Shanghai': 24000, 'Sao Paulo': 21300, 'Paris': 10800,
19 'London': 8600, 'Istambul': 15000,
20 'Tokyo': 13500, 'Moscow': 12200}
21

22 def representative(self):
23 dict = {City._city_pop_size[c]: c for c in self.data
24 if c in City._city_pop_size.keys()}
25 return dict[max(dict.keys())]
26

27

28 class JobTitle(Variable):
1.5. MULTIPLE INHERITANCE 31

29 # class variable
30 _range = {'CEO': 1, 'CTO': 2, 'Analyst': 3, 'Intern': 4}
31

32 def representative(self):
33 dict = {JobTitle._range[c]: c for c in self.data if
34 c in JobTitle._range.keys()}
35 return dict[min(dict.keys())]
36

37

38 if __name__ == "__main__":
39 income_list = Income([50, 80, 90, 150, 45, 65, 78, 89, 59, 77, 90])
40 city_list = City(['Shanghai', 'Sao Paulo', 'Paris', 'London',
41 'Istambul', 'Tokyo', 'Moscow'])
42 job_title_list = JobTitle(['CTO', 'Analyst', 'CEO', 'Intern'])
43 print(income_list.representative())
44 print(city_list.representative())
45 print(job_title_list.representative())

79.36363636363636
Shanghai
CEO

Operator Overriding

Python has several built-in operators that work for many of the built-in classes. For example, the operator “+” can
sum up two numbers, concatenate two strings, mix two lists, etc., depending on the object we are working with. The
following code shows an example:

1 # operator_overriding_1.py
2

3 a = [1, 2, 3, 4]
4 b = [5, 6, 7, 8]
5 print(a + b)
6

7 c = "Hello"
8 d = " World"
9 print(c + d)
32 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

[1, 2, 3, 4, 5, 6, 7, 8]
Hello World

Thanks to polymorphism, we can also personalize the method __add__ to make it work on any particular class we
want. For example, we may need to create a specific way of adding two instances of the ShoppingCart class in the
following code:

1 # operator_overriding_2.py
2

3 class ShoppingCart:
4

5 def __init__(self, product_list):


6 self.product_list = product_list # Python dictionary
7

8 def __call__(self, product_list = None):


9 if product_list is None:
10 product_list = self.product_list
11 self.product_list = product_list
12

13 def __add__(self, other_cart):


14 added_list = self.product_list
15 for p in other_cart.product_list.keys():
16 if p in self.product_list.keys():
17 value = other_cart.product_list[p] + self.product_list[p]
18 added_list.update({p: value})
19 else:
20 added_list.update({p: other_cart.product_list[p]})
21

22 return ShoppingCart(added_list)
23

24 def __repr__(self):
25 return "\n".join("Product: {} | Quantity: {}".format(
26 p, self.product_list[p]) for p in self.product_list.keys()
27 )
28

29
1.5. MULTIPLE INHERITANCE 33

30 if __name__ == "__main__":
31 s_cart_1 = ShoppingCart({'muffin': 3, 'milk': 2, 'water': 6})
32 s_cart_2 = ShoppingCart({'milk': 5, 'soda': 2, 'beer': 12})
33 s_cart_3 = s_cart_1 + s_cart_2
34 print(s_cart_3.product_list)
35 print(s_cart_3)

{’soda’: 2, ’water’: 6, ’milk’: 7, ’beer’: 12, ’muffin’: 3}


Product: soda | Quantity: 2
Product: water | Quantity: 6
Product: milk | Quantity: 7
Product: beer | Quantity: 12
Product: muffin | Quantity: 3

The __repr__ method allows us to generate a string that will be used everytime we ask to print any instance of
the class. We could also implement the __str__ method instead, it works almost exactly as __repr__, the main
difference is that __str__ should be used when we need a user friendly print of the object instance, related to the
particular context where it is used. The __repr__ method should generate a more detailed printing, containing all the
necessary information to understand the instance. In cases where __str__ and __repr__ are both implemented,
Python will use __str__ when print(instance) is called. Hence, __repr__ will be used only if __str__
is not implemented.

There are other operators that we can override, for example “less than” (__lt__), “greather than” (__gt__) and
“equal” (__eq__). We refer the reader to https://docs.python.org/3.4/library/operator.html
for a detailed list of built-in operators. Here is an example that shows how to override the __lt__ method for
implementing the comparison between two elements of the Point class:

1 # operator_overriding_3.py
2

3 class Point:
4

5 def __init__(self, x, y):


6 self.x = x
7 self.y = y
8

9 def __lt__(self, other_point):


34 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

10 self_mag = (self.x ** 2) + (self.y ** 2)


11 other_point_mag = (other_point.x ** 2) + (other_point.y ** 2)
12 return self_mag < other_point_mag
13

14 if __name__ == "__main__":
15 p1 = Point(2, 4)
16 p2 = Point(8, 3)
17 print(p1 < p2)

True

Duck Typing

The most common way to define it is "If it walks like a duck and quacks like a duck, then it is a duck." In other words,
it does not matter what kind of object performs the action, if it can do it, let it do it. Duck typing is a feature that
some programming languages have that makes polymorphism less attractive because it allows polymorphic behavior
without inheritance. In the next example, we can see that the activate function makes a duck scream and walk.
Despite that the method is implemented for Duck objects, it can be used with any object that has the scream and
walk methods implemented:

1 # duck_typing.py
2

4 class Duck:
5

6 def scream(self):
7 print("Cuack!")
8

9 def walk(self):
10 print("Walking like a duck...")
11

12

13 class Person:
14

15 def scream(self):
16 print("Ahhh!")
1.6. ABSTRACT BASE CLASS 35

17

18 def walk(self):
19 print("Walking like a human...")
20

21

22 def activate(duck):
23 duck.scream()
24 duck.walk()
25

26 if __name__ == "__main__":
27 Donald = Duck()
28 John = Person()
29 activate(Donald)
30 # this is not supported in other languajes, because John
31 # is not a Duck object
32 activate(John)

Cuack!
Walking like a duck...
Ahhh!
Walking like a human...

Typed programming languages that verify the type of objects during compilation time, such as C/C++, do not support
duck typing because in the list of arguments the object’s type has to be specified.

1.6 Abstract Base Class

Abstract classes in a programming language allow us to represent abstract objects better. What is an abstract object?
Abstract objects are created only to be inherited, so it does not make any sense to instantiate them. For example,
imagine that we have cars, buses, ships, and planes. Each one has similar properties (passengers capacity, color,
among others) and actions (load, move, stop) but they implement their methods differently: it is not the same to stop a
ship than a car. For this reason, we can create the class called Vehicle, to be a superclass of Car, Bus, Ship and
Plane.

Our problem now is how do we define Vehicle’s actions. We cannot define any of those behaviors inside Vehicle.
We can only do it inside any of its subclasses. That explains why it does not make any sense to instantiate the abstract
36 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

class Vehicle. Hence, it is recommended to make sure that abstract classes are not going to be instantiated in the
code, by raising an exception in case any programmer attempts to instantiate it.

We can also have abstract methods, in other words, methods that have to be defined in the subclasses because their
implementation makes no sense to occur in the abstract class. Abstract classes can also have traditional (non abstract)
methods when they do not need to be modified withing the subclasses. Let’s try to define abstract classes and abstract
methods in Python. The following code shows an example:

1 # 01_abstract_1.py
2

3 class Base:
4 def func_1(self):
5 raise NotImplementedError()
6

7 def func_2(self):
8 raise NotImplementedError()
9

10 class SubClass(Base):
11 def func_1(self):
12 print("func_1() called...")
13 return
14

15 # We intentionally did not implement func_2


16

17 b1 = Base()
18 b2 = SubClass()
19 b2.func_1()
20 b2.func_2()

func_1() called...
-----------------------------------------------------
NotImplementedError Traceback (most recent call last)
<ipython-input-17-0803174cce17> in <module>()
16 b2 = SubClass()
17 b2.func_1()
---> 18 b2.func_2()
1.6. ABSTRACT BASE CLASS 37

<ipython-input-17-0803174cce17> in func_2(self)
4
5 def func_2(self):
----> 6 raise NotImplementedError()
7
8 class SubClass(Base):

NotImplementedError:

The problem with this approach is that the program lets us instantiate Base without complaining, that is not what we
want. It also allows us not to implement all the needed methods in the subclass. An Abstract class allows the class
designer to assert that the user will implement all the required methods in the respective subclasses.

Python, unlike other programming languages, does not have a built-in way to declare abstract classes. Fortunately,
we can import the ABC module (stands for Abstract Base Class), that satisfies our requirements. The following code
shows an example:

1 # 03_ABC_1.py
2

3 from abc import ABCMeta, abstractmethod


4

6 class Base(metaclass=ABCMeta):
7 @abstractmethod
8 def func_1(self):
9 pass
10

11 @abstractmethod
12 def func_2(self):
13 pass
14

15

16 class SubClass(Base):
17 def func_1(self):
18 pass
19
38 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

20 # We intentionally did not implement func_2


21

22 print('Is it subclass?: {}'.format(issubclass(SubClass, Base)))


23 print('Is it instance?: {}'.format(isinstance(SubClass(), Base)))

Is it subclass?: True
-----------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-19-b1003dd6fd92> in <module>()
17
18 print(’Is it subclass?: {}’.format(issubclass(SubClass, Base)))
---> 19 print(’Is it instance?: {}’.format(isinstance(SubClass(), Base)))

TypeError: Can’t instantiate abstract class SubClass with abstract methods ’ \


’func_2

1 # 04_ABC_2.py
2

3 print('Trying to generate an instance of the Base class\n')


4 a = Base()

Trying to generate an instance of the Base class


---------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-20-e8aa694c9937> in <module>()
1 print(’Trying to generate an instance of the Base class\n’)
----> 2 a = Base()

TypeError: Can’t instantiate abstract class Base with abstract methods


func_1, func_2

Note that to declare a method as abstract we have to add the @abstractmethod decorator over its declaration. The
following code shows the implementation of the abstract methods:

1 # 05_ABC_3.py
2

3 from abc import ABCMeta, abstractmethod


1.7. CLASS DIAGRAMS 39

6 class Base(metaclass=ABCMeta):
7 @abstractmethod
8 def func_1(self):
9 pass
10

11 @abstractmethod
12 def func_2(self):
13 pass
14

15

16 class SubClass(Base):
17

18 def func_1(self):
19 pass
20

21 def func_2(self):
22 pass
23

24 # We forgot again to implement func_2


25

26 c = SubClass()
27 print('Subclass: {}'.format(issubclass(SubClass, Base)))
28 print('Instance: {}'.format(isinstance(SubClass(), Base)))

Subclass: True
Instance: True

1.7 Class Diagrams

By using class diagrams, we can visualize the classes that form most of the objects in our problem. Besides the classes,
we can also represent their properties, methods, and the way other classes interact with them. These diagrams belong
to a language known as Unified Modelling Language (UML). UML allows us to incorporate elements and tools to
model more complex systems, but it is out of the scope of this book. A class diagram is composed of a set of classes
40 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

and their relations. Rectangles represent classes, and they have three fields; the class name, its data (attributes and
variables), and its methods. Figure 1.2 shows an example.

Figure 1.2: UML Class diagram example

Suppose that by using OOP we want to model a database with stars that exist in a given area of the Universe. Each
star is correspond to a set of T observations, where each observation is a tuple (mi , ti , ei ), where mi is the bright
magnitude of the star in observation i, ti is the time when the observation i was obtained, and ei is the instrumental
error associated with observation i. Using UML diagrams, we can model the system as shown in figure 1.3.

Figure 1.3: UML tables for the stars model

Consider now that the TimeSeries class has methods to add an observation to the time series and to return the
average and standard deviation of the set of observations that belong to the star. We can represent the class and the
mentioned methods as in figure 1.4.

Besides the classes, we can represent the relations among them using UML notation as well. The most common types
of relations are: composition, agreggation and inheritance (Concepts explained previously in this chapter). Figure 1.5
shows an example of Composition. This relation is represented by an arrow starting from the base object towards the
target that the class is composing. The base of the connector is a black diamond. The number at the beginning and end
of the arrow represent the cardinalities, in other words, the range of the number of objects included in each side of the
relation. In this example, the number one at the beginning of the arrow and the 1, . . . , ∗ at the end, mean that one Time
Series may include a set of one or more observations, respectively.
1.7. CLASS DIAGRAMS 41

Figure 1.4: UML table for the TimeSeries class including the add_observation, average and
standard_deviation methods.

Figure 1.5: Example of the composition relation between classes in a UML diagram.

Similarly, agreggation is represented as an arrow with a hollow diamond at the base. Figure 1.6 shows an example. As
we learn previously in this chapter, here the only difference is that the database aggregates time series, but the time
series objects are entities that have a significance even out of the database where they are aggregate.

Figure 1.6: Example of the agreggation relation between classes in a UML diagram.
42 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

In UML, we represent the inheritance as a simple arrow with a hollow triangle at the head. To show an example,
consider the case of astronomical stars again. Imagine that some of the time series are periodic. It means
that there is a set of values repeated at a constant amount of time. According to that, we can define the subclass
PeriodicTimeSeries that inherits from the TimeSeries class its common attributes and behaviors. Figure
1.7 shows this example in a UML diagram. The complete UML diagram for the astronomical stars example is shown
in figure 1.8.

Figure 1.7: Example of the inheritance relation between classes in a UML diagram.

Figure 1.8: The complete UML diagram for the astronomical stars example.
1.8. HANDS-ON ACTIVITIES 43

1.8 Hands-On Activities

Activity 1.1

Variable stars are stars whose level of brightness changes with time. They are of considerable interest in the
astronomical community. Each star belongs to one of the possible classes of variability. Some of the classes are RR
Lyrae, Eclipsing Binaries, Mira, Long Period Variables, Cepheids, and Quasars. Each star has a position in the sky
represented by RA and DEC coordinates. Stars are represented by an identifier and contain a set of observations. Each
observation is a tuple with three values: time, magnitude and error. Time value indicates the moment in which the
telescope or the instrument does the observation. The magnitude indicates the amount of brightness calculated in the
observation. The error corresponds to a range of uncertainty associated with the measurement. Many fields compose
the sky, and each field contains a huge amount of stars. For each star, we need to know the average and the variance
of the bright magnitudes. Create the necessary Python classes which allow modeling the situation described above.
Classes must have the corresponding attributes and methods. Write code to instantiate the classes involved.

Activity 1.2

A software company is building a computer program that works with geometric shapes and needs help with the initial
model. The company is interested in making the model as extensible as possible.

• Each figure has:

– A property center as an ordered pair (x,y). It should be possible to access and set it. The constructor
needs one to build a figure.

– A method translate that receives an ordered pair (a, b) and sums to each of the center’s component,
the components in (a, b).

– A property perimeter that should be calculated with the figure’s dimensions.

– A property area that should be calculated with the figure’s dimensions.

– A method grow_area that enlarges the area of the figure x times, increasing its dimensions proportionally.
For example, in the case of a rectangle it should modify its width y length.

– A method grow_perimeter that enlarges the perimeter in x units, increasing its dimensions propor-
tionally. For example, in the case of a rectangle it should modify its width y length.

– Each time a figure is printed, the output should have the following format:
ClassName - Perimeter: value, Area: value, Center: (x, y)
44 CHAPTER 1. OBJECT ORIENTED PROGRAMMING

• A rectangle has:

– Two properties, length and width. It must be possible to access and set them. The constructor needs
both of them to build a figure.

• An Equilateral Triangle has:

– A property side that must be possible to access and to set. The constructor needs it to build a figure.

Implement all the necessary classes to represent the model proposed. Some of the classes and methods might be
abstract. Also implement a vertices property for all the figures that returns a list of ordered pairs (x, y). Hint:
Recall that to change what print(object) shows, you have to override the method __repr__.
Chapter 2

Data Structures

We define a data structure as a specific way to group and manage the information, such that we can efficiently use the
data. Opposite to the simple variables, a data structure is an abstract data type that involves a high level of abstraction,
and therefore a tight relation with OOP. We will show the Python implementation of every data structure according to
its conceptual model. Each data structure depends on the problem’s context and design, and the expected efficiency
of our algorithm. In conclusion, choosing the right data structure impacts directly on the outcome of any software
development project.

In Python, we could create a simple data structure by using an empty object without methods and add the attributes
along with our program. However, using empty classes is not recommended, because:

• i) it requires a lot of memory to keep tracked all the potentially new attributes, names, and values.

• ii) it decreases the maintainability of the code.

• iii) it is an overkill solution.

The example below shows the use of the pass sentence to let the class empty, which corresponds to a null operation.
We commonly use the pass sentence when we expect the method to be defined later. Once we create the object, we
can add more attributes.

1 # We create an empty class


2 class Video:
3 pass
4

5 vid = Video()
46 CHAPTER 2. DATA STRUCTURES

7 # We add new attributes


8 vid.ext = 'avi'
9 vid.size = '1024'
10

11 print(vid.ext, vid.size)

avi 1024

We can also create a class only with few attributes, but still without methods. Python allows us to add new attributes to
our class on the fly.

1 # We create a class with some attributes


2 class Image:
3

4 def __init__(self):
5 self.ext = ''
6 self.size = ''
7 self.data = ''
8

10 # Create an instance of the Image class


11 img = Image()
12 img.ext = 'bmp'
13 img.size = '8'
14 img.data = [255, 255, 255, 200, 34, 35]
15

16 # We add this new attribute dynamically


17 img.ids = 20
18

19 print(img.ext, img.size, img.data, img.ids)

bmp 8 [255, 255, 255, 200, 34, 35] 20

Fortunately, Python has many built-in data structures that let us manage data efficiently, such as: list, tuples,
dictionaries, sets, stacks, and queues.
2.1. ARRAY-BASED DATA STRUCTURES 47

2.1 Array-Based Data Structures

In this section, we will review a group of data structures based on the sequential order of their elements. These kinds
of structures are indexed through seq[index]. Python uses an index format that goes from 0 to n − 1, where n is
the number of elements in the sequence. Examples of this type of structures are: tuple and list.

Tuples

Tuples are useful for handling ordered data. We can get a particular element inside the tuple by using its index:

Figure 2.1: Diagram of indexing on tuples. Each cell contains a value of the tuple that could be referenced using its
index. In Python, indices go from 0 until n − 1, where the tuple has length n.

Tuples can handle various kind of data types. We can create a tuple using the tuple constructor as follows:
tuple(element0 , element1 , . . . , elementn−1 ). We can create a empty tuple using tuple() without arguments:
a = tuple(). We can also create a tuple by directly adding the tuple elements:

1 b = (0, 1, 2)
2 print(b[0], b[1])

0 1

A tuple can handle various data types. The parentheses are not mandatory during its creation:

1 c = 0, 'message'
2 print(c[0], c[1])

0 message

We can also add any object to the tuple:

1 teacher = ('Christian', '23112436-0', 2)


2 video = ('data-structures.avi', 1024, 'mp4')
3 entry = (1, teacher, video)
4 print(entry)
48 CHAPTER 2. DATA STRUCTURES

(1, (’Christian’, ’23112436-0’, 2), (’data-structures.avi’, 1024, ’mp4’))

Tuples are immutable, i.e, once we create a tuple, it is not possible to add, remove or change elements of the tuple.
This immutability allows us to use tuples as a key value in hashing-based data structures, such as dictionaries. In
the next example, we create a tuple with three elements: an instance of the class Image, a string, and a float.
Then, we attempt to change the element in position 0 by a string. We can see that this attempt raise a TypeError
exception:

1 a = ('this is' , 'a tuple', 'of strings')


2 a[1] = 'new data'

Traceback (most recent call last):


File "05_tuple_inmutable.py", line 2, in <module>
a[1] = ’new data’
TypeError: ’tuple’ object does not support item assignment

We can map tuples into a set of individual variables. For example, if a function returns a tuple with several values,
the tuple can be assigned separately to a set of individual variables. The code below shows an example, the function
compute_geometry() receives as input the sides a and b of a quadrilateral and returns a set of geometric measures:

1 def compute_geometry(a, b):


2 area = a * b
3 perimeter = (2 * a) + (2 * b)
4 mpa = a / 2
5 mpb = b / 2
6

7 return (area, perimeter, mpa, mpb)


8

9 data = compute_geometry(20.0, 10.0)


10 print('1: {0}'.format(data))
11

12 a = data[0]
13 print('2: {0}'.format(a))
14

15 # Here we unpack the values into independent variables contained


16 # in the tuple
17 a, p, mpa, mpb = data
Discovering Diverse Content Through
Random Scribd Documents
represents the actual rise. What the rise may amount to at any
particular place must be determined by other means.
This method of calculating how much the temperature of the
earth’s surface would rise or fall from an increase or a decrease in
the absolute amount of heat received is that adopted by Sir John
Herschel in his “Outlines of Astronomy,” § 369a.
About three years ago, in an article in the Reader, I endeavoured
to show that this method is not rigidly correct. It has been shown
from the experiments of Dulong and Petit, Dr. Balfour Stewart,
Professor Draper, and others, that the rate at which a body radiates
its heat off into space is not directly proportionate to its absolute
temperature. The rate at which a body loses its heat as its
temperature rises increases more rapidly than the temperature. As a
body rises in temperature the rate at which it radiates off its heat
increases; the rate of this increase, however, is not uniform, but
increases with the temperature. Consequently the temperature is not
lowered in proportion to the decrease of the sun’s heat. But at the
comparatively low temperature with which we have at present to
deal, the error resulting from assuming the decrease of temperature
to be proportionate to the decrease of heat would not be great.
It may be remarked, however, that the experiments referred to
were made on solids; but, from certain results arrived at by Dr.
Balfour Stewart, it would seem that the radiation of a material
particle may be proportionate to its absolute temperature.[24] This
physicist found that the radiation of a thick plate of glass increases
more rapidly than that of a thin plate as the temperature rises, and
that, if we go on continually diminishing the thickness of the plate
whose radiation at different temperatures we are ascertaining, we
find that as it grows thinner and thinner the rate at which it radiates
off its heat as its temperature rises becomes less and less. In other
words, as the plate grows thinner and thinner its rate of radiation
becomes more and more proportionate to its absolute temperature.
And we can hardly resist the conviction that if we could possibly go
on diminishing the thickness of the plate till we reached a film so
thin as to embrace but only one particle in its thickness, its rate of
radiation would be proportionate to its temperature. Dr. Balfour
Stewart has very ingeniously suggested the probable reason why the
rate of radiation of thick plates increases with rise of temperature
more rapidly than that of thin. It is this: all substances are more
diathermanous for heat of high temperatures than for heat of low
temperatures. When a body is at a low temperature, we may
suppose that only the exterior rows of particles supply the radiation,
the heat from the interior particles being all stopped by the exterior
ones, the substance being very opaque for heat of low temperature;
while at a high temperature we may imagine that part of the heat
from the interior particles is allowed to pass, thereby swelling the
total radiation. But as the plate becomes thinner and thinner, the
obstructions to interior radiation become less and less, and as these
obstructions are greater for radiation at low temperatures than for
radiation at high temperatures, it necessarily follows that, by
reducing the thickness of the plate, we assist radiation at low
temperatures more than we do at high.
In a gas, where each particle may be assumed to radiate by itself,
and where the particles stand at a considerable distance from one
another, the obstruction to interior radiation must be far less than in
a solid. In this case the rate at which a gas radiates off its heat as its
temperature rises must increase more slowly than that of a solid
substance. In other words, its rate of radiation must correspond
more nearly to its absolute temperature than that of a solid. If this
be the case, a reduction in the amount of heat received from the
sun, owing to an increase of his distance, should tend to produce a
greater lowering effect on the temperature of the air than it does on
the temperature of the solid ground. But as the temperature of our
climate is determined by the temperature of the air, it must follow
that the error of assuming that the decrease of temperature would
be proportionate to the decrease in the intensity of the sun’s heat
may not be great.
It may be observed here, although it does not bear directly on this
point, that although the air in a room, for example, or at the earth’s
surface is principally cooled by convection rather than by radiation,
yet it is by radiation alone that the earth’s atmosphere parts with its
heat to stellar space; and this is the chief matter with which we are
at present concerned. Air, like all other gases, is a bad radiator; and
this tends to protect it from being cooled to such an extent as it
would otherwise be, were it a good radiator like solids. True, it is
also a bad absorber; but as it is cooled by radiation into space, and
heated, not altogether by absorption, but to a very large extent by
convection, it on the whole gains its heat more easily than it loses it,
and consequently must stand at a higher temperature than it would
do were it heated by absorption alone.
But, to return; the error of regarding the decrease of temperature
as proportionate to the decrease in the amount of heat received, is
probably neutralized by one of an opposite nature, viz., that of
taking space at too high a temperature; for by so doing we make the
result too small.
We know that absolute zero is at least 493° below the melting-
point of ice. This is 222° below that of space. Consequently, if the
heat derived from the stars is able to maintain a temperature of
−239°, or 222° of absolute temperature, then nearly as much heat
is derived from the stars as from the sun. But if so, why do the stars
give so much heat and so very little light? If the radiation from the
stars could maintain a thermometer 222° above absolute zero, then
space must be far more transparent to heat-rays than to light-rays,
or else the stars give out a great amount of heat, but very little light,
neither of which suppositions is probably true. The probability is, I
venture to presume, that the temperature of space is not very much
above absolute zero. At the time when these investigations into the
probable temperature of space were made, at least as regards the
labours of Pouillet, the modern science of heat had no existence,
and little or nothing was then known with certainty regarding
absolute zero. In this case the whole matter would require to be
reconsidered. The result of such an investigation in all probability
would be to assign a lower temperature to stellar space than −239°.
Taking all these various considerations into account, it is probable
that if we adopt −239° as the temperature of space, we shall not be
far from the truth in assuming that the absolute temperature of a
place above that of space is proportionate to the amount of heat
received from the sun.
We may, therefore, in this case conclude that 59° of rise is
probably not very far from the truth, as representing the influence of
the Gulf-stream. The Gulf-stream, instead of producing little or no
effect, produces an effect far greater than is generally supposed.
Our island has a mean annual temperature of about 12° above the
normal due to its latitude. This excess of temperature has been
justly attributed to the influence of the Gulf-stream. But it is singular
how this excess should have been taken as the measure of the rise
resulting from the influence of the stream. These figures only
represent the number of degrees that the mean normal temperature
of our island stands above what is called the normal temperature of
the latitude.
The mode in which Professor Dove constructed his Tables of
normal temperature was as follows:—He took the temperature of
thirty-six equidistant points on every ten degrees of latitude. The
mean temperature of these thirty-six points he calls in each case the
normal temperature of the parallel. The excess above the normal
merely represents how much the stream raises our temperature
above the mean of all places on the same latitude, but it affords us
no information regarding the absolute rise produced. In the Pacific,
as well as in the Atlantic, there are immense masses of water
flowing from the tropical to the temperate regions. Now, unless we
know how much of the normal temperature of a latitude is due to
ocean-currents, and how much to the direct heat of the sun, we
could not possibly, from Professor Dove’s Tables, form the most
distant conjecture as to how much of our temperature is derived
from the Gulf-stream. The overlooking of this fact has led to a
general misconception regarding the positive influence of the Gulf-
stream on temperature. The 12° marked in Tables of normal
temperature do not represent the absolute effect of the stream, but
merely show how much the stream raises the temperature of our
country above the mean of all places on the same latitude. Other
places have their temperature raised by ocean-currents as well as
this country; only the Gulf-stream produces a rise of several degrees
over and above that produced by other streams in the same latitude.
At present there is a difference merely of 80° between the mean
temperature of the equator and the poles;[25] but were each part of
the globe’s surface to depend only upon the direct heat which it
receives from the sun, there ought, according to theory, to be a
difference of more than 200°. The annual quantity of heat received
at the equator is to that received at the poles (supposing the
proportionate quantity absorbed by the atmosphere to be the same
in both cases) as 12 to 4·98, or, say, as 12 to 5. Consequently, if the
temperatures of the equator and the poles be taken as proportionate
to the absolute amount of heat received from the sun, then the
temperature of the equator above that of space must be to that of
the poles above that of space as 12 to 5. What ought, therefore, to
be the temperatures of the equator and the poles, did each place
depend solely upon the heat which it receives directly from the sun?
Were all ocean and aërial currents stopped, so that there could be
no transference of heat from one part of the earth’s surface to
another, what ought to be the temperatures of the equator and the
poles? We can at least arrive at a rough estimate on this point. If we
diminish the quantity of warm water conveyed from the equatorial
regions to the temperate and arctic regions, the temperature of the
equator will begin to rise, and that of the poles to sink. It is
probable, however, that this process would affect the temperature of
the poles more than it would that of the equator; for as the warm
water flows from the equator to the poles, the area over which it is
spread becomes less and less. But as the water from the tropics has
to raise the temperature of the temperate regions as well as the
polar, the difference of effect at the equator and poles might not, on
that account, be so very great. Let us take a rough estimate. Say
that, as the temperature of the equator rises one degree, the
temperature of the poles sinks one degree and a half. The mean
annual temperature of the globe is about 58°. The mean
temperature of the equator is 80°, and that of the poles 0°. Let
ocean and aërial currents now begin to cease, the temperature of
the equator commences to rise and the temperature of the poles to
sink. For every degree that the temperature of the equator rises,
that of the poles sinks 1½°; and when the currents are all stopped
and each place becomes dependent solely upon the direct rays of
the sun, the mean annual temperature of the equator above that of
space will be to that of the poles, above that of space, as 12 to 5.
When this proportion is reached, the equator will be 374° above that
of space, and the poles 156°; for 374 is to 156 as 12 is to 5. The
temperature of space we have seen to be −239°, consequently the
temperature of the equator will in this case be 135°, reckoned from
the zero of the Fahrenheit thermometer, and the poles 83° below
zero. The equator would therefore be 55° warmer than at present,
and the poles 83° colder. The difference between the temperature of
the equator and the poles will in this case amount to 218°.
Now, if we take into account the quantity of positive energy in the
form of heat carried by warm currents from the equator to the
temperate and polar regions, and also the quantity of negative
energy (cold) carried by cold currents from the polar regions to the
equator, we shall find that they are sufficient to reduce the
difference of temperature between the poles and the equator from
218° to 80°.
The quantity of heat received in the latitude of London, for
example, is to that received at the equator nearly as 12 to 8. This,
according to theory, should produce a difference of about 125°. The
temperature of the equator above that of space, as we have seen,
would be 374°. Therefore 249° above that of space would represent
the temperature of the latitude of London. This would give 10° as its
temperature. The stoppage of all ocean and aërial currents would
thus increase the difference between the equator and the latitude of
London by about 85°. The stoppage of ocean-currents would not be
nearly so much felt, of course, in the latitude of London as at the
equator and the poles, because, as has been already noticed, in all
latitudes midway between the equator and the poles the two sets of
currents to a considerable extent compensate each other—the warm
currents from the equator raise the temperature, while the cold ones
from the poles lower it; but as the warm currents chiefly keep on the
surface and the cold return-currents are principally under-currents,
the heating effect very greatly exceeds the cooling effect. Now, as
we have seen, the stoppage of all currents would raise the
temperature of the equator 55°; that is to say, the rise at the
equator alone would increase the difference of temperature between
the equator and that of London by 55°. But the actual difference, as
we have seen, ought to be 85°; consequently the temperature of
London would be lowered 30° by the stoppage of the currents. For if
we raise the temperature of the equator 55° and lower the
temperature of London 30°, we then increase the difference by 85°.
The normal temperature of the latitude of London being 40°, the
stoppage of all ocean and aërial currents would thus reduce it to
10°. But the Gulf-stream raises the actual mean temperature of
London 10° above the normal. Consequently 30° + 10° = 40°
represents the actual rise at London due to the influence of the Gulf-
stream over and above all the lowering effects resulting from arctic
currents. On some parts of the American shores on the latitude of
London, the temperature is 10° below the normal. The stoppage of
all ocean and aërial currents would therefore lower the temperature
there only 20°.
It is at the equator and the poles that the great system of ocean
and aërial currents produces its maximum effects. The influence
becomes less and less as we recede from those places, and between
them there is a point where the influence of warm currents from the
equator and of cold currents from the poles exactly neutralize each
other. At this point the stoppage of ocean-currents would not
sensibly affect temperature. This point, of course, is not situated on
the same latitude in all meridians, but varies according to the
position of the meridian in relation to land, and ocean-currents,
whether cold or hot, and other circumstances. A line drawn round
the globe through these various points would be very irregular. At
one place, such as on the western side of the Atlantic, where the
arctic current predominates, the neutral line would be deflected
towards the equator, while on the eastern side, where warm currents
predominate, the line would be deflected towards the north. It is a
difficult problem to determine the mean position of this line; it
probably lies somewhere not far north of the tropics.
CHAPTER III.

OCEAN-CURRENTS IN RELATION TO THE DISTRIBUTION OF HEAT OVER


THE GLOBE.—(Continued.)
Influence of the Gulf-stream on the Climate of the Arctic Regions.—Absolute
Amount of Heat received by the Arctic Regions from the Sun.—Influence of
Ocean-currents shown by another Method.—Temperature of a Globe all Water
or all Land according to Professor J. D. Forbes.—An important Consideration
overlooked.—Without Ocean-currents the Globe would not be habitable.—
Conclusions not affected by Imperfection of Data.

Influence of the Gulf-stream on the Climate of the Arctic Regions.


—Does the Gulf-stream pass into the arctic regions? Are the seas
around Spitzbergen and North Greenland heated by the warm water
of the stream?
Those who deny this nevertheless admit the existence of an arctic
current. They admit that an immense mass of cold water is
continually flowing south from the polar regions around Greenland
into the Atlantic. If it be admitted, then, that a mass of water flows
across the arctic circle from north to south, it must also be admitted
that an equal mass flows across from south to north. It is also
evident that the water crossing from south to north must be warmer
than the water crossing from north to south; for the temperate
regions are warmer than the arctic, and the ocean in temperate
regions warmer than the ocean in the arctic; consequently the
current which flows into the arctic seas, to compensate for the cold
arctic current, must be a warmer current.
Is the Gulf-stream this warm current? Does this compensating
warm current proceed from the Atlantic or from the Pacific? If it
proceeds from the Atlantic, it is simply the warm water of the Gulf-
stream. We may call it the warm water of the Atlantic if we choose;
but this cannot materially affect the question at issue, for the heat
which the waters of the Atlantic possess is derived, as we have seen,
to an enormous extent from the water brought from the tropics by
the Gulf-stream. If we deny that the warm compensating current
comes from the Atlantic, then we must assume that it comes from
the Pacific. But if the cold current flows from the arctic regions into
the Atlantic, and the warm compensating current from the Pacific
into the arctic regions, the highest temperature should be found on
the Pacific side of the arctic regions and not on the Atlantic side; the
reverse, however, is the case. In the Atlantic, for example, the 41°
isothermal line reaches to latitude 65°30′, while in the Pacific it
nowhere goes beyond latitude 57°. The 27° isotherm reaches to
latitude 75° in the Atlantic, but in the Pacific it does not pass beyond
64°. And the 14° isotherm reaches the north of Spitzbergen in
latitude 80°, whereas on the Pacific side of the arctic regions it does
not reach to latitude 72°.
On no point of the earth’s surface does the mean annual
temperature rise so high above the normal as in the northern
Atlantic, just at the arctic circle, at a spot believed to be in the
middle of the Gulf-stream. This place is no less than 22°·5 above the
normal, while in the northern Pacific the temperature does not
anywhere rise more than 9° above the normal. These facts prove
that the warm current passes up the Atlantic into the arctic regions
and not up the Pacific, or at least that the larger amount of warm
water must pass into the arctic regions through the Atlantic. In other
words, the Gulf-stream is the warm compensating current. Not only
must there be a warm stream, but one of very considerable
magnitude, in order to compensate for the great amount of cold
water that is constantly flowing from the arctic regions, and also to
maintain the temperature of those regions so much above the
temperature of space as they actually are.
No doubt, when the results of the late dredging expedition are
published, they will cast much additional light on the direction and
character of the currents forming the north-eastern branch of the
Gulf-stream.
The average quantity of heat received by the arctic regions as a
whole per unit surface to that received at the equator, as we have
already seen, is as 5·45 to 12, assuming that the percentage of rays
cut off by the atmosphere is the same at both places. In this case
the mean annual temperature of the arctic regions, taken as a
whole, would be about −69°, did those regions depend entirely for
their temperature upon the heat received directly from the sun. But
the temperature would not even reach to this; for the percentage of
rays cut off by the atmosphere in arctic regions is generally believed
to be greater than at the equator, and consequently the actual mean
quantity of heat received by the arctic regions will be less than
5·45−12ths of what is received at the equator.
In the article on Climate in the “Encyclopædia Britannica” there is
a Table calculated upon the principle that the quantity of heat cut off
is proportionate to the number of aërial particles which the rays
have to encounter before reaching the surface of the earth—that, as
a general rule, if the tracts of the rays follow an arithmetical
progression, the diminished force with which the rays reach the
ground will form a decreasing geometrical progression. According to
this Table about 75 per cent. of the sun’s rays are cut off by the
atmosphere in arctic regions. If 75 per cent. of the rays were cut off
by the atmosphere in arctic regions, then the direct rays of the sun
could not maintain a mean temperature 100° above that of space.
But this is no doubt much too high a percentage for the quantity of
heat cut off; for recent discoveries in regard to the absorption of
radiant heat by gases and vapours prove that Tables computed on
this principle must be incorrect. The researches of Tyndall and
Melloni show that when rays pass through any substance, the
absorption is rapid at first: but the rays are soon “sifted,” as it is
called, and they then pass onwards with but little further
obstruction. Still, however, owing to the dense fogs which prevail in
arctic regions, the quantity of heat cut off must be considerable. If
as much as 50 per cent. of the sun’s rays are cut off by the
atmosphere in arctic regions, the amount of heat received directly
from the sun would not be sufficient to maintain a mean annual
temperature of −100°. Consequently the arctic regions must depend
to an enormous extent upon ocean-currents for their temperature.
Influence of Ocean-currents shown by another Method.—That the
temperature of the arctic regions would sink enormously, and the
temperature of the equator rise enormously, were all ocean-currents
stopped, can be shown by another method—viz., by taking the mean
annual temperature from the equator to the pole along a meridian
passing through the ocean, say, the Atlantic, and comparing it with
the mean annual temperature taken along a meridian passing
through a great continent, say, the Asiatic.
Professor J. D. Forbes, in an interesting memoir,[26] has
endeavoured by this method to determine what would be the
temperature of the equator and the poles were the globe all water
or all land. He has taken the temperature of the two meridians from
the tables and charts of Professor Dove, and ascertained the exact
proportion of land and water on every 10° of latitude from the
equator to the poles, with the view of determining what proportion
of the average temperature of the globe in each parallel is due to
the land, and what to the water which respectively belongs to it. He
next endeavours to obtain a formula for expressing the mean
temperature of a given parallel, and thence arrives at “an
approximate answer to the inquiry as to what would have been the
equatorial or polar temperature of the globe, or that of any latitude,
had its surface been entirely composed of land or of water.”
The result at which he arrived is this: that, were the surface of the
globe all water, 71°·7 would be the temperature of the equator, and
12°·5 the temperature of the poles; and were the surface all land,
109°·8 would be the temperature of the equator, and −25°·6 the
temperature of the poles.
But in Professor Forbes’s calculations no account whatever is taken
of the influence of currents, whether of water or of air, and the
difference of temperature is attributed wholly to difference of
latitude and the physical properties of land and water in relation to
their powers in absorbing and detaining the sun’s rays, and to the
laws of conduction and of convection which regulate the internal
motion of heat in the one and in the other. He considers that the
effects of currents are all compensatory.
“If a current of hot water,” he says, “moderates the cold of a
Lapland winter, the counter-current, which brings the cold of
Greenland to the shores of the United States, in a great measure
restores the balance of temperature, so far as it is disturbed by this
particular influence. The prevalent winds, in like manner, including
the trade-winds, though they render some portions of continents, on
the average, hotter or colder than others, produce just the contrary
effect elsewhere. Each continent, if it has a cold eastern shore, has
likewise a warm western one; and even local winds have for the
most part established laws of compensation. In a given parallel of
latitude all these secondary causes of local climate may be imagined
to be mutually compensatory, and the outstanding gradation of
mean or normal temperature will mainly depend, 1st, upon the
effect of latitude simply; 2nd, on the distribution of land and water
considered in their primary or statical effect.”
It is singular that a physicist so acute as Professor Forbes should,
in a question such as this, leave out of account the influence of
currents, under the impression that their effects were compensatory.
If there is a constant transference of hot water from the equatorial
regions to the polar, and of cold water from the polar regions to the
equatorial (a thing which Professor Forbes admitted), then there can
only be one place between the equator and the pole where the two
sets of currents compensate each other. At all places on the
equatorial side of this point a cooling effect is the result. Starting
from this neutral point, the preponderance of the cooling effect over
the heating increases as we approach towards the equator, and the
preponderance of the heating effect over the cooling increases as we
recede from this point towards the pole—the cooling effect reaching
a maximum at the equator, and the heating effect a maximum at the
pole.
Had Professor Forbes observed this important fact, he would have
seen at once that the low temperature of the land in high latitudes,
in comparison with that of the sea, was no index whatever as to how
much the temperature of those regions would sink were the sea
entirely removed and the surface to become land; for the present
high temperature of the sea is not due wholly to the mere physical
properties of water, but to a great extent is due to the heat brought
by currents from the equator. Now, unless it is known how much of
the absolute temperature of the ocean in those latitudes is due to
currents, we cannot tell how much the removal of the sea would
lower the absolute temperature of those places. Were the sea
removed, the continents in high latitudes would not simply lose the
heating advantages which they presently derive from the mere fact
of their proximity to so much sea, but the removal would, in addition
to this, deprive them of an enormous amount of heat which they at
present receive from the tropics by means of ocean-currents. And,
on the other hand, at the equator, were the sea removed, the
continents there would not simply lose the cooling influences which
result from their proximity to so much water, but, in addition to this,
they would have to endure the scorching effects which would result
from the heat which is at present carried away from the tropics by
ocean-currents.
We have already seen that Professor Forbes concluded that the
removal of the sea would raise the mean temperature of the equator
30°, and lower the temperature of the poles 28°; it is therefore
perfectly certain that, had he added to his result the effect due to
ocean-currents, and had he been aware that about one-fifth of all
the heat possessed by the Atlantic is actually derived from the
equator by means of the Gulf-stream, he would have assigned a
temperature to the equator and the poles, of a globe all land,
differing not very far from what I have concluded would be the
temperature of those places were all ocean and aërial currents
stopped, and each place to depend solely upon the heat which it
received directly from the sun.
Without Ocean-currents the Globe would not be habitable.—All
these foregoing considerations show to what an extent the climatic
condition of our globe is due to the thermal influences of ocean-
currents.
As regards the northern hemisphere, we have two immense
oceans, the Pacific and the Atlantic, extending from the equator to
near the north pole, or perhaps to the pole altogether. Between
these two oceans lie two great continents, the eastern and the
western. Owing to the earth’s spherical form, far too much heat is
received at the equator and far too little at high latitudes to make
the earth a suitable habitation for sentient beings. The function of
these two great oceans is to remove the heat from the equator and
carry it to temperate and polar regions. Aërial currents could not do
this. They might remove the heat from the equator, but they could
not, as we have already seen, carry it to the temperate and polar
regions; for the greater portion of the heat which aërial currents
remove from the equator is dissipated into stellar space: the ocean
alone can convey the heat to distant shores. But aërial currents have
a most important function; for of what avail would it be, though
ocean-currents should carry heat to high latitudes, if there were no
means of distributing the heat thus conveyed over the land? The
function of aërial currents is to do this. Upon this twofold
arrangement depends the thermal condition of the globe. Exclude
the waters of the Pacific and the Atlantic from temperate and polar
regions and place them at the equator, and nothing now existing on
the globe could live in high latitudes.
Were these two great oceans placed beside each other on one
side of the globe, and the two great continents placed beside each
other on the other side, the northern hemisphere would not then be
suitable for the present order of things: the land on the central and
on the eastern side of the united continent would be far too cold.
The foregoing Conclusions not affected by the Imperfection of the
Data.—The general results at which we have arrived in reference to
the influence of ocean-currents on the climatic condition of the globe
are not affected by the imperfection of the data employed. It is
perfectly true that considerable uncertainty prevails regarding some
of the data; but, after making the fullest allowance for every
possible error, the influence of currents is so enormous that the
general conclusion cannot be materially affected. I can hardly
imagine that any one familiar with the physics of the subject will be
likely to think that, owing to possible errors in the data, the effects
have probably been doubled. Even admitting, however, that this
were proved to be the case, still that would not materially alter the
general conclusion at which we have arrived. The influence of
ocean-currents in the distribution of heat over the surface of the
globe would still be admittedly enormous, whether we concluded
that owing to them the present temperature of the equator is 55° or
27° colder than it would otherwise be, or the poles 83° or 41° hotter
than they would be did no currents exist.
Nay, more, suppose we should again halve the result; even in that
case we should have to admit that, owing to ocean-currents, the
equator is about 14° colder and the poles about 21° hotter than
they would otherwise be; in other words, we should have to admit
that, were it not for ocean-currents, the mean temperature of the
equator would be about 100° and the mean temperature of the
poles about −21°.
If the influence of ocean-currents in reducing the difference
between the temperature of the equator and poles amounted to only
a few degrees, it would of course be needless to put much weight
on any results arrived at by the method of calculation which I have
adopted; but when it is a matter of two hundred degrees, it is not at
all likely that the general results will be very much affected by any
errors which may ever be found in the data.
Objections of a palæontological nature have frequently been
urged against the opinion that our island is much indebted for its
mild climate to the influence of the Gulf-stream; but, from what has
already been stated, it must be apparent that all objections of that
nature are of little avail. The palæontologist may detect, from the
character of the flora and fauna brought up from the sea-bottom by
dredging and other means, the presence of a warm or of a cold
current; but this can never enable him to prove that the temperate
and polar regions are not affected to an enormous extent by warm
water conveyed from the equatorial regions. For anything that
palæontology can show to the contrary, were ocean-currents to
cease, the mean annual temperature of our island might sink below
the present midwinter temperature of Siberia. What would be the
thermal condition of our globe were there no ocean-currents is a
question for the physicist; not for the naturalist.
CHAPTER IV.

OUTLINE OF THE PHYSICAL AGENCIES WHICH LEAD TO SECULAR


CHANGES OF CLIMATE.
Eccentricity of the Earth’s Orbit; its Effect on Climate.—Glacial Epoch not the direct
Result of an Increase of Eccentricity.—An important Consideration overlooked.
—Change of Eccentricity affects Climate only indirectly.—Agencies which are
brought into Operation by an Increase of Eccentricity.—How an Accumulation
of Snow is produced.—The Effect of Snow on the Summer Temperature.—
Reason of the low Summer Temperature of Polar Regions.—Deflection of
Ocean-currents the chief Cause of secular Changes of Climate.—How the
foregoing Causes deflect Ocean-currents.—Nearness of the Sun in Perigee a
Cause of the Accumulation of Ice.—A remarkable Circumstance regarding the
Causes which lead to secular Changes of Climate.—The primary Cause an
Increase of Eccentricity.—Mean Temperature of whole Earth should be greater
in Aphelion than in Perihelion.—Professor Tyndall on the Glacial Epoch.—A
general Reduction of Temperature will not produce a Glacial Epoch.—Objection
from the present Condition of the Planet Mars.

Primary cause of Change of Eccentricity of the Earth’s Orbit.—


There are two causes affecting the position of the earth in relation to
the sun, which must, to a very large extent, influence the earth’s
climate; viz., the precession of the equinoxes and the change in the
eccentricity of the earth’s orbit. If we duly examine the combined
influence of these two causes, we shall find that the northern and
southern portions of the globe are subject to an excessively slow
secular change of climate, consisting in a slow periodic change of
alternate warmer and colder cycles.
According to the calculations of Leverrier, the superior limit of the
earth’s eccentricity is 0·07775.[27] The eccentricity is at present
diminishing, and will continue to do so during 23,980 years, from the
year 1800 a.d., when its value will be then ·00314.
The change in the eccentricity of the earth’s orbit may affect the
climate in two different ways; viz., by either increasing or
diminishing the mean annual amount of heat received from the sun,
or by increasing or diminishing the difference between summer and
winter temperature.
Let us consider the former case first. The total quantity of heat
received from the sun during one revolution is inversely proportional
to the minor axis.
The difference of the minor axis of the orbit when at its maximum
and its minimum state of eccentricity is as 997 to 1000. This small
amount of difference cannot therefore sensibly affect the climate.
Hence we must seek for our cause in the second case under
consideration.
There is of course as yet some little uncertainty in regard to the
exact mean distance of the sun. I shall, however, in the present
volume assume it to be 91,400,000 miles. When the eccentricity is at
its superior limit, the distance of the sun from the earth, when the
latter is in the aphelion of its orbit, is no less than 98,506,350 miles;
and when in the perihelion it is only 84,293,650 miles. The earth is
therefore 14,212,700 miles further from the sun in the former
position than in the latter. The direct heat of the sun being inversely
as the square of the distance, it follows that the amount of heat
received by the earth when in these two positions will be as 19 to
26. Taking the present eccentricity to be ·0168, the earth’s distance
during winter, when nearest to the sun, is 89,864,480 miles.
Suppose now that, according to the precession of the equinoxes,
winter in our northern hemisphere should happen when the earth is
in the aphelion of its orbit, at the time when the orbit is at its
greatest eccentricity; the earth would then be 8,641,870 miles
further from the sun in winter than at present. The direct heat of the
sun would therefore be one-fifth less during that season than at
present; and in summer one-fifth greater. This enormous difference
would affect the climate to a very great extent. But if winter under
these circumstances should happen when the earth is in the
perihelion of its orbit, the earth would then be 14,212,700 miles
nearer the sun in winter than in summer. In this case the difference
between winter and summer in the latitude of this country would be
almost annihilated. But as the winter in the one hemisphere
corresponds with the summer in the other, it follows that while the
one hemisphere would be enduring the greatest extremes of
summer heat and winter cold, the other would be enjoying a
perpetual summer.
It is quite true that whatever may be the eccentricity of the earth’s
orbit, the two hemispheres must receive equal quantities of heat per
annum; for proximity to the sun is exactly compensated by the effect
of swifter motion—the total amount of heat received from the sun
between the two equinoxes is the same in both halves of the year,
whatever the eccentricity of the earth’s orbit may be. For example,
whatever extra heat the southern hemisphere may at present
receive from the sun during its summer months owing to greater
proximity to the sun, is exactly compensated by a corresponding loss
arising from the shortness of the season; and, on the other hand,
whatever deficiency of heat we in the northern hemisphere may at
present have during our summer half year in consequence of the
earth’s distance from the sun, is also exactly compensated by a
corresponding length of season.
It has been shown in the introductory chapter that a simple
change in the sun’s distance would not alone produce a glacial
epoch, and that those physicists who confined their attention to
purely astronomical effects were perfectly correct in affirming that
no increase of eccentricity of the earth’s orbit could account for that
epoch. But the important fact was overlooked that although the
glacial epoch could not result directly from an increase of
eccentricity, it might nevertheless do so indirectly. The glacial epoch,
as I hope to show, was not due directly to an increase in the
eccentricity of the earth’s orbit, but to a number of physical agents
that were brought into operation as a result of an increase.
I shall now proceed to give an outline of what these physical
agents were, how they were brought into operation, and the way in
which they led to the glacial epoch.
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like