Nhận số
Bài học 18 trên 29 trong khóa học Dự án máy tính bằng Python của Coddy.
Bây giờ, chúng ta muốn phân tích chuỗi thành dạng danh sách để eval có thể nhận làm đầu vào.
Ví dụ, 32 +12* 4 cần được phân tích thành ['+', 32, ['*', 12, 4]]
Hãy bắt đầu với hàm hỗ trợ, hàm này sẽ giúp chúng ta trong hàm phân tích chính.
Thử thách
DễTạo hàm get_next nhận chuỗi không có khoảng trắng và một số nguyên là chỉ số bắt đầu trong chuỗi, rồi trả về số tiếp theo hoặc toán tử.
Lần này chỉ xử lý các số.
Ví dụ:
get_next('32+12*4', 0)->32get_next('1.2*3.54', 4)->3.54get_next('3/56-2', 3)->6
Bạn có thể giả định chỉ số bắt đầu nằm ở một số.
Lưu ý: có hai kiểu số, int hoặc float.
Nhớ trả về một số có kiểu int hoặc float, không phải str!
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, '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 lstTất cả bài học trong Dự án máy tính bằng Python
5Phân tích cú pháp
Nhận sốTự luyện tập: Trình biên dịch Python online