Streamline introductory notebooks (#733)

This commit is contained in:
José Valim 2021-12-03 15:17:09 +01:00 committed by GitHub
parent 04f15f60a3
commit 2c91de3cd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 87 deletions

View file

@ -195,19 +195,24 @@ Date.from_iso8601("2020-02-30")
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
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
# Bring in Livebook inputs
Mix.install([
{: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
date_input = Kino.Input.text("Date")
```
Now we can read its value and parse it:
```elixir
# Read the date input, which returns something like "2020-02-30"
input = Kino.Input.read(date_input)
@ -222,15 +227,12 @@ case Date.from_iso8601(input) do
end
```
We have been using `IO.inspect` to write values out of the notebook
and here we used `IO.gets` to read data in. The string passed to
`IO.gets` must have the same suffix as the input name. The returned
string is always appended with a newline. Then we remove the trailing new
line and use `case` to pattern match on the different outcomes of the
`Date.from_iso8601` function. We say the `case` above has two clauses,
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.
Now try adding a date to the input above, such as `2020-02-30` and
reevaluate the cell accordingly. In this example, we are using `case`
to pattern match on the different outcomes of the `Date.from_iso8601`
function. We say the `case` above has two clauses, 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
values for the given keys:

View file

@ -37,28 +37,6 @@ return the Elixir version.
Note you can also press <kbd>tab</kbd> to cycle across the completion
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
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)
```
## 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
Livebook automatically shows the execution time of each Elixir

View file

@ -5,8 +5,8 @@
In this notebook we will explore the possibilities that
[`kino`](https://github.com/elixir-nx/kino) brings
into your notebooks. Kino can be thought of as Livebook's
friend that instructs it how to render certain output
and interact with it.
friend that instructs it how to render certain widgets
and interact with them.
```elixir
Mix.install([

View file

@ -5,8 +5,8 @@
To render graphs in Livebook, we need the
[`vega_lite`](https://github.com/elixir-nx/vega_lite) package
for defining our graph specification and
[`kino`](https://github.com/elixir-nx/kino), which augments
Livebook with client-driven interactive widgets:
[`kino`](https://github.com/elixir-nx/kino). We won't use Kino
directly, but it is required to render VegaLite:
```elixir
Mix.install([

View file

@ -48,18 +48,16 @@ IO.puts node()
IO.puts Node.get_cookie()
```
Now, paste these in the inputs below:
Now render the inputs below:
```elixir
node_input = Kino.Input.text("Node")
```
```elixir
cookie_input = Kino.Input.text("Cookie")
```
And now execute the code cell below, which will read the inputs,
configure the cookie, and connect to the other notebook:
And paste the node name and the cookie value from the other node inside.
Now let's read the inputs, configure the cookie, and connect to the other notebook:
```elixir
node =