wslでelixir その135

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
ハッカソンなので、練習問題、やってみた。

# 練習問題
Livebookで、小遣い帳を書け。

# 方針
- sqlite使う。
- ecto使う。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7372a7a2-2dd6-edf4-c86b-94ad64100366.png)

# セットアップ

```

Mix.install([
  {:ecto_sql, "~> 3.9"},
  {:ecto, "~> 3.9"},
  {:kino, "~> 0.10.0"},
  {:ecto_sqlite3, "~> 0.12"}
])
```

# サンプルコード

```
defmodule CreateKozu do
  use Ecto.Migration

  def change do
    create table(:kozu) do
      add(:adate, :date)
      add(:memo, :string, null: false)
      add(:inp, :integer, default: 0)
      add(:oup, :integer, default: 0)
    end
  end
end

defmodule Kozu do
  use Ecto.Schema

  schema "kozu" do
    field(:adate, :date)
    field(:memo, :string)
    field(:inp, :integer, default: 0)
    field(:oup, :integer, default: 0)
  end
end


defmodule Repo do
  use Ecto.Repo, adapter: Ecto.Adapters.SQLite3, otp_app: :nothing
end

Repo.start_link(database: "test.db")

Ecto.Migrator.up(Repo, 1, CreateKozu)

defmodule Kozuk do
  def insert(a, b, c, d) do
    e = 0
    f = 0

    if c == "+" do
      {e, _} = Integer.parse(d)
      p = %Kozu{adate: Date.from_iso8601!(a), memo: b, inp: e, oup: f}
      Repo.insert(p)
    else
      {f, _} = Integer.parse(d)
      p = %Kozu{adate: Date.from_iso8601!(a), memo: b, inp: e, oup: f}
      Repo.insert(p)
    end
  end

  def update(n, a, b, c, d) do
    {id, _} = Integer.parse(n)
    p = Repo.get(Kozu, id)
    e = 0
    f = 0

    if c == "+" do
      {e, _} = Integer.parse(d)
      o = Ecto.Changeset.change(p, %{adate: Date.from_iso8601!(a), memo: b, inp: e, oup: f})
      Repo.update(o)
    else
      {f, _} = Integer.parse(d)
      o = Ecto.Changeset.change(p, %{adate: Date.from_iso8601!(a), memo: b, inp: e, oup: f})
      Repo.update(o)
    end
  end

  def delete(n) do
    {id, _} = Integer.parse(n)
    p = Repo.get(Kozu, id)
    Repo.delete(p)
  end

  def list() do
    import Ecto.Query, only: [order_by: 2]
    IO.puts(" id	date 内訳　貰ったお金　使ったお金　残金")

    Kozu
    |> Ecto.Query.order_by(asc: :adate)
    |> Repo.all()
    |> Enum.reduce(0, fn v, acc ->
      acc = v.inp - v.oup + acc
      IO.puts(" #{v.id}	#{v.adate}	#{v.memo}	#{v.inp}	#{v.oup}	#{acc}")
      acc
    end)
  end

  def run(l) do
    #l = IO.gets("> ")
    l = String.replace(l, "\n", "")
    s = String.split(l, " ")
    cond do
    
      Enum.at(s, 0) == "in" ->
        Kozuk.insert(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3), Enum.at(s, 4))
      Enum.at(s, 0) == "del" ->
        Kozuk.delete(Enum.at(s, 1))
      Enum.at(s, 0) == "up" ->
        Kozuk.update(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3), Enum.at(s, 4), Enum.at(s, 5))
      Enum.at(s, 0) == "disp" ->
        Kozuk.list()
      true ->
        IO.inspect(l)
    end
    #run()
  end
end

Kozuk.run("in 2023-08-01 棚卸 + 1100")

Kozuk.run("in 2023-08-04 アイス - 100")


Kozuk.run("in 2023-08-05 ジュース - 110")

Kozuk.run("disp")


```

# 実行結果

```
 id	date 内訳　貰ったお金　使ったお金　残金

11:14:43.612 [debug] QUERY OK source="kozu" db=4.9ms idle=1901.0ms
SELECT k0."id", k0."adate", k0."memo", k0."inp", k0."oup" FROM "kozu" AS k0 ORDER BY k0."adate" []
 1	2023-08-01	棚卸	1100	0	1100
 2	2023-08-04	アイス	0	100	1000
 3	2023-08-05	ジュース	0	110	890

```

以上。