oliverwang15 commited on
Commit
772f8cb
1 Parent(s): 97f7347

updates on the submit button

Browse files
Files changed (8) hide show
  1. .gitattributes +35 -35
  2. README.md +13 -13
  3. app.py +156 -156
  4. backend.py +301 -301
  5. openai.py +44 -44
  6. prompt.py +91 -91
  7. requirements.txt +3 -3
  8. template.py +176 -176
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,13 @@
1
- ---
2
- title: DAN AI
3
- emoji: 🏆
4
- colorFrom: yellow
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 3.46.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: DAN AI
3
+ emoji: 🏆
4
+ colorFrom: yellow
5
+ colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: 3.46.1
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,157 +1,157 @@
1
- import warnings
2
- warnings.filterwarnings("ignore")
3
-
4
- import os, json
5
- import gradio as gr
6
- import pandas as pd
7
-
8
- from backend import Backend
9
-
10
-
11
-
12
- QUESTIONS = [
13
- "Animal Type",
14
- "Exposure Age",
15
- "Behavior Test",
16
- "Intervention 1",
17
- "Intervention 2",
18
- "Genetic Chain",
19
- ]
20
-
21
- with gr.Blocks(theme="dark") as demo:
22
- backend = Backend()
23
- with gr.Row():
24
- with gr.Row():
25
- # Update
26
- with gr.Group():
27
- gr.Markdown(f'<center><h1>Input</h1></center>')
28
- gr.Markdown(f'<center><p>Please First Upload the File</p></center>')
29
-
30
- openai_key = gr.Textbox(
31
- label='Enter your OpenAI API key here',
32
- type='password')
33
-
34
- file = gr.File(label='Upload your .txt or .pdf file here', file_types=['.txt', '.pdf'], file_count = 'multiple')
35
-
36
- questions = gr.CheckboxGroup(choices = QUESTIONS, value = QUESTIONS, label="Questions", info="Please select the question you want to ask")
37
-
38
- btn_submit_txt = gr.Button(value='Submit txt')
39
- btn_submit_txt.style(full_width=True)
40
-
41
- # Output
42
- with gr.Group():
43
- gr.Markdown(f'<center><h1>Output</h1></center>')
44
- gr.Markdown(f'<center><p>The answer to your question is :</p></center>')
45
- filename_box = gr.Textbox(label = "File")
46
- question_box = gr.Textbox(label='Question')
47
- answer_box = gr.Textbox(label='Answer')
48
- # reference_box = gr.Textbox(label='Reference')
49
-
50
- highlighted_text = gr.outputs.HTML(label="Highlighted Text")
51
- with gr.Group():
52
- gr.Markdown("<center><h4>Please select different questions</h4></center>")
53
- with gr.Row():
54
- btn_last_question = gr.Button(value='Last Question')
55
- btn_next_question = gr.Button(value='Next Question')
56
-
57
- with gr.Group():
58
- gr.Markdown("<center><h4>Please select different passages</h4></center>")
59
- with gr.Row():
60
- btn_last_passage = gr.Button(value='Last Passage')
61
- btn_next_passage = gr.Button(value='Next Passage')
62
-
63
- # Correctness
64
- with gr.Group():
65
- gr.Markdown(f'<center><h1>Correct the Result</h1></center>')
66
- gr.Markdown(f'<center><p>Please Correct the Results</p></center>')
67
-
68
- with gr.Row():
69
- save_results = gr.Textbox(placeholder = "Still need to click the button above to save the results", label = 'Save Results')
70
- with gr.Group():
71
- gr.Markdown(f'<center><p>Please Choose: </p></center>')
72
- answer_correct = gr.Radio(choices = ["Correct", "Incorrect"], label='Is the Generated Answer Correct?', info="Pease select whether the generated text is correct")
73
- correct_answer = gr.Textbox(placeholder = "Please judge on the generated answer", label = 'Correct Answer', interactive = True)
74
-
75
- reference_correct = gr.Radio(choices = ["Correct", "Incorrect"], label="Is the Reference Correct?", info="Pease select whether the reference is correct")
76
- correct_reference = gr.Textbox(placeholder = "Please judge on the generated answer", label = 'Correct Reference', interactive = True)
77
-
78
- btn_submit_correctness = gr.Button(value='Submit Correctness')
79
- btn_submit_correctness.style(full_width=True)
80
-
81
- # Download
82
- with gr.Group():
83
- gr.Markdown(f'<center><h1>Download</h1></center>')
84
- gr.Markdown(f'<center><p>Download the original LLM answers and corrected LLM answers</p></center>')
85
- answer_file = gr.File(label='Download original LLM answers', file_types=['.xlsx'])
86
- btn_download_answer = gr.Button(value='Download original LLM answers')
87
- btn_download_answer.style(full_width=True)
88
- corrected_file = gr.File(label='Download corrected data', file_types=['.xlsx'])
89
- btn_download_corrected = gr.Button(value='Download corrected LLM answers')
90
- btn_download_corrected.style(full_width=True)
91
-
92
-
93
- with gr.Row():
94
- reset = gr.Button(value='Reset')
95
- reset.style(full_width=True)
96
-
97
- # Answer change
98
- answer_correct.input(
99
- backend.change_correct_answer,
100
- inputs = [answer_correct],
101
- outputs = [correct_answer],
102
- )
103
-
104
- reference_correct.input(
105
- backend.change_correct_reference,
106
- inputs = [reference_correct],
107
- outputs = [correct_reference],
108
- )
109
-
110
-
111
- # Submit button
112
- btn_submit_txt.click(
113
- backend.process_file,
114
- inputs=[file, questions, openai_key],
115
- outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference],
116
- )
117
-
118
- btn_submit_correctness.click( # TODO
119
- backend.process_results,
120
- inputs=[answer_correct, correct_answer, reference_correct, correct_reference],
121
- outputs=[save_results],
122
- )
123
-
124
- # Switch question button
125
- btn_last_question.click(
126
- backend.process_last,
127
- outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
128
- )
129
-
130
- btn_next_question.click(
131
- backend.process_next,
132
- outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
133
- )
134
-
135
- # Switch passwage button
136
- btn_last_passage.click(
137
- backend.switch_last_passage,
138
- outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
139
- )
140
- btn_next_passage.click(
141
- backend.switch_next_passage,
142
- outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
143
- )
144
-
145
- # Download button
146
- btn_download_answer.click(
147
- backend.download_answer,
148
- outputs=[answer_file],
149
- )
150
-
151
- btn_download_corrected.click(
152
- backend.download_corrected,
153
- outputs=[corrected_file],
154
- )
155
-
156
- demo.queue()
157
  demo.launch(show_error=True, show_tips=True)
 
