Arvutiteaduse instituut
  1. Kursused
  2. 2019/20 sügis
  3. Programmeerimiskeeled (MTAT.03.006)
EN
Logi sisse

Programmeerimiskeeled 2019/20 sügis

  • Info
  • Õppekava
  • Moodle
  • Loengud & Praksid
  • Lisamaterjalid
  • Küsi abi! (Fleep)

Scala baastest

1. Objektide väärtustamine

Olgu defineeritud järgmised klassid:

  trait IntSet {
    def +(x: Int): IntSet
  }

  case class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {
    def +(x: Int): IntSet =
      if (x < elem) NonEmpty(elem, left + x, right)
      else if (x > elem) NonEmpty(elem, left, right + x)
      else this
  }

  case object Empty extends IntSet {
    def +(x: Int): IntSet = NonEmpty(x, Empty, Empty)
  }

Ülesanne on näidata, kuidas avaldist NonEmpty(5, Empty, Empty) + 3 väärtustatakse.

Lahendus

  • NonEmpty(5, Empty, Empty) + 3
  • if (3 < 5) NonEmpty(5, Empty + 3, Empty) else if (3 > 5) NonEmpty(5, Empty, Empty + 3) else NonEmpty(5, Empty, Empty)
  • NonEmpty(5, Empty + 3, Empty)
  • NonEmpty(5, NonEmpty(3, Empty, Empty), Empty)

NB! Tähtis on siin arvutusmudel endale selgeks teha. Klassid võivad muutuda ja baastesti klassihiarhia võib olla täiesti tähendusetu (nagu Kala klassid). Minimaalselt tuleks välja tuua avaldise kuju vahetult enne antud klassi operatsioonide rakendamist.

2. Puhtad funktsioonid

Defineerige funktsioon sumLen(list: List[Int]): (Int, Int), mis arvutab korraga summa ja elementide arv listis. Seega peaks kehtima SumLen(xs)._1 == xs.sum ja sumLen(xs)._2 = xs.size.

  • Lahendus peab olema ilma kõrvalefektideta!
  • Peab töötama ka pikematel listidel (lahendus peab olema sabarekursiivne).

Lahendus

  def sumLen(list: List[Int]): (Int, Int) = {
    def helper(list: List[Int], sum: Int, len: Int): (Int, Int) = list match {
      case Nil => (sum, len)
      case x :: xs => helper(xs, sum + x, len + 1)
    }
    helper(list, 0, 0)
  }

Siin võib ka lahendada foldiga:
list.foldLeft(0,0){case ((sum,len), x) => (sum + x, len + 1)}

3. Collection klasside kasutamine

Meil on selline klassi definitsioon:

    case class Person(name: String, age: Int, children: Seq[Person] = Seq.empty) {
      override def toString: String = s"Olen $name, $age."
    }

Defineerige funktsioon smallChildren(ppl: Seq[Person]): Set[(String, Person)], mille sisendiks on inimeste järjend ja tulemuseks on paaride hulk, kus on kõikide nende inimeste laste nimed koos oma vanemaga, aga tahame ainult need lapsed, kes on alla 18 aastat vana (ehk age < 18). Siin on kõik lahendused lubatud, aga for-avaldisega on ilmselt kõige lihtsam.

Võib proovida järgmise sisendandmete peal:

      val people = Seq(
        Person("Peeter", 23, Seq(Person("Elsa", 5), Person("Anna", 3))),
        Person("Carmen", 17, Seq(Person("Juhan", 1))),
        Person("Liina",  48, Seq(Person("Pelle", 12), Person("Alina", 23))))

      for ((laps, vanem) <- smallChildren(people)) {
        println(s"Lapse nimi: $laps. Vanema tutvustus: $vanem")
      }

Selle väljund on siis järgmine:

Lapse nimi: Elsa. Vanema tutvustus: Olen Peeter, 23.
Lapse nimi: Anna. Vanema tutvustus: Olen Peeter, 23.
Lapse nimi: Juhan. Vanema tutvustus: Olen Carmen, 17.
Lapse nimi: Pelle. Vanema tutvustus: Olen Liina, 48.

Lahendus

   def smallChildren(ppl: Seq[Person]): Set[(String, Person)] = {
      for {
        person <- ppl.toSet[Person]
        child <- person.children
        if child.age < 18
      } yield (child.name, person)
    }
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused