<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _record_values_for_fit_summary_and_statsmodels(self):
 """ Store the various estimation results that are used to describe how well the estimated model fits the given dataset, and record the values that are needed for the statsmodels estimation results table. All values are stored on the model instance. Returns ------- None. """

        # Make sure we have all attributes needed to create the results summary
        needed_attributes = ["fitted_probs",
                             "params",
                             "log_likelihood",
                             "standard_errors"]
        try:
            assert all([hasattr(self, attr) for attr in needed_attributes])
            assert all([getattr(self, attr) is not None
                        for attr in needed_attributes])
        except AssertionError:
            msg = "Call this function only after setting/calculating all other"
            msg_2 = " estimation results attributes"
            raise NotImplementedError(msg + msg_2)

        # Record the number of observations
        self.nobs = self.fitted_probs.shape[0]
        # This is the number of estimated parameters
        self.df_model = self.params.shape[0]
        # The number of observations minus the number of estimated parameters
        self.df_resid = self.nobs - self.df_model
        # This is just the log-likelihood. The opaque name is used for
        # conformance with statsmodels
        self.llf = self.log_likelihood
        # This is just a repeat of the standard errors
        self.bse = self.standard_errors
        # These are the penalized measures of fit used for model comparison
        self.aic = compute_aic(self)
        self.bic = compute_bic(self)

        return None