Skip to content

Commit ed30bda

Browse files
钱忱钱忱
authored andcommitted
eval
1 parent fd00a41 commit ed30bda

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

chatdev/eval_quality.py

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import os
2+
import re
3+
import signal
4+
import subprocess
5+
import time
6+
import numpy as np
7+
from openai import OpenAI
8+
9+
client = OpenAI(
10+
api_key='',
11+
base_url="",
12+
)
13+
14+
def getFilesFromType(sourceDir, filetype):
15+
files = []
16+
for root, directories, filenames in os.walk(sourceDir):
17+
for filename in filenames:
18+
if filename.endswith(filetype):
19+
files.append(os.path.join(root, filename))
20+
return files
21+
22+
def get_code(directory):
23+
def _format_code(code):
24+
code = "\n".join([line for line in code.split("\n") if len(line.strip()) > 0])
25+
return code
26+
27+
codebooks = {}
28+
filepaths = getFilesFromType(directory, ".py")
29+
for filepath in filepaths:
30+
filename = os.path.basename(filepath)
31+
codebooks[filename] = _format_code(open(filepath, "r", encoding="utf-8").read())
32+
33+
code = ""
34+
for filename in codebooks.keys():
35+
code += "{}\n```Python\n{}\n```\n\n".format(filename, codebooks[filename])
36+
37+
if len(code) == 0:
38+
code = "# None"
39+
40+
return code.strip()
41+
42+
def get_completeness(directory):
43+
assert os.path.isdir(directory)
44+
vn = get_code(directory)
45+
lines = vn.split("\n")
46+
lines = [line for line in lines if
47+
"password" not in line.lower() and "passenger" not in line.lower() and "passed" not in line.lower() and "passes" not in line.lower()]
48+
lines = [line for line in lines if "pass" in line.lower() or "todo" in line.lower()]
49+
if len(lines) > 0:
50+
return 0.0
51+
return 1.0
52+
53+
def get_executability(directory):
54+
assert os.path.isdir(directory)
55+
def findFile(directory, target):
56+
main_py_path = None
57+
for subroot, _, filenames in os.walk(directory):
58+
for filename in filenames:
59+
if target in filename:
60+
main_py_path = os.path.join(subroot, filename)
61+
return main_py_path
62+
63+
def exist_bugs(directory):
64+
assert os.path.isdir(directory)
65+
success_info = "The software run successfully without errors."
66+
try:
67+
command = "cd \"{}\"; ls -l; python3 main.py;".format(directory)
68+
process = subprocess.Popen(command, shell=True, preexec_fn=os.setsid, stdout=subprocess.PIPE,
69+
stderr=subprocess.PIPE)
70+
time.sleep(3)
71+
72+
error_type = ""
73+
return_code = process.returncode
74+
if process.poll() is None:
75+
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
76+
if return_code == 0:
77+
return False, success_info, error_type
78+
else:
79+
error_output = process.stderr.read().decode('utf-8')
80+
try:
81+
error_pattern = r'\w+Error:'
82+
error_matches = re.findall(error_pattern, error_output)
83+
error_type = error_matches[0].replace(":", "")
84+
except:
85+
pass
86+
if error_output:
87+
if "Traceback".lower() in error_output.lower():
88+
errs = error_output.replace(directory + "/", "")
89+
return True, errs, error_type
90+
else:
91+
return False, success_info, error_type
92+
except subprocess.CalledProcessError as e:
93+
return True, f"Error: {e}", "subprocess.CalledProcessError"
94+
except Exception as ex:
95+
return True, f"An error occurred: {ex}", "OtherException"
96+
97+
return False, success_info, error_type
98+
99+
main_py_path = findFile(directory, ".py")
100+
pass_flag, error_type = True, ""
101+
if main_py_path is not None:
102+
main_py_path = os.path.dirname(main_py_path)
103+
bug_flag, info, error_type = exist_bugs(main_py_path)
104+
pass_flag = not bug_flag
105+
else:
106+
pass_flag, error_type = False, "NoMain"
107+
108+
if error_type == "":
109+
error_type = info.replace("\n", "\\n")
110+
111+
if pass_flag:
112+
return 1.0
113+
return 0.0
114+
115+
def get_consistency(directory):
116+
def remove_comments(string):
117+
def remove_comments_by_regex(string, regex):
118+
lines = string.split("\n")
119+
lines = [line for line in lines if not line.strip().startswith("#")]
120+
string = "\n".join(lines)
121+
comments = []
122+
matches = re.finditer(regex, string, re.DOTALL)
123+
for match in matches:
124+
group1 = match.group(1)
125+
comments.append(group1)
126+
for comment in comments + ["''''''\n"]:
127+
string = string.replace(comment, "")
128+
return string
129+
130+
string = remove_comments_by_regex(string, r"'''(.*?)'''")
131+
string = remove_comments_by_regex(string, r"\"\"\"(.*?)\"\"\"")
132+
return string
133+
134+
def get_text_embedding(text: str):
135+
if text == "":
136+
text = "None"
137+
ada_embedding = client.embeddings.create(input=text, model="text-embedding-ada-002").model_dump()['data'][0]['embedding']
138+
return ada_embedding
139+
140+
def get_code_embedding(code: str):
141+
if code == "":
142+
code = "#"
143+
ada_embedding = client.embeddings.create(input=code, model="text-embedding-ada-002").model_dump()['data'][0]['embedding']
144+
return ada_embedding
145+
146+
def get_cosine_similarity(embeddingi, embeddingj):
147+
embeddingi = np.array(embeddingi)
148+
embeddingj = np.array(embeddingj)
149+
cos_sim = embeddingi.dot(embeddingj) / (np.linalg.norm(embeddingi) * np.linalg.norm(embeddingj))
150+
return cos_sim
151+
152+
assert os.path.isdir(directory)
153+
files = getFilesFromType(directory, ".txt")
154+
if len(files) == 0:
155+
print()
156+
filepath = files[0]
157+
task = open(filepath).read().strip()
158+
codes = get_code(directory)
159+
codes = remove_comments(codes)
160+
161+
text_embedding = get_text_embedding(task)
162+
code_embedding = get_code_embedding(codes)
163+
task_code_alignment = get_cosine_similarity(text_embedding, code_embedding)
164+
165+
return task_code_alignment
166+
167+
def main(warehouse_root):
168+
def write_string(string):
169+
writer.write(string)
170+
print(string, end="")
171+
172+
directories = []
173+
for directory in os.listdir(warehouse_root):
174+
directories.append(os.path.join(warehouse_root, directory))
175+
directories = sorted(directories)
176+
directories = [directory for directory in directories if os.path.isdir(directory)]
177+
print("len(directories):", len(directories))
178+
179+
suffix = warehouse_root.replace("/", "__").replace("-", "_")
180+
tsv_file = __file__.replace(".py", ".{}.tsv".format(suffix))
181+
print("tsv_file:", tsv_file)
182+
183+
counter = 0
184+
completeness_list, executability_list, consistency_list = [], [], []
185+
with open(tsv_file, "a", encoding="utf-8") as writer:
186+
for i, directory in enumerate(directories):
187+
directory_basename = os.path.basename(directory)
188+
189+
completeness = get_completeness(directory)
190+
executability = get_executability(directory)
191+
consistency = get_consistency(directory)
192+
193+
completeness_list.append(completeness)
194+
executability_list.append(executability)
195+
consistency_list.append(consistency)
196+
197+
counter += 1
198+
199+
main(warehouse_root = "./WareHouse")

0 commit comments

Comments
 (0)