create general input method

This commit is contained in:
ZhigalskiiIvan 2023-03-25 11:46:24 +03:00
parent 87e744f55f
commit d9c5ac32bc

View File

@ -4,6 +4,8 @@ import kotlin.system.exitProcess
import org.jetbrains.letsPlot.*
import org.jetbrains.letsPlot.geom.geomBar
import org.jetbrains.letsPlot.intern.Plot
import kotlin.reflect.KType
import kotlin.reflect.typeOf
val scanner = Scanner(System.`in`)
@ -18,31 +20,26 @@ object StatisticBuilder {
val wordsCountsMap = text.getSentencesList().map { counter++ to it.getWordsCount() }
println("Print \"console\" if you have see data in console, \"graphic\" if you have see histogram and \"both\" if you have see them together:")
whenStatShowCycle@ while (true) {
when (readln()) {
"console" -> printStatisticsInConsole(text.getName(), wordsCountsMap.toMap())
"graphic" -> buildGraphic(text.getName(), wordsCountsMap.toMap())
"both" -> {
buildGraphic(text.getName(), wordsCountsMap.toMap())
printStatisticsInConsole(text.getName(), wordsCountsMap.toMap())
}
"return" -> return
else -> {
println("Repeat input or enter \"return\" to return in main menu")
continue@whenStatShowCycle
}
val request = Main.requestInput(listOf("console", "graphic", "both"))
request.first.exe()
when (request.second) {
"console" -> printStatisticsInConsole(text.getName(), wordsCountsMap.toMap())
"graphic" -> buildGraphic(text.getName(), wordsCountsMap.toMap())
"both" -> {
buildGraphic(text.getName(), wordsCountsMap.toMap())
printStatisticsInConsole(text.getName(), wordsCountsMap.toMap())
}
break@whenStatShowCycle
}
}
private fun buildGraphic(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
val plot: Plot =
ggplot(mapOfSentenceNumToItsSize) + ggsize(1000, 600) + geomBar { x = "sentence number"; y = "words count" }
}
private fun printStatisticsInConsole(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
@ -51,48 +48,35 @@ object StatisticBuilder {
println("-".repeat(textName.length))
println(
"Statistics[num of sentence: count of words in it]: ${
mapOfSentenceNumToItsSize.toList().joinToString("; ") { "${it.first}: ${it.second}" } }.")
mapOfSentenceNumToItsSize.toList().joinToString("; ") { "${it.first}: ${it.second}" }
}.")
println("-".repeat(textName.length))
println("Done!\n")
}
private fun getTextData(): TextData.Text? {
println("Input name of text which you have to get statistics about:")
println("Saved texts: ${TextData.getTextsNamesInString()}")
cycleSearchText@ while (true) {
return when (val name = readln().trim()) {
in TextData.getTextsNamesList() -> {
TextData.getTextByName(name)!!
}
"return" -> null
else -> {
println("No text with name $name. Repeat input or enter return to return in main menu.")
continue@cycleSearchText
}
}
}
val nameRequest = Main.requestInput(TextData.getTextsNamesList())
nameRequest.first.exe()
return TextData.getTextByName(nameRequest.second.toString())
}
}
object TextReader {
fun askAndExecuteSelfCommands() {
println("Where do you want to add the text: from the console of a file?")
when (readln().lowercase()) {
println("Where do you want to add the text: from the console or a file?")
val kindOfSource = Main.requestInput(listOf("console", "file"))
kindOfSource.first.exe()
when (kindOfSource.second) {
"console" -> readFromConsole()
"file" -> readFromFile()
"return" -> return
else -> {
println("Repeat input or print \"return\" to return in main menu:")
askAndExecuteSelfCommands()
}
}
}
@ -128,38 +112,33 @@ object TextReader {
val name = readln()
val contentsFile: File
pathReadCycle@ while (true) {
println("Input a path to file:")
val filePath = readln()
val pathRequest = Main.requestInput<String>()
pathRequest.first.exe()
val filePath = pathRequest.second.toString()
val testFile = File(filePath)
when {
filePath == "return" -> return
!testFile.exists() -> {
println("File path incorrect. Repeat input or enter \"return\" to return in main menu:")
continue@pathReadCycle
}
else -> {
contentsFile = testFile
break@pathReadCycle
}
if (!testFile.exists()) {
println("Incorrect path. Repeat the input:")
continue@pathReadCycle
} else {
contentsFile = testFile
break@pathReadCycle
}
}
val content = contentsFile.readText()
correctInputQuestion@ while (true) {
print("Input was correct?[yes, no]: ")
when (readln()) {
"yes" -> addTextToData(name, content)
"no" -> readFromFile()
"return" -> return
else -> {
println("Input only \"yes\" or \"no\" or \"return\" if you want to exit in main menu:")
}
}
}
print("Input was correct?[yes, no]: ")
val correctInputRequest = Main.requestInput(listOf("yes", "no"))
correctInputRequest.first.exe()
when (correctInputRequest.second) {
"yes" -> addTextToData(name, content)
"no" -> readFromFile()
}
}
private fun addTextToData(textName: String, content: String) {
@ -222,11 +201,10 @@ object TextData {
) {
fun getSentencesCount() = sentencesCount
fun getName() = name
fun getSentencesList(): List<Sentence> {
return sentencesList
}
fun getSentencesList() = sentencesList
data class Sentence(private val wordsCount: Int) {
fun getWordsCount() = wordsCount
@ -236,14 +214,15 @@ object TextData {
}
fun exit(): Nothing {
println("bye!")
exitProcess(0)
}
object CommandCenter {
private enum class Commands(val executingFun: () -> Unit) {
EXIT({
println("bye!")
exitProcess(0)
}),
EXIT(::exit),
ADD_TEXT({ TextReader.askAndExecuteSelfCommands() }),
SHOW_STATISTICS({ StatisticBuilder.askAndExecuteSelfCommands() }),
REMOVE_TEXT({ println("remove") })
@ -261,8 +240,85 @@ object CommandCenter {
}
fun main() {
mainCycle@ while (true) {
(CommandCenter.readCommandFromConsole())()
interface InputOutcomeCommand {
val exe: () -> Unit
}
object ContinueCommand : InputOutcomeCommand {
override val exe: () -> Unit = {}
}
object ReturnCommand : InputOutcomeCommand {
override val exe: () -> Unit = { Main.work() }
}
class InvalidInputTypeException(expectedType: String) : Exception(expectedType) {
override val message: String = expectedType
get() = "Was expected type: $field, but it's impossible to convert input in it."
}
class InvalidElemInInputException() : Exception()
object Main {
fun work() {
mainCycle@ while (true) {
(CommandCenter.readCommandFromConsole())()
}
}
inline fun <reified T> requestInput(availableInputs: List<T>? = null): Pair<InputOutcomeCommand, Any> {
var inputT: Any
readingAndChangingTypeCycle@ while (true) {
val input = readln()
if (input == "return") return Pair(ReturnCommand, "")
try {
inputT = when (typeOf<T>()) {
typeOf<Int>() -> input.toInt()
typeOf<Double>() -> input.toDouble()
typeOf<Boolean>() -> input.toBoolean()
typeOf<Byte>() -> input.toByte()
typeOf<Long>() -> input.toLong()
typeOf<Float>() -> input.toFloat()
typeOf<Char>() -> {
if (input.trim().length == 1) {
input.trim().toCharArray()[0]
} else throw InvalidInputTypeException(typeOf<Char>().toString())
}
typeOf<String>() -> input
else -> throw InvalidInputTypeException(typeOf<T>().toString())
}
return if (availableInputs != null) {
if (inputT.toString() in availableInputs.map { it.toString() }) Pair(ContinueCommand, inputT)
else throw InvalidElemInInputException()
} else Pair(ContinueCommand, inputT)
} catch (e: NumberFormatException) {
println(e.message)
println("")
continue@readingAndChangingTypeCycle
} catch (e: InvalidInputTypeException) {
println(e.message)
println("")
continue@readingAndChangingTypeCycle
} catch (e: InvalidElemInInputException) {
println("There isn't this elem in list of available inputs. Try to repeat or enter return to exit in main menu: ")
continue@readingAndChangingTypeCycle
}
}
}
}
fun main() {
Main.work()
}