Intorduction to Object Oriented Programming in Python

Definition of the minimal class in two lines

Define class


In [ ]:
class A():
    pass

Use class


In [ ]:
a = A()    # create an instance of class A
print (a)
print (type(a))

Definition of a class with attributes (properties)


In [ ]:
class Human(object):
    name = ''
    age = 0

In [ ]:
human1 = Human()          # create instance of Human
human1.name = 'Anton'     # name him    (add data to this object)
human1.age = 39           # set the age (add data to this object)

print (type(human1))
print (human1.name)
print (human1.age)

Definition of a class with constructor


In [ ]:
class Human(object):
    name = ''
    age = 0
    
    def __init__(self, name):
        self.name = name

Create a Human instance and give him a name instantly


In [ ]:
h1 = Human('Anton')
print (h1.name)
print (h1.age)

Definition of a class with several methods


In [ ]:
class Human(object):
    ''' Human being '''
    name = ''
    age = 0
    
    def __init__(self, name):
        ''' Create a Human '''
        self.name = name
    
    def grow(self):
        ''' Grow a Human by one year (in-place) '''
        self.age += 1

Create a Human, give him a name, grow by one year (in-place)


In [ ]:
human1 = Human('Adam')
human1.grow()

print (human1.name)
print (human1.age)

Add get_ methods to the class


In [ ]:
class Human(object):
    ''' Human being '''
    name = ''
    age = 0
    
    def __init__(self, name):
        ''' Create a Human '''
        self.name = name
    
    def grow(self):
        ''' Grow a Human by one year (in-place) '''
        self.age += 1
    
    def get_name(self):
        ''' Return name of a Human '''
        return self.name

    def get_age(self):
        ''' Return name of a Human '''
        return self.age

In [ ]:
h1 = Human('Eva')
print (h1.get_name())

Create a class with Inheritance


In [ ]:
class Teacher(Human):
    ''' Teacher of Python '''

    def give_lecture(self):
        ''' Print lecture on the screen ''' 
        
        print ('bla bla bla')

Create an Teacher with name, grow him sufficiently, use him.


In [ ]:
t1 = Teacher('Anton')

while t1.get_age() < 50:
    t1.grow()

print (t1.get_name())
print (t1.get_age())
t1.give_lecture()

Import class definition from a module

Store class definition in a separate file. E.g.:

https://github.com/nansencenter/nansat-lectures/blob/master/human_teacher.py


In [1]:
# add directory scripts to PYTHONPATH (searchable path)
import sys
sys.path.append('scripts')

In [2]:
from human_teacher import Teacher

t1 = Teacher('Morten')
t1.give_lecture()


bla bla bla

Practical example


In [3]:
## add scripts to the list of searchable directories
import sys
sys.path.append('scripts')

# import class definiton our module
from ts_profile import Profile

# load data
p = Profile('data/tsprofile.txt')

# work with the object
print (p.get_ts_at_level(5))
print (p.get_ts_at_depth(200))
print (p.get_mixed_layer_depth(.1))


(24.6049260667, 35.3978824361)
(18.2284575833, 35.9177127349)
40.0

How would it look without OOP?

1. A lot of functions to import


In [ ]:
from st_profile import load_profile, get_ts_at_level, get_ts_at_depth
from st_profile import get_mixed_layer_depth, plot_ts

2. A lot of data to unpack and to pass between functions


In [ ]:
depth, temp, sal =  load_profile('tsprofile.txt')
print (get_ts_at_level(depth, temp, sal))

3. And imagine now we open a satellite image which has:

  • many matrices with data
  • georeference information (e.g. lon, lat of corners)
  • description of data (metadata)
  • and so on...

And here comes OOP:


In [ ]:
from nansat import Nansat
n = Nansat('satellite_filename.hdf')

Exercise

Create a class for managing data from T/S profile

The class should:

  1. Load a D/T/S profile from tsprofile.txt
  2. Print D/T/S values of all measurements
  3. Print D/T/S values and depth of measurement a from given point
  4. Print T/S values for a given depth (linear interpolation)
  5. Find a mixed layer depth

Input data

'tsprofile.txt' contains three columns of synthetic values: depth (H), temperature (T), salinity (S)

http://192.168.33.10:8888/edit/data/tsprofile.txt

Example usage

  • profile = Profile(fileName)
  • allTemperatures = profile.get_all_temperature_values()
  • t1 = profile.get_temperature_at_point(pointNumber)
  • t2 = profile.get_temperature_at_depth(depth)
  • mld = profile.get_mixed_layer_depth(threshold)

Hints

  • Add attributes temperature, salinity, depth of type list

  • Use f = open(fileName) and lines = f.readlines() to read data from file

  • If you have two measurements of e.g. temperature (t1 and t1) at two depths (d1 and d2) you can linearly interpolate between these values and calculate a temperature (t) at depth (d):

t = t1 + (d - d1) * (t2 - t1) / (d2 - d1)

  • Mixed layer can be defined as a layer, where temperature variability do not exceed a predefined threshold (water is relatively homogenous). Therefore to find a mixed layer depth, we need to loop through values of T and identify when the difference beween the value of T at one depth and at the next depth is above a threshold.

Get the nansat-lectures course material at Github: 'git clone https://github.com/nansencenter/nansat-lectures' To get stay updated: 'git pull'


In [ ]: