קבלת מספר
שיעור 18 מתוך 29 בקורס פרויקט מחשבון באמצעות Python של Coddy.
כעת נרצה לנתח מחרוזת לייצוג של רשימה ש-eval יוכל לקבל כקלט.
לדוגמה, יש לנתח את 32 +12* 4 ל-['+', 32, ['*', 12, 4]]
נתחיל בפונקציית עזר שתעזור לנו בפונקציית הניתוח הראשית.
אתגר
קלצרו פונקציה get_next שמקבלת מחרוזת ללא רווחים ומספר, את אינדקס ההתחלה במחרוזת, ומחזירה את המספר או האופרטור הבאים.
הפעם יש לטפל רק במספרים.
דוגמאות:
get_next('32+12*4', 0)->32get_next('1.2*3.54', 4)->3.54get_next('3/56-2', 3)->6
אפשר להניח שאינדקס ההתחלה מצביע על מספר.
הערה: יש שני סוגים של מספרים, int או float.
הקפידו להחזיר מספר מטיפוס int או float, ולא מטיפוס str!
נסו בעצמכם
def calc(op, n1, n2=None):
if not isinstance(n1, int) and not isinstance(n1, float):
raise Exception('Invalid number "' + str(n1) + '"')
if n2 is None:
if op == '+' or op == 'add':
return n1
if op == '-' or op == 'sub':
return -n1
raise Exception('Invalid operator "' + op + '"')
if not isinstance(n2, int) and not isinstance(n2, float):
raise Exception('Invalid number "' + str(n2) + '"')
if op == '+' or op == 'add':
return n1 + n2
if op == '-' or op == 'sub':
return n1 - n2
if op == '*' or op == 'mul':
return n1 * n2
if op == '/' or op == 'div':
if n2 == 0:
raise Exception("Division by zero")
return n1 / n2
if op == '%' or op == 'mod':
if n2 == 0:
raise Exception("Division by zero")
return n1 % n2
if op == '^' or op == 'pow':
return n1 ** n2
raise Exception('Invalid operator "' + op + '"')
def eval(lst):
if not isinstance(lst, list):
raise Exception('Failed to evaluate "' + str(lst) + '"')
if len(lst) == 2:
op = lst[0]
n = lst[1]
if not isinstance(n, list):
return calc(op, n)
if isinstance(n, list):
n = eval(n)
return calc(op, n)
elif len(lst) == 3:
op = lst[0]
n1 = lst[1]
n2 = lst[2]
if not isinstance(n1, list) and not isinstance(n2, list):
return calc(op, n1, n2)
if isinstance(n1, list):
n1 = eval(n1)
if isinstance(n2, list):
n2 = eval(n2)
return calc(op, n1, n2)
else:
raise Exception('Failed to evaluate "' + str(lst) + '"')
LEVEL_TWO_OPERATORS = ['+', '-', 'add', 'sub']
LEVEL_ONE_OPERATORS = ['*', '/', '%', 'mul', 'div', 'mod']
FUNCTIONS_OPERATORS = ['^', 'pow']
def struct(lst):
if not isinstance(lst, list) or len(lst) <= 1:
raise Exception('Failed to structure "' + str(lst) + '"')
if len(lst) == 2:
return lst
lst_cpy = lst
operators_groups = [FUNCTIONS_OPERATORS, LEVEL_ONE_OPERATORS, LEVEL_TWO_OPERATORS, 'all']
for operators_group in operators_groups:
i = 0
while i < len(lst):
if (not isinstance(lst[i], int) and not isinstance(lst[i], float) and not isinstance(lst[i], list)) if operators_group == 'all' else (lst[i] in operators_group):
if len(lst) - 1 == i:
raise Exception('Failed to structure "' + str(lst_cpy) + '"')
if len(lst) == 3:
return [lst[i], lst[i - 1], lst[i + 1]]
temp = lst[:i - 1]
temp.append([lst[i], lst[i - 1], lst[i + 1]])
temp += lst[i + 2:]
lst = temp
else:
i += 1
return lstכל השיעורים ביחידה פרויקט מחשבון באמצעות Python
תרגלו בעצמכם: קומפיילר Python אונליין