from utils import test_code_preprocess

def data_to_prompt(data: list[dict], data_type: str="python", output_type: str="code") -> list[str]:
    """
    根据数据和类型标签生成对应的提示
    
    参数:
        data: 字典列表
        data_type: 数据类型标签, ["python", "cpp", "java"]
        output_type: 输出类型, ["case", "test_code", "code", "code_part_problem", "text"]
    
    返回:
        prompts_list: 生成的提示列表
    """
    
    prompts_list = []
    if data_type.lower() == 'python':
        for task in data:
            # 确保任务包含所有必要的字段
            required_fields = ['problem-description', 'code_list', 'demo-input', 'demo-output']
            for field in required_fields:
                if field not in task:
                    raise ValueError(f"任务数据缺少必要字段: {field}")
            test_code_list = ["```python\n" + code + "\n```" if code is not None else "" for code in task.get('code_list', [])]
            test_code_format_str = '\n\n'.join(test_code_list)
            verdict_list = ["OK" if elem == "OK" else "FAILED" for elem in task.get('verdict_list', [])]
            demo_input = task['demo-input']
            demo_output = task['demo-output']
            new_demo_input = [item.replace('\n', '\\n').rstrip('\\n') for item in demo_input]
            new_demo_output = [item.replace('\n', '\\n').rstrip('\\n') for item in demo_output]
            if output_type.lower() == "case":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please generate corresponding test cases based on the submitted code and problem description above. 
It is required that at least one test case of the submitted code that does not meet the requirements of the question does not pass, and the submitted code that meets the requirements of the question can pass all test cases
Please strictly follow the format of forming a case input-output pair every two lines for the test cases you generated.
Please place all the generated unit test case at the end of the response. The generated unit test case is strictly written in the following format:
```python
input_str = '5\\n10 12 13 15 10'
output_str = '5 1'

input_str = '4\\n10 20 30 40'
output_str = '1 2'

input_str = '6\\n744 359 230 586 944 442'
output_str = '2 3'

input_str = '5\\n826 747 849 687 437'
output_str = '1 2'

input_str = '5\\n999 999 993 969 999'
output_str = '1 2'

input_str = '5\\n4 24 6 1 15'
output_str = '3 4'

input_str = '2\\n511 32'
output_str = '1 2'

input_str = '4\\n303 872 764 401'
output_str = '4 1'
```
When generating unit test case, strictly follow the following rules:
1.When generating unit test code, please start with ```python and end with ```, please do not repeatedly encapsulate into code blocks.
2.Please write as many test cases as possible while ensuring that they meet the requirements of the question.
3.The input_str in the example should be replaced with the input you designed. The output_str in the example should be replaced with the output you designed. Please do not generate test samples with illegal input.
4.Please refer to the specifications of input and output for the code when designing input_str and output_str. Please refer to the examples of input and output for the code when designing input_str and output_str.
5.Please do not generate excessively long samples. When testing large amounts of data, the generated length is approximately 100 characters.
"""
                prompts_list.append(prompt)
            elif output_type.lower() == "text":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

Please determine whether the above codes can perfectly solve the corresponding programming problem. If it can, return the result as OK; if not, return FAILED. 
You can first output the reason for the judgment, and then output the final judgment result. The judgment result starts with <result> and ends with </result>
Please do not include <result> and </result> outside of the final judgment result. Please do not add code and description when outputting the judgment result. 
Please place the judgment results of all submitted codes at the end of the response. You need to output the result of each code line by line. The judgment result is strictly written in the form of the following example:

<result>
OK
FAILED
FAILED
OK
</result>
"""   
                prompts_list.append(prompt)
            elif output_type.lower() == "test_code":
                # 构建Python类型的prompt

# The corresponding evaluation results for the above {len(test_code_list)} codes are {verdict_list}.
# Among them, "OK" indicates that the code has passed all test cases, and "FAILED" indicates that there are test cases that did not pass.

                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please generate unit test code that can pass all tests on submitted code that meets the requirements of the question, and at least one sample that does not meet the requirements of the question.
