Compare commits

...

9 commits

Author SHA1 Message Date
Timofey Khoruzhii 594525aeeb solve 2023-04-02 00:47:19 +03:00
Anton Brovkin b79c3daa6f Homework 6 more tests fixed 2023-03-28 10:39:07 +03:00
Anton Brovkin 7a94db6196 Homework 6 more test added 2023-03-27 16:19:28 +03:00
Anton Brovkin b7568007b3 Homework 6 task description 2023-03-27 14:21:44 +03:00
Anton Brovkin a56cc694c6 Homework 6 task 2023-03-25 16:42:23 +03:00
Anton Brovkin cb78e90533 Lint instruction 2023-02-11 20:09:32 +03:00
Anton Brovkin d1c716856f Lint task fixed 2023-02-11 20:04:38 +03:00
Anton Brovkin ce9b994d34 Task project template 2023-02-11 19:58:56 +03:00
Anton Brovkin 177cf65c81 Task project template 2023-02-11 19:53:42 +03:00
24 changed files with 172 additions and 98 deletions

23
.github/workflows/scala.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Scala CI
on:
push:
branches:
- main
- 'homework/*'
pull_request:
branches:
- main
- 'homework/*'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: sbt test
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Formatting
run: sbt scalafmtCheck test:scalafmtCheck

8
.scalafmt.conf Normal file
View file

@ -0,0 +1,8 @@
binPack.parentConstructors = true
maxColumn = 120
includeCurlyBraceInSelectChains = false
align = most
version = "2.4.2"
trailingCommas = preserve
newlines.penalizeSingleSelectMultiArgList = false
newlines.alwaysBeforeMultilineDef = false

View file

@ -1,7 +1,11 @@
# Домашние задания по курсу Scala в бакалавриате МФТИ # Постановка задачи
Все домашние задания привязаны к лекциям по номеру. Каждое задание располагается в ветке *homework/lecture-N-M*, где N - номер семестра, M - номер лекции в семестре. Задание предназначено для освоения темы наследования типов в Scala. Нужно выполнить задания в:
* [TraitLineization](src/main/scala/mipt/homework6/TraitLineization.scala) реализовать алгоритм линеизации для множественного наследования типов
# Подготовка к выполнению домашнего задания
Для работы над домашними заданиями нужно: Для работы над домашними заданиями нужно:
* установить IntelliJ IDEA и подготовить ее для работы со Scala. Это описано в [инструкции по установке IDEA](docs/idea-install/install.md). * установить IntelliJ IDEA и подготовить ее для работы со Scala. Это описано в [инструкции по установке IDEA](docs/idea-install/install.md).
* сделать **приватный форк** данного репозитория. Это описано в [инструкции по созданию форка](docs/create-fork/private-fork.md). * сделать **приватный форк** данного репозитория. Это описано в [инструкции по созданию форка](docs/create-fork/private-fork.md).
* в проекте стоит настроить [форматирование в scalafmt](docs/code-style/code-style.md).

21
build.sbt Normal file
View file

@ -0,0 +1,21 @@
import _root_.sbt.Keys._
import wartremover.Wart
import wartremover.Wart._
name := "bachelor-homeworks"
version := "0.1"
scalaVersion := "2.13.10"
scalacOptions := List(
"-encoding",
"utf8",
"-feature",
"-unchecked",
"-deprecation",
"-language:_",
"-Ymacro-annotations"
)
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.0" % "test"
wartremoverErrors ++= Seq[Wart](Any, AsInstanceOf, Null, Return, Throw, While, MutableDataStructures)

View file

@ -0,0 +1,12 @@
# Настройка форматирования
Если не настроено форматирование, у вас будет падать таск lint на CI, который проверяет сode style.
Поэтому стоит настроить плагин scalafmt, который сам следит за кодстайлом и помогает переформатировать код как надо.
1. Перейти в File > Settings
2. Вбить в поиск `scalafmt`
3. Выбрать меню Editor > Code Style > Scala
4. Выбрать в качестве форматировщика `Scalafmt`
5. Отметить галочку "reformat on Save"! Тогда при явном сохранении исходника scalafmt автоматически обновит ваш файл.
![Scalafmt](images/scalafmt.png "scalafmt")

