-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathequation_parser.py
114 lines (97 loc) · 3.94 KB
/
equation_parser.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
from output_formatter import print_full_form
def argv_check(str):
"""Checks the validity of the input equation string."""
if str.count('=') != 1:
return False
for i, char in enumerate(str):
if char not in set("0123456789^.*=+-X"):
return False
if char == '*' and i < len(str) - 1 and str[i + 1] != 'X':
return False
if char in ('-', '+') and i < len(str) - 1:
if not str[i + 1].isdigit() and str[i + 1] != 'X':
return False
if char in set("+-*=") and i == len(str) - 1:
return False
if char == '^':
if i > 0 and str[i - 1] != 'X':
return False
if i < len(str) - 1 and str[i + 1] not in set('0123'):
return False
if i == 0 or i == len(str) - 1:
return False
if i < len(str) - 2 and str[i + 2] not in set('+-='):
return False
if (char == '=' or char == '*') and i == 0:
return False
if char == '.' and i > 0 and str[i - 1] == '.':
return False
if char == 'X':
if i > 0 and str[i - 1] not in set('*+-='):
return False
elif i < len(str) - 1 and str[i + 1] not in set('^=+-'):
return False
return True
def split_equation(part_str):
"""Splits the equation string into list based on the symbols '+' '-'."""
equation_parts = part_str.split('+')
split_parts = []
for part in equation_parts:
parts_with_minus = part.split('-')
for i, sub_part in enumerate(parts_with_minus):
if i == 0:
split_parts.append(sub_part)
else:
split_parts.append('-' + sub_part)
return split_parts
def parse_sides(f_list, side, p):
"""Parses the equation side and updates the coefficient dictionary."""
for s in side:
index = s.find("*X^")
if (index > 0):
num = float(s[:index])
index += 3
order = int(s[index])
f_list[f'x{order}'].append(num) if p == 'l' \
else f_list[f'x{order}'].append(-num)
else:
index_any = s.find("X^")
if index_any == 0:
order = int(s[index_any + 2])
f_list[f'x{order}'].append(1) if p == 'l' \
else f_list[f'x{order}'].append(-1)
elif index_any == 1 and s[0] == '-':
order = int(s[index_any + 2])
f_list[f'x{order}'].append(-1) if p == 'l' \
else f_list[f'x{order}'].append(1)
else:
index1 = s.find("X")
if index1 == 0:
f_list['x1'].append(1) if p == 'l' \
else f_list['x1'].append(-1)
elif index1 == 1 and s[0] == '-':
f_list['x1'].append(-1) if p == 'l' \
else f_list['x1'].append(1)
elif index1 > 0:
num = float(s[:index - 1])
f_list['x1'].append(num) if p == 'l' \
else f_list['x1'].append(-num)
elif s:
num = float(s)
f_list['x0'].append(num) if p == 'l' \
else f_list['x0'].append(-num)
def argv_parser(arg_str):
"""
Parse the input string of an equation.
Create a dictionary of equation coefficients for printing the full form,
Then returns a dictionary with coefficients for calculations.
formula = {"x0": 0, "x1": 0, "x2": 0, "x3": 0}
"""
f_list = {"x0": [], "x1": [], "x2": [], "x3": []}
sides_equation = arg_str.split('=')
left_side = split_equation(sides_equation[0])
right_side = split_equation(sides_equation[1])
parse_sides(f_list, left_side, 'l')
parse_sides(f_list, right_side, 'r')
print_full_form(f_list)
return {key: sum(values) for key, values in f_list.items()}