Object-Oriented Programming Part-2

Indices and tables

Introduction

In the last topic, we defined a base class for batteries. Using inheritance, we can create different types of batteries, and specialize the characteristics of the base class battery to match.

KR6_Battery

The KR6 battery type is AA sized and uses NiCD chemistry. We can specialize the Battery base class for the KR6 battery as follows:

  • Derive a new class from the Battery base class
  • Reimplement the class variables with KR6 specific values
  • Reimplement the get_voltage() method with KR6 specific formula
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from Battery import Battery

class KR6(Battery):
    # Specialize base class variables to this type of battery
    form_factor = "AA"
    chemistry = "NiCd"
    discharged_voltage = 0.9
    charged_voltage = 1.2

    # Override the get_voltage() method to specialize it to
    # this battery
    def get_voltage(self):
        # Linearly interpolate between fully discharged and
        # fully charged voltages, based on percentage_charged.
        delta_voltage = self.charged_voltage - self.discharged_voltage
        return self.discharged_voltage + delta_voltage * (self.percent_charged / 100)

For very little work, we were able to create a new battery that took advantage of previously created logic for all but 5 of the class attributes. Fig. 49 represents the class diagram of the KR6 class that has been created:

../../_images/kr6_class_diagram.png

Fig. 50 KR6 Class Diagram

And we can see the fruits of our labor, a customized battery type!

>>> #
>>> # Import the battery type
>>> #
>>> from BatteryOrigPkg.KR6 import KR6
>>> #
>>> # Create a KR6 battery
>>> #
batt0 = KR6("K7811")
>>> #
>>> # Get the eval'able form
>>> #
>>> repr(batt0)
'KR6("K7811", 0)'
>>> #
>>> # Get the human readable form
>>> #
>>> print(batt0)
0.9v (Charge:0% Size:AA Type:NiCd SN:"K7811")
>>> #
>>> # Change it's charge level
>>> #
>>> batt0.set_percent_charged(50)
>>> print(batt0)
1.05v (Charge:50% Size:AA Type:NiCd SN:"K7811")
>>> batt0.set_percent_charged(100)
>>> print(batt0)
1.2v (Charge:100% Size:AA Type:NiCd SN:"K7811")

HR14_Battery

The HR14 battery type is C sized and uses NiMH chemistry. For this battery, we use an exponential curve to represent the discharge curve, which is easily handled using a customized get_voltage() method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from Battery import Battery


class HR14(Battery):
    # Specialize base class variables to this type of battery
    form_factor = "C"
    chemistry = "NiMH"
    discharged_voltage = 1.0
    charged_voltage = 1.2

    # Override the get_voltage() method to specialize it to
    # this battery
    def get_voltage(self):
        # For this cell, the charge to voltage conversion follows
        # a y=x^2 curve.
        return (0.4472 * self.percent_charged / 100) ** 2 + self.discharged_voltage

Taking the HR14 battery for a spin…

>>> #
>>> # Import the battery type
>>> #
>>> from BatteryOrigPkg.HR14 import HR14
>>> #
>>> # Create a HR14 battery
>>> #
batt1 = HR14("AF4194", 35)
>>> #
>>> # Get the eval'able form
>>> #
>>> repr(batt1)
'HR14("AF4194", 35)'
>>> #
>>> # Get the human readable form
>>> #
>>> print(batt1)
1.0244985104v (Charge:35% Size:C Type:NiMH SN:"AF4194")
>>> #
>>> # Change it's charge level
>>> #
>>> batt1.set_percent_charged(50)
>>> print(batt1)
1.04999696v (Charge:50% Size:C Type:NiMH SN:"AF4194")
>>> batt1.set_percent_charged(100)
>>> print(batt1)
1.19998784v (Charge:100% Size:C Type:NiMH SN:"AF4194")

LR4_Battery

The LR4 battery type is AA sized using Alkaline chemistry. For this battery, the conversion from charge to voltage is based on a piecewise curve. Again, this is easily handled using a customized get_voltage() method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from Battery import Battery

class LR4(Battery):
    # Specialize base class variables to this type of battery
    form_factor = "AA"
    chemistry = "Alkaline"
    charge_curve = {0: 0.62,
                    10: 0.98,
                    20: 1.04,
                    30: 1.08,
                    40: 1.10,
                    50: 1.12,
                    60: 1.16,
                    70: 1.20,
                    80: 1.27,
                    90: 1.35,
                    100: 1.49}
    discharged_voltage = charge_curve[0]
    charged_voltage = charge_curve[100]

    # Override the get_voltage() method to specialize it to
    # this battery
    def get_voltage(self):
        # Interpolate along the charge_curve, based on the
        # percentage charged, to get the output voltage.
        # Start by finding the lower and upper bounds in the
        # charge_curve table to interpolate over
        lower = (self.percent_charged // 10) * 10
        if self.percent_charged == 100:
            upper = 100
        else:
            upper = (self.percent_charged // 10 + 1) * 10
        # Interpolate between the lower and upper bounds
        return self.charge_curve[lower] + \
               (self.charge_curve[upper] - self.charge_curve[lower]) * (
                       upper / 100 - self.percent_charged / 100)

Taking the LR4 battery for a spin…

>>> #
>>> # Import the battery type
>>> #
>>> from BatteryOrigPkg.LR4 import LR4
>>> #
>>> # Create a LR4 battery
>>> #
batt2 = LR4("GK245-01", 25)
>>> #
>>> # Get the eval'able form
>>> #
>>> repr(batt2)
'LR4("GK245-01", 25)'
>>> #
>>> # Get the human readable form
>>> #
>>> print(batt2)
1.042v (Charge:25% Size:AA Type:Alkaline SN:"GK245-01")
>>> #
>>> # Change it's charge level
>>> #
>>> batt2.set_percent_charged(50)
>>> print(batt2)
1.124v (Charge:50% Size:AA Type:Alkaline SN:"GK245-01")
>>> batt2.set_percent_charged(100)
>>> print(batt2)
1.49v (Charge:100% Size:AA Type:Alkaline SN:"GK245-01")

Playing with Batteries

Above, we created 3 batteries (one for each type). Lets try out the various operations on them:

>>> #
>>> # Getting properties of the battery
>>> #
>>> batt0.get_num_created()
3
>>> # Remember, the instance counter is
>>> # on the base class and was never
>>> # reimplemented, so, '3' makes sense.
>>> # because we made 3 batteries.
>>> #
>>> batt0.get_form_factor()
'AA'
>>> batt0.get_chemistry()
'NiCd'
>>> batt0.get_serial_numer()
'K7811;
>>> batt0.get_percent_charged()
100
>>> batt0.get_voltage()
1.2
>>> batt1.get_voltage()
1.1998784
>>> batt2.get_voltage()
1.49
>>> #
>>> # Comparison Operations
>>> #
>>> batt0 == batt1
False
>>> batt0 != batt1
True
>>> batt0 <= batt1
False
>>> batt0 < batt1
False
>>> batt0 >= batt1
True
>>> batt0 > batt1
True
>>> #
>>> # Numerical Operations
>>> #
>>> batt0 + batt1
2.3999878399999997
>>> batt0 - batt2
-0.29000000000000004
>>> int(batt0)
1
>>> float(batt0)
1.2