<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def effect_repertoire(self, mechanism, purview):
 """Return the effect repertoire of a mechanism over a purview. Args: mechanism (tuple[int]):
 The mechanism for which to calculate the effect repertoire. purview (tuple[int]):
 The purview over which to calculate the effect repertoire. Returns: np.ndarray: The effect repertoire of the mechanism over the purview. .. note:: The returned repertoire is a distribution over purview node states, not the states of the whole network. """

        # If the purview is empty, the distribution is empty, so return the
        # multiplicative identity.
        if not purview:
            return np.array([1.0])
        # Use a frozenset so the arguments to `_single_node_effect_repertoire`
        # can be hashed and cached.
        mechanism = frozenset(mechanism)
        # Preallocate the repertoire with the proper shape, so that
        # probabilities are broadcasted appropriately.
        joint = np.ones(repertoire_shape(purview, self.tpm_size))
        # The effect repertoire is the product of the effect repertoires of the
        # individual nodes.
        return joint * functools.reduce(
            np.multiply, [self._single_node_effect_repertoire(mechanism, p)
                          for p in purview]
        )