Repository: microsoft/RD-Agent
File: rdagent/scenarios/data_science/dev/runner/eval.py (Python)

Code before:

    def evaluate(
        self,
        target_task: Task,
        implementation: FBWorkspace,
        gt_implementation: FBWorkspace,
        queried_knowledge: QueriedKnowledge = None,
        **kwargs,
    ) -> DSCoSTEEREvalFeedback:

        env = get_ds_env(
            extra_volumes={
                f"{DS_RD_SETTING.local_data_path}/{self.scen.competition}": T(
                    "scenarios.data_science.share:scen.input_path"
                ).r()
            },
            running_timeout_period=DS_RD_SETTING.full_timeout,
        )

        stdout = implementation.execute(
            env=env, entry=get_clear_ws_cmd()
        )  # Remove previous submission and scores files generated by worklfow.

        # execute workflow
        stdout, execute_ret_code = implementation.execute_ret_code(env=env, entry="python -m coverage run main.py")
        running_time = re.search(r"Total running time: (\d+\.\d+) seconds.", stdout).group(1)
        implementation.inject_files(**{"running_time.txt": running_time})

        match = re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL)
        eda_output = match.groups()[1] if match else None
        if eda_output is None:
            eda_output = "No EDA output."
        implementation.inject_files(**{"EDA.md": eda_output})
        stdout = remove_eda_part(stdout)
        stdout += f"The code executed {'successfully' if execute_ret_code == 0 else 'failed'}. {'The EDA output is removed from the stdout. ' if eda_output else ''}"

        # Check score file
        score_fp = implementation.workspace_path / "scores.csv"
        score_ret_code = 0
        score_check_text = ""
        if not score_fp.exists():
            logger.warning("Metrics file (scores.csv) is not generated!")
            score_check_text = "[Error] Metrics file (scores.csv) is not generated!"
            score_ret_code = 1
        else:
            try:
                score_df = pd.read_csv(score_fp, index_col=0)
                model_set_in_scores = set(score_df.index)
                model_set_in_folder = set(
                    f[:-3] for f in implementation.file_dict.keys() if re.match(r"^model_(?!test)\w+\.py$", f)
                )

Review comment (suggestion):
maybe be we can create a result class to make it more reasonable and extensible.
```
class Resuult:
     stdout:
     ret_code:
     execute_time: 
```

Code after:

    def evaluate(
        self,
        target_task: Task,
        implementation: FBWorkspace,
        gt_implementation: FBWorkspace,
        queried_knowledge: QueriedKnowledge = None,
        **kwargs,
    ) -> DSCoSTEEREvalFeedback:

        env = get_ds_env(
            extra_volumes={
                f"{DS_RD_SETTING.local_data_path}/{self.scen.competition}": T(
                    "scenarios.data_science.share:scen.input_path"
                ).r()
            },
            running_timeout_period=DS_RD_SETTING.full_timeout,
        )

        stdout = implementation.execute(
            env=env, entry=get_clear_ws_cmd()
        )  # Remove previous submission and scores files generated by worklfow.

        # execute workflow
        result = implementation.run(env=env, entry="python -m coverage run main.py")
        stdout = result.stdout
        execute_ret_code = result.ret_code
        implementation.running_info.running_time = result.running_time

        match = re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL)
        eda_output = match.groups()[1] if match else None
        if eda_output is None:
            eda_output = "No EDA output."
        implementation.inject_files(**{"EDA.md": eda_output})
        stdout = remove_eda_part(stdout)
        stdout += f"The code executed {'successfully' if execute_ret_code == 0 else 'failed'}. {'The EDA output is removed from the stdout. ' if eda_output else ''}"

        # Check score file
        score_fp = implementation.workspace_path / "scores.csv"
        score_ret_code = 0
        score_check_text = ""
        if not score_fp.exists():
            logger.warning("Metrics file (scores.csv) is not generated!")
            score_check_text = "[Error] Metrics file (scores.csv) is not generated!"
            score_ret_code = 1
        else:
            try:
                score_df = pd.read_csv(score_fp, index_col=0)
                model_set_in_scores = set(score_df.index)
                model_set_in_folder = set(
                    f[:-3] for f in implementation.file_dict.keys() if re.match(r"^model_(?!test)\w+\.py$", f)