<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def cached_dataframe(self, csv_path, compute_fn):
 """ If a CSV path is in the _memory_cache, then return that cached value. If we've already saved the DataFrame as a CSV then load it. Otherwise run the provided `compute_fn`, and store its result in memory and and save it as a CSV. """

        if not csv_path.endswith(".csv"):
            raise ValueError("Invalid path '%s', must be a CSV file" % csv_path)

        if csv_path in self._memory_cache:
            return self._memory_cache[csv_path]

        if exists(csv_path) and not self.is_empty(csv_path):
            df = self._read_csv(csv_path)
        else:
            df = compute_fn()
            if not isinstance(df, pd.DataFrame):
                raise TypeError(
                    "Expected compute_fn to return DataFrame, got %s : %s" % (
                        df, type(df)))
            self._write_csv(df, csv_path)
        self._memory_cache[csv_path] = df
        return df