-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathtool.py
168 lines (151 loc) · 4.59 KB
/
tool.py
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
161
162
163
164
165
166
167
168
from typing import Union, Any
from math import isclose
import func_timeout
from sympy.solvers import solve
from sympy import Symbol, Eq
import math
from sympy import simplify
import numpy as np
import cvxpy as cp
import statistics
def get_precision(gt_ans: float) -> int:
precision = 5
if '.' in str(gt_ans):
precision = len(str(gt_ans).split('.')[-1])
return precision
def finqa_equal(prediction: Union[bool, float, str],
reference: Union[float, str],
include_percentage: bool = False,
is_close: float = False) -> bool:
if prediction is None:
return False
elif type(prediction) == bool:
# bool questions
if prediction:
return reference == 'yes'
else:
return reference == 'no'
elif type(reference) == str or type(prediction) == str:
# string questions
return prediction == reference
else:
# number questions
if include_percentage:
gt_result = [reference / 100, reference, reference * 100]
else:
gt_result = [reference]
for item in gt_result:
try:
if is_close:
if isclose(item, prediction, rel_tol=0.001):
return True
precision = min(get_precision(prediction), get_precision(item))
if round(prediction, precision) == round(item, precision):
return True
except Exception:
continue
return False
def simplify_ans(ans, convert_to_str: bool = True):
if 'relational' in str(type(ans)):
return str(ans)
elif 'numpy' in str(type(ans)):
if ans.shape == ():
# scalar value
ans = round(float(ans), 2)
else:
# array value
ans = round(float(ans[0]), 2)
if convert_to_str:
return str(ans)
else:
return ans
elif not ans:
return None
else:
if type(ans) in [list, tuple]:
if 'sympy' in str(type(ans[0])):
try:
ans = [round(float(x), 2) for x in ans]
except Exception:
ans = [str(x) for x in ans]
if len(ans) == 1:
ans = ans[0]
else:
if 'sympy' in str(type(ans)):
try:
ans = round(float(ans), 2)
except Exception:
ans = str(ans)
if convert_to_str:
return str(ans)
else:
return ans
def floatify_ans(ans):
if ans is None:
return None
elif type(ans) == dict:
ans = list(ans.values())[0]
elif type(ans) == bool:
ans = ans
elif type(ans) in [list, tuple]:
if not ans:
return None
else:
try:
ans = float(ans[0])
except Exception:
ans = str(ans[0])
else:
try:
ans = float(ans)
except Exception:
ans = str(ans)
return ans
def parse_api_result(result):
to_return = []
for idx, g in enumerate(result['choices']):
text = g['text']
logprob = sum(g['logprobs']['token_logprobs'])
to_return.append((text, logprob))
to_return = sorted(to_return, key=lambda tup: tup[1], reverse=True)
to_return = [r[0] for r in to_return]
return to_return
def solve_it(equation, variable):
solution = solve(equation, variable, dict=True)
if not solution:
if isinstance(variable, list):
solution = {v: None for v in variable}
else:
solution = {variable: None}
return solution
else:
solution = solution[0]
return solution
def safe_execute(code_string: str, keys=None):
def execute(x):
try:
exec(x)
locals_ = locals()
if keys is None:
return locals_.get('ans', None)
else:
return [locals_.get(k, None) for k in keys]
except Exception:
return None
try:
ans = func_timeout.func_timeout(5, execute, args=(code_string,))
except func_timeout.FunctionTimedOut:
ans = None
return ans
def synthesize_program(result: str, prefix: str) -> str:
program = prefix
for i, line in enumerate(result.split('\n')):
if i == 0:
program += line + '\n'
else:
if line.startswith(' '):
program += line + '\n'
else:
break
program += 'ans = solver()'
return program