<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def do_paste(self, event):
 """ Read clipboard into dataframe Paste data into grid, adding extra rows if needed and ignoring extra columns. """

        # find where the user has clicked
        col_ind = self.GetGridCursorCol()
        row_ind = self.GetGridCursorRow()
        # read in clipboard text
        text_df = pd.read_clipboard(header=None, sep='\t').fillna('')
        # add extra rows if need to accomadate clipboard text
        row_length_diff = len(text_df) - (len(self.row_labels) - row_ind)
        if row_length_diff > 0:
            for n in range(row_length_diff):
                self.add_row()
        # ignore excess columns if present
        col_length_diff = len(text_df.columns) - (len(self.col_labels) - col_ind)
        if col_length_diff > 0:
            text_df = text_df.iloc[:, :-col_length_diff].copy()
        # go through copied text and parse it into the grid rows
        for label, row_data in text_df.iterrows():
            col_range = list(range(col_ind, col_ind + len(row_data)))
            if len(row_data) > 1:
                cols = list(zip(col_range, row_data.index))
                for column in cols:
                    value = row_data[column[1]]
                    this_col = column[0]
                    self.SetCellValue(row_ind, this_col, str(value))
            else:
                value = row_data[0]
                self.SetCellValue(row_ind, col_ind, str(value))
            row_ind += 1
        # could instead use wxPython clipboard here
        # see old git history for that
        self.size_grid()
        event.Skip()