The generated unit test code is strictly written in the following format:
```python
from tempcode import run_method
import pytest
class TestCode():
    def test_single_node(self):
        input_str = '5\\n10 12 13 15 10'
        output_str = '5 1'
        assert run_method(input_str) == output_str

    def test_sequence_nodes(self):
        input_str = '4\\n10 20 30 40'
        output_str = '1 2'
        assert run_method(input_str) == output_str

    def test_mixed_values(self):
        input_str = '6\\n744 359 230 586 944 442'
        output_str = '2 3'
        assert run_method(input_str) == output_str

    def test_descending_order(self):
        input_str = '5\\n826 747 849 687 437'
        output_str = '1 2'
        assert run_method(input_str) == output_str

    def test_multiple_max(self):
        input_str = '5\\n999 999 993 969 999'
        output_str = '1 2'
        assert run_method(input_str) == output_str

    def test_small_values(self):
        input_str = '5\\n4 24 6 1 15'
        output_str = '3 4'
        assert run_method(input_str) == output_str

    def test_two_nodes(self):
        input_str = '2\\n511 32'
        output_str = '1 2'
        assert run_method(input_str) == output_str

    def test_reverse_order(self):
        input_str = '4\\n303 872 764 401'
        output_str = '4 1'
        assert run_method(input_str) == output_str

```
When generating unit test code, strictly follow the following rules:
1.When generating unit test code, please start with ```python and end with ```, please do not repeatedly encapsulate into code blocks
2.Please do not write the content of the submitted code into the test function. Please note that calling run_method will obtain the output from the input input_str to the submitted code. Please do not modify the function name, keep it as run_method().
3.The unit test code should be supplemented with as many test methods as possible, using appropriate naming conventions. 
4.The input_str in the example should be replaced with the input you designed. The output_str in the example should be replaced with the output you designed. Please do not generate test samples with illegal input.
5.Please refer to the specifications of input and output for the code when designing input_str and output_str. Please refer to the examples of input and output for the code when designing input_str and output_str.
6.Please check the syntax and indentation to ensure that the program can execute.
7.Please do not make any changes to any code except for the areas that need to be replaced as mentioned above, such as not needing to wrap lines.
"""     
                prompts_list.append(prompt)
            elif output_type.lower() == "code":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please write code that can solve the problem based on the task description, input-output specifications, and input-output examples.
More test cases similar to input-output examples will be used for verification, and the code you write needs to pass all the cases.
The generated code is strictly written in the following format:
```python
n, d = map(int, input().split())
a = list(map(int, input().split()))
l = 0
ans = 0
for i in range(n):
    while abs(a[i] - a[l]) > d :
        l = l + 1
    len = i - l - 1
    if len > 0:
        ans = ans + len * (len + 1) // 2
print(ans)
```

When generating code that can solve the problem, strictly follow the following rules:
1.Please read the data from the standard input and write it to the standard output, using input() and print(). 
2.Please check the syntax and indentation to ensure that the program can execute.
"""
                prompts_list.append(prompt)
            elif output_type.lower() == "code_part_problem":
                problem = task['problem-description']
                problem_len = len(problem)
                prompt = f"""
Part of the description of a programming problem is
{problem[:int(problem_len*0.7)]}

Please complete the problem description and write corresponding code to solve the problem based on the completed problem.

The generated code is strictly written in the following format:
```python
n, d = map(int, input().split())
a = list(map(int, input().split()))
l = 0
ans = 0
for i in range(n):
    while abs(a[i] - a[l]) > d :
        l = l + 1
    len = i - l - 1
    if len > 0:
        ans = ans + len * (len + 1) // 2
print(ans)
```

When generating code that can solve the problem, strictly follow the following rules:
1.Please read the data from the standard input and write it to the standard output, using input() and print(). 
2.Please check the syntax and indentation to ensure that the program can execute.
"""
                prompts_list.append(prompt)
            else:
                raise ValueError(f"不支持的输出类型: {output_type}")

#==========================================================================================================================================================












