Implement a new Measure

Purpose of this Chapter

The aim of this chapter to explain how to implement a new measure. This will be presented by implementing a simple example. Let’s assume that we have several tests in a group or sequence and each test returns its results. We will implement the weighted mean to combine the results.

Define the Metadata of the Measure

Note

Each measure has to inherit from the abstract base class BaseMeasure and has to implement the abstract method apply. Moreover, each measure has to provide its metadata. The following metadata has to be provided by each measure: NAME and DESCRIPTION. See also: autom8qc.measures.base.BaseMeasure

Warning

Make sure that the class name ends with the suffix Measure. Other modules will check for the suffix to identify that the class is a measure.

from autom8qc.core import exceptions
from autom8qc.measures.base import BaseMeasure
from autom8qc.qaqc.base import TestGroup

class SimpleMeasure(BaseMeasure):

    NAME = "Weighted mean"
    DESCRIPTION = "Calculates the weighted mean of the given probabilities"

Define the Supported Parameters

Each measure has to provide the supported parameters. Therefore, you have to implement the static method supported_parameters. The method allows you to access the supported parameters without creating an instance of the class. If your measure doesn’t need additional parameters, you don’t have to implement it. In our case, we don’t need additional parameters.

Implement the Constructor

The constructor is a method that is called when an object is created. In our case, we don’t have to pass the parameters to the constructor. Note that you don’t have to check the type of the parameters since a Parameter checks the type when you set the value. If you want to implement additional checks (e.g., the threshold must be between 0 and 1), you have to implement them in the constructor and raise an exception if a constraint is not satisfied. Finally, you have to call the super method check_metadata that checks if the instance is valid.

Warning

Even your measure doesn’t need parameters you have to implement the constructor since you have to call the super-constructor and to check the metadata of the measure.

def __init__(self):
    super().__init__()
    self.check_metadata()

Implement the Abstract Method

Finally, we have to implement the abstract method apply. The method takes a TestGroup or TestSequence as a parameter and returns the combined results. To access the results (pd.DataFrame) of a test group or a test sequence, you have to use the method get_results which also checks the type of the component. If the type is invalid, the method will raises an error.

def apply(self, component):
    results = self.get_results(component)
    total_weights = 0
    for item in component:
        total_weights += item.weight
        results[item.name] = results[item.name] * item.weight
    return results.sum(axis=1) / total_weights