mirror of
https://github.com/ZhigalskiiIvan/TextStatisticsProject.git
synced 2024-11-12 19:11:52 +03:00
Removed global singletons, renamed functions
This commit is contained in:
parent
ef7b49b301
commit
0bc2c199d6
@ -6,33 +6,30 @@ import org.jetbrains.letsPlot.intern.Plot
|
|||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
|
||||||
object StatisticBuilder {
|
/** Singleton object which gives statistics of saved texts.
|
||||||
/**
|
|
||||||
* Singleton object which gives statistics of saved texts.
|
|
||||||
*/
|
*/
|
||||||
|
class StatisticBuilder {
|
||||||
|
|
||||||
|
/** Recognizes the name of the text, which
|
||||||
fun askAndExecuteSelfCommands() {
|
|
||||||
/**
|
|
||||||
* Recognizes the name of the text, which
|
|
||||||
* user want to see statistics about and type of output.
|
* user want to see statistics about and type of output.
|
||||||
* It calls methods of graphic building or printing data in console,
|
* It calls methods of graphic building or printing data in console,
|
||||||
* build required for it objects.
|
* build required for it objects.
|
||||||
*/
|
*/
|
||||||
|
fun getStatistics(textData: TextData) {
|
||||||
|
|
||||||
if (!TextData.haveText()) {
|
if (!textData.haveText()) {
|
||||||
println("No saved texts")
|
println("No saved texts")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val text = TextData.getTextData("Input name of a text which you want to see statistics about.")
|
val text = textData.getTextData("Input name of a text which you want to see statistics about.")
|
||||||
|
|
||||||
var counter = 1
|
var counter = 1
|
||||||
val wordsCountsMap = text.getSentencesList().map { counter++ to it.getWordsCount() }
|
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:")
|
println("Print \"console\" if you have see data in console, \"graphic\" if you have see histogram and \"both\" if you have see them together:")
|
||||||
|
|
||||||
val request = Main.requestInput(listOf("console", "graphic", "both"))
|
val request = requestInput(listOf("console", "graphic", "both"))
|
||||||
request.first.exe()
|
request.first.exe()
|
||||||
|
|
||||||
when (request.second) {
|
when (request.second) {
|
||||||
@ -47,13 +44,11 @@ object StatisticBuilder {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** It builds bar chart with data of mapOfSentenceNumToItsSize.
|
||||||
private fun buildGraphic(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
|
|
||||||
/**
|
|
||||||
* It builds bar chart with data of mapOfSentenceNumToItsSize.
|
|
||||||
* textName: name of texts, which user want to see statistics about.
|
* textName: name of texts, which user want to see statistics about.
|
||||||
* mapOfSentenceNumToItsSize: map of pairs of sentence numbers and their words count.
|
* mapOfSentenceNumToItsSize: map of pairs of sentence numbers and their words count.
|
||||||
*/
|
*/
|
||||||
|
private fun buildGraphic(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
|
||||||
|
|
||||||
val plot: Plot =
|
val plot: Plot =
|
||||||
ggplot(mapOfSentenceNumToItsSize) + ggsize(1000, 600) + geomBar { x = "sentence number"; y = "words count" }
|
ggplot(mapOfSentenceNumToItsSize) + ggsize(1000, 600) + geomBar { x = "sentence number"; y = "words count" }
|
||||||
@ -62,13 +57,13 @@ object StatisticBuilder {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printStatisticsInConsole(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
|
|
||||||
/**
|
/**
|
||||||
* Prints statistics according to data from mapOfSentenceNumToItsSize.
|
* Prints statistics according to data from mapOfSentenceNumToItsSize.
|
||||||
*
|
*
|
||||||
* textName: name of texts, which user want to see statistics about.
|
* textName: name of texts, which user want to see statistics about.
|
||||||
* mapOfSentenceNumToItsSize: map of pairs of sentence numbers and their words count.
|
* mapOfSentenceNumToItsSize: map of pairs of sentence numbers and their words count.
|
||||||
*/
|
*/
|
||||||
|
private fun printStatisticsInConsole(textName: String, mapOfSentenceNumToItsSize: Map<Int, Int>) {
|
||||||
|
|
||||||
val sectionTitle = "Text name: $textName"
|
val sectionTitle = "Text name: $textName"
|
||||||
println("-".repeat(sectionTitle.length))
|
println("-".repeat(sectionTitle.length))
|
||||||
@ -96,43 +91,39 @@ object StatisticBuilder {
|
|||||||
println("-".repeat(sectionTitle.length))
|
println("-".repeat(sectionTitle.length))
|
||||||
println("Done!\n")
|
println("Done!\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object TextReader {
|
|
||||||
/** Singleton object used for reading text from a file or console. */
|
/** Singleton object used for reading text from a file or console. */
|
||||||
|
class TextReader {
|
||||||
|
|
||||||
|
|
||||||
fun askAndExecuteSelfCommands() {
|
|
||||||
/**
|
/**
|
||||||
* Asks the user which where they want to read the text from and
|
* Asks the user which where they want to read the text from and
|
||||||
* calls special for file- and console- reading methods according the answer.
|
* calls special for file- and console- reading methods according the answer.
|
||||||
*/
|
*/
|
||||||
|
fun readNewText(textData: TextData) {
|
||||||
|
|
||||||
println("Where do you want to add the text: from the console or a file?")
|
println("Where do you want to add the text: from the console or a file?")
|
||||||
|
|
||||||
val kindOfSource = Main.requestInput(listOf("console", "file"))
|
val kindOfSource = requestInput(listOf("console", "file"))
|
||||||
kindOfSource.first.exe()
|
kindOfSource.first.exe()
|
||||||
|
|
||||||
when (kindOfSource.second) {
|
when (kindOfSource.second) {
|
||||||
"console" -> readFromConsole()
|
"console" -> readFromConsole(textData)
|
||||||
"file" -> readFromFile()
|
"file" -> readFromFile(textData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun readFromConsole() {
|
/** Read from console the name of text, checks that it hasn't saved yet and its contents,
|
||||||
/**
|
|
||||||
* Read from console the name of text, checks that it hasn't saved yet and its contents,
|
|
||||||
* asks if entered text is not correct and re-calls itself or
|
* asks if entered text is not correct and re-calls itself or
|
||||||
* calls method of adding received text to data.
|
* calls method of adding received text to data.
|
||||||
*/
|
*/
|
||||||
|
private fun readFromConsole(textData: TextData) {
|
||||||
|
|
||||||
println("Input name of a text:")
|
println("Input name of a text:")
|
||||||
if (TextData.haveText()) println("Unavailable(existing) names: ${TextData.getTextNamesInString()}.")
|
if (textData.haveText()) println("Unavailable(existing) names: ${textData.getTextNamesInString()}.")
|
||||||
val nameRequest = Main.requestInput(unavailableInputs = TextData.getTextNamesList())
|
val nameRequest = requestInput(unavailableInputs = textData.getTextNamesList())
|
||||||
nameRequest.first.exe()
|
nameRequest.first.exe()
|
||||||
|
|
||||||
val name = nameRequest.second.toString()
|
val name = nameRequest.second.toString()
|
||||||
@ -157,21 +148,20 @@ object TextReader {
|
|||||||
|
|
||||||
println("Was input data right?[yes, no]:")
|
println("Was input data right?[yes, no]:")
|
||||||
|
|
||||||
val correctInputRequest = Main.requestInput(listOf("yes", "no"))
|
val correctInputRequest = requestInput(listOf("yes", "no"))
|
||||||
correctInputRequest.first.exe()
|
correctInputRequest.first.exe()
|
||||||
|
|
||||||
if (correctInputRequest.second == "yes") addTextToData(name, content)
|
if (correctInputRequest.second == "yes") addTextToData(textData, name, content)
|
||||||
else readFromConsole()
|
else readFromConsole(textData)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readFromFile() {
|
|
||||||
/**
|
/**
|
||||||
* Asks for the name of text, path to file to read text from,
|
* Asks for the name of text, path to file to read text from,
|
||||||
* checks for its existing, reads contents and,
|
* checks for its existing, reads contents and,
|
||||||
* asks if entered names is not correct and re-calls itself or
|
* asks if entered names is not correct and re-calls itself or
|
||||||
* calls method of adding received text to data.
|
* calls method of adding received text to data.
|
||||||
*/
|
*/
|
||||||
|
private fun readFromFile(textData: TextData) {
|
||||||
|
|
||||||
println("Input a name of a text:")
|
println("Input a name of a text:")
|
||||||
val name = readln()
|
val name = readln()
|
||||||
@ -180,7 +170,7 @@ object TextReader {
|
|||||||
val contentsFile: File
|
val contentsFile: File
|
||||||
|
|
||||||
pathReadCycle@ while (true) {
|
pathReadCycle@ while (true) {
|
||||||
val pathRequest = Main.requestInput<String>()
|
val pathRequest = requestInput<String>()
|
||||||
pathRequest.first.exe()
|
pathRequest.first.exe()
|
||||||
val filePath = pathRequest.second.toString()
|
val filePath = pathRequest.second.toString()
|
||||||
|
|
||||||
@ -198,49 +188,41 @@ object TextReader {
|
|||||||
val content = contentsFile.readText()
|
val content = contentsFile.readText()
|
||||||
|
|
||||||
print("Input was correct?[yes, no]: ")
|
print("Input was correct?[yes, no]: ")
|
||||||
val correctInputRequest = Main.requestInput(listOf("yes", "no"))
|
val correctInputRequest = requestInput(listOf("yes", "no"))
|
||||||
correctInputRequest.first.exe()
|
correctInputRequest.first.exe()
|
||||||
|
|
||||||
when (correctInputRequest.second) {
|
when (correctInputRequest.second) {
|
||||||
"yes" -> addTextToData(name, content)
|
"yes" -> addTextToData(textData, name, content)
|
||||||
"no" -> readFromFile()
|
"no" -> readFromFile(textData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun addTextToData(textName: String, content: String) {
|
|
||||||
/**
|
/**
|
||||||
* Calls method of TextData class to add new text in set
|
* Calls method of TextData class to add new text in set
|
||||||
* of tracked texts.
|
* of tracked texts.
|
||||||
* textName: name of new text.
|
* @param textName name of new text.
|
||||||
* content: content of new text.
|
* @param content content of new text.
|
||||||
*/
|
*/
|
||||||
|
private fun addTextToData(textData: TextData, textName: String, content: String) =
|
||||||
TextData.addNewText(textName, content)
|
textData.addNewText(textName, content)
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Object used for storing data about tracking texts,
|
||||||
object TextData {
|
|
||||||
/**
|
|
||||||
* Object used for storing data about tracking texts,
|
|
||||||
* includes methods for work with them.
|
* includes methods for work with them.
|
||||||
* textsList: list of monitored texts.
|
|
||||||
*/
|
*/
|
||||||
|
class TextData {
|
||||||
|
|
||||||
|
/** list of monitored texts. */
|
||||||
private val textsList = mutableListOf<Text>()
|
private val textsList = mutableListOf<Text>()
|
||||||
|
|
||||||
|
|
||||||
fun haveText(): Boolean = textsList.isNotEmpty()
|
fun haveText(): Boolean = textsList.isNotEmpty()
|
||||||
|
|
||||||
|
/** Method for removing text from watch list. Asks for a name of a text
|
||||||
fun removeText() {
|
|
||||||
/**
|
|
||||||
* Method for removing text from watch list. Asks for a name of a text
|
|
||||||
* and if it's being tracked, remove it from the textsList.
|
* and if it's being tracked, remove it from the textsList.
|
||||||
*/
|
*/
|
||||||
|
fun removeText() {
|
||||||
|
|
||||||
|
|
||||||
if (!haveText()) {
|
if (!haveText()) {
|
||||||
@ -254,70 +236,71 @@ object TextData {
|
|||||||
println("Text ${removingText.getName()} removed.")
|
println("Text ${removingText.getName()} removed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getTextByName(searchingName: String): Text? {
|
|
||||||
/**
|
/**
|
||||||
* Returns Text object whose name matches searchingName or null
|
* Returns Text object whose name matches searchingName or null
|
||||||
* if there is no text with same name in the textsList.
|
* if there is no text with same name in the textsList.
|
||||||
* searchingName: name of the text to be found.
|
* searchingName: name of the text to be found.
|
||||||
* return: the text with searchingName name or null.
|
* return: the text with searchingName name or null.
|
||||||
*/
|
*/
|
||||||
|
private fun getTextByName(searchingName: String): Text? {
|
||||||
|
|
||||||
for (text in textsList) if (text.getName() == searchingName) return text
|
for (text in textsList) if (text.getName() == searchingName) return text
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return string with names of tracking texts separated by delimiter. */
|
||||||
fun getTextNamesInString(delimiter: String = ", "): String {
|
fun getTextNamesInString(delimiter: String = ", "): String {
|
||||||
/** Returns string with names of tracking texts separated by delimiter. */
|
|
||||||
return textsList.joinToString(delimiter) { it.getName() }
|
return textsList.joinToString(delimiter) { it.getName() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @return list with names of tracking texts. */
|
||||||
fun getTextNamesList(): List<String> {
|
fun getTextNamesList(): List<String> {
|
||||||
/** Returns list with names of tracking texts. */
|
|
||||||
return textsList.map { it.getName() }
|
return textsList.map { it.getName() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun addNewText(textName: String, content: String) {
|
/** Calls method of textAnalyzer for getting Text object from
|
||||||
/**
|
|
||||||
* Calls method of textAnalyzer for getting Text object from
|
|
||||||
* textName and content and adds it in textsList.
|
* textName and content and adds it in textsList.
|
||||||
*/
|
*/
|
||||||
|
fun addNewText(textName: String, content: String) {
|
||||||
textsList.add(TextAnalyzer.getTextObjFromContents(textName, content))
|
textsList.add(TextAnalyzer.getTextObjFromContents(textName, content))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getTextData(message: String = "Input name of a text"): Text {
|
|
||||||
/**
|
/**
|
||||||
* Reads name of the text to be found and returns it text if
|
* Reads name of the text to be found and returns it text if
|
||||||
* it exists.
|
* it exists.
|
||||||
* message: message which prints with calling this method.
|
* @param message message which prints with calling this method.
|
||||||
* return: text
|
* @return text
|
||||||
*/
|
*/
|
||||||
|
fun getTextData(message: String = "Input name of a text"): Text {
|
||||||
|
|
||||||
|
|
||||||
println(message)
|
println(message)
|
||||||
println("Saved texts: ${getTextNamesInString()}.")
|
println("Saved texts: ${getTextNamesInString()}.")
|
||||||
|
|
||||||
val nameRequest = Main.requestInput(getTextNamesList())
|
val nameRequest = requestInput(getTextNamesList())
|
||||||
nameRequest.first.exe()
|
nameRequest.first.exe()
|
||||||
|
|
||||||
return getTextByName(nameRequest.second.toString())!!
|
return getTextByName(nameRequest.second.toString())!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object TextAnalyzer {
|
|
||||||
/** Object used for getting text from the string information. */
|
/** Object used for getting text from the string information. */
|
||||||
|
object TextAnalyzer {
|
||||||
|
|
||||||
private val DELIMITERS = Regex("[!?.]+\\s+")
|
private val DELIMITERS = Regex("[!?.]+\\s+")
|
||||||
private val WHITESPACES = Regex("\\s+")
|
private val WHITESPACES = Regex("\\s+")
|
||||||
private val WHITESPACES_OR_EMPTY = Regex("(\\s+)?")
|
private val WHITESPACES_OR_EMPTY = Regex("(\\s+)?")
|
||||||
|
|
||||||
fun getTextObjFromContents(name: String, content: String): Text {
|
|
||||||
/**
|
/**
|
||||||
* Receives text as input and splits it by sentence, calculate its lengths,
|
* Receives text as input and splits it by sentence, calculate its lengths,
|
||||||
* create list of Sentence objects and returns Text object, created with
|
* create list of Sentence objects and returns Text object, created with
|
||||||
* this list, input field name, and count of sentences in content.
|
* this list, input field name, and count of sentences in content.
|
||||||
*/
|
*/
|
||||||
|
fun getTextObjFromContents(name: String, content: String): Text {
|
||||||
|
|
||||||
|
|
||||||
var sentencesCount = 1
|
var sentencesCount = 1
|
||||||
val listOfSentences = mutableListOf<Text.Sentence>()
|
val listOfSentences = mutableListOf<Text.Sentence>()
|
||||||
@ -340,20 +323,20 @@ object TextData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Stores information about conjugated text. */
|
||||||
data class Text(
|
data class Text(
|
||||||
private val name: String,
|
private val name: String,
|
||||||
private val sentencesCount: Int,
|
private val sentencesCount: Int,
|
||||||
private val sentencesList: List<Sentence>,
|
private val sentencesList: List<Sentence>,
|
||||||
) {
|
) {
|
||||||
/** Stores information about conjugated text. */
|
|
||||||
|
|
||||||
fun getName() = name
|
fun getName() = name
|
||||||
|
|
||||||
fun getSentencesList() = sentencesList
|
fun getSentencesList() = sentencesList
|
||||||
|
|
||||||
|
|
||||||
|
/** Stores information about count of words. */
|
||||||
data class Sentence(private val wordsCount: Int) {
|
data class Sentence(private val wordsCount: Int) {
|
||||||
/** stores information about count of words. */
|
|
||||||
fun getWordsCount() = wordsCount
|
fun getWordsCount() = wordsCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,110 +344,103 @@ object TextData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Function used for exiting out of program. */
|
||||||
fun exit(): Nothing {
|
fun exit(): Nothing {
|
||||||
/** function used for exiting out of program. */
|
|
||||||
println("bye!")
|
println("bye!")
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object CommandCenter {
|
/** Singleton used for reading commands from console and storing data about
|
||||||
/**
|
|
||||||
* Singleton used for reading commands from console and storing data about
|
|
||||||
* the functions they should execute.
|
* the functions they should execute.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private enum class Commands(val executingFun: () -> Unit) {
|
class CommandCenter(
|
||||||
/**
|
private val textData: TextData,
|
||||||
* Enumerating of available commands names and functions conjugated
|
private val textReader: TextReader,
|
||||||
|
private val statisticBuilder: StatisticBuilder
|
||||||
|
) {
|
||||||
|
|
||||||
|
|
||||||
|
private val exitCommand = Command("exit", ::exit)
|
||||||
|
private val addCommand = Command("add text") { textReader.readNewText(textData) }
|
||||||
|
private val showStatisticsCommand = Command("show statistics") { statisticBuilder.getStatistics(textData) }
|
||||||
|
private val removeTextCommand = Command("Remove text") { textData.removeText() }
|
||||||
|
|
||||||
|
private val commandsList = listOf(exitCommand, addCommand, showStatisticsCommand, removeTextCommand)
|
||||||
|
val commandsNames = commandsList.map { it.name }
|
||||||
|
|
||||||
|
/** Enumerating of available commands names and functions conjugated
|
||||||
* with them.
|
* with them.
|
||||||
*/
|
*/
|
||||||
EXIT(::exit),
|
class Command(val name: String, val executingFun: () -> Unit)
|
||||||
ADD_TEXT({ TextReader.askAndExecuteSelfCommands() }),
|
|
||||||
SHOW_STATISTICS({ StatisticBuilder.askAndExecuteSelfCommands() }),
|
|
||||||
REMOVE_TEXT({ TextData.removeText() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fun readCommandFromConsole(): () -> Unit {
|
/** Prints list of names of available commands, requests the name and
|
||||||
/**
|
|
||||||
* Prints list of names of available commands, requests the name and
|
|
||||||
* returns corresponding to entered name function.
|
* returns corresponding to entered name function.
|
||||||
*/
|
*/
|
||||||
println("Input one of the commands: ${Commands.values().joinToString { it.name }}:")
|
fun readCommandFromConsole(): () -> Unit {
|
||||||
|
|
||||||
val commandNameRequest = Main.requestInput(Commands.values().map { it.name })
|
println("Input one of the commands: ${commandsNames.joinToString()}:")
|
||||||
|
|
||||||
|
val commandNameRequest = requestInput(commandsNames)
|
||||||
commandNameRequest.first.exe()
|
commandNameRequest.first.exe()
|
||||||
|
|
||||||
val funName = commandNameRequest.second.toString()
|
val funName = commandNameRequest.second.toString()
|
||||||
|
|
||||||
return Commands.valueOf(funName).executingFun
|
return commandsList.find { it.name == funName }!!.executingFun
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Interface used to existing commands objects, whose exe value
|
||||||
interface InputOutcomeCommand {
|
|
||||||
/**
|
|
||||||
* Interface used to existing commands objects, whose exe value
|
|
||||||
* stores function which calls after request due the program.
|
* stores function which calls after request due the program.
|
||||||
* exe: function returned in a Main.requestInput method for returned to
|
*/
|
||||||
|
interface InputOutcomeCommand {
|
||||||
|
/** Function returned in a Main.requestInput method for returned to
|
||||||
* main menu of application or continuation of the process.
|
* main menu of application or continuation of the process.
|
||||||
*/
|
*/
|
||||||
val exe: () -> Unit
|
val exe: () -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
object ContinueCommand : InputOutcomeCommand {
|
|
||||||
/** If called exe of this object, program continue executing
|
/** If called exe of this object, program continue executing
|
||||||
* without changes.
|
* without changes.
|
||||||
*/
|
*/
|
||||||
|
class ContinueCommand : InputOutcomeCommand {
|
||||||
override val exe: () -> Unit = {}
|
override val exe: () -> Unit = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ReturnCommand : InputOutcomeCommand {
|
|
||||||
/**
|
/**
|
||||||
* If called exe of this object, a custom ReturnException is thrown
|
* If called exe of this object, a custom ReturnException is thrown
|
||||||
* and process of executing some called command interrupted. Exception
|
* and process of executing some called command interrupted. Exception
|
||||||
* catches in mainCycle and program command request is repeated.
|
* catches in mainCycle and program command request is repeated.
|
||||||
*/
|
*/
|
||||||
override val exe: () -> Unit = {
|
class ReturnCommand : InputOutcomeCommand {
|
||||||
throw ReturnException()
|
override val exe: () -> Unit = throw ReturnException()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReturnException : Exception() {
|
|
||||||
/** Custom exception being thrown if user want to return to the menu. */
|
/** Custom exception being thrown if user want to return to the menu. */
|
||||||
}
|
class ReturnException : Exception()
|
||||||
|
|
||||||
class InvalidInputTypeException : Exception() {
|
/** Custom exception being thrown if input can't be converted
|
||||||
/**
|
|
||||||
* Custom exception being thrown if input can't be converted
|
|
||||||
* to the requested type.
|
* to the requested type.
|
||||||
*/
|
*/
|
||||||
}
|
class InvalidInputTypeException : Exception()
|
||||||
|
|
||||||
class InvalidElemInInputException : Exception() {
|
/** Custom exception being thrown if input doesn't match the list
|
||||||
/**
|
|
||||||
* Custom exception being thrown if input doesn't match the list
|
|
||||||
* of possible values.
|
* of possible values.
|
||||||
*/
|
*/
|
||||||
}
|
class InvalidElemInInputException : Exception()
|
||||||
|
|
||||||
|
|
||||||
object Main {
|
/** Method repeating the process of calling functions returned by
|
||||||
/**
|
|
||||||
* Object which contains request processing method and working body of
|
|
||||||
* application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fun workCycle() {
|
|
||||||
/**
|
|
||||||
* Method repeating the process of calling functions returned by
|
|
||||||
* CommandCenter. If ReturnException was thrown, it is caught here,
|
* CommandCenter. If ReturnException was thrown, it is caught here,
|
||||||
* last iteration breaks and new one is called.
|
* last iteration breaks and new one is called.
|
||||||
*/
|
*/
|
||||||
|
fun workCycle(commandCenter: CommandCenter) {
|
||||||
mainCycle@ while (true) {
|
mainCycle@ while (true) {
|
||||||
try {
|
try {
|
||||||
(CommandCenter.readCommandFromConsole())()
|
(commandCenter.readCommandFromConsole())()
|
||||||
} catch (e: ReturnException) {
|
} catch (e: ReturnException) {
|
||||||
println("You have been returned in main menu.")
|
println("You have been returned in main menu.")
|
||||||
continue@mainCycle
|
continue@mainCycle
|
||||||
@ -472,30 +448,31 @@ object Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Method reads from console input, check if it isn't available, repeat the request from the console
|
||||||
|
* in this case and convert input in type T if possible, else throws an exception and repeat the
|
||||||
|
* request.
|
||||||
|
*
|
||||||
|
* @param availableInputs list of available values, the choice among which
|
||||||
|
* is requested from the console at some stage of the program.
|
||||||
|
* @param unavailableInputs list of unavailable values.
|
||||||
|
* @return a pair of function, which could be called after the request from this function to return
|
||||||
|
* if user want it or continue and value that the user has selected from the list of available.
|
||||||
|
*/
|
||||||
inline fun <reified T> requestInput(
|
inline fun <reified T> requestInput(
|
||||||
availableInputs: List<T>? = null,
|
availableInputs: List<T>? = null,
|
||||||
unavailableInputs: List<T>? = null
|
unavailableInputs: List<T>? = null
|
||||||
): Pair<InputOutcomeCommand, Any> {
|
): Pair<InputOutcomeCommand, Any> {
|
||||||
/**
|
|
||||||
* Method reads from console input, check if it isn't available, repeat the request from the console
|
|
||||||
* in this case and convert input in type T if possible, else throws an exception and repeat the
|
|
||||||
* request.
|
|
||||||
*
|
|
||||||
* availableInputs: list of available values, the choice among which
|
|
||||||
* is requested from the console at some stage of the program.
|
|
||||||
* unavailableInputs: list of unavailable values.
|
|
||||||
* return: a pair of function, which could be called after the request from this function to return
|
|
||||||
* if user want it or continue and value that the user has selected from the list of available.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var inputT: Any
|
var inputT: Any
|
||||||
|
|
||||||
readingAndChangingTypeCycle@ while (true) {
|
readingAndChangingTypeCycle@ while (true) {
|
||||||
|
|
||||||
val input = readln().trim()
|
val input = readln().trim()
|
||||||
if (input == "return") return Pair(ReturnCommand, "")
|
if (input == "return") return Pair(ReturnCommand(), "")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// inputT = input to typeOf<T>()
|
||||||
inputT = when (typeOf<T>()) {
|
inputT = when (typeOf<T>()) {
|
||||||
typeOf<Int>() -> input.toInt()
|
typeOf<Int>() -> input.toInt()
|
||||||
typeOf<Double>() -> input.toDouble()
|
typeOf<Double>() -> input.toDouble()
|
||||||
@ -516,21 +493,21 @@ object Main {
|
|||||||
return when {
|
return when {
|
||||||
availableInputs != null && unavailableInputs != null -> {
|
availableInputs != null && unavailableInputs != null -> {
|
||||||
if (inputT.toString() in availableInputs.map { it.toString() } &&
|
if (inputT.toString() in availableInputs.map { it.toString() } &&
|
||||||
inputT.toString() !in unavailableInputs.map { it.toString() }) Pair(ContinueCommand, inputT)
|
inputT.toString() !in unavailableInputs.map { it.toString() }) Pair(ContinueCommand(), inputT)
|
||||||
else throw InvalidElemInInputException()
|
else throw InvalidElemInInputException()
|
||||||
}
|
}
|
||||||
|
|
||||||
availableInputs != null -> {
|
availableInputs != null -> {
|
||||||
if (inputT.toString() in availableInputs.map { it.toString() }) Pair(ContinueCommand, inputT)
|
if (inputT.toString() in availableInputs.map { it.toString() }) Pair(ContinueCommand(), inputT)
|
||||||
else throw InvalidElemInInputException()
|
else throw InvalidElemInInputException()
|
||||||
}
|
}
|
||||||
|
|
||||||
unavailableInputs != null -> {
|
unavailableInputs != null -> {
|
||||||
if (inputT.toString() !in unavailableInputs.map { it.toString() }) Pair(ContinueCommand, inputT)
|
if (inputT.toString() !in unavailableInputs.map { it.toString() }) Pair(ContinueCommand(), inputT)
|
||||||
else throw InvalidElemInInputException()
|
else throw InvalidElemInInputException()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Pair(ContinueCommand, inputT)
|
else -> Pair(ContinueCommand(), inputT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -548,9 +525,14 @@ object Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
Main.workCycle()
|
|
||||||
|
val textData = TextData()
|
||||||
|
val statisticBuilder = StatisticBuilder()
|
||||||
|
val textReader = TextReader()
|
||||||
|
|
||||||
|
val commandCenter = CommandCenter(textData, textReader, statisticBuilder)
|
||||||
|
|
||||||
|
workCycle(commandCenter)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user