#==========================================================================================================================================================
    if data_type.lower() == 'cpp':
        for task in data:
            # 确保任务包含所有必要的字段
            required_fields = ['problem-description', 'code_list', 'demo_input', 'demo_output']
            for field in required_fields:
                if field not in task:
                    raise ValueError(f"任务数据缺少必要字段: {field}")
            test_code_list = ["```cpp\n" + code + "\n```" if code is not None else "" for code in task.get('code_list', [])]
            test_code_format_str = '\n\n'.join(test_code_list)
            verdict_list = ["OK" if elem == "OK" else "FAILED" for elem in task.get('verdict_list', [])]
            demo_input = task['demo_input']
            demo_output = task['demo_output']
            new_demo_input = [item.replace('\n', '\\n').rstrip('\\n') for item in demo_input]
            new_demo_output = [item.replace('\n', '\\n').rstrip('\\n') for item in demo_output]
            if output_type.lower() == "case":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please generate corresponding test cases based on the submitted code and problem description above. 
It is required that at least one test case of the submitted code that does not meet the requirements of the question does not pass, and the submitted code that meets the requirements of the question can pass all test cases
Please strictly follow the format of forming a case input-output pair every two lines for the test cases you generated.
Please place all the generated unit test case at the end of the response. The generated unit test case is strictly written in the following format:
```cpp
input_str = '5\\n10 12 13 15 10'
output_str = '5 1'

input_str = '4\\n10 20 30 40'
output_str = '1 2'

input_str = '6\\n744 359 230 586 944 442'
output_str = '2 3'

input_str = '5\\n826 747 849 687 437'
output_str = '1 2'

input_str = '5\\n999 999 993 969 999'
output_str = '1 2'

input_str = '5\\n4 24 6 1 15'
output_str = '3 4'

input_str = '2\\n511 32'
output_str = '1 2'

input_str = '4\\n303 872 764 401'
output_str = '4 1'
```
When generating unit test case, strictly follow the following rules:
1.When generating unit test code, please start with ```cpp and end with ```, please do not repeatedly encapsulate into code blocks.
2.Please write as many test cases as possible while ensuring that they meet the requirements of the question.
3.The input_str in the example should be replaced with the input you designed. The output_str in the example should be replaced with the output you designed. Please do not generate test samples with illegal input.
4.Please refer to the specifications of input and output for the code when designing input_str and output_str. Please refer to the examples of input and output for the code when designing input_str and output_str.
5.Please do not generate excessively long samples. When testing large amounts of data, the generated length is approximately 100 characters.
"""
                prompts_list.append(prompt)
            elif output_type.lower() == "text":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

Please determine whether the above codes can perfectly solve the corresponding programming problem. If it can, return the result as OK; if not, return FAILED. 
You can first output the reason for the judgment, and then output the final judgment result. The judgment result starts with <result> and ends with </result>
Please do not include <result> and </result> outside of the final judgment result. Please do not add code and description when outputting the judgment result. 
Please place the judgment results of all submitted codes at the end of the response. You need to output the result of each code line by line. The judgment result is strictly written in the form of the following example:

<result>
OK
FAILED
FAILED
OK
</result>
"""   
                prompts_list.append(prompt)
            elif output_type.lower() == "test_code":
                # 构建Python类型的prompt
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

These are {len(test_code_list)} submitted codes, including those that meet the requirements and those that do not. Each code block is a submitted code.
{test_code_format_str}

