<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_by_cols(self, cols, direction=1):
 """Return the first or last row that satisfies the given col value constraints, or None if no row contains the given value. Parameters cols: :obj:'dict' Dictionary of col values for a specific row. direction: int, optional Either 1 or -1. 1 means find the first row, -1 means find the last row. Returns ------- :obj:`dict` A dictionary mapping keys (header strings) to values, which represents a row of the table. This row contains the given value in the specified column. """

        if direction == 1:
            iterator = range(self.num_rows)
        elif direction == -1:
            iterator = range(self.num_rows-1, -1, -1)
        else:
            raise ValueError("Direction can only be 1 (first) or -1 (last). Got: {0}".format(direction))

        for i in iterator:
            row = self._table[i+1]

            all_sat = True
            for key, val in cols.items():
                if row[key] != val:
                    all_sat = False
                    break

            if all_sat:
                return row.copy()

        return None