From 315b333a5883d98c7dab0de4a38a40cbe95af06b Mon Sep 17 00:00:00 2001 From: yostane <1958676+yostane@users.noreply.github.com> Date: Sat, 24 Aug 2024 00:16:46 +0200 Subject: [PATCH] update quiz collector --- .../.gitignore | 3 +- .../assets/gradle-build.png | Bin 0 -> 24490 bytes .../gradle.properties | 4 + .../{results.bru => responses.bru} | 4 +- .../rest-api-ui-ktor-quiz-collector/readme.md | 11 + .../result-explorer/demo01.ipynb | 981 +++++++++++++----- .../main/kotlin/example/com/QuizCollector.kt | 16 +- .../src/main/resources/application.yaml | 13 +- 8 files changed, 762 insertions(+), 270 deletions(-) create mode 100644 material/rest-api-ui-ktor-quiz-collector/assets/gradle-build.png rename material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/{results.bru => responses.bru} (53%) create mode 100644 material/rest-api-ui-ktor-quiz-collector/readme.md diff --git a/material/rest-api-ui-ktor-quiz-collector/.gitignore b/material/rest-api-ui-ktor-quiz-collector/.gitignore index c426c32f..ecf450de 100644 --- a/material/rest-api-ui-ktor-quiz-collector/.gitignore +++ b/material/rest-api-ui-ktor-quiz-collector/.gitignore @@ -33,4 +33,5 @@ out/ /.nb-gradle/ ### VS Code ### -.vscode/ \ No newline at end of file +.vscode/ +.kotlin \ No newline at end of file diff --git a/material/rest-api-ui-ktor-quiz-collector/assets/gradle-build.png b/material/rest-api-ui-ktor-quiz-collector/assets/gradle-build.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d2553652c4978ade33cc0d5fb60f291c6776c7 GIT binary patch literal 24490 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 U>+K+*2LCN3d8k~4j7ji+0B44blmGw# literal 0 HcmV?d00001 diff --git a/material/rest-api-ui-ktor-quiz-collector/gradle.properties b/material/rest-api-ui-ktor-quiz-collector/gradle.properties index 7fc6f1ff..d8ec6a9b 100644 --- a/material/rest-api-ui-ktor-quiz-collector/gradle.properties +++ b/material/rest-api-ui-ktor-quiz-collector/gradle.properties @@ -1 +1,5 @@ kotlin.code.style=official + +org.gradle.caching=true +org.gradle.configuration-cache=true +org.gradle.parallel=true \ No newline at end of file diff --git a/material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/results.bru b/material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/responses.bru similarity index 53% rename from material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/results.bru rename to material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/responses.bru index 77d7627b..9f4f0516 100644 --- a/material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/results.bru +++ b/material/rest-api-ui-ktor-quiz-collector/quiz-collector-bruno/responses.bru @@ -1,11 +1,11 @@ meta { - name: /results + name: /responses type: http seq: 4 } get { - url: http://localhost:8080/results + url: http://localhost:8080/responses body: none auth: none } diff --git a/material/rest-api-ui-ktor-quiz-collector/readme.md b/material/rest-api-ui-ktor-quiz-collector/readme.md new file mode 100644 index 00000000..c1bf9088 --- /dev/null +++ b/material/rest-api-ui-ktor-quiz-collector/readme.md @@ -0,0 +1,11 @@ +# Ktor + jupyter quiz collection + +Enable dev mode + +- Make sure development mode is enabled in your Ktor configuration file. This depends on how you created and run your + server. If you use EngineMain to run a server, enable development mode in the configuration file. +- Add run task that runs `./gradlew -t build` and run it. + +![img.png](assets/gradle-build.png) + +- Run the ktor server with `./gradlew run` or from a run task \ No newline at end of file diff --git a/material/rest-api-ui-ktor-quiz-collector/result-explorer/demo01.ipynb b/material/rest-api-ui-ktor-quiz-collector/result-explorer/demo01.ipynb index 9c813c92..367f42c7 100644 --- a/material/rest-api-ui-ktor-quiz-collector/result-explorer/demo01.ipynb +++ b/material/rest-api-ui-ktor-quiz-collector/result-explorer/demo01.ipynb @@ -9,128 +9,28 @@ }, { "cell_type": "code", - "execution_count": 3, "metadata": { "vscode": { "languageId": "python" + }, + "ExecuteTime": { + "end_time": "2024-08-23T22:10:39.416441300Z", + "start_time": "2024-08-23T22:10:34.053252400Z" } }, + "source": [ + "%use kandy\n", + "%use dataframe\n", + "val df = DataFrame.read(\"http://localhost:8080/responses\")\n", + "df" + ], "outputs": [ { "data": { - "application/kotlindataframe+json": { - "columns": [ - "responses" - ], - "kotlin_dataframe": [ - { - "responses": [ - { - "answer": "Muzukashi", - "question": "What is the primary goal of Kotlin Multiplatform?" - }, - { - "answer": "", - "question": "How does Kotlin Multiplatform facilitate code sharing between platforms?" - } - ] - }, - { - "responses": [ - { - "answer": "To share code between multiple platforms", - "question": "What is the primary goal of Kotlin Multiplatform?" - }, - { - "answer": "By sharing business logic and adapting UI", - "question": "How does Kotlin Multiplatform facilitate code sharing between platforms?" - }, - { - "answer": "Android, iOS, and web", - "question": "Which platforms does Kotlin Multiplatform support?" - }, - { - "answer": "Developing a cross-platform app", - "question": "What is a common use case for Kotlin Multiplatform?" - }, - { - "answer": "Shared module", - "question": "What is a shared code module in Kotlin Multiplatform called?" - }, - { - "answer": "Through expect and actual declarations", - "question": "How does Kotlin Multiplatform handle platform-specific implementations?" - }, - { - "answer": "Java, JavaScript, Swift", - "question": "What languages can be interoperable with Kotlin Multiplatform?" - }, - { - "answer": "IntelliJ IDEA, Android Studio", - "question": "What tooling supports Kotlin Multiplatform development?" - }, - { - "answer": "Code reuse and sharing", - "question": "What is the benefit of using Kotlin Multiplatform for mobile development?" - }, - { - "answer": "Kotlin Multiplatform allows sharing code between different platforms using common modules.", - "question": "How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?" - } - ] - }, - { - "responses": [ - { - "answer": "Nashi", - "question": "What is the primary goal of Kotlin Multiplatform?" - }, - { - "answer": "Don't know", - "question": "How does Kotlin Multiplatform facilitate code sharing between platforms?" - }, - { - "answer": "Windows Phone", - "question": "Which platforms does Kotlin Multiplatform support?" - }, - { - "answer": "No", - "question": "What is a common use case for Kotlin Multiplatform?" - }, - { - "answer": "Nashi", - "question": "What is a shared code module in Kotlin Multiplatform called?" - }, - { - "answer": "Copy paste is the best", - "question": "How does Kotlin Multiplatform handle platform-specific implementations?" - }, - { - "answer": "Zenbu", - "question": "What languages can be interoperable with Kotlin Multiplatform?" - }, - { - "answer": "Vim", - "question": "What tooling supports Kotlin Multiplatform development?" - }, - { - "answer": "Code reuse and sharing", - "question": "What is the benefit of using Kotlin Multiplatform for mobile development?" - }, - { - "answer": "Kotlin Multiplatform allows sharing code between different platforms using common modules.", - "question": "How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?" - } - ] - } - ], - "ncol": 1, - "nrow": 3 - }, "text/html": [ - " \n", - " \n", - " \n", " \n", " \n", - "
\n", - "\n", - "