1
+ import warnings
2
+ warnings.filterwarnings("ignore")
3
+
4
+ import os, json
5
+ import gradio as gr
6
+ import pandas as pd
7
+
8
+ from backend import Backend
9
+
10
+
11
+
12
+ QUESTIONS = [
13
+ "Animal Type",
14
+ "Exposure Age",
15
+ "Behavior Test",
16
+ "Intervention 1",
17
+ "Intervention 2",
18
+ "Genetic Chain",
19
+ ]
20
+
21
+ with gr.Blocks(theme="dark") as demo:
22
+ backend = Backend()
23
+ with gr.Row():
24
+ with gr.Row():
25
+ # Update
26
+ with gr.Group():
27
+ gr.Markdown(f'<center><h1>Input</h1></center>')
28
+ gr.Markdown(f'<center><p>Please First Upload the File</p></center>')
29
+
30
+ openai_key = gr.Textbox(
31
+ label='Enter your OpenAI API key here',
32
+ type='password')
33
+
34
+ file = gr.File(label='Upload your .txt or .pdf file here', file_types=['.txt', '.pdf'], file_count = 'multiple')
35
+
36
+ questions = gr.CheckboxGroup(choices = QUESTIONS, value = QUESTIONS, label="Questions", info="Please select the question you want to ask")
37
+
38
+ btn_submit_txt = gr.Button(value='Submit')
39
+ btn_submit_txt.style(full_width=True)
40
+
41
+ # Output
42
+ with gr.Group():
43
+ gr.Markdown(f'<center><h1>Output</h1></center>')
44
+ gr.Markdown(f'<center><p>The answer to your question is :</p></center>')
45
+ filename_box = gr.Textbox(label = "File")
46
+ question_box = gr.Textbox(label='Question')
47
+ answer_box = gr.Textbox(label='Answer')
48
+ # reference_box = gr.Textbox(label='Reference')
49
+
50
+ highlighted_text = gr.outputs.HTML(label="Highlighted Text")
51
+ with gr.Group():
52
+ gr.Markdown("<center><h4>Please select different questions</h4></center>")
53
+ with gr.Row():
54
+ btn_last_question = gr.Button(value='Last Question')
55
+ btn_next_question = gr.Button(value='Next Question')
56
+
57
+ with gr.Group():
58
+ gr.Markdown("<center><h4>Please select different passages</h4></center>")
59
+ with gr.Row():
60
+ btn_last_passage = gr.Button(value='Last Passage')
61
+ btn_next_passage = gr.Button(value='Next Passage')
62
+
63
+ # Correctness
64
+ with gr.Group():
65
+ gr.Markdown(f'<center><h1>Correct the Result</h1></center>')
66
+ gr.Markdown(f'<center><p>Please Correct the Results</p></center>')
67
+
68
+ with gr.Row():
69
+ save_results = gr.Textbox(placeholder = "Still need to click the button above to save the results", label = 'Save Results')
70
+ with gr.Group():
71
+ gr.Markdown(f'<center><p>Please Choose: </p></center>')
72
+ answer_correct = gr.Radio(choices = ["Correct", "Incorrect"], label='Is the Generated Answer Correct?', info="Pease select whether the generated text is correct")
73
+ correct_answer = gr.Textbox(placeholder = "Please judge on the generated answer", label = 'Correct Answer', interactive = True)
74
+
75
+ reference_correct = gr.Radio(choices = ["Correct", "Incorrect"], label="Is the Reference Correct?", info="Pease select whether the reference is correct")
76
+ correct_reference = gr.Textbox(placeholder = "Please judge on the generated answer", label = 'Correct Reference', interactive = True)
77
+
78
+ btn_submit_correctness = gr.Button(value='Submit Correctness')
79
+ btn_submit_correctness.style(full_width=True)
80
+
81
+ # Download
82
+ with gr.Group():
83
+ gr.Markdown(f'<center><h1>Download</h1></center>')
84
+ gr.Markdown(f'<center><p>Download the original LLM answers and corrected LLM answers</p></center>')
85
+ answer_file = gr.File(label='Download original LLM answers', file_types=['.xlsx'])
86
+ btn_download_answer = gr.Button(value='Download original LLM answers')
87
+ btn_download_answer.style(full_width=True)
88
+ corrected_file = gr.File(label='Download corrected data', file_types=['.xlsx'])
89
+ btn_download_corrected = gr.Button(value='Download corrected LLM answers')
90
+ btn_download_corrected.style(full_width=True)
91
+
92
+
93
+ with gr.Row():
94
+ reset = gr.Button(value='Reset')
95
+ reset.style(full_width=True)
96
+
97
+ # Answer change
98
+ answer_correct.input(
99
+ backend.change_correct_answer,
100
+ inputs = [answer_correct],
101
+ outputs = [correct_answer],
102
+ )
103
+
104
+ reference_correct.input(
105
+ backend.change_correct_reference,
106
+ inputs = [reference_correct],
107
+ outputs = [correct_reference],
108
+ )
109
+
110
+
111
+ # Submit button
112
+ btn_submit_txt.click(
113
+ backend.process_file,
114
+ inputs=[file, questions, openai_key],
115
+ outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference],
116
+ )
117
+
118
+ btn_submit_correctness.click( # TODO
119
+ backend.process_results,
120
+ inputs=[answer_correct, correct_answer, reference_correct, correct_reference],
121
+ outputs=[save_results],
122
+ )
123
+
124
+ # Switch question button
125
+ btn_last_question.click(
126
+ backend.process_last,
127
+ outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
128
+ )
129
+
130
+ btn_next_question.click(
131
+ backend.process_next,
132
+ outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
133
+ )
134
+
135
+ # Switch passwage button
136
+ btn_last_passage.click(
137
+ backend.switch_last_passage,
138
+ outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
139
+ )
140
+ btn_next_passage.click(
141
+ backend.switch_next_passage,
142
+ outputs=[filename_box, question_box, answer_box, highlighted_text, correct_answer, correct_reference, save_results, answer_correct, reference_correct],
143
+ )
144
+
145
+ # Download button
146
+ btn_download_answer.click(
147
+ backend.download_answer,
148
+ outputs=[answer_file],
149
+ )
150
+
151
+ btn_download_corrected.click(
152
+ backend.download_corrected,
153
+ outputs=[corrected_file],
154
+ )
155
+
156
+ demo.queue()
157
  demo.launch(show_error=True, show_tips=True)
