-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c2a2e3
commit 099b066
Showing
46 changed files
with
358 additions
and
708 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name := "homework_3" | ||
name := "Lecture4" | ||
|
||
version := "0.1" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,46 @@ | ||
# Домашнее задание №3 (курс Scala, Naumen) | ||
|
||
Задания описаны в файле Exercises.scala в sbt проекте, который находится в папке /homeworks/homework_3 | ||
Ниже приводится вспомогательная информация которая поможет вам справится с заданием. | ||
Как всегда - необходимо написать тесты к своим решениям (минимум 3 теста к каждой реализованной функции решения). | ||
|
||
## 1. Определение типа в рантайме | ||
|
||
Для определения простого, не параметризованного типа в рантайме в Scala есть несколько способов: | ||
- использовать x.isInstanceOf[SomeClass] | ||
- паттерн матчинг (https://docs.scala-lang.org/ru/tour/pattern-matching.html) | ||
- использовать x.getClass | ||
- рефлексия | ||
- и другие | ||
|
||
Для приведения типов (type cast) есть 2 способа: | ||
- x.asInstanceof[SomeClass] | ||
- паттерн матчинг | ||
|
||
## 2. Отсутствие правильного значения | ||
|
||
В программировании довольно часто может отсутствовать значение вычисления функции. Напирмер в функции деления, значение деления на 0 не определено. | ||
|
||
Отсутствие верного значения, возвращаемого из какого либо метода или функции, или невозможность верно вычислить результат можно кодировать и обрабатывать в программе разными способами. | ||
|
||
Иногда, для этого используются целочисленные коды ошибки - это распространено в языке Си и системном программировании. | ||
|
||
Иногда для этого используется null, а иногда для этого используется выбрасывание исключения (exception). | ||
Это распространено в современных ООП языках (Java, C#, python, JavaScript). | ||
|
||
В функциональных языках и в Scala в частности - любят кодировать отсуствие значений с помощью специальных контейнерных типов. | ||
Самый простой из них - тип список, или другие коллекции похожие на список (seq, set, array, stream, и др.). Если у нас есть корректные значения которые возвращает функция - мы возвращаем список этих значений. Особенно это удобно, когда верных значений может быть несколько - например в задаче нахождения всех делителей числа. Пустой список - означает отсутсвие таких значений. | ||
|
||
Также есть тип Option. В нем явно кодируется отсутствие значение с помощью объекта None, а наличие значение в виде контейнера Some(x). | ||
Для краткого ознакомления для работы с Option подойдет данная статья - https://www.tutorialspoint.com/scala/scala_options.htm . | ||
Для более глубокого - https://danielwestheide.com/blog/the-neophytes-guide-to-scala-part-5-the-option-type/ . | ||
|
||
## 3. Параметры типов и отношение подтипов | ||
|
||
Для решения задания №3 достаточно обратиться к материалам лекции. | ||
|
||
|
||
|
||
|
||
|
||
|
||
Необходимо реализовать класс простой электронной таблицы (класс Table). | ||
<br><br> | ||
Таблица имеет фиксированную ширину и длину (параметры конструктора Table). | ||
<br> | ||
<br>Таблица должна быть представлена следующими типами ячеек (базовый интерфейс Cell): | ||
<br> -Пустая ячейка (класс EmptyCell), | ||
<br> -Ячейка с 32-битным целым числом (класс NumberCell), | ||
<br> -Ячейка с текстом (класс StringCell), | ||
<br> -Ячейка, содержащая ссылку на другую ячейку (класс ReferenceCell). | ||
<br> | ||
<br>По умолчанию, все ячейки таблицы являются пустыми (класс "EmptyCell") | ||
<br> | ||
<br>Таблица (класс Table) должна предоставлять следующие общедоступные методы: | ||
<br> -getCell(ix: Int, iy: Int): Option\[Cell\] (возвращает ячейку по индексам строки и столбца, | ||
<br> либо "None", если ix или iy вне границ таблицы), | ||
<br> -setCell(ix: Int, iy: Int, cell: Cell): Unit (устанавливает ячейку cell в указанные столбец и строку), | ||
<br> здесь ix - индекс колонки (ix>=0), iy - индекс строки (iy>=0), | ||
<br> cell - ячейка таблицы, представленная конкретной реализацией (EmptyCell/NumberCell/StringCell/ReferenceCell). | ||
<br> | ||
<br>Таблица хранит коллекцию ячеек. Так как определён метод "setCell", можно использовать мутабельную коллекцию | ||
<br>(package scala.collection.mutable). | ||
<br> | ||
<br>Каждая ячейка должна предоставлять основной конструктор, посредством которого инициализируется значение ячейки. | ||
<br>Например, class NumberCell(number: Int) extends Cell . | ||
<br>В случае "EmptyCell" какого-либо конструктора не требуется. | ||
<br>В случае "ReferenceCell": class ReferenceCell(ix: Int, iy: Int, table: Table) extends Cell, где ix и iy - | ||
<br>индексы столбца и строки ячейки (на которую ведёт ссылка) таблицы table (которой принадлежит ячейка, на которую ведёт ссылка). | ||
<br> | ||
<br>Каждая ячейка (реализация интерфейса Cell) должна предоставлять общедоступный метод toString(): String, | ||
<br>который возвращает хранящееся в ней значение в виде строки (типа String). | ||
<br>В случае "EmptyCell" метод "toString" должен возвращать значение "empty" | ||
<br>В случае "ReferenceCell" метод "toString" должен возвращать значение той ячейки, на которую определена ссылка. | ||
<br>В случае, если "ReferenceCell" ячейка ссылается на индекс ячейки, находящийся за границами таблицы, метод "toString" | ||
<br>должен возвращать значение "outOfRange" | ||
<br>В случае "циклических" ссылок (если, например, "ReferenceCell" ячейка ссылается на другую "ReferenceCell" ячейку, | ||
<br>которая вновь ссылается на первую), метод "toString" должен возвращать значение "cyclic". | ||
<br> | ||
<br>При реализации можно учесть, что двумерный список можно однозначно выразить одномерным: | ||
<br> i = ix + iy * w, | ||
<br>где i - индекс одномерного списка, ix - индекс колонки двумерного списка, iy - индекс строки двумерного списка, | ||
<br>w - ширина (количество колонок) двумерного списка. | ||
<br> | ||
<br>Необходимо, чтобы реализация успешно проходила юнит-тесты <a href='https://github.com/naumen-student/naumen.scala.course.2023.autumn/tree/master/homeworks/homework_3/src/test/scala'>(src/test/scala/Test.scala)</a> |
File renamed without changes.
File renamed without changes.
49 changes: 0 additions & 49 deletions
49
homeworks/homework_3/src/main/scala/homework_3/Exercises.scala
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import utest._ | ||
|
||
object Test extends TestSuite { | ||
val tests = Tests { | ||
'test_createTable - { | ||
val table = new Table(3, 3) | ||
for (i <- 0 until 9) { | ||
assert(table.getCell(i / 3, i % 3).map(_.toString) == Some("empty")) | ||
} | ||
assert(table.getCell(0, -1).map(_.toString) == None) | ||
assert(table.getCell(-1, 0).map(_.toString) == None) | ||
assert(table.getCell(9, 8).map(_.toString) == None) | ||
assert(table.getCell(8, 9).map(_.toString) == None) | ||
} | ||
'test_numberCell - { | ||
val table = new Table(2, 2) | ||
val cellInt00 = new NumberCell(5) | ||
val cellInt11 = new NumberCell(2147483647) | ||
table.setCell(0, 0, cellInt00) | ||
table.setCell(1, 1, cellInt11) | ||
assert(table.getCell(0, 0).map(_.toString) == Some("5")) | ||
assert(table.getCell(0, 1).map(_.toString) == Some("empty")) | ||
assert(table.getCell(1, 0).map(_.toString) == Some("empty")) | ||
assert(table.getCell(1, 1).map(_.toString) == Some("2147483647")) | ||
} | ||
'test_stringCell - { | ||
val table = new Table(2, 2) | ||
val cellStr01 = new StringCell("01") | ||
val cellStr10 = new StringCell("10") | ||
table.setCell(0, 1, cellStr01) | ||
table.setCell(1, 0, cellStr10) | ||
assert(table.getCell(0, 0).map(_.toString) == Some("empty")) | ||
assert(table.getCell(0, 1).map(_.toString) == Some("01")) | ||
assert(table.getCell(1, 0).map(_.toString) == Some("10")) | ||
assert(table.getCell(1, 1).map(_.toString) == Some("empty")) | ||
} | ||
'test_referenceCell - { | ||
val table = new Table(3, 3) | ||
/*ix = 0*/ | ||
val cellStr00 = new StringCell("00") | ||
val cellRef01 = new ReferenceCell(0, 2, table) | ||
val cellRef02 = new ReferenceCell(0, 1, table) | ||
/*ix = 1*/ | ||
val cellInt10 = new NumberCell(10) | ||
val cellInt11 = new NumberCell(11) | ||
val cellRef12 = new ReferenceCell(0, 0, table) | ||
/*ix = 2*/ | ||
val cellEmpty20 = new EmptyCell | ||
val cellRef21 = new ReferenceCell(1, 1, table) | ||
val cellRef22 = new ReferenceCell(2, 1, table) | ||
table.setCell(0, 0, cellStr00) | ||
table.setCell(0, 1, cellRef01) | ||
table.setCell(0, 2, cellRef02) | ||
table.setCell(1, 0, cellInt10) | ||
table.setCell(1, 1, cellInt11) | ||
table.setCell(1, 2, cellRef12) | ||
table.setCell(2, 0, cellEmpty20) | ||
table.setCell(2, 1, cellRef21) | ||
table.setCell(2, 2, cellRef22) | ||
for (i <- 0 until 9) { | ||
val value = table.getCell(i / 3, i % 3).get.toString | ||
i match { | ||
case 0 => assert(value == "00") | ||
case 1 => assert(value == "cyclic") | ||
case 2 => assert(value == "cyclic") | ||
case 3 => assert(value == "10") | ||
case 4 => assert(value == "11") | ||
case 5 => assert(value == "00") | ||
case 6 => assert(value == "empty") | ||
case 7 => assert(value == "11") | ||
case 8 => assert(value == "11") | ||
case _ => assert(false) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
/.idea | ||
/target | ||
project/target | ||
# Project exclude paths | ||
/project/project/target/ | ||
/project/target/ | ||
/target/ | ||
/target/scala-2.12/classes/ | ||
/target/scala-2.12/test-classes/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
name := "Lecture4" | ||
ThisBuild / version := "0.1.0-SNAPSHOT" | ||
|
||
version := "0.1" | ||
|
||
scalaVersion := "2.12.10" | ||
ThisBuild / scalaVersion := "2.12.10" | ||
|
||
libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test" | ||
|
||
testFrameworks += new TestFramework("utest.runner.Framework") | ||
testFrameworks += new TestFramework("utest.runner.Framework") | ||
|
||
lazy val root = (project in file(".")) | ||
.settings( | ||
name := "homework-1" | ||
) |
Oops, something went wrong.