<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_encoder(self,param_dict, encoder_dict):
 """ run the encoder on a supplied param_dict """

        X_dict = {}
        Xcol_dict = {}
        # put each column of X in Xbycol_dict
        Xbycol_dict = {}
        for key in encoder_dict:
            if (key != 'twoway') and (key != 'threeway') and (key != 'trimmed_columns'):
                encoder = encoder_dict[key]
                param_values = param_dict[key]
                Xsub,names = encoder(key,param_values)
                X_dict[key] = Xsub
                Xcol_dict[key] = names
                for i in np.arange(0,len(names)):
                    Xbycol_dict[names[i]] = Xsub[:,i]

        # now do interactions
        inter_list = self._inter_list
        for interaction in inter_list:
            if 'twoway' in encoder_dict.keys():
                encoder = encoder_dict['twoway']
                param_name1 = interaction[0]
                param_name2 = interaction[1]
                col_names1 = Xcol_dict[param_name1]
                col_names2 = Xcol_dict[param_name2]
                X_int, names = encoder(param_name1,param_name2, \
                                       col_names1,col_names2, X_dict)

                # put columns into Xbycol_dict
                for i in np.arange(0,len(names)):
                    Xbycol_dict[names[i]] = X_int[:,i]

            if 'threeway' in encoder_dict.keys():
                encoder = encoder_dict['threeway']
                param_name1 = interaction[0]
                param_name2 = interaction[1]
                param_name3 = interaction[2]
                col_names1 = Xcol_dict[param_name1]
                col_names2 = Xcol_dict[param_name2]
                col_names3 = Xcol_dict[param_name3]
                X_int, names = encoder(param_name1,param_name2,param_name3, \
                                       col_names1,col_names2,col_names3, X_dict)

                # put columns into Xbycol_dict
                for i in np.arange(0,len(names)):
                    Xbycol_dict[names[i]] = X_int[:,i]

        # remove columns that were trimmed (if any)
        trimmed_columns = encoder_dict['trimmed_columns']
        full_columns = Xbycol_dict.keys()
        used_columns = [x for x in full_columns if x not in trimmed_columns]
        # make design matrix array
        X = []
        for name in used_columns:
            X.append(Xbycol_dict[name])
        # always add intercept column last
        X.insert(0,np.ones(np.shape(X[0])))
        used_columns.insert(0,'Intercept')
        # final design matrix
        X = np.vstack(X).T
        return X, used_columns