backend.py CHANGED
@@ -1,302 +1,302 @@
1
- from prompt import Prompt
2
- from openai import OpenAI
3
- from fuzzywuzzy import fuzz
4
- from fuzzywuzzy import process
5
-
6
- import gradio as gr
7
- import pandas as pd
8
- import os
9
-
10
- class Backend:
11
- def __init__(self):
12
- self.agent = OpenAI()
13
- self.prompt = Prompt()
14
-
15
- def read_file_single(self, file):
16
- # read the file
17
- if file is not None:
18
- with open(file.name, 'r') as f:
19
- text = f.read()
20
- else:
21
- raise gr.Error("You need to upload a file first")
22
- return text
23
-
24
- def phrase_pdf(self, file_path):
25
- from langchain.document_loaders import UnstructuredPDFLoader
26
- loader = UnstructuredPDFLoader(file_path, model = 'elements')
27
- file = loader.load()
28
- return file[0].page_content
29
-
30
- def read_file(self, files):
31
- # read the file
32
- text_list = []
33
- self.filename_list = []
34
- if files is not None:
35
- for file in files:
36
- if file.name.split('.')[-1] == 'pdf':
37
- # convert pdf to txt
38
- text = self.phrase_pdf(file.name)
39
-
40
- else:
41
- with open(file.name, 'r', encoding='utf-8') as f:
42
- text = f.read()
43
-
44
- text_list.append(text)
45
- self.filename_list.append(file.name.split('\\')[-1])
46
- else:
47
- raise gr.Error("You need to upload a file first")
48
- return text_list
49
-
50
- def highlight_text(self, text, highlight_list):
51
- # Find the original sentences
52
- # Split the passage into sentences
53
- sentences_in_passage = text.split('.')
54
- sentences_in_passage = [i.split('\n') for i in sentences_in_passage]
55
- new_sentences_in_passage = []
56
- for i in sentences_in_passage:
57
- new_sentences_in_passage =new_sentences_in_passage + i
58
-
59
- # hightlight the reference
60
- for hl in highlight_list:
61
- # Find the best match using fuzzy matching
62
- best_match = process.extractOne(hl, new_sentences_in_passage, scorer=fuzz.partial_ratio)
63
- text = text.replace(best_match[0], f'<mark style="background: #A5D2F1">{best_match[0]}</mark><mark style="background: #FFC0CB"><font color="red"> (match score:{best_match[1]})</font></mark>')
64
-
65
- # add line break
66
- text = text.replace('\n', f" <br /> ")
67
-
68
- # add scroll bar
69
- text = f'<div style="height: 300px; overflow: auto;">{text}</div>'
70
-
71
- return text
72
-
73
- def process_file(self, file, questions, openai_key, progress = gr.Progress()):
74
- # record the questions
75
- self.questions = questions
76
-
77
- # get the text_list
78
- self.text_list = self.read_file(file)
79
-
80
- # make the prompt
81
- prompt_list = [self.prompt.get(text, questions, 'v3') for text in self.text_list]
82
-
83
- # interact with openai
84
- self.res_list = []
85
- for prompt in progress.tqdm(prompt_list, desc = 'Generating answers...'):
86
- res = self.agent(prompt, with_history = False, temperature = 0.1, model = 'gpt-3.5-turbo-16k', api_key = openai_key)
87
- res = self.prompt.process_result(res, 'v3')
88
- self.res_list.append(res)
89
-
90
- # Use the first file as default
91
- # Use the first question for multiple questions
92
- gpt_res = self.res_list[0]
93
- self.gpt_result = gpt_res
94
-
95
- self.current_question = 0
96
- self.totel_question = len(res.keys())
97
- self.current_passage = 0
98
- self.total_passages = len(self.res_list)
99
-
100
- # make a dataframe to record everything
101
- self.ori_answer_df = pd.DataFrame()
102
- self.answer_df = pd.DataFrame()
103
- for i, res in enumerate(self.res_list):
104
- tmp = pd.DataFrame(res).T
105
- tmp = tmp.reset_index()
106
- tmp = tmp.rename(columns={"index":"question_id"})
107
- tmp['filename'] = self.filename_list[i]
108
- tmp['question'] = self.questions
109
- self.ori_answer_df = pd.concat([tmp, self.ori_answer_df])
110
- self.answer_df = pd.concat([tmp, self.answer_df])
111
-
112
- # default fist question
113
- res = res['Question 1']
114
- question = self.questions[self.current_question]
115
- self.answer = res['answer']
116
- self.text = self.text_list[0]
117
- self.highlighted_out = res['original sentences']
118
- highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
119
- self.highlighted_out = '\n'.join(self.highlighted_out)
120
-
121
- file_name = self.filename_list[self.current_passage]
122
-
123
- return file_name, question, self.answer, highlighted_out_html, self.answer, self.highlighted_out
124
-
125
- def process_results(self, answer_correct, correct_answer, reference_correct, correct_reference):
126
- if not hasattr(self, 'clicked_correct_answer'):
127
- raise gr.Error("You need to judge whether the generated answer is correct first")
128
-
129
- if not hasattr(self, 'clicked_correct_reference'):
130
- raise gr.Error("You need to judge whether the highlighted reference is correct first")
131
-
132
- if not hasattr(self, 'answer_df'):
133
- raise gr.Error("You need to submit the document first")
134
-
135
- if self.current_question >= self.totel_question or self.current_question < 0:
136
- raise gr.Error("No more questions, please return back")
137
-
138
- # record the answer
139
- condition = (self.answer_df['question_id'] == f'Question {self.current_question + 1}' ) & \
140
- (self.answer_df['filename'] == self.filename_list[self.current_passage])
141
- self.answer_df.loc[condition, 'answer_correct'] = answer_correct
142
- self.answer_df.loc[condition, 'reference_correct'] = reference_correct
143
-
144
- # self.answer_df.loc[f'Question {self.current_question + 1}', 'answer_correct'] = answer_correct
145
- # self.answer_df.loc[f'Question {self.current_question + 1}', 'reference_correct'] = reference_correct
146
-
147
- if self.clicked_correct_answer == True:
148
- if hasattr(self, 'answer'):
149
- self.answer_df.loc[condition, 'correct_answer'] = self.answer
150
- else:
151
- raise gr.Error("You need to submit the document first")
152
- else:
153
- # self.answer_df.loc[f'Question {self.current_question + 1}', 'correct_answer'] = correct_answer
154
- self.answer_df.loc[condition, 'correct_answer'] = correct_answer
155
-
156
- if self.clicked_correct_reference == True:
157
- if hasattr(self, 'highlighted_out'):
158
- self.answer_df.loc[condition, 'correct_reference'] = self.highlighted_out
159
- else:
160
- raise gr.Error("You need to submit the document first")
161
- else:
162
- self.answer_df.loc[condition, 'correct_reference'] = correct_reference
163
-
164
- gr.Info('Results saved!')
165
- return "Results saved!"
166
-
167
- def process_next(self):
168
- self.current_question += 1
169
- if hasattr(self, 'clicked_correct_answer'):
170
- del self.clicked_correct_answer
171
- if hasattr(self, 'clicked_correct_reference'):
172
- del self.clicked_correct_reference
173
-
174
- if self.current_question >= self.totel_question:
175
- # self.current_question -= 1
176
- return "No more questions!", "No more questions!", "No more questions!", "No more questions!", 'No more questions!', 'No more questions!', 'Still need to click the button above to save the results', None, None
177
- else:
178
- res = self.gpt_result[f'Question {self.current_question + 1}']
179
- question = self.questions[self.current_question]
180
- self.answer = res['answer']
181
- self.highlighted_out = res['original sentences']
182
- highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
183
- self.highlighted_out = '\n'.join(self.highlighted_out)
184
- file_name = self.filename_list[self.current_passage]
185
-
186
- return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
187
-
188
- def process_last(self):
189
- self.current_question -= 1
190
-
191
- # To make sure to correct the answer first
192
- if hasattr(self, 'clicked_correct_answer'):
193
- del self.clicked_correct_answer
194
- if hasattr(self, 'clicked_correct_reference'):
195
- del self.clicked_correct_reference
196
-
197
- # check question boundary
198
- if self.current_question < 0:
199
- # self.current_question += 1
200
- return "No more questions!", "No more questions!", "No more questions!", "No more questions!", 'No more questions!', 'No more questions!', 'Still need to click the button above to save the results', None, None
201
- else:
202
- res = self.gpt_result[f'Question {self.current_question + 1}']
203
- question = self.questions[self.current_question]
204
- self.answer = res['answer']
205
- self.highlighted_out = res['original sentences']
206
- highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
207
- self.highlighted_out = '\n'.join(self.highlighted_out)
208
- file_name = self.filename_list[self.current_passage]
209
- return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
210
-
211
- def switch_next_passage(self):
212
- self.current_question = 0
213
-
214
- # To make sure to correct the answer first
215
- if hasattr(self, 'clicked_correct_answer'):
216
- del self.clicked_correct_answer
217
- if hasattr(self, 'clicked_correct_reference'):
218
- del self.clicked_correct_reference
219
-
220
- self.current_passage += 1
221
-
222
-
223
- if self.current_passage >= self.total_passages:
224
- # self.current_passage -= 1
225
- return "No more passages!", "No more passages!", "No more passages!", "No more passages!", 'No more passages!', 'No more passages!', 'Still need to click the button above to save the results', None, None
226
- else:
227
- self.text = self.text_list[self.current_passage]
228
- gpt_res = self.res_list[self.current_passage]
229
- self.gpt_result = gpt_res
230
- res = self.gpt_result[f'Question {self.current_question + 1}']
231
- question = self.questions[self.current_question]
232
- self.answer = res['answer']
233
- self.highlighted_out = res['original sentences']
234
- highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
235
- self.highlighted_out = '\n'.join(self.highlighted_out)
236
- file_name = self.filename_list[self.current_passage]
237
- return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
238
-
239
- def switch_last_passage(self):
240
- self.current_question = 0
241
-
242
- # To make sure to correct the answer first
243
- if hasattr(self, 'clicked_correct_answer'):
244
- del self.clicked_correct_answer
245
- if hasattr(self, 'clicked_correct_reference'):
246
- del self.clicked_correct_reference
247
-
248
- self.current_passage -= 1
249
-
250
- if self.current_passage < 0:
251
- # self.current_passage += 1
252
- return "No more passages!", "No more passages!", "No more passages!", "No more passages!", 'No more passages!', 'No more passages!', 'Still need to click the button above to save the results', None, None
253
- else:
254
- self.text = self.text_list[self.current_passage]
255
- gpt_res = self.res_list[self.current_passage]
256
- self.gpt_result = gpt_res
257
- res = self.gpt_result[f'Question {self.current_question + 1}']
258
- question = self.questions[self.current_question]
259
- self.answer = res['answer']
260
- self.highlighted_out = res['original sentences']
261
- highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
262
- self.highlighted_out = '\n'.join(self.highlighted_out)
263
- file_name = self.filename_list[self.current_passage]
264
- return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
265
-
266
- def download_answer(self, path = './tmp', name = 'answer.xlsx'):
267
- os.makedirs(path, exist_ok = True)
268
- path = os.path.join(path, name)
269
- # self.ori_answer_df['questions'] = self.questions
270
- self.ori_answer_df.to_excel(path, index = False)
271
-
272
- return path
273
-
274
- def download_corrected(self, path = './tmp', name = 'corrected_answer.xlsx'):
275
- os.makedirs(path, exist_ok = True)
276
- path = os.path.join(path, name)
277
- # self.answer_df['questions'] = self.questions
278
- self.answer_df.to_excel(path, index = False)
279
-
280
- return path
281
-
282
- def change_correct_answer(self, correctness):
283
- if correctness == "Correct":
284
- self.clicked_correct_answer = True
285
- return "No need to change"
286
- else:
287
- if hasattr(self, 'answer'):
288
- self.clicked_correct_answer = False
289
- return self.answer
290
- else:
291
- return "No answer yet, you need to submit the document first"
292
-
293
- def change_correct_reference(self, correctness):
294
- if correctness == "Correct":
295
- self.clicked_correct_reference = True
296
- return "No need to change"
297
- else:
298
- if hasattr(self, 'highlighted_out'):
299
- self.clicked_correct_reference = False
300
- return self.highlighted_out
301
- else:
302
  return "No answer yet, you need to submit the document first"
 
