---
active_crumb: Calculator <code><sub>ex</sub></code>
layout: documentation
id: calculator
fa_icon: fa-cube
---

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<div class="col-md-8 second-column example">
    <section id="overview">
        <h2 class="section-title">Overview <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            This example provides a very simple calculator implementation.
            It supports restricted set of arithmetic operations for numeric values.
        </p>
        <p>
            <b>Complexity:</b> <span class="complexity-one-star"><i class="fas fa-star"></i> <i class="far fa-star"></i> <i class="far fa-star"></i></span><br/>
            <span class="ex-src">Source code: <a target="github" href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples/caclulator">GitHub <i class="fab fa-fw fa-github"></i></a><br/></span>
            <span class="ex-review-all">Review: <a target="github" href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples">All Examples at GitHub <i class="fab fa-fw fa-github"></i></a></span>
        </p>
    </section>
    <section id="new_project">
        <h2 class="section-title">Create New Project <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            You can create new Scala projects in many ways - we'll use SBT
            to accomplish this task. Make sure that <code>build.sbt</code> file has the following content:
        </p>
        <pre class="brush: js, highlight: []">
            ThisBuild / version := "0.1.0-SNAPSHOT"
            ThisBuild / scalaVersion := "3.1.3"
            lazy val root = (project in file("."))
              .settings(
                name := "NLPCraft Calculator Example",
                version := "{{site.latest_version}}",
                libraryDependencies += "org.apache.nlpcraft" % "nlpcraft" % "{{site.latest_version}}",
                libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.14" % "test"
              )
        </pre>
        <p><b>NOTE: </b>use the latest versions of Scala and ScalaTest.</p>
        <p>Create the following files so that resulting project structure would look like the following:</p>
        <ul>
            <li><code>CalculatorModel.scala</code> - Scala class, model implementation.</li>
            <li><code>CalculatorModelSpec.scala</code> - Scala tests class, which allows to test your model.</li>
        </ul>
        <pre class="brush: plain, highlight: [8, 12]">
            |  build.sbt
            +--project
            |    build.properties
            \--src
               +--main
               |  \--scala
               |     \--demo
               |          CalculatorModel.scala
               \--test
                  \--scala
                     \--demo
                          CalculatorModelSpec.scala
        </pre>
    </section>
    <section id="model">
        <h2 class="section-title">Data Model<a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            All element definitions are provided programmatically inside Scala model <code>CalculatorModel</code> class.
            Open <code>src/main/scala/demo/<b>CalculatorModel.scala</b></code> file and replace its content with the following code:
        </p>
        <pre class="brush: scala, highlight: [11, 12, 14, 21, 22, 23, 31, 35, 41, 47, 56, 61]">
            package demo

            import edu.stanford.nlp.pipeline.StanfordCoreNLP
            import org.apache.nlpcraft.*
            import org.apache.nlpcraft.annotations.*
            import org.apache.nlpcraft.nlp.entity.parser.stanford.*
            import org.apache.nlpcraft.nlp.parsers.*
            import org.apache.nlpcraft.nlp.token.parser.stanford.NCStanfordNLPTokenParser
            import java.util.Properties

            object CalculatorModel:
                private val OPS: Map[String, (Int, Int) => Int] =
                    Map("+" -> (_ + _), "-" -> (_ - _), "*" -> (_ * _), "/" -> (_ / _))
                private val PIPELINE: NCPipeline =
                    val props = new Properties()
                    props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner")

                    val stanford = new StanfordCoreNLP(props)

                    new NCPipelineBuilder().
                        withTokenParser(new NCStanfordNLPTokenParser(stanford)).
                        withEntityParser(new NCNLPEntityParser(t => OPS.contains(t.getText))).
                        withEntityParser(new NCStanfordNLPEntityParser(stanford, Set("number"))).
                        build

                private def nne(e: NCEntity): Int =
                    java.lang.Double.parseDouble(e[String]("stanford:number:nne")).intValue

            import CalculatorModel.*

            class CalculatorModel extends NCModelAdapter(
                NCModelConfig("nlpcraft.calculator.ex", "Calculator Example Model", "1.0"),
                PIPELINE
            ) :
                private var mem: Option[Int] = None

                private def calc(x: Int, op: String, y: Int): NCResult =
                    mem = Some(OPS.getOrElse(op, throw new IllegalStateException()).apply(x, y))
                    NCResult(mem.get)

                @NCIntent(
                    "intent=calc options={ 'ordered': true }" +
                    "   term(x)={# == 'stanford:number'}" +
                    "   term(op)={has(list('+', '-', '*', '/'), meta_ent('nlp:token:text')) == true}" +
                    "   term(y)={# == 'stanford:number'}"
                )
                def onMatch(
                    ctx: NCContext,
                    im: NCIntentMatch,
                    @NCIntentTerm("x") x: NCEntity,
                    @NCIntentTerm("op") op: NCEntity,
                    @NCIntentTerm("y") y: NCEntity
                ): NCResult =
                    calc(nne(x), op.mkText, nne(y))

                @NCIntent(
                    "intent=calcMem options={ 'ordered': true }" +
                    "   term(op)={has(list('+', '-', '*', '/'), meta_ent('nlp:token:text')) == true}" +
                    "   term(y)={# == 'stanford:number'}"
                )
                def onMatchMem(
                    ctx: NCContext,
                    im: NCIntentMatch,
                    @NCIntentTerm("op") op: NCEntity,
                    @NCIntentTerm("y") y: NCEntity
                ): NCResult =
                    calc(mem.getOrElse(throw new NCRejection("Memory is empty.")), op.mkText, nne(y))
        </pre>
        <p>
            There are two intents with simple logic. First returns arithmetic operation result with two input parameters,
            second uses last operation result instead of the first argument. Note also that the arithmetic notations
            (<code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>) are used as is for without any additional synonyms.
            Let's review this implementation step by step:
        </p>
        <ul>
            <li>
                <code>Line 11</code> declares <code>CalculatorModel</code>, model companion object, which contains
                static content and helper methods.
            </li>
            <li>
                <code>Line 12</code> defines arithmetic operations map with notations as keys and functions definitions as values.
            </li>
            <li>
                <code>Line 14</code> defines model pipeline based on three built components.
                <code>Line 21</code> defines Stanford token parser <code>NCStanfordNLPTokenParser</code>
                (we use Stanford NLP components in this example).
            </li>
            <li>
                <code>Line 22</code> declares entity parser <code>NCNLPEntityParser</code>
                which allows to find arithmetic operations notations.
            </li>
            <li>
                <code>Line 23</code> defines entity parser <code>NCStanfordNLPEntityParser</code>,
                which allows to find numerics in the text input.
            </li>
            <li>
                <code>Line 31</code> declares <code>CalculatorModel</code> model class.
            </li>
            <li>
                <code>line 35</code> declares variable named <code>mem</code> which act as a holder for the last operation result.
            </li>
            <li>
                <code>Lines 41 and 47</code> annotate intents <code>calc</code> and its callback method <code>onMatch()</code>.
                Intent <code>calc</code> requires one arithmetic operation notation and two numerics as its arguments.
            </li>
            <li>
                <code>Lines 56 and 61</code> annotate intents <code>calcMem</code> and its callback method <code>onMatchMem()</code>.
                Intent <code>calcMem</code> requires one arithmetic operation notation and one numeric as its second arguments.
                Note that it attempts to use last operation result as its first argument, if one exists.
            </li>
        </ul>
    </section>

    <section id="testing">
        <h2 class="section-title">Testing <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            The test provided in <code>CalculatorModelSpec</code> allows to check that all input test sentences are
            processed correctly and trigger the expected intents <code>calc</code> or <code>calcMem</code>:
        </p>
        <pre class="brush: scala, highlight: [9, 11, 15, 16]">
            package demo

            import org.apache.nlpcraft.*
            import org.scalatest.funsuite.AnyFunSuite
            import scala.util.Using

            class CalculatorModelSpec extends AnyFunSuite:
                test("test") {
                    Using.resource(new NCModelClient(new CalculatorModel())) { client =>
                        def check(txt: String, v: Int): Unit =
                            require(v == client.ask(txt, "userId").getBody)

                        check("2 + 2", 4)
                        check("3 * 4", 12)
                        check("/ two", 6)
                        check("+ twenty two", 28)
                        check("7 + 2", 9)
                    }
                }
        </pre>
        <ul>
            <li>
                <code>Line 9</code> creates the client for our model.
            </li>
            <li>
                <code>Line 11</code> calls the method <code>ask()</code>. Its result is checked with expected value.
            </li>
            <li>
                Note that test sentences on <code>lines 15, 16</code> trigger <code>calcMem</code> intent while other sentences
                trigger <code>calc</code> intent.
            </li>
        </ul>
        <p>
            You can run this test via SBT task <code>executeTests</code> or using IDE.
        </p>
        <pre class="brush: scala, highlight: []">
            $ sbt executeTests
        </pre>
    </section>
    <section>
        <h2 class="section-title">Done! 👌 <a href="#"><i class="top-link fas fa-fw fa-angle-double-up"></i></a></h2>
        <p>
            You've created calculator model and tested it.
        </p>
    </section>
</div>
<div class="col-md-2 third-column">
    <ul class="side-nav">
        <li class="side-nav-title">On This Page</li>
        <li><a href="#overview">Overview</a></li>
        <li><a href="#new_project">New Project</a></li>
        <li><a href="#model">Data Model</a></li>
        <li><a href="#code">Model Class</a></li>
        <li><a href="#testing">Testing</a></li>
        {% include quick-links.html %}
    </ul>
</div>






