Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework 4 Boris Liskov РИ-370012 #195

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.DS_Store
Binary file added homeworks/.DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions homeworks/homework_4/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.idea
/target
*DS_Store
project/target
9 changes: 9 additions & 0 deletions homeworks/homework_4/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name := "Lecture4"

version := "0.1"

scalaVersion := "2.12.10"

libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"

testFrameworks += new TestFramework("utest.runner.Framework")
46 changes: 46 additions & 0 deletions homeworks/homework_4/homework_4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Домашнее задание №4 (курс Scala, Naumen)


Необходимо реализовать класс простой электронной таблицы (класс 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.2019.autumn/tree/master/homeworks/homework_4/src/test/scala'>(src/test/scala/Test.scala)</a>
1 change: 1 addition & 0 deletions homeworks/homework_4/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version = 1.3.3
3 changes: 3 additions & 0 deletions homeworks/homework_4/src/main/scala/Cell.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trait Cell {
def toString: String
}
3 changes: 3 additions & 0 deletions homeworks/homework_4/src/main/scala/EmptyCell.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class EmptyCell extends Cell{
override def toString: String = "empty"
}
3 changes: 3 additions & 0 deletions homeworks/homework_4/src/main/scala/NumberCell.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class NumberCell(var value: Int) extends Cell {
override def toString : String = value.toString
}
14 changes: 14 additions & 0 deletions homeworks/homework_4/src/main/scala/ReferenceCell.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class ReferenceCell(var ix: Int, var iy: Int, table: Table) extends Cell {
override def toString: String = {
val referenceCell = table.getCell(ix, iy)
referenceCell match {
case some => some.get match {
case ref: ReferenceCell =>
if (table.getCell(ref.ix, ref.iy).contains(this)) "cyclic"
else ref.toString
case _ => referenceCell.get.toString
}
case None => "outOfRange"
}
}
}
3 changes: 3 additions & 0 deletions homeworks/homework_4/src/main/scala/StringCell.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class StringCell(var value: String) extends Cell {
override def toString: String = value
}
21 changes: 21 additions & 0 deletions homeworks/homework_4/src/main/scala/Table.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Table(val width: Int, val height: Int) {

private val table: scala.collection.mutable.Seq[Cell] = scala.collection.mutable.Seq.fill(width * height)(new EmptyCell)

def isOnTable(ix: Int, iy: Int): Boolean = (ix >= 0 && ix < width && iy >= 0 && iy < height)

def setCell(ix: Int, iy: Int, cell: Cell): Unit = {
if (isOnTable(ix, iy)) {
table(ix + width * iy) = cell
}
}

def getCell(ix: Int, iy: Int): Option[Cell] = {
if(isOnTable(ix, iy)) {
Some(table(ix + width * iy))
}
else {
None
}
}
}
77 changes: 77 additions & 0 deletions homeworks/homework_4/src/test/scala/Test.scala
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)
}
}
}
}
}