Reasoning-with-StarCoder / mathprompter.py
rootacess's picture
fixed auth
201cfef
import pandas as pd
import numpy as np
import re
from prompt import algebric_prompt, python_prompt
from utils import generate_response, run_code
def generate_algebric_template(question):
var_names = [chr(i) for i in range(ord('A'), ord('Z') + 1)]
pattern = re.compile(r"[-+]?\d*\.\d+|\d+")
var_map = {}
matches = re.findall(pattern, question)
for i, num in enumerate(matches):
var_name = var_names[i]
question = question.replace(num, var_name)
var_map[var_name] = float(num)
return question, var_map
def generate_algebric_expression(question, param):
question = question.strip()
query = algebric_prompt.format(question=question).strip() + "\n"
response = generate_response(query, param)
expression = response.split(f"#Ques: {question}")[-1].strip()
return expression.split("Answer = ")[-1]
def generate_python_code(question, equation, param):
query = python_prompt.format(question=question.strip(), expression=equation.strip()).strip() + "\n"
response = generate_response(query, param)
function_code = response.split("# Function for above expression is:")[-1].strip()
return function_code
def run(question, random_candidates, hps):
question, var_map = generate_algebric_template(question)
# generating the random candidates for arguments
random_mapping = pd.DataFrame(columns=list(var_map.keys()))
for _ in range(random_candidates):
random_mapping.loc[len(random_mapping)] = np.random.randint(1, 100, (len(random_mapping.columns),))
candidates = []
acc = []
# accumulating results
N = len(hps)
for i in range(N):
expression = generate_algebric_expression(question, hps[i])
code = generate_python_code(question, expression, hps[i])
candidates.append((expression, code))
current_acc = 0
try:
for idx in range(5):
arguments = random_mapping.iloc[idx].to_list()
# running expression
exp = expression
temp_code = code
for k, v in zip(list(var_map.keys()), arguments):
exp = exp.replace(k, str(v))
exp = "print(" + exp + ")"
if "input(" in exp or "input(" in temp_code:
acc.append(0)
continue
exp_ans = run_code(exp)
# running code
parameters = temp_code.split("\n")[0].split("def solution")[-1][1:-2].split(",")
if '' in parameters:
parameters.remove('')
arguments = [(param.strip(), int(random_mapping.iloc[idx][param.strip()])) for param in parameters]
arg_string = ""
for param, val in arguments:
arg_string += f"{param}={val},"
func_call = f"\nprint(solution({arg_string[:-1]}))"
temp_code += func_call
code_ans = run_code(temp_code)
current_acc += int(exp_ans == code_ans)
# reverting the changes
exp = expression
temp_code = code
except Exception as ex:
pass
acc.append(current_acc)
candidate_index = np.argmax(acc)
top_candidate = candidates[candidate_index]
return top_candidate, var_map
def solve_mp(question):
hps = [0.9, 0.95]
(expression, code), var_map = run(question, 5, hps)
exp_op = None
code_op = None
try:
# expression output
for k, v in var_map.items():
expression = expression.replace(k, str(v))
expression = "print(" + expression + ")"
print(expression)
if "input(" in expression:
raise Exception
exp_op = run_code(expression)
except:
print("expression cannot be executed", expression)
try:
# code output
parameters = code.split("\n")[0].split("def solution")[-1][1:-2].split(",")
if '' in parameters:
parameters.remove('')
arguments = [(param.strip(), int(var_map[param.strip()])) for param in parameters]
arg_string = ""
for param, val in arguments:
arg_string += f"{param}={val},"
func_call = f"\nprint(solution({arg_string[:-1]}))"
code += func_call
if "input(" in code:
print("code cannot be executed")
raise Exception
code_op = run_code(code)
except:
return None, None, code, expression
return exp_op, code_op, code, expression