-
Notifications
You must be signed in to change notification settings - Fork 59
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
dru
committed
Nov 23, 2023
1 parent
a3504d2
commit 5ef029a
Showing
13 changed files
with
254 additions
and
0 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
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,12 @@ | ||
.bsp/ | ||
.idea/ | ||
target/ | ||
boot/ | ||
logs/ | ||
lib_managed/ | ||
src_managed/ | ||
project/plugins/project/ | ||
*.conf | ||
.bloop | ||
.metals | ||
.vscode |
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,12 @@ | ||
ThisBuild / version := "0.1.0-SNAPSHOT" | ||
|
||
ThisBuild / scalaVersion := "2.13.12" | ||
|
||
lazy val root = (project in file(".")) | ||
.settings( | ||
name := "practice_2023", | ||
// https://mvnrepository.com/artifact/org.typelevel/cats-core | ||
libraryDependencies += "org.typelevel" %% "cats-core" % "2.10.0", | ||
// https://mvnrepository.com/artifact/org.typelevel/cats-effect | ||
libraryDependencies += "org.typelevel" %% "cats-effect" % "3.6-0142603" | ||
) |
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 @@ | ||
sbt.version = 1.9.7 |
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,6 @@ | ||
// DO NOT EDIT! This file is auto-generated. | ||
|
||
// This file enables sbt-bloop to create bloop config files. | ||
|
||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.11") | ||
|
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,6 @@ | ||
// DO NOT EDIT! This file is auto-generated. | ||
|
||
// This file enables sbt-bloop to create bloop config files. | ||
|
||
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.11") | ||
|
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,3 @@ | ||
package online | ||
|
||
case class Book(name: String, author: String) |
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,3 @@ | ||
package online | ||
|
||
case class Client(name: String) |
66 changes: 66 additions & 0 deletions
66
lectures/practice2/src/main/scala/online/CommandParser.scala
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,66 @@ | ||
package online | ||
|
||
object CommandParser { | ||
def parse(commandLine: String): LibraryOperation[String] = commandLine.split(' ').toList match { | ||
case command :: arguments if arguments.nonEmpty => | ||
command match { | ||
|
||
case "addClient" => LibraryOperation(db => | ||
db.copy(clients = db.clients :+ Client(arguments.mkString(" "))) -> Right("ok") | ||
) | ||
|
||
case "addBook" => { | ||
val totalArgument = arguments.mkString(" ").split('|') | ||
val name = totalArgument.headOption | ||
val author = totalArgument.drop(1).headOption | ||
(name, author) match { | ||
case (Some(name), Some(author)) => LibraryOperation { db => db.copy(books = db.books :+ Book(name, author)) -> Right("ok") } | ||
case _ => LibraryOperation.failure(new RuntimeException("wrong syntax")) | ||
} | ||
} | ||
|
||
case _ => LibraryOperation.failure(new Exception("unknown command")) | ||
} | ||
case _ => LibraryOperation.failure(new Exception("wrong syntax")) | ||
} | ||
} | ||
|
||
trait Command { | ||
def couldParse(commandLine: String): Boolean | ||
|
||
def parse(commandLine: String): LibraryOperation[String] | ||
} | ||
|
||
class UniversalCommandParser(additionalCommands: List[Command]) { | ||
|
||
val defaultCommands: List[Command] = List( | ||
new Command { | ||
override def couldParse(commandLine: String): Boolean = commandLine.split(' ').toList match { | ||
case command :: arguments if arguments.nonEmpty => | ||
command match { | ||
case "addClient" => true | ||
case _ => false | ||
} | ||
case _ => false | ||
} | ||
|
||
override def parse(commandLine: String): LibraryOperation[String] = commandLine.split(' ').toList match { | ||
case command :: arguments if arguments.nonEmpty => | ||
command match { | ||
case "addClient" => LibraryOperation(db => | ||
db.copy(clients = db.clients :+ Client(arguments.mkString(" "))) -> Right("ok") | ||
) | ||
case _ => LibraryOperation.failure(new Exception("unknownCommand")) | ||
} | ||
case _ => LibraryOperation.failure(new Exception("wrong syntax")) | ||
} | ||
} | ||
) | ||
|
||
def parse(commandLine: String): LibraryOperation[String] = (defaultCommands ++ additionalCommands) | ||
.dropWhile(!_.couldParse(commandLine)) | ||
.headOption | ||
.map(_.parse(commandLine)) | ||
.getOrElse(LibraryOperation.failure(new Exception("unknown command"))) | ||
} | ||
|
3 changes: 3 additions & 0 deletions
3
lectures/practice2/src/main/scala/online/LibraryDatabase.scala
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,3 @@ | ||
package online | ||
|
||
case class LibraryDatabase(clients: List[Client], books: List[Book], issuedBoos: Map[Book, Client]) |
39 changes: 39 additions & 0 deletions
39
lectures/practice2/src/main/scala/online/LibraryOperation.scala
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,39 @@ | ||
package online | ||
|
||
case class LibraryOperation[+R](run: LibraryDatabase => (LibraryDatabase, Either[Throwable, R])) { | ||
|
||
def map[R2](f: R => R2): LibraryOperation[R2] = LibraryOperation { db => | ||
val (newDb, res) = run(db) | ||
|
||
res match { | ||
case Left(error) => newDb -> Left(error) | ||
case Right(value) => newDb -> Right(f(value)) | ||
} | ||
|
||
} | ||
|
||
def flatMap[R2](f: R => LibraryOperation[R2]): LibraryOperation[R2] = LibraryOperation { db => | ||
val (newDb, res: Either[Throwable, R]) = run(db) | ||
|
||
res match { | ||
case Left(error) => newDb -> Left(error) | ||
case Right(value) => | ||
|
||
val r1: LibraryOperation[R2] = f(value) | ||
|
||
val r2: (LibraryDatabase, Either[Throwable, R2]) = r1.run(newDb) | ||
val r3: Either[Throwable, R2] = r2._2 | ||
|
||
|
||
r2._1 -> r2._2 | ||
} | ||
} | ||
} | ||
|
||
object LibraryOperation{ | ||
|
||
def failure(e: Throwable) = LibraryOperation(db => db -> Left(e)) | ||
|
||
def pure[R](value: R): LibraryOperation[R] = LibraryOperation(db => db -> Right(value)) | ||
|
||
} |
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,99 @@ | ||
package online | ||
|
||
import cats.effect.IO | ||
import cats.effect.unsafe.implicits.global | ||
|
||
import scala.concurrent.duration.DurationInt | ||
import scala.concurrent.{Await, ExecutionContextExecutor, Future} | ||
|
||
/** | ||
* Написать программу, которая реализует потребности базы данных библиотеки: | ||
* 1. Пополнение фонда книгой | ||
* 2. Регистрация пользователя (выдача читательского билета) | ||
* 3. Выдача книги на руки | ||
* 4. Возврат книги | ||
* .... | ||
* | ||
* Программе на вход подается набор инструкций (с клавиатуры, по сети, из файла, ...), | ||
* а программа должна их исполнять | ||
* | ||
* Набор команд программы может расширяться | ||
*/ | ||
|
||
|
||
object Main extends App { | ||
val lib = LibraryDatabase(Nil, Nil, Map.empty) | ||
|
||
// val totalOperation = for { | ||
// _ <- LibraryOperation(db => db.copy(clients = db.clients :+ Client("Vasya")) -> Right("ok")) | ||
// _ <- LibraryOperation(db => db.copy(books = db.books :+ Book("Властелин колец", "Tolkin")) -> Right("ok")) | ||
// r <- LibraryOperation(db => db.copy(books = db.books :+ Book("Designing data intensive applications", "Клепинин")) -> Right("ok")) | ||
// } yield r | ||
// | ||
// val (newDb, result) = totalOperation.run(lib) | ||
// println(newDb) | ||
// println(result) | ||
|
||
//// ------------------------------- | ||
|
||
|
||
|
||
// val parsedCommands = commands.map(CommandParser.parse) | ||
// | ||
// val resultOperation: LibraryOperation[String] = parsedCommands.foldLeft(LibraryOperation.pure(""))((op1, op2) => op1.flatMap(_ => op2)) | ||
// | ||
// val (newDb, res) = resultOperation.run(lib) | ||
// println(newDb, res) | ||
|
||
val dropClientCommand = new Command { | ||
override def couldParse(commandLine: String): Boolean = commandLine.split(' ').toList match { | ||
case command :: arguments if arguments.nonEmpty => | ||
command match { | ||
case "dropClient" => true | ||
case _ => false | ||
} | ||
case _ => false | ||
} | ||
|
||
override def parse(commandLine: String): LibraryOperation[String] = commandLine.split(' ').toList match { | ||
case command :: arguments if arguments.nonEmpty => | ||
command match { | ||
case "dropClient" => LibraryOperation(db => db.copy(clients = db.clients.filter(_.name != arguments.mkString(" "))) -> Right("ok")) | ||
case _ => LibraryOperation.failure(new Exception("unknown command")) | ||
} | ||
case _ => LibraryOperation.failure(new Exception("wrong syntax")) | ||
} | ||
} | ||
|
||
// val commands = List( | ||
// "addClient Ivanov Ivan Ivanovich", | ||
// "addClient Petya", | ||
// "dropClient Ivanov Ivan Ivanovich" | ||
// ) | ||
|
||
//implicit val context: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global | ||
|
||
val program = for { | ||
commands <- IO (scala.io.Source.fromFile("<change_to_your_path>\\commands.txt").getLines()) | ||
|
||
parsedCommands <- IO(commands.map( new UniversalCommandParser(List(dropClientCommand)).parse)) | ||
resultOperation <- IO {parsedCommands.foldLeft(LibraryOperation.pure("")) ((op1, op2) => op1.flatMap(_ => op2))} | ||
|
||
_res <- IO { resultOperation.run(lib) } | ||
(newDb, res) = (_res._1, _res._2) | ||
_ <- IO { println (newDb, res) } | ||
} yield () | ||
|
||
//Await.result(program, 1.minutes) | ||
|
||
program.unsafeRunSync() | ||
|
||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
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,3 @@ | ||
addClient Ivanov2 Ivan Ivanovich | ||
addClient Petya | ||
dropClient Ivanov Ivan Ivanovich |