Jupyter Notebooks 是一個出色的工具,最初是為了幫助資料科學家和工程師使用 Python 程式語言簡化資料處理工作而開發的。事實上,筆記本的互動性使其非常適合快速查看程式碼結果,而無需建立開發環境、編譯、打包等。此功能對於資料科學、機器學習和統計建模的採用至關重要,在這些領域,開發技能不如資料操作專業知識那麼重要。
以下是 Jupyter Notebook 的一些優點
總結一下我們可以說
Jupyter 筆記本簡化了從初始探索到生產就緒程式碼的開發過程,提供了靈活性和即時回饋。
考慮到Jupyter Notebook 的優勢,對於軟體開發人員來說,使用這種Notebook 方法進行開發會非常有用,例如,專案用例測試或提供有用的互動式操作指南。
這裡的問題是:
是否可以使用 JUPYTER Notebook 進行 Python 以外的程式語言❓?
答案是是? .
Jupyter 工具的架構旨在透過 核心 概念支援多種程式語言,請參考下圖:
核心是 Jupyter 筆記本伺服器評估使用者在筆記本文件 (.ipynb) 內編寫的程式碼區塊的方式,因此擁有一個可以評估您選擇的程式語言的程式碼的核心就足夠了Jupyter筆記本支援它。
當然,很容易推斷出 Jupyter 內核可以支援的每種潛在程式語言都應該支援讀取-評估-列印循環 (REPL) 功能。
問題變成:
除了 Python ONE 之外還有 JUPYTER 核心嗎❓?
答案是是? 。
最近我一直在研究 Langgraph4J,它是更著名的 Langgraph.js 的 Java 實現,Langgraph.js 是 Langchain 用於創建代理和多代理工作流程的 Javascript 庫。有趣的是,[Langchain.js] 使用由 DENO Jupiter 核心支援的 Javascript Jupyter 筆記本來實作和記錄 How-Tos。
因此,我面臨著如何在Java 中使用(或可能模擬)相同方法的困境,並且沒有太多希望,我開始尋找支援Java 的Jupyter 內核,因為從JDK 9 版本開始,引入了為Java 啟用REPL 的JShell 。
經過一些研究(以及嘗試將自己投入 DIY 實現的奇怪想法),我找到了 rapaio-jupyter-kernel,它是一個支援 Java 的 Jupyter 核心。此項目指出:
基於 JShell 的 Java 語言 Jupyter 核心。它實作了 Jupyter 訊息規範版本 5.4,並且需要 Java = 22。
太棒了;我開始使用它,哇! ? 。看看它的一些特點,下面我總結了最具代表性的幾個:
你可以寫普通的Java。
var result = 2 + 2; result登入後複製4
// including classes record Complex(double a, double b) { public Complex add(Complex c) { return new Complex(a+c.a, b+c.b); } } Complex x = new Complex(10,20); x.add(new Complex(1,1))登入後複製複雜[a=11.0, b=21.0]
// methods can also be implemented int add(int a, int b) { return a+b; } add(2,3)登入後複製5
Magic commands
Besides Java code, a cell can contain special commands implemented by the kernel. These are called magic code and there are two types: magic lines and magic cells.
Magic lines are lines which are prefixed with %. After the prefix it is followed by the magic command and the optional parameters. Below is an example of magic line:// magic line which asks JShell to list the types defined in this notebook in this moment %jshell /types登入後複製| record Complex
Magic commands interpolation
Sometimes there is a need to run a magic command in a more dynamic way. This can be done using magic interpolation.
Magic interpolation is the interpolation of marked content which starts with \{ and ends with }. Any content decorated with those markers is evaluated in jshell and the result is transformed in a String which replaces the decorated content in the magic command.String version = "1.0.2";登入後複製
%dependency /add com.github.javafaker:javafaker:\{version}登入後複製Adding dependency com.github.javafaker:javafaker:1.0.2
Dependency management ?
You can add dependencies using %dependency /add and after adding all dependencies you can call %dependency /resolve
%dependency /add com.github.javafaker:javafaker:1.0.2 %dependency /resolve登入後複製Adding dependency com.github.javafaker:javafaker:1.0.2
Solving dependencies
Resolved artifacts count: 5
Add to classpath: /home/ati/work/rapaio-jupyter-kernel/target/mima_cache/com/github/javafaker/javafaker/1.0.2/javafaker-1.0.2.jar
Add to classpath: /home/ati/work/rapaio-jupyter-kernel/target/mima_cache/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar
Add to classpath: /home/ati/work/rapaio-jupyter-kernel/target/mima_cache/org/yaml/snakeyaml/1.23/snakeyaml-1.23-android.jar
Add to classpath: /home/ati/work/rapaio-jupyter-kernel/target/mima_cache/com/github/mifmif/generex/1.0.2/generex-1.0.2.jar
Add to classpath: /home/ati/work/rapaio-jupyter-kernel/target/mima_cache/dk/brics/automaton/automaton/1.11-8/automaton-1.11-8.jarWhen added you can import and use the dependency.
import com.github.javafaker.Faker; var faker = new Faker(); faker.name().fullName()登入後複製Hayley Anderson
Resolving conflict dependencies
You there are conflicts you can manage them with optional. Let's take an example which have conflicts:
%dependency /add com.google.guava:guava:20.0 --optional %dependency /add com.google.inject:guice:4.2.2 %dependency /add com.google.guava:guava:25.1-android %dependency /resolve登入後複製Help on magic commands
The magic %help provides more examples and guidance.
JShell commands
Some JShell commands are implemented. For example you can inspect which variables are defined
%jshell /vars登入後複製or the types you defined in this session
%jshell /types登入後複製Execute bash commands
You can execute bash scripting commands. Here we display the java version number.
%%bash java --version登入後複製openjdk 22.0.2 2024-07-16
OpenJDK Runtime Environment Corretto-22.0.2.9.1 (build 22.0.2+9-FR)
OpenJDK 64-Bit Server VM Corretto-22.0.2.9.1 (build 22.0.2+9-FR, mixed mode, sharing)You can even define variables. In fact all the lines below cell magic marker are executed as a bash script.
%%bash name="John" echo "Hello $name"登入後複製Hello John
Show an image for immediate inspection
%image https://www.google.com/logos/doodles/2024/paris-games-sailing-6753651837110529.4-law.gif登入後複製Display data
Jupyter notebooks uses outputs to display objects of various types. By default when an object is returned as the result of the last code operation, that result is displayed.
The object which is displayed can be anything. If the object has a display handler registered, than that renderer is used to transform the object into a displayable content. If there is no registered display handler than the object is transformed into a string and that will be displayed.
Previously we used magic commands to display an image. However for BufferedImages there is a registered handler and if you obtain an instance of a BufferedImage it will be displayed properly.import javax.imageio.*; display(ImageIO.read(new URL("https://www.google.com/logos/doodles/2024/paris-games-sailing-6753651837110529.4-law.gif")));登入後複製Displayed data has a mime type. You can use that to describe how the object should be interpreted. For example we display a markdown snippet and we direct the output interpretation of the snippet through MIME type.
display("text/markdown", "Markdown *test* **snippet**:\n* bullet 1\n* bullet 2")登入後複製Markdown test snippet:
- bullet 1
- bullet 2
display command returns an id which identifies the piece of output from the notebook which handles the display. Notice that we captured the id of the display. This id can be used to update the same display with a different content. For example we can update the content of that display with a html snippet, using the MIME type for interpretation.
String id = display("text/markdown", "Markdown *test* **snippet**:\n* bullet 1\n* bullet 2");登入後複製
updateDisplay(id, "text/html", "Html <i>test</i> <b>snippet</b>:<p><ulist><li>bullet 1</li><li>bullet 2</li></ulist></p>")登入後複製A Java object is displayed as a String using Objects.toString. As such, if the object has an implementation of toString, that method will be called.
new Complex(10,Math.PI);登入後複製Complex[a=10.0, b=3.141592653589793]
The versatility of Jupyter notebooks extends beyond Python, the integration of kernels like rapaio-jupyter-kernel break new ground for Java developers. My preferred feature is the possibility to write HOW-TOs interactively documenting them contextually, but there are a bunch of potential use cases and it’s up to you to explore them, so let’s explore and let me know.
I hope that this knowledge will be helpful, in the meanwhile, enjoy coding! ?
? My sperimentations of Java notebooks are on Github ?
Originally published at https://bsorrentino.github.io on September 6, 2024.
以上是適用於 Java 的 Jupyter 筆記本的詳細內容。更多資訊請關注PHP中文網其他相關文章!