DataFrame: rowsCount = 3, columnsCount = 1

\n", - "
responses
DataFrame [2 x 2]
questionanswer
What is the primary goal of Kotlin Mu...Muzukashi
How does Kotlin Multiplatform facilit...
DataFrame [10 x 2]
questionanswer
What is the primary goal of Kotlin Mu...To share code between multiple platforms
How does Kotlin Multiplatform facilit...By sharing business logic and adaptin...
Which platforms does Kotlin Multiplat...Android, iOS, and web
What is a common use case for Kotlin ...Developing a cross-platform app
What is a shared code module in Kotli...Shared module

... showing only top 5 of 10 rows

DataFrame [10 x 2]
questionanswer
What is the primary goal of Kotlin Mu...Nashi
How does Kotlin Multiplatform facilit...Don't know
Which platforms does Kotlin Multiplat...Windows Phone
What is a common use case for Kotlin ...No
What is a shared code module in Kotli...Nashi

... showing only top 5 of 10 rows

\n", + "
What is the primary goal of Kotlin Multiplatform?How does Kotlin Multiplatform facilitate code sharing between platforms?Which platforms does Kotlin Multiplatform support?What is a common use case for Kotlin Multiplatform?What is a shared code module in Kotlin Multiplatform called?How does Kotlin Multiplatform handle platform-specific implementations?What languages can be interoperable with Kotlin Multiplatform?What tooling supports Kotlin Multiplatform development?What is the benefit of using Kotlin Multiplatform for mobile development?How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?
MuzukashiBy sharing business logic and adaptin...nullnullnullnullnullnullnullnull
To share code between multiple platformsBy sharing business logic and adaptin...Android, iOS, and webDeveloping a cross-platform appShared moduleThrough expect and actual declarationsJava, JavaScript, SwiftIntelliJ IDEA, Android StudioCode reuse and sharingKotlin Multiplatform allows sharing c...
NashiDon't knowWindows PhoneNoNashiCopy paste is the bestZenbuVimCode reuse and sharingKotlin Multiplatform allows sharing c...
\n", " \n", " \n", " " - ] + ], + "application/kotlindataframe+json": "{\"$version\":\"2.0.0\",\"metadata\":{\"columns\":[\"What is the primary goal of Kotlin Multiplatform?\",\"How does Kotlin Multiplatform facilitate code sharing between platforms?\",\"Which platforms does Kotlin Multiplatform support?\",\"What is a common use case for Kotlin Multiplatform?\",\"What is a shared code module in Kotlin Multiplatform called?\",\"How does Kotlin Multiplatform handle platform-specific implementations?\",\"What languages can be interoperable with Kotlin Multiplatform?\",\"What tooling supports Kotlin Multiplatform development?\",\"What is the benefit of using Kotlin Multiplatform for mobile development?\",\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\"],\"nrow\":3,\"ncol\":10},\"kotlin_dataframe\":[{\"What is the primary goal of Kotlin Multiplatform?\":\"Muzukashi\",\"How does Kotlin Multiplatform facilitate code sharing between platforms?\":\"By sharing business logic and adapting UI\",\"Which platforms does Kotlin Multiplatform support?\":null,\"What is a common use case for Kotlin Multiplatform?\":null,\"What is a shared code module in Kotlin Multiplatform called?\":null,\"How does Kotlin Multiplatform handle platform-specific implementations?\":null,\"What languages can be interoperable with Kotlin Multiplatform?\":null,\"What tooling supports Kotlin Multiplatform development?\":null,\"What is the benefit of using Kotlin Multiplatform for mobile development?\":null,\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\":null},{\"What is the primary goal of Kotlin Multiplatform?\":\"To share code between multiple platforms\",\"How does Kotlin Multiplatform facilitate code sharing between platforms?\":\"By sharing business logic and adapting UI\",\"Which platforms does Kotlin Multiplatform support?\":\"Android, iOS, and web\",\"What is a common use case for Kotlin Multiplatform?\":\"Developing a cross-platform app\",\"What is a shared code module in Kotlin Multiplatform called?\":\"Shared module\",\"How does Kotlin Multiplatform handle platform-specific implementations?\":\"Through expect and actual declarations\",\"What languages can be interoperable with Kotlin Multiplatform?\":\"Java, JavaScript, Swift\",\"What tooling supports Kotlin Multiplatform development?\":\"IntelliJ IDEA, Android Studio\",\"What is the benefit of using Kotlin Multiplatform for mobile development?\":\"Code reuse and sharing\",\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\":\"Kotlin Multiplatform allows sharing code between different platforms using common modules.\"},{\"What is the primary goal of Kotlin Multiplatform?\":\"Nashi\",\"How does Kotlin Multiplatform facilitate code sharing between platforms?\":\"Don't know\",\"Which platforms does Kotlin Multiplatform support?\":\"Windows Phone\",\"What is a common use case for Kotlin Multiplatform?\":\"No\",\"What is a shared code module in Kotlin Multiplatform called?\":\"Nashi\",\"How does Kotlin Multiplatform handle platform-specific implementations?\":\"Copy paste is the best\",\"What languages can be interoperable with Kotlin Multiplatform?\":\"Zenbu\",\"What tooling supports Kotlin Multiplatform development?\":\"Vim\",\"What is the benefit of using Kotlin Multiplatform for mobile development?\":\"Code reuse and sharing\",\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\":\"Kotlin Multiplatform allows sharing code between different platforms using common modules.\"}]}" }, - "execution_count": 3, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "%use kandy\n", - "%use dataframe\n", - "\n", - "val df = DataFrame.read(\"http://localhost:8080/results\")\n", - "df" - ] + "execution_count": 6 }, { "cell_type": "code", - "execution_count": 7, "metadata": { "vscode": { "languageId": "python" + }, + "ExecuteTime": { + "end_time": "2024-08-23T21:40:01.838147400Z", + "start_time": "2024-08-23T21:39:58.091494700Z" } }, + "source": [ + "val table = DataFrame.readJson(\"http://localhost:8080/table\")\n", + "table" + ], "outputs": [ { "data": { - "application/kotlindataframe+json": { - "columns": [ - "What is the primary goal of Kotlin Multiplatform?", - "How does Kotlin Multiplatform facilitate code sharing between platforms?", - "Which platforms does Kotlin Multiplatform support?", - "What is a common use case for Kotlin Multiplatform?", - "What is a shared code module in Kotlin Multiplatform called?", - "How does Kotlin Multiplatform handle platform-specific implementations?", - "What languages can be interoperable with Kotlin Multiplatform?", - "What tooling supports Kotlin Multiplatform development?", - "What is the benefit of using Kotlin Multiplatform for mobile development?", - "How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?" - ], - "kotlin_dataframe": [ - { - "How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?": [ - "Kotlin Multiplatform allows sharing code between different platforms using common modules.", - "Kotlin Multiplatform allows sharing code between different platforms using common modules." - ], - "How does Kotlin Multiplatform facilitate code sharing between platforms?": [ - "By sharing business logic and adapting UI", - "By sharing business logic and adapting UI", - "Don't know" - ], - "How does Kotlin Multiplatform handle platform-specific implementations?": [ - "Through expect and actual declarations", - "Copy paste is the best" - ], - "What is a common use case for Kotlin Multiplatform?": [ - "Developing a cross-platform app", - "No" - ], - "What is a shared code module in Kotlin Multiplatform called?": [ - "Shared module", - "Nashi" - ], - "What is the benefit of using Kotlin Multiplatform for mobile development?": [ - "Code reuse and sharing", - "Code reuse and sharing" - ], - "What is the primary goal of Kotlin Multiplatform?": [ - "Muzukashi", - "To share code between multiple platforms", - "Nashi" - ], - "What languages can be interoperable with Kotlin Multiplatform?": [ - "Java, JavaScript, Swift", - "Zenbu" - ], - "What tooling supports Kotlin Multiplatform development?": [ - "IntelliJ IDEA, Android Studio", - "Vim" - ], - "Which platforms does Kotlin Multiplatform support?": [ - "Android, iOS, and web", - "Windows Phone" - ] - } - ], - "ncol": 10, - "nrow": 1 - }, "text/html": [ - " \n", - " \n", - " \n", " \n", " \n", - "
\n", - "\n", - "

DataFrame: rowsCount = 1, columnsCount = 10

\n", - "
What is the primary goal of Kotlin Multiplatform?How does Kotlin Multiplatform facilitate code sharing between platforms?Which platforms does Kotlin Multiplatform support?What is a common use case for Kotlin Multiplatform?What is a shared code module in Kotlin Multiplatform called?How does Kotlin Multiplatform handle platform-specific implementations?What languages can be interoperable with Kotlin Multiplatform?What tooling supports Kotlin Multiplatform development?What is the benefit of using Kotlin Multiplatform for mobile development?How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?
[Muzukashi, To share code between mul...[By sharing business logic and adapti...[Android, iOS, and web, Windows Phone][Developing a cross-platform app, No][Shared module, Nashi][Through expect and actual declaratio...[Java, JavaScript, Swift, Zenbu][IntelliJ IDEA, Android Studio, Vim][Code reuse and sharing, Code reuse a...[Kotlin Multiplatform allows sharing ...
\n", + "
What is the primary goal of Kotlin Multiplatform?How does Kotlin Multiplatform facilitate code sharing between platforms?Which platforms does Kotlin Multiplatform support?What is a common use case for Kotlin Multiplatform?What is a shared code module in Kotlin Multiplatform called?How does Kotlin Multiplatform handle platform-specific implementations?What languages can be interoperable with Kotlin Multiplatform?What tooling supports Kotlin Multiplatform development?What is the benefit of using Kotlin Multiplatform for mobile development?How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?
[Muzukashi, To share code between mul...[By sharing business logic and adapti...[Android, iOS, and web, Windows Phone][Developing a cross-platform app, No][Shared module, Nashi][Through expect and actual declaratio...[Java, JavaScript, Swift, Zenbu][IntelliJ IDEA, Android Studio, Vim][Code reuse and sharing, Code reuse a...[Kotlin Multiplatform allows sharing ...
\n", " \n", " \n", " " - ] + ], + "application/kotlindataframe+json": "{\"$version\":\"2.0.0\",\"metadata\":{\"columns\":[\"What is the primary goal of Kotlin Multiplatform?\",\"How does Kotlin Multiplatform facilitate code sharing between platforms?\",\"Which platforms does Kotlin Multiplatform support?\",\"What is a common use case for Kotlin Multiplatform?\",\"What is a shared code module in Kotlin Multiplatform called?\",\"How does Kotlin Multiplatform handle platform-specific implementations?\",\"What languages can be interoperable with Kotlin Multiplatform?\",\"What tooling supports Kotlin Multiplatform development?\",\"What is the benefit of using Kotlin Multiplatform for mobile development?\",\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\"],\"nrow\":1,\"ncol\":10},\"kotlin_dataframe\":[{\"What is the primary goal of Kotlin Multiplatform?\":[\"Muzukashi\",\"To share code between multiple platforms\",\"Nashi\"],\"How does Kotlin Multiplatform facilitate code sharing between platforms?\":[\"By sharing business logic and adapting UI\",\"By sharing business logic and adapting UI\",\"Don't know\"],\"Which platforms does Kotlin Multiplatform support?\":[\"Android, iOS, and web\",\"Windows Phone\"],\"What is a common use case for Kotlin Multiplatform?\":[\"Developing a cross-platform app\",\"No\"],\"What is a shared code module in Kotlin Multiplatform called?\":[\"Shared module\",\"Nashi\"],\"How does Kotlin Multiplatform handle platform-specific implementations?\":[\"Through expect and actual declarations\",\"Copy paste is the best\"],\"What languages can be interoperable with Kotlin Multiplatform?\":[\"Java, JavaScript, Swift\",\"Zenbu\"],\"What tooling supports Kotlin Multiplatform development?\":[\"IntelliJ IDEA, Android Studio\",\"Vim\"],\"What is the benefit of using Kotlin Multiplatform for mobile development?\":[\"Code reuse and sharing\",\"Code reuse and sharing\"],\"How does Kotlin Multiplatform differ from Kotlin Native and Kotlin/JS?\":[\"Kotlin Multiplatform allows sharing code between different platforms using common modules.\",\"Kotlin Multiplatform allows sharing code between different platforms using common modules.\"]}]}" }, - "execution_count": 7, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "val table = DataFrame.readJson(\"http://localhost:8080/table\")\n", - "table" - ] + "execution_count": 4 } ], "metadata": { diff --git a/material/rest-api-ui-ktor-quiz-collector/src/main/kotlin/example/com/QuizCollector.kt b/material/rest-api-ui-ktor-quiz-collector/src/main/kotlin/example/com/QuizCollector.kt index 36e6ee19..dcc94923 100644 --- a/material/rest-api-ui-ktor-quiz-collector/src/main/kotlin/example/com/QuizCollector.kt +++ b/material/rest-api-ui-ktor-quiz-collector/src/main/kotlin/example/com/QuizCollector.kt @@ -17,13 +17,23 @@ fun Application.configureQuizCollector() { call.respond(CollectResponse(quizResponse.getScore())) } - get("/results") { + get("/responses") { + call.respond(quizResponses.map { quizResponse -> + quizResponse.responses.fold(mutableMapOf()) { acc, element -> + acc[element.question] = element.answer + acc + } + }) + } + + get("/table2") { call.respond(quizResponses) } get("/table") { - call.respond(quizResponses.flatMap { it.responses }.groupBy { it.question } - .mapValues { it.value.map { it.answer } }) + val result = quizResponses.flatMap { it.responses }.groupBy { it.question } + .mapValues { it.value.map { value -> value.answer } } + call.respond(result) } get("/ui") { diff --git a/material/rest-api-ui-ktor-quiz-collector/src/main/resources/application.yaml b/material/rest-api-ui-ktor-quiz-collector/src/main/resources/application.yaml index 3689c620..4ac0a499 100644 --- a/material/rest-api-ui-ktor-quiz-collector/src/main/resources/application.yaml +++ b/material/rest-api-ui-ktor-quiz-collector/src/main/resources/application.yaml @@ -1,6 +1,9 @@ ktor: - application: - modules: - - example.com.ApplicationKt.module - deployment: - port: 8080 + development: true + application: + modules: + - example.com.ApplicationKt.module + deployment: + port: 8080 + watch: + - classes