def test_constant0_variable_2(self):
     # to avoid static method warnings in tests,
     # that by construction of the unittest package have to be expressed in such way
     self.dummy_variable = "dummy_value"
     const = Constant0()
     values = [0.0000001, 0.0000001, 0.0000002]
     loglikeli = const.calculate_loglikelihood(values)
     if abs(loglikeli) < 10000000:
         raise Exception("problem in managing constant variables")
     rand = RandomVariable()
     rand.calculate_parameters(values)
     if not rand.get_distribution_type() == "IMMEDIATE":
         raise Exception("Expected a constant!")
     loglikeli = rand.calculate_loglikelihood(values)
     if abs(loglikeli) < 10000000:
         raise Exception("problem in managing constant variables (2)")
    def read_from_string(self, distribution_type, distribution_parameters):
        """
        Read the random variable from string

        Parameters
        -----------
        distribution_type
            Distribution type
        distribution_parameters
            Distribution parameters splitted by ;
        """
        if distribution_type == "NORMAL":
            self.random_variable = Normal()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "UNIFORM":
            self.random_variable = Uniform()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "EXPONENTIAL":
            self.random_variable = Exponential()
            self.random_variable.read_from_string(distribution_parameters)
        elif distribution_type == "IMMEDIATE":
            self.random_variable = Constant0()
    def calculate_parameters(self,
                             values,
                             parameters=None,
                             force_distribution=None):
        """
        Calculate parameters of the current distribution

        Parameters
        -----------
        values
            Empirical values to work on
        parameters
            Possible parameters of the algorithm
        force_distribution
            If provided, distribution to force usage (e.g. EXPONENTIAL)

        """

        if parameters is None:
            parameters = {}

        debug_mode = parameters["debug"] if "debug" in parameters else False

        if self.random_variable is not None:
            self.random_variable.calculate_parameters(values)
        else:
            norm = Normal()
            unif = Uniform()
            expon = Exponential()
            constant = Constant0()

            if not force_distribution or not force_distribution == "EXPONENTIAL":
                likelihoods = list()
                likelihoods.append(
                    [constant,
                     constant.calculate_loglikelihood(values)])
                if force_distribution == "NORMAL" or force_distribution is None:
                    norm.calculate_parameters(values)
                    likelihoods.append(
                        [norm, norm.calculate_loglikelihood(values)])
                if force_distribution == "UNIFORM" or force_distribution is None:
                    unif.calculate_parameters(values)
                    likelihoods.append(
                        [unif, unif.calculate_loglikelihood(values)])
                if force_distribution == "EXPONENTIAL" or force_distribution is None:
                    expon.calculate_parameters(values)
                    likelihoods.append(
                        [expon, expon.calculate_loglikelihood(values)])
                likelihoods = [x for x in likelihoods if str(x[1]) != 'nan']
                likelihoods = sorted(likelihoods,
                                     key=lambda x: x[1],
                                     reverse=True)

                if debug_mode:
                    print("likelihoods = ", likelihoods)

                self.random_variable = likelihoods[0][0]
            else:
                avg_values = np.average(values)
                if values and avg_values > 0.00000:
                    expon.scale = avg_values
                    self.random_variable = expon
                else:
                    self.random_variable = constant