Menu
Coddy logo textTech

Pobieranie liczby

Lekcja 18 z 29 w kursie Projekt kalkulatora w Python w Coddy.

Teraz chcemy sparsować ciąg znaków do reprezentacji listy, którą eval może otrzymać jako dane wejściowe.

Na przykład 32 +12* 4 powinno zostać sparsowane do ['+', 32, ['*', 12, 4]]

Zacznijmy od funkcji pomocniczej, która pomoże nam w głównej funkcji parsującej.

challenge icon

Wyzwanie

Łatwy

Utwórz funkcję get_next, która otrzymuje ciąg znaków bez spacji i liczbę oznaczającą indeks początkowy w ciągu, a następnie zwraca następną liczbę lub operator.

Tym razem zajmij się tylko liczbami.

Przykłady:

  • get_next('32+12*4', 0)  ->  32
  • get_next('1.2*3.54', 4)  ->  3.54
  • get_next('3/56-2', 3)  ->  6

Możesz założyć, że indeks początkowy wskazuje liczbę.

Uwaga: istnieją dwa typy liczb: int i float.

Pamiętaj, aby zwrócić liczbę typu int lub float, a nie str!

Spróbuj swoich sił

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

Wszystkie lekcje w sekcji Projekt kalkulatora w Python

Poćwicz samodzielnie: Kompilator Python online