{ "cells":[ { "cell_type":"markdown", "source":[ "# Libraries API Guide\n", "[Documentation](https:\/\/github.com\/Kotlin\/kotlin-jupyter\/blob\/master\/docs\/libraries.md)" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"yvyRyH288A7MoqtYzoauPM", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"0ON8yI917hwj8FeK0pQsky" } } } }, { "cell_type":"code", "source":[ "notebook.kernelVersion" ], "execution_count":1, "outputs":[ { "data":{ "text\/plain":[ "0.11.0.365" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"473vDoAud72LeO1mGYfdT5", "type":"CODE", "hide_input_from_viewers":true, "hide_output_from_viewers":true } } }, { "cell_type":"markdown", "source":[ "## Dependencies and imports\n", "\n", "Assume we want to add binary dependency on some library.\n", "In this case let's add JAR coordinates of this library to the `dependencies`\n", "array of our descriptor. If it is not on Maven Central, we add repository\n", "(or repositories) where this dependency is located. Also, we can add\n", "default imports" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"3EWan5WOD4obPRmJJoHRyl", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"vS92wiTvpFntHSEMCrr5H9" } } } }, { "cell_type":"code", "source":[ "val dollar = \"$\"\n", "loadLibraryDescriptor(\n", " \"\"\"\n", " {\n", " \"dependencies\": [\n", " \"org.ileasile:kformat:${dollar}libVersion\"\n", " ],\n", " \"repositories\": [\n", " \"https:\/\/maven.pkg.github.com\/ileasile\/kformat\"\n", " ],\n", " \"imports\": [\n", " \"org.ileasile.kformat.*\"\n", " ],\n", " \"properties\": {\n", " \"libVersion\": \"0.0.1\"\n", " }\n", " }\n", " \"\"\",\n", " mapOf(\"libVersion\" to \"0.0.2\")\n", ")" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"0CWJquaSDtgDzeUv0DimCZ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"3XSS7u0TNIQpjxsTLZoRig" } } } }, { "cell_type":"markdown", "source":[ "Huh, we've got 401(Unauthorized). That's because reading from GitHub Packages\n", "requires authorization. We can add authorization for our repository in descriptor." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"V4uuN3nNDZXE311jEAydWG", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9aQzeJN8aSKkrM8z1a8Acs" } } } }, { "cell_type":"code", "source":[ "val readToken = \"ghp_\"" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"6yN7sFRwduz7klnJgPrB7X", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"XiD8FUF2KgFyi8XBVKQpnU" } } } }, { "cell_type":"code", "source":[ "loadLibraryDescriptor(\"\"\"\n", " {\n", " \"dependencies\": [\n", " \"org.ileasile:kformat:0.0.2\"\n", " ],\n", " \"repositories\": [\n", " {\n", " \"path\": \"https:\/\/maven.pkg.github.com\/ileasile\/kformat\",\n", " \"username\": \"ileasile\",\n", " \"password\": \"$readToken\"\n", " }\n", " ],\n", " \"imports\": [\n", " \"org.ileasile.kformat.*\"\n", " ]\n", " }\n", "\"\"\")" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"ICuKkECCy5fwEPqwa2R1CX", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"guaD3yArd3wnoMlMhxLe4X" } } } }, { "cell_type":"code", "source":[ "kFormat {\n", " color(BasicColor.Red) {\n", " italic {\n", " + \"Red italic text\"\n", " }\n", " }\n", "}.asAnsiEscaped()" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "\u001b[31m\u001b[3mRed italic text\u001b[m\u001b[31m\u001b[m\u001b[m" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"3Mn7l2KWXSxKCw6uMPijdM", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"iUfleWm1l7UrnMboME6qdN" } } } }, { "cell_type":"markdown", "source":[ "Another way to do the same thing using Kotlin API:" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"Yaijjy4T9JqYtAASLGAqul", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"SZQ4DmXm4LKPZXSWKa2FUa" } } } }, { "cell_type":"code", "source":[ "USE {\n", " dependencies(\"org.ileasile:kformat:0.0.2\")\n", " repository(\n", " \"https:\/\/maven.pkg.github.com\/ileasile\/kformat\",\n", " \"ileasile\",\n", " readToken\n", " )\n", " import(\"org.ileasile.kformat.*\")\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"XcH81I9hFMNzCHqxiMEJUE", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"SqdpEchM5GWiblQZFplRpl" } } } }, { "cell_type":"markdown", "source":[ "Also, Kotlin API allows to define dependencies in Gradle style:" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"staCddVMHTi49I5b31E1tk", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"YrLfbBZxK3gmzAjhOcToTI" } } } }, { "cell_type":"code", "source":[ "USE {\n", " dependencies {\n", " implementation(\"org.ileasile:kformat:0.0.2\")\n", " }\n", " repositories {\n", " maven {\n", " url = \"https:\/\/maven.pkg.github.com\/ileasile\/kformat\"\n", " credentials {\n", " username = \"ileasile\"\n", " password = readToken\n", " }\n", " }\n", " }\n", " import(\"org.ileasile.kformat.*\")\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"CFm4qEKjHsxHHGyVltuetk", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"aY56fUvdq8nKDNJRhibmjc" } } } }, { "cell_type":"code", "source":[ "\/\/@file:DependsOn\n", "\/\/@file:Repository" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"pvtJ9O84yMmtOfFEvlXXc0", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"cM7Eec2U1CVBlHSH17Rg1D" } } } }, { "cell_type":"markdown", "source":[ "## Initialization callbacks\n", "You can define the code that should be run after library initialization.\n", "In descriptors, only code executions are available for this purpose.\n", "In Kotlin API you can do a bit more." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"2t4kFtppYUB60JpAX4G0Vy", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"c3ukpEDkef9NnK5W6m80fX" } } } }, { "cell_type":"code", "source":[ "loadLibraryDescriptor(\"\"\"\n", " {\n", " \"init\": [\n", " \"val myVar1 = 42\",\n", " \"fun doInit1() {}\",\n", " \"println(\\\"Library 1 initialized\\\")\"\n", " ]\n", " }\n", "\"\"\")" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Library 1 initialized\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"L1LDqh7lkS1goN8rbBjSIE", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"bJriUMfF1ALMgCZRqL2vPR" } } } }, { "cell_type":"code", "source":[ "class Config(\n", " var bufferSize: Int = 100\n", ")\n", "\n", "val config1 = Config()\n", "\n", "USE {\n", " onLoaded {\n", " declare(\"myVar3\" to config1)\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"9eqic9jFlk5HV7wtGa0xxV", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"eg2gxPucspll8gUsgPMeml" } } } }, { "cell_type":"code", "source":[ "myVar3.bufferSize = myVar1" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"jiSOTAXlmYqOJp0PhnBgnT", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"WOxFiL3cGnwp0EfdM7ZMHv" } } } }, { "cell_type":"code", "source":[ "myVar3.bufferSize" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "42" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"4ZHpp8jFXYZuKXCBbchbFV", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"PwhJpKfF01V5FgWZ0vKmJH" } } } }, { "cell_type":"code", "source":[ "myVar3.bufferSize = 10" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"oE4AsSeJFz2ekobazrAZyL", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ajiBPydxHG4Xeq9tlTUVNm" } } } }, { "cell_type":"code", "source":[ "config1.bufferSize" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "10" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"I19AnHiRpO5KqIFPSgZ4tW", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"trd9FQC5p4kj2twt1NSdZi" } } } }, { "cell_type":"markdown", "source":[ "## Before- and after-cell callbacks\n", "\n", "Sometimes you may want to execute some code before cell execution.\n", "That's how you can achieve it with library descriptor" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"t2yRsMNARg8l0sorhYSM2s", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ytCzH78nG3CehElCoOlCp2" } } } }, { "cell_type":"code", "source":[ "loadLibraryDescriptor(\"\"\"\n", " {\n", " \"initCell\": [\n", " \"println(\\\"Before cell execution - 1\\\")\"\n", " ]\n", " }\n", "\"\"\")" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"BIsRgylmv6Ck8pCagHjIfQ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kIehA33S1UmxSoILQBOezz" } } } }, { "cell_type":"code", "source":[ "2 + 2 + 7" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Before cell execution - 1\r\n", "\n" ], "output_type":"stream" }, { "name":"stderr", "text":[ "\n" ], "output_type":"stream" }, { "data":{ "text\/plain":[ "11" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"AzGRGqzpPJipHpBnXJmFzs", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"loTaywakOhZgSG9nNxroBD" } } } }, { "cell_type":"markdown", "source":[ "You can achieve the same thing using Kotlin API" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"eARU2WTPp6GXOG3A2eatMP", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"aRiAfUct8tkDWLUoCXSPUa" } } } }, { "cell_type":"code", "source":[ "USE {\n", " beforeCellExecution {\n", " println(\"Before cell execution - 2\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Before cell execution - 1\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"1sxa0CXvhLZDzOhrskiMbO", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"29gNY5AfVcwwJIu9XdIeZC" } } } }, { "cell_type":"code", "source":[ "2 + 2" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Before cell execution - 1\r\n", "Before cell execution - 2\r\n", "\n" ], "output_type":"stream" }, { "name":"stderr", "text":[ "\n" ], "output_type":"stream" }, { "data":{ "text\/plain":[ "4" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"q0Aua9OEl1Z2vV3jqDgf1d", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"qPr8FSa9A021OrxQcpqgvf" } } } }, { "cell_type":"markdown", "source":[ "You can manage added callbacks. Let's clear them." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"1m5WHFHEZTkENJegwK28fp", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"5H8VGC7gJEfYKSDQ1wDrFw" } } } }, { "cell_type":"code", "source":[ "notebook.beforeCellExecutionsProcessor.unregisterAll()" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Before cell execution - 1\r\n", "Before cell execution - 2\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"QOda8P2ggk7v4KPAXRBBSH", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"LEj97CaHd6FEIUoWTDWrUd" } } } }, { "cell_type":"code", "source":[ "2 + 2" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "4" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"1AhY64SK9ZxwRYARDBoZBL", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kUqpFEoT4wdrCyvaRjlL9U" } } } }, { "cell_type":"markdown", "source":[ "With Kotlin API, you can also create callbacks that are run after cells execution. Execution result is passed to them." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"ZbulAcAi9qUoHNTvuIiBlv", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"83T4EixM904negk4PspoX9" } } } }, { "cell_type":"code", "source":[ "USE {\n", " afterCellExecution { snippetInstance, result ->\n", " val maybeDoubledResult = (result.value as? Int)?.let { it * 2 }\n", " println(\"After execution of $snippetInstance: $maybeDoubledResult (${result.name})\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"1byxvh0xyBADy8SwMLniCS", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"jiBee7WXAMh0dRE0mXCwYJ" } } } }, { "cell_type":"code", "source":[ "2 + 2" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "After execution of Line_34_jupyter@4306c59c: 8 (res34)\r\n", "\n" ], "output_type":"stream" }, { "name":"stderr", "text":[ "\n" ], "output_type":"stream" }, { "data":{ "text\/plain":[ "4" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"noRPMGssyqDY0I3ylUbUyF", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"vWW1rKGiTC5wCiRppqSPtl" } } } }, { "cell_type":"markdown", "source":[ "Let's remove this callback as well, but do it in a bit more complicated manner" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"ZsKekEpBlqek77sWCjZNyw", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"NZYYw8krWxxsn6ViFn8HQZ" } } } }, { "cell_type":"code", "source":[ "notebook.afterCellExecutionsProcessor.let { processor ->\n", " processor.unregister(processor.registeredExtensions().first())\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"v3NZFJcHzeAbSs7N7RFbGH", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"dr2BNXz8zjk4Heei7SHzTo" } } } }, { "cell_type":"markdown", "source":[ "## Shutdown and interruption callbacks\n", "\n", "Kernel users have the ability to interrupt, restart and stop the kernel.\n", "What does it mean?\n", "\n", "**Interruption** just interrupts current cell execution. For example,\n", "if the user has run very long or infinite computation, they might want\n", "to interrupt it. After interruption kernel state remains untouched.\n", "\n", "**Stopping** kernel means just stopping the session. Kernel process is aborted,\n", "kernel state is aborted too.\n", "\n", "**Restarting** kernel means stopping followed by starting. Kernel process\n", "is aborted and then started again, kernel state is also cleared.\n", "\n", "Sometimes you may want to write a callback on kernel interruption or shutdown (that happens on stopping or restarting). And you can, using descriptor or Kotlin API." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"pzpQRXUrmoe70HgLdNw7vd", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"HLOTmBX4YcaBXoCInGaWBA" } } } }, { "cell_type":"code", "source":[ "\/\/ Interruption callbacks aren't supported by descriptor API\n", "loadLibraryDescriptor(\"\"\"\n", " {\n", " \"shutdown\": [\n", " \"println(\\\"Bye!\\\")\"\n", " ]\n", " }\n", "\"\"\")" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"7CKOXDY3J8daQDdptDqR77", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"sZDxeSOclpqLQU6I3U4ZFU" } } } }, { "cell_type":"code", "source":[ "var interruptionCount = 0\n", "USE {\n", " onShutdown {\n", " println(\"Bye! (2)\")\n", " }\n", "\n", " onInterrupt {\n", " ++interruptionCount\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"mMZepUVoYIFK0dFv0vrDT5", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"XJdz2W54VQ71MD37E7zK44" } } } }, { "cell_type":"code", "source":[ "while(true) {}" ], "execution_count":null, "outputs":[ { "name":"stderr", "text":[ "The execution was interrupted" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"wDfX0A3EqhWkX2UCADHWvM", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"sWNQSLVUcaeEBmAPpke16g" } } } }, { "cell_type":"markdown", "source":[ "Shutdown callbacks can be managed by corresponding processor.\n", "API for extensions management will be most likely reworked in the future\n", "versions of kernel." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"LDvkJAbLhf0sLT8naKOpdj", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9uUmhY5IEWb0F9Z4LLL9ns" } } } }, { "cell_type":"code", "source":[ "interruptionCount" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "1" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"AxHz6sT8igD0xHatR2O3TI", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9aUzTpm3Fs3zjX6Fl5svDH" } } } }, { "cell_type":"code", "source":[ "notebook.shutdownExecutionsProcessor.unregisterAll()\n", "notebook.interruptionCallbacksProcessor.unregisterAll()" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"jVo4UAFNdHBeHnI0NgQTEy", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"XKeLbzujSGyt7sGXweJGW6" } } } }, { "cell_type":"markdown", "source":[ "## Color scheme change callbacks\n", "\n", "Sometimes you may want to do something when the user changes current\n", "color scheme in their client. For example, you might want to change color\n", "scheme for newly created outputs or even update already created ones.\n", "You definitely can, but only in Kotlin API, and only if the user uses Kotlin Notebook plugin" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"Y8m8UCdfIZajEZZOo0DeSR", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"TjL2Gby4DlurAmXZNsOMiY" } } } }, { "cell_type":"code", "source":[ "var isDark = notebook.currentColorScheme == ColorScheme.DARK\n", "USE {\n", " println(\"Dark? - $isDark\")\n", "\n", " onColorSchemeChange { colorScheme ->\n", " isDark = colorScheme == ColorScheme.DARK\n", " println(\"Color scheme is changed\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Dark? - false\r\n", "Color scheme is changed\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"kfACAahonfgtU9aTCjq8A5", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"FSrS8i1Hfq5tw0NeYR13tC" } } } }, { "cell_type":"code", "source":[ "isDark" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "false" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"fPAAWxuXezIC0ijB7Z665a", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"wCZCvAr5I4GqhHJUWcEKSL" } } } }, { "cell_type":"code", "source":[ "notebook.colorSchemeChangeCallbacksProcessor.unregisterAll()" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"2I7qSrr5q1pjDGlafkAkQb", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"8RvJheV7qmMV3TgAjrClo9" } } } }, { "cell_type":"markdown", "source":[ "## Rendering" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"CShwMC7nRK99DulXh8qLcf", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"cZG2Gg1q6ricyrJ2obqEVN" } } } }, { "cell_type":"markdown", "source":[ "Imagine you're developing a model for TicTacToe game and want to experiment with it in the notebook.\n", "You want to have some visual representation of the model. Now all what you have is a following\n", "string representation of the game state:" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"dcpELDBqZXULEmSZWx0H5S", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"MgHGwgpl2ke1SqG0BvCeuI" } } } }, { "cell_type":"code", "source":[ "val gameState = \"x_o|_x_|___\"\n", "gameState" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "x_o|_x_|___" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"y63yo6tLdvnMsm0KGSGdnu", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"CKP7bVtnKhgS7hYqLrbKIs" } } } }, { "cell_type":"markdown", "source":[ "First thing you might want to do is to create a matrix containing the state in easier-to-use form" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"xGjOhoO7Z8zpMX2BUfFPy6", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"FYVprXZJX8ybIkUdRYlbMC" } } } }, { "cell_type":"code", "source":[ "enum class TTTCell {\n", " X, O, Empty\n", "}\n", "\n", "fun getGameState(state: String) = state.split('|')\n", " .map { line ->\n", " line.map {\n", " when (it) {\n", " 'x' -> TTTCell.X\n", " 'o' -> TTTCell.O\n", " '_' -> TTTCell.Empty\n", " else -> error(\"Not possible\")\n", " }\n", " }\n", " }" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"qzbgFqmprSHGn4hbFD4DeE", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"3CkWbCch8Jhw0YWvzybrWe" } } } }, { "cell_type":"code", "source":[ "val stateMatrix = getGameState(gameState)\n", "stateMatrix" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "[[X, Empty, O], [Empty, X, Empty], [Empty, Empty, Empty]]" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"pIEgOcSU0NZ7T2iMeis8jN", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"yO7NShs20PgUXH62mQECW9" } } } }, { "cell_type":"code", "source":[ "class TTTState(val stateMatrix: List>)" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"tGc4r1UI8QshX6E0SNwHlF", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ueDFLSiaxErv3sQNrMRxQK" } } } }, { "cell_type":"code", "source":[ "val state = TTTState(stateMatrix)" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"lgYCIs3FwBLQgbbFcsvMvX", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Zfx5UVcbiQybfkOTQunf2u" } } } }, { "cell_type":"markdown", "source":[ "To render it, we may add a text renderer. Text renderers are supported only by Kotlin API and can only\n", "render values to string. Their benefit is that they can easily stack together: string are addable." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"JlMwa1IOmmwF53KAeZoY6n", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"mEXNvt604KWPfHBDZf3wLy" } } } }, { "cell_type":"code", "source":[ "USE {\n", " addTextRenderer(TextRenderer { _, value ->\n", " (value as? TTTState)?.let { state ->\n", " state.stateMatrix.joinToString(\"\\n\") { line ->\n", " line.joinToString(\" \") {\n", " when (it) {\n", " TTTCell.X -> \"X\"\n", " TTTCell.O -> \"O\"\n", " TTTCell.Empty -> \"_\"\n", " }\n", " }\n", " }\n", " }\n", " })\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"KvqdiHpdZi2CphIYSxMj1r", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"uP4CXk9t9NAos3ns4xyVrl" } } } }, { "cell_type":"code", "source":[ "state" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "X _ O\n", "_ X _\n", "_ _ _" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"z3IzOGeflKEYFIWPTw7hU8", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"XsGdpQCPHSyqtXVbcGgYN4" } } } }, { "cell_type":"markdown", "source":[ "It's much better now, but we still might wish some graphic representation of the state.\n", "Let's create a couple of renderers. Renderers accept some values and return some other\n", "values. Rendering logic is described in [kernel documentation](https:\/\/github.com\/Kotlin\/kotlin-jupyter\/blob\/master\/docs\/README.md#rendering). Here, we register created renderers with `RenderersProcessor` and specify priority for them to ensure the order of probation" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"rJECecwjQvVYlV4SIPIZc8", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"pHiR3R2hbskzidNu8lLsT0" } } } }, { "cell_type":"code", "source":[ "val htmlStateRenderer = createRenderer {\n", " val style = \"\"\"\n", " border: 1px solid black;border-collapse: collapse;\n", " \"\"\".trimIndent()\n", " val html =\n", " it.stateMatrix.joinToString(\"\\n\", prefix = \"
\", postfix = \"<\/table><\/div>\") { line ->\n", " line.joinToString(\"\", prefix = \"\", postfix = \"<\/tr>\") { cell ->\n", " buildString {\n", " append(\"
\")\n", " append(\n", " when (cell) {\n", " TTTCell.X -> \"X\"\n", " TTTCell.O -> \"O\"\n", " TTTCell.Empty -> \"\\u200D\"\n", " }\n", " )\n", " append(\"<\/td>\")\n", " }\n", " }\n", " }\n", " mimeResult(\n", " MimeTypes.HTML to html,\n", " MimeTypes.PLAIN_TEXT to it.stateMatrix.toString()\n", " )\n", "}\n", "notebook.renderersProcessor.registerWithoutOptimizing(htmlStateRenderer, ProcessingPriority.DEFAULT + 5)" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"DLTsEANu9jBz4ergY2ux1u", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"y1qxBTRSDNmRIZDSEXtwTP" } } } }, { "cell_type":"code", "source":[ "state" ], "execution_count":null, "outputs":[ { "data":{ "text\/html":[ "
X<\/td>‍<\/td>O<\/td><\/tr>\n", "
‍<\/td>X<\/td>‍<\/td><\/tr>\n", "
‍<\/td>‍<\/td>‍<\/td><\/tr><\/table><\/div>" ] }, "metadata":{ }, "output_type":"display_data" }, { "data":{ "text\/plain":[ "[[X, Empty, O], [Empty, X, Empty], [Empty, Empty, Empty]]" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"5PphdaFz14XBvovS6ZYF8z", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"HAMo4XcsvceFepwnsltw4q" } } } }, { "cell_type":"markdown", "source":[ "The following renderer will render not to `DisplayResult`, but to a `BufferedImage`.\n", "Kernel knows how to render `BufferedImage`, that's because it works fine." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"Bu94DrZBzM5aNZzmNILMJl", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"qDjMyIfpi7x9tS6RQm0eqH" } } } }, { "cell_type":"code", "source":[ "import java.awt.Color\n", "import java.awt.geom.Ellipse2D\n", "import java.awt.image.BufferedImage\n", "\n", "@OptIn(ExperimentalStdlibApi::class)\n", "val imageStateRenderer = createRenderer { state ->\n", " val cellSize = 100\n", " val padding = 5\n", " val mtx = state.stateMatrix\n", " val rowsCount = mtx.size\n", " val colsCount = mtx.first().size\n", " val width = 2 * padding + cellSize * colsCount\n", " val height = 2 * padding + cellSize * rowsCount\n", "\n", " val img = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)\n", " val g = img.createGraphics()\n", " g.color = Color.BLACK\n", "\n", " val figPadding = cellSize \/ 10\n", " fun drawCell(xOffset: Int, yOffset: Int, cell: TTTCell) {\n", " when (cell) {\n", " TTTCell.X -> {\n", " g.drawLine(\n", " xOffset + figPadding,\n", " yOffset + figPadding,\n", " xOffset + cellSize - figPadding,\n", " yOffset + cellSize - figPadding\n", " )\n", " g.drawLine(\n", " xOffset + cellSize - figPadding,\n", " yOffset + figPadding,\n", " xOffset + figPadding,\n", " yOffset + cellSize - figPadding\n", " )\n", " }\n", " TTTCell.O -> {\n", " g.draw(Ellipse2D.Double(\n", " (xOffset + figPadding).toDouble(),\n", " (yOffset + figPadding).toDouble(),\n", " (cellSize - 2 * figPadding).toDouble(),\n", " (cellSize - 2 * figPadding).toDouble(),\n", " ))\n", " }\n", "\n", " TTTCell.Empty -> {}\n", " }\n", " }\n", "\n", " fun drawGrid() {\n", " for (i in 0..rowsCount) {\n", " g.drawLine(\n", " padding,\n", " padding + i * cellSize,\n", " padding + colsCount * cellSize,\n", " padding + i * cellSize,\n", " )\n", " }\n", " for (j in 0..colsCount) {\n", " g.drawLine(\n", " padding + j * cellSize,\n", " padding,\n", " padding + j * cellSize,\n", " padding + rowsCount * cellSize,\n", " )\n", " }\n", " }\n", "\n", " drawGrid()\n", " for (i in 0..< rowsCount) {\n", " for (j in 0..< colsCount) {\n", " drawCell(padding + j * cellSize, padding + i * cellSize, mtx[i][j])\n", " }\n", " }\n", "\n", " img\n", "}\n", "\n", "notebook.renderersProcessor.registerWithoutOptimizing(imageStateRenderer, ProcessingPriority.HIGHER)" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"m9mMXXKfygvqQT9Dy5t6VZ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Nd5ZojCHu4qwbynpIuulr9" } } } }, { "cell_type":"code", "source":[ "state" ], "execution_count":null, "outputs":[ { "data":{ "image\/png":[ "iVBORw0KGgoAAAANSUhEUgAAATYAAAE2CAYAAADrvL6pAAASDElEQVR4Xu3W0W7ltrZE0fz\/T9+LRk7DiWO3JymyWJLmAPZDkuLiEgsw8tdfkiRJkiRJkiRJwP\/58+fP341+CA4qwj662EcX3AcOKsI+uthHF9wHDirCPrrYRxfcBw4qwj662EcX3AcOKsI+uthHF9wHDirCPrrYRxfcBw4qwj662EcX3AcOKsI+uthHF9wHDirCPrrYRxfcBw3SnL5G34\/mlHHXPn7t\/affXeHdcfCvsaw+jLzbSFb7tffx+Q8W\/cP1OT9y9iS8Hw7+z2j+7UbfazSvvRr72P1HaPf8K\/BOOPgPM2feaOadZs5on5Y+Tv2xOXXvd\/AeOPjJ7Lm3mH2f2XPa43QfbX9UTu+C78fBL1w5+2RX3uXKWa13so+Td\/\/Jyb3w3Tj4javnn+bqe1w9r7VO9NHwf0Y\/ObUjvhMH\/2DFjCdY8Q4rZmidZB+n\/lhckd4Z34WDP1g1565Wff+qOVoj1Ufqnl1S++N7cBBYOetOVn73ylm6bncf6f\/j2SnxLXg+DkKr57Vb\/b2r5+manX3snH3Szu\/Cs3FwwI6ZjXZ8546Zmrerj11zW+z6PjwXBwftmtti1\/ftmqs5O\/rYMbPRju\/EM3Fwws7ZJ+38rp2zNW51H6vntVv9vXgeDk7aPT9t9\/fsnq8xK\/tYOetOVn43noWDFyTuSEh8R+IOcSv7WDnrTlZ+N56Fgxel7tkltX\/qHjGr+lg1565WfT+eg4MLJO9aKbl38i79bEUfK2Y8wYp3wDNwcJH0fVel903fpz9b0ceKGU+w4h3wDBxc6MSdM07seeJOfe9qH1fPP83V98DncXCxU\/dSp\/Y7da++drWPq+ef5up74PM4uMHJu\/\/k5F4n79Z\/Xenjytknu\/Iu+CwObnL6\/s9O73P6fv3bbB+z595i9n3wORzcqGGHXxr2aNhBH2b7mD33FrPvg8\/h4Gan9zh9\/28te+hvM33MnHmjmXfCZ3Aw4NQup+79StMumutj5swbzbwTPoODIel90vf9pG2ft5vpY+bMG828Ez6Dg0GpnVL3jGjc6c1G+xjNv93oe+E8Dobt3mv3\/Fmte73VaB+j+bcbfS+cx8EDdu22a+4Kzbu90Wgfo\/m3G30vnMfBQ1bvt3reau37vc1IHyNZfRh5N5zFwYNW7bhqzk532PFNRvoYyerDyLvhLA4ednXPq+dT7rLnW4z0MZLVh5F3w1kcLDC76+y5E+606xuM9DGS1YeRd8NZHCwxuu9o\/rS77ft0I32MZPVh5N1wFgeL0J1prskdd36ykT5Gsvow8m44i4Nlftr7p\/\/e6q57P9VIHyNZ\/Rt9O5rjwULf7f7dv7+DO+\/+RLQPmtPX6PvRHA+W+rz\/53++m7vv\/zS0D5rT1+j70RwPFvv9DU\/6FnWgfdCcvkbfj+Z4sJzfoR1oHzSnr9H3ozkeLOb\/sWkX2gfN6Wv0\/WiOB0t93v\/zP9\/N3fd\/GtoHzelr9P1ojgcLfbf7d\/\/+Du68+xPRPmhOX6PvR3M8WOanvX\/6763uuvdT0T5oTv818nY4i4NF6M401+SOOz\/ZSB8jWX0YeTecxcESo\/uO5k+7275PN9LHSFYfRt4NZ3GwwOyus+dOuNOubzDSx0hWH0beDWdx8LCre149n3KXPd9ipI+RrD6MvBvO4uBBq3ZcNWenO+z4JiN9jGT1YeTdcBYHD1m93+p5q7Xv9zYjfYxk9WHk3XAWBw\/YtduuuSs07\/ZGo32M5t9u9L1wHgfDdu+1e\/6s1r3earSP0fzbjb4XzuNgUGqn1D0jGnd6s9E+RvNvN\/peOI+DIel90vf9pG2ft5vpY+bMG828Ez6DgwGndjl171eadtFcHzNn3mjmnfAZHNzs9B6n7\/+tZQ\/9baaPmTNvNPNO+AwObtSwwy8NezTsoA+zfcyee4vZ98HncHCT0\/d\/dnqf0\/fr32b7mD33FrPvg8\/h4AYn7\/6Tk3udvFv\/daWPK2ef7Mq74LM4uNipe6lT+526V1+72sfV809z9T3weRxc6MSdM07seeJOfe9qH1fPP83V98DncXCR9H1XpfdN36c\/W9HHihlPsOId8AwcXCB510rJvZN36Wcr+lgx4wlWvAOegYMXpe7ZJbV\/6h4xq\/pYNeeuVn0\/noODFyTuSEh8R+IOcSv7WDnrTlZ+N56Fg5N2z0\/b\/T2752vMyj5WzrqTld+NZ+HghJ2zT9r5XTtna9zqPlbPa7f6e\/E8HBy0a26LXd+3a67m7Ohjx8xGO74Tz8TBATtmNtrxnTtmat6uPnbNbbHr+\/BcHIRWz2u3+ntXz9M1O\/vYOfuknd+FZ+MgsHLWnaz87pWzdN3uPn7N331HSuJb8Hwc\/MGqOXe16vtXzdEaqT5S9+yS2h\/fg4N\/sGLGE6x4hxUztE6yj8T\/8ayW3hnfhYPfuHr+aa6+x9XzWutEH+k\/FjNO7YjvxMEvXDn7ZFfe5cpZrXeyj5N3\/8nJvfDdOPjJ7Lm3mH2f2XPa43Qfp\/7P6CsNu+D7cfAfZs680cw7zZzRPi19\/P6jkt7n1L3fwXvg4P+M5t9u9L1G89qrsY\/df2x2z78C74SDf41l9WHk3Uay2q+9j3\/+Efr8+8nnPD13Et6PBmlOX6PvR3PKuHMfn\/9gff7dEd4bBxVhH13sowvuAwcVYR9d7KML7gMHFWEfXeyjC+4DBxVhH13sowvuAwcVYR9d7KML7gMHFWEfXeyjC+4DBxVhH13sowvuAwcVYR9d7KML7gMHFWEfXeyjC+7jV9CfP3\/+7vJDcFAR9tHFPrrgPnBQEfbRxT664D5wUBH20cU+uuA+cFAR9tHFPrrgPnBQEfbRxT664D5wUBH20cU+uuA+cFAR9tHFPrrgPnBQEfbRxT664D5wUBH20cU+uuA+cFARtA+a09fo+9GcMnAfOKiIkT5Gsvow8m4jWe2H+8BBRYz2MZp\/u9H3Gs1rL9wHDipipo+ZM280804zZ7QP7gMHFTHbx+y5t5h9n9lz2gP3gYOKuNLHlbNPduVdrpzVergPHFTE1T6unn+aq+9x9bzWwn3goCJW9LFixhOseIcVM7QO7gMHFbGqj1Vz7mrV96+aozVwHzioiJV9rJx1Jyu\/e+UsXYf7wEFFrO5j9bx2q7939Txdg\/vAQUXs6GPHzEY7vnPHTM3DfeCgInb1sWtui13ft2uu5uA+cFARO\/vYOfuknd+1c7bG4T5wUBG7+9g9P2339+yerzG4DxxURKKPxB0Jie9I3CEO94GDikj1kbpnl9T+qXvE4D5wUBHJPpJ3rZTcO3mXfob7wEFFpPtI33dVet\/0ffoz3AcOKuJEHyfunHFizxN36nu4DxxUxKk+Tt1Lndrv1L36Gu4DBxVxso+Td\/\/Jyb1O3q3\/wn3goCJO93H6\/s9O73P6fv0b7gMHFdHQR8MOvzTs0bCDPuA+cFARLX2c3uP0\/b+17KG\/4T5wUBFNfZza5dS9X2naRQN94KAi2vpI75O+7ydt+7wd7gMHFdHYR2qn1D0jGnd6M9wHDiqitY\/de+2eP6t1r7fCfeCgIpr72LXbrrkrNO\/2RrgPHFREex+r91s9b7X2\/d4G94GDirhDH6t2XDVnpzvs+Ca4DxxUxF36uLrn1fMpd9nzLXAfOKiIO\/Uxu+vsuRPutOsb4D5wUBF362N039H8aXfb9+lwHzioiDv2QXemuSZ33PnJcB84qIi79vHT3j\/991Z33fupcB84qIg79\/Hd7t\/9+zu48+5PhPvAQUXcvY\/P+3\/+57u5+\/5Pg\/vAQUU8oY\/f3\/Ckb1EH3AcOKuIpffgd2gH3gYOKeEIf\/h+bdsF94KAi7t7H5\/0\/\/\/Pd3H3\/p8F94KAi7tzHd7t\/9+\/v4M67PxHuAwcVcdc+ftr7p\/\/e6q57PxXuAwcVccc+6M401+SOOz8Z7gMHFXG3Pkb3Hc2fdrd9nw73gYOKuFMfs7vOnjvhTru+Ae4DBxVxlz6u7nn1fMpd9nwL3AcOKuIOfazacdWcne6w45vgPnBQEe19rN5v9bzV2vd7G9wHDiqiuY9du+2au0Lzbm+E+8BBRbT2sXuv3fNnte71VrgPHFREYx+pnVL3jGjc6c1wHzioiLY+0vuk7\/tJ2z5vh\/vAQUU09XFql1P3fqVpFw30gYOKaOnj9B6n7\/+tZQ\/9DfeBg4po6KNhh18a9mjYQR9wHzioiNN9nL7\/s9P7nL5f\/4b7wEFFnOzj5N1\/cnKvk3frv3AfOKiIU32cupc6td+pe\/U13AcOKuJEHyfunHFizxN36nu4DxxURLqP9H1XpfdN36c\/w33goCKSfSTvWim5d\/Iu\/Qz3gYOKSPWRumeX1P6pe8TgPnBQEYk+EnckJL4jcYc43AcOKmJ3H7vnp+3+nt3zNQb3gYOK2NnHztkn7fyunbM1DveBg4rY1ceuuS12fd+uuZqD+8BBRezoY8fMRju+c8dMzcN94KAiVvexel671d+7ep6uwX3goCJW9rFy1p2s\/O6Vs3Qd7gMHFbGqj1Vz7mrV96+aozVwHzioiBV9rJjxBCveYcUMrYP7wEFFXO3j6vmnufoeV89rLdwHDiriSh9Xzj7ZlXe5clbr4T5wUBGzfcyee4vZ95k9pz1wHzioiJk+Zs680cw7zZzRPrgPHFTEaB+j+bcbfa\/RvPbCfeCgIkb6GMnqw8i7jWS1H+4DBxVB+6A5fY2+H80pA\/eBg4qwjy720QX3gYOKsI8u9tEF94GDirCPLvbRBfeBg4qwjy720QX3gYOKsI8u9tEF94GDirCPLvbRBfeBg4qwjy720QX3gYOKsI8u9tEF94GDirCPLvbRBffxK+jPnz9\/d\/khOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfOKgI++hiH11wHzioCPvoYh9dcB84qAj76GIfXXAfv4L+\/Pnzd5efJEmSJEmSpIX+H8jrcygzyPgqAAAAAElFTkSuQmCC" ] }, "metadata":{ "image\/png":{ } }, "output_type":"display_data" }, { "data":{ "text\/plain":[ "class java.awt.image.BufferedImage: 310x310 px" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"kwGhJrChXIRY0tYqmotHfc", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"4hEPWmIcECUaChEgXJrN0S" } } } }, { "cell_type":"markdown", "source":[ "Renderer for `BufferedImage` is already registered!" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"ng2zV101bxX24o7MSgD6dZ", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Qd052RbLjMEDY3x2JGGqTv" } } } }, { "cell_type":"code", "source":[ "USE {\n", " render { it }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"sQjhort3iyyWDrLl9AtNFg", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"MBhVi2ZZKdBe0dT3idTCsR" } } } }, { "cell_type":"code", "source":[ "notebook.renderersProcessor.registeredRenderers()\n", " .map { it.renderer }\n", " .filter { (it as? RendererTypeHandler)?.acceptsType(BufferedImage::class) == true }" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "[Renderer of subtypes of class java.awt.image.BufferedImage]" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"84VYitLbQDrzppAY3kkMVM", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"X5HduZd3JUswZqdIvQWcvr" } } } }, { "cell_type":"markdown", "source":[ "You can add a renderer in the library descriptor as well, but functionality isn't\n", "so rich there. In fact, you can only write code-based renderers, and renderers are\n", "matched by **exact** FQN match. Subtypes aren't accepted." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"neNhsh456vZpwFtqBB3eCG", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9nzoHcpCP1GLrQWAukO1fW" } } } }, { "cell_type":"code", "source":[ "val dollar = \"$\"\n", "val dollarIt = \"\\$it\"\n", "\n", "class Customer2(val name: String, val age: Int)\n", "\n", "loadLibraryDescriptor(\n", " \"\"\"\n", " {\n", " \"renderers\": {\n", " \"${Customer2::class.qualifiedName}\": \"\\\"Customer $dollar{${dollarIt}.name} aged $dollar{${dollarIt}.age}\\\"\"\n", " }\n", " }\n", " \"\"\"\n", ")" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"DjeeRi7xI6DAN675VH3TV9", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ffdXcOShKpmT2VFamXtJoC" } } } }, { "cell_type":"code", "source":[ "Customer2(\"Ada\", 42)" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "Customer Ada aged 42" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"YKWpaYM2PmmUpoF9vhf61N", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kHqcBGP4zD4qWEOevgWkNs" } } } }, { "cell_type":"markdown", "source":[ "One more thing that you can render are exceptions! Let's add a renderer for `NullPointerException`" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"JvvYOG9AwfJmiLrbi9ptjh", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"gdPUAVfcoA8aRXf03ir1fe" } } } }, { "cell_type":"code", "source":[ "USE {\n", " renderThrowable {\n", " HTML(\"Kotlin is a null-safe language<\/b>\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"0bmnxaUAEOgc3cJDuZ2Lc2", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"82XbePaUlOwT2VXGYcd3i1" } } } }, { "cell_type":"code", "source":[ "System.getProperty(\"some_unexistent_property\")!!" ], "execution_count":null, "outputs":[ { "data":{ "text\/html":[ "Kotlin is a null-safe language<\/b>" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"25RWEOniQuibHNAUEFrZGX", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"4V66M4w1UlwOuLZ5IY81NX" } } } }, { "cell_type":"markdown", "source":[ "You can also render having current execution host in the context" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"DdO4dw40LFzJt0TlKDs7Ne", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"fYC5xnKtUSpYiFLT4HkPws" } } } }, { "cell_type":"code", "source":[ "USE {\n", " fun TTTCell.toHTML() = HTML(\"\")\n", "\n", " renderWithHost { executionHost, value ->\n", " executionHost.execute {\n", " display(value.toHTML(), \"12\")\n", " display(textResult(value.toString()), \"\")\n", " }\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"4UpYgouDImsXkRAmaOLt7w", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kuzi0a4lenTKR7ytAIYZmk" } } } }, { "cell_type":"markdown", "source":[ "## Code preprocessing\n", "\n", "Kotlin kernel gives you an ability to preprocess the code before execution.\n", "One of the examples of preprocessing is magics. They are preprocessed with a built-in processor.\n", "But sometimes you have to write your own one.\n", "\n", "For now, you can't run suspend functions directly in the notebook cells. Let's\n", "try to improve the situation writing a workaround for this problem. We start\n", "with creating a function" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"wuFD1A0TnFq8qZ6IPoYLIa", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"NOfKq0qMhXm4RcKXXqyYwo" } } } }, { "cell_type":"code", "source":[ "%use coroutines" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"58W81fgX6daM7aIKDnnavh", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"dDJZFeeBhojcOcn3fSLEN9" } } } }, { "cell_type":"code", "source":[ "private class Decl(val varMod: String, val name: String)\n", "\n", "fun generateRunBlocking(code: String): String {\n", " val declarationRegex = \"\"\"^(va[lr]) +(\\w+) \"\"\".toRegex(RegexOption.MULTILINE)\n", " val matches = declarationRegex.findAll(code).toList()\n", " val newCode = code.toCharArray()\n", " val declarations = matches.map { m ->\n", " val modGroup = m.groups[1]!!\n", " val modifier = modGroup.value\n", " for (i in modGroup.range) {\n", " newCode[i] = ' '\n", " }\n", " val varName = m.groups[2]!!.value\n", " Decl(modifier, varName)\n", " }\n", " return buildString {\n", " for (decl in declarations) {\n", " append(\"var ${decl.name}: Any? = null\\n\")\n", " }\n", " append(\"runBlocking {\\n\")\n", " append(String(newCode))\n", " append(\"\\n}\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"xhyJl9glfo6cA260XrKLDh", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"rmLFvTENMlhrdGdMmhlyIY" } } } }, { "cell_type":"markdown", "source":[ "Let's test it" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"SiixTH7FAskvuw87Lfd3lt", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"pkdocjfEgkHGZkNZEg0qCd" } } } }, { "cell_type":"code", "source":[ "generateRunBlocking(\"\"\"\n", " val xyz = 42\n", " var t = 12\n", "\"\"\".trimIndent())" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "var xyz: Any? = null\n", "var t: Any? = null\n", "runBlocking {\n", " xyz = 42\n", " t = 12\n", "}" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"rZWCos0jH1pOtVldRGKTLd", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"2L3O1gtgQ8JkbcyvVkKWfr" } } } }, { "cell_type":"code", "source":[ "USE {\n", " preprocessCode { code -> generateRunBlocking(code) }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"ufBXDa1Z2D1lqqzsC5jsx1", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"pOyf1UlbzzgBt6BrEgyP7E" } } } }, { "cell_type":"code", "source":[ "suspend fun susF(): Int = 42\n", "\n", "val a = susF()" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"2XzF3wRX6NlEi908xxy79f", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"96w8EcjnewffqtxVvAuwxe" } } } }, { "cell_type":"code", "source":[ "a" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "42" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"YrKPSd2rYaSdmMqCqg3wpZ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kIaSOBKE2g3ETEsImhWpdg" } } } }, { "cell_type":"code", "source":[ "val processors = notebook.codePreprocessorsProcessor.registeredExtensions().toList()\n", "println(processors)" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "[org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration$Builder$preprocessCodeWithLibraries$1@599b664e, org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"ZSwIBjnKNC9wUbR77I809V", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"llihElBjAad2oVi7hWmWAx" } } } }, { "cell_type":"code", "source":[ "notebook.codePreprocessorsProcessor.unregister((processors!! as List)[0])" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"lCcIkGEmDmPrV08sm0QPyQ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"l6bMEDM7mmkgLAYM3Cx11y" } } } }, { "cell_type":"code", "source":[ "val processors2 = notebook.codePreprocessorsProcessor.registeredExtensions().toList()\n", "println(processors2)" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "[org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"NsralVlhrNcMb9qo6aYVoD", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"uMUYx3GxM8W3gSyXYyndH7" } } } }, { "cell_type":"markdown", "source":[ "## Reflection- and compile-based postprocessing" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"Yuom2vfRznicODzeNz2iWH", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"uA1w1Ni8u1amC6sqba2deq" } } } }, { "cell_type":"markdown", "source":[ "As we discussed above, there is possibility to add after-evaluation callbacks.\n", "There is a possibility to consider script instance as well. Script instance\n", "contains all top-level variables and functions you define as members. Let's take a look" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"fI6J2geUPju5oQkqKb6UJL", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"UQMvJcHI0ln68VZJIE06He" } } } }, { "cell_type":"code", "source":[ "import kotlin.reflect.KProperty\n", "import kotlin.reflect.KProperty1\n", "import kotlin.reflect.full.memberFunctions\n", "import kotlin.reflect.full.memberProperties\n", "\n", "USE {\n", " afterCellExecution { snippetInstance, _ ->\n", " val kClass = snippetInstance::class\n", " println(\n", " \"\"\"\n", "Variables:\n", "${\n", " kClass.memberProperties.joinToString(\"\\n\") { prop ->\n", " \"${prop.name} = ${\n", " (prop as KProperty1).get(\n", " snippetInstance\n", " )\n", " }\"\n", " }\n", "}\n", "\n", "Functions:\n", "${kClass.memberFunctions.joinToString(\"\\n\") { f -> f.name }}\n", " \"\"\"\n", " )\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"cuf7gLKdl8bK8RhWcRP5JX", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"JIR4tHKUJupbyHezxDu6rB" } } } }, { "cell_type":"code", "source":[ "val myVar1 = 42\n", "val myVar2 = \"str\"\n", "\n", "fun myFun1() { println(\"fun called\") }" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "\n", "Variables:\n", "myVar1 = 42\n", "myVar2 = str\n", "userHandlesProvider = org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl@4d7b2340\n", "\n", "Functions:\n", "myFun1\n", "equals\n", "hashCode\n", "toString\n", " \r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"fwCdP3B5jvwkKrMOew4DbM", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"NvyjPbw6vlV9DWit5NXRvi" } } } }, { "cell_type":"code", "source":[ "notebook.afterCellExecutionsProcessor.unregisterAll()" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"Rdv5QgxSWWOGEYOw56HZ3H", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"DMUBf9e38abIudGGGHZrk4" } } } }, { "cell_type":"markdown", "source":[ "Let's now try to do something compile-time based. We start with file annotations processing" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"Iw3cA7GOJzTSMejCwXURkk", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Ue3t61m1qFdbl9fwdraTDd" } } } }, { "cell_type":"code", "source":[ "USE {\n", " onFileAnnotation {\n", " val myAnno = it.first() as Suppress\n", " println(\"Warnings suppressed: \" + myAnno.names.toList())\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"5OjDKIR999WfJF08kVA86Y", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ftKvOUhM7UYCFRG8iznQP0" } } } }, { "cell_type":"code", "source":[ "@file:Suppress(\"UNUSED_PARAMETER\")\n", "\n", "fun u(unusedArg: Int) = 44" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Warnings suppressed: [UNUSED_PARAMETER]\r\n" ], "output_type":"stream" } ], "metadata":{ "datalore":{ "node_id":"Nh3EpmYl0tBAxGwwqwXQNB", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"unVxCJ8mv1nzlS9snliOpW" } } } }, { "cell_type":"markdown", "source":[ "We can also handle annotations for classes. They are runtime-based." ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"sANMnKtdLBqWHE0UY4khwY", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"7oBfufAnaB25PwW9IheO4A" } } } }, { "cell_type":"code", "source":[ "annotation class MyAnnotation" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"fPWAxrOHL7h1vqTLkbapvJ", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"ZgdMbkYUbDk204pfAfvdSz" } } } }, { "cell_type":"code", "source":[ "USE {\n", " onClassAnnotation { println(\"Annotated classes: $it\") }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"zKc6ZM3mWDVbaZDBzRv58R", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"NylSfpzWwx01t38GW0vXGS" } } } }, { "cell_type":"code", "source":[ "@MyAnnotation\n", "class MyClass\n", "\n", "class MyClass2\n", "\n", "@MyAnnotation\n", "interface MyInterface3\n", "\n", "3 + 3" ], "execution_count":null, "outputs":[ { "name":"stdout", "text":[ "Annotated classes: [class Line_83_jupyter$MyClass, class Line_83_jupyter$MyInterface3]\r\n", "\n" ], "output_type":"stream" }, { "name":"stderr", "text":[ "\n" ], "output_type":"stream" }, { "data":{ "text\/plain":[ "6" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"iIk33g296Bt6B27UvrTDyz", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Eq0K2et7uGLQlKSnAWm8Uq" } } } }, { "cell_type":"code", "source":[ "class MyData\n", "\n", "USE {\n", " onVariable { t, kProperty ->\n", " execute(\"val gen_${kProperty.name} = 1\")\n", " }\n", "\/\/ updateVariable { t, kProperty ->\n", "\/\/ execute(\"\")\n", "\/\/\n", "\/\/ }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"5VdHBYcZNscUy0ou5yUMKt", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"eaAFdDYc1oCRRGDgPy8AGJ" } } } }, { "cell_type":"code", "source":[ "val d = MyData()" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"MgfPiwZIKmWInsmZlCnsHI", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"soaq6Yi9OYf8mQbpJRCb7j" } } } }, { "cell_type":"code", "source":[ "gen_d" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "1" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"QK41I4Epmue1zjnyHgICo8", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"kBanpx6Ot83NVP52jes2xZ" } } } }, { "cell_type":"markdown", "source":[ "## Variables reports" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"8CNMoO5jhodouuWOJYRJBP", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"mptCNNSClB79mlxA6WYEe4" } } } }, { "cell_type":"code", "source":[ "notebook.variablesReport" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "Visible vars: \n", "\tdollar : $\n", "\treadToken : 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\n", "\tmyVar1 : 42\n", "\tconfig1 : Line_16_jupyter$Config@45d5ee1e\n", "\tmyVar3 : Line_16_jupyter$Config@45d5ee1e\n", "\tinterruptionCount : 1\n", "\tisDark : false\n", "\tgameState : x_o|_x_|___\n", "\tstateMatrix : [[X, Empty, O], [Empty, X, Empty], [Empty, Empty, Empty]]\n", "\tstate : Line_47_jupyter$TTTState@1f8e46f4\n", "\thtmlStateRenderer : Renderer of subtypes of class Line_47_jupyter$TTTState\n", "\timageStateRenderer : Renderer of subtypes of class Line_47_jupyter$TTTState\n", "\tdollarIt : $it\n", "\t___a : 42\n", "\ta : 42\n", "\t___processors : [org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration$Builder$preprocessCodeWithLibraries$1@599b664e, org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tprocessors : [org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration$Builder$preprocessCodeWithLibraries$1@599b664e, org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tprocessors2 : [org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tmyVar2 : str\n", "\td : Line_84_jupyter$MyData@9b17514\n", "\tgen_d : 1\n" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"5ahvq3kILgZ4xr0Jt8UZUV", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"g97VskGuaBU5jyi2xxOJUb" } } } }, { "cell_type":"code", "source":[ "USE {\n", " markVariableInternal { prop ->\n", " prop.name.startsWith(\"___\")\n", " }\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"fLOUvAhGCF8NRHi1PWmTBe", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"Fes2WbRkwHV6Du6NNpNfN8" } } } }, { "cell_type":"code", "source":[ "val ___b = 8\n", "val b = 9" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"KoOWWoR61ZGylladTKqlt5", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9FJyAOc7qD5ZKKsxhS2plB" } } } }, { "cell_type":"code", "source":[ "notebook.variablesReport" ], "execution_count":null, "outputs":[ { "data":{ "text\/plain":[ "Visible vars: \n", "\tdollar : $\n", "\treadToken : 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\n", "\tmyVar1 : 42\n", "\tconfig1 : Line_16_jupyter$Config@45d5ee1e\n", "\tmyVar3 : Line_16_jupyter$Config@45d5ee1e\n", "\tinterruptionCount : 1\n", "\tisDark : false\n", "\tgameState : x_o|_x_|___\n", "\tstateMatrix : [[X, Empty, O], [Empty, X, Empty], [Empty, Empty, Empty]]\n", "\tstate : Line_47_jupyter$TTTState@1f8e46f4\n", "\thtmlStateRenderer : Renderer of subtypes of class Line_47_jupyter$TTTState\n", "\timageStateRenderer : Renderer of subtypes of class Line_47_jupyter$TTTState\n", "\tdollarIt : $it\n", "\t___a : 42\n", "\ta : 42\n", "\t___processors : [org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration$Builder$preprocessCodeWithLibraries$1@599b664e, org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tprocessors : [org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration$Builder$preprocessCodeWithLibraries$1@599b664e, org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tprocessors2 : [org.jetbrains.kotlinx.jupyter.magics.MagicsProcessor@6b1106a5]\n", "\tmyVar2 : str\n", "\td : Line_84_jupyter$MyData@9b17514\n", "\tgen_d : 1\n", "\tb : 9\n" ] }, "metadata":{ }, "output_type":"display_data" } ], "metadata":{ "datalore":{ "node_id":"Se41f1KLqwakQF9AeTOsr7", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"dEtLSwVj8RQQMjcZQlsPhB" } } } }, { "cell_type":"markdown", "source":[ "## Auxiliary" ], "attachments":{ }, "metadata":{ "datalore":{ "node_id":"noC2jHXlVoQ3PMfuElXPoG", "type":"MD", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"9a8AAkac3yjxfQQJywjA8z" } } } }, { "cell_type":"code", "source":[ "\/\/ You can set minimal supported version of kernel\n", "USE {\n", " setMinimalKernelVersion(\"0.11.0.365\")\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"gyyNLLGMnX9FzdAXqkW1uA", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"bK2uTOWSiI8RG4NCcZz9LY" } } } }, { "cell_type":"code", "source":[ "USE {\n", " setDescription(\"Very good library\")\n", " setWebsite(\"https:\/\/cool.site\")\n", "}" ], "execution_count":null, "outputs":[ ], "metadata":{ "datalore":{ "node_id":"TN8rb2Cg0tKiEYhimMLvhV", "type":"CODE", "hide_input_from_viewers":false, "hide_output_from_viewers":false, "report_properties":{ "rowId":"PiIX4Cd5LWPealJqQT75s7" } } } } ], "metadata":{ "kernelspec":{ "display_name":"Kotlin", "language":"kotlin", "name":"kotlin" }, "datalore":{ "computation_mode":"JUPYTER", "package_manager":"pip", "base_environment":"default", "packages":[ { "name":"kotlin-jupyter-kernel", "version":"0.11.0.365", "source":"PIP" } ], "report_row_ids":[ "0ON8yI917hwj8FeK0pQsky", "vS92wiTvpFntHSEMCrr5H9", "3XSS7u0TNIQpjxsTLZoRig", "9aQzeJN8aSKkrM8z1a8Acs", "XiD8FUF2KgFyi8XBVKQpnU", "guaD3yArd3wnoMlMhxLe4X", "iUfleWm1l7UrnMboME6qdN", "SZQ4DmXm4LKPZXSWKa2FUa", "SqdpEchM5GWiblQZFplRpl", "YrLfbBZxK3gmzAjhOcToTI", "aY56fUvdq8nKDNJRhibmjc", "cM7Eec2U1CVBlHSH17Rg1D", "c3ukpEDkef9NnK5W6m80fX", "bJriUMfF1ALMgCZRqL2vPR", "eg2gxPucspll8gUsgPMeml", "WOxFiL3cGnwp0EfdM7ZMHv", "PwhJpKfF01V5FgWZ0vKmJH", "ajiBPydxHG4Xeq9tlTUVNm", "trd9FQC5p4kj2twt1NSdZi", "ytCzH78nG3CehElCoOlCp2", "kIehA33S1UmxSoILQBOezz", "loTaywakOhZgSG9nNxroBD", "aRiAfUct8tkDWLUoCXSPUa", "29gNY5AfVcwwJIu9XdIeZC", "qPr8FSa9A021OrxQcpqgvf", "5H8VGC7gJEfYKSDQ1wDrFw", "LEj97CaHd6FEIUoWTDWrUd", "kUqpFEoT4wdrCyvaRjlL9U", "83T4EixM904negk4PspoX9", "jiBee7WXAMh0dRE0mXCwYJ", "vWW1rKGiTC5wCiRppqSPtl", "NZYYw8krWxxsn6ViFn8HQZ", "dr2BNXz8zjk4Heei7SHzTo", "HLOTmBX4YcaBXoCInGaWBA", "sZDxeSOclpqLQU6I3U4ZFU", "XJdz2W54VQ71MD37E7zK44", "sWNQSLVUcaeEBmAPpke16g", "9uUmhY5IEWb0F9Z4LLL9ns", "9aUzTpm3Fs3zjX6Fl5svDH", "XKeLbzujSGyt7sGXweJGW6", "TjL2Gby4DlurAmXZNsOMiY", "FSrS8i1Hfq5tw0NeYR13tC", "wCZCvAr5I4GqhHJUWcEKSL", "8RvJheV7qmMV3TgAjrClo9", "cZG2Gg1q6ricyrJ2obqEVN", "MgHGwgpl2ke1SqG0BvCeuI", "CKP7bVtnKhgS7hYqLrbKIs", "FYVprXZJX8ybIkUdRYlbMC", "3CkWbCch8Jhw0YWvzybrWe", "yO7NShs20PgUXH62mQECW9", "ueDFLSiaxErv3sQNrMRxQK", "Zfx5UVcbiQybfkOTQunf2u", "mEXNvt604KWPfHBDZf3wLy", "uP4CXk9t9NAos3ns4xyVrl", "XsGdpQCPHSyqtXVbcGgYN4", "pHiR3R2hbskzidNu8lLsT0", "y1qxBTRSDNmRIZDSEXtwTP", "HAMo4XcsvceFepwnsltw4q", "qDjMyIfpi7x9tS6RQm0eqH", "Nd5ZojCHu4qwbynpIuulr9", "4hEPWmIcECUaChEgXJrN0S", "Qd052RbLjMEDY3x2JGGqTv", "MBhVi2ZZKdBe0dT3idTCsR", "X5HduZd3JUswZqdIvQWcvr", "9nzoHcpCP1GLrQWAukO1fW", "ffdXcOShKpmT2VFamXtJoC", "kHqcBGP4zD4qWEOevgWkNs", "gdPUAVfcoA8aRXf03ir1fe", "82XbePaUlOwT2VXGYcd3i1", "4V66M4w1UlwOuLZ5IY81NX", "fYC5xnKtUSpYiFLT4HkPws", "kuzi0a4lenTKR7ytAIYZmk", "NOfKq0qMhXm4RcKXXqyYwo", "dDJZFeeBhojcOcn3fSLEN9", "rmLFvTENMlhrdGdMmhlyIY", "pkdocjfEgkHGZkNZEg0qCd", "2L3O1gtgQ8JkbcyvVkKWfr", "pOyf1UlbzzgBt6BrEgyP7E", "96w8EcjnewffqtxVvAuwxe", "kIaSOBKE2g3ETEsImhWpdg", "llihElBjAad2oVi7hWmWAx", "l6bMEDM7mmkgLAYM3Cx11y", "uMUYx3GxM8W3gSyXYyndH7", "uA1w1Ni8u1amC6sqba2deq", "UQMvJcHI0ln68VZJIE06He", "JIR4tHKUJupbyHezxDu6rB", "NvyjPbw6vlV9DWit5NXRvi", "DMUBf9e38abIudGGGHZrk4", "Ue3t61m1qFdbl9fwdraTDd", "ftKvOUhM7UYCFRG8iznQP0", "unVxCJ8mv1nzlS9snliOpW", "7oBfufAnaB25PwW9IheO4A", "ZgdMbkYUbDk204pfAfvdSz", "NylSfpzWwx01t38GW0vXGS", "Eq0K2et7uGLQlKSnAWm8Uq", "eaAFdDYc1oCRRGDgPy8AGJ", "soaq6Yi9OYf8mQbpJRCb7j", "kBanpx6Ot83NVP52jes2xZ", "mptCNNSClB79mlxA6WYEe4", "g97VskGuaBU5jyi2xxOJUb", "Fes2WbRkwHV6Du6NNpNfN8", "9FJyAOc7qD5ZKKsxhS2plB", "dEtLSwVj8RQQMjcZQlsPhB", "9a8AAkac3yjxfQQJywjA8z", "bK2uTOWSiI8RG4NCcZz9LY", "PiIX4Cd5LWPealJqQT75s7" ], "version":3 } }, "nbformat":4, "nbformat_minor":4 }