Menu
Coddy logo textTech

קבלת מספר

שיעור 18 מתוך 29 בקורס פרויקט מחשבון באמצעות Python של Coddy.

כעת נרצה לנתח מחרוזת לייצוג של רשימה ש-eval יוכל לקבל כקלט.

לדוגמה, יש לנתח את 32 +12* 4 ל-['+', 32, ['*', 12, 4]]

נתחיל בפונקציית עזר שתעזור לנו בפונקציית הניתוח הראשית.

challenge icon

אתגר

קל

צרו פונקציה get_next שמקבלת מחרוזת ללא רווחים ומספר, את אינדקס ההתחלה במחרוזת, ומחזירה את המספר או האופרטור הבאים.

הפעם יש לטפל רק במספרים.

דוגמאות:

  • get_next('32+12*4', 0)  ->  32
  • get_next('1.2*3.54', 4)  ->  3.54
  • get_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 אונליין