View file

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View file

@ -1,96 +0,0 @@
# Создание приватного форка репозитория с домашними заданиями
Репозитории в git можно fork-ать, то есть делать его полную копию с возможностью синхронизации с начальным репозиторием.
Этот механизм похож на ветки, но отличается тем, что форк может иметь свои настройки доступа и видимости и может существовать независимо от изначального репозитория.
Гитхаб не позвляет создавать приватные форки через кнопку Fork, поэтому придет делать форк вручную. К счастью, это не сложно.
### Подготовка проекта
1. Создать у себя в профиле пустой приватный репозиторий - [https://github.com/new](https://github.com/new)
1. Назвать `bachelor-homeworks`
2. Сделать его приватным
3. Добавлять никаких файлов не надо
![Create repository](images/create_repository.png "create repository")
4. Далее перейти в настройки репозитория, в раздел Collaborators
![Collaborators](images/collaborators.png "collaborators")
5. Нажав `Add people`, добавить в свой проект своего преподавателя
2. Скопировать ссылку на клонирование с главной страницы репозитория с заданием
![clone_link](images/fork_link.png "clone link")
3. В окне Intellij выбрать Get from VCS
![Get from VCS](images/get_from_vcs.png "Get from vcs")
4. В поле `Ссылка` вставить скопированный линк
1. IDEA может написать, что не установлен GIT, тогда следует нажать кнопку `Скачать и установить`
5. Нажать кнопку `Clone`, желательно, чтобы итоговый путь до проекта не содержал русских символов и пробелов
6. Далее необходимо добавить ваш репозиторий в качестве основного, подменив наш.
1. Скопировать ссылку на ваш репозиторий
![fork_clone](images/fork_link.png "Link to fork")
1. Windows
1. открыть приложение Git CMD
2. Linux / MacOS
1. открыть терминал
3. Перейти в директорию с проектом
4. ввести следующие команды по очереди:
1. `git remote rename origin upstream`
2. `git remote add origin <ссылка на ваш репозиторий>`
![Git cmd](images/git_cmd.png "Git cmd")
7. Далее необходимо настроить корректную сборку проекта
1. Переходим в File > Settings
2. Вбить в поиск sbt
3. Выбрать меню Build, Execution, Deployment > Build Tools > sbt
4. Поставить следующие настройки
![SBT settings](images/sbt_settings.png "SBT settings")
8. Запускаем импорт проекта - нажать на маленькую красную кнопку справа-сверху
![Reload sbt project](images/reload_sbt_project.png "Reload sbt project")
9. Пока проект импортируется, можно переключить форматировщик
1. Перейти в File > Settings
2. Вбить в поиск `scalafmt`
3. Выбрать меню Editor > Code Style > Scala
4. Выбрать в качестве форматировщика `Scalafmt`
![Scalafmt](images/scalafmt.png "scalafmt")
10. ***Далее необходимо сделать `push` в свой пустой репозиторий - `git push origin` в терминале гита или через UI intellij, ничего не изменяя. Так вы добавите актуальную ветку main к себе проект.***
> Обратите на последний шаг внимание - если этого не сделать, то main не будет основной веткой.
### Регистрация на портале образования
1. Зарегистрироваться на [https://edu.tinkoff.ru/](https://edu.tinkoff.ru/);
2. Присоединиться к курсу
3. Когда вы создадите Pull Request на гитхабе, нужно сдать соответствуещее ей задание в этом курсе - просто прикрепите в поле для ответа ссылку на ваш PR. Баллы за задание тоже будут там.
1. Перейдите на страницу нужной практики
![Task page](images/task_page.jpeg)
2. Вставьте в поле "Ответ" ссылку на ваш PR и отправьте работу
![Send task](images/pull_request_link.jpeg)
## Работа с github по SSH
При работе по https необходимо вводить логин и пароль, сохранять его на локальной машине в настройках git и т.д.
Чтобы этого не делать, можно воспользоваться функциональностью создания и добавления SSH-ключа в github.
### Создание SSH ключа
1. Windows
1. Открыть cmd.exe
2. Ввести команду `ssh-keygen -b 2048 -t rsa`
3. Если не сработало, то надо установить клиент OpenSSH:
1. Открыть Настройки > Приложения > Приложения и возможности > Дополнительные компоненты
2. Нажать сверху "Добавить компонент" и там через поиск установить "Клиент OpenSSH".
4. Проследовать всем пунктам установки, пароль устанавливать смысла нет, менять путь тоже не стоит
5. После завершения будет сгенерирована пара файлов - `id_rsa` и `id_rsa.pub`, путь к ним был указан в процессе установки
6. Необходимо скопировать в буфер обмена содержимое файла `id_rsa.pub`
2. Linux / Macos
1. Открыть терминал
2. Аналогично windows, начиная с 3-го шага
### Установка SSH ключа в GitHub
1. Перейти на [https://github.com/settings/keys](https://github.com/settings/keys)
2. Нажать на кнопку `New SSH key`
![New ssh key](images/new_ssh_key.png "new ssh key")
3. Дать удобное вам название, например <имя пользователя>_<операционная система>
4. В поле `Key` вставить содержимое файла `id_rsa.pub`
5. Нажать кнопку `Add SSH key`
> Впредь вы сможете взаимодействовать со своим GitHub аккаунтом по SSH - клонировать, пушить и т.д. без ввода пароля
> Для клонирования надо использовать SSH-ссылку вместо HTTPS

1
project/build.properties Normal file
View file

@ -0,0 +1 @@
sbt.version=1.6.2

2
project/plugins.sbt Normal file
View file

@ -0,0 +1,2 @@
addSbtPlugin("org.wartremover" % "sbt-wartremover" % "3.0.9")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")

View file

@ -0,0 +1,31 @@
package mipt.homework6
import mipt.utils.Homeworks._
import scala.collection.mutable.Set
object TraitLineization {
type MethodDef = String
case class TraitDef(parents: List[TraitDef], methods: Map[String, MethodDef])
def resolveMethod(traitDef: TraitDef, method: String): Option[MethodDef] = {
val visited: Set[TraitDef] = Set.empty
def dfs(currentTrait: TraitDef): Option[MethodDef] = {
if (visited.contains(currentTrait)) {
None
} else {
visited.add(currentTrait)
val result_dfs = currentTrait.parents.foldLeft(Option.empty[MethodDef]) {
case (result, parent) =>
dfs(parent).orElse(result)
}
currentTrait.methods.get(method).orElse(result_dfs)
}
}
dfs(traitDef)
}
}

View file

@ -0,0 +1,21 @@
package mipt.utils
object Homeworks {
final case class TaskNotDone(num: String, text: String) extends RuntimeException(s"выполните задание $num : \n $text")
trait TaskDef {
def applySeq(num: Seq[Int]): Nothing
def apply(num: Int*): Nothing = applySeq(num)
}
@SuppressWarnings(Array("org.wartremover.warts.Throw"))
implicit class TaskSyntax(private val cs: StringContext) extends AnyVal {
def task(refs: Any*): TaskDef = xs => {
val message = cs.s(refs: _*).stripMargin
throw TaskNotDone(xs.mkString("."), message)
}
}
}

View file

@ -0,0 +1,47 @@
package mipt.homework6
import TraitLineization._
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class TraitLineizationSpec extends AnyFlatSpec with Matchers {
"resolveMethod" should "correctly resolve method for multi-trait extension chain" in {
val traitDefA = TraitDef(
parents = List.empty,
methods = Map("foo" -> "println bar")
)
val traitDefB = TraitDef(
parents = List(traitDefA),
methods = Map("foo" -> "println lol")
)
val traitDefC = TraitDef(
parents = List(traitDefA),
methods = Map("foo" -> "println kek")
)
val traitDefFin1 = TraitDef(
parents = List(
traitDefB,
traitDefC,
traitDefA
),
methods = Map.empty
)
val traitDefFin2 = TraitDef(
parents = List(
traitDefA,
traitDefB
),
methods = Map.empty
)
resolveMethod(traitDefFin1, "foo") shouldBe Some("println kek")
resolveMethod(traitDefFin2, "foo") shouldBe Some("println lol")
}
}