---
# System prepended metadata

title: 'Lab 1: SBT & Rational'

---

# Lab 1: SBT & Rational
> **Due Date**: 30.01.2020 9:00 AM


## Stage 1 – Simple Build Tool (sbt)

1. Download and Install IntelliJ IDEA. [Link](https://www.jetbrains.com/idea/download/)
2. Download and Install the Scala Plugin: [Link](https://plugins.jetbrains.com/plugin/1347-scala)

![](https://i.imgur.com/cQCDpvl.png)

<!-- 3. Congratz! You found an easter egg! Contact your TA for bonus points -->
4. Create a new sbt project using these versions:
- Java Version: `1.8`
- Scala Version: `2.12.10`
- sbt Version: `1.2.8`

Make sure that you selected "Use sbt shell for imports and build".

![](https://i.imgur.com/c4PSNCh.png)

5. Create a package `<your-name>.<your-surname>` in the directory `src/main/scala`.
6. Create a file `Rational.scala` in that package.

## Stage 2 – Rational

```scala
package <your-name>.<your-surname>

class Rational(n: Int, d: Int) { 
  require(d != 0)
  private val g = gcd(n.abs, d.abs)
  val numer = n / g
  val denom = d / g
  def this(n: Int) = this(n, 1)
  def + (that: Rational): Rational = new Rational(numer * that.denom + that.numer * denom, denom * that.denom)
  def + (i: Int): Rational = ???
  def - (that: Rational): Rational = new Rational(numer * that.denom - that.numer * denom, denom * that.denom)
  def - (i: Int): Rational = ???
  def * (that: Rational): Rational = new Rational(numer * that.numer, denom * that.denom)
  def * (i: Int): Rational = ???
  def / (that: Rational): Rational = new Rational(numer * that.denom, denom * that.numer)
  def / (i: Int): Rational = ???
  override def toString = numer + "/" + denom
  private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
```

Tasks:
1. Introduce a companion object `Rational` and move the `gcd` method into that object.
2. Make the constructor of `Rational` private and create a method called `apply` in the companion object, which will call the constructor.
3. Calculate the GCD of the numerator and the denominator in the `apply` method and invoke the constructor of `Rational` inside `apply` with normalized arguments.
4. Implement `def == (other: Rational): Boolean` method to the `Rational` class. Make sure that it outputs `true` for `Rational(4, 2)` and `Rational(2, 1)`. At this stage two objects should be equal iff all their member fields are equal.


## Stage 3 – Tests

Now we are going to write some unit-tests. Open your `build.sbt` file and add the following line:

```scala
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test
```

This line brings the [ScalaTest](http://www.scalatest.org/) framework as a dependency of your project. It will be used to create and run test suites for your code.

Similarly to Stage 1, create a package `<your-name>.<your-surname>` in the directory `src/test/scala`. Notice the directory `test` – it will contain all test-related code and resources. The ScalaTest framework will be unavailable in the main code.

Create a file `RationalSpec.scala` in the `test` section and paste the following code:
```scala
package <your-name>.<your-surname>

import org.scalatest.{FlatSpec, Matchers}

class RationalSpec extends FlatSpec with Matchers {
  "==" should "be correct for 2/1 and 4/2" in {
    val isEqual = Rational(2, 1) == Rational(4, 2)
    isEqual shouldBe true
  }
}
```

You can run the spec via your IDE – notice the green next to class name and individual tests, as well as via your sbt shell – run `test` command in the panel `sbt shell` below. Try to do it both ways.

Task:
- Implement 2 tests for any desired operations of `Rational`

## Stage 4 - REPL

Scala has a convinient REPL that you can use to test your code. To start the REPL with all the dependencies of sbt project - run `console` command in the sbt shell.

Tasks:
- Import your `Rational` implementation into the scope of REPL
- Create two instances and perform any operation
- Screenshot the REPL panel with all entered instructions and outputs

## Deliverables

1. zip archive with your sbt project – 0.5 points
2. screenshot of your REPL output – 0.5 points
