-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtable_converter.py
More file actions
160 lines (139 loc) · 6.05 KB
/
Copy pathtable_converter.py
File metadata and controls
160 lines (139 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import json
import os
import re
from tqdm import tqdm
from openai import OpenAI
from dotenv import load_dotenv
from typing import List, Dict, Any
load_dotenv(".env")
client = OpenAI(api_key=os.getenv('openai_api_key'))
def load_json(file_path: str):
"""從指定路徑讀取JSON文件,並處理潛在的例外情況。"""
try:
with open(file_path, 'r', encoding='utf-8') as file:
data = json.load(file)
file_name = os.path.basename(file_path)
print(f"文件 {file_name} 讀取成功,共讀取到 {len(data)} 筆數據。")
return data
except FileNotFoundError:
print(f"Error: The file '{os.path.basename(file_path)}' does not exist.")
except json.JSONDecodeError:
print(f"Error: The file '{os.path.basename(file_path)}' contains invalid JSON.")
except Exception as e:
print(f"Error: An unexpected error occurred: {e}")
return None
def load_used_id(*file_paths: str) -> set:
"""從多個指定的 JSON 文件中加載已經使用過的文檔。"""
used_ids = set()
for file_path in file_paths:
try:
with open(file_path, "r", encoding='utf-8') as file:
data = json.load(file)
used_ids.update(entry['id'] for entry in data)
except FileNotFoundError:
print(f"Error: The file '{os.path.basename(file_path)}' does not exist.")
except json.JSONDecodeError:
print(f"Error: The file '{os.path.basename(file_path)}' contains invalid JSON.")
except Exception as e:
print(f"Error: An unexpected error occurred: {e}")
return used_ids
def convert_to_markdown(table: Dict[str, Any]) -> str:
"""將給定的表格轉換為Markdown格式。"""
header = table['header']
rows = table['rows']
markdown_table = "| " + " | ".join(header) + " |\n"
markdown_table += "| " + " | ".join(["---"] * len(header)) + " |\n"
for row in rows:
markdown_table += "| " + " | ".join(row) + " |\n"
return markdown_table
def get_gpt_prompt(question: str, markdown_table: str, answers: List[str]) -> str:
"""獲得用於 GPT 請求的prompt。"""
prompt = "你接下來會看到一組Table QA的資料,資料內容包含英文的問題、英文的表格、英文的答案。"\
+"你的任務是把這筆資料轉成繁體中文,並將表格以Markdown的格式儲存。"\
+"翻譯時需保留人名、地名、專有名詞等等,並確保翻譯後仍然能夠透過表格獲得答案。"\
+"輸出時請以範例格式輸出"\
+'[{"question": "translated_question", "markdown_table": "translated_table", "answers": ["translated_answers"]}]'\
+f"問題:\n{question}\n\n"\
+f"表格:\n{markdown_table}\n\n"\
+f"答案:\n{answers}"
return prompt
def get_gpt_reply(content: str) -> str:
"""使用指定的模型發送請求到 OpenAI 並獲取回覆。"""
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
messages=[
{
"role": "user",
"content": f"{content}",
}
],
temperature=0,
top_p=0.95,
frequency_penalty=0,
presence_penalty=0,
stop=None,
)
resp = response.choices[0].message.content
return resp
except Exception as e:
print(f"An error occurred: {e}")
return []
def parse_output(output_string: str) -> Dict[str, Any]:
"""使用正則表達式解析GPT回覆的輸出,尋找JSON格式的輸出。"""
try:
json_pattern = r'\[{"question": ".*?", "markdown_table": ".*?", "answers": \[".*?"\]}]'
matches = re.search(json_pattern, output_string, re.DOTALL)
if matches:
parsed_output = json.loads(matches.group())
if isinstance(parsed_output, list) and len(parsed_output) == 1:
return parsed_output[0]
else:
raise ValueError("Output is not in the expected format.")
else:
raise ValueError("No valid JSON output found in the response.")
except json.JSONDecodeError as e:
print("JSON decoding error:", e)
return {}
except Exception as e:
print("Error occurred:", e)
return {}
def add_to_output(output_list, id, question, table, answers):
output_list.append({
'id': int(id),
'question': question,
'markdown_table': table,
'answers': answers,
})
def save_to_json(file_path: str, data: list):
"""將數據保存到指定的JSON文件。"""
with open(file_path, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
print(f"數據已保存到 {file_path},總共 {len(data)} 筆資料。")
if __name__ == "__main__":
file = '200'
file_path = f'dataset/wiki_table_question/WTQ_{file}.json'
output_file = f'dataset/wiki_table_question/WTQ_{file}_markdown_all.json'
data = load_json(file_path)
used_file = 'dataset/wiki_table_question/WTQ_1000_markdown_zh.json'
used_ids = load_used_id(used_file)
output_data = []
for entry in tqdm(data, desc="資料轉換進度"):
id = entry['id']
question = entry['question']
table = entry['table']
answers = entry['answers']
if id in used_ids:
continue
markdown_table = convert_to_markdown(table)
prompt = get_gpt_prompt(question, markdown_table, answers)
reply = get_gpt_reply(prompt)
parsed_reply = parse_output(reply)
if parsed_reply == {}:
add_to_output(output_data, id, question, markdown_table, answers)
else:
question_zh = parsed_reply['question']
markdown_table_zh = parsed_reply['markdown_table']
answers_zh = parsed_reply['answers']
add_to_output(output_data, id, question_zh, markdown_table_zh, answers_zh)
save_to_json(output_file, output_data)