1
+ from prompt import Prompt
2
+ from openai import OpenAI
3
+ from fuzzywuzzy import fuzz
4
+ from fuzzywuzzy import process
5
+
6
+ import gradio as gr
7
+ import pandas as pd
8
+ import os
9
+
10
+ class Backend:
11
+ def __init__(self):
12
+ self.agent = OpenAI()
13
+ self.prompt = Prompt()
14
+
15
+ def read_file_single(self, file):
16
+ # read the file
17
+ if file is not None:
18
+ with open(file.name, 'r') as f:
19
+ text = f.read()
20
+ else:
21
+ raise gr.Error("You need to upload a file first")
22
+ return text
23
+
24
+ def phrase_pdf(self, file_path):
25
+ from langchain.document_loaders import UnstructuredPDFLoader
26
+ loader = UnstructuredPDFLoader(file_path, model = 'elements')
27
+ file = loader.load()
28
+ return file[0].page_content
29
+
30
+ def read_file(self, files):
31
+ # read the file
32
+ text_list = []
33
+ self.filename_list = []
34
+ if files is not None:
35
+ for file in files:
36
+ if file.name.split('.')[-1] == 'pdf':
37
+ # convert pdf to txt
38
+ text = self.phrase_pdf(file.name)
39
+
40
+ else:
41
+ with open(file.name, 'r', encoding='utf-8') as f:
42
+ text = f.read()
43
+
44
+ text_list.append(text)
45
+ self.filename_list.append(file.name.split('\\')[-1])
46
+ else:
47
+ raise gr.Error("You need to upload a file first")
48
+ return text_list
49
+
50
+ def highlight_text(self, text, highlight_list):
51
+ # Find the original sentences
52
+ # Split the passage into sentences
53
+ sentences_in_passage = text.split('.')
54
+ sentences_in_passage = [i.split('\n') for i in sentences_in_passage]
55
+ new_sentences_in_passage = []
56
+ for i in sentences_in_passage:
57
+ new_sentences_in_passage =new_sentences_in_passage + i
58
+
59
+ # hightlight the reference
60
+ for hl in highlight_list:
61
+ # Find the best match using fuzzy matching
62
+ best_match = process.extractOne(hl, new_sentences_in_passage, scorer=fuzz.partial_ratio)
63
+ text = text.replace(best_match[0], f'<mark style="background: #A5D2F1">{best_match[0]}</mark><mark style="background: #FFC0CB"><font color="red"> (match score:{best_match[1]})</font></mark>')
64
+
65
+ # add line break
66
+ text = text.replace('\n', f" <br /> ")
67
+
68
+ # add scroll bar
69
+ text = f'<div style="height: 300px; overflow: auto;">{text}</div>'
70
+
71
+ return text
72
+
73
+ def process_file(self, file, questions, openai_key, progress = gr.Progress()):
74
+ # record the questions
75
+ self.questions = questions
76
+
77
+ # get the text_list
78
+ self.text_list = self.read_file(file)
79
+
80
+ # make the prompt
81
+ prompt_list = [self.prompt.get(text, questions, 'v3') for text in self.text_list]
82
+
83
+ # interact with openai
84
+ self.res_list = []
85
+ for prompt in progress.tqdm(prompt_list, desc = 'Generating answers...'):
86
+ res = self.agent(prompt, with_history = False, temperature = 0.1, model = 'gpt-3.5-turbo-16k', api_key = openai_key)
87
+ res = self.prompt.process_result(res, 'v3')
88
+ self.res_list.append(res)
89
+
90
+ # Use the first file as default
91
+ # Use the first question for multiple questions
92
+ gpt_res = self.res_list[0]
93
+ self.gpt_result = gpt_res
94
+
95
+ self.current_question = 0
96
+ self.totel_question = len(res.keys())
97
+ self.current_passage = 0
98
+ self.total_passages = len(self.res_list)
99
+
100
+ # make a dataframe to record everything
101
+ self.ori_answer_df = pd.DataFrame()
102
+ self.answer_df = pd.DataFrame()
103
+ for i, res in enumerate(self.res_list):
104
+ tmp = pd.DataFrame(res).T
105
+ tmp = tmp.reset_index()
106
+ tmp = tmp.rename(columns={"index":"question_id"})
107
+ tmp['filename'] = self.filename_list[i]
108
+ tmp['question'] = self.questions
109
+ self.ori_answer_df = pd.concat([tmp, self.ori_answer_df])
110
+ self.answer_df = pd.concat([tmp, self.answer_df])
111
+
112
+ # default fist question
113
+ res = res['Question 1']
114
+ question = self.questions[self.current_question]
115
+ self.answer = res['answer']
116
+ self.text = self.text_list[0]
117
+ self.highlighted_out = res['original sentences']
118
+ highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
119
+ self.highlighted_out = '\n'.join(self.highlighted_out)
120
+
121
+ file_name = self.filename_list[self.current_passage]
122
+
123
+ return file_name, question, self.answer, highlighted_out_html, self.answer, self.highlighted_out
124
+
125
+ def process_results(self, answer_correct, correct_answer, reference_correct, correct_reference):
126
+ if not hasattr(self, 'clicked_correct_answer'):
127
+ raise gr.Error("You need to judge whether the generated answer is correct first")
128
+
129
+ if not hasattr(self, 'clicked_correct_reference'):
130
+ raise gr.Error("You need to judge whether the highlighted reference is correct first")
131
+
132
+ if not hasattr(self, 'answer_df'):
133
+ raise gr.Error("You need to submit the document first")
134
+
135
+ if self.current_question >= self.totel_question or self.current_question < 0:
136
+ raise gr.Error("No more questions, please return back")
137
+
138
+ # record the answer
139
+ condition = (self.answer_df['question_id'] == f'Question {self.current_question + 1}' ) & \
140
+ (self.answer_df['filename'] == self.filename_list[self.current_passage])
141
+ self.answer_df.loc[condition, 'answer_correct'] = answer_correct
142
+ self.answer_df.loc[condition, 'reference_correct'] = reference_correct
143
+
144
+ # self.answer_df.loc[f'Question {self.current_question + 1}', 'answer_correct'] = answer_correct
145
+ # self.answer_df.loc[f'Question {self.current_question + 1}', 'reference_correct'] = reference_correct
146
+
147
+ if self.clicked_correct_answer == True:
148
+ if hasattr(self, 'answer'):
149
+ self.answer_df.loc[condition, 'correct_answer'] = self.answer
150
+ else:
151
+ raise gr.Error("You need to submit the document first")
152
+ else:
153
+ # self.answer_df.loc[f'Question {self.current_question + 1}', 'correct_answer'] = correct_answer
154
+ self.answer_df.loc[condition, 'correct_answer'] = correct_answer
155
+
156
+ if self.clicked_correct_reference == True:
157
+ if hasattr(self, 'highlighted_out'):
158
+ self.answer_df.loc[condition, 'correct_reference'] = self.highlighted_out
159
+ else:
160
+ raise gr.Error("You need to submit the document first")
161
+ else:
162
+ self.answer_df.loc[condition, 'correct_reference'] = correct_reference
163
+
164
+ gr.Info('Results saved!')
165
+ return "Results saved!"
166
+
167
+ def process_next(self):
168
+ self.current_question += 1
169
+ if hasattr(self, 'clicked_correct_answer'):
170
+ del self.clicked_correct_answer
171
+ if hasattr(self, 'clicked_correct_reference'):
172
+ del self.clicked_correct_reference
173
+
174
+ if self.current_question >= self.totel_question:
175
+ # self.current_question -= 1
176
+ return "No more questions!", "No more questions!", "No more questions!", "No more questions!", 'No more questions!', 'No more questions!', 'Still need to click the button above to save the results', None, None
177
+ else:
178
+ res = self.gpt_result[f'Question {self.current_question + 1}']
179
+ question = self.questions[self.current_question]
180
+ self.answer = res['answer']
181
+ self.highlighted_out = res['original sentences']
182
+ highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
183
+ self.highlighted_out = '\n'.join(self.highlighted_out)
184
+ file_name = self.filename_list[self.current_passage]
185
+
186
+ return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
187
+
188
+ def process_last(self):
189
+ self.current_question -= 1
190
+
191
+ # To make sure to correct the answer first
192
+ if hasattr(self, 'clicked_correct_answer'):
193
+ del self.clicked_correct_answer
194
+ if hasattr(self, 'clicked_correct_reference'):
195
+ del self.clicked_correct_reference
196
+
197
+ # check question boundary
198
+ if self.current_question < 0:
199
+ # self.current_question += 1
200
+ return "No more questions!", "No more questions!", "No more questions!", "No more questions!", 'No more questions!', 'No more questions!', 'Still need to click the button above to save the results', None, None
201
+ else:
202
+ res = self.gpt_result[f'Question {self.current_question + 1}']
203
+ question = self.questions[self.current_question]
204
+ self.answer = res['answer']
205
+ self.highlighted_out = res['original sentences']
206
+ highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
207
+ self.highlighted_out = '\n'.join(self.highlighted_out)
208
+ file_name = self.filename_list[self.current_passage]
209
+ return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
210
+
211
+ def switch_next_passage(self):
212
+ self.current_question = 0
213
+
214
+ # To make sure to correct the answer first
215
+ if hasattr(self, 'clicked_correct_answer'):
216
+ del self.clicked_correct_answer
217
+ if hasattr(self, 'clicked_correct_reference'):
218
+ del self.clicked_correct_reference
219
+
220
+ self.current_passage += 1
221
+
222
+
223
+ if self.current_passage >= self.total_passages:
224
+ # self.current_passage -= 1
225
+ return "No more passages!", "No more passages!", "No more passages!", "No more passages!", 'No more passages!', 'No more passages!', 'Still need to click the button above to save the results', None, None
226
+ else:
227
+ self.text = self.text_list[self.current_passage]
228
+ gpt_res = self.res_list[self.current_passage]
229
+ self.gpt_result = gpt_res
230
+ res = self.gpt_result[f'Question {self.current_question + 1}']
231
+ question = self.questions[self.current_question]
232
+ self.answer = res['answer']
233
+ self.highlighted_out = res['original sentences']
234
+ highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
235
+ self.highlighted_out = '\n'.join(self.highlighted_out)
236
+ file_name = self.filename_list[self.current_passage]
237
+ return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
238
+
239
+ def switch_last_passage(self):
240
+ self.current_question = 0
241
+
242
+ # To make sure to correct the answer first
243
+ if hasattr(self, 'clicked_correct_answer'):
244
+ del self.clicked_correct_answer
245
+ if hasattr(self, 'clicked_correct_reference'):
246
+ del self.clicked_correct_reference
247
+
248
+ self.current_passage -= 1
249
+
250
+ if self.current_passage < 0:
251
+ # self.current_passage += 1
252
+ return "No more passages!", "No more passages!", "No more passages!", "No more passages!", 'No more passages!', 'No more passages!', 'Still need to click the button above to save the results', None, None
253
+ else:
254
+ self.text = self.text_list[self.current_passage]
255
+ gpt_res = self.res_list[self.current_passage]
256
+ self.gpt_result = gpt_res
257
+ res = self.gpt_result[f'Question {self.current_question + 1}']
258
+ question = self.questions[self.current_question]
259
+ self.answer = res['answer']
260
+ self.highlighted_out = res['original sentences']
261
+ highlighted_out_html = self.highlight_text(self.text, self.highlighted_out)
262
+ self.highlighted_out = '\n'.join(self.highlighted_out)
263
+ file_name = self.filename_list[self.current_passage]
264
+ return file_name, question, self.answer, highlighted_out_html, 'Please judge on the generated answer', 'Please judge on the generated answer', 'Still need to click the button above to save the results', None, None
265
+
266
+ def download_answer(self, path = './tmp', name = 'answer.xlsx'):
267
+ os.makedirs(path, exist_ok = True)
268
+ path = os.path.join(path, name)
269
+ # self.ori_answer_df['questions'] = self.questions
270
+ self.ori_answer_df.to_excel(path, index = False)
271
+
272
+ return path
273
+
274
+ def download_corrected(self, path = './tmp', name = 'corrected_answer.xlsx'):
275
+ os.makedirs(path, exist_ok = True)
276
+ path = os.path.join(path, name)
277
+ # self.answer_df['questions'] = self.questions
278
+ self.answer_df.to_excel(path, index = False)
279
+
280
+ return path
281
+
282
+ def change_correct_answer(self, correctness):
283
+ if correctness == "Correct":
284
+ self.clicked_correct_answer = True
285
+ return "No need to change"
286
+ else:
287
+ if hasattr(self, 'answer'):
288
+ self.clicked_correct_answer = False
289
+ return self.answer
290
+ else:
291
+ return "No answer yet, you need to submit the document first"
292
+
293
+ def change_correct_reference(self, correctness):
294
+ if correctness == "Correct":
295
+ self.clicked_correct_reference = True
296
+ return "No need to change"
297
+ else:
298
+ if hasattr(self, 'highlighted_out'):
299
+ self.clicked_correct_reference = False
300
+ return self.highlighted_out
301
+ else:
302
  return "No answer yet, you need to submit the document first"
