Livebook+Kinoでアプリを作ってみる(AtCoderの正解チェックアプリの作成)

# はじめに

LivebookでAtCoderの正解チェックを行ってみました。

https://qiita.com/GeekMasahiro/items/5fce18be4a4902b9936f

Kinoを使うと、テキストボックスやボタンがあり、これらの部品を配置して、操作できる画面を作ることができます。

AtCoderの正解チェックをKinoを使ってアプリっぽくしてみます。

# 使い方

作成した画面は、次のようなものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/c0021d0c-a0e5-5985-2a5e-e1970003db3b.png)

コンテスト名と問題名を入力して、入力例で実行のボタンを押すと、問題のページにある入力例を入力としてプログラムを実行し、出力例と一致しているかを表示します。

入力欄に入力に与えたい文字列を入力し、実行ボタンを押すと、入力欄の値を入力としてプログラムを実行し、結果を表示します。

# 画面の作り方

まず使用する部品を作り、変数に入れておきます。
```elixir
contest_name = Kino.Input.text("コンテスト名")
problem_name = Kino.Input.text("問題名")
judge_all = Kino.Control.button("入力例で実行")
```

ボタンについては、ボタンが押された時に実行する関数を作成します。

入力例で実行のボタンが押された時には、AtCoder.judge_all()を実行するようにしています。
AtCoder.new()は、入力例、出力例を取得し、AtCoder.judge_all()は、入力例を入力として、回答プログラムを実行し、回答が正しいか出力する関数になっています。

```elixir:入力例で実行のボタン
Kino.listen(judge_all, fn _event ->
  atcoder = AtCoder.new(Kino.Input.read(contest_name), Kino.Input.read(problem_name))
  AtCoder.judge_all(atcoder) end)
```

次に、部品を配置するframeを作成します。
```elixir
frame = Kino.Frame.new()
```

作成したframeに部品を配置します。
frameを引数にして、Kino.Frame.renderを呼び出すことで部品を配置できます。
次のように、作成した部品を引数に渡せば、部品が配置されます。
```elixir
  Kino.Frame.render(frame,contest_name)
```

しかし、これだと一つの部品しか配置できません。
複数の部品を配置するには、Kino.Layout.grid()を使います。
次の記述で、contest_name, problem_name,judge_allを配置できます。
`Kino.Layout.grid([contest_name, problem_name,judge_all], columns: 1)`
colums: 1を指定しているので、縦一列に配置されます。

今回は、左側に、
`Kino.Layout.grid([contest_name, problem_name,judge_all], columns: 1)`
右側に
`Kino.Layout.grid([input_string,run], columns: 1)`
を配置したかったので、
Kino.Layout.grid()を二重に使ってみました。
全体のコードは、以下の通りです。
```elixir  
  Kino.Frame.render(frame,
  Kino.Layout.grid([
    Kino.Layout.grid([contest_name, problem_name,judge_all], columns: 1),
    Kino.Layout.grid([input_string,run], columns: 1)
  ], columns: 2)
  )
```

最後に、frameの値を表示させます。
frameの値の内容は、kinoのフレームなので、自動的に、配置した部品が表示されます。ボタンも指定した通りに動作します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/151ad4c3-63dc-fb3a-6586-54d39eb2216c.png)


# プログラム全体

```elixir
contest_name = Kino.Input.text("コンテスト名")
problem_name = Kino.Input.text("問題名")
judge_all = Kino.Control.button("入力例で実行")

Kino.listen(judge_all, fn _event ->
  atcoder = AtCoder.new(Kino.Input.read(contest_name), Kino.Input.read(problem_name))
  AtCoder.judge_all(atcoder) end)
input_string = Kino.Input.textarea("入力")
run = Kino.Control.button("実行")
Kino.listen(run, fn _event ->
  input_string
  |> Kino.Input.read()
  |> AtCoder.run_main()
  |> IO.puts()
end)
frame = Kino.Frame.new()
  Kino.Frame.render(frame,
  Kino.Layout.grid([
    Kino.Layout.grid([contest_name, problem_name,judge_all], columns: 1),
    Kino.Layout.grid([input_string,run], columns: 1)
  ], columns: 2)
)
```

# 試してみたい方

livebookのURLで開くを使って、次のURLを開けば使用できます。
ぜひ試してみてください。
https://github.com/masahiro-999/easy_atcoder/blob/main/easy_atcoder.livemd

[![Run in Livebook](https://livebook.dev/badge/v1/blue.svg)](https://livebook.dev/run?url=https%3A%2F%2Fgithub.com%2Fmasahiro-999%2Feasy_atcoder%2Fblob%2Fmain%2Feasy_atcoder.livemd)

# まとめ
- Livebookは、ドキュメントとともに、プログラムや実行結果が書ける道具だったはずだが、いつのまにか、アプリが作れるようになっていました。
- AtCoderの正解チェックのアプリとしては、行いたいことがほぼ実現できた。
- テキストボックスとボタンを使ってみましたが、このほかにもいろいろな部品があるので試してみたい
- 入力した回答プログラムをAtCoderにPOSTする機能を実現したい※

※回答プログラムは、Livebook自身にの回答入力欄に書かれているのでこれを取得しないといけません。この方法わかる方いらしたら教えていただきたいです。