mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-12-18 14:09:38 +08:00
Streamline introductory notebooks (#733)
This commit is contained in:
parent
04f15f60a3
commit
2c91de3cd6
5 changed files with 21 additions and 87 deletions
|
|
@ -195,19 +195,24 @@ Date.from_iso8601("2020-02-30")
|
||||||
Now, what happens if we want our code to behave differently depending
|
Now, what happens if we want our code to behave differently depending
|
||||||
if the date is valid or not? We can use `case` to pattern match on
|
if the date is valid or not? We can use `case` to pattern match on
|
||||||
the different tuples. This is also a good opportunity to use Livebook's
|
the different tuples. This is also a good opportunity to use Livebook's
|
||||||
inputs to pass different values to our code:
|
inputs to pass different values to our code. To render inputs, we need to
|
||||||
|
install the [Kino](https://github.com/livebook-dev/kino) library:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# Bring in Livebook inputs
|
|
||||||
Mix.install([
|
Mix.install([
|
||||||
{:kino, "~> 0.3.1", github: "livebook-dev/kino"}
|
{:kino, "~> 0.3.1", github: "livebook-dev/kino"}
|
||||||
])
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Kino allows our code notebooks to control Livebook itself. Let's render
|
||||||
|
an input by evaluating the cell below:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
date_input = Kino.Input.text("Date")
|
date_input = Kino.Input.text("Date")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Now we can read its value and parse it:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
# Read the date input, which returns something like "2020-02-30"
|
# Read the date input, which returns something like "2020-02-30"
|
||||||
input = Kino.Input.read(date_input)
|
input = Kino.Input.read(date_input)
|
||||||
|
|
@ -222,15 +227,12 @@ case Date.from_iso8601(input) do
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
We have been using `IO.inspect` to write values out of the notebook
|
Now try adding a date to the input above, such as `2020-02-30` and
|
||||||
and here we used `IO.gets` to read data in. The string passed to
|
reevaluate the cell accordingly. In this example, we are using `case`
|
||||||
`IO.gets` must have the same suffix as the input name. The returned
|
to pattern match on the different outcomes of the `Date.from_iso8601`
|
||||||
string is always appended with a newline. Then we remove the trailing new
|
function. We say the `case` above has two clauses, one matching on
|
||||||
line and use `case` to pattern match on the different outcomes of the
|
`{:ok, date}` and another on `{:error, reason}`. Try changing the input
|
||||||
`Date.from_iso8601` function. We say the `case` above has two clauses,
|
and re-executing the cell to see how the outcome changes.
|
||||||
one matching on `{:ok, date}` and another on `{:error, reason}`.
|
|
||||||
Try changing the input and re-executing the cell to see how the outcome
|
|
||||||
changes.
|
|
||||||
|
|
||||||
Finally, we can also pattern match on maps. This is used to extract the
|
Finally, we can also pattern match on maps. This is used to extract the
|
||||||
values for the given keys:
|
values for the given keys:
|
||||||
|
|
|
||||||
|
|
@ -37,28 +37,6 @@ return the Elixir version.
|
||||||
Note you can also press <kbd>tab</kbd> to cycle across the completion
|
Note you can also press <kbd>tab</kbd> to cycle across the completion
|
||||||
alternatives.
|
alternatives.
|
||||||
|
|
||||||
## Imports
|
|
||||||
|
|
||||||
You can import Elixir modules to make the imported functions visible
|
|
||||||
to all subsequent cells. Usually you want to keep `import`, `alias`, and
|
|
||||||
`require` in the first section, as part of the notebook setup.
|
|
||||||
|
|
||||||
For instance, you can import `IEx.Helpers` and bring all of the amazing
|
|
||||||
conveniences in Elixir's shell to your notebook:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
import IEx.Helpers
|
|
||||||
```
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
h(Enum.map())
|
|
||||||
```
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
# Sidenote: http://www.numbat.org.au/thenumbat
|
|
||||||
i("I ❤️ Numbats")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using packages
|
## Using packages
|
||||||
|
|
||||||
Sometimes you need a dependency or two and notebooks are no exception to this.
|
Sometimes you need a dependency or two and notebooks are no exception to this.
|
||||||
|
|
@ -162,50 +140,6 @@ Since this branch is a separate process, a crash has limited scope:
|
||||||
Process.exit(self(), :kill)
|
Process.exit(self(), :kill)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Inputs
|
|
||||||
|
|
||||||
Livebook supports inputs and you read the input values directly
|
|
||||||
from your notebook code, using `IO.gets/1`. Let's see an example
|
|
||||||
that expects a date in the format `YYYY-MM-DD` and returns if the
|
|
||||||
data is valid or not:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
date_input = Kino.Input.text("Date")
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- livebook:{"reevaluate_automatically":true} -->
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
# Read the date input, which returns something like "2020-02-30"
|
|
||||||
input = Kino.Input.read(date_input)
|
|
||||||
|
|
||||||
# And then match on the return value
|
|
||||||
case Date.from_iso8601(input) do
|
|
||||||
{:ok, date} ->
|
|
||||||
"We got a valid date: #{inspect(date)}"
|
|
||||||
|
|
||||||
{:error, reason} ->
|
|
||||||
"Oh no, the date is invalid. Reason: #{inspect(reason)}"
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
The string passed to `IO.gets/1` must be prefixed with the name you
|
|
||||||
assigned to the input. The returned string is always appended with
|
|
||||||
a newline. This is built-in on top of Erlang's IO protocol and built
|
|
||||||
in a way that your notebooks can be exported to Elixir scripts and
|
|
||||||
still work!
|
|
||||||
|
|
||||||
You may also have noticed something special about the code cell above.
|
|
||||||
After you evaluate it for the first time, it says "Reevaluates automatically"
|
|
||||||
instead of showing the "Reevaluate" button. This means the cell will
|
|
||||||
automatically reevaluate whenever the input changes or whenever a
|
|
||||||
previous cell is reevaluated. Give it a try! You can enable this
|
|
||||||
behaviour by clicking the Cell Settings icon (<i class="ri-settings-3-line"></i>)
|
|
||||||
after focusing a code cell.
|
|
||||||
|
|
||||||
There are many other input types available, give them a try to learn
|
|
||||||
more.
|
|
||||||
|
|
||||||
## Evaluation vs compilation
|
## Evaluation vs compilation
|
||||||
|
|
||||||
Livebook automatically shows the execution time of each Elixir
|
Livebook automatically shows the execution time of each Elixir
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
In this notebook we will explore the possibilities that
|
In this notebook we will explore the possibilities that
|
||||||
[`kino`](https://github.com/elixir-nx/kino) brings
|
[`kino`](https://github.com/elixir-nx/kino) brings
|
||||||
into your notebooks. Kino can be thought of as Livebook's
|
into your notebooks. Kino can be thought of as Livebook's
|
||||||
friend that instructs it how to render certain output
|
friend that instructs it how to render certain widgets
|
||||||
and interact with it.
|
and interact with them.
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Mix.install([
|
Mix.install([
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
To render graphs in Livebook, we need the
|
To render graphs in Livebook, we need the
|
||||||
[`vega_lite`](https://github.com/elixir-nx/vega_lite) package
|
[`vega_lite`](https://github.com/elixir-nx/vega_lite) package
|
||||||
for defining our graph specification and
|
for defining our graph specification and
|
||||||
[`kino`](https://github.com/elixir-nx/kino), which augments
|
[`kino`](https://github.com/elixir-nx/kino). We won't use Kino
|
||||||
Livebook with client-driven interactive widgets:
|
directly, but it is required to render VegaLite:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
Mix.install([
|
Mix.install([
|
||||||
|
|
|
||||||
|
|
@ -48,18 +48,16 @@ IO.puts node()
|
||||||
IO.puts Node.get_cookie()
|
IO.puts Node.get_cookie()
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, paste these in the inputs below:
|
Now render the inputs below:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
node_input = Kino.Input.text("Node")
|
node_input = Kino.Input.text("Node")
|
||||||
```
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
cookie_input = Kino.Input.text("Cookie")
|
cookie_input = Kino.Input.text("Cookie")
|
||||||
```
|
```
|
||||||
|
|
||||||
And now execute the code cell below, which will read the inputs,
|
And paste the node name and the cookie value from the other node inside.
|
||||||
configure the cookie, and connect to the other notebook:
|
|
||||||
|
Now let's read the inputs, configure the cookie, and connect to the other notebook:
|
||||||
|
|
||||||
```elixir
|
```elixir
|
||||||
node =
|
node =
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue