---
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, 10, 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>
                On <code>line 9</code> the client for our model is created.
            </li>
            <li>
                On <code>line 10</code> the method <code>ask()</code> is called. 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>






