From 82115c8dea39bffb69c012da1ed7a5a84c369ca0 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sat, 1 Jun 2019 14:17:33 +0300 Subject: [PATCH 01/29] Final Task Version 1 --- final_task/config.py | 50 ++ final_task/entry_point.py | 21 + final_task/py_calc.py | 340 +++++++++++ final_task/setup.py | 12 + .../unittest_process_unary_operations.py | 151 +++++ final_task/unittests/unittests_calc.py | 301 ++++++++++ .../unittests/unittests_parse_function.py | 538 ++++++++++++++++++ .../unittests/unittests_prevalidation.py | 97 ++++ .../unittests_sort_to_polish_function.py | 528 +++++++++++++++++ final_task/unittests/unittests_validation.py | 406 +++++++++++++ 10 files changed, 2444 insertions(+) create mode 100644 final_task/config.py create mode 100644 final_task/entry_point.py create mode 100644 final_task/py_calc.py create mode 100644 final_task/unittests/unittest_process_unary_operations.py create mode 100644 final_task/unittests/unittests_calc.py create mode 100644 final_task/unittests/unittests_parse_function.py create mode 100644 final_task/unittests/unittests_prevalidation.py create mode 100644 final_task/unittests/unittests_sort_to_polish_function.py create mode 100644 final_task/unittests/unittests_validation.py diff --git a/final_task/config.py b/final_task/config.py new file mode 100644 index 00000000..cfa0d5e4 --- /dev/null +++ b/final_task/config.py @@ -0,0 +1,50 @@ +import math +import operator +import string + +LETTERS = tuple(string.ascii_lowercase + string.ascii_uppercase) +DIGITS = tuple(string.digits) + +UNARY_OPERATORS = {'+': (1, operator.add), + '-': (1, operator.sub), + } + +BINARY_OPERATORS = {'*': (2, operator.mul), + '/': (2, operator.truediv), + '//': (2, operator.floordiv), + '%': (2, operator.imod), + '^': (3, operator.ipow), + '<': (0, operator.lt), + '<=': (0, operator.le), + '>': (0, operator.gt), + '>=': (0, operator.ge), + '==': (0, operator.eq), + '!=': (0, operator.ne), + } + +OPERATORS = UNARY_OPERATORS.copy() +OPERATORS.update(BINARY_OPERATORS) + +PARENTHESES = ('(', ')') + +OPERATORS_BEGIN = ('+', '-', '*', '/', '%', '^', '<', '>', '=', '!',) + +DOUBLE_OPER_PART1 = ('/', '<', '>', '=', '!',) +DOUBLE_OPER_PART2 = ('/', '=',) + +BUILT_IN_FUNCTIONS = ('abs', 'round') +NOT_SUPPORTED_MATH_FUNCTIONS = ('frexp', 'isclose', 'isinf', 'isfinite', 'isnan') +MATH_CONSTS = ('e', 'pi', 'inf', 'nan', 'tau') +MATH_FUNCTIONS = tuple([func for func in dir(math) if not func.startswith('_') and + func not in (MATH_CONSTS + NOT_SUPPORTED_MATH_FUNCTIONS)]) + +ALL_FUNCTIONS = BUILT_IN_FUNCTIONS + MATH_FUNCTIONS +ALL_FUNCTIONS_AND_CONSTS = ALL_FUNCTIONS + MATH_CONSTS + +ALL_FUNCTIONS_DICT = {el: (4,) for el in ALL_FUNCTIONS} +ALL_FUNCTIONS_AND_OPERATORS_DICT = ALL_FUNCTIONS_DICT.copy() +ALL_FUNCTIONS_AND_OPERATORS_DICT.update(OPERATORS) + + +DELIMETERS = ('.', ',', ' ') +ALLOWED_TOKENS = OPERATORS_BEGIN + LETTERS + DIGITS + PARENTHESES + DELIMETERS \ No newline at end of file diff --git a/final_task/entry_point.py b/final_task/entry_point.py new file mode 100644 index 00000000..1e410507 --- /dev/null +++ b/final_task/entry_point.py @@ -0,0 +1,21 @@ +import argparse +from sys import argv + +from py_calc import PyCalcProcessing + + +def create_parser(): + parser_ = argparse.ArgumentParser(prog='Py Calc', + description='Pure-python command-line calculator', + epilog='(c) Alina Laevskaya 2019.' + ) + + parser_.add_argument('EXPRESSION', type=str, help='String formula for processing.') + return parser_ + + +if __name__ == '__main__': + parser = create_parser() + namespace = parser.parse_args(argv[1:]) + py_calc_obj = PyCalcProcessing(namespace.EXPRESSION) + py_calc_obj.launch_processing() diff --git a/final_task/py_calc.py b/final_task/py_calc.py new file mode 100644 index 00000000..526f314a --- /dev/null +++ b/final_task/py_calc.py @@ -0,0 +1,340 @@ +# -*- coding: Windows-1251 -*- +import sys +import inspect + +from config import * + + +# т. к. ValueError пишет в лог traceback, переопределим функцию в sys, чтобы в лог писалось только сообщение +def excepthook(type, value, traceback): + print(value) + + +sys.excepthook = excepthook + + +class PyCalcProcessing(object): + + def __init__(self, formula_string): + self.formula_string = formula_string + + @staticmethod + def _matched_parentheses(el, count): + """ + Counter for '(', ')'. + + :param el (str): opening or closing parentheses + :param count (int): counter of parentheses + :return: count (int) + """ + if el == "(": + count += 1 + elif el == ")": + count -= 1 + return count + + @staticmethod + def pre_validate(formula_string): + """ + Need to apply pre-validation of some errors before parsing to tokens fo more convenient + parsing in current version of implementation. + + :param formula_string: input formula as text + :return: None + """ + # проверка, что формула не пустая строка + if not isinstance(formula_string, str) or not formula_string: + raise ValueError('Formula should be not empty string!') + # проверяем, что в формуле нет более одного разделителя подряд + # в текущей реализации удобнее сделать это здесь, чтобы упростить дальнейший парсинг на токены + if '..' in formula_string: + raise ValueError('Number can not contain more than one delimiter "." !') + # проверка на разрешённые элементы + for el in formula_string.strip(): + if el not in ALLOWED_TOKENS: + raise ValueError('Formula contains incorrect symbol "{}"'.format(el)) + + @staticmethod + def parse(formula_string): + number = '' # для накопления чисел + op = '' # для накопления операторов + function = '' # для накопления функций + for el in formula_string.strip(): + if el in LETTERS: # обработка функции + function += el.lower() + if op: # выстрелили оператор, если был накоплен + yield op + op = '' + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + number = '' + elif el in string.digits + '.': # обработка чисел целых и с точкой + if function: + function += el # продолжаем накапливать функцию, пока не встретим что-то отличное от цифры + else: + number += el + if op: # выстрелили оператор, если был накоплен + yield op + op = '' + if function: # выстрелили функцию, если было накоплено + yield function + function = '' + elif el in OPERATORS_BEGIN: # обработка операторов + if el in DOUBLE_OPER_PART1 and not op: # если возможен двойной оператор, добавили и ждём + op += el + elif el in DOUBLE_OPER_PART2 and op: # найден двойной + op += el + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + number = '' + if function: # выстрелили функцию, если было накоплено + yield function + function = '' + yield op # выстрелили оператор двойной, когда он был накоплен + op = '' + else: # если оператор одинарный + if op: # если был накоплен на предыдущем шаге - выстрелили, обнулили + yield op + op = '' + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + number = '' + if function: # выстрелили функцию, если было накоплено + yield function + function = '' + yield el # довыстрелили одинарный оператор + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + number = '' + if function: # выстрелили функцию, если было накоплено + yield function + function = '' + elif el in PARENTHESES + (',',): # обработка скобок и запятых (если функция с несколькими аргументами) + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + number = '' + if function: # выстрелили функцию, если было накоплено + yield function + function = '' + if op: # выстрелили оператор, если был накоплен + yield op + op = '' + yield el # выстрелили скобку или запятую, как только встретили + if function: # выстрелили функцию, если было накоплено + yield function + if number: # выстрелили число, если было накоплено + yield float(number) if number != '.' else '.' + if op: # выстрелили оператор, если было накоплено + yield op + + def validate_parsed_list(self, parsed_list): + if parsed_list[-1] in OPERATORS: + raise ValueError('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + if parsed_list[0] in BINARY_OPERATORS: + raise ValueError('Formula can not start with binary operator "{}"'.format(parsed_list[0])) + + counter = 0 # counter for parentheses + + previous_el = '' + for el in parsed_list: + counter = self._matched_parentheses(el, counter) + + message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) + + if el == '.': + raise ValueError('Single delimiter is prohibited in formula!') + + if isinstance(el, str) and el[0] in LETTERS: + if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: + raise ValueError('Function or constant {} is not supported by calculator'.format(el)) + + if previous_el == '(': + if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): + raise ValueError(message) + + if previous_el == ')': + if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): + raise ValueError(message) + + if previous_el == ',': + if el in (')', ',', '.'): + raise ValueError(message) + + if previous_el in UNARY_OPERATORS: + if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): + raise ValueError(message) + + if previous_el in BINARY_OPERATORS: + if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): + raise ValueError(message) + + if previous_el in ALL_FUNCTIONS: + if el != '(': + raise ValueError(message) + + if isinstance(previous_el, float) or previous_el in MATH_CONSTS: + if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): + raise ValueError(message) + + previous_el = el + + if counter != 0: + raise ValueError('Wrong number of opened or closed parentheses in formula!') + + return 'Formula was validated! Errors were not found.' + + @staticmethod + def process_unary_operations(validated_list): + """ + :param validated_list: list of tokens after parsing of input formula and validation of it + :return: processed_list: all unary '+' are removed, all redundant unary '-' are removed + """ + stack_str = '' + processed_list = [] + for el in validated_list: + if el in UNARY_OPERATORS: + stack_str += el + else: + is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or + not processed_list) + if stack_str: + if '-' in stack_str: + if stack_str.count('-') % 2 == 0: # считаем кол-во -, заменяя на + либо на - + if is_unary_plus: + stack_str = '' + else: + stack_str = '+' + else: + stack_str = '-' + else: + if is_unary_plus: + stack_str = '' + else: + stack_str = '+' + if stack_str: + processed_list.append(stack_str) + stack_str = '' + processed_list.append(el) + return processed_list + + @staticmethod + def sort_to_polish(parsed_formula): + stack = [] # в качестве стэка используем список + previous_token = '' + for token in parsed_formula: + # если элемент - оператор, то отправляем дальше все операторы из стека, + # чей приоритет больше или равен пришедшему, + # до открывающей скобки или опустошения стека. + if token in ALL_FUNCTIONS_AND_OPERATORS_DICT: + if token == '-' and previous_token in ('(', ',', '') + tuple(BINARY_OPERATORS.keys()): + yield 0.0 + stack.append(token) + else: + while (stack and stack[-1] != "(" and + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and + token != '^'): + yield stack.pop() + stack.append(token) + elif token == ")": + # если элемент - закрывающая скобка, выдаём все элементы из стека, до открывающей скобки, + # а открывающую скобку выкидываем из стека. + while stack: + x = stack.pop() + if x == "(": + break + yield x + elif token == "(": + # если элемент - открывающая скобка, просто положим её в стек + stack.append(token) + elif token == ",": # конец аргумента + # выдаём все операторы из стека до открывающей скобки + while stack and stack[-1] != "(": + yield stack.pop() + yield token + else: + # если элемент - число или константа, отправим его сразу на выход + yield token + previous_token = token + while stack: + yield stack.pop() + + # TODO gcd only integer input + # TODO ldexp float + integer input + # TODO 1 arg, 2 args, 4 args - seems is working + @staticmethod + def calc(polish_list): + stack = [] + + for token in polish_list: + if token in MATH_FUNCTIONS: + arguments = [] + func_name = getattr(math, token) + + # TODO пока костыль с log + if func_name != math.log: + number_of_args = len(inspect.getfullargspec(func_name).args) + for i in range(number_of_args): + if stack: + arguments.insert(0, stack.pop()) + else: + # т. к. log имеет переменное кол-во аргументов отдельная обработка + index_current_log_token = polish_list.index(token) + try: + next_token_after_log = polish_list[index_current_log_token + 1] + except IndexError: + next_token_after_log = '' + + if next_token_after_log in OPERATORS and len(stack) == 2: + arguments.insert(0, stack.pop()) + else: + if len(stack) >= 2: + arguments.insert(0, stack.pop()) + arguments.insert(0, stack.pop()) + else: + arguments.insert(0, stack.pop()) + + try: + function_result = func_name(*tuple(arguments)) + except TypeError: + raise ValueError('Formula contains incorrect number of arguments in function.') + + stack.append(function_result) # вычисляем оператор, возвращаем в стек + arguments = [] + + elif token in BUILT_IN_FUNCTIONS: + x = stack.pop() # забираем 1 числo из стека + # TODO how to get built-in attr automatically + if token == 'abs': + stack.append(abs(x)) + elif token == 'round': + stack.append(round(x)) + elif token in OPERATORS: # если приходящий элемент - оператор, + y, x = stack.pop(), stack.pop() # забираем 2 числа из стека + stack.append(OPERATORS[token][1](x, y)) # вычисляем оператор, возвращаем в стек + elif token in MATH_CONSTS: + stack.append(getattr(math, token)) + else: + stack.append(token) + + if len(stack) > 1: + raise ValueError('Formula contains incorrect number of arguments in function.') + + return stack[0] # результат вычисления - единственный элемент в стеке + + def launch_processing(self): + self.pre_validate(self.formula_string) + print('Prevalidation was done!') + parsed_list = [] + for el in self.parse(self.formula_string): + parsed_list.append(el) + print('Formula was parsed to tokens.') + print(self.validate_parsed_list(parsed_list)) + print('Validation was done!') + parsed_list = self.process_unary_operations(parsed_list) + print('Redundant unary operations were deleted!') + polish_list = [] + for el in self.sort_to_polish(parsed_list): + polish_list.append(el) + print('Tokens were sorted to polish list!') + result = self.calc(polish_list) + print('Result of calculating of {} is {}'.format(self.formula_string, result)) diff --git a/final_task/setup.py b/final_task/setup.py index e69de29b..03dbbedc 100644 --- a/final_task/setup.py +++ b/final_task/setup.py @@ -0,0 +1,12 @@ +from setuptools import setup + +setup( + name='py_calc', + version='1.0', + description='Pure-python command-line calculator.', + url='', + author='Layeuskaya Alina', + author_email='cool.girl.alina@mail.ru', + py_modules=['py_calc', 'config', 'entry_point'], + entry_points={'console_scripts': ['entry_point=entry_point:main', ], }, +) diff --git a/final_task/unittests/unittest_process_unary_operations.py b/final_task/unittests/unittest_process_unary_operations.py new file mode 100644 index 00000000..f2c9fa67 --- /dev/null +++ b/final_task/unittests/unittest_process_unary_operations.py @@ -0,0 +1,151 @@ +import unittest + +from py_calc import PyCalcProcessing + +calc_obj = PyCalcProcessing('1') + + +class TestProcessUnaryOperations(unittest.TestCase): + def test1(self): + list_ = calc_obj.process_unary_operations(['-', 13.0, ]) + self.assertEqual(list_, ['-', 13.0]) + + def test2(self): + list_ = calc_obj.process_unary_operations(['+', 13.0, ]) + self.assertEqual(list_, [13.0]) + + def test3(self): + list_ = calc_obj.process_unary_operations(['-', '-', 13.0, ]) + self.assertEqual(list_, [13.0]) + + def test4(self): + list_ = calc_obj.process_unary_operations(['-', '-', '-', 13.0, ]) + self.assertEqual(list_, ['-', 13.0]) + + def test5(self): + list_ = calc_obj.process_unary_operations(['-', '-', '-', '-', 13.0, ]) + self.assertEqual(list_, [13.0]) + + def test6(self): + list_ = calc_obj.process_unary_operations(['+', '-', '+', '+', 13.0, ]) + self.assertEqual(list_, ['-', 13.0]) + + def test7(self): + list_ = calc_obj.process_unary_operations(['-', '(', '-', 13.0, ')']) + self.assertEqual(list_, ['-', '(', '-', 13.0, ')']) + + def test8(self): + list_ = calc_obj.process_unary_operations(['-', '(', '-', '-', 13.0, ')']) + self.assertEqual(list_, ['-', '(', 13.0, ')']) + + def test9(self): + list_ = calc_obj.process_unary_operations(['+', '+', '+', '+', 13.0, ]) + self.assertEqual(list_, [13.0]) + + def test10(self): + list_ = calc_obj.process_unary_operations([1.0, '*', '-', '-', 13.0, ]) + self.assertEqual(list_, [1.0, '*', 13.0]) + + def test11(self): + list_ = calc_obj.process_unary_operations([1.0, '*', '-', 13.0, ]) + self.assertEqual(list_, [1.0, '*', '-', 13.0]) + + def test12(self): + list_ = calc_obj.process_unary_operations([1.0, '*', '+', 13.0, ]) + self.assertEqual(list_, [1.0, '*', 13.0]) + + def test13(self): + list_ = calc_obj.process_unary_operations([1.0, '*', '(', '+', 13.0, ')']) + self.assertEqual(list_, [1.0, '*', '(', 13.0, ')']) + + def test14(self): + list_ = calc_obj.process_unary_operations(['(', 1.0, '+', 13.0, ')']) + self.assertEqual(list_, ['(', 1.0, '+', 13.0, ')']) + + def test15(self): + list_ = calc_obj.process_unary_operations(['-', '-', '-', '-', '-', 1.0, '-', '+', '(', '-', 1.0, ')']) + self.assertEqual(list_, ['-', 1.0, '-', '(', '-', 1.0, ')']) + + def test16(self): + list_ = calc_obj.process_unary_operations(['-', '+', '-', '-', '-', '+', '-', 1.0]) + self.assertEqual(list_, ['-', 1.0]) + + def test17(self): + list_ = calc_obj.process_unary_operations(['-', '+', '-', '+', '-', '+', '-', '+', '-', '+', '-', 1.0]) + self.assertEqual(list_, [1.0]) + + def test18(self): + list_ = calc_obj.process_unary_operations(['-', '+', '(', '-', '-', '+', '-', 1.0, ')']) + self.assertEqual(list_, ['-', '(', '-', 1.0, ')']) + + def test19(self): + list_ = calc_obj.process_unary_operations(['+', '+', '-', '-', '+', '+', '-', '(', '-', 1.0, ')']) + self.assertEqual(list_, ['-', '(', '-', 1.0, ')']) + + def test20(self): + list_ = calc_obj.process_unary_operations([1, '-', '-', '-', 1.0]) + self.assertEqual(list_, [1.0, '-', 1.0]) + + def test21(self): + list_ = calc_obj.process_unary_operations([1.0, '-', '-', 1.0, '-', '-', 1.0]) + self.assertEqual(list_, [1.0, '+', 1.0, '+', 1.0]) + + def test22(self): + list_ = calc_obj.process_unary_operations([1.0, '-', '+', 1.0, '+', '-', 1.0]) + self.assertEqual(list_, [1.0, '-', 1.0, '-', 1.0]) + + def test23(self): + list_ = calc_obj.process_unary_operations(['+', '+', '+', '+', '+', 1.0]) + self.assertEqual(list_, [1.0]) + + def test24(self): + list_ = calc_obj.process_unary_operations(['-', '-', '-', '-', '-', 1.0]) + self.assertEqual(list_, ['-', 1.0]) + + def test25(self): + list_ = calc_obj.process_unary_operations(['+', '+', '(', '+', '(', '+', '+', 1.0, ')', ')']) + self.assertEqual(list_, ['(', '(', 1.0, ')', ')']) + + def test26(self): + list_ = calc_obj.process_unary_operations(['-', '(', '-', '+', '(', '-', '+', 1.0, ')', ')']) + self.assertEqual(list_, ['-', '(', '-', '(', '-', 1.0, ')', ')']) + + def test27(self): + list_ = calc_obj.process_unary_operations(['+', 1.0, ]) + self.assertEqual(list_, [1.0]) + + def test28(self): + list_ = calc_obj.process_unary_operations([6.0, '-', '(', '-', 13.0, ')']) + self.assertEqual(list_, [6.0, '-', '(', '-', 13.0, ')']) + + def test29(self): + list_ = calc_obj.process_unary_operations([1.0, '-', '-', '-', 1.0]) + self.assertEqual(list_, [1.0, '-', 1.0]) + + def test30(self): + list_ = calc_obj.process_unary_operations(['-', '+', '-', '-', '-', '+', '-', 1.0]) + self.assertEqual(list_, ['-', 1.0]) + + def test31(self): + list_ = calc_obj.process_unary_operations( + ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', + 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', + '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', 34.0, + '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', '-', 'cos', '(', 1.0, ')', '-', + '-', 'cos', '(', 0.0, ')', '^', 3.0, ')']) + self.assertEqual(list_, ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', + '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', '(', 43.0, ')', + ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', 34.0, '-', 2.0, '^', 2.0, ')', + ')', ')', ')', '+', 'cos', '(', 1.0, ')', '+', 'cos', '(', 0.0, ')', '^', 3.0, ')']) + + def test32(self): + list_ = calc_obj.process_unary_operations( + [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, + '-', 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', + 5.0]) + self.assertEqual(list_, [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', + 10.0, ')', '+', 'abs', '(', '-', 53.0, '/', 10.0, ')', '-', 5.0]) + + +if __name__ == '__main__': + unittest.main() diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py new file mode 100644 index 00000000..2bf82cac --- /dev/null +++ b/final_task/unittests/unittests_calc.py @@ -0,0 +1,301 @@ +# -*- coding: Windows-1251 -*- +import unittest +import math + +from py_calc import PyCalcProcessing + +calc_obj = PyCalcProcessing('1') + + +class TestCalcing(unittest.TestCase): + + # Unary operators + def test1(self): + self.assertEqual(-13.0, calc_obj.calc([0.0, 13.0, '-'])) + + def test2(self): + self.assertEqual(6.0 - (-13.0), calc_obj.calc([6.0, 0.0, 13.0, '-', '-'])) + + def test3(self): + self.assertEqual(1.0---1.0, calc_obj.calc([1.0, 1.0, '-'])) + + def test4(self): + self.assertEqual(-+---+-1.0, calc_obj.calc([0.0, 1.0, '-'])) + + def test5(self): + self.assertEqual(1.0 + 2.0 * 2.0, calc_obj.calc([1.0, 2.0, 2.0, '*', '+'])) + + def test6(self): + self.assertEqual(1.0 + (2.0 + 3.0 * 2.0) * 3.0, calc_obj.calc([1.0, 2.0, 3.0, 2.0, '*', '+', 3.0, '*', '+'])) + + def test7(self): + self.assertEqual(10.0 * (2.0 + 1.0), calc_obj.calc([10.0, 2.0, 1.0, '+', '*'])) + + def test8(self): + self.assertEqual(10.0 ** (2.0 + 1.0), calc_obj.calc([10.0, 2.0, 1.0, '+', '^'])) + + def test9(self): + self.assertEqual(100.0 / 3.0 ** 2.0, calc_obj.calc([100.0, 3.0, 2.0, '^', '/'])) + + def test10(self): + self.assertEqual(100.0 / 3.0 % 2.0 ** 2.0, calc_obj.calc([100.0, 3.0, '/', 2.0, 2.0, '^', '%'])) + + # Functions and constants + def test11(self): + self.assertEqual(math.pi + math.e, calc_obj.calc(['pi', 'e', '+'])) + + def test12(self): + self.assertEqual(math.log(math.e), calc_obj.calc(['e', 'log'])) + + def test13(self): + self.assertEqual(math.sin(math.pi / 2.0), calc_obj.calc(['pi', 2.0, '/', 'sin'])) + + def test14(self): + self.assertEqual(math.log10(100.0), calc_obj.calc([100.0, 'log10'])) + + def test15(self): + self.assertEqual(math.sin(math.pi / 2.0) * 111 * 6, calc_obj.calc(['pi', 2.0, '/', 'sin', 111.0, '*', 6.0, '*'])) + + def test16(self): + self.assertEqual(2.0 * math.sin(math.pi / 2.0), calc_obj.calc([2.0, 'pi', 2.0, '/', 'sin', '*'])) + + def test17(self): + self.assertEqual(abs(-5.0), calc_obj.calc([0.0, 5.0, '-', 'abs'])) + + def test18(self): + self.assertEqual(round(123.456789), calc_obj.calc([123.456789, 'round'])) + + # Associative + def test19(self): + self.assertEqual(102.0 % 12.0 % 7.0, calc_obj.calc([102.0, 12.0, '%', 7.0, '%'])) + + def test20(self): + self.assertEqual(100.0 / 4.0 / 3.0, calc_obj.calc([100.0, 4.0, '/', 3.0, '/'])) + + def test21(self): + self.assertEqual(2.0 ** 3.0 ** 4.0, calc_obj.calc([2.0, 3.0, 4.0, '^', '^'])) + + # Comparison operators + def test22(self): + self.assertEqual(1.0 + 2.0 * 3.0 == 1.0 + 2.0 * 3.0, calc_obj.calc([1.0, 2.0, 3.0, '*', '+', + 1.0, 2.0, 3.0, '*', '+', '=='])) + + def test23(self): + self.assertEqual(math.e ** 5.0 >= math.e ** 5.0 + 1.0, calc_obj.calc(['e', 5.0, '^', 'e', 5.0, '^', 1.0, '+', '>='])) + + def test24(self): + self.assertEqual(1.0 + 2.0 * 4.0 / 3.0 + 1.0 != 1.0 + 2.0 * 4.0 / 3.0 + 2.0, + calc_obj.calc([1.0, 2.0, 4.0, '*', 3.0, '/', '+', 1.0, '+', 1.0, 2.0, 4.0, '*', + 3.0, '/', '+', 2.0, '+', '!='])) + + # Common tests + def test25(self): + self.assertEqual((100.0), calc_obj.calc([100.0])) + + def test26(self): + self.assertEqual(666.0, calc_obj.calc([666.0])) + + def test27(self): + self.assertEqual(-.1, calc_obj.calc([0.0, 0.1, '-'])) + + def test28(self): + self.assertEqual(1.0 / 3.0, calc_obj.calc([1.0, 3.0, '/'])) + + def test29(self): + self.assertEqual(1.0 / 3.0, calc_obj.calc([1.0, 3.0, '/'])) + + def test30(self): + self.assertEqual(.1*2.0**56.0, calc_obj.calc([0.1, 2.0, 56.0, '^', '*'])) + + def test31(self): + self.assertEqual(math.e ** 34.0, calc_obj.calc(['e', 34.0, '^'])) + + def test32(self): + self.assertEqual((2.0 ** (math.pi/math.pi+math.e/math.e+2.0**0.0)), calc_obj.calc([2.0, 'pi', 'pi', '/', 'e', 'e', '/', + '+', 2.0, 0.0, '^', '+', '^'])) + + def test33(self): + self.assertEqual((2.0**(math.pi/math.pi+math.e/math.e+2.0**0.0))**(1.0/3.0), calc_obj.calc( + [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^', 1.0, 3.0, '/', '^'])) + + def test34(self): + self.assertEqual(math.sin(math.pi/2.0**1.0) + math.log(1*4+2**2+1, 3**2), calc_obj.calc(['pi', 2.0, 1.0, '^', '/', 'sin', + 1.0, 4.0, '*', 2.0, 2.0, '^', '+', + 1.0, '+', 3.0, 2.0, '^', + 'log', '+'])) + + def test35(self): + self.assertEqual(10.0*math.e**0.0*math.log10(.4 -5.0/ -0.1-10.0) - -abs(-53.0/10.0) + -5.0, + calc_obj.calc([10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, '-', 'log10', '*', + 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-'])) + + def test36(self): + self.assertEqual(math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos + (math.log10(43.0))))+math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)-- + math.cos(0.0)**3.0), calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', + 43.0, 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', + '-', 'sin', 'sin', 'cos', '+', 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, + '^', 'cos', '+', 'sin'])) + + def test37(self): + self.assertEqual(2.0**(2.0**2.0*2.0**2.0), calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^'])) + + def test38(self): + self.assertEqual(math.sin(math.e**math.log(math.e**math.e**math.sin(23.0), 45.0) + + math.cos(3.0+math.log10(math.e**-math.e))), + calc_obj.calc(['e', 'e', 'e', 23.0, 'sin', '^', '^', 45.0, 'log', '^', 3.0, 'e', 0.0, 'e', '-', + '^', 'log10', '+', 'cos', '+', 'sin'])) + + # Self-made cases + def test52(self): + self.assertEqual(100.0/3.0, calc_obj.calc([100.0, 3.0, '/'])) + + def test54(self): + self.assertEqual(100.0+3.0, calc_obj.calc([100.0, 3.0, '+'])) + + def test55(self): + self.assertEqual(100.0//3.0, calc_obj.calc([100.0, 3.0, '//'])) + + def test56(self): + self.assertEqual(math.sin(math.sin(1.0)), calc_obj.calc([1.0, 'sin', 'sin'])) + + def test57(self): + self.assertEqual(math.sin(math.sin(1.0))+1.0+math.sin(1.0), + calc_obj.calc([1.0, 'sin', 'sin', 1.0, '+', 1.0, 'sin', '+'])) + + def test58(self): + self.assertEqual(abs(-3.0), calc_obj.calc([0.0, 3.0, '-', 'abs'])) + + def test59(self): + self.assertEqual(round(3.56393), calc_obj.calc([3.56393, 'round'])) + + def test60(self): + self.assertEqual(abs(-round(3.56393)), calc_obj.calc([0.0, 3.56393, 'round', '-', 'abs'])) + + # logarithms + def test61(self): + self.assertEqual(math.log(8.0, 2.0), calc_obj.calc([8.0, 2.0, 'log'])) + + def test62(self): + self.assertEqual(math.log(2.7), calc_obj.calc([2.7, 'log'])) + + def test63(self): + self.assertEqual((math.log(8.0, 2.0)-1.0)-2.0, calc_obj.calc([8.0, 2.0, 'log', 1.0, '-', 2.0, '-'])) + + def test64(self): + self.assertEqual(-math.log(8.0, 2.0), calc_obj.calc([0.0, 8.0, 2.0, 'log', '-'])) + + def test65(self): + self.assertEqual(math.log(8.0, 2.0)-1.0, calc_obj.calc([8.0, 2.0, 'log', 1.0, '-'])) + + def test66(self): + self.assertEqual(math.log(8.0, 2.0)*math.log(16.0, 2.0), + calc_obj.calc([8.0, 2.0, 'log', 16.0, 2.0, 'log', '*'])) + + def test67(self): + self.assertEqual(math.sin(math.log(8.0, 2.0)*math.log(16.0, 2.0)), + calc_obj.calc([8.0, 2.0, 'log', 16.0, 2.0, 'log', '*', 'sin'])) + + def test68(self): + self.assertEqual(math.log(8.0+20.0-1.0, 2.0+1.0), calc_obj.calc([8.0, 20.0, '+', 1.0, '-', 2.0, 1.0, '+', 'log'])) + + def test69(self): + self.assertEqual(math.log10(100.0), calc_obj.calc([100.0, 'log10'])) + + def test70(self): + self.assertEqual(math.log(100.0, 10.0), calc_obj.calc([100.0, 10.0, 'log'])) + + def test71(self): + self.assertEqual((math.log10(100.0)-1.0)-2.0, calc_obj.calc([100.0, 'log10', 1.0, '-', 2.0, '-'])) + + def test72(self): + self.assertEqual(-math.log10(100.0), calc_obj.calc([0.0, 100.0, 'log10', '-'])) + + def test73(self): + self.assertEqual(math.log10(100.0)-1.0, calc_obj.calc([100.0, 'log10', 1.0, '-'])) + + def test74(self): + self.assertEqual(math.log10(100.0)*math.log10(1000.0), calc_obj.calc([100.0, 'log10', 1000.0, 'log10', '*'])) + + def test75(self): + self.assertEqual(math.sin(math.log10(100.0)*math.log10(1000.0)), + calc_obj.calc([100.0, 'log10', 1000.0, 'log10', '*', 'sin'])) + + def test76(self): + self.assertEqual(math.log10(800.0/2.0/4.0), calc_obj.calc([800.0, 2.0, '/', 4.0, '/', 'log10'])) + + # pow + def test77(self): + self.assertEqual(math.pow(2.0, 4.0), calc_obj.calc([2.0, 4.0, 'pow'])) + + def test78(self): + self.assertEqual(math.log(math.pow(10.0, 2.0), 10), calc_obj.calc([10.0, 2.0, 'pow', 10.0, 'log'])) + + def test79(self): + self.assertEqual((math.pow(2.0, 4.0)-1.0)-2.0, calc_obj.calc([2.0, 4.0, 'pow', 1.0, '-', 2.0, '-'])) + + def test80(self): + self.assertEqual(-math.pow(2.0, 4.0), calc_obj.calc([0.0, 2.0, 4.0, 'pow', '-'])) + + def test81(self): + self.assertEqual(math.pow(2.0, 4.0)-1.0, calc_obj.calc([2.0, 4.0, 'pow', 1.0, '-'])) + + def test82(self): + self.assertEqual(math.pow(2.0, 4.0)*math.pow(2.0, 3.0), calc_obj.calc([2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*'])) + + def test83(self): + self.assertEqual(math.sin(math.pow(2.0, 4.0)*math.pow(2.0, 3.0)), calc_obj.calc([2.0, 4.0, 'pow', 2.0, 3.0, + 'pow', '*', 'sin'])) + + def test84(self): + self.assertEqual(math.pow(2.0**(2.0**2.0*2.0**2.0), math.log10(100.0)*math.log10(1000.0)), + calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', 100.0, 'log10', 1000.0, 'log10', '*', + 'pow'])) + + def test85(self): + self.assertEqual(13.0, calc_obj.calc([13.0])) + + def test86(self): + self.assertEqual(-(-13.0), calc_obj.calc([0.0, 0.0, 13.0, '-', '-'])) + + def test87(self): + self.assertEqual(-(13.0), calc_obj.calc([0.0, 13.0, '-'])) + + def test88(self): + self.assertEqual(1.0*-13.0, calc_obj.calc([1.0, 0.0, 13.0, '-', '*'])) + + def test89(self): + self.assertEqual(1.0*(-13.0), calc_obj.calc([1.0, 0.0, 13.0, '-', '*'])) + + def test90(self): + self.assertEqual(1.0*(13.0), calc_obj.calc([1.0, 13.0, '*'])) + + def test91(self): + self.assertEqual((1.0+13.0), calc_obj.calc([1.0, 13.0, '+'])) + + def test92(self): + self.assertEqual(-1.0-(-1.0), calc_obj.calc([0.0, 1.0, '-', 0.0, 1.0, '-', '-'])) + + def test93(self): + self.assertEqual(((1.0)), calc_obj.calc([1.0])) + + def test94(self): + self.assertEqual(-(-(-1.0)), calc_obj.calc([0.0, 0.0, 0.0, 1.0, '-', '-', '-'])) + + +class TestCalcNegativeCases(unittest.TestCase): + def test1(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 'sin'])) + + def test2(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'sin'])) + + def test3(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 'pow'])) + + def test4(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'pow'])) + + +if __name__ == '__main__': + unittest.main() diff --git a/final_task/unittests/unittests_parse_function.py b/final_task/unittests/unittests_parse_function.py new file mode 100644 index 00000000..12ad5c2f --- /dev/null +++ b/final_task/unittests/unittests_parse_function.py @@ -0,0 +1,538 @@ +import unittest + +from py_calc import PyCalcProcessing + + +calc_obj = PyCalcProcessing('1') + + +class TestParsingPositiveCases(unittest.TestCase): + + # Unary operators + def test1(self): + list_ = [] + for el in calc_obj.parse('-13'): + list_.append(el) + self.assertEqual(list_, ['-', 13.0]) + + def test2(self): + list_ = [] + for el in calc_obj.parse('6-(-13)'): + list_.append(el) + self.assertEqual(list_, [6.0, '-', '(', '-', 13.0, ')']) + + def test3(self): + list_ = [] + for el in calc_obj.parse('1---1'): + list_.append(el) + self.assertEqual(list_, [1.0, '-', '-', '-', 1.0]) + + def test4(self): + list_ = [] + for el in calc_obj.parse('-+---+-1'): + list_.append(el) + self.assertEqual(list_, ['-', '+', '-', '-', '-', '+', '-', 1.0]) + + # Operation priority + def test5(self): + list_ = [] + for el in calc_obj.parse('1+2*2'): + list_.append(el) + self.assertEqual(list_, [1.0, '+', 2.0, '*', 2.0]) + + def test6(self): + list_ = [] + for el in calc_obj.parse('1+(2+3*2)*3'): + list_.append(el) + self.assertEqual(list_, [1.0, '+', '(', 2.0, '+', 3.0, '*', 2.0, ')', '*', 3.0]) + + def test7(self): + list_ = [] + for el in calc_obj.parse('10*(2+1)'): + list_.append(el) + self.assertEqual(list_, [10.0, '*', '(', 2.0, '+', 1.0, ')']) + + def test8(self): + list_ = [] + for el in calc_obj.parse('10^(2+1)'): + list_.append(el) + self.assertEqual(list_, [10.0, '^', '(', 2.0, '+', 1.0, ')']) + + def test9(self): + list_ = [] + for el in calc_obj.parse('100/3^2'): + list_.append(el) + self.assertEqual(list_, [100.0, '/', 3.0, '^', 2.0]) + + def test10(self): + list_ = [] + for el in calc_obj.parse('100/3%2^2'): + list_.append(el) + self.assertEqual(list_, [100.0, '/', 3.0, '%', 2.0, '^', 2.0]) + + # Functions and constants + def test11(self): + list_ = [] + for el in calc_obj.parse('pi+e'): + list_.append(el) + self.assertEqual(list_, ['pi', '+', 'e']) + + def test12(self): + list_ = [] + for el in calc_obj.parse('log(e)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 'e', ')']) + + def test13(self): + list_ = [] + for el in calc_obj.parse('sin(pi/2)'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'pi', '/', 2.0, ')']) + + def test14(self): + list_ = [] + for el in calc_obj.parse('log10(100)'): + list_.append(el) + self.assertEqual(list_, ['log10', '(', 100.0, ')']) + + def test15(self): + list_ = [] + for el in calc_obj.parse('sin(pi/2)*111*6'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0]) + + def test16(self): + list_ = [] + for el in calc_obj.parse('2*sin(pi/2)'): + list_.append(el) + self.assertEqual(list_, [2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')']) + + def test17(self): + list_ = [] + for el in calc_obj.parse('abs(-5)'): + list_.append(el) + self.assertEqual(list_, ['abs', '(', '-', 5.0, ')']) + + def test18(self): + list_ = [] + for el in calc_obj.parse('round(123.456789)'): + list_.append(el) + self.assertEqual(list_, ['round', '(', 123.456789, ')']) + + # Associative + def test19(self): + list_ = [] + for el in calc_obj.parse('102%12%7'): + list_.append(el) + self.assertEqual(list_, [102.0, '%', 12.0, '%', 7.0]) + + def test20(self): + list_ = [] + for el in calc_obj.parse('100/4/3'): + list_.append(el) + self.assertEqual(list_, [100.0, '/', 4.0, '/', 3.0]) + + def test21(self): + list_ = [] + for el in calc_obj.parse('2^3^4'): + list_.append(el) + self.assertEqual(list_, [2.0, '^', 3.0, '^', 4.0]) + + # Comparison operators + def test22(self): + list_ = [] + for el in calc_obj.parse('1+2*3==1+2*3'): + list_.append(el) + self.assertEqual(list_, [1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0]) + + def test23(self): + list_ = [] + for el in calc_obj.parse('e^5>=e^5+1'): + list_.append(el) + self.assertEqual(list_, ['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0]) + + def test24(self): + list_ = [] + for el in calc_obj.parse('1+2*4/3+1!=1+2*4/3+2'): + list_.append(el) + self.assertEqual(list_, [1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, '+', + 2.0, '*', 4.0, '/', 3.0, '+', 2.0]) + + # Common tests + def test25(self): + list_ = [] + for el in calc_obj.parse('(100)'): + list_.append(el) + self.assertEqual(list_, ['(', 100.0, ')']) + + def test26(self): + list_ = [] + for el in calc_obj.parse('666'): + list_.append(el) + self.assertEqual(list_, [666.0]) + + def test27(self): + list_ = [] + for el in calc_obj.parse('-.1'): + list_.append(el) + self.assertEqual(list_, ['-', 0.1]) + + def test28(self): + list_ = [] + for el in calc_obj.parse('1/3'): + list_.append(el) + self.assertEqual(list_, [1.0, '/', 3.0]) + + def test29(self): + list_ = [] + for el in calc_obj.parse('1.0/3.0'): + list_.append(el) + self.assertEqual(list_, [1.0, '/', 3.0]) + + def test30(self): + list_ = [] + for el in calc_obj.parse('.1 * 2.0^56.0'): + list_.append(el) + self.assertEqual(list_, [0.1, '*', 2.0, '^', 56.0]) + + def test31(self): + list_ = [] + for el in calc_obj.parse('e^34'): + list_.append(el) + self.assertEqual(list_, ['e', '^', 34.0]) + + def test32(self): + list_ = [] + for el in calc_obj.parse('(2.0^(pi/pi+e/e+2.0^0.0))'): + list_.append(el) + self.assertEqual(list_, ['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')']) + + def test33(self): + list_ = [] + for el in calc_obj.parse('(2.0^(pi/pi+e/e+2.0^0.0))^(1.0/3.0)'): + list_.append(el) + self.assertEqual(list_, ['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, + ')', ')', '^', '(', 1.0, '/', 3.0, ')']) + + # def test34(self): # how to process comma in log + # list_ = [] + # for el in calc_obj.parse('sin(pi/2^1) + log(1*4+2^2+1, 3^2)'): + # list_.append(el) + # self.assertEqual(list_, ['sin', '(', 'pi', '/', 2.0, '^', 1.0, ')', '+', 'log', '(', 1.0, '*', 4.0, '+', + # 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']) + + def test35(self): # why there are no parentheses after division in log + list_ = [] + for el in calc_obj.parse('10*e^0*log10(.4 -5/ -0.1-10) - -abs(-53/10) + -5'): + list_.append(el) + self.assertEqual(list_, [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', + 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', 5.0]) + + def test36(self): + list_ = [] + for el in calc_obj.parse('sin(-cos(-sin(3.0)-cos(-sin(-3.0*5.0)-sin(cos(log10(43.0))))+' + 'cos(sin(sin(34.0-2.0^2.0))))--cos(1.0)--cos(0.0)^3.0)'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', + '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', + 'log10', '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', + 34.0, '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', '-', 'cos', '(', 1.0, ')', '-', '-', + 'cos', '(', 0.0, ')', '^', 3.0, ')']) + + def test37(self): + list_ = [] + for el in calc_obj.parse('2.0^(2.0^2.0*2.0^2.0)'): + list_.append(el) + self.assertEqual(list_, [2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')']) + + def test38(self): + list_ = [] + for el in calc_obj.parse('sin(e^log(e^e^sin(23.0),45.0) + cos(3.0+log10(e^-e)))'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', ',', + 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')']) + + # Error cases + def test39(self): + list_ = [] + for el in calc_obj.parse(''): + list_.append(el) + self.assertEqual(list_, []) + + def test40(self): + list_ = [] + for el in calc_obj.parse('+'): + list_.append(el) + self.assertEqual(list_, ['+']) + + def test41(self): + list_ = [] + for el in calc_obj.parse('1-'): + list_.append(el) + self.assertEqual(list_, [1.0, '-']) + + def test42(self): + list_ = [] + for el in calc_obj.parse('ee'): + list_.append(el) + self.assertEqual(list_, ['ee']) + + def test43(self): + list_ = [] + for el in calc_obj.parse('==7'): + list_.append(el) + self.assertEqual(list_, ['==', 7.0]) + + def test44(self): + list_ = [] + for el in calc_obj.parse('1 + 2(3 * 4))'): + list_.append(el) + self.assertEqual(list_, [1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')']) + + def test45(self): + list_ = [] + for el in calc_obj.parse('((1+2)'): + list_.append(el) + self.assertEqual(list_, ['(', '(', 1.0, '+', 2.0, ')']) + + def test46(self): + list_ = [] + for el in calc_obj.parse('log100(100)'): + list_.append(el) + self.assertEqual(list_, ['log100', '(', 100.0, ')']) + + def test47(self): + list_ = [] + for el in calc_obj.parse('------'): + list_.append(el) + self.assertEqual(list_, ['-', '-', '-', '-', '-', '-']) + + def test48(self): + list_ = [] + for el in calc_obj.parse('6 * * 6'): + list_.append(el) + self.assertEqual(list_, [6.0, '*', '*', 6.0]) + + def test49(self): + list_ = [] + for el in calc_obj.parse('((((('): + list_.append(el) + self.assertEqual(list_, ['(', '(', '(', '(', '(', ]) + + def test50(self): # how to process commas in pow + list_ = [] + for el in calc_obj.parse('pow(2, 3, 4)'): + list_.append(el) + self.assertEqual(list_, ['pow', '(', 2.0, ',', 3.0, ',', 4.0, ')']) + + # Self-made cases + def test51(self): + list_ = [] + for el in calc_obj.parse('77====77'): + list_.append(el) + self.assertEqual(list_, [77.0, '==', '==', 77.0]) + + def test52(self): + list_ = [] + for el in calc_obj.parse('100/3'): + list_.append(el) + self.assertEqual(list_, [100.0, '/', 3.0]) + + def test53(self): + list_ = [] + for el in calc_obj.parse('100=3'): + list_.append(el) + self.assertEqual(list_, [100.0, '=', 3.0]) + + def test54(self): + list_ = [] + for el in calc_obj.parse('100+3'): + list_.append(el) + self.assertEqual(list_, [100.0, '+', 3.0]) + + def test55(self): + list_ = [] + for el in calc_obj.parse('100//3'): + list_.append(el) + self.assertEqual(list_, [100.0, '//', 3.0]) + + def test56(self): + list_ = [] + for el in calc_obj.parse('sin(sin(1))'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'sin', '(', 1.0, ')', ')']) + + def test57(self): + list_ = [] + for el in calc_obj.parse('sin(sin(1))+1+sin(1)'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'sin', '(', 1.0, ')', ')', '+', 1.0, '+', 'sin', '(', 1.0, ')']) + + def test58(self): + list_ = [] + for el in calc_obj.parse('log100l(100)'): + list_.append(el) + self.assertEqual(list_, ['log100l', '(', 100.0, ')']) + + def test59(self): + list_ = [] + for el in calc_obj.parse('log100+(100)'): + list_.append(el) + self.assertEqual(list_, ['log100', '+', '(', 100.0, ')']) + + def test60(self): + list_ = [] + for el in calc_obj.parse('.+1'): + list_.append(el) + self.assertEqual(list_, ['.', '+', 1.0, ]) + + # logarithms + def test61(self): + list_ = [] + for el in calc_obj.parse('log(8,2)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 8.0, ',', 2.0, ')']) + + def test62(self): + list_ = [] + for el in calc_obj.parse('log(2.7)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 2.7, ')']) + + def test63(self): + list_ = [] + for el in calc_obj.parse('(log(8,2)-1)-2'): + list_.append(el) + self.assertEqual(list_, ['(', 'log', '(', 8.0, ',', 2.0, ')', '-', 1.0, ')', '-', 2.0]) + + def test64(self): + list_ = [] + for el in calc_obj.parse('-log(8,2)'): + list_.append(el) + self.assertEqual(list_, ['-', 'log', '(', 8.0, ',', 2.0, ')']) + + def test65(self): + list_ = [] + for el in calc_obj.parse('log(8,2)-1'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 8.0, ',', 2.0, ')', '-', 1.0]) + + def test66(self): + list_ = [] + for el in calc_obj.parse('log(8,2)*log(16,2)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, ')']) + + def test67(self): + list_ = [] + for el in calc_obj.parse('sin(log(8,2)*log(16,2))'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, ')', ')']) + + def test68(self): + list_ = [] + for el in calc_obj.parse('log(8+20-1,2+1)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 8.0, '+', 20.0, '-', 1.0, ',', 2.0, '+', 1.0, ')']) + + def test69(self): + list_ = [] + for el in calc_obj.parse('log10(100)'): + list_.append(el) + self.assertEqual(list_, ['log10', '(', 100.0, ')']) + + def test70(self): + list_ = [] + for el in calc_obj.parse('log(100,10)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 100.0, ',', 10.0, ')']) + + def test71(self): + list_ = [] + for el in calc_obj.parse('(log10(100)-1)-2'): + list_.append(el) + self.assertEqual(list_, ['(', 'log10', '(', 100.0, ')', '-', 1.0, ')', '-', 2.0]) + + def test72(self): + list_ = [] + for el in calc_obj.parse('-log10(100)'): + list_.append(el) + self.assertEqual(list_, ['-', 'log10', '(', 100.0, ')']) + + def test73(self): + list_ = [] + for el in calc_obj.parse('log10(100)-1'): + list_.append(el) + self.assertEqual(list_, ['log10', '(', 100.0, ')', '-', 1.0]) + + def test74(self): + list_ = [] + for el in calc_obj.parse('log10(100)*log10(1000)'): + list_.append(el) + self.assertEqual(list_, ['log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')']) + + def test75(self): + list_ = [] + for el in calc_obj.parse('sin(log10(100)*log10(1000))'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')']) + + def test76(self): + list_ = [] + for el in calc_obj.parse('log10(800/2/4)'): + list_.append(el) + self.assertEqual(list_, ['log10', '(', 800.0, '/', 2.0, '/', 4.0, ')']) + + # pow + def test77(self): + list_ = [] + for el in calc_obj.parse('pow(2,4)'): + list_.append(el) + self.assertEqual(list_, ['pow', '(', 2.0, ',', 4.0, ')']) + + def test78(self): + list_ = [] + for el in calc_obj.parse('log(pow(10,2),10)'): + list_.append(el) + self.assertEqual(list_, ['log', '(', 'pow', '(', 10.0, ',', 2.0, ')', ',', 10.0, ')']) + + def test79(self): + list_ = [] + for el in calc_obj.parse('(pow(2,4)-1)-2'): + list_.append(el) + self.assertEqual(list_, ['(', 'pow', '(', 2.0, ',', 4.0, ')', '-', 1.0, ')', '-', 2.0]) + + def test80(self): + list_ = [] + for el in calc_obj.parse('-pow(2,4)'): + list_.append(el) + self.assertEqual(list_, ['-', 'pow', '(', 2.0, ',', 4.0, ')']) + + def test81(self): + list_ = [] + for el in calc_obj.parse('pow(2,4)-1'): + list_.append(el) + self.assertEqual(list_, ['pow', '(', 2.0, ',', 4.0, ')', '-', 1.0]) + + def test82(self): + list_ = [] + for el in calc_obj.parse('pow(2,4)*pow(2,3)'): + list_.append(el) + self.assertEqual(list_, ['pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')']) + + def test83(self): + list_ = [] + for el in calc_obj.parse('sin(pow(2,4)*pow(2,3))'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')', ')']) + + def test84(self): + list_ = [] + for el in calc_obj.parse('pow(2.0^(2.0^2.0*2.0^2.0),sin(log10(100)*log10(1000)))'): + list_.append(el) + self.assertEqual(list_, ['pow', '(', 2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')', ',', 'sin', '(', + 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')', ')']) + + +if __name__ == '__main__': + unittest.main() diff --git a/final_task/unittests/unittests_prevalidation.py b/final_task/unittests/unittests_prevalidation.py new file mode 100644 index 00000000..c726a10b --- /dev/null +++ b/final_task/unittests/unittests_prevalidation.py @@ -0,0 +1,97 @@ +import unittest + +from py_calc import PyCalcProcessing + + +calc_obj = PyCalcProcessing('1') + + +class TestParsingNegativeCases(unittest.TestCase): + def test1(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+&6.0')) + + def test86(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+6.0&')) + + def test87(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('_5+6')) + + def test88(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('5_+6')) + + def test89(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1>=@')) + + def test90(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1@>=9')) + + def test91(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('-2+(#+1)')) + + def test92(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('abs(@)')) + + def test93(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('round(@)')) + + def test94(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(5+@)')) + + def test95(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(@+5)')) + + def test96(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('(5+@)/7')) + + def test97(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+#+6')) + + def test98(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+#8+6')) + + # Number with more than one delimiter + def test99(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5')) + + def test100(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('-1..5')) + + def test101(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5+3..7')) + + def test102(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5+3')) + + def test103(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('3+1..5')) + + def test104(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+1..5-4')) + + def test105(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(1..5)')) + + def test106(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('(1..5+3)/2')) + + def test107(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('round(1..5)')) + + def test108(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('abs(-1..5)')) + + def test109(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1>=1..5')) + + def test110(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate('')) + + def test111(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate(None)) + + def test112(self): + self.assertRaises(ValueError, lambda: calc_obj.pre_validate(18)) + + +if __name__ == '__main__': + unittest.main() diff --git a/final_task/unittests/unittests_sort_to_polish_function.py b/final_task/unittests/unittests_sort_to_polish_function.py new file mode 100644 index 00000000..9187c2b6 --- /dev/null +++ b/final_task/unittests/unittests_sort_to_polish_function.py @@ -0,0 +1,528 @@ +import unittest + +from py_calc import PyCalcProcessing + +calc_obj = PyCalcProcessing('1') + + +class TestSorting(unittest.TestCase): + + # Unary operators + def test1(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 13.0]): + list_.append(el) + self.assertEqual(list_, [0.0, 13.0, '-']) + + def test2(self): + list_ = [] + for el in calc_obj.sort_to_polish([6.0, '-', '(', '-', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [6.0, 0.0, 13.0, '-', '-']) + + def test3(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '-', 1.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 1.0, '-']) + + def test4(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 1.0]): + list_.append(el) + self.assertEqual(list_, [0.0, 1.0, '-']) + + # Operation priority + def test5(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '+', 2.0, '*', 2.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 2.0, 2.0, '*', '+']) + + def test6(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '+', '(', 2.0, '+', 3.0, '*', 2.0, ')', '*', 3.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 2.0, 3.0, 2.0, '*', '+', 3.0, '*', '+']) + + def test7(self): + list_ = [] + for el in calc_obj.sort_to_polish([10.0, '*', '(', 2.0, '+', 1.0, ')']): + list_.append(el) + self.assertEqual(list_, [10.0, 2.0, 1.0, '+', '*']) + + def test8(self): + list_ = [] + for el in calc_obj.sort_to_polish([10.0, '^', '(', 2.0, '+', 1.0, ')']): + list_.append(el) + self.assertEqual(list_, [10.0, 2.0, 1.0, '+', '^']) + + def test9(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '/', 3.0, '^', 2.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 3.0, 2.0, '^', '/']) + + def test10(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '/', 3.0, '%', 2.0, '^', 2.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 3.0, '/', 2.0, 2.0, '^', '%']) + + # Functions and constants + def test11(self): + list_ = [] + for el in calc_obj.sort_to_polish(['pi', '+', 'e']): + list_.append(el) + self.assertEqual(list_, ['pi', 'e', '+']) + + def test12(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 'e', ')']): + list_.append(el) + self.assertEqual(list_, ['e', 'log']) + + def test13(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'pi', '/', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, ['pi', 2.0, '/', 'sin']) + + def test14(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log10', '(', 100.0, ')']): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10']) + + def test15(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0]): + list_.append(el) + self.assertEqual(list_, ['pi', 2.0, '/', 'sin', 111.0, '*', 6.0, '*']) + + def test16(self): + list_ = [] + for el in calc_obj.sort_to_polish([2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [2.0, 'pi', 2.0, '/', 'sin', '*']) + + def test17(self): + list_ = [] + for el in calc_obj.sort_to_polish(['abs', '(', '-', 5.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 5.0, '-', 'abs']) + + def test18(self): + list_ = [] + for el in calc_obj.sort_to_polish(['round', '(', 123.456789, ')']): + list_.append(el) + self.assertEqual(list_, [123.456789, 'round']) + + # Associative + def test19(self): + list_ = [] + for el in calc_obj.sort_to_polish([102.0, '%', 12.0, '%', 7.0]): + list_.append(el) + self.assertEqual(list_, [102.0, 12.0, '%', 7.0, '%']) + + def test20(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '/', 4.0, '/', 3.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 4.0, '/', 3.0, '/']) + + def test21(self): + list_ = [] + for el in calc_obj.sort_to_polish([2.0, '^', 3.0, '^', 4.0]): + list_.append(el) + self.assertEqual(list_, [2.0, 3.0, 4.0, '^', '^']) + + # Comparison operators + def test22(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 2.0, 3.0, '*', '+', 1.0, 2.0, 3.0, '*', '+', '==']) + + def test23(self): + list_ = [] + for el in calc_obj.sort_to_polish(['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0]): + list_.append(el) + self.assertEqual(list_, ['e', 5.0, '^', 'e', 5.0, '^', 1.0, '+', '>=']) + + def test24(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', + 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 2.0, 4.0, '*', 3.0, '/', '+', 1.0, '+', 1.0, + 2.0, 4.0, '*', 3.0, '/', '+', 2.0, '+', '!=']) + + # Common tests + def test25(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 100.0, ')']): + list_.append(el) + self.assertEqual(list_, [100.0]) + + def test26(self): + list_ = [] + for el in calc_obj.sort_to_polish([666.0]): + list_.append(el) + self.assertEqual(list_, [666.0]) + + def test27(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 0.1]): + list_.append(el) + self.assertEqual(list_, [0.0, 0.1, '-']) + + def test28(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '/', 3.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 3.0, '/']) + + def test29(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '/', 3.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 3.0, '/']) + + def test30(self): + list_ = [] + for el in calc_obj.sort_to_polish([0.1, '*', 2.0, '^', 56.0]): + list_.append(el) + self.assertEqual(list_, [0.1, 2.0, 56.0, '^', '*']) + + def test31(self): + list_ = [] + for el in calc_obj.sort_to_polish(['e', '^', 34.0]): + list_.append(el) + self.assertEqual(list_, ['e', 34.0, '^']) + + def test32(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', + '+', 2.0, '^', 0.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^']) + + def test33(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', + ')', '^', '(', 1.0, '/', 3.0, ')']): + list_.append(el) + self.assertEqual(list_, [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', + '^', 1.0, 3.0, '/', '^']) + + # TODO: fixed + def test34(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 1.0, '*', 4.0, '+', 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 4.0, '*', 2.0, 2.0, '^', '+', 1.0, '+', ',', 3.0, 2.0, '^', 'log']) + + # TODO: problem, when unary operations go after binary without parentheses as -5/ -0.1 + def test35(self): # 10*e^0*log10(.4 -5/ -0.1-10)+abs(-53/10)-5 + list_ = [] + for el in calc_obj.sort_to_polish([10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, + '-', 10.0, ')', '+', 'abs', '(', '-', 53.0, '/', 10.0, ')', '-', 5.0]): + list_.append(el) + self.assertEqual(list_, [10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, '-', 'log10', '*', + 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-']) + + def test36(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', + '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', '(', 43.0, ')', + ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', 34.0, '-', 2.0, '^', 2.0, ')', + ')', ')', ')', '+', 'cos', '(', 1.0, ')', '+', 'cos', '(', 0.0, ')', '^', 3.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, 'log10', + 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', 'cos', '+', + 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, '^', 'cos', '+', 'sin']) + + def test37(self): + list_ = [] + for el in calc_obj.sort_to_polish([2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^']) + + # TODO: process log correctly (if we put here first argument of log in (), everything will be done correctly) + # TODO: problem, when unary operations go after binary without parentheses as e^-e + def test38(self): # sin(e^log(e^e^sin(23.0),45.0) + cos(3.0+log10(e^-e))) + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', + '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', + '(', 'e', '^', '-', 'e', ')', ')', ')']): + list_.append(el) + self.assertEqual(list_, ['e', 'e', 'e', 23.0, 'sin', '^', '^', ',', 45.0, 'log', '^', 3.0, 'e', 0.0, + 'e', '-', '^', 'log10', '+', 'cos', '+', 'sin']) + + # Self-made cases + def test52(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '/', 3.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 3.0, '/']) + + def test54(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '+', 3.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 3.0, '+']) + + def test55(self): + list_ = [] + for el in calc_obj.sort_to_polish([100.0, '//', 3.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 3.0, '//']) + + def test56(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'sin', '(', 1.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 'sin', 'sin']) + + def test57(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'sin', '(', 1.0, ')', ')', '+', 1.0, '+', 'sin', '(', 1.0, ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 'sin', 'sin', 1.0, '+', 1.0, 'sin', '+']) + + def test58(self): + list_ = [] + for el in calc_obj.sort_to_polish(['abs', '(', '-', 3.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 3.0, '-', 'abs']) + + def test59(self): + list_ = [] + for el in calc_obj.sort_to_polish(['round', '(', 3.56393, ')']): + list_.append(el) + self.assertEqual(list_, [3.56393, 'round']) + + def test60(self): + list_ = [] + for el in calc_obj.sort_to_polish(['abs', '(', '-', 'round', '(', 3.56393, ')', ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 3.56393, 'round', '-', 'abs']) + + # logarithms + def test61(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [8.0, ',', 2.0, 'log']) + + def test62(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 2.7, ')']): + list_.append(el) + self.assertEqual(list_, [2.7, 'log']) + + def test63(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 'log', '(', 8.0, ',', 2.0, ')', '-', 1.0, ')', '-', 2.0]): + list_.append(el) + self.assertEqual(list_, [8.0, ',', 2.0, 'log', 1.0, '-', 2.0, '-']) + + def test64(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 'log', '(', 8.0, ',', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 8.0, ',', 2.0, 'log', '-']) + + def test65(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')', '-', 1.0]): + list_.append(el) + self.assertEqual(list_, [8.0, ',', 2.0, 'log', 1.0, '-']) + + def test66(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, ')']): + list_.append(el) + self.assertEqual(list_, [8.0, ',', 2.0, 'log', 16.0, ',', 2.0, 'log', '*']) + + def test67(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'log', '(', 8.0, ',', 2.0, ')', '*', + 'log', '(', 16.0, ',', 2.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [8.0, ',', 2.0, 'log', 16.0, ',', 2.0, 'log', '*', 'sin']) + + # TODO: fixed + def test68(self): # log(8+20-1,2+1) + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 8.0, '+', 20.0, '-', 1.0, ',', 2.0, '+', 1.0, ')']): + list_.append(el) + self.assertEqual(list_, [8.0, 20.0, '+', 1.0, '-', ',', 2.0, 1.0, '+', 'log']) + + def test69(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log10', '(', 100.0, ')']): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10']) + + def test70(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 100.0, ',', 10.0, ')']): + list_.append(el) + self.assertEqual(list_, [100.0, ',', 10.0, 'log']) + + def test71(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 'log10', '(', 100.0, ')', '-', 1.0, ')', '-', 2.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10', 1.0, '-', 2.0, '-']) + + def test72(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 'log10', '(', 100.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 100.0, 'log10', '-']) + + def test73(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log10', '(', 100.0, ')', '-', 1.0]): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10', 1.0, '-']) + + def test74(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')']): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10', 1000.0, 'log10', '*']) + + def test75(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [100.0, 'log10', 1000.0, 'log10', '*', 'sin']) + + def test76(self): + list_ = [] + for el in calc_obj.sort_to_polish(['log10', '(', 800.0, '/', 2.0, '/', 4.0, ')']): + list_.append(el) + self.assertEqual(list_, [800.0, 2.0, '/', 4.0, '/', 'log10']) + + # pow + def test77(self): + list_ = [] + for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')']): + list_.append(el) + self.assertEqual(list_, [2.0, ',', 4.0, 'pow']) + + # TODO: process log correctly (if we put here first argument of log in (), everything will be done correctly) + def test78(self): # log(pow(10,2),10) + list_ = [] + for el in calc_obj.sort_to_polish(['log', '(', 'pow', '(', 10.0, ',', 2.0, ')', ',', 10.0, ')']): + list_.append(el) + self.assertEqual(list_, [10.0, ',', 2.0, 'pow', ',', 10.0, 'log']) + + def test79(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 'pow', '(', 2.0, ',', 4.0, ')', '-', 1.0, ')', '-', 2.0]): + list_.append(el) + self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 1.0, '-', 2.0, '-']) + + def test80(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 'pow', '(', 2.0, ',', 4.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 2.0, ',', 4.0, 'pow', '-']) + + def test81(self): + list_ = [] + for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')', '-', 1.0]): + list_.append(el) + self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 1.0, '-']) + + def test82(self): + list_ = [] + for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')']): + list_.append(el) + self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 2.0, ',', 3.0, 'pow', '*']) + + def test83(self): + list_ = [] + for el in calc_obj.sort_to_polish(['sin', '(', 'pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 2.0, ',', 3.0, 'pow', '*', 'sin']) + + # TODO: process pow correctly (if we put arguments of pow in (), everything will be done correctly) + def test84(self): # pow(2.0^(2.0^2.0*2.0^2.0),sin(log10(100)*log10(1000))) + list_ = [] + for el in calc_obj.sort_to_polish(['pow', '(', 2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')', ',', 'sin', '(', + 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')', ')']): + list_.append(el) + self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', ',', 100.0, 'log10', 1000.0, 'log10', '*', + 'sin', 'pow']) + + # unary_operations + def test85(self): + list_ = [] + for el in calc_obj.sort_to_polish([13.0]): + list_.append(el) + self.assertEqual(list_, [13.0]) + + def test86(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', '(', '-', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 0.0, 13.0, '-', '-']) + + def test87(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', '(', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 13.0, '-']) + + # TODO: problem, when unary operations go after binary without parentheses + def test88(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '*', '-', 13.0]): + list_.append(el) + self.assertEqual(list_, [1.0, 0.0, 13.0, '-', '*']) + + def test89(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '*', '(', '-', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 0.0, 13.0, '-', '*']) + + def tes90(self): + list_ = [] + for el in calc_obj.sort_to_polish([1.0, '*', '(', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 13.0, '*']) + + def test91(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', 1.0, '+', 13.0, ')']): + list_.append(el) + self.assertEqual(list_, [1.0, 13.0, '+']) + + def test92(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', 1.0, '-', '(', '-', 1.0, ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 1.0, '-', 0.0, 1.0, '-', '-']) + + def test93(self): + list_ = [] + for el in calc_obj.sort_to_polish(['(', '(', 1.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [1.0]) + + def test94(self): + list_ = [] + for el in calc_obj.sort_to_polish(['-', '(', '-', '(', '-', 1.0, ')', ')']): + list_.append(el) + self.assertEqual(list_, [0.0, 0.0, 0.0, 1.0, '-', '-', '-']) + + +if __name__ == '__main__': + unittest.main() diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py new file mode 100644 index 00000000..5332fded --- /dev/null +++ b/final_task/unittests/unittests_validation.py @@ -0,0 +1,406 @@ +import unittest + +from py_calc import PyCalcProcessing + +calc_obj = PyCalcProcessing('1') + + +class ExpectedFailureTestCase(unittest.TestCase): + # Error cases + def test1(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+', '+'])) + + def test2(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+'])) + + def test3(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([1.0, '-'])) + + def test4(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['ee'])) + + def test5(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['==', 7.0])) + + def test6(self): + self.assertRaises(ValueError, + lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) + + def test7(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) + + def test8(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + + def test9(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) + + def test10(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) + + def test11(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + + def test12(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) + + def test13(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + + def test14(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) + + # TODO: this type of error is not processed here for now + # def test15(self): + # self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['pow', '(', 2.0, ',', 3.0, ',', 4.0, ')'])) + + def test16(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) + + def test17(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) + + def test18(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) + + def test19(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) + + def test20(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) + + def test21(self): + self.assertRaises(ValueError, + lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) + + def test22(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) + + def test23(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) + + def test24(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', + 'sin', '(', 2.0, ')'])) + + def test25(self): + self.assertRaises(ValueError, + lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) + + def test26(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) + + def test27(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, + ')', 'sin', '(', 2.0, ')'])) + + def test28(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + '.', '(', 2.0, '+', '1'])) + + def test29(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', + + 4.0, '.', '.', ')'])) + + def test30(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + '.', '(', 2.0, '+', '1'])) + + def test31(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + '.', ',', 2.0, '+', '1'])) + + def test32(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + '.', '-', 2.0, '+', '1'])) + + def test33(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + '.', 'sin', '(', 2.0, ')'])) + + def test34(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) + + def test35(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) + + def test36(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) + + def test37(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) + + def test38(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) + + def test39(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) + + def test40(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) + + def test41(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) + + def test42(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) + + def test43(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) + + def test44(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) + + def test45(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) + + def test46(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) + + def test47(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) + + def test48(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) + + def test49(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) + + def test50(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) + + def test51(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) + + def test52(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) + + def test53(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) + + def test54(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) + + def test55(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) + + def test56(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) + + def test57(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) + + def test58(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) + + def test59(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) + + # matched parentheses + def test60(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) + + def test61(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) + + def test62(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) + + def test63(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) + + def test64(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, + '+', ')', 1.0, ')'])) + + +class ExpectedSuccessTestCase(unittest.TestCase): + def test_1(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 13.0])) + + def test_2(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([6.0, '-', '(', '-', + 13.0, ')'])) + + def test_3(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([1.0, '-', '-', '-', + 1.0])) + + def test_4(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['-', '+', '-', '-', + '-', '+', '-', 1.0])) + + def test_5(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '+', 2.0, + '*', 2.0])) + + def test_6(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([1.0, '+', '(', 2.0, '+', + 3.0, '*', 2.0, ')', '*', + 3.0])) + + def test_7(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([10.0, '*', '(', 2.0, + '+', 1.0, ')'])) + + def test_8(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([10.0, '^', '(', 2.0, + '+', 1.0, ')'])) + + def test_9(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([100.0, '/', 3.0, + '^', 2.0])) + + def test_10(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([100.0, '/', 3.0, '%', + 2.0, '^', 2.0])) + + def test_11(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['pi', '+', 'e'])) + + def test_12(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['log', '(', 'e', ')'])) + + def test_13(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', + 2.0, ')'])) + + def test_14(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['log10', '(', + 100.0, ')'])) + + def test_15(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + ['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0])) + + def test_16(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + [2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')'])) + + def test_17(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['abs', '(', '-', 5.0, + ')'])) + + def test_18(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['round', '(', + 123.456789, + ')'])) + + def test_19(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([102.0, '%', 12.0, + '%', 7.0])) + + def test_20(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([100.0, '/', 4.0, '/', + 3.0])) + + def test_21(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([2.0, '^', 3.0, '^', + 4.0])) + + def test_22(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + [1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0])) + + def test_23(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + ['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0])) + + def test_24(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + [1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0])) + + def test_25(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['(', 100.0, ')'])) + + def test_26(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([666.0])) + + def test_27(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 0.1])) + + def test_28(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([1.0, '/', 3.0])) + + def test_29(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([0.1, '*', 2.0, '^', + 56.0])) + + def test_30(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['e', '^', 34.0])) + + def test_31(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', + '/', 'e', '+', 2.0, '^', 0.0, ')', ')'])) + + def test_32(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', + '/', 'e', '+', 2.0, '^', 0.0, ')', ')', + '^', '(', 1.0, '/', 3.0, ')'])) + + def test_33(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', + 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', 5.0])) + + def test_34(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', + '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', + 'log10', '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', + 34.0, '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', '-', 'cos', '(', 1.0, ')', '-', '-', + 'cos', '(', 0.0, ')', '^', 3.0, ')'])) + + def test_35(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + [2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')'])) + + def test_36(self): + self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + ['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', ',', 45.0, + ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')'])) + + def test_37(self): + self.assertEqual('Formula was validated! Errors were not found.', + calc_obj.validate_parsed_list([1.0, '*', '-', 13.0])) + + def test_38(self): + self.assertEqual('Formula was validated! ' + 'Errors were not found.', + calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '-', 13.0, ')'])) + + def test_39(self): + self.assertEqual('Formula was validated! ' + 'Errors were not found.', calc_obj.validate_parsed_list(['log', '(', 1.0, ',', + '(', '-', 13.0, ')', ')'])) + + # incorrect number of arguments processing in calc + def test_40(self): + self.assertEqual('Formula was validated! ' + 'Errors were not found.', calc_obj.validate_parsed_list(['pow', '(', 1.0, ')'])) + + +if __name__ == '__main__': + unittest.main() From 2fdff0b2769046f29b159a521fb6f9867856a806 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sat, 1 Jun 2019 14:57:29 +0300 Subject: [PATCH 02/29] Fix pycalc name --- .idea/PythonHomework.iml | 11 + .idea/inspectionProfiles/Project_Default.xml | 12 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 290 ++++++++++++++++++ final_task/{entry_point.py => pycalc.py} | 8 +- final_task/{py_calc.py => pycalc_proc.py} | 0 final_task/setup.py | 6 +- .../unittest_process_unary_operations.py | 2 +- final_task/unittests/unittests_calc.py | 2 +- .../unittests/unittests_parse_function.py | 2 +- .../unittests/unittests_prevalidation.py | 2 +- .../unittests_sort_to_polish_function.py | 2 +- final_task/unittests/unittests_validation.py | 2 +- 15 files changed, 346 insertions(+), 11 deletions(-) create mode 100644 .idea/PythonHomework.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml rename final_task/{entry_point.py => pycalc.py} (90%) rename final_task/{py_calc.py => pycalc_proc.py} (100%) diff --git a/.idea/PythonHomework.iml b/.idea/PythonHomework.iml new file mode 100644 index 00000000..67116063 --- /dev/null +++ b/.idea/PythonHomework.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..0ef22171 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..32b11402 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..1d518fa3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..41212020 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -132,6 +165,20 @@ + + + + + + - + + @@ -166,18 +218,25 @@ + + + + + + - + - + + @@ -189,7 +248,6 @@ - @@ -220,16 +278,6 @@ - - - - - - - - - - @@ -250,22 +298,32 @@ - + - - + + - + - - + + - + + + + + + + + + + + @@ -278,30 +336,28 @@ - + - - + + - + - + - + - - - + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index cd4c02fb..3138790d 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -44,15 +44,15 @@ def pre_validate(formula_string): """ # проверка, что формула не пустая строка if not isinstance(formula_string, str) or not formula_string: - print('Formula should be not empty string!') + print('ERROR: Formula should be not empty string!') # проверяем, что в формуле нет более одного разделителя подряд # в текущей реализации удобнее сделать это здесь, чтобы упростить дальнейший парсинг на токены if '..' in formula_string: - print('Number can not contain more than one delimiter "." !') + print('ERROR: Number can not contain more than one delimiter "." !') # проверка на разрешённые элементы for el in formula_string.strip(): if el not in ALLOWED_TOKENS: - print('Formula contains incorrect symbol "{}"'.format(el)) + print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) @staticmethod def parse(formula_string): @@ -129,9 +129,9 @@ def parse(formula_string): def validate_parsed_list(self, parsed_list): if parsed_list[-1] in OPERATORS: - print('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) if parsed_list[0] in BINARY_OPERATORS: - print('Formula can not start with binary operator "{}"'.format(parsed_list[0])) + print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) counter = 0 # counter for parentheses @@ -139,10 +139,10 @@ def validate_parsed_list(self, parsed_list): for el in parsed_list: counter = self._matched_parentheses(el, counter) - message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) + message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) if el == '.': - print('Single delimiter is prohibited in formula!') + print('ERROR: Single delimiter is prohibited in formula!') if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: @@ -179,7 +179,7 @@ def validate_parsed_list(self, parsed_list): previous_el = el if counter != 0: - print('Wrong number of opened or closed parentheses in formula!') + print('ERROR: Wrong number of opened or closed parentheses in formula!') return 'Formula was validated! Errors were not found.' @@ -250,7 +250,6 @@ def sort_to_polish(parsed_formula): # выдаём все операторы из стека до открывающей скобки while stack and stack[-1] != "(": yield stack.pop() - yield token else: # если элемент - число или константа, отправим его сразу на выход yield token @@ -302,7 +301,7 @@ def calc(self, polish_list): try: function_result = func_name(*tuple(arguments)) except TypeError: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') stack.append(function_result) # вычисляем оператор, возвращаем в стек arguments = [] @@ -323,7 +322,7 @@ def calc(self, polish_list): stack.append(token) if len(stack) > 1: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') return stack[0] # результат вычисления - единственный элемент в стеке diff --git a/final_task/unittests/unittests_sort_to_polish_function.py b/final_task/unittests/unittests_sort_to_polish_function.py index f6888ec1..4e6ef6fd 100644 --- a/final_task/unittests/unittests_sort_to_polish_function.py +++ b/final_task/unittests/unittests_sort_to_polish_function.py @@ -221,7 +221,7 @@ def test34(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 1.0, '*', 4.0, '+', 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']): list_.append(el) - self.assertEqual(list_, [1.0, 4.0, '*', 2.0, 2.0, '^', '+', 1.0, '+', ',', 3.0, 2.0, '^', 'log']) + self.assertEqual(list_, [1.0, 4.0, '*', 2.0, 2.0, '^', '+', 1.0, '+', 3.0, 2.0, '^', 'log']) # TODO: problem, when unary operations go after binary without parentheses as -5/ -0.1 def test35(self): # 10*e^0*log10(.4 -5/ -0.1-10)+abs(-53/10)-5 @@ -257,7 +257,7 @@ def test38(self): # sin(e^log(e^e^sin(23.0),45.0) + cos(3.0+log10(e^-e))) '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')']): list_.append(el) - self.assertEqual(list_, ['e', 'e', 'e', 23.0, 'sin', '^', '^', ',', 45.0, 'log', '^', 3.0, 'e', 0.0, + self.assertEqual(list_, ['e', 'e', 'e', 23.0, 'sin', '^', '^', 45.0, 'log', '^', 3.0, 'e', 0.0, 'e', '-', '^', 'log10', '+', 'cos', '+', 'sin']) # Self-made cases @@ -314,7 +314,7 @@ def test61(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')']): list_.append(el) - self.assertEqual(list_, [8.0, ',', 2.0, 'log']) + self.assertEqual(list_, [8.0, 2.0, 'log']) def test62(self): list_ = [] @@ -326,39 +326,39 @@ def test63(self): list_ = [] for el in calc_obj.sort_to_polish(['(', 'log', '(', 8.0, ',', 2.0, ')', '-', 1.0, ')', '-', 2.0]): list_.append(el) - self.assertEqual(list_, [8.0, ',', 2.0, 'log', 1.0, '-', 2.0, '-']) + self.assertEqual(list_, [8.0, 2.0, 'log', 1.0, '-', 2.0, '-']) def test64(self): list_ = [] for el in calc_obj.sort_to_polish(['-', 'log', '(', 8.0, ',', 2.0, ')']): list_.append(el) - self.assertEqual(list_, [0.0, 8.0, ',', 2.0, 'log', '-']) + self.assertEqual(list_, [0.0, 8.0, 2.0, 'log', '-']) def test65(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')', '-', 1.0]): list_.append(el) - self.assertEqual(list_, [8.0, ',', 2.0, 'log', 1.0, '-']) + self.assertEqual(list_, [8.0, 2.0, 'log', 1.0, '-']) def test66(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, ')']): list_.append(el) - self.assertEqual(list_, [8.0, ',', 2.0, 'log', 16.0, ',', 2.0, 'log', '*']) + self.assertEqual(list_, [8.0, 2.0, 'log', 16.0, 2.0, 'log', '*']) def test67(self): list_ = [] for el in calc_obj.sort_to_polish(['sin', '(', 'log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, ')', ')']): list_.append(el) - self.assertEqual(list_, [8.0, ',', 2.0, 'log', 16.0, ',', 2.0, 'log', '*', 'sin']) + self.assertEqual(list_, [8.0, 2.0, 'log', 16.0, 2.0, 'log', '*', 'sin']) # TODO: fixed def test68(self): # log(8+20-1,2+1) list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 8.0, '+', 20.0, '-', 1.0, ',', 2.0, '+', 1.0, ')']): list_.append(el) - self.assertEqual(list_, [8.0, 20.0, '+', 1.0, '-', ',', 2.0, 1.0, '+', 'log']) + self.assertEqual(list_, [8.0, 20.0, '+', 1.0, '-', 2.0, 1.0, '+', 'log']) def test69(self): list_ = [] @@ -370,7 +370,7 @@ def test70(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 100.0, ',', 10.0, ')']): list_.append(el) - self.assertEqual(list_, [100.0, ',', 10.0, 'log']) + self.assertEqual(list_, [100.0, 10.0, 'log']) def test71(self): list_ = [] @@ -413,44 +413,44 @@ def test77(self): list_ = [] for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')']): list_.append(el) - self.assertEqual(list_, [2.0, ',', 4.0, 'pow']) + self.assertEqual(list_, [2.0, 4.0, 'pow']) # TODO: process log correctly (if we put here first argument of log in (), everything will be done correctly) def test78(self): # log(pow(10,2),10) list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 'pow', '(', 10.0, ',', 2.0, ')', ',', 10.0, ')']): list_.append(el) - self.assertEqual(list_, [10.0, ',', 2.0, 'pow', ',', 10.0, 'log']) + self.assertEqual(list_, [10.0, 2.0, 'pow', 10.0, 'log']) def test79(self): list_ = [] for el in calc_obj.sort_to_polish(['(', 'pow', '(', 2.0, ',', 4.0, ')', '-', 1.0, ')', '-', 2.0]): list_.append(el) - self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 1.0, '-', 2.0, '-']) + self.assertEqual(list_, [2.0, 4.0, 'pow', 1.0, '-', 2.0, '-']) def test80(self): list_ = [] for el in calc_obj.sort_to_polish(['-', 'pow', '(', 2.0, ',', 4.0, ')']): list_.append(el) - self.assertEqual(list_, [0.0, 2.0, ',', 4.0, 'pow', '-']) + self.assertEqual(list_, [0.0, 2.0, 4.0, 'pow', '-']) def test81(self): list_ = [] for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')', '-', 1.0]): list_.append(el) - self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 1.0, '-']) + self.assertEqual(list_, [2.0, 4.0, 'pow', 1.0, '-']) def test82(self): list_ = [] for el in calc_obj.sort_to_polish(['pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')']): list_.append(el) - self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 2.0, ',', 3.0, 'pow', '*']) + self.assertEqual(list_, [2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*']) def test83(self): list_ = [] for el in calc_obj.sort_to_polish(['sin', '(', 'pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')', ')']): list_.append(el) - self.assertEqual(list_, [2.0, ',', 4.0, 'pow', 2.0, ',', 3.0, 'pow', '*', 'sin']) + self.assertEqual(list_, [2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*', 'sin']) # TODO: process pow correctly (if we put arguments of pow in (), everything will be done correctly) def test84(self): # pow(2.0^(2.0^2.0*2.0^2.0),sin(log10(100)*log10(1000))) @@ -458,7 +458,7 @@ def test84(self): # pow(2.0^(2.0^2.0*2.0^2.0),sin(log10(100)*log10(1000))) for el in calc_obj.sort_to_polish(['pow', '(', 2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')', ',', 'sin', '(', 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')', ')']): list_.append(el) - self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', ',', 100.0, 'log10', 1000.0, 'log10', '*', + self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', 100.0, 'log10', 1000.0, 'log10', '*', 'sin', 'pow']) # unary_operations From 2cb89bd91816f683832fae7bf701d71fafdbcd95 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 09:00:29 +0300 Subject: [PATCH 08/29] Fix minimal requirements --- .idea/workspace.xml | 238 ++++++++++-------- final_task/config.py | 2 +- final_task/pycalc_proc.py | 8 +- final_task/unittests/unittests_calc.py | 52 ++-- .../unittests/unittests_parse_function.py | 16 +- .../unittests_sort_to_polish_function.py | 60 +++-- final_task/unittests/unittests_validation.py | 182 +++++++------- 7 files changed, 287 insertions(+), 271 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 7412bee2..e8589f99 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,12 @@ + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -87,19 +45,20 @@ - + + + + + + + - - - + + + + + + - + + + + @@ -218,25 +225,46 @@ - + + + + + + + + + + + + + + + + + + + - + - + + + + - + - + @@ -260,86 +288,90 @@ - + - + - + - - + + - + - - + + - + - + - - + + - + + + + + + + + + - - - - - + + + - + - - + + - + - + - - - - - + + + - + - - + + - - + + @@ -348,21 +380,11 @@ - - + + - - - - - - - - - - \ No newline at end of file diff --git a/final_task/config.py b/final_task/config.py index cfa0d5e4..262fc758 100644 --- a/final_task/config.py +++ b/final_task/config.py @@ -47,4 +47,4 @@ DELIMETERS = ('.', ',', ' ') -ALLOWED_TOKENS = OPERATORS_BEGIN + LETTERS + DIGITS + PARENTHESES + DELIMETERS \ No newline at end of file +ALLOWED_TOKENS = OPERATORS_BEGIN + LETTERS + DIGITS + PARENTHESES + DELIMETERS diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 3138790d..cb8ec8d5 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -195,8 +195,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or - not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in + (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # считаем кол-во -, заменяя на + либо на - @@ -231,8 +231,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and - token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] + and token != '^'): yield stack.pop() stack.append(token) elif token == ")": diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py index 20fe97be..3cc54ee8 100644 --- a/final_task/unittests/unittests_calc.py +++ b/final_task/unittests/unittests_calc.py @@ -54,7 +54,8 @@ def test14(self): self.assertEqual(math.log10(100.0), calc_obj.calc([100.0, 'log10'])) def test15(self): - self.assertEqual(math.sin(math.pi / 2.0) * 111 * 6, calc_obj.calc(['pi', 2.0, '/', 'sin', 111.0, '*', 6.0, '*'])) + self.assertEqual(math.sin(math.pi / 2.0) * 111 * 6, + calc_obj.calc(['pi', 2.0, '/', 'sin', 111.0, '*', 6.0, '*'])) def test16(self): self.assertEqual(2.0 * math.sin(math.pi / 2.0), calc_obj.calc([2.0, 'pi', 2.0, '/', 'sin', '*'])) @@ -77,16 +78,17 @@ def test21(self): # Comparison operators def test22(self): - self.assertEqual(1.0 + 2.0 * 3.0 == 1.0 + 2.0 * 3.0, calc_obj.calc([1.0, 2.0, 3.0, '*', '+', - 1.0, 2.0, 3.0, '*', '+', '=='])) + self.assertEqual(1.0 + 2.0 * 3.0 == 1.0 + 2.0 * 3.0, + calc_obj.calc([1.0, 2.0, 3.0, '*', '+', 1.0, 2.0, 3.0, '*', '+', '=='])) def test23(self): - self.assertEqual(math.e ** 5.0 >= math.e ** 5.0 + 1.0, calc_obj.calc(['e', 5.0, '^', 'e', 5.0, '^', 1.0, '+', '>='])) + self.assertEqual(math.e ** 5.0 >= math.e ** 5.0 + 1.0, + calc_obj.calc(['e', 5.0, '^', 'e', 5.0, '^', 1.0, '+', '>='])) def test24(self): self.assertEqual(1.0 + 2.0 * 4.0 / 3.0 + 1.0 != 1.0 + 2.0 * 4.0 / 3.0 + 2.0, - calc_obj.calc([1.0, 2.0, 4.0, '*', 3.0, '/', '+', 1.0, '+', 1.0, 2.0, 4.0, '*', - 3.0, '/', '+', 2.0, '+', '!='])) + calc_obj.calc([1.0, 2.0, 4.0, '*', 3.0, '/', '+', 1.0, '+', 1.0, 2.0, 4.0, '*', 3.0, '/', '+', + 2.0, '+', '!='])) # Common tests def test25(self): @@ -111,31 +113,30 @@ def test31(self): self.assertEqual(math.e ** 34.0, calc_obj.calc(['e', 34.0, '^'])) def test32(self): - self.assertEqual((2.0 ** (math.pi/math.pi+math.e/math.e+2.0**0.0)), calc_obj.calc([2.0, 'pi', 'pi', '/', 'e', 'e', '/', - '+', 2.0, 0.0, '^', '+', '^'])) + self.assertEqual((2.0 ** (math.pi/math.pi+math.e/math.e+2.0**0.0)), + calc_obj.calc([2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^'])) def test33(self): self.assertEqual((2.0**(math.pi/math.pi+math.e/math.e+2.0**0.0))**(1.0/3.0), calc_obj.calc( [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^', 1.0, 3.0, '/', '^'])) def test34(self): - self.assertEqual(math.sin(math.pi/2.0**1.0) + math.log(1*4+2**2+1, 3**2), calc_obj.calc(['pi', 2.0, 1.0, '^', '/', 'sin', - 1.0, 4.0, '*', 2.0, 2.0, '^', '+', - 1.0, '+', 3.0, 2.0, '^', - 'log', '+'])) + self.assertEqual(math.sin(math.pi/2.0**1.0) + math.log(1*4+2**2+1, 3**2), + calc_obj.calc(['pi', 2.0, 1.0, '^', '/', 'sin', 1.0, 4.0, '*', 2.0, 2.0, '^', + '+', 1.0, '+', 3.0, 2.0, '^', 'log', '+'])) def test35(self): self.assertEqual(10.0*math.e**0.0*math.log10(.4 -5.0/ -0.1-10.0) - -abs(-53.0/10.0) + -5.0, - calc_obj.calc([10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, '-', 'log10', '*', - 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-'])) + calc_obj.calc([10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, + '-', 'log10', '*', 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-'])) def test36(self): self.assertEqual(math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos (math.log10(43.0))))+math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)-- - math.cos(0.0)**3.0), calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', - 43.0, 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', - '-', 'sin', 'sin', 'cos', '+', 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, - '^', 'cos', '+', 'sin'])) + math.cos(0.0)**3.0), + calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, + 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', + 'cos', '+', 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, '^', 'cos', '+', 'sin'])) def test37(self): self.assertEqual(2.0**(2.0**2.0*2.0**2.0), calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^'])) @@ -143,8 +144,8 @@ def test37(self): def test38(self): self.assertEqual(math.sin(math.e**math.log(math.e**math.e**math.sin(23.0), 45.0) + math.cos(3.0+math.log10(math.e**-math.e))), - calc_obj.calc(['e', 'e', 'e', 23.0, 'sin', '^', '^', 45.0, 'log', '^', 3.0, 'e', 0.0, 'e', '-', - '^', 'log10', '+', 'cos', '+', 'sin'])) + calc_obj.calc(['e', 'e', 'e', 23.0, 'sin', '^', '^', 45.0, 'log', '^', 3.0, 'e', 0.0, + 'e', '-', '^', 'log10', '+', 'cos', '+', 'sin'])) # Self-made cases def test52(self): @@ -197,7 +198,8 @@ def test67(self): calc_obj.calc([8.0, 2.0, 'log', 16.0, 2.0, 'log', '*', 'sin'])) def test68(self): - self.assertEqual(math.log(8.0+20.0-1.0, 2.0+1.0), calc_obj.calc([8.0, 20.0, '+', 1.0, '-', 2.0, 1.0, '+', 'log'])) + self.assertEqual(math.log(8.0+20.0-1.0, 2.0+1.0), + calc_obj.calc([8.0, 20.0, '+', 1.0, '-', 2.0, 1.0, '+', 'log'])) def test69(self): self.assertEqual(math.log10(100.0), calc_obj.calc([100.0, 'log10'])) @@ -244,13 +246,13 @@ def test82(self): self.assertEqual(math.pow(2.0, 4.0)*math.pow(2.0, 3.0), calc_obj.calc([2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*'])) def test83(self): - self.assertEqual(math.sin(math.pow(2.0, 4.0)*math.pow(2.0, 3.0)), calc_obj.calc([2.0, 4.0, 'pow', 2.0, 3.0, - 'pow', '*', 'sin'])) + self.assertEqual(math.sin(math.pow(2.0, 4.0)*math.pow(2.0, 3.0)), + calc_obj.calc([2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*', 'sin'])) def test84(self): self.assertEqual(math.pow(2.0**(2.0**2.0*2.0**2.0), math.log10(100.0)*math.log10(1000.0)), - calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', 100.0, 'log10', 1000.0, 'log10', '*', - 'pow'])) + calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', + 100.0, 'log10', 1000.0, 'log10', '*', 'pow'])) def test85(self): self.assertEqual(13.0, calc_obj.calc([13.0])) diff --git a/final_task/unittests/unittests_parse_function.py b/final_task/unittests/unittests_parse_function.py index d4334ec6..ae86b19d 100644 --- a/final_task/unittests/unittests_parse_function.py +++ b/final_task/unittests/unittests_parse_function.py @@ -214,14 +214,14 @@ def test33(self): self.assertEqual(list_, ['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')', '^', '(', 1.0, '/', 3.0, ')']) - # def test34(self): # how to process comma in log - # list_ = [] - # for el in calc_obj.parse('sin(pi/2^1) + log(1*4+2^2+1, 3^2)'): - # list_.append(el) - # self.assertEqual(list_, ['sin', '(', 'pi', '/', 2.0, '^', 1.0, ')', '+', 'log', '(', 1.0, '*', 4.0, '+', - # 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']) + def test34(self): + list_ = [] + for el in calc_obj.parse('sin(pi/2^1) + log(1*4+2^2+1, 3^2)'): + list_.append(el) + self.assertEqual(list_, ['sin', '(', 'pi', '/', 2.0, '^', 1.0, ')', '+', 'log', '(', 1.0, '*', 4.0, '+', + 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']) - def test35(self): # why there are no parentheses after division in log + def test35(self): list_ = [] for el in calc_obj.parse('10*e^0*log10(.4 -5/ -0.1-10) - -abs(-53/10) + -5'): list_.append(el) @@ -231,7 +231,7 @@ def test35(self): # why there are no parentheses after division in log def test36(self): list_ = [] for el in calc_obj.parse('sin(-cos(-sin(3.0)-cos(-sin(-3.0*5.0)-sin(cos(log10(43.0))))+' - 'cos(sin(sin(34.0-2.0^2.0))))--cos(1.0)--cos(0.0)^3.0)'): + 'cos(sin(sin(34.0-2.0^2.0))))--cos(1.0)--cos(0.0)^3.0)'): list_.append(el) self.assertEqual(list_, ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', diff --git a/final_task/unittests/unittests_sort_to_polish_function.py b/final_task/unittests/unittests_sort_to_polish_function.py index 4e6ef6fd..6bb3cdd3 100644 --- a/final_task/unittests/unittests_sort_to_polish_function.py +++ b/final_task/unittests/unittests_sort_to_polish_function.py @@ -153,7 +153,7 @@ def test23(self): def test24(self): list_ = [] for el in calc_obj.sort_to_polish([1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', - 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0]): + 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0]): list_.append(el) self.assertEqual(list_, [1.0, 2.0, 4.0, '*', 3.0, '/', '+', 1.0, '+', 1.0, 2.0, 4.0, '*', 3.0, '/', '+', 2.0, '+', '!=']) @@ -203,41 +203,41 @@ def test31(self): def test32(self): list_ = [] - for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', - '+', 2.0, '^', 0.0, ')', ')']): + for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', + 'e', '+', 2.0, '^', 0.0, ')', ')']): list_.append(el) self.assertEqual(list_, [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^']) def test33(self): list_ = [] - for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', - ')', '^', '(', 1.0, '/', 3.0, ')']): + for el in calc_obj.sort_to_polish(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, + '^', 0.0, ')', ')', '^', '(', 1.0, '/', 3.0, ')']): list_.append(el) self.assertEqual(list_, [2.0, 'pi', 'pi', '/', 'e', 'e', '/', '+', 2.0, 0.0, '^', '+', '^', 1.0, 3.0, '/', '^']) - # TODO: fixed def test34(self): list_ = [] - for el in calc_obj.sort_to_polish(['log', '(', 1.0, '*', 4.0, '+', 2.0, '^', 2.0, '+', 1.0, ',', 3.0, '^', 2.0, ')']): + for el in calc_obj.sort_to_polish(['log', '(', 1.0, '*', 4.0, '+', 2.0, '^', 2.0, '+', 1.0, + ',', 3.0, '^', 2.0, ')']): list_.append(el) self.assertEqual(list_, [1.0, 4.0, '*', 2.0, 2.0, '^', '+', 1.0, '+', 3.0, 2.0, '^', 'log']) - # TODO: problem, when unary operations go after binary without parentheses as -5/ -0.1 - def test35(self): # 10*e^0*log10(.4 -5/ -0.1-10)+abs(-53/10)-5 + def test35(self): list_ = [] for el in calc_obj.sort_to_polish([10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, - '-', 10.0, ')', '+', 'abs', '(', '-', 53.0, '/', 10.0, ')', '-', 5.0]): + '-', 10.0, ')', '+', 'abs', '(', '-', 53.0, '/', 10.0, ')', '-', 5.0]): list_.append(el) self.assertEqual(list_, [10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, '-', 'log10', '*', 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-']) def test36(self): list_ = [] - for el in calc_obj.sort_to_polish(['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', - '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', '(', 43.0, ')', - ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', 34.0, '-', 2.0, '^', 2.0, ')', - ')', ')', ')', '+', 'cos', '(', 1.0, ')', '+', 'cos', '(', 0.0, ')', '^', 3.0, ')']): + for el in calc_obj.sort_to_polish(['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', + 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', + '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', 34.0, + '-', 2.0, '^', 2.0, ')', ')', ')', ')', '+', 'cos', '(', 1.0, ')', '+', + 'cos', '(', 0.0, ')', '^', 3.0, ')']): list_.append(el) self.assertEqual(list_, [0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', 'cos', '+', @@ -249,13 +249,11 @@ def test37(self): list_.append(el) self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^']) - # TODO: process log correctly (if we put here first argument of log in (), everything will be done correctly) - # TODO: problem, when unary operations go after binary without parentheses as e^-e - def test38(self): # sin(e^log(e^e^sin(23.0),45.0) + cos(3.0+log10(e^-e))) + def test38(self): list_ = [] - for el in calc_obj.sort_to_polish(['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', - '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', - '(', 'e', '^', '-', 'e', ')', ')', ')']): + for el in calc_obj.sort_to_polish(['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', + ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', + ')', ')', ')']): list_.append(el) self.assertEqual(list_, ['e', 'e', 'e', 23.0, 'sin', '^', '^', 45.0, 'log', '^', 3.0, 'e', 0.0, 'e', '-', '^', 'log10', '+', 'cos', '+', 'sin']) @@ -348,13 +346,12 @@ def test66(self): def test67(self): list_ = [] - for el in calc_obj.sort_to_polish(['sin', '(', 'log', '(', 8.0, ',', 2.0, ')', '*', - 'log', '(', 16.0, ',', 2.0, ')', ')']): + for el in calc_obj.sort_to_polish(['sin', '(', 'log', '(', 8.0, ',', 2.0, ')', '*', 'log', '(', 16.0, ',', 2.0, + ')', ')']): list_.append(el) self.assertEqual(list_, [8.0, 2.0, 'log', 16.0, 2.0, 'log', '*', 'sin']) - # TODO: fixed - def test68(self): # log(8+20-1,2+1) + def test68(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 8.0, '+', 20.0, '-', 1.0, ',', 2.0, '+', 1.0, ')']): list_.append(el) @@ -415,8 +412,7 @@ def test77(self): list_.append(el) self.assertEqual(list_, [2.0, 4.0, 'pow']) - # TODO: process log correctly (if we put here first argument of log in (), everything will be done correctly) - def test78(self): # log(pow(10,2),10) + def test78(self): list_ = [] for el in calc_obj.sort_to_polish(['log', '(', 'pow', '(', 10.0, ',', 2.0, ')', ',', 10.0, ')']): list_.append(el) @@ -448,15 +444,16 @@ def test82(self): def test83(self): list_ = [] - for el in calc_obj.sort_to_polish(['sin', '(', 'pow', '(', 2.0, ',', 4.0, ')', '*', 'pow', '(', 2.0, ',', 3.0, ')', ')']): + for el in calc_obj.sort_to_polish(['sin', '(', 'pow', '(', 2.0, ',', 4.0, ')', '*', + 'pow', '(', 2.0, ',', 3.0, ')', ')']): list_.append(el) self.assertEqual(list_, [2.0, 4.0, 'pow', 2.0, 3.0, 'pow', '*', 'sin']) - # TODO: process pow correctly (if we put arguments of pow in (), everything will be done correctly) - def test84(self): # pow(2.0^(2.0^2.0*2.0^2.0),sin(log10(100)*log10(1000))) + def test84(self): list_ = [] - for el in calc_obj.sort_to_polish(['pow', '(', 2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')', ',', 'sin', '(', - 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, ')', ')', ')']): + for el in calc_obj.sort_to_polish(['pow', '(', 2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')', ',', + 'sin', '(', 'log10', '(', 100.0, ')', '*', 'log10', '(', 1000.0, + ')', ')', ')']): list_.append(el) self.assertEqual(list_, [2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^', 100.0, 'log10', 1000.0, 'log10', '*', 'sin', 'pow']) @@ -480,7 +477,6 @@ def test87(self): list_.append(el) self.assertEqual(list_, [0.0, 13.0, '-']) - # TODO: problem, when unary operations go after binary without parentheses def test88(self): list_ = [] for el in calc_obj.sort_to_polish([1.0, '*', '-', 13.0]): diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index a8dda8a2..a2d01dc6 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -50,322 +50,318 @@ def test13(self): def test14(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) - # TODO: this type of error is not processed here for now - # def test15(self): - # self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['pow', '(', 2.0, ',', 3.0, ',', 4.0, ')'])) - - def test16(self): + def test15(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) - def test17(self): + def test16(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) - def test18(self): + def test17(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) - def test19(self): + def test18(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) - def test20(self): + def test19(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) - def test21(self): + def test20(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) - def test22(self): + def test21(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) - def test23(self): + def test22(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) - def test24(self): + def test23(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) - def test25(self): + def test24(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) - def test26(self): + def test25(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) - def test27(self): + def test26(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) - def test28(self): + def test27(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) - def test29(self): + def test28(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, '.', '.', ')'])) - def test30(self): + def test29(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) - def test31(self): + def test30(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', ',', 2.0, '+', '1'])) - def test32(self): + def test31(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '-', 2.0, '+', '1'])) - def test33(self): + def test32(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'sin', '(', 2.0, ')'])) - def test34(self): + def test33(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) - def test35(self): + def test34(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) - def test36(self): + def test35(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) - def test37(self): + def test36(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) - def test38(self): + def test37(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) - def test39(self): + def test38(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) - def test40(self): + def test39(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) - def test41(self): + def test40(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) - def test42(self): + def test41(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) - def test43(self): + def test42(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) - def test44(self): + def test43(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) - def test45(self): + def test44(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) - def test46(self): + def test45(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) - def test47(self): + def test46(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) - def test48(self): + def test47(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) - def test49(self): + def test48(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) - def test50(self): + def test49(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) - def test51(self): + def test50(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) - def test52(self): + def test51(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) - def test53(self): + def test52(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) - def test54(self): + def test53(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) - def test55(self): + def test54(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) - def test56(self): + def test55(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) - def test57(self): + def test56(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) - def test58(self): + def test57(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) - def test59(self): + def test58(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) # matched parentheses - def test60(self): + def test59(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) - def test61(self): + def test60(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) - def test62(self): + def test61(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) - def test63(self): + def test62(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) - def test64(self): + def test63(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, '+', ')', 1.0, ')'])) class ExpectedSuccessTestCase(unittest.TestCase): - def test_1(self): + def test1(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 13.0])) - def test_2(self): + def test2(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([6.0, '-', '(', '-', 13.0, ')'])) - def test_3(self): + def test3(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '-', '-', '-', 1.0])) - def test_4(self): + def test4(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', '+', '-', '-', '-', '+', '-', 1.0])) - def test_5(self): + def test5(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '+', 2.0, '*', 2.0])) - def test_6(self): + def test6(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '+', '(', 2.0, '+', 3.0, '*', 2.0, ')', '*', 3.0])) - def test_7(self): + def test7(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([10.0, '*', '(', 2.0, '+', 1.0, ')'])) - def test_8(self): + def test8(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([10.0, '^', '(', 2.0, '+', 1.0, ')'])) - def test_9(self): + def test9(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([100.0, '/', 3.0, '^', 2.0])) - def test_10(self): + def test10(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([100.0, '/', 3.0, '%', 2.0, '^', 2.0])) - def test_11(self): + def test11(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['pi', '+', 'e'])) - def test_12(self): + def test12(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['log', '(', 'e', ')'])) - def test_13(self): + def test13(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', 2.0, ')'])) - def test_14(self): + def test14(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['log10', '(', 100.0, ')'])) - def test_15(self): + def test15(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( ['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0])) - def test_16(self): + def test16(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( [2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')'])) - def test_17(self): + def test17(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['abs', '(', '-', 5.0, ')'])) - def test_18(self): + def test18(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['round', '(', 123.456789, ')'])) - def test_19(self): + def test19(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([102.0, '%', 12.0, '%', 7.0])) - def test_20(self): + def test20(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([100.0, '/', 4.0, '/', 3.0])) - def test_21(self): + def test21(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([2.0, '^', 3.0, '^', 4.0])) - def test_22(self): + def test22(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( [1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0])) - def test_23(self): + def test23(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( ['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0])) - def test_24(self): + def test24(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( [1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0])) - def test_25(self): + def test25(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['(', 100.0, ')'])) - def test_26(self): + def test26(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([666.0])) - def test_27(self): + def test27(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 0.1])) - def test_28(self): + def test28(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '/', 3.0])) - def test_29(self): + def test29(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([0.1, '*', 2.0, '^', 56.0])) - def test_30(self): + def test30(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['e', '^', 34.0])) - def test_31(self): + def test31(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')'])) - def test_32(self): + def test32(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')', '^', '(', 1.0, '/', 3.0, ')'])) - def test_33(self): + def test33(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', 5.0])) - def test_34(self): + def test34(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', @@ -373,31 +369,31 @@ def test_34(self): 34.0, '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', '-', 'cos', '(', 1.0, ')', '-', '-', 'cos', '(', 0.0, ')', '^', 3.0, ')'])) - def test_35(self): + def test35(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( [2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')'])) - def test_36(self): + def test36(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( ['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')'])) - def test_37(self): + def test37(self): self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '*', '-', 13.0])) - def test_38(self): + def test38(self): self.assertEqual('Formula was validated! ' 'Errors were not found.', calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '-', 13.0, ')'])) - def test_39(self): + def test39(self): self.assertEqual('Formula was validated! ' 'Errors were not found.', calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '(', '-', 13.0, ')', ')'])) # incorrect number of arguments processing in calc - def test_40(self): + def test40(self): self.assertEqual('Formula was validated! ' 'Errors were not found.', calc_obj.validate_parsed_list(['pow', '(', 1.0, ')'])) From 5974dd17e51da6a0277fa2d2b7a90657277bb89a Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 09:36:02 +0300 Subject: [PATCH 09/29] Fix whitespaces and abs --- .idea/workspace.xml | 173 +++++++++++-------- final_task/config.py | 2 +- final_task/pycalc_proc.py | 17 +- final_task/unittests/unittests_validation.py | 3 + 4 files changed, 113 insertions(+), 82 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index e8589f99..f8d22183 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,9 +4,6 @@ - - - - + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + @@ -49,16 +72,16 @@ - + - + - + - + @@ -195,19 +218,19 @@ - - - - - + + + + + - - - - - + + + + + @@ -228,43 +251,43 @@ - - - - - - - - - - - + + - + - + - + + + + + + + + + + - + - + @@ -306,34 +329,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -368,7 +363,15 @@ - + + + + + + + + + @@ -378,11 +381,33 @@ + + + + + + + + + + - - - + + + + + + + + + + + + + + + diff --git a/final_task/config.py b/final_task/config.py index 262fc758..723c4689 100644 --- a/final_task/config.py +++ b/final_task/config.py @@ -46,5 +46,5 @@ ALL_FUNCTIONS_AND_OPERATORS_DICT.update(OPERATORS) -DELIMETERS = ('.', ',', ' ') +DELIMETERS = ('.', ',') ALLOWED_TOKENS = OPERATORS_BEGIN + LETTERS + DIGITS + PARENTHESES + DELIMETERS diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index cb8ec8d5..ae64acbc 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -2,7 +2,7 @@ import sys import inspect -from config import * +from final_task.config import * # т. к. ValueError пишет в лог traceback, переопределим функцию в sys, чтобы в лог писалось только сообщение @@ -134,6 +134,7 @@ def validate_parsed_list(self, parsed_list): print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) counter = 0 # counter for parentheses + was_number = False previous_el = '' for el in parsed_list: @@ -173,6 +174,7 @@ def validate_parsed_list(self, parsed_list): print(message) if isinstance(previous_el, float) or previous_el in MATH_CONSTS: + was_number = True if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): print(message) @@ -181,6 +183,9 @@ def validate_parsed_list(self, parsed_list): if counter != 0: print('ERROR: Wrong number of opened or closed parentheses in formula!') + if not was_number: + print('Formula does not contain numbers!') + return 'Formula was validated! Errors were not found.' @staticmethod @@ -328,19 +333,17 @@ def calc(self, polish_list): def launch_processing(self): self.pre_validate(self.formula_string) - # print('Prevalidation was done!') parsed_list = [] for el in self.parse(self.formula_string): parsed_list.append(el) - # print('Formula was parsed to tokens.') self.validate_parsed_list(parsed_list) - # print('Validation was done!') parsed_list = self.process_unary_operations(parsed_list) - # print('Redundant unary operations were deleted!') polish_list = [] for el in self.sort_to_polish(parsed_list): polish_list.append(el) - # print('Tokens were sorted to polish list!') result = self.calc(polish_list) - # print('Result of calculating of {} is {}'.format(self.formula_string, result)) print(result) + + +obj = PyCalcProcessing('abs') +obj.launch_processing() \ No newline at end of file diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index a2d01dc6..65b52183 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -210,6 +210,9 @@ def test63(self): self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, '+', ')', 1.0, ')'])) + def test64(self): + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['abs'])) + class ExpectedSuccessTestCase(unittest.TestCase): def test1(self): From 006e2ffe148b8f42451585fd56c455ed81e242ad Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 09:40:12 +0300 Subject: [PATCH 10/29] Fix module --- .idea/workspace.xml | 36 +++++++++++++++++++++++------------- final_task/pycalc_proc.py | 2 +- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index f8d22183..2100a8a5 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,9 +2,7 @@ - - @@ -80,13 +103,13 @@ @@ -156,8 +179,8 @@ - - + + - + - + - + - - - - - + + + + + - - - - - + + + + + @@ -258,18 +281,18 @@ - - + + + + + - - + + - - - @@ -339,14 +362,6 @@ - - - - - - - - @@ -373,21 +388,21 @@ - + - - - + + + + + - + - - - - - + + + @@ -401,20 +416,28 @@ - + - - + + + + + + + + + + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 2f1ca443..7a20ce59 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -5,7 +5,7 @@ from config import * -# т. к. ValueError пишет в лог traceback, переопределим функцию в sys, чтобы в лог писалось только сообщение +# ?. ?. ValueError ????? ? ??? traceback, ????????????? ??????? ? sys, ????? ? ??? ???????? ?????? ????????? def excepthook(type, value, traceback): print(value) @@ -22,7 +22,6 @@ def __init__(self, formula_string): def _matched_parentheses(el, count): """ Counter for '(', ')'. - :param el (str): opening or closing parentheses :param count (int): counter of parentheses :return: count (int) @@ -38,93 +37,92 @@ def pre_validate(formula_string): """ Need to apply pre-validation of some errors before parsing to tokens fo more convenient parsing in current version of implementation. - :param formula_string: input formula as text :return: None """ - # проверка, что формула не пустая строка + # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: print('ERROR: Formula should be not empty string!') - # проверяем, что в формуле нет более одного разделителя подряд - # в текущей реализации удобнее сделать это здесь, чтобы упростить дальнейший парсинг на токены + # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? + # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: print('ERROR: Number can not contain more than one delimiter "." !') - # проверка на разрешённые элементы + # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) @staticmethod def parse(formula_string): - number = '' # для накопления чисел - op = '' # для накопления операторов - function = '' # для накопления функций + number = '' # ??? ?????????? ????? + op = '' # ??? ?????????? ?????????? + function = '' # ??? ?????????? ??????? for el in formula_string.strip(): - if el in LETTERS: # обработка функции + if el in LETTERS: # ????????? ??????? function += el.lower() - if op: # выстрелили оператор, если был накоплен + if op: # ?????????? ????????, ???? ??? ???????? yield op op = '' - if number: # выстрелили число, если было накоплено + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' number = '' - elif el in string.digits + '.': # обработка чисел целых и с точкой + elif el in string.digits + '.': # ????????? ????? ????? ? ? ?????? if function: - function += el # продолжаем накапливать функцию, пока не встретим что-то отличное от цифры + function += el # ?????????? ??????????? ???????, ???? ?? ???????? ???-?? ???????? ?? ????? else: number += el - if op: # выстрелили оператор, если был накоплен + if op: # ?????????? ????????, ???? ??? ???????? yield op op = '' - if function: # выстрелили функцию, если было накоплено + if function: # ?????????? ???????, ???? ???? ????????? yield function function = '' - elif el in OPERATORS_BEGIN: # обработка операторов - if el in DOUBLE_OPER_PART1 and not op: # если возможен двойной оператор, добавили и ждём + elif el in OPERATORS_BEGIN: # ????????? ?????????? + if el in DOUBLE_OPER_PART1 and not op: # ???? ???????? ??????? ????????, ???????? ? ???? op += el - elif el in DOUBLE_OPER_PART2 and op: # найден двойной + elif el in DOUBLE_OPER_PART2 and op: # ?????? ??????? op += el - if number: # выстрелили число, если было накоплено + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' number = '' - if function: # выстрелили функцию, если было накоплено + if function: # ?????????? ???????, ???? ???? ????????? yield function function = '' - yield op # выстрелили оператор двойной, когда он был накоплен + yield op # ?????????? ???????? ???????, ????? ?? ??? ???????? op = '' - else: # если оператор одинарный - if op: # если был накоплен на предыдущем шаге - выстрелили, обнулили + else: # ???? ???????? ????????? + if op: # ???? ??? ???????? ?? ?????????? ???? - ??????????, ???????? yield op op = '' - if number: # выстрелили число, если было накоплено + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' number = '' - if function: # выстрелили функцию, если было накоплено + if function: # ?????????? ???????, ???? ???? ????????? yield function function = '' - yield el # довыстрелили одинарный оператор - if number: # выстрелили число, если было накоплено + yield el # ???????????? ????????? ???????? + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' number = '' - if function: # выстрелили функцию, если было накоплено + if function: # ?????????? ???????, ???? ???? ????????? yield function function = '' - elif el in PARENTHESES + (',',): # обработка скобок и запятых (если функция с несколькими аргументами) - if number: # выстрелили число, если было накоплено + elif el in PARENTHESES + (',',): # ????????? ?????? ? ??????? (???? ??????? ? ??????????? ???????????) + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' number = '' - if function: # выстрелили функцию, если было накоплено + if function: # ?????????? ???????, ???? ???? ????????? yield function function = '' - if op: # выстрелили оператор, если был накоплен + if op: # ?????????? ????????, ???? ??? ???????? yield op op = '' - yield el # выстрелили скобку или запятую, как только встретили - if function: # выстрелили функцию, если было накоплено + yield el # ?????????? ?????? ??? ???????, ??? ?????? ????????? + if function: # ?????????? ???????, ???? ???? ????????? yield function - if number: # выстрелили число, если было накоплено + if number: # ?????????? ?????, ???? ???? ????????? yield float(number) if number != '.' else '.' - if op: # выстрелили оператор, если было накоплено + if op: # ?????????? ????????, ???? ???? ????????? yield op def validate_parsed_list(self, parsed_list): @@ -147,7 +145,7 @@ def validate_parsed_list(self, parsed_list): if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: - print('Function or constant {} is not supported by calculator'.format(el)) + print('ERROR: Function or constant {} is not supported by calculator'.format(el)) if previous_el == '(': if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): @@ -184,9 +182,9 @@ def validate_parsed_list(self, parsed_list): print('ERROR: Wrong number of opened or closed parentheses in formula!') if not was_number: - print('Formula does not contain numbers!') + print('ERROR: Formula does not contain numbers!') - return 'Formula was validated! Errors were not found.' + return 'ERROR: Formula was validated! Errors were not found.' @staticmethod def process_unary_operations(validated_list): @@ -200,11 +198,11 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in - (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or + not processed_list) if stack_str: if '-' in stack_str: - if stack_str.count('-') % 2 == 0: # считаем кол-во -, заменяя на + либо на - + if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - if is_unary_plus: stack_str = '' else: @@ -224,39 +222,39 @@ def process_unary_operations(validated_list): @staticmethod def sort_to_polish(parsed_formula): - stack = [] # в качестве стэка используем список + stack = [] # ? ???????? ????? ?????????? ?????? previous_token = '' for token in parsed_formula: - # если элемент - оператор, то отправляем дальше все операторы из стека, - # чей приоритет больше или равен пришедшему, - # до открывающей скобки или опустошения стека. + # ???? ??????? - ????????, ?? ?????????? ?????? ??? ????????? ?? ?????, + # ??? ????????? ?????? ??? ????? ??????????, + # ?? ??????????? ?????? ??? ??????????? ?????. if token in ALL_FUNCTIONS_AND_OPERATORS_DICT: if token == '-' and previous_token in ('(', ',', '') + tuple(BINARY_OPERATORS.keys()): yield 0.0 stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] - and token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and + token != '^'): yield stack.pop() stack.append(token) elif token == ")": - # если элемент - закрывающая скобка, выдаём все элементы из стека, до открывающей скобки, - # а открывающую скобку выкидываем из стека. + # ???? ??????? - ??????????? ??????, ?????? ??? ???????? ?? ?????, ?? ??????????? ??????, + # ? ??????????? ?????? ?????????? ?? ?????. while stack: x = stack.pop() if x == "(": break yield x elif token == "(": - # если элемент - открывающая скобка, просто положим её в стек + # ???? ??????? - ??????????? ??????, ?????? ??????? ?? ? ???? stack.append(token) - elif token == ",": # конец аргумента - # выдаём все операторы из стека до открывающей скобки + elif token == ",": # ????? ????????? + # ?????? ??? ????????? ?? ????? ?? ??????????? ?????? while stack and stack[-1] != "(": yield stack.pop() else: - # если элемент - число или константа, отправим его сразу на выход + # ???? ??????? - ????? ??? ?????????, ???????? ??? ????? ?? ????? yield token previous_token = token while stack: @@ -280,14 +278,14 @@ def calc(self, polish_list): arguments = [] func_name = getattr(math, token) - # TODO пока костыль с log + # TODO ???? ??????? ? log if func_name != math.log: number_of_args = self._get_num_args(func_name) for i in range(number_of_args): if stack: arguments.insert(0, stack.pop()) else: - # т. к. log имеет переменное кол-во аргументов отдельная обработка + # ?. ?. log ????? ?????????? ???-?? ?????????? ????????? ????????? index_current_log_token = polish_list.index(token) try: next_token_after_log = polish_list[index_current_log_token + 1] @@ -308,19 +306,19 @@ def calc(self, polish_list): except TypeError: print('ERROR: Formula contains incorrect number of arguments in function.') - stack.append(function_result) # вычисляем оператор, возвращаем в стек + stack.append(function_result) # ????????? ????????, ?????????? ? ???? arguments = [] elif token in BUILT_IN_FUNCTIONS: - x = stack.pop() # забираем 1 числo из стека + x = stack.pop() # ???????? 1 ????o ?? ????? # TODO how to get built-in attr automatically if token == 'abs': stack.append(abs(x)) elif token == 'round': stack.append(round(x)) - elif token in OPERATORS: # если приходящий элемент - оператор, - y, x = stack.pop(), stack.pop() # забираем 2 числа из стека - stack.append(OPERATORS[token][1](x, y)) # вычисляем оператор, возвращаем в стек + elif token in OPERATORS: # ???? ?????????? ??????? - ????????, + y, x = stack.pop(), stack.pop() # ???????? 2 ????? ?? ????? + stack.append(OPERATORS[token][1](x, y)) # ????????? ????????, ?????????? ? ???? elif token in MATH_CONSTS: stack.append(getattr(math, token)) else: @@ -329,7 +327,7 @@ def calc(self, polish_list): if len(stack) > 1: print('ERROR: Formula contains incorrect number of arguments in function.') - return stack[0] # результат вычисления - единственный элемент в стеке + return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? def launch_processing(self): self.pre_validate(self.formula_string) @@ -343,7 +341,3 @@ def launch_processing(self): polish_list.append(el) result = self.calc(polish_list) print(result) - - -obj = PyCalcProcessing('abs') -obj.launch_processing() \ No newline at end of file From b86fc5099833491274e4eeaddaf48ae220697f48 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 16:09:30 +0300 Subject: [PATCH 12/29] Fix whitespaces --- .idea/workspace.xml | 33 ++++++++++++++++++--------------- final_task/config.py | 2 +- final_task/pycalc_proc.py | 12 +++++++++--- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1465e595..1b472dfb 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,9 +2,7 @@ - - - + - + @@ -428,16 +429,18 @@ - - - + + + + + - - + + diff --git a/final_task/config.py b/final_task/config.py index 723c4689..262fc758 100644 --- a/final_task/config.py +++ b/final_task/config.py @@ -46,5 +46,5 @@ ALL_FUNCTIONS_AND_OPERATORS_DICT.update(OPERATORS) -DELIMETERS = ('.', ',') +DELIMETERS = ('.', ',', ' ') ALLOWED_TOKENS = OPERATORS_BEGIN + LETTERS + DIGITS + PARENTHESES + DELIMETERS diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 7a20ce59..b9af2f8c 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -1,6 +1,7 @@ # -*- coding: Windows-1251 -*- import sys import inspect +import re from config import * @@ -16,7 +17,7 @@ def excepthook(type, value, traceback): class PyCalcProcessing(object): def __init__(self, formula_string): - self.formula_string = formula_string + self.formula_string = re.sub(' +', ' ', formula_string) @staticmethod def _matched_parentheses(el, count): @@ -47,6 +48,9 @@ def pre_validate(formula_string): # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: print('ERROR: Number can not contain more than one delimiter "." !') + # ???????? ?? ?????? ? ??????? ?????????? + if re.search('/ /|< =|> =|= =|! =', formula_string): + print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: @@ -140,6 +144,9 @@ def validate_parsed_list(self, parsed_list): message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) + if isinstance(el, float) or el in MATH_CONSTS and was_number is False: + was_number = True + if el == '.': print('ERROR: Single delimiter is prohibited in formula!') @@ -172,7 +179,6 @@ def validate_parsed_list(self, parsed_list): print(message) if isinstance(previous_el, float) or previous_el in MATH_CONSTS: - was_number = True if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): print(message) @@ -181,7 +187,7 @@ def validate_parsed_list(self, parsed_list): if counter != 0: print('ERROR: Wrong number of opened or closed parentheses in formula!') - if not was_number: + if was_number is False: print('ERROR: Formula does not contain numbers!') return 'ERROR: Formula was validated! Errors were not found.' From 91c647a704b7d67d911c93f1c101de652cce41f1 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 22:34:37 +0300 Subject: [PATCH 13/29] Fix whitespaces 2 --- .idea/workspace.xml | 48 ++++++++++++++++---------- final_task/pycalc_proc.py | 10 +++--- final_task/unittests/unittests_calc.py | 4 +-- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 1b472dfb..cc557e40 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,8 @@ - + - + - + @@ -363,16 +375,6 @@ - - - - - - - - - - @@ -437,10 +439,20 @@ + + + + + + + + + + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index b9af2f8c..fb7f1e6c 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -51,6 +51,8 @@ def pre_validate(formula_string): # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') + if re.search('\d\s\d', formula_string): + print('ERROR: space is not allowed between digits!') # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: @@ -204,8 +206,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or - not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) + or not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - @@ -240,8 +242,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and - token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] + and token != '^'): yield stack.pop() stack.append(token) elif token == ")": diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py index 3cc54ee8..bfda9fd6 100644 --- a/final_task/unittests/unittests_calc.py +++ b/final_task/unittests/unittests_calc.py @@ -131,9 +131,7 @@ def test35(self): '-', 'log10', '*', 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-'])) def test36(self): - self.assertEqual(math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos - (math.log10(43.0))))+math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)-- - math.cos(0.0)**3.0), + self.assertEqual(math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos(math.log10(43.0))))+math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)--math.cos(0.0)**3.0), calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', 'cos', '+', 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, '^', 'cos', '+', 'sin'])) From 50f4845c0c5e758ba30b4cf4cfc6f079a04b7909 Mon Sep 17 00:00:00 2001 From: alinonax Date: Sun, 2 Jun 2019 23:26:09 +0300 Subject: [PATCH 14/29] Fix minimal requirements 2 --- .idea/workspace.xml | 74 +++++++++++++------------- final_task/pycalc_proc.py | 6 +-- final_task/unittests/unittests_calc.py | 12 +++-- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index cc557e40..d33977fa 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,6 +2,7 @@ + @@ -17,8 +18,8 @@ - - + + @@ -29,8 +30,8 @@ - - + + @@ -65,8 +66,8 @@ - - + + @@ -103,6 +104,7 @@ ',', function_result numbers + was v @@ -119,15 +121,15 @@ - + - + @@ -306,34 +308,34 @@ - + - + - + - + - + - + - + - + @@ -409,16 +411,6 @@ - - - - - - - - - - @@ -439,10 +431,20 @@ + + + + + + + + + + - - + + @@ -451,8 +453,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index fb7f1e6c..9ed93f75 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -192,7 +192,7 @@ def validate_parsed_list(self, parsed_list): if was_number is False: print('ERROR: Formula does not contain numbers!') - return 'ERROR: Formula was validated! Errors were not found.' + return 'Formula was validated! Errors were not found.' @staticmethod def process_unary_operations(validated_list): @@ -206,8 +206,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) - or not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in + (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py index bfda9fd6..4286200b 100644 --- a/final_task/unittests/unittests_calc.py +++ b/final_task/unittests/unittests_calc.py @@ -126,15 +126,17 @@ def test34(self): '+', 1.0, '+', 3.0, 2.0, '^', 'log', '+'])) def test35(self): - self.assertEqual(10.0*math.e**0.0*math.log10(.4 -5.0/ -0.1-10.0) - -abs(-53.0/10.0) + -5.0, + self.assertEqual(10.0*math.e**0.0*math.log10(.4 - 5.0 / -0.1-10.0) - -abs(-53.0/10.0) + -5.0, calc_obj.calc([10.0, 'e', 0.0, '^', '*', 0.4, 5.0, 0.0, 0.1, '-', '/', '-', 10.0, '-', 'log10', '*', 0.0, 53.0, 10.0, '/', '-', 'abs', '+', 5.0, '-'])) def test36(self): - self.assertEqual(math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos(math.log10(43.0))))+math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)--math.cos(0.0)**3.0), - calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, - 'log10', 'cos', 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', - 'cos', '+', 'cos', '-', 1.0, 'cos', '+', 0.0, 3.0, '^', 'cos', '+', 'sin'])) + self.assertEqual( + math.sin(-math.cos(-math.sin(3.0)-math.cos(-math.sin(-3.0*5.0)-math.sin(math.cos(math.log10(43.0)))) + + math.cos(math.sin(math.sin(34.0-2.0**2.0))))--math.cos(1.0)--math.cos(0.0)**3.0), + calc_obj.calc([0.0, 0.0, 3.0, 'sin', '-', 0.0, 0.0, 3.0, 5.0, '*', '-', 'sin', '-', 43.0, 'log10', 'cos', + 'sin', '-', 'cos', '-', 34.0, 2.0, 2.0, '^', '-', 'sin', 'sin', 'cos', '+', 'cos', '-', 1.0, + 'cos', '+', 0.0, 3.0, '^', 'cos', '+', 'sin'])) def test37(self): self.assertEqual(2.0**(2.0**2.0*2.0**2.0), calc_obj.calc([2.0, 2.0, 2.0, '^', 2.0, 2.0, '^', '*', '^'])) From 7785c6e70d97c99b8d6eae221fad30539e19a351 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 08:53:17 +0300 Subject: [PATCH 15/29] Fix minimal requirements 3 --- .idea/workspace.xml | 80 ++------------------------------------- final_task/pycalc_proc.py | 2 +- 2 files changed, 5 insertions(+), 77 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index d33977fa..26309301 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,9 +2,7 @@ - - @@ -453,8 +381,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 9ed93f75..d7686fe7 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -51,7 +51,7 @@ def pre_validate(formula_string): # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') - if re.search('\d\s\d', formula_string): + if re.search(r'\d\\s\d', formula_string): print('ERROR: space is not allowed between digits!') # ???????? ?? ??????????? ???????? for el in formula_string.strip(): From 260035db7984bdf686a8e197ac93989c73c223ec Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 08:58:19 +0300 Subject: [PATCH 16/29] Fix minimal requirements 4 --- .idea/workspace.xml | 8 ++++---- final_task/pycalc_proc.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 26309301..d9c15ac2 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,8 +16,8 @@ - - + + @@ -381,8 +381,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index d7686fe7..7e4beb86 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -51,7 +51,7 @@ def pre_validate(formula_string): # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') - if re.search(r'\d\\s\d', formula_string): + if re.search(r'\d\s\d', formula_string): print('ERROR: space is not allowed between digits!') # ???????? ?? ??????????? ???????? for el in formula_string.strip(): From 44f7dff87987f714abb22b3414e00649759d0d44 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 09:39:03 +0300 Subject: [PATCH 17/29] Fix error handling --- .idea/workspace.xml | 65 +++++++++++-------- final_task/pycalc_proc.py | 52 +++++++-------- .../unittests/unittests_prevalidation.py | 56 ++++++++-------- 3 files changed, 92 insertions(+), 81 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index d9c15ac2..00ceb42d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,6 +3,7 @@ + - + - - + + - + + + + + + + + + + + @@ -33,9 +44,11 @@ function_result numbers was v + Raises(ValueError + Equal(True @@ -45,7 +58,6 @@ - - - - - - - - - - @@ -373,21 +378,27 @@ - - - + - - + + - + + + + + + + + + \ No newline at end of file diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 7e4beb86..d3d0d3b6 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -1,19 +1,11 @@ # -*- coding: Windows-1251 -*- -import sys import inspect import re +import builtins from config import * -# ?. ?. ValueError ????? ? ??? traceback, ????????????? ??????? ? sys, ????? ? ??? ???????? ?????? ????????? -def excepthook(type, value, traceback): - print(value) - - -sys.excepthook = excepthook - - class PyCalcProcessing(object): def __init__(self, formula_string): @@ -41,22 +33,29 @@ def pre_validate(formula_string): :param formula_string: input formula as text :return: None """ + was_error = False # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: print('ERROR: Formula should be not empty string!') + return True # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: print('ERROR: Number can not contain more than one delimiter "." !') + was_error = True # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') + was_error = True if re.search(r'\d\s\d', formula_string): print('ERROR: space is not allowed between digits!') + was_error = True # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) + was_error = True + return was_error @staticmethod def parse(formula_string): @@ -286,7 +285,6 @@ def calc(self, polish_list): arguments = [] func_name = getattr(math, token) - # TODO ???? ??????? ? log if func_name != math.log: number_of_args = self._get_num_args(func_name) for i in range(number_of_args): @@ -319,11 +317,8 @@ def calc(self, polish_list): elif token in BUILT_IN_FUNCTIONS: x = stack.pop() # ???????? 1 ????o ?? ????? - # TODO how to get built-in attr automatically - if token == 'abs': - stack.append(abs(x)) - elif token == 'round': - stack.append(round(x)) + func_name = getattr(builtins, token) + stack.append(func_name(x)) elif token in OPERATORS: # ???? ?????????? ??????? - ????????, y, x = stack.pop(), stack.pop() # ???????? 2 ????? ?? ????? stack.append(OPERATORS[token][1](x, y)) # ????????? ????????, ?????????? ? ???? @@ -338,14 +333,19 @@ def calc(self, polish_list): return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? def launch_processing(self): - self.pre_validate(self.formula_string) - parsed_list = [] - for el in self.parse(self.formula_string): - parsed_list.append(el) - self.validate_parsed_list(parsed_list) - parsed_list = self.process_unary_operations(parsed_list) - polish_list = [] - for el in self.sort_to_polish(parsed_list): - polish_list.append(el) - result = self.calc(polish_list) - print(result) + was_error = self.pre_validate(self.formula_string) + if not was_error: + parsed_list = [] + for el in self.parse(self.formula_string): + parsed_list.append(el) + self.validate_parsed_list(parsed_list) + parsed_list = self.process_unary_operations(parsed_list) + polish_list = [] + for el in self.sort_to_polish(parsed_list): + polish_list.append(el) + result = self.calc(polish_list) + print(result) + + + # obj = PyCalcProcessing('12+3') + # obj.launch_processing() diff --git a/final_task/unittests/unittests_prevalidation.py b/final_task/unittests/unittests_prevalidation.py index 0345649c..35f9bfe3 100644 --- a/final_task/unittests/unittests_prevalidation.py +++ b/final_task/unittests/unittests_prevalidation.py @@ -8,89 +8,89 @@ class TestParsingNegativeCases(unittest.TestCase): def test1(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+&6.0')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1+&6.0')) def test86(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+6.0&')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1+6.0&')) def test87(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('_5+6')) + self.assertEqual(True, lambda: calc_obj.pre_validate('_5+6')) def test88(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('5_+6')) + self.assertEqual(True, lambda: calc_obj.pre_validate('5_+6')) def test89(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1>=@')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1>=@')) def test90(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1@>=9')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1@>=9')) def test91(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('-2+(#+1)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('-2+(#+1)')) def test92(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('abs(@)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('abs(@)')) def test93(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('round(@)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('round(@)')) def test94(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(5+@)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('sin(5+@)')) def test95(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(@+5)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('sin(@+5)')) def test96(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('(5+@)/7')) + self.assertEqual(True, lambda: calc_obj.pre_validate('(5+@)/7')) def test97(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+#+6')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1+#+6')) def test98(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+#8+6')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1+#8+6')) # Number with more than one delimiter def test99(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1..5')) def test100(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('-1..5')) + self.assertEqual(True, lambda: calc_obj.pre_validate('-1..5')) def test101(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5+3..7')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1..5+3..7')) def test102(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1..5+3')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1..5+3')) def test103(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('3+1..5')) + self.assertEqual(True, lambda: calc_obj.pre_validate('3+1..5')) def test104(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1+1..5-4')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1+1..5-4')) def test105(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('sin(1..5)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('sin(1..5)')) def test106(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('(1..5+3)/2')) + self.assertEqual(True, lambda: calc_obj.pre_validate('(1..5+3)/2')) def test107(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('round(1..5)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('round(1..5)')) def test108(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('abs(-1..5)')) + self.assertEqual(True, lambda: calc_obj.pre_validate('abs(-1..5)')) def test109(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('1>=1..5')) + self.assertEqual(True, lambda: calc_obj.pre_validate('1>=1..5')) def test110(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate('')) + self.assertEqual(True, lambda: calc_obj.pre_validate('')) def test111(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate(None)) + self.assertEqual(True, lambda: calc_obj.pre_validate(None)) def test112(self): - self.assertRaises(ValueError, lambda: calc_obj.pre_validate(18)) + self.assertEqual(True, lambda: calc_obj.pre_validate(18)) if __name__ == '__main__': From 31370444285d9cb26886622e1c8fc6ee7c3f57f9 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 09:43:33 +0300 Subject: [PATCH 18/29] Fix error handling 2 --- .idea/workspace.xml | 47 +++++++++++++++++++-------------------- final_task/pycalc_proc.py | 4 ---- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 00ceb42d..e428a66b 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,7 +3,6 @@ - - + - - + + @@ -26,7 +25,7 @@ - + @@ -65,14 +64,14 @@ - - - + @@ -331,7 +330,7 @@ - + @@ -349,7 +348,7 @@ - + @@ -359,7 +358,7 @@ - + @@ -369,7 +368,7 @@ - + @@ -382,16 +381,6 @@ - - - - - - - - - - @@ -400,5 +389,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index d3d0d3b6..99a888ff 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -345,7 +345,3 @@ def launch_processing(self): polish_list.append(el) result = self.calc(polish_list) print(result) - - - # obj = PyCalcProcessing('12+3') - # obj.launch_processing() From 64347dd0962f010d92a0817068664602f8fcbfb1 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 10:10:45 +0300 Subject: [PATCH 19/29] Fix error handling 3 --- .idea/workspace.xml | 17 ++++++++--------- final_task/pycalc_proc.py | 31 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index e428a66b..8f54c324 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,8 +16,8 @@ - - + + @@ -69,9 +69,8 @@ - - - + - + @@ -391,8 +390,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 99a888ff..a32f45e1 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -59,9 +59,7 @@ def pre_validate(formula_string): @staticmethod def parse(formula_string): - number = '' # ??? ?????????? ????? - op = '' # ??? ?????????? ?????????? - function = '' # ??? ?????????? ??????? + number = op = function = '' # ??? ?????????? ?????, ??????????, ??????? for el in formula_string.strip(): if el in LETTERS: # ????????? ??????? function += el.lower() @@ -123,6 +121,7 @@ def parse(formula_string): yield op op = '' yield el # ?????????? ?????? ??? ???????, ??? ?????? ????????? + if function: # ?????????? ???????, ???? ???? ????????? yield function if number: # ?????????? ?????, ???? ???? ????????? @@ -131,15 +130,18 @@ def parse(formula_string): yield op def validate_parsed_list(self, parsed_list): + was_error = False + counter = 0 # counter for parentheses + was_number = False + previous_el = '' + if parsed_list[-1] in OPERATORS: print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + was_error = True if parsed_list[0] in BINARY_OPERATORS: print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) + was_error = True - counter = 0 # counter for parentheses - was_number = False - - previous_el = '' for el in parsed_list: counter = self._matched_parentheses(el, counter) @@ -150,22 +152,27 @@ def validate_parsed_list(self, parsed_list): if el == '.': print('ERROR: Single delimiter is prohibited in formula!') + was_error = True if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: print('ERROR: Function or constant {} is not supported by calculator'.format(el)) + was_error = True if previous_el == '(': if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): print(message) + was_error = True if previous_el == ')': if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): print(message) + was_error = True if previous_el == ',': if el in (')', ',', '.'): print(message) + was_error = True if previous_el in UNARY_OPERATORS: if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): @@ -174,24 +181,29 @@ def validate_parsed_list(self, parsed_list): if previous_el in BINARY_OPERATORS: if el in ((')', ',',) + tuple(BINARY_OPERATORS.keys())): print(message) + was_error = True if previous_el in ALL_FUNCTIONS: if el != '(': print(message) + was_error = True if isinstance(previous_el, float) or previous_el in MATH_CONSTS: if el in (('(',) + ALL_FUNCTIONS_AND_CONSTS) or isinstance(el, float): print(message) + was_error = True previous_el = el if counter != 0: print('ERROR: Wrong number of opened or closed parentheses in formula!') + was_error = True if was_number is False: print('ERROR: Formula does not contain numbers!') + was_error = True - return 'Formula was validated! Errors were not found.' + return was_error @staticmethod def process_unary_operations(validated_list): @@ -338,7 +350,8 @@ def launch_processing(self): parsed_list = [] for el in self.parse(self.formula_string): parsed_list.append(el) - self.validate_parsed_list(parsed_list) + was_error = self.validate_parsed_list(parsed_list) + if not was_error: parsed_list = self.process_unary_operations(parsed_list) polish_list = [] for el in self.sort_to_polish(parsed_list): From 75ded7d61d81da4a0acf432e7f97a663f2cead1e Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 10:25:18 +0300 Subject: [PATCH 20/29] Fix error handling 4 --- .idea/workspace.xml | 16 +++++-------- final_task/pycalc_proc.py | 50 ++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 8f54c324..b1fdee79 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,11 +16,9 @@ - - - - - + + + @@ -390,11 +388,9 @@ - - - - - + + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index a32f45e1..93133aa0 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -15,6 +15,7 @@ def __init__(self, formula_string): def _matched_parentheses(el, count): """ Counter for '(', ')'. + :param el (str): opening or closing parentheses :param count (int): counter of parentheses :return: count (int) @@ -30,18 +31,19 @@ def pre_validate(formula_string): """ Need to apply pre-validation of some errors before parsing to tokens fo more convenient parsing in current version of implementation. + :param formula_string: input formula as text :return: None """ was_error = False # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: - print('ERROR: Formula should be not empty string!') + print('Formula should be not empty string!') return True # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: - print('ERROR: Number can not contain more than one delimiter "." !') + print('Number can not contain more than one delimiter "." !') was_error = True # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): @@ -53,7 +55,7 @@ def pre_validate(formula_string): # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: - print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) + print('Formula contains incorrect symbol "{}"'.format(el)) was_error = True return was_error @@ -136,27 +138,27 @@ def validate_parsed_list(self, parsed_list): previous_el = '' if parsed_list[-1] in OPERATORS: - print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + print('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) was_error = True if parsed_list[0] in BINARY_OPERATORS: - print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) + print('Formula can not start with binary operator "{}"'.format(parsed_list[0])) was_error = True for el in parsed_list: counter = self._matched_parentheses(el, counter) - message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) + message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) if isinstance(el, float) or el in MATH_CONSTS and was_number is False: was_number = True if el == '.': - print('ERROR: Single delimiter is prohibited in formula!') + print('Single delimiter is prohibited in formula!') was_error = True if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: - print('ERROR: Function or constant {} is not supported by calculator'.format(el)) + print('Function or constant {} is not supported by calculator'.format(el)) was_error = True if previous_el == '(': @@ -196,11 +198,11 @@ def validate_parsed_list(self, parsed_list): previous_el = el if counter != 0: - print('ERROR: Wrong number of opened or closed parentheses in formula!') + print('Wrong number of opened or closed parentheses in formula!') was_error = True if was_number is False: - print('ERROR: Formula does not contain numbers!') + print('Formula does not contain numbers!') was_error = True return was_error @@ -217,8 +219,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in - (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or + not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - @@ -253,8 +255,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] - and token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and + token != '^'): yield stack.pop() stack.append(token) elif token == ")": @@ -322,7 +324,7 @@ def calc(self, polish_list): try: function_result = func_name(*tuple(arguments)) except TypeError: - print('ERROR: Formula contains incorrect number of arguments in function.') + print('Formula contains incorrect number of arguments in function.') stack.append(function_result) # ????????? ????????, ?????????? ? ???? arguments = [] @@ -340,7 +342,7 @@ def calc(self, polish_list): stack.append(token) if len(stack) > 1: - print('ERROR: Formula contains incorrect number of arguments in function.') + print('Formula contains incorrect number of arguments in function.') return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? @@ -350,11 +352,11 @@ def launch_processing(self): parsed_list = [] for el in self.parse(self.formula_string): parsed_list.append(el) - was_error = self.validate_parsed_list(parsed_list) - if not was_error: - parsed_list = self.process_unary_operations(parsed_list) - polish_list = [] - for el in self.sort_to_polish(parsed_list): - polish_list.append(el) - result = self.calc(polish_list) - print(result) + was_error = self.validate_parsed_list(parsed_list) + if not was_error: + parsed_list = self.process_unary_operations(parsed_list) + polish_list = [] + for el in self.sort_to_polish(parsed_list): + polish_list.append(el) + result = self.calc(polish_list) + print(result) From 7598b1376c0a877fdba1fd2bb699605dd4911730 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 10:29:42 +0300 Subject: [PATCH 21/29] Fix error handling 5 --- .idea/workspace.xml | 16 ++++++++----- final_task/pycalc_proc.py | 50 +++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b1fdee79..4fc863d4 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,9 +16,11 @@ - - - + + + + + @@ -388,9 +390,11 @@ - - - + + + + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 93133aa0..a32f45e1 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -15,7 +15,6 @@ def __init__(self, formula_string): def _matched_parentheses(el, count): """ Counter for '(', ')'. - :param el (str): opening or closing parentheses :param count (int): counter of parentheses :return: count (int) @@ -31,19 +30,18 @@ def pre_validate(formula_string): """ Need to apply pre-validation of some errors before parsing to tokens fo more convenient parsing in current version of implementation. - :param formula_string: input formula as text :return: None """ was_error = False # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: - print('Formula should be not empty string!') + print('ERROR: Formula should be not empty string!') return True # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: - print('Number can not contain more than one delimiter "." !') + print('ERROR: Number can not contain more than one delimiter "." !') was_error = True # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): @@ -55,7 +53,7 @@ def pre_validate(formula_string): # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: - print('Formula contains incorrect symbol "{}"'.format(el)) + print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) was_error = True return was_error @@ -138,27 +136,27 @@ def validate_parsed_list(self, parsed_list): previous_el = '' if parsed_list[-1] in OPERATORS: - print('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) was_error = True if parsed_list[0] in BINARY_OPERATORS: - print('Formula can not start with binary operator "{}"'.format(parsed_list[0])) + print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) was_error = True for el in parsed_list: counter = self._matched_parentheses(el, counter) - message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) + message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) if isinstance(el, float) or el in MATH_CONSTS and was_number is False: was_number = True if el == '.': - print('Single delimiter is prohibited in formula!') + print('ERROR: Single delimiter is prohibited in formula!') was_error = True if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: - print('Function or constant {} is not supported by calculator'.format(el)) + print('ERROR: Function or constant {} is not supported by calculator'.format(el)) was_error = True if previous_el == '(': @@ -198,11 +196,11 @@ def validate_parsed_list(self, parsed_list): previous_el = el if counter != 0: - print('Wrong number of opened or closed parentheses in formula!') + print('ERROR: Wrong number of opened or closed parentheses in formula!') was_error = True if was_number is False: - print('Formula does not contain numbers!') + print('ERROR: Formula does not contain numbers!') was_error = True return was_error @@ -219,8 +217,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or - not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in + (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - @@ -255,8 +253,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and - token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] + and token != '^'): yield stack.pop() stack.append(token) elif token == ")": @@ -324,7 +322,7 @@ def calc(self, polish_list): try: function_result = func_name(*tuple(arguments)) except TypeError: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') stack.append(function_result) # ????????? ????????, ?????????? ? ???? arguments = [] @@ -342,7 +340,7 @@ def calc(self, polish_list): stack.append(token) if len(stack) > 1: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? @@ -352,11 +350,11 @@ def launch_processing(self): parsed_list = [] for el in self.parse(self.formula_string): parsed_list.append(el) - was_error = self.validate_parsed_list(parsed_list) - if not was_error: - parsed_list = self.process_unary_operations(parsed_list) - polish_list = [] - for el in self.sort_to_polish(parsed_list): - polish_list.append(el) - result = self.calc(polish_list) - print(result) + was_error = self.validate_parsed_list(parsed_list) + if not was_error: + parsed_list = self.process_unary_operations(parsed_list) + polish_list = [] + for el in self.sort_to_polish(parsed_list): + polish_list.append(el) + result = self.calc(polish_list) + print(result) From d7f52325d6b4b237f1ddabc8c252faad36158871 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 10:31:48 +0300 Subject: [PATCH 22/29] Fix error handling 6 --- .idea/workspace.xml | 8 +++--- final_task/pycalc_proc.py | 52 ++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4fc863d4..5b33f28a 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,8 +16,8 @@ - - + + @@ -390,8 +390,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index a32f45e1..1bb7a1bf 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -15,6 +15,7 @@ def __init__(self, formula_string): def _matched_parentheses(el, count): """ Counter for '(', ')'. + :param el (str): opening or closing parentheses :param count (int): counter of parentheses :return: count (int) @@ -30,18 +31,19 @@ def pre_validate(formula_string): """ Need to apply pre-validation of some errors before parsing to tokens fo more convenient parsing in current version of implementation. + :param formula_string: input formula as text :return: None """ was_error = False # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: - print('ERROR: Formula should be not empty string!') + print('Formula should be not empty string!') return True # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: - print('ERROR: Number can not contain more than one delimiter "." !') + print('Number can not contain more than one delimiter "." !') was_error = True # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): @@ -53,7 +55,7 @@ def pre_validate(formula_string): # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: - print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) + print('Formula contains incorrect symbol "{}"'.format(el)) was_error = True return was_error @@ -136,27 +138,27 @@ def validate_parsed_list(self, parsed_list): previous_el = '' if parsed_list[-1] in OPERATORS: - print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + print('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) was_error = True if parsed_list[0] in BINARY_OPERATORS: - print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) + print('Formula can not start with binary operator "{}"'.format(parsed_list[0])) was_error = True for el in parsed_list: counter = self._matched_parentheses(el, counter) - message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) + message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) if isinstance(el, float) or el in MATH_CONSTS and was_number is False: was_number = True if el == '.': - print('ERROR: Single delimiter is prohibited in formula!') + print('Single delimiter is prohibited in formula!') was_error = True if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: - print('ERROR: Function or constant {} is not supported by calculator'.format(el)) + print('Function or constant {} is not supported by calculator'.format(el)) was_error = True if previous_el == '(': @@ -196,11 +198,11 @@ def validate_parsed_list(self, parsed_list): previous_el = el if counter != 0: - print('ERROR: Wrong number of opened or closed parentheses in formula!') + print('Wrong number of opened or closed parentheses in formula!') was_error = True if was_number is False: - print('ERROR: Formula does not contain numbers!') + print('Formula does not contain numbers!') was_error = True return was_error @@ -217,8 +219,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in - (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or + not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - @@ -253,8 +255,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] - and token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and + token != '^'): yield stack.pop() stack.append(token) elif token == ")": @@ -322,7 +324,7 @@ def calc(self, polish_list): try: function_result = func_name(*tuple(arguments)) except TypeError: - print('ERROR: Formula contains incorrect number of arguments in function.') + print('Formula contains incorrect number of arguments in function.') stack.append(function_result) # ????????? ????????, ?????????? ? ???? arguments = [] @@ -340,21 +342,21 @@ def calc(self, polish_list): stack.append(token) if len(stack) > 1: - print('ERROR: Formula contains incorrect number of arguments in function.') + print('Formula contains incorrect number of arguments in function.') return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? def launch_processing(self): + parsed_list = [] + polish_list = [] was_error = self.pre_validate(self.formula_string) if not was_error: - parsed_list = [] for el in self.parse(self.formula_string): parsed_list.append(el) - was_error = self.validate_parsed_list(parsed_list) - if not was_error: - parsed_list = self.process_unary_operations(parsed_list) - polish_list = [] - for el in self.sort_to_polish(parsed_list): - polish_list.append(el) - result = self.calc(polish_list) - print(result) + was_error = self.validate_parsed_list(parsed_list) + if not was_error: + parsed_list = self.process_unary_operations(parsed_list) + for el in self.sort_to_polish(parsed_list): + polish_list.append(el) + result = self.calc(polish_list) + print(result) From d39c1bb24eacb107c0c6c0714edd25c173b41a9e Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 10:41:47 +0300 Subject: [PATCH 23/29] Fix error handling 7 --- .idea/workspace.xml | 8 ++++---- final_task/pycalc_proc.py | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 5b33f28a..557a6443 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -16,8 +16,8 @@ - - + + @@ -390,8 +390,8 @@ - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index 1bb7a1bf..f853e3b1 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -38,12 +38,12 @@ def pre_validate(formula_string): was_error = False # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: - print('Formula should be not empty string!') + print('ERROR: Formula should be not empty string!') return True # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? if '..' in formula_string: - print('Number can not contain more than one delimiter "." !') + print('ERROR: Number can not contain more than one delimiter "." !') was_error = True # ???????? ?? ?????? ? ??????? ?????????? if re.search('/ /|< =|> =|= =|! =', formula_string): @@ -55,7 +55,7 @@ def pre_validate(formula_string): # ???????? ?? ??????????? ???????? for el in formula_string.strip(): if el not in ALLOWED_TOKENS: - print('Formula contains incorrect symbol "{}"'.format(el)) + print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) was_error = True return was_error @@ -138,27 +138,27 @@ def validate_parsed_list(self, parsed_list): previous_el = '' if parsed_list[-1] in OPERATORS: - print('Operator at the end of the formula: "{}" '.format(parsed_list[-1])) + print('ERROR: Operator at the end of the formula: "{}" '.format(parsed_list[-1])) was_error = True if parsed_list[0] in BINARY_OPERATORS: - print('Formula can not start with binary operator "{}"'.format(parsed_list[0])) + print('ERROR: Formula can not start with binary operator "{}"'.format(parsed_list[0])) was_error = True for el in parsed_list: counter = self._matched_parentheses(el, counter) - message = 'After {} element {} is forbidden!'.format(str(previous_el), str(el)) + message = 'ERROR: After {} element {} is forbidden!'.format(str(previous_el), str(el)) if isinstance(el, float) or el in MATH_CONSTS and was_number is False: was_number = True if el == '.': - print('Single delimiter is prohibited in formula!') + print('ERROR: Single delimiter is prohibited in formula!') was_error = True if isinstance(el, str) and el[0] in LETTERS: if el.lower() not in ALL_FUNCTIONS_AND_CONSTS: - print('Function or constant {} is not supported by calculator'.format(el)) + print('ERROR: Function or constant {} is not supported by calculator'.format(el)) was_error = True if previous_el == '(': @@ -198,11 +198,11 @@ def validate_parsed_list(self, parsed_list): previous_el = el if counter != 0: - print('Wrong number of opened or closed parentheses in formula!') + print('ERROR: Wrong number of opened or closed parentheses in formula!') was_error = True if was_number is False: - print('Formula does not contain numbers!') + print('ERROR: Formula does not contain numbers!') was_error = True return was_error @@ -219,8 +219,8 @@ def process_unary_operations(validated_list): if el in UNARY_OPERATORS: stack_str += el else: - is_unary_plus = ((processed_list and processed_list[-1] in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or - not processed_list) + is_unary_plus = ((processed_list and processed_list[-1] + in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) if stack_str: if '-' in stack_str: if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - @@ -255,8 +255,8 @@ def sort_to_polish(parsed_formula): stack.append(token) else: while (stack and stack[-1] != "(" and - ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] and - token != '^'): + ALL_FUNCTIONS_AND_OPERATORS_DICT[token][0] <= ALL_FUNCTIONS_AND_OPERATORS_DICT[stack[-1]][0] + and token != '^'): yield stack.pop() stack.append(token) elif token == ")": @@ -324,7 +324,7 @@ def calc(self, polish_list): try: function_result = func_name(*tuple(arguments)) except TypeError: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') stack.append(function_result) # ????????? ????????, ?????????? ? ???? arguments = [] @@ -342,7 +342,7 @@ def calc(self, polish_list): stack.append(token) if len(stack) > 1: - print('Formula contains incorrect number of arguments in function.') + print('ERROR: Formula contains incorrect number of arguments in function.') return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? From 36f1a91781c040809c3bf21bec75ab94e9b20a6a Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 12:20:08 +0300 Subject: [PATCH 24/29] Refactor parse function --- .idea/workspace.xml | 157 +++++++++++-------- final_task/pycalc_proc.py | 92 +++++------ final_task/unittests/unittests_calc.py | 14 -- final_task/unittests/unittests_validation.py | 128 +++++++-------- 4 files changed, 194 insertions(+), 197 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 557a6443..607ea137 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,10 @@ + + + @@ -62,16 +77,16 @@ - @@ -119,7 +134,7 @@ - + - + - + @@ -176,7 +191,7 @@ - + @@ -206,18 +221,18 @@ - - - - + + + + - - - - + + + + @@ -235,34 +250,34 @@ - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + @@ -270,11 +285,11 @@ - + - - + + @@ -342,16 +357,6 @@ - - - - - - - - - - @@ -362,36 +367,54 @@ - + - - + + + + + + + + + + + + + + + + + + - + - + - - - + + + + + - + - - + + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index f853e3b1..c280f7f0 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -36,7 +36,7 @@ def pre_validate(formula_string): :return: None """ was_error = False - # ????????, ??? ??????? ?? ?????? ?????? + # check that formula is not empty if not isinstance(formula_string, str) or not formula_string: print('ERROR: Formula should be not empty string!') return True @@ -60,76 +60,64 @@ def pre_validate(formula_string): return was_error @staticmethod - def parse(formula_string): + def _push_out_number(number): + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' + return number + + @staticmethod + def _push_out_op(op): + if op: # ?????????? ????????, ???? ??? ???????? + yield op + op = '' + return op + + @staticmethod + def _push_out_func(function): + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' + return function + + def parse(self, formula_string): number = op = function = '' # ??? ?????????? ?????, ??????????, ??????? for el in formula_string.strip(): if el in LETTERS: # ????????? ??????? function += el.lower() - if op: # ?????????? ????????, ???? ??? ???????? - yield op - op = '' - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' + op = self._push_out_op(op) + number = self._push_out_number(number) elif el in string.digits + '.': # ????????? ????? ????? ? ? ?????? if function: function += el # ?????????? ??????????? ???????, ???? ?? ???????? ???-?? ???????? ?? ????? else: number += el - if op: # ?????????? ????????, ???? ??? ???????? - yield op - op = '' - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' + op = self._push_out_op(op) + function = self._push_out_func(function) elif el in OPERATORS_BEGIN: # ????????? ?????????? if el in DOUBLE_OPER_PART1 and not op: # ???? ???????? ??????? ????????, ???????? ? ???? op += el elif el in DOUBLE_OPER_PART2 and op: # ?????? ??????? op += el - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' - yield op # ?????????? ???????? ???????, ????? ?? ??? ???????? - op = '' + number = self._push_out_number(number) + function = self._push_out_func(function) + op = self._push_out_op(op) else: # ???? ???????? ????????? - if op: # ???? ??? ???????? ?? ?????????? ???? - ??????????, ???????? - yield op - op = '' - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' + op = self._push_out_op(op) + number = self._push_out_number(number) + function = self._push_out_func(function) yield el # ???????????? ????????? ???????? - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' + number = self._push_out_number(number) + function = self._push_out_func(function) elif el in PARENTHESES + (',',): # ????????? ?????? ? ??????? (???? ??????? ? ??????????? ???????????) - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' - if op: # ?????????? ????????, ???? ??? ???????? - yield op - op = '' + number = self._push_out_number(number) + function = self._push_out_func(function) + op = self._push_out_op(op) yield el # ?????????? ?????? ??? ???????, ??? ?????? ????????? - if function: # ?????????? ???????, ???? ???? ????????? - yield function - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - if op: # ?????????? ????????, ???? ???? ????????? - yield op + function = self._push_out_func(function) + number = self._push_out_number(number) + op = self._push_out_op(op) def validate_parsed_list(self, parsed_list): was_error = False diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py index 4286200b..28407ed7 100644 --- a/final_task/unittests/unittests_calc.py +++ b/final_task/unittests/unittests_calc.py @@ -285,19 +285,5 @@ def test94(self): self.assertEqual(-(-(-1.0)), calc_obj.calc([0.0, 0.0, 0.0, 1.0, '-', '-', '-'])) -class TestCalcNegativeCases(unittest.TestCase): - def test1(self): - self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 'sin'])) - - def test2(self): - self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'sin'])) - - def test3(self): - self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 'pow'])) - - def test4(self): - self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'pow'])) - - if __name__ == '__main__': unittest.main() diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index 65b52183..275c97a3 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -8,210 +8,210 @@ class ExpectedFailureTestCase(unittest.TestCase): # Error cases def test1(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+', '+'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+', '+'])) def test2(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+'])) def test3(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([1.0, '-'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '-'])) def test4(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['ee'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['ee'])) def test5(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['==', 7.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['==', 7.0])) def test6(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) def test7(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) def test8(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test9(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) def test10(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) def test11(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test12(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) def test13(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test14(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) def test15(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) def test16(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) def test17(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) def test18(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) def test19(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) def test20(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) def test21(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) def test22(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) def test23(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test24(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) def test25(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) def test26(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test27(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test28(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, '.', '.', ')'])) def test29(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test30(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', ',', 2.0, '+', '1'])) def test31(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '-', 2.0, '+', '1'])) def test32(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'sin', '(', 2.0, ')'])) def test33(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) def test34(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) def test35(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) def test36(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) def test37(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) def test38(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) def test39(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) def test40(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) def test41(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) def test42(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) def test43(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) def test44(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) def test45(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) def test46(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) def test47(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) def test48(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) def test49(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) def test50(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) def test51(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) def test52(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) def test53(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) def test54(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) def test55(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) def test56(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) def test57(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) def test58(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) # matched parentheses def test59(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) def test60(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) def test61(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) def test62(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) def test63(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, '+', ')', 1.0, ')'])) def test64(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['abs'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['abs'])) class ExpectedSuccessTestCase(unittest.TestCase): From 6b3ee62754083e90fa00fa41566a0da5a76a6ea8 Mon Sep 17 00:00:00 2001 From: alinonax Date: Mon, 3 Jun 2019 13:06:28 +0300 Subject: [PATCH 25/29] Revert "Refactor parse function" This reverts commit 36f1a91781c040809c3bf21bec75ab94e9b20a6a. --- .idea/workspace.xml | 157 ++++++++----------- final_task/pycalc_proc.py | 92 ++++++----- final_task/unittests/unittests_calc.py | 14 ++ final_task/unittests/unittests_validation.py | 128 +++++++-------- 4 files changed, 197 insertions(+), 194 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 607ea137..557a6443 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,10 +2,7 @@ - - - @@ -77,16 +62,16 @@ - @@ -134,7 +119,7 @@ - + - + - + @@ -191,7 +176,7 @@ - + @@ -221,18 +206,18 @@ - - - - + + + + - - - - + + + + @@ -250,34 +235,34 @@ - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + @@ -285,11 +270,11 @@ - + - - + + @@ -357,64 +342,56 @@ - + - - + + - + - - - - - - - - - + - - - + + + + + - + - - + + - + - + - - - - - + + + - + - - + + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index c280f7f0..f853e3b1 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -36,7 +36,7 @@ def pre_validate(formula_string): :return: None """ was_error = False - # check that formula is not empty + # ????????, ??? ??????? ?? ?????? ?????? if not isinstance(formula_string, str) or not formula_string: print('ERROR: Formula should be not empty string!') return True @@ -60,64 +60,76 @@ def pre_validate(formula_string): return was_error @staticmethod - def _push_out_number(number): - if number: # ?????????? ?????, ???? ???? ????????? - yield float(number) if number != '.' else '.' - number = '' - return number - - @staticmethod - def _push_out_op(op): - if op: # ?????????? ????????, ???? ??? ???????? - yield op - op = '' - return op - - @staticmethod - def _push_out_func(function): - if function: # ?????????? ???????, ???? ???? ????????? - yield function - function = '' - return function - - def parse(self, formula_string): + def parse(formula_string): number = op = function = '' # ??? ?????????? ?????, ??????????, ??????? for el in formula_string.strip(): if el in LETTERS: # ????????? ??????? function += el.lower() - op = self._push_out_op(op) - number = self._push_out_number(number) + if op: # ?????????? ????????, ???? ??? ???????? + yield op + op = '' + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' elif el in string.digits + '.': # ????????? ????? ????? ? ? ?????? if function: function += el # ?????????? ??????????? ???????, ???? ?? ???????? ???-?? ???????? ?? ????? else: number += el - op = self._push_out_op(op) - function = self._push_out_func(function) + if op: # ?????????? ????????, ???? ??? ???????? + yield op + op = '' + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' elif el in OPERATORS_BEGIN: # ????????? ?????????? if el in DOUBLE_OPER_PART1 and not op: # ???? ???????? ??????? ????????, ???????? ? ???? op += el elif el in DOUBLE_OPER_PART2 and op: # ?????? ??????? op += el - number = self._push_out_number(number) - function = self._push_out_func(function) - op = self._push_out_op(op) + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' + yield op # ?????????? ???????? ???????, ????? ?? ??? ???????? + op = '' else: # ???? ???????? ????????? - op = self._push_out_op(op) - number = self._push_out_number(number) - function = self._push_out_func(function) + if op: # ???? ??? ???????? ?? ?????????? ???? - ??????????, ???????? + yield op + op = '' + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' yield el # ???????????? ????????? ???????? - number = self._push_out_number(number) - function = self._push_out_func(function) + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' elif el in PARENTHESES + (',',): # ????????? ?????? ? ??????? (???? ??????? ? ??????????? ???????????) - number = self._push_out_number(number) - function = self._push_out_func(function) - op = self._push_out_op(op) + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + number = '' + if function: # ?????????? ???????, ???? ???? ????????? + yield function + function = '' + if op: # ?????????? ????????, ???? ??? ???????? + yield op + op = '' yield el # ?????????? ?????? ??? ???????, ??? ?????? ????????? - function = self._push_out_func(function) - number = self._push_out_number(number) - op = self._push_out_op(op) + if function: # ?????????? ???????, ???? ???? ????????? + yield function + if number: # ?????????? ?????, ???? ???? ????????? + yield float(number) if number != '.' else '.' + if op: # ?????????? ????????, ???? ???? ????????? + yield op def validate_parsed_list(self, parsed_list): was_error = False diff --git a/final_task/unittests/unittests_calc.py b/final_task/unittests/unittests_calc.py index 28407ed7..4286200b 100644 --- a/final_task/unittests/unittests_calc.py +++ b/final_task/unittests/unittests_calc.py @@ -285,5 +285,19 @@ def test94(self): self.assertEqual(-(-(-1.0)), calc_obj.calc([0.0, 0.0, 0.0, 1.0, '-', '-', '-'])) +class TestCalcNegativeCases(unittest.TestCase): + def test1(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 'sin'])) + + def test2(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'sin'])) + + def test3(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 'pow'])) + + def test4(self): + self.assertRaises(ValueError, lambda: calc_obj.calc([1.0, 2.0, 3.0, 'pow'])) + + if __name__ == '__main__': unittest.main() diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index 275c97a3..65b52183 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -8,210 +8,210 @@ class ExpectedFailureTestCase(unittest.TestCase): # Error cases def test1(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+', '+'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+', '+'])) def test2(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+'])) def test3(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '-'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([1.0, '-'])) def test4(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['ee'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['ee'])) def test5(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['==', 7.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['==', 7.0])) def test6(self): - self.assertEqual(True, + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) def test7(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) def test8(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test9(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) def test10(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) def test11(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test12(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) def test13(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test14(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) def test15(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) def test16(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) def test17(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) def test18(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) def test19(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) def test20(self): - self.assertEqual(True, + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) def test21(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) def test22(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) def test23(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test24(self): - self.assertEqual(True, + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) def test25(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) def test26(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test27(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test28(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, '.', '.', ')'])) def test29(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test30(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', ',', 2.0, '+', '1'])) def test31(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '-', 2.0, '+', '1'])) def test32(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'sin', '(', 2.0, ')'])) def test33(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) def test34(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) def test35(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) def test36(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) def test37(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) def test38(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) def test39(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) def test40(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) def test41(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) def test42(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) def test43(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) def test44(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) def test45(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) def test46(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) def test47(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) def test48(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) def test49(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) def test50(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) def test51(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) def test52(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) def test53(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) def test54(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) def test55(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) def test56(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) def test57(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) def test58(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) # matched parentheses def test59(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) def test60(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) def test61(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) def test62(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) def test63(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, '+', ')', 1.0, ')'])) def test64(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['abs'])) + self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['abs'])) class ExpectedSuccessTestCase(unittest.TestCase): From 81ebf2c4983dc2a0ab9c52b5a5f6adb329cc8913 Mon Sep 17 00:00:00 2001 From: alinonax Date: Tue, 4 Jun 2019 10:46:01 +0300 Subject: [PATCH 26/29] Add comments and docstrings --- .idea/workspace.xml | 297 +++++++++++++++++++++++++++++++++++--- final_task/pycalc_proc.py | 136 ++++++++++------- 2 files changed, 356 insertions(+), 77 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 557a6443..cd0fd182 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,6 +2,7 @@ + @@ -44,6 +35,7 @@ numbers was v Raises(ValueError + ???? @@ -65,6 +57,7 @@ @@ -270,11 +263,11 @@ - + - - + + @@ -284,11 +277,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -364,10 +531,78 @@ - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -376,7 +611,6 @@ - @@ -384,14 +618,29 @@ + + + + + + + + + + + + + + + - - + + diff --git a/final_task/pycalc_proc.py b/final_task/pycalc_proc.py index f853e3b1..cdcb0f12 100644 --- a/final_task/pycalc_proc.py +++ b/final_task/pycalc_proc.py @@ -33,26 +33,26 @@ def pre_validate(formula_string): parsing in current version of implementation. :param formula_string: input formula as text - :return: None + :return: was_error """ was_error = False - # ????????, ??? ??????? ?? ?????? ?????? + # check that formula is not empty if not isinstance(formula_string, str) or not formula_string: print('ERROR: Formula should be not empty string!') return True - # ?????????, ??? ? ??????? ??? ????? ?????? ??????????? ?????? - # ? ??????? ?????????? ??????? ??????? ??? ?????, ????? ????????? ?????????? ??????? ?? ?????? + # check that there is not more than one delimiter in a row in the formula + # it's more convenient to do it here in order to simplify parsing to tokens if '..' in formula_string: print('ERROR: Number can not contain more than one delimiter "." !') was_error = True - # ???????? ?? ?????? ? ??????? ?????????? + # check if there is whitespace between double operators if re.search('/ /|< =|> =|= =|! =', formula_string): print('ERROR: space is not allowed in operators: //, <=, >=, ==, !=.') was_error = True if re.search(r'\d\s\d', formula_string): print('ERROR: space is not allowed between digits!') was_error = True - # ???????? ?? ??????????? ???????? + # check allowed tokens for el in formula_string.strip(): if el not in ALLOWED_TOKENS: print('ERROR: Formula contains incorrect symbol "{}"'.format(el)) @@ -61,77 +61,89 @@ def pre_validate(formula_string): @staticmethod def parse(formula_string): - number = op = function = '' # ??? ?????????? ?????, ??????????, ??????? + """ + Parsing formula to tokens + + :param formula_string: input formula as text which have passed pre-validation + :return: None + """ + number = op = function = '' for el in formula_string.strip(): - if el in LETTERS: # ????????? ??????? + if el in LETTERS: # function processing function += el.lower() - if op: # ?????????? ????????, ???? ??? ???????? + if op: # shot the operator if it has been accumulated yield op op = '' - if number: # ?????????? ?????, ???? ???? ????????? + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' number = '' - elif el in string.digits + '.': # ????????? ????? ????? ? ? ?????? + elif el in string.digits + '.': # processing integers and floats if function: - function += el # ?????????? ??????????? ???????, ???? ?? ???????? ???-?? ???????? ?? ????? + function += el # continue to accumulate the function until meet something different from the number else: number += el - if op: # ?????????? ????????, ???? ??? ???????? + if op: # shot the operator if has been accumulated yield op op = '' - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function function = '' - elif el in OPERATORS_BEGIN: # ????????? ?????????? - if el in DOUBLE_OPER_PART1 and not op: # ???? ???????? ??????? ????????, ???????? ? ???? + elif el in OPERATORS_BEGIN: # operator processing + if el in DOUBLE_OPER_PART1 and not op: # if double operator is possible, add and wait op += el - elif el in DOUBLE_OPER_PART2 and op: # ?????? ??????? + elif el in DOUBLE_OPER_PART2 and op: # found double op += el - if number: # ?????????? ?????, ???? ???? ????????? + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' number = '' - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function function = '' - yield op # ?????????? ???????? ???????, ????? ?? ??? ???????? + yield op # shot an double operator when it was accumulated op = '' - else: # ???? ???????? ????????? - if op: # ???? ??? ???????? ?? ?????????? ???? - ??????????, ???????? + else: # if the operator is single + if op: # if it was accumulated at the previous step - shot, reset yield op op = '' - if number: # ?????????? ?????, ???? ???? ????????? + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' number = '' - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function function = '' - yield el # ???????????? ????????? ???????? - if number: # ?????????? ?????, ???? ???? ????????? + yield el # hit a single operator + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' number = '' - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function function = '' - elif el in PARENTHESES + (',',): # ????????? ?????? ? ??????? (???? ??????? ? ??????????? ???????????) - if number: # ?????????? ?????, ???? ???? ????????? + elif el in PARENTHESES + (',',): # handling brackets and commas (if a function with multiple arguments) + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' number = '' - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function function = '' - if op: # ?????????? ????????, ???? ??? ???????? + if op: # shot the operator if has been accumulated yield op op = '' - yield el # ?????????? ?????? ??? ???????, ??? ?????? ????????? + yield el # shot brace or comma as soon as they are met - if function: # ?????????? ???????, ???? ???? ????????? + if function: # shot the function if it has been accumulated yield function - if number: # ?????????? ?????, ???? ???? ????????? + if number: # shot number if it was accumulated yield float(number) if number != '.' else '.' - if op: # ?????????? ????????, ???? ???? ????????? + if op: # shot the operator if it has been accumulated yield op def validate_parsed_list(self, parsed_list): + """ + Validation of various errors before polish sorting + + :param parsed_list: list with tokens of pre-validated and parsed formula for validation + :return: was_error + """ was_error = False counter = 0 # counter for parentheses was_number = False @@ -223,7 +235,7 @@ def process_unary_operations(validated_list): in (('(', ',') + tuple(BINARY_OPERATORS.keys()))) or not processed_list) if stack_str: if '-' in stack_str: - if stack_str.count('-') % 2 == 0: # ??????? ???-?? -, ??????? ?? + ???? ?? - + if stack_str.count('-') % 2 == 0: # count the number of minuses, replacing with plus or minus if is_unary_plus: stack_str = '' else: @@ -243,12 +255,18 @@ def process_unary_operations(validated_list): @staticmethod def sort_to_polish(parsed_formula): - stack = [] # ? ???????? ????? ?????????? ?????? + """ + Implementing polish sorting needed for calculating the result + + :param parsed_formula: list that passed validation with tokens of parsed formula + :return: None + """ + stack = [] # use list as stack previous_token = '' for token in parsed_formula: - # ???? ??????? - ????????, ?? ?????????? ?????? ??? ????????? ?? ?????, - # ??? ????????? ?????? ??? ????? ??????????, - # ?? ??????????? ?????? ??? ??????????? ?????. + # if the element is an operator, then we send further all the operators from the stack, + # whose priority is greater than or equal to the newcomer, + # up to the opening bracket or the stack is empty. if token in ALL_FUNCTIONS_AND_OPERATORS_DICT: if token == '-' and previous_token in ('(', ',', '') + tuple(BINARY_OPERATORS.keys()): yield 0.0 @@ -260,22 +278,22 @@ def sort_to_polish(parsed_formula): yield stack.pop() stack.append(token) elif token == ")": - # ???? ??????? - ??????????? ??????, ?????? ??? ???????? ?? ?????, ?? ??????????? ??????, - # ? ??????????? ?????? ?????????? ?? ?????. + # if the element is a closing bracket, we give all the elements from the stack, + # up to the opening bracket, and throw away the opening bracket out of the stack. while stack: x = stack.pop() if x == "(": break yield x elif token == "(": - # ???? ??????? - ??????????? ??????, ?????? ??????? ?? ? ???? + # if the element is an opening bracket, just put it to the stack stack.append(token) - elif token == ",": # ????? ????????? - # ?????? ??? ????????? ?? ????? ?? ??????????? ?????? + elif token == ",": # end of argument + # give all operators from the stack to the opening bracket while stack and stack[-1] != "(": yield stack.pop() else: - # ???? ??????? - ????? ??? ?????????, ???????? ??? ????? ?? ????? + # if the element is a number or a constant, send it immediately to the output yield token previous_token = token while stack: @@ -291,6 +309,12 @@ def _get_num_args(func): return args.count(',') + 1 if args else 0 def calc(self, polish_list): + """ + Calculating the result after polish sorting + + :param polish_list: list that have been polish-sorted + :return: stack[0]: the result of calculation + """ stack = [] function_result = None @@ -305,7 +329,7 @@ def calc(self, polish_list): if stack: arguments.insert(0, stack.pop()) else: - # ?. ?. log ????? ?????????? ???-?? ?????????? ????????? ????????? + # since log has a changing number of arguments, separate processing index_current_log_token = polish_list.index(token) try: next_token_after_log = polish_list[index_current_log_token + 1] @@ -326,16 +350,16 @@ def calc(self, polish_list): except TypeError: print('ERROR: Formula contains incorrect number of arguments in function.') - stack.append(function_result) # ????????? ????????, ?????????? ? ???? + stack.append(function_result) # calculate the operator, return to the stack arguments = [] elif token in BUILT_IN_FUNCTIONS: - x = stack.pop() # ???????? 1 ????o ?? ????? + x = stack.pop() # take one number from the stack func_name = getattr(builtins, token) stack.append(func_name(x)) - elif token in OPERATORS: # ???? ?????????? ??????? - ????????, - y, x = stack.pop(), stack.pop() # ???????? 2 ????? ?? ????? - stack.append(OPERATORS[token][1](x, y)) # ????????? ????????, ?????????? ? ???? + elif token in OPERATORS: # if the incoming element is an operator, + y, x = stack.pop(), stack.pop() # pick up two numbers from the stack + stack.append(OPERATORS[token][1](x, y)) # calculate the operator, return to the stack elif token in MATH_CONSTS: stack.append(getattr(math, token)) else: @@ -344,9 +368,15 @@ def calc(self, polish_list): if len(stack) > 1: print('ERROR: Formula contains incorrect number of arguments in function.') - return stack[0] # ????????? ?????????? - ???????????? ??????? ? ????? + return stack[0] # the result of the calculation is the only item on the stack def launch_processing(self): + """ + Launch of program + + :param self + :return: None + """ parsed_list = [] polish_list = [] was_error = self.pre_validate(self.formula_string) From 85a33847c4ba575c4eb093ddcdc551c943192f59 Mon Sep 17 00:00:00 2001 From: alinonax Date: Wed, 5 Jun 2019 22:28:00 +0400 Subject: [PATCH 27/29] Fix unittests_validation --- .idea/workspace.xml | 216 +++++-------------- final_task/unittests/unittests_validation.py | 211 +++++++++--------- 2 files changed, 158 insertions(+), 269 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index cd0fd182..48e0ccc3 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,8 +2,7 @@ - - + - + - + @@ -26,6 +25,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -34,12 +56,15 @@ function_result numbers was v - Raises(ValueError ???? + Raises(ValueError + \'Formula was validated\! \'\n \'Errors were not found\.\' + 'Formula was validated! Errors were not found.' Equal(True + False @@ -54,17 +79,17 @@ - @@ -399,74 +424,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -529,84 +487,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -614,13 +494,6 @@ - - - - - - - @@ -639,7 +512,7 @@ - + @@ -647,5 +520,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index 65b52183..615f07c7 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -8,364 +8,364 @@ class ExpectedFailureTestCase(unittest.TestCase): # Error cases def test1(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+', '+'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+', '+'])) def test2(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['+'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['+'])) def test3(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([1.0, '-'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '-'])) def test4(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['ee'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['ee'])) def test5(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['==', 7.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['==', 7.0])) def test6(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) def test7(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) def test8(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test9(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['log10', 0.0, '(', 100.0, ')'])) def test10(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '-', '-', '-', '-', '-'])) def test11(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test12(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([6.0, '*', '*', 6.0])) def test13(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ')'])) def test14(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', '(', '(', '(', ])) def test15(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([77.0, '==', '==', 77.0])) def test16(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['_', '+', 'son'])) def test17(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '+', 2.0])) def test18(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', '+', 2.0])) def test19(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) def test20(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) def test21(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) def test22(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', ',', 2.0])) def test23(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test24(self): - self.assertRaises(ValueError, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) def test25(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e'])) def test26(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', 'sin', '(', 2.0, ')'])) def test27(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test28(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, '.', '.', ')'])) def test29(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '(', 2.0, '+', '1'])) def test30(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', ',', 2.0, '+', '1'])) def test31(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', '-', 2.0, '+', '1'])) def test32(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'sin', '(', 2.0, ')'])) def test33(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) def test34(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ')', 4.0])) def test35(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '.', 4.0])) def test36(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', ',', 4.0])) def test37(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['-', '//', 4.0])) def test38(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ')', 4.0])) def test39(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '.', 4.0])) def test40(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', ',', 4.0])) def test41(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([26.0, '//', '%', 4.0])) def test42(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ')', 4.0, ')'])) def test43(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '.', 4.0, ')'])) def test44(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', ',', 4.0, ')'])) def test45(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '-', 4.0, ')'])) def test46(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', '//', 4.0, ')'])) def test47(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'cos', 4.0, ')'])) def test48(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 4.0, ')'])) def test49(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['cos', 'e', 4.0, ')'])) def test50(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '(', '+', 5.0, ')'])) def test51(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, '.', '+', 5.0])) def test52(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'sin', '(', 5.0, ')'])) def test53(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 3.0, '+', 5.0])) def test54(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([4.0, 'e', '+', 5.0, ')'])) def test55(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '(', '+', 'pi'])) def test56(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', '.', '+', 'pi'])) def test57(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 'sin', '(', 3.0, ')'])) def test58(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['e', 3.0, '+', 'pi'])) # matched parentheses def test59(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', '(', 25.0, '+', 1.0])) def test60(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, ')'])) def test61(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', ')', 25.0, '+', 1.0, ')'])) def test62(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', 1.0, '(', ')'])) def test63(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, '+', ')', 1.0, ')'])) def test64(self): - self.assertRaises(ValueError, lambda: calc_obj.validate_parsed_list(['abs'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['abs'])) class ExpectedSuccessTestCase(unittest.TestCase): def test1(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 13.0])) + self.assertEqual(False, calc_obj.validate_parsed_list(['-', 13.0])) def test2(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([6.0, '-', '(', '-', 13.0, ')'])) def test3(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '-', '-', '-', 1.0])) def test4(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['-', '+', '-', '-', '-', '+', '-', 1.0])) def test5(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([1.0, '+', 2.0, + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', 2.0, '*', 2.0])) def test6(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', '(', 2.0, '+', 3.0, '*', 2.0, ')', '*', 3.0])) def test7(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([10.0, '*', '(', 2.0, '+', 1.0, ')'])) def test8(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([10.0, '^', '(', 2.0, '+', 1.0, ')'])) def test9(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 3.0, '^', 2.0])) def test10(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 3.0, '%', 2.0, '^', 2.0])) def test11(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['pi', '+', 'e'])) def test12(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 'e', ')'])) def test13(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', 2.0, ')'])) def test14(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['log10', '(', + self.assertEqual(False, calc_obj.validate_parsed_list(['log10', '(', 100.0, ')'])) def test15(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( ['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0])) def test16(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( [2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')'])) def test17(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['abs', '(', '-', 5.0, ')'])) def test18(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['round', '(', + self.assertEqual(False, calc_obj.validate_parsed_list(['round', '(', 123.456789, ')'])) def test19(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([102.0, '%', 12.0, '%', 7.0])) def test20(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 4.0, '/', 3.0])) def test21(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([2.0, '^', 3.0, '^', 4.0])) def test22(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( [1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0])) def test23(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( ['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0])) def test24(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( [1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0])) def test25(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 100.0, ')'])) def test26(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list([666.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([666.0])) def test27(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list(['-', 0.1])) + self.assertEqual(False, calc_obj.validate_parsed_list(['-', 0.1])) def test28(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '/', 3.0])) def test29(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([0.1, '*', 2.0, '^', 56.0])) def test30(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['e', '^', 34.0])) def test31(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')'])) def test32(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', '+', 2.0, '^', 0.0, ')', ')', '^', '(', 1.0, '/', 3.0, ')'])) def test33(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', 5.0])) def test34(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', 'log10', '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', @@ -373,32 +373,29 @@ def test34(self): 'cos', '(', 0.0, ')', '^', 3.0, ')'])) def test35(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( [2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')'])) def test36(self): - self.assertEqual('Formula was validated! Errors were not found.', calc_obj.validate_parsed_list( + self.assertEqual(False, calc_obj.validate_parsed_list( ['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')'])) def test37(self): - self.assertEqual('Formula was validated! Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '*', '-', 13.0])) def test38(self): - self.assertEqual('Formula was validated! ' - 'Errors were not found.', + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '-', 13.0, ')'])) def test39(self): - self.assertEqual('Formula was validated! ' - 'Errors were not found.', calc_obj.validate_parsed_list(['log', '(', 1.0, ',', + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '(', '-', 13.0, ')', ')'])) # incorrect number of arguments processing in calc def test40(self): - self.assertEqual('Formula was validated! ' - 'Errors were not found.', calc_obj.validate_parsed_list(['pow', '(', 1.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['pow', '(', 1.0, ')'])) if __name__ == '__main__': From 49884a212bba58248681c5e53b2f666d3ee51082 Mon Sep 17 00:00:00 2001 From: alinonax Date: Wed, 5 Jun 2019 23:12:58 +0400 Subject: [PATCH 28/29] Fix unittests_validation 2 --- .idea/workspace.xml | 19 +- final_task/unittests/unittests_validation.py | 175 +++++++------------ 2 files changed, 74 insertions(+), 120 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 48e0ccc3..2960a41f 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -28,11 +28,11 @@ - - + + - + @@ -413,7 +413,7 @@ - + @@ -424,7 +424,7 @@ - + @@ -474,6 +474,9 @@ + + + @@ -530,11 +533,11 @@ - - + + - + diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index 615f07c7..7aba242f 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -23,8 +23,7 @@ def test5(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['==', 7.0])) def test6(self): - self.assertEqual(True, - lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list([1.0, '+', 2.0, '(', 3.0, '*', 4.0, ')', ')'])) def test7(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '(', 1.0, '+', 2.0, ')'])) @@ -66,8 +65,8 @@ def test19(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', '+', 2.0])) def test20(self): - self.assertEqual(True, - lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', 1.0, '+', 5.0, ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', 1.0, '+', 5.0, ')', '(', + 1.0, '+', 5.0, ')'])) def test21(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 2.0])) @@ -77,7 +76,7 @@ def test22(self): def test23(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, ')', - 'sin', '(', 2.0, ')'])) + 'sin', '(', 2.0, ')'])) def test24(self): self.assertEqual(True, @@ -88,32 +87,30 @@ def test25(self): def test26(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '//', 77.0, '-', 4.0, - ')', 'sin', '(', 2.0, ')'])) + ')', 'sin', '(', 2.0, ')'])) def test27(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', - '.', '(', 2.0, '+', '1'])) + '.', '(', 2.0, '+', '1'])) def test28(self): - self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', - - 4.0, '.', '.', ')'])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, '.', '.', ')'])) def test29(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', - '.', '(', 2.0, '+', '1'])) + '.', '(', 2.0, '+', '1'])) def test30(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', - '.', ',', 2.0, '+', '1'])) + '.', ',', 2.0, '+', '1'])) def test31(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', - '.', '-', 2.0, '+', '1'])) + '.', '-', 2.0, '+', '1'])) def test32(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', - '.', 'sin', '(', 2.0, ')'])) + '.', 'sin', '(', 2.0, ')'])) def test33(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', '.', 'e'])) @@ -208,7 +205,7 @@ def test62(self): def test63(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list([15.0, '*', 25.0, '+', '(', 1.0, - '+', ')', 1.0, ')'])) + '+', ')', 1.0, ')'])) def test64(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['abs'])) @@ -219,115 +216,77 @@ def test1(self): self.assertEqual(False, calc_obj.validate_parsed_list(['-', 13.0])) def test2(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([6.0, '-', '(', '-', - 13.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list([6.0, '-', '(', '-', 13.0, ')'])) def test3(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([1.0, '-', '-', '-', - 1.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '-', '-', '-', 1.0])) def test4(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['-', '+', '-', '-', - '-', '+', '-', 1.0])) + self.assertEqual(False, calc_obj.validate_parsed_list(['-', '+', '-', '-', '-', '+', '-', 1.0])) def test5(self): - self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', 2.0, - '*', 2.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', 2.0, '*', 2.0])) def test6(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([1.0, '+', '(', 2.0, '+', - 3.0, '*', 2.0, ')', '*', - 3.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', '(', 2.0, '+', 3.0, '*', 2.0, ')', '*', 3.0])) def test7(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([10.0, '*', '(', 2.0, - '+', 1.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list([10.0, '*', '(', 2.0, '+', 1.0, ')'])) def test8(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([10.0, '^', '(', 2.0, - '+', 1.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list([10.0, '^', '(', 2.0, '+', 1.0, ')'])) def test9(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([100.0, '/', 3.0, - '^', 2.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 3.0, '^', 2.0])) def test10(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([100.0, '/', 3.0, '%', - 2.0, '^', 2.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 3.0, '%', 2.0, '^', 2.0])) def test11(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['pi', '+', 'e'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['pi', '+', 'e'])) def test12(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['log', '(', 'e', ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 'e', ')'])) def test13(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', - 2.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', 2.0, ')'])) def test14(self): - self.assertEqual(False, calc_obj.validate_parsed_list(['log10', '(', - 100.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['log10', '(', 100.0, ')'])) def test15(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - ['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0])) + self.assertEqual(False, calc_obj.validate_parsed_list(['sin', '(', 'pi', '/', 2.0, ')', '*', 111.0, '*', 6.0])) def test16(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - [2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list([2.0, '*', 'sin', '(', 'pi', '/', 2.0, ')'])) def test17(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['abs', '(', '-', 5.0, - ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['abs', '(', '-', 5.0, ')'])) def test18(self): - self.assertEqual(False, calc_obj.validate_parsed_list(['round', '(', - 123.456789, - ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['round', '(', 123.456789, ')'])) def test19(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([102.0, '%', 12.0, - '%', 7.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([102.0, '%', 12.0, '%', 7.0])) def test20(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([100.0, '/', 4.0, '/', - 3.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([100.0, '/', 4.0, '/', 3.0])) def test21(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([2.0, '^', 3.0, '^', - 4.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([2.0, '^', 3.0, '^', 4.0])) def test22(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - [1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', 2.0, '*', 3.0, '==', 1.0, '+', 2.0, '*', 3.0])) def test23(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - ['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0])) + self.assertEqual(False, calc_obj.validate_parsed_list(['e', '^', 5.0, '>=', 'e', '^', 5.0, '+', 1.0])) def test24(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - [1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '+', 2.0, '*', 4.0, '/', 3.0, '+', 1.0, '!=', 1.0, + '+', 2.0, '*', 4.0, '/', 3.0, '+', 2.0])) def test25(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['(', 100.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 100.0, ')'])) def test26(self): self.assertEqual(False, calc_obj.validate_parsed_list([666.0])) @@ -336,62 +295,54 @@ def test27(self): self.assertEqual(False, calc_obj.validate_parsed_list(['-', 0.1])) def test28(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([1.0, '/', 3.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '/', 3.0])) def test29(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([0.1, '*', 2.0, '^', - 56.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([0.1, '*', 2.0, '^', 56.0])) def test30(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['e', '^', 34.0])) + self.assertEqual(False, calc_obj.validate_parsed_list(['e', '^', 34.0])) def test31(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', - '/', 'e', '+', 2.0, '^', 0.0, ')', ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', + '+', 2.0, '^', 0.0, ')', ')'])) def test32(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', - '/', 'e', '+', 2.0, '^', 0.0, ')', ')', - '^', '(', 1.0, '/', 3.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['(', 2.0, '^', '(', 'pi', '/', 'pi', '+', 'e', '/', 'e', + '+', 2.0, '^', 0.0, ')', ')', '^', '(', 1.0, '/', + 3.0, ')'])) def test33(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - [10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', 5.0, '/', '-', 0.1, '-', - 10.0, ')', '-', '-', 'abs', '(', '-', 53.0, '/', 10.0, ')', '+', '-', 5.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([10.0, '*', 'e', '^', 0.0, '*', 'log10', '(', 0.4, '-', + 5.0, '/', '-', 0.1, '-', 10.0, ')', '-', '-', 'abs', '(', + '-', 53.0, '/', 10.0, ')', '+', '-', 5.0])) def test34(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - ['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', '-', 'cos', - '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, ')', '-', 'sin', '(', 'cos', '(', - 'log10', '(', 43.0, ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', '(', - 34.0, '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', '-', 'cos', '(', 1.0, ')', '-', '-', - 'cos', '(', 0.0, ')', '^', 3.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['sin', '(', '-', 'cos', '(', '-', 'sin', '(', 3.0, ')', + '-', 'cos', '(', '-', 'sin', '(', '-', 3.0, '*', 5.0, + ')', '-', 'sin', '(', 'cos', '(', 'log10', '(', 43.0, + ')', ')', ')', ')', '+', 'cos', '(', 'sin', '(', 'sin', + '(', 34.0, '-', 2.0, '^', 2.0, ')', ')', ')', ')', '-', + '-', 'cos', '(', 1.0, ')', '-', '-', 'cos', '(', 0.0, + ')', '^', 3.0, ')'])) def test35(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - [2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list([2.0, '^', '(', 2.0, '^', 2.0, '*', 2.0, '^', 2.0, ')'])) def test36(self): - self.assertEqual(False, calc_obj.validate_parsed_list( - ['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', 'sin', '(', 23.0, ')', ',', 45.0, - ')', '+', 'cos', '(', 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['sin', '(', 'e', '^', 'log', '(', 'e', '^', 'e', '^', + 'sin', '(', 23.0, ')', ',', 45.0, ')', '+', 'cos', '(', + 3.0, '+', 'log10', '(', 'e', '^', '-', 'e', ')', ')', + ')'])) def test37(self): - self.assertEqual(False, - calc_obj.validate_parsed_list([1.0, '*', '-', 13.0])) + self.assertEqual(False, calc_obj.validate_parsed_list([1.0, '*', '-', 13.0])) def test38(self): - self.assertEqual(False, - calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '-', 13.0, ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '-', 13.0, ')'])) def test39(self): - self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 1.0, ',', - '(', '-', 13.0, ')', ')'])) + self.assertEqual(False, calc_obj.validate_parsed_list(['log', '(', 1.0, ',', '(', '-', 13.0, ')', ')'])) # incorrect number of arguments processing in calc def test40(self): From a40e0e6f87562164c956d392939bd3a4da3400ba Mon Sep 17 00:00:00 2001 From: alinonax Date: Wed, 5 Jun 2019 23:15:32 +0400 Subject: [PATCH 29/29] Fix unittests_validation 3 --- .idea/workspace.xml | 14 +++++++------- final_task/unittests/unittests_validation.py | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2960a41f..92272c9a 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -28,11 +28,11 @@ - - + + - + @@ -424,7 +424,7 @@ - + @@ -533,11 +533,11 @@ - - + + - + diff --git a/final_task/unittests/unittests_validation.py b/final_task/unittests/unittests_validation.py index 7aba242f..7e8d65b9 100644 --- a/final_task/unittests/unittests_validation.py +++ b/final_task/unittests/unittests_validation.py @@ -79,8 +79,7 @@ def test23(self): 'sin', '(', 2.0, ')'])) def test24(self): - self.assertEqual(True, - lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) + self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', '.', 77.0, '-', 4.0, ')', 2.0, '+', 1.0])) def test25(self): self.assertEqual(True, lambda: calc_obj.validate_parsed_list(['(', ',', 77.0, '-', 4.0, ')', 'e']))