<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def to_frame(self, columns=None):
 """ Make a DataFrame with the given columns. Will always return a copy of the underlying table. Parameters columns : sequence or string, optional Sequence of the column names desired in the DataFrame. A string can also be passed if only one column is desired. If None all columns are returned, including registered columns. Returns ------- frame : pandas.DataFrame """

        extra_cols = _columns_for_table(self.name)

        if columns is not None:
            columns = [columns] if isinstance(columns, str) else columns
            columns = set(columns)
            set_extra_cols = set(extra_cols)
            local_cols = set(self.local.columns) & columns - set_extra_cols
            df = self.local[list(local_cols)].copy()
            extra_cols = {k: extra_cols[k] for k in (columns & set_extra_cols)}
        else:
            df = self.local.copy()

        with log_start_finish(
                'computing {!r} columns for table {!r}'.format(
                    len(extra_cols), self.name),
                logger):
            for name, col in extra_cols.items():
                with log_start_finish(
                        'computing column {!r} for table {!r}'.format(
                            name, self.name),
                        logger):
                    df[name] = col()

        return df