2828
2929import re
3030
31+
3132def evaluate (expr : str ):
3233 """
3334 Evaluate an arithmetic/bitwise expression string and return result.
@@ -50,7 +51,7 @@ def evaluate(expr: str):
5051 """
5152
5253 # --- Tokenization ---
53- tokens = re .findall (r' \d+\.\d+|\d+|\*\*|<<|>>|[&|^+\-*/()]' , expr .replace (" " , "" ))
54+ tokens = re .findall (r" \d+\.\d+|\d+|\*\*|<<|>>|[&|^+\-*/()]" , expr .replace (" " , "" ))
5455
5556 # --- Handle unary minus (e.g., -5 + 3) and minus in starting ---
5657 if tokens and tokens [0 ] == "-" :
@@ -63,23 +64,23 @@ def solve_power(z):
6364 while "**" in z :
6465 i = z .index ("**" )
6566 z [i - 1 ] = float (z [i - 1 ]) ** float (z [i + 1 ])
66- z [i : i + 2 ] = [None , None ]
67+ z [i : i + 2 ] = [None , None ]
6768 z = clean (z )
6869 return z
6970
7071 def solve_div (z ):
7172 while "/" in z :
7273 i = z .index ("/" )
7374 z [i - 1 ] = float (z [i - 1 ]) / float (z [i + 1 ])
74- z [i : i + 2 ] = [None , None ]
75+ z [i : i + 2 ] = [None , None ]
7576 z = clean (z )
7677 return z
7778
7879 def solve_mul (z ):
7980 while "*" in z :
8081 i = z .index ("*" )
8182 z [i - 1 ] = float (z [i - 1 ]) * float (z [i + 1 ])
82- z [i : i + 2 ] = [None , None ]
83+ z [i : i + 2 ] = [None , None ]
8384 z = clean (z )
8485 return z
8586
@@ -94,64 +95,74 @@ def solve_add(z):
9495 while "+" in z :
9596 i = z .index ("+" )
9697 z [i - 1 ] = float (z [i - 1 ]) + float (z [i + 1 ])
97- z [i : i + 2 ] = [None , None ]
98+ z [i : i + 2 ] = [None , None ]
9899 z = clean (z )
99100 return z
100101
101102 def solve_lshift (z ):
102103 while "<<" in z :
103104 i = z .index ("<<" )
104105 z [i - 1 ] = int (float (z [i - 1 ])) << int (float (z [i + 1 ]))
105- z [i : i + 2 ] = [None , None ]
106+ z [i : i + 2 ] = [None , None ]
106107 z = clean (z )
107108 return z
108109
109110 def solve_rshift (z ):
110111 while ">>" in z :
111112 i = z .index (">>" )
112113 z [i - 1 ] = int (float (z [i - 1 ])) >> int (float (z [i + 1 ]))
113- z [i : i + 2 ] = [None , None ]
114+ z [i : i + 2 ] = [None , None ]
114115 z = clean (z )
115116 return z
116117
117118 def solve_and (z ):
118119 while "&" in z :
119120 i = z .index ("&" )
120121 z [i - 1 ] = int (float (z [i - 1 ])) & int (float (z [i + 1 ]))
121- z [i : i + 2 ] = [None , None ]
122+ z [i : i + 2 ] = [None , None ]
122123 z = clean (z )
123124 return z
124125
125126 def solve_xor (z ):
126127 while "^" in z :
127128 i = z .index ("^" )
128129 z [i - 1 ] = int (float (z [i - 1 ])) ^ int (float (z [i + 1 ]))
129- z [i : i + 2 ] = [None , None ]
130+ z [i : i + 2 ] = [None , None ]
130131 z = clean (z )
131132 return z
132133
133134 def solve_or (z ):
134135 while "|" in z :
135136 i = z .index ("|" )
136137 z [i - 1 ] = int (float (z [i - 1 ])) | int (float (z [i + 1 ]))
137- z [i : i + 2 ] = [None , None ]
138+ z [i : i + 2 ] = [None , None ]
138139 z = clean (z )
139140 return z
140141
141142 def solve_parentheses (z ):
142143 while "(" in z :
143144 close = z .index (")" )
144145 open_ = max (i for i , v in enumerate (z [:close ]) if v == "(" )
145- inner = z [open_ + 1 : close ]
146+ inner = z [open_ + 1 : close ]
146147 result = evaluate (" " .join (map (str , inner )))
147- z = z [:open_ ] + [str (result )] + z [close + 1 :]
148+ z = z [:open_ ] + [str (result )] + z [close + 1 :]
148149 return z
149150
150151 tokens = solve_parentheses (tokens )
151152
152153 # Precedence order
153- for func in [solve_power , solve_div , solve_mul , solve_minus , solve_add ,
154- solve_lshift , solve_rshift , solve_and , solve_xor , solve_or ]:
154+ for func in [
155+ solve_power ,
156+ solve_div ,
157+ solve_mul ,
158+ solve_minus ,
159+ solve_add ,
160+ solve_lshift ,
161+ solve_rshift ,
162+ solve_and ,
163+ solve_xor ,
164+ solve_or ,
165+ ]:
155166 tokens = func (tokens )
156167
157168 result = tokens [0 ]
@@ -168,8 +179,9 @@ def solve_parentheses(z):
168179 return int (f ) if f .is_integer () else f
169180 except ValueError :
170181 raise ValueError ("Invalid expression or unsupported syntax." )
171-
182+
172183
173184if __name__ == "__main__" :
174185 import doctest
186+
175187 doctest .testmod (verbose = True )
0 commit comments