Skip to content

Instantly share code, notes, and snippets.

@jdesilvio
Last active February 18, 2017 05:13
Show Gist options
  • Save jdesilvio/7972ff3274e85b37dd933aca6d3bab22 to your computer and use it in GitHub Desktop.
Save jdesilvio/7972ff3274e85b37dd933aca6d3bab22 to your computer and use it in GitHub Desktop.
Elixir Pomodoro Timer
defmodule Pomodoro do
@moduledoc """
Adapted from the Countdown module
in 'Programming Elixir' by Dave Thomas.
# Usage:
$ iex pomodoro.ex
iex> Pomodoro.start(15, 5, true)
"""
defp sleep(seconds) do
receive do
after seconds * 1000 -> nil
end
end
def say(text) do
spawn fn -> :os.cmd('say #{text}') end
end
defp announce_time(count, every) do
case rem(count, every) do
0 -> "#{count / 60} minutes left!"
_ -> nil
end
end
@doc """
Start a countdown.
Inputs:
* interval = duration of countdown in minutes
* announce_every = interval (in minutes) to announce remaining time
* speak = do you want the announcement to be audible? (only works on Mac)
"""
def start(interval \\ 15, announce_every \\ 5, speak \\ false)
def start(interval, announce_every, speak) do
IO.puts("Pomodoro timer set for #{interval} minute(s) has begun...")
timer = Stream.resource(
fn -> interval * 60 end,
fn
0 -> {:halt, 0}
time_remaining ->
sleep(1)
{[announce_time(time_remaining, announce_every * 60)], time_remaining - 1}
end,
fn _ -> nil end
)
|> Stream.each(&IO.puts/1)
case speak do
true -> timer |> Stream.each(&Pomodoro.say/1) |> Enum.to_list
false -> timer |> Enum.to_list
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment