GithubHelp home page GithubHelp logo

rpnlibrary's Introduction

RPNLibrary

Simple RPN (Reverse Polish Notation) Library for Java.
It is based on Dijkstra Algorithm. (https://en.wikipedia.org/wiki/Reverse_Polish_notation)

Reliability Rating

Maven Central

javadoc

Story

Couple years ago I read Joshua Bloch's "Java. Effective Programming". I wanted to practice what I've learned. I didn't want to create another CRUD like application, so I found that Dijkstra's algorithm would be good to learn design patterns, and effective programming. First version's were available on Sourceforge. Couple years later I manage to publish my library on maven cetral repo. Over the years I built a small ecosystem around this library. Feel free to check my other projects that use this one.

Available functions:

+,-,*,/ with (), power(^) Sin, cos, tg, ctg, min, max, fib

example:

        Calculator calc = Calculator.createCalulator();
        BigDecimal result = calc.calculate("2^3*(12/6)+18/3+5.0/2");
        BigDecimal result2 = calc.calculate("3.678^2");
        BigDecimal resultSin = calc.calculate("sin(2)");
        BigDecimal resultSin2 = calc.calculate("sin(1+1)")
        BigDecimal resultCtg = calc.calculate("ctg(-1.65091)");
        BigDecimal min = calc.calculate("min(10, 8) + 10");

Maven:

        <dependency>
            <groupId>com.github.bartlomiej-gora</groupId>
            <artifactId>RPNLibrary</artifactId>
            <version>5.0.0</version>
        </dependency>

Changelog:

Version 5.0.0:

  • Moved to java 8
  • Refactoring, split Calculator class into smaller pieces, using java 8 functional interfaces
  • Added tests written in Kotest:

example:

class RPNFactoryTest : FreeSpec({

    val tested = RPNFactory(RPNChecker(DefaultStrategyProvider()))
            "should Return RPN" - {
                val text = "( 2 + 3 ) * 5"
                val result = tested.apply(text)
                result shouldBe "2 3 + 5 *"
            }
            "should Return RPN for Function call" - {
                val text = "sin ( 1 )"
                val result = tested.apply(text)
                result shouldBe "1 sin"
            }
            "should Return RPN for Function and equation" - {
                val text = "sin ( 1 ) + 27 * 8"
                val result = tested.apply(text)
                result shouldBe "1 sin 27 8 * +"
            }
            "should Return RPN for  two Functions call" - {
                val text = "sin ( 1 ) + ctg ( 0 )"
                val result = tested.apply(text)
                result shouldBe "1 sin 0 ctg +"
            }
})

Version 4.0.0:

Version 3.2.2:

  • Changed internal calculation from BigDecimal to Double in DefaultCalculator implementation

Version 3.2.1:

  • Fixed bug in divide operator, that caused: ex: "10/4 = 2, and not 2.5", "5/2 = 2, and not 2.5"
  • Changed RoundinMode from HALF_UP, to HALF_EVEN
  • Changed internal calculation type from BigDecimal to Double

Version 3.2.1-SNAPSHOT:

  • Fixed bug in divide operator, that caused: ex: "10/4 = 2, and not 2.5", "5/2 = 2, and not 2.5"
  • Changed RoundinMode from HALF_UP, to HALF_EVEN
  • Changed internal calculation type from BigDecimal to Double

Version 3.2.0:

IMPORTANT:
Changed package names from

    pl.bgora.rpn

to

com.github.bgora.rpnlibrary

Fixed bug, that prevented from exucuting functions with multiple parameters.

New functions:
max() - takes two parameters, returns greater one
min() - take two parameters, returns less one
fib() - Fibonacci number

Refactor:

Changed createCalulator, and getDefaultEngine to use CalculationEngine interface

    /**
     * Creates AdvanceCalculator with given CalculatorEngine
     *
     * @param engine CalculationEngine implementation
     * @return AdvanceCalculator
     */
    public CalculatorInterface createCalulator(CalculationEngine engine) {
        return new AdvancedCalculator(RoundingMode.HALF_UP, engine);
    }


    /**
     * Return default CalculationEngine implementation
     *
     * @return CalculatorEngine
     */
    public CalculationEngine getDefaultEngine() {
        return new CalculatorEngine(StrategiesUtil.DEFAULT_OPERATORS, StrategiesUtil.DEFAULT_FUNCTIONS);
    }

Version 3.1.0:

  • Added package pl.bgora.rpn.advanced
  • Added AdvancedCalculatorFactory

The advanced Calculator works with CalculationEngine, which uses strategy pattern to run. please see:
pl.bgora.rpn.AbstractOperatorStrategy
pl.bgora.rpn.AbstractFunctionStrategy

Example 1:

        AdvancedCalculatorFactory advancedCalculatorFactory = new AdvancedCalculatorFactory();
        calc = advancedCalculatorFactory.createCalulator();

Example 2:

Assume that you want to add a function sqrt(number), which will return The square root , You will have to extend AbstractFunctionStrategy like this:

public class SqrtFunctionStrategy extends AbstractFunctionStrategy {
    public SqrtFunctionStrategy() {
        super("sqrt", 1, RoundingMode.HALF_EVEN);
    }

    @Override
    public BigDecimal execute(String... params) {
        return java.math.BigDecimal.valueOf(Math.sqrt(x));
    }
}

And then you can add your function like that:

        CalculatorInterface calc;
        AdvancedCalculatorFactory advancedCalculatorFactory = new AdvancedCalculatorFactory();
        CalculatorEngine engine = advancedCalculatorFactory.getDefaultEngine();
        engine.addFunctionStartegy(new SqrtFunctionStrategy());
        calc = advancedCalculatorFactory.createCalulator(engine);

Example 3:

Assume that you want to add a function max(number, number), which will return greater value, You will have to extend AbstractFunctionStrategy like this:

public class MaxFunctionStrategy extends AbstractFunctionStrategy {
    public MaxFunctionStrategy() {
        super("max", 2, RoundingMode.HALF_EVEN);
    }

    @Override
    public BigDecimal execute(String... params) {
        String first = params[0];
        String second = params[1];
        BigDecimal result = //do you calculation here
        return result; //result;
    }
}

And then you can add your function like that:

        CalculatorInterface calc;
        AdvancedCalculatorFactory advancedCalculatorFactory = new AdvancedCalculatorFactory();
        CalculatorEngine engine = advancedCalculatorFactory.getDefaultEngine();
        engine.addFunctionStartegy(new MaxFunctionStrategy());
        calc = advancedCalculatorFactory.createCalulator(engine);

rpnlibrary's People

Contributors

bartgora avatar codacy-badger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rpnlibrary's Issues

refactor to new version

Create a refactor for the new version.
Use good practices and Joshua Bloch's effective java 3rd

Refacotring

Think about refoctor of DefaultCalculator and FunctionCalculator

sin(-1) returns NPE

Tested on calculator view.
12+sin(-1)*80 returned server 500.
cause: NPE,
#stack:


java.util.NoSuchElementException: null
    at java.util.LinkedList.removeFirst(LinkedList.java:270) ~[na:1.8.0_65]
    at java.util.LinkedList.pop(LinkedList.java:801) ~[na:1.8.0_65]
    at pl.bgora.rpn.FunctionsCalculator.getResult(FunctionsCalculator.java:235) ~[RPNLibrary-2.0.jar:na]
    at pl.bgora.rpn.FunctionsCalculator.calculate(FunctionsCalculator.java:46) ~[RPNLibrary-2.0.jar:na]
    at pl.bgora.calculator.web.rest.RestCalculatorController.calculate(RestCalculatorController.java:20) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]

Create Advanced Calculator

Create branch for the advanced calculator.
Advanced Calculator is implementation that will give possibility to add your own functions to the rpn calculation.

White space between operand caused index out of bounds

Input: "1+2 + sin(1)"
Stack trace:

2016-04-02T22:32:00.628375+00:00 app[web.1]: 2016-04-02 22:32:00.627 ERROR 3 --- [nio-4998-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.StringIndexOutOfBoundsException: String index out of range: 0] with root cause
2016-04-02T22:32:00.628426+00:00 app[web.1]:
2016-04-02T22:32:00.628428+00:00 app[web.1]: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
2016-04-02T22:32:00.628429+00:00 app[web.1]: at java.lang.String.charAt(String.java:658) ~[na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628430+00:00 app[web.1]: at pl.bgora.rpn.FunctionsDefaultChecker.isDigit(FunctionsDefaultChecker.java:40) ~[RPNLibrary-2.0.jar!/:na]
2016-04-02T22:32:00.628447+00:00 app[web.1]: at pl.bgora.rpn.FunctionsCalculator.createRPN(FunctionsCalculator.java:146) ~[RPNLibrary-2.0.jar!/:na]
2016-04-02T22:32:00.628448+00:00 app[web.1]: at pl.bgora.rpn.FunctionsCalculator.calculate(FunctionsCalculator.java:44) ~[RPNLibrary-2.0.jar!/:na]
2016-04-02T22:32:00.628449+00:00 app[web.1]: at pl.bgora.calculator.web.rest.RestCalculatorController.calculate(RestCalculatorController.java:20) ~[classes!/:na]
2016-04-02T22:32:00.628449+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628450+00:00 app[web.1]: at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628451+00:00 app[web.1]: at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628451+00:00 app[web.1]: at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628452+00:00 app[web.1]: at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628453+00:00 app[web.1]: at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628454+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628455+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628461+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628462+00:00 app[web.1]: at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628463+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628464+00:00 app[web.1]: at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628465+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628466+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628466+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628467+00:00 app[web.1]: at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) ~[spring-webmvc-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628468+00:00 app[web.1]: at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628468+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628469+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628469+00:00 app[web.1]: at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628470+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628471+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628476+00:00 app[web.1]: at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628477+00:00 app[web.1]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628477+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628478+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628479+00:00 app[web.1]: at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628479+00:00 app[web.1]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628480+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628481+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628481+00:00 app[web.1]: at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628482+00:00 app[web.1]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628483+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628483+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628484+00:00 app[web.1]: at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628485+00:00 app[web.1]: at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar!/:4.2.5.RELEASE]
2016-04-02T22:32:00.628485+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628486+00:00 app[web.1]: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628486+00:00 app[web.1]: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628489+00:00 app[web.1]: at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628487+00:00 app[web.1]: at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628489+00:00 app[web.1]: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628488+00:00 app[web.1]: at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628490+00:00 app[web.1]: at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628487+00:00 app[web.1]: at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628491+00:00 app[web.1]: at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628491+00:00 app[web.1]: at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628492+00:00 app[web.1]: at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628492+00:00 app[web.1]: at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628493+00:00 app[web.1]: at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628494+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628494+00:00 app[web.1]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628497+00:00 app[web.1]: at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar!/:8.0.32]
2016-04-02T22:32:00.628498+00:00 app[web.1]: at java.lang.Thread.run(Thread.java:745) [na:1.8.0_74-cedar14]
2016-04-02T22:32:00.628498+00:00 app[web.1]:
2016-04-02T22:32:27.061404+00:00 heroku[router]: at=info method=GET path="/calculate/1+2+sin(1)" host=calculatorweb.herokuapp.com request_id=1a498263-6b4e-47a1-aeaa-89beb483a117 fwd="87.101.22.98" dyno=web.1 connect=1ms service=20ms status=200 bytes=239

Design Builder for Calculator

As complexity of the calculator grows, introduce a simpler way to customize it for external users.
Builder, or factory should allow library users to modify some, choose by them, properties, and behaviors, and leave other as default.
Think about remodel of the EngineModel maybe.

Update version number

According to versioning documentation the version should be 3.0 as it is not back compatibile with the version from sourceforge.net (changed package names)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.