openai.py CHANGED
@@ -1,44 +1,44 @@
1
- import requests
2
-
3
- class OpenAI:
4
- def __init__(self, init_prompt = None):
5
- self.history = []
6
- if init_prompt is not None:
7
- self.history.append({'role': 'system', 'content': init_prompt})
8
-
9
- def clear_history(self):
10
- self.history = []
11
-
12
- def show_history(self):
13
- for message in self.history:
14
- print(f"{message['role']}: {message['content']}")
15
-
16
- def get_raw_history(self):
17
- return self.history
18
-
19
- def __call__(self, prompt, with_history = False, model = 'gpt-3.5-turbo', temperature = 0, api_key = None):
20
- URL = 'https://api.openai.com/v1/chat/completions'
21
- new_message = {'role': 'user', 'content': prompt}
22
- if with_history:
23
- self.history.append(new_message)
24
- messages = self.history
25
- else:
26
- messages = [new_message]
27
-
28
- resp = requests.post(URL, json={
29
- 'model': model,
30
- 'messages': messages,
31
- 'temperature': temperature,
32
- }, headers={
33
- 'Authorization': f"Bearer {api_key}"
34
- })
35
- self.history.append(resp.json()['choices'][0]['message'])
36
- res = resp.json()['choices'][0]['message']['content']
37
-
38
- # with open("tmp_res.txt", 'w') as f:
39
- # f.write(res)
40
-
41
- # with open("tmp_res.txt", 'r') as f:
42
- # res = f.read()
43
-
44
- return res
 
1
+ import requests
2
+
3
+ class OpenAI:
4
+ def __init__(self, init_prompt = None):
5
+ self.history = []
6
+ if init_prompt is not None:
7
+ self.history.append({'role': 'system', 'content': init_prompt})
8
+
9
+ def clear_history(self):
10
+ self.history = []
11
+
12
+ def show_history(self):
13
+ for message in self.history:
14
+ print(f"{message['role']}: {message['content']}")
15
+
16
+ def get_raw_history(self):
17
+ return self.history
18
+
19
+ def __call__(self, prompt, with_history = False, model = 'gpt-3.5-turbo', temperature = 0, api_key = None):
20
+ URL = 'https://api.openai.com/v1/chat/completions'
21
+ new_message = {'role': 'user', 'content': prompt}
22
+ if with_history:
23
+ self.history.append(new_message)
24
+ messages = self.history
25
+ else:
26
+ messages = [new_message]
27
+
28
+ resp = requests.post(URL, json={
29
+ 'model': model,
30
+ 'messages': messages,
31
+ 'temperature': temperature,
32
+ }, headers={
33
+ 'Authorization': f"Bearer {api_key}"
34
+ })
35
+ self.history.append(resp.json()['choices'][0]['message'])
36
+ res = resp.json()['choices'][0]['message']['content']
37
+
38
+ # with open("tmp_res.txt", 'w') as f:
39
+ # f.write(res)
40
+
41
+ # with open("tmp_res.txt", 'r') as f:
42
+ # res = f.read()
43
+
44
+ return res
prompt.py CHANGED
@@ -1,91 +1,91 @@
1
- from template import TEMPLATE_v1, TEMPLATE_v2, TEMPLATE_v3, QUESTIONS
2
- import json
3
-
4
- class Prompt:
5
- def __init__(self) -> None:
6
- # self.questions = QUESTIONS
7
- self.template_v1 = TEMPLATE_v1
8
- self.template_v2 = TEMPLATE_v2
9
- self.template_v3 = TEMPLATE_v3
10
- self.version = "v3"
11
-
12
- def combine_questions(self, questions):
13
- questions = [ f'Question {id_ +1 }: {q}' for id_, q in enumerate(questions) if 'Input question' not in q]
14
- questions = '\n'.join(questions)
15
- return questions
16
-
17
- def _get_v1(self, input, questions):
18
- questions = self.combine_questions(questions)
19
- return self.template_v1.format(input, self.questions)
20
-
21
- def _get_v2(self, input, questions):
22
- questions = self.combine_questions(questions)
23
- return self.template_v2.format(input, self.questions)
24
-
25
- def _get_v3(self, input, questions):
26
- return self.template_v3.format(input)
27
-
28
- def get(self, input, questions, version = None):
29
- self.version = version if version else self.version
30
- if self.version == 'v1':
31
- return self._get_v1(input, questions)
32
- elif self.version == 'v2':
33
- return self._get_v2(input, questions)
34
- elif self.version == 'v3':
35
- return self._get_v3(input, questions)
36
- else:
37
- raise ValueError('Version should be one of {v1, v2, v3}')
38
-
39
- def _process_v1(self, res):
40
- res = json.loads(res)
41
- return res
42
-
43
- def _process_v2(self, res):
44
- res = json.loads(res)
45
- return res
46
-
47
- def _process_v3(self, x):
48
- x = json.loads(x)
49
- res = {}
50
- question_id = 0
51
- for k, v in x.items():
52
-
53
- if 'answer' in v:
54
- question_id += 1
55
- question_name = f'Question {question_id}'
56
- res_tmp = {"answer": v['answer'], "original sentences": v['original sentences']}
57
- res[question_name] = res_tmp
58
- else:
59
-
60
- k_1, k_2 = v.keys()
61
- in_1 = v[k_1]
62
- in_2 = v[k_2]
63
-
64
- question_id += 1
65
- question_name = f'Question {question_id}'
66
- res_tmp_1 = {"answer": in_1['answer'], "original sentences": in_1['original sentences']}
67
- res[question_name] = res_tmp_1
68
-
69
- question_id += 1
70
- question_name = f'Question {question_id}'
71
- res_tmp_2 = {"answer": in_2['answer'], "original sentences": in_2['original sentences']}
72
- res[question_name] = res_tmp_2
73
-
74
- return res
75
-
76
- def process_result(self, result, version = None):
77
- if not version is None and self.version != version:
78
- self.version = version
79
- print(f'Version changed to {version}')
80
-
81
- if version == 'v1':
82
- result = self._process_v1(result)
83
- return result
84
- elif version == 'v2':
85
- result = self._process_v2(result)
86
- return result
87
- elif version == 'v3':
88
- result = self._process_v3(result)
89
- return result
90
- else:
91
- raise ValueError('Version should be one of {v1, v2, v3}')
 
