<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_ocv(self, cycles=None, direction="up", remove_first=False, interpolated=False, dx=None, number_of_points=None):
 """get the open curcuit voltage relaxation curves. Args: cycles (list of ints or None):
 the cycles to extract from (selects all if not given). direction ("up", "down", or "both"):
 extract only relaxations that is performed during discharge for "up" (because then the voltage relaxes upwards) etc. remove_first: remove the first relaxation curve (typically, the first curve is from the initial rest period between assembling the cell to the actual testing/cycling starts) interpolated (bool):
 set to True if you want the data to be interpolated (e.g. for creating smaller files) dx (float):
 the step used when interpolating. number_of_points (int):
 number of points to use (over-rides dx) for interpolation (i.e. the length of the interpolated data). Returns: A pandas.DataFrame with cycle-number, step-number, step-time, and voltage columns. """


        if cycles is None:
            cycles = self.get_cycle_numbers()
        else:
            if not isinstance(cycles, (list, tuple)):
                cycles = [cycles, ]
            else:
                remove_first = False

        ocv_rlx_id = "ocvrlx"
        if direction == "up":
            ocv_rlx_id += "_up"
        elif direction == "down":
            ocv_rlx_id += "_down"

        step_table = self.dataset.step_table
        dfdata = self.dataset.dfdata

        ocv_steps = step_table.loc[
                    step_table["cycle"].isin(cycles), :
                    ]

        ocv_steps = ocv_steps.loc[
                    ocv_steps.type.str.startswith(ocv_rlx_id), :
                    ]

        if remove_first:
            ocv_steps = ocv_steps.iloc[1:, :]

        step_time_label = self.headers_normal.step_time_txt
        voltage_label = self.headers_normal.voltage_txt
        cycle_label = self.headers_normal.cycle_index_txt
        step_label = self.headers_normal.step_index_txt

        selected_df = dfdata.where(
            dfdata[cycle_label].isin(ocv_steps.cycle) &
            dfdata[step_label].isin(ocv_steps.step)
        ).dropna()

        selected_df = selected_df.loc[
            :, [cycle_label, step_label, step_time_label, voltage_label]
        ]

        if interpolated:
            if dx is None and number_of_points is None:
                dx = prms.Reader.time_interpolation_step
            new_dfs = list()
            groupby_list = [cycle_label, step_label]

            for name, group in selected_df.groupby(groupby_list):
                new_group = _interpolate_df_col(
                    group,
                    x=step_time_label,
                    y=voltage_label,
                    dx=dx,
                    number_of_points=number_of_points,
                )

                for i, j in zip(groupby_list, name):
                    new_group[i] = j
                new_dfs.append(new_group)

            selected_df = pd.concat(new_dfs)

        return selected_df