The corresponding evaluation results for the above {len(test_code_list)} codes are:
{verdict_list}
Among them, "OK" indicates that the code has passed all test cases, and "FAILED" indicates that there are test cases that did not pass.

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please generate unit test code that can pass all tests on submitted code that meets the requirements of the question, and at least one sample that does not meet the requirements of the question.
The generated unit test code is strictly written in the following format:
```cpp
TEST(MyCodeTest, SinglePixelTests) {{
    EXPECT_EQ(format(run_mycode("1 1\\nW")), format("#Black&White\\n"));
    EXPECT_EQ(format(run_mycode("1 1\\nB")), format("#Black&White\\n"));
    EXPECT_EQ(format(run_mycode("1 1\\nC")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("1 1\\nM")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("1 1\\nY")), format("#Color\\n"));
}}

TEST(MyCodeTest, AllColorTest) {{
    EXPECT_EQ(format(run_mycode("1 2\\nC Y")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("3 2\\nC Y\\nC Y\\nM M")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("2 2\\nC M\\nM Y")), format("#Color\\n"));
}}

TEST(MyCodeTest, ContainsColorTests) {{
    EXPECT_EQ(format(run_mycode("2 2\\nC M\\nY Y")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("1 5\\nW B Y W B")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("2 3\\nW B M\\nW W W")), format("#Color\\n"));
}}

TEST(MyCodeTest, AllBlackWhiteTest) {{
    EXPECT_EQ(format(run_mycode("1 1\\nB")), format("#Black&White\\n"));
    EXPECT_EQ(format(run_mycode("3 2\\nW W\\nW W\\nB B")), format("#Black&White\\n"));
    EXPECT_EQ(format(run_mycode("1 6\\nW B W B W B")), format("#Black&White\\n"));
}}

TEST(MyCodeTest, ColorAndBlackWhiteTest) {{
    EXPECT_EQ(format(run_mycode("2 2\\nC M\\nY Y")), format("#Color\\n"));
    EXPECT_EQ(format(run_mycode("3 2\\nW W\\nW W\\nB B")), format("#Black&White\\n"));
    EXPECT_EQ(format(run_mycode("1 1\\nW")), format("#Black&White\\n"));
}}

```
When generating unit test code, strictly follow the following rules:
1.When generating unit test code, please start with ```cpp and end with ```, please do not repeatedly encapsulate into code blocks.
2.The generated test code should not include the definition and import of format function and run_cycode function, as they have already been defined and initialized.
3.Please do not write the content of the submitted code into the test function. Please note that calling run_mycode will obtain the output from the input input_str to the submitted code. Please do not modify the function name, keep it as run_mycode().
4.The unit test code should be supplemented with as many test methods as possible, using appropriate naming conventions. 
5.The input_str in the example, such as "1 1\\nW", should be replaced with the input you designed. The output_str in the example, such as "#Black&White\\n", should be replaced with the output you designed. Please do not generate test samples with illegal input or empty input.
6.Please refer to the specifications of input and output for the code when designing input_str and output_str. Please refer to the examples of input and output for the code when designing input_str and output_str.
7.Please check the syntax and indentation to ensure that the program can execute.
8.Please do not make any changes to any code except for the areas that need to be replaced as mentioned above, such as not needing to wrap lines.
"""     
                prompts_list.append(prompt)
            elif output_type.lower() == "code":
                prompt = f"""
Description of programming problem is:
{task['problem-description']}

The input specification for the submitted codes is:
{task['input-specification']}

The output specification for the submitted codes is:
{task['output-specification']}

These are multiple sets of example inputs, please design your input_str based on them:
{new_demo_input}

These are multiple sets of corresponding example outputs, please design your output_str based on them:
{new_demo_output}

Please write code that can solve the problem based on the task description, input-output specifications, and input-output examples.
More test cases similar to input-output examples will be used for verification, and the code you write needs to pass all the cases.
The generated code is strictly written in the following format:
```cpp
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#define forn(i,n) for(int i =0; i < (int)n; i++)
#define dforn(i,n) for(int i = n-1; i >= 0; i--)
#define pb push_back
using namespace std;
int N,M;
char c;
bool f = true;
int main(){{    
    cin>>N>>M;
    forn(i,N)
        forn(j,M){{
            cin>>c;
            if(c=='C' or c == 'M' or c =='Y')
                f = false;
        }}
    if(f)
        cout<<"#Black&White"<<endl;
    else
        cout<<"#Color"<<endl;
    return 0;
}}
```

When generating code that can solve the problem, strictly follow the following rules:
1.Please read the data from the standard input and write it to the standard output, using cin() and cout(). 
2.Please check the syntax and indentation to ensure that the program can execute.
"""
                prompts_list.append(prompt)
            else:
                raise ValueError(f"不支持的输出类型: {output_type}")
    return prompts_list    