Skip to content

Instantly share code, notes, and snippets.

@polvalente
Created June 21, 2023 08:59
Show Gist options
  • Save polvalente/c288b2582eb06da5111cc1ecfb38bee8 to your computer and use it in GitHub Desktop.
Save polvalente/c288b2582eb06da5111cc1ecfb38bee8 to your computer and use it in GitHub Desktop.
Nx (?!) solution for to-do app
# To-Do app
Mix.install [:exla, {:nx, github: "elixir-nx/nx", sparse: "nx", override: true}]
max_todo_length = 5
max_todos = 10
run = fn run_fn, state ->
case IO.gets("Choose one of the following options:\n1. List TO-DOs\n2. Add a new TO-DO\n3. Mark TO-DO as completed\n4. Delete TO-DO.\n5. Exit\n>> ") |> String.trim() do
"1" ->
todos = if state.count > 0, do: Nx.to_list(state.to_dos[0..(state.count - 1)]), else: []
IO.puts("To-Dos: ")
todos
|> Enum.with_index(fn row, index ->
{contents, [completed]} = Enum.split(row, -1)
{String.trim_trailing(List.to_string(contents), "\0"), if(completed == 1, do: "✔", else: " "), index}
end)
|> Enum.map_join("\n", fn {todo, completed, idx} ->
"#{idx}. #{todo} [#{completed}]"
end)
|> IO.puts()
state
"2" ->
todo = IO.gets("Insert your new to-do\n>> ") |> String.trim()
todo = String.slice(todo, 0, min(byte_size(todo), max_todo_length)) |> String.pad_trailing(max_todo_length, "\0")
todo_tensor = Nx.from_binary(todo <> <<0>>, :u8) |> Nx.reshape({1, max_todo_length + 1})
%{state | to_dos: Nx.put_slice(state.to_dos, [state.count, 0], todo_tensor), count: state.count + 1}
"3" ->
try do
{todo_idx, _} = IO.gets("Insert the index for the to-do to be completed\n>> ") |> Integer.parse()
%{state | to_dos: Nx.indexed_put(state.to_dos, Nx.tensor([todo_idx, max_todo_length]), Nx.u8(1))}
rescue
_ ->
IO.warn("Failed to complete to-do.")
state
end
"4" ->
try do
{todo_idx, _} = IO.gets("Insert the index for the to-do to be deleted\n>> ") |> Integer.parse()
to_dos =
if todo_idx == state.count do
state.to_dos
else
Nx.put_slice(state.to_dos, [todo_idx, 0], state.to_dos[[(todo_idx + 1)..-1//1, 0..-1//1]])
end
%{state | to_dos: to_dos, count: state.count - 1}
rescue
_ ->
IO.warn("Failed to delete to-do.")
state
end
"5" ->
IO.puts("Exiting")
:exit
cmd ->
IO.warn("Invalid command #{inspect(cmd)}")
state
end
|> then(fn
:exit ->
:exit
state ->
run_fn.(run_fn, state)
end)
end
Nx.default_backend(EXLA.Backend)
run.(run, %{count: 0, to_dos: Nx.broadcast(Nx.u8(0), {max_todos, max_todo_length + 1})})
05:56:47.344 [info] TfrtCpuClient created.
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 2
Insert your new to-do
>> a
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 2
Insert your new to-do
>> b
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 2
Insert your new to-do
>> c
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. a [ ]
1. b [ ]
2. c [ ]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 3
Insert the index for the to-do to be completed
>> 1
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. a [ ]
1. b [✔]
2. c [ ]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 4
Insert the index for the to-do to be deleted
>> 2
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. a [ ]
1. b [✔]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 2
Insert your new to-do
>> d
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 2
Insert your new to-do
>> e
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. a [ ]
1. b [✔]
2. d [ ]
3. e [ ]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 4
Insert the index for the to-do to be deleted
>> 0
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. b [✔]
1. d [ ]
2. e [ ]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 4
Insert the index for the to-do to be deleted
>> 1
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 1
To-Dos:
0. b [✔]
1. e [ ]
Choose one of the following options:
1. List TO-DOs
2. Add a new TO-DO
3. Mark TO-DO as completed
4. Delete TO-DO.
5. Exit
>> 5
Exiting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment