Menu
CoddyTech

Nhận toán tử

Bài học 19 trên 29 trong khóa học Dự án máy tính bằng Python của Coddy.

Giờ chúng ta cùng tìm hiểu về những thứ không phải là số: các toán tử.

challenge icon

Thử thách

Dễ

Thêm hỗ trợ cho get_next để tìm cả "operators", không chỉ số.

Ví dụ:

  • get_next('12+34',  2)  ->  '+'
  • get_next('42.2mul16+32', 4)  ->  'mul'
  • get_next('42.2mul16+32', 6)  ->  'l'
  • get_next('42.2mul16+32', 7)  ->  16

Nhớ kiểm tra xem bạn đọc được số hay toán tử.

Lưu ý: Đừng kiểm tra xem toán tử có phải là toán tử thực sự hay không, chúng ta đã kiểm tra điều này trong một hàm khác!

Tự làm thử

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]
    for operators_group in operators_groups:
        i = 0
        while i < len(lst):
            if 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


NUMBERS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
def get_next(s, i):
    res = ''
    is_float = False
    while i < len(s) and (s[i] in NUMBERS or s[i] == '.'):
        res += s[i]
        if s[i] == '.':
            is_float = True
        i += 1
    
    if is_float:
        return float(res)
    return int(res)

Tất cả bài học trong Dự án máy tính bằng Python

Tự luyện tập: Trình biên dịch Python online