Spaces:
Sleeping
Sleeping
File size: 3,823 Bytes
17cd01c 333a6de 17cd01c 333a6de 715e9c8 333a6de 17cd01c 333a6de 17cd01c 333a6de 17cd01c 333a6de 17cd01c 333a6de |
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 |
import copy
import json
import time
"""
We will handle here the code evaluation phase.
"""
import json
EVAL_ANSWER_NOEVAL = 0
EVAL_ANSWER_POSITIVE = 1
EVAL_ANSWER_NEGATIVE = -1
CODE_AUGMENTATIONS=[
("NO_COMPILE", "The code provided is not a valid C code"),
("DRY", "Don't repeat yourself."),
("SRP", "Single object[function] responsability"),
("MC", "Magic constants."),
("NAME", "Meaningful names in the code."),
]
def clean_prompt_answer(answer):
"""
Chatgpt4 is ok, does not pollute the code but 3.5 encloses it in ```
:param answer:
:return:
"""
cleaned = []
for l in answer.split("\n"):
if l.startswith("```"):
continue
else:
cleaned.append(l)
return "\n".join(cleaned)
def parse_chatgpt_answer(ans_text):
try:
js_answer = json.loads(ans_text)
except:
# for now we dump the error in console
import traceback
exception = traceback.format_exc()
print(exception)
return {"error":exception}
return js_answer
def eval_code_by_chatgpt(openai_client, ccode):
"""
Will evaluate a piece of code using our heavily tuned prompt!
:param openai_client:
:param ccode:
:return:
"""
# time.sleep(3)
try:
return """[
{
"criteria": "DRY",
"explanation": "The memory allocation and initialization for ``p1``, ``p2``, and ``p3`` are repetitive. Consider creating a function like ``allocateAndInitializeMemory``."
},
{
"criteria": "DRY",
"explanation": "Tne second DRY failure, because this is the observed ChatGPT behaviour."
},
{
"criteria": "SRP",
"explanation": "The ``main`` function handles memory allocation, initialization, and printing. You should separate these responsibilities into different functions like ``allocateMemory``, ``initializeData``, and ``printData``."
},
{
"criteria": "NAME",
"explanation": "``x1`` should be called ``title``, ``y1`` should be called ``author``, ``z1`` should be called ``year``, ``p1`` should be called ``titlePtr``, ``p2`` should be called ``authorPtr``, ``p3`` should be called ``yearPtr``."
}
]"""
assert openai_client is not None
except:
import traceback
traceback.print_exc()
return {"error":"There was an error while parsing the answer. Maybe ChatGPT is overloaded?"}
def add_evaluation_fields_on_js_answer(json_answer, all_criterias = None):
"""
Adds some JSON fields to store the human feedback.
The textual human feedback will always be in the 0 position.
:param json_answer:
:return:
"""
if all_criterias is None:
all_criterias = CODE_AUGMENTATIONS
enhanced_answer = []
overall_feedback = {
"criteria":"HUMAN_FEEDBACK",
"explanation":"",
"EVAL": EVAL_ANSWER_NOEVAL
}
if all_criterias is not None:
existing = {c["criteria"] for c in json_answer}
for criteria in all_criterias:
if criteria[0] not in existing:
json_answer.append({"criteria":criteria[0], "explanation":"Not infringed"})
enhanced_answer.append(overall_feedback)
for ans in json_answer:
ans = copy.deepcopy(ans)
ans["EVAL"] = EVAL_ANSWER_NOEVAL
enhanced_answer.append(ans)
return enhanced_answer
def eval_the_piece_of_c_code(openai_client, ccode):
"""
Main entrypoint to this module. Will be called from backend. Will block so multithreading pls.
Will return a proprer json and will have EVAL fields, too.
:param ccode:
:return:
"""
chatgpt_ans = eval_code_by_chatgpt(openai_client, ccode)
chatgpt_js = parse_chatgpt_answer(chatgpt_ans)
enhanced_answer = add_evaluation_fields_on_js_answer(chatgpt_js)
return enhanced_answer
|