1
+ from template import TEMPLATE_v1, TEMPLATE_v2, TEMPLATE_v3, QUESTIONS
2
+ import json
3
+
4
+ class Prompt:
5
+ def __init__(self) -> None:
6
+ # self.questions = QUESTIONS
7
+ self.template_v1 = TEMPLATE_v1
8
+ self.template_v2 = TEMPLATE_v2
9
+ self.template_v3 = TEMPLATE_v3
10
+ self.version = "v3"
11
+
12
+ def combine_questions(self, questions):
13
+ questions = [ f'Question {id_ +1 }: {q}' for id_, q in enumerate(questions) if 'Input question' not in q]
14
+ questions = '\n'.join(questions)
15
+ return questions
16
+
17
+ def _get_v1(self, input, questions):
18
+ questions = self.combine_questions(questions)
19
+ return self.template_v1.format(input, self.questions)
20
+
21
+ def _get_v2(self, input, questions):
22
+ questions = self.combine_questions(questions)
23
+ return self.template_v2.format(input, self.questions)
24
+
25
+ def _get_v3(self, input, questions):
26
+ return self.template_v3.format(input)
27
+
28
+ def get(self, input, questions, version = None):
29
+ self.version = version if version else self.version
30
+ if self.version == 'v1':
31
+ return self._get_v1(input, questions)
32
+ elif self.version == 'v2':
33
+ return self._get_v2(input, questions)
34
+ elif self.version == 'v3':
35
+ return self._get_v3(input, questions)
36
+ else:
37
+ raise ValueError('Version should be one of {v1, v2, v3}')
38
+
39
+ def _process_v1(self, res):
40
+ res = json.loads(res)
41
+ return res
42
+
43
+ def _process_v2(self, res):
44
+ res = json.loads(res)
45
+ return res
46
+
47
+ def _process_v3(self, x):
48
+ x = json.loads(x)
49
+ res = {}
50
+ question_id = 0
51
+ for k, v in x.items():
52
+
53
+ if 'answer' in v:
54
+ question_id += 1
55
+ question_name = f'Question {question_id}'
56
+ res_tmp = {"answer": v['answer'], "original sentences": v['original sentences']}
57
+ res[question_name] = res_tmp
58
+ else:
59
+
60
+ k_1, k_2 = v.keys()
61
+ in_1 = v[k_1]
62
+ in_2 = v[k_2]
63
+
64
+ question_id += 1
65
+ question_name = f'Question {question_id}'
66
+ res_tmp_1 = {"answer": in_1['answer'], "original sentences": in_1['original sentences']}
67
+ res[question_name] = res_tmp_1
68
+
69
+ question_id += 1
70
+ question_name = f'Question {question_id}'
71
+ res_tmp_2 = {"answer": in_2['answer'], "original sentences": in_2['original sentences']}
72
+ res[question_name] = res_tmp_2
73
+
74
+ return res
75
+
76
+ def process_result(self, result, version = None):
77
+ if not version is None and self.version != version:
78
+ self.version = version
79
+ print(f'Version changed to {version}')
80
+
81
+ if version == 'v1':
82
+ result = self._process_v1(result)
83
+ return result
84
+ elif version == 'v2':
85
+ result = self._process_v2(result)
86
+ return result
87
+ elif version == 'v3':
88
+ result = self._process_v3(result)
89
+ return result
90
+ else:
91
+ raise ValueError('Version should be one of {v1, v2, v3}')
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- fuzzywuzzy
2
- openpyxl
3
- unstructured[all-docs]
4
  langchain
 
1
+ fuzzywuzzy
2
+ openpyxl
3
+ unstructured[all-docs]
4
  langchain
template.py CHANGED
@@ -1,177 +1,177 @@
1
- TEMPLATE_v3 = '''We now have a following <document> in the medical field:
2
-
3
- """
4
- {}
5
- """
6
- You are an expert in biomedical research.
7
- You are asked to answer the following <question>s based on the <document>, the <question>s and their <instruction>s and <rule>s are as follows:
8
-
9
- - "Question 1":
10
- - "question": "What is the <animal type> of this study?"
11
- - "instruction": "This task is to find the <animal type> according to the <document>."
12
- - "definition":
13
- - "animal type": "The rodent type used in the article"
14
- - "rule": "<answer> of <animal type> should be one of the two choices {{mice/rats}} or both"
15
-
16
- - "Question 2":
17
- - "question": "What is the <exposure age> of this study?"
18
- - "instruction": "This task is to find the <exposure age> according to the <document>."
19
- - "definition":
20
- - "exposure age": "The age when the animals were exposed to anesthetics. There are two kinds of <exposure age>: <postnatal day> and <gestational day>"
21
- - "postnatal day": "<postnatal day> means the days after the animals were born. For example, 'postnatal day <int>' means the animals were born for <int> day. 'postnatal day <int>' is sometimes shortened to 'PND <int>' or 'pnd <int>', which still means 'postnatal day <int>', after birth. 'postnatal day <int>' is sometimes shortened to 'p<int>', which still means 'postnatal day <int>', after birth"
22
- - "gestational day": "<gestational day> means the days after the animals were pregnant. For example, 'gestational day <int>' means the animals were pregnant for <int> day. 'gestational day <int>' is sometimes abbreviated as 'E <int>', 'E' meaning before birth"
23
- - "rule": "<answer> of <exposure age> should be expressed as one of {{'postnatal day <int>'/'gestational day <int>'}}. For Example: "postnatal day 7", "Gestational day 21"
24
-
25
- - "Question 3":
26
- - "question": "Is there any <behavior test> done in this study?"
27
- - "instruction": "This task is to find whether there are any <behavior test> in the study according to the <document>."
28
- - "definition":
29
- - "behavior test": "If there are any of the <behavior tests> described and done in the article, which mentioned as: 'Open field test', 'Morris water task', 'fear conditioning test', 'Dark/light avoidance'; 'passive/active avoidance test'; 'elevated maze', 'Forced swim test', 'Object recognition test', 'Social interaction/preference'."
30
- - "rule": "<answer> to <behavior test> should be one of the two choices {{Yes/No}}."
31
-
32
- - "Question 4":
33
- - "question": "What's the <intervention>s of this study?
34
- - "instruction": "This task is to find the <intervention>s according to the <document>."
35
- - "definition":
36
- - "intervention": "The <intervention>s are anesthetic drugs, which in one of {{"isoflurane"/"sevoflurane"/"desflurane"/"ketamine"/"propofol"/"Midazolam"/"Nitrous oxide“}}."
37
- - "rule": "There are one or two <intervention>s in the <document>. Please find them all and answer the <question>. If there is only one <intervention>, the second one is 'None'."
38
-
39
- - "Question 5":
40
- - "question": "What's the <genetic chain> of this study?"
41
- - "instruction": "This task is to find the <genetic chain> according to the <document>."
42
- - "definition":
43
- - "genetic chain": "The <genetic chain> is the genetic type of the animals being used in the article."
44
- - "rule": "Please do as the following examples: 'C57BL/6', 'C57BL/6J' should be extracted as 'C57BL/6'; 'Sprague Dawley', 'Sprague-Dawley', 'SD' should be extracted as 'Sprague Dawley'; 'CD-1' should be extracted as 'CD-1'; 'Wistar/ST' should be extracted as 'Wistar/ST'; 'Wistar' should be extracted as 'Wistar'; 'FMR-1 KO' should be extracted as 'FMR-1 KO'."
45
-
46
-
47
- Here is the instrucrtions for all the <question>s:
48
-
49
- 1. Please select the <original sentences> related the "behavior tests" from the <document> for each <question>.
50
- 2. Please use the <original sentences> to answer the <question> by following the <rule> and <instruction> accroding to the <definition>.
51
- 3. Please provide <original sentences> coming from the <document>.
52
- 4. Output the <answer> in the following JSON format:
53
-
54
- {{
55
- "Question 1": {{
56
- "answer": "{{mice/rats/both}}",
57
- "original sentences": []
58
- }},
59
- "Question 2": {{
60
- "answer": "{{postnatal day <int>/gestational day <int>}}",
61
- "original sentences": []
62
- }},
63
- "Question 3": {{
64
- "answer": "{{Yes/No}}",
65
- "original sentences": []
66
- }},
67
- "Question 4":
68
- {{
69
- {{intervention 1}}: {{
70
- "answer": "{{intervention 1}}]",
71
- "original sentences": []
72
- }}
73
- {{intervention 2}}: {{
74
- "answer": "{{intervention 2}}",
75
- "original sentences": []
76
- }}
77
- }},
78
- "Question 5": {{
79
- "answer": "{{genetic chain}}",
80
- "original sentences": []
81
- }}
82
- }}
83
- '''
84
-
85
- TEMPLATE_v2 = '''We now have a following <document> in the medical field:
86
-
87
- """
88
- {}
89
- """
90
- We have some introduction here:
91
-
92
- 1. DOI: The DOI link for the article, usually can be found in the first line of the .txt file for the article. E.g., “DOI: 10.3892/mmr.2019.10397”.
93
- 2. Citation ID: The number in the file name. E.g., “1134”.
94
- 3. First author: The last name in the file name. E.g., “Guan”.
95
- 4. Year: The year in the file name. E.g., “2019”.
96
- 5. Animal type: The rodent type used in the article, should be one of the choices: mice, rats. E.g., “rats”.
97
- 6. Exposure age: The age when the animals were exposed to anesthetics, should be mentioned as "PND1", "PND7","postnatal day 7", "Gestational day 21", etc, which should be extract as: 'PND XX' , 'Gestational day xx'. E.g., “PND7”.
98
- 7. Behavior test: Whether there is any behavior test in the article, should be one of the choices: "Y", "N". "Y" is chosen if there are any of the behavior tests described and done in the article, which mentioned as: "Open field test", "Morris water task", "fear conditioning test", "Dark/light avoidance"; "passive/active avoidance test"; "elevated maze", "Forced swim test", "Object recognition test", "Social interaction/preference“. E.g., “N”.
99
- 8. Intervention 1 & Intervention 2: Intervention 1 and Intervention 2 are both anesthetic drugs, which listed as: "isoflurane", "sevoflurane", "desflurane", "ketamine", "propofol", "Midazolam", "Nitrous oxide“. If none, put “NA”. E.g., “propofol”.
100
- 9. Genetic chain: Genetic chain is the genetic type of the animals being used in the article, here is the examples:
101
- "C57BL/6", "C57BL/6J" should be extracted as "C57BL/6"; "Sprague Dawley", "Sprague-Dawley", "SD" should be extracted as "Sprague Dawley"; "CD-1" should be extracted as "CD-1"; "Wistar/ST" should be extracted as "Wistar/ST"; "Wistar" should be extracted as "Wistar"; "FMR-1 KO" should be extracted as "FMR-1 KO“. E.g., “Sprague Dawley”.
102
-
103
- We have some <question>s begin with "Question" here:
104
- """
105
- {}
106
- """
107
-
108
- Please finish the following task:
109
-
110
- 1. Please select the <original sentences> related the each <question> from the <document>.
111
- 2. Please use the <original sentences> to answer the <question>.
112
- 3. Please provide <original sentences> coming from the <document>.
113
- 4. Output the <answer> in the following json format:
114
-
115
- {{
116
- "Question 1": {{
117
- "question": {{}},
118
- "answer": {{}},
119
- "original sentences": []
120
- }},
121
- "Question 2": {{
122
- "question": {{}},
123
- "answer": {{}},
124
- "original sentences": []
125
- }},
126
- ...
127
- }}
128
- '''
129
-
130
- TEMPLATE_v1 = '''We now have a following <document> in the medical field:
131
-
132
- """
133
- {}
134
- """
135
-
136
- We have some <question>s begin with "Question" here:
137
- """
138
- {}
139
- """
140
-
141
- Please finish the following task:
142
-
143
- 1. Please select the <original sentences> related the each <question> from the <document>.
144
- 2. Please use the <original sentences> to answer the <question>.
145
- 3. Please provide <original sentences> coming from the <document>.
146
- 4. Output the <answer> in the following json format:
147
-
148
- {{
149
- "Question 1": {{
150
- "question": {{}},
151
- "answer": {{}},
152
- "original sentences": []
153
- }},
154
- "Question 2": {{
155
- "question": {{}},
156
- "answer": {{}},
157
- "original sentences": []
158
- }},
159
- ...
160
- }}
161
- '''
162
-
163
- QUESTIONS = [
164
- "What is the DOI of this study?",
165
- "What is the Citation ID of this study?",
166
- "What is the First author of this study?",
167
- "What is the year of this study?",
168
- "What is the animal type of this study?",
169
- "What is the exposure age of this study?",
170
- "Is there any behavior test done in this study?",
171
- "What's the Intervention 1's name of this study?(anesthetics only)",
172
- "What's the Intervention 2's name of this study?(anesthetics only)",
173
- "What's the genetic chain of this study?",
174
- "Input question",
175
- ]
176
- QUESTIONS = [ f'Question {id_ +1 }: {q}' for id_, q in enumerate(QUESTIONS) if 'Input question' not in q]
177
  QUESTIONS = '\n'.join(QUESTIONS)
 
