Object Oriented Programming (OOP) --------------------------------- OOP allows you to encapsulate specific behaviour into so called classes. Instances of those classes can be used to write intuitive program code. Below is an example using classes defined in rock.py to create instances of fruits and rocks and to determine their cumulative weight on a scale. Classes can represent real world objects as in this example but also abstract things like a button in a graphical user interface or a list with special sorting algorithms. Normally you would import the classes from the module rock like this: .. code:: python #from rock import Rock, Sediment, MagneticMatter, MagneticSediment, Scale, Fruit Alternatively you can use the magic %load command to get the whole file into this ipython notebook: .. code:: python # %load rock.py # object oriented programming with Python # Michael Wack 2015 class Fruit: def __init__(self, weight): self.weight = weight def __repr__(self): return( "fruit with weight {:.2e}".format( self.weight)) class Rock: # class variable rockcounter=0 @classmethod def BlueRock(cls, weight, volume): return cls( color="blue", weight=weight, volume=volume) @staticmethod def density( weight, volume): return weight / volume def __init__(self, color, weight, volume=11e-6): self.color = color self.weight = weight # SI: kg self.volume = volume # SI: m^3 Rock.rockcounter += 1 self.no = Rock.rockcounter print("{}. rock created".format(Rock.rockcounter)) def calculate_density(self): return Rock.density( self.weight, self.volume) # SI: kg / m^3 def __repr__(self): return( "{} rock (No {}) with a density of {:.2f}".format( self.color, self.no, self.calculate_density())) class Sediment( Rock): def __init__(self, color, weight, volume=11e-6, grainsize=0): super().__init__(color, weight, volume) self.grainsize = grainsize def double_grainsize(self): self.grainsize *= 2 def __repr__(self): return( "{} sediment (No {}) with a density of {:.2e} and a grainsize of {:.2e}".format( self.color, self.no, self.calculate_density(), self.grainsize)) class MagneticMatter(): # all volume normalized def __init__(self, magnetization=0, susceptibiltiy=0): self.magnetization = magnetization # Am^2 / m^3 = A/m self.susceptibility = susceptibiltiy # volume normailzed -> no units def induced_magnetization(self, external_field_H): # SI A/m return self.susceptibility * external_field_H def total_magnetization(self, external_field_H): # SI A/m return self.induced_magnetization(external_field_H) + self.magnetization class MagneticSediment( MagneticMatter, Sediment): def __init__(self, color, weight, volume, grainsize=0, magnetization=0, susceptibility=0): MagneticMatter.__init__( self, magnetization, susceptibility) Sediment.__init__( self, color, weight, volume) def magnetic_moment(self): return self.magnetization * self.volume # class to determine weight of other object instances class Scale(): def __init__(self, weight_limit=100): self.weight_limit = weight_limit self.instances = [] def put_on(self, inst): if inst in self.instances: print("{} is already on scale.".format(inst)) else: self.instances.append(inst) print("{} placed on scale.".format(inst)) def take_off(self, inst): try: self.instances.remove(inst) print("{} removed.".format(inst)) except KeyError: print("{} was not on scale.".format(inst)) @property def weight(self): weight = 0 for i in self.instances: weight += i.weight if weight > self.weight_limit: print("Scale overloaded.") return weight .. code:: python apple = Fruit(weight=0.2) .. code:: python apple .. parsed-literal:: fruit with weight 2.00e-01 .. code:: python my_first_rock = Rock(color='red', weight=10) .. parsed-literal:: 1. rock created .. code:: python my_first_rock .. parsed-literal:: red rock (No 1) with a density of 909090.91 .. code:: python my_second_rock = Sediment(color='yellow', weight=12) .. parsed-literal:: 2. rock created .. code:: python blue_rock = Rock.BlueRock(weight=3, volume = 0.1) .. parsed-literal:: 3. rock created .. code:: python blue_rock .. parsed-literal:: blue rock (No 3) with a density of 30.00 .. code:: python my_last_rock = MagneticSediment(color='purple', weight=1, volume=0.01, magnetization=1e-3, susceptibility=5e-3) .. parsed-literal:: 4. rock created .. code:: python my_last_rock.induced_magnetization(external_field_H = 40) .. parsed-literal:: 0.2 .. code:: python my_last_rock.total_magnetization(external_field_H = 40) .. parsed-literal:: 0.201 .. code:: python myscale = Scale(weight_limit = 20) .. code:: python myscale .. parsed-literal:: <__main__.Scale at 0x7f45b01a36d8> .. code:: python myscale.put_on( blue_rock) .. parsed-literal:: blue rock (No 3) with a density of 30.00 placed on scale. .. code:: python myscale.weight .. parsed-literal:: 3 .. code:: python myscale.put_on( my_second_rock) .. parsed-literal:: yellow sediment (No 2) with a density of 1.09e+06 and a grainsize of 0.00e+00 placed on scale. .. code:: python myscale.weight .. parsed-literal:: 15 .. code:: python myscale.put_on( my_second_rock) .. parsed-literal:: yellow sediment (No 2) with a density of 1.09e+06 and a grainsize of 0.00e+00 is already on scale. .. code:: python myscale.weight .. parsed-literal:: 15 .. code:: python myscale.put_on( my_first_rock) .. parsed-literal:: red rock (No 1) with a density of 909090.91 placed on scale. .. code:: python myscale.weight .. parsed-literal:: Scale overloaded. .. parsed-literal:: 25 .. code:: python myscale.take_off( blue_rock) .. parsed-literal:: blue rock (No 3) with a density of 30.00 removed. .. code:: python myscale.weight .. parsed-literal:: Scale overloaded. .. parsed-literal:: 22