/Apress-Calc

Abak press test task - simple calculator

Primary LanguageJavaApache License 2.0Apache-2.0

Apress-Calculator

Приложение представляет собой простейший калькулятор и работает на Android начиная с 2.3, а не с 2.2. Этому есть множество причин, а именно крайне низкая распространённость требуемой версии на рынке и невозможность использовать appCompat, что ведет к использованию стилей платформы по-умолчанию. Неприятный дизайн Android 2.2 Froyo портит впечатления от выполенной работы.

В ветке kotlin находится портированная версия калькулятора с небольшими улучшениями и дополнениями.

Build status

Build Status

Структура проекта

Проект разделен на два модуля:

  1. app – нативное андроид приложение
  2. calculator – библиотечный модуль вычисления результата

Библиотечный модуль использует Dependency injection для разделения функции между классами и формирования единого объекта Calculator

Analyzer analyzer = new Analyzer(
    new MemberConverter(
        new MultiOperatorExtractor(
            new ExpressionPartExtractor()
        )
     )
);
NotationTranslator translator = new PolishTranslator();
NotationInterpreter interpreter = new PolishInterpreter();
Calculator calculator = new Calculator(translator, interpreter);

Компонент Analyzer выполняет разбор выражения на токены. NotationTranslator сортирует токены для получения определенной нотации (в данном случае – постфиксной). NotationInterpreter по очереди обрабатывает их, вычисляя результат выражения. На этом уровне токеном является интерфейс Member и две его реализации (для операторов и операндов). В библиотеке предусмотена трансформация токенов в интерфейс Visual для создания текстового (или другого) представления в Printer'е. Модульная стурктура позволяет снизить расходы при внедрении новых операторов.

Расчет выражения может быть проведен по двух различным сценариям:

  1. При "ленивых" вычислении и обработке каждого следующего токена. Используется интерфейс Iterable.
  2. Формированием исходной последовательности токенов целиком и ее дальнейшем расчете.

Калькулятор понимает следующие операции: сложение, вычитание, умножение, деление, группировка, "унарный минус" и работает с десятичными цифрами. Унарный минус обрабатывается как отдельная операция. Все операции перечислены в классе Operators.

Приложение имеет простую архитектуру, не выполняет асинхронных операций. Перерасчет производится после каждого изменения выражения, но обработчик кнопки EN выполняет полную поцедуру.

Для форматного вывода математического выражения организована обратная связь от модуля calculator в виджет Editor. После разбора выражения на токены, они представляются в виде единого списка CalculatorVisual, допускающим представление в текстовом виде и имеющим дополнительные возможности. Реализация этого интерфейса может накладывать ограничения на перемещение курсора в текстовом поле. Это актуально для обработки пробелов в выражении.

В целях демонстрации результат работы компонента NotationTranslator выводится в виде горизонтального списка, левее от вычисленного значения выражения. Это дает возможность просмотреть выражение в той нотации, в которой происходит вычисление.

Логика работы

В текстовое поле вводится выражение

1 + 2 * 5 - 5/22 + ( 45 + 34 ) * -3

Калькулятор вычисляет значение этого выражения

-226.227

Вычисления производятся по нажатию кнопку EN, удаление отдельных символов по нажатию CL, удаление всего ввода по удержанию CL. Сообщения об ошибках выводятся в строке результата. Например:

  • Неверное выражение
  • Неправильно расставлены скобки и др.

Unit-тестами покрыта логика вычисления результата.

Демонстрация

Демонстрация