1
+ TEMPLATE_v3 = '''We now have a following <document> in the medical field:
2
+
3
+ """
4
+ {}
5
+ """
6
+ You are an expert in biomedical research.
7
+ You are asked to answer the following <question>s based on the <document>, the <question>s and their <instruction>s and <rule>s are as follows:
8
+
9
+ - "Question 1":
10
+ - "question": "What is the <animal type> of this study?"
11
+ - "instruction": "This task is to find the <animal type> according to the <document>."
12
+ - "definition":
13
+ - "animal type": "The rodent type used in the article"
14
+ - "rule": "<answer> of <animal type> should be one of the two choices {{mice/rats}} or both"
15
+
16
+ - "Question 2":
17
+ - "question": "What is the <exposure age> of this study?"
18
+ - "instruction": "This task is to find the <exposure age> according to the <document>."
19
+ - "definition":
20
+ - "exposure age": "The age when the animals were exposed to anesthetics. There are two kinds of <exposure age>: <postnatal day> and <gestational day>"
21
+ - "postnatal day": "<postnatal day> means the days after the animals were born. For example, 'postnatal day <int>' means the animals were born for <int> day. 'postnatal day <int>' is sometimes shortened to 'PND <int>' or 'pnd <int>', which still means 'postnatal day <int>', after birth. 'postnatal day <int>' is sometimes shortened to 'p<int>', which still means 'postnatal day <int>', after birth"
22
+ - "gestational day": "<gestational day> means the days after the animals were pregnant. For example, 'gestational day <int>' means the animals were pregnant for <int> day. 'gestational day <int>' is sometimes abbreviated as 'E <int>', 'E' meaning before birth"
23
+ - "rule": "<answer> of <exposure age> should be expressed as one of {{'postnatal day <int>'/'gestational day <int>'}}. For Example: "postnatal day 7", "Gestational day 21"
24
+
25
+ - "Question 3":
26
+ - "question": "Is there any <behavior test> done in this study?"
27
+ - "instruction": "This task is to find whether there are any <behavior test> in the study according to the <document>."
28
+ - "definition":
29
+ - "behavior test": "If there are any of the <behavior tests> described and done in the article, which mentioned as: 'Open field test', 'Morris water task', 'fear conditioning test', 'Dark/light avoidance'; 'passive/active avoidance test'; 'elevated maze', 'Forced swim test', 'Object recognition test', 'Social interaction/preference'."
30
+ - "rule": "<answer> to <behavior test> should be one of the two choices {{Yes/No}}."
31
+
32
+ - "Question 4":
33
+ - "question": "What's the <intervention>s of this study?
34
+ - "instruction": "This task is to find the <intervention>s according to the <document>."
35
+ - "definition":
36
+ - "intervention": "The <intervention>s are anesthetic drugs, which in one of {{"isoflurane"/"sevoflurane"/"desflurane"/"ketamine"/"propofol"/"Midazolam"/"Nitrous oxide“}}."
37
+ - "rule": "There are one or two <intervention>s in the <document>. Please find them all and answer the <question>. If there is only one <intervention>, the second one is 'None'."
38
+
39
+ - "Question 5":
40
+ - "question": "What's the <genetic chain> of this study?"
41
+ - "instruction": "This task is to find the <genetic chain> according to the <document>."
42
+ - "definition":
43
+ - "genetic chain": "The <genetic chain> is the genetic type of the animals being used in the article."
44
+ - "rule": "Please do as the following examples: 'C57BL/6', 'C57BL/6J' should be extracted as 'C57BL/6'; 'Sprague Dawley', 'Sprague-Dawley', 'SD' should be extracted as 'Sprague Dawley'; 'CD-1' should be extracted as 'CD-1'; 'Wistar/ST' should be extracted as 'Wistar/ST'; 'Wistar' should be extracted as 'Wistar'; 'FMR-1 KO' should be extracted as 'FMR-1 KO'."
45
+
46
+
47
+ Here is the instrucrtions for all the <question>s:
48
+
49
+ 1. Please select the <original sentences> related the "behavior tests" from the <document> for each <question>.
50
+ 2. Please use the <original sentences> to answer the <question> by following the <rule> and <instruction> accroding to the <definition>.
51
+ 3. Please provide <original sentences> coming from the <document>.
52
+ 4. Output the <answer> in the following JSON format:
53
+
54
+ {{
55
+ "Question 1": {{
56
+ "answer": "{{mice/rats/both}}",
57
+ "original sentences": []
58
+ }},
59
+ "Question 2": {{
60
+ "answer": "{{postnatal day <int>/gestational day <int>}}",
61
+ "original sentences": []
62
+ }},
63
+ "Question 3": {{
64
+ "answer": "{{Yes/No}}",
65
+ "original sentences": []
66
+ }},
67
+ "Question 4":
68
+ {{
69
+ {{intervention 1}}: {{
70
+ "answer": "{{intervention 1}}",
71
+ "original sentences": []
72
+ }}
73
+ {{intervention 2}}: {{
74
+ "answer": "{{intervention 2}}",
75
+ "original sentences": []
76
+ }}
77
+ }},
78
+ "Question 5": {{
79
+ "answer": "{{genetic chain}}",
80
+ "original sentences": []
81
+ }}
82
+ }}
83
+ '''
84
+
85
+ TEMPLATE_v2 = '''We now have a following <document> in the medical field:
86
+
87
+ """
88
+ {}
89
+ """
90
+ We have some introduction here:
91
+
92
+ 1. DOI: The DOI link for the article, usually can be found in the first line of the .txt file for the article. E.g., “DOI: 10.3892/mmr.2019.10397”.
93
+ 2. Citation ID: The number in the file name. E.g., “1134”.
94
+ 3. First author: The last name in the file name. E.g., “Guan”.
95
+ 4. Year: The year in the file name. E.g., “2019”.
96
+ 5. Animal type: The rodent type used in the article, should be one of the choices: mice, rats. E.g., “rats”.
97
+ 6. Exposure age: The age when the animals were exposed to anesthetics, should be mentioned as "PND1", "PND7","postnatal day 7", "Gestational day 21", etc, which should be extract as: 'PND XX' , 'Gestational day xx'. E.g., “PND7”.
98
+ 7. Behavior test: Whether there is any behavior test in the article, should be one of the choices: "Y", "N". "Y" is chosen if there are any of the behavior tests described and done in the article, which mentioned as: "Open field test", "Morris water task", "fear conditioning test", "Dark/light avoidance"; "passive/active avoidance test"; "elevated maze", "Forced swim test", "Object recognition test", "Social interaction/preference“. E.g., “N”.
99
+ 8. Intervention 1 & Intervention 2: Intervention 1 and Intervention 2 are both anesthetic drugs, which listed as: "isoflurane", "sevoflurane", "desflurane", "ketamine", "propofol", "Midazolam", "Nitrous oxide“. If none, put “NA”. E.g., “propofol”.
100
+ 9. Genetic chain: Genetic chain is the genetic type of the animals being used in the article, here is the examples:
101
+ "C57BL/6", "C57BL/6J" should be extracted as "C57BL/6"; "Sprague Dawley", "Sprague-Dawley", "SD" should be extracted as "Sprague Dawley"; "CD-1" should be extracted as "CD-1"; "Wistar/ST" should be extracted as "Wistar/ST"; "Wistar" should be extracted as "Wistar"; "FMR-1 KO" should be extracted as "FMR-1 KO“. E.g., “Sprague Dawley”.
102
+
103
+ We have some <question>s begin with "Question" here:
104
+ """
105
+ {}
106
+ """
107
+
108
+ Please finish the following task:
109
+
110
+ 1. Please select the <original sentences> related the each <question> from the <document>.
111
+ 2. Please use the <original sentences> to answer the <question>.
112
+ 3. Please provide <original sentences> coming from the <document>.
113
+ 4. Output the <answer> in the following json format:
114
+
115
+ {{
116
+ "Question 1": {{
117
+ "question": {{}},
118
+ "answer": {{}},
119
+ "original sentences": []
120
+ }},
121
+ "Question 2": {{
122
+ "question": {{}},
123
+ "answer": {{}},
124
+ "original sentences": []
125
+ }},
126
+ ...
127
+ }}
128
+ '''
129
+
130
+ TEMPLATE_v1 = '''We now have a following <document> in the medical field:
131
+
132
+ """
133
+ {}
134
+ """
135
+
136
+ We have some <question>s begin with "Question" here:
137
+ """
138
+ {}
139
+ """
140
+
141
+ Please finish the following task:
142
+
143
+ 1. Please select the <original sentences> related the each <question> from the <document>.
144
+ 2. Please use the <original sentences> to answer the <question>.
145
+ 3. Please provide <original sentences> coming from the <document>.
146
+ 4. Output the <answer> in the following json format:
147
+
148
+ {{
149
+ "Question 1": {{
150
+ "question": {{}},
151
+ "answer": {{}},
152
+ "original sentences": []
153
+ }},
154
+ "Question 2": {{
155
+ "question": {{}},
156
+ "answer": {{}},
157
+ "original sentences": []
158
+ }},
159
+ ...
160
+ }}
161
+ '''
162
+
163
+ QUESTIONS = [
164
+ "What is the DOI of this study?",
165
+ "What is the Citation ID of this study?",
166
+ "What is the First author of this study?",
167
+ "What is the year of this study?",
168
+ "What is the animal type of this study?",
169
+ "What is the exposure age of this study?",
170
+ "Is there any behavior test done in this study?",
171
+ "What's the Intervention 1's name of this study?(anesthetics only)",
172
+ "What's the Intervention 2's name of this study?(anesthetics only)",
173
+ "What's the genetic chain of this study?",
174
+ "Input question",
175
+ ]
176
+ QUESTIONS = [ f'Question {id_ +1 }: {q}' for id_, q in enumerate(QUESTIONS) if 'Input question' not in q]
177
  QUESTIONS = '\n'.join(QUESTIONS)