def weighted_choice(self, probabilities, key):
        """Makes a weighted choice between several options.

        Probabilities is a list of 2-tuples, (probability, option). The
        probabilties don't need to add up to anything, they are automatically
        scaled."""

        try:
            choice = self.values[key].lower()
        except KeyError:
            # override not set.
            result = super(OverridableParameters, self)\
                .weighted_choice(probabilities, key)
            if hasattr(result, "__call__"):
                self.results[key] = result.__name__
            else:
                self.results[key] = str(result)
            return result

        # Find the matching key (case insensitive)
        for probability, option in probabilities:
            if str(option).lower() == choice:
                self.results[key] = option
                return option

        # for function or class-type choices, also check __name__
        for probability, option in probabilities:
            if option.__name__.lower() == choice:
                self.results[key] = option.__name__
                return option

        assert False, "Invalid value provided"
Makes a weighted choice between several options.

        Probabilities is a list of 2-tuples, (probability, option). The
        probabilties don't need to add up to anything, they are automatically
        scaled.