Bottles of Soda
Mix.install([
{:kino, github: "livebook-dev/kino", override: true},
{:kino_lab, "~> 0.1.0-dev", github: "jonatanklosko/kino_lab"},
{:vega_lite, "~> 0.1.4"},
{:kino_vega_lite, "~> 0.1.1"},
{:benchee, "~> 0.1"},
{:ecto, "~> 3.7"},
{:math, "~> 0.7.0"},
{:faker, "~> 0.17.0"},
{:utils, path: "#{__DIR__}/../utils"},
{:tested_cell, git: "https://github.com/BrooklinJazz/tested_cell"}
])
Navigation
Bottles of Soda
In the Elixir cell below create a module BottlesOfSoda
with a function on_the_wall/0
.
It should return a list with the following lyrics from 99
to 0
.
Ensure you handle the special cases for 2
, 1
and 0
.
BottlesOfSoda.on_the_wall()
[
"99 bottles of soda on the wall.
99 bottles of soda.
Take one down, pass it around.
98 bottles of soda on the wall.",
# ... and so on until you reach 2 where the grammar changes
"2 bottles of soda on the wall.
2 bottles of soda.
Take one down, pass it around.
1 bottle of soda on the wall.",
"1 bottle of soda on the wall.
1 bottle of soda.
Take one down, pass it around.
0 bottles of soda on the wall.",
"No more bottles of soda on the wall, no more bottles of soda.
Go to the store and buy some more, 99 bottles of soda on the wall."
]
ExUnit.start(auto_run: false)
defmodule Assertion do
use ExUnit.Case
test "" do
defmodule BottlesOfSoda do
def on_the_wall do
end
end
defmodule Solutions.BottlesOfSoda do
def on_the_wall do
Enum.to_list(99..0)
|> Enum.map(&sentence/1)
end
defp container(1), do: "bottle"
defp container(_n), do: "bottles"
defp sentence(0) do
"No more bottles of soda on the wall, no more bottles of soda.\nGo to the store and buy some more, 99 bottles of soda on the wall."
end
defp sentence(n) when n > 0 do
"#{n} #{container(n)} of soda on the wall.\n#{n} #{container(n)} of soda.\nTake one down, pass it around.\n#{n - 1} #{container(n - 1)} of soda on the wall."
end
end
result = BottlesOfSoda.on_the_wall()
assert result, "Implement the `on_the_wall/0` function."
assert is_list(result), "`on_the_wall/0` should return a list."
assert Enum.at(result, 0) ==
"99 bottles of soda on the wall.\n99 bottles of soda.\nTake one down, pass it around.\n98 bottles of soda on the wall."
assert length(result) == 100, "There should be 100 total verses."
assert Enum.at(result, 97) ==
"2 bottles of soda on the wall.\n2 bottles of soda.\nTake one down, pass it around.\n1 bottle of soda on the wall."
assert Enum.at(result, 98) ==
"1 bottle of soda on the wall.\n1 bottle of soda.\nTake one down, pass it around.\n0 bottles of soda on the wall."
assert Enum.at(result, 99) ==
"No more bottles of soda on the wall, no more bottles of soda.\nGo to the store and buy some more, 99 bottles of soda on the wall."
assert result == Utils.Solutions.BottlesOfSoda.on_the_wall()
end
end
ExUnit.run()
# Make variables and modules defined in the test available.
# Also allows for exploration using the output of the cell.
defmodule BottlesOfSoda do
def on_the_wall do
end
end
(Bonus) Bottles of ???
Make a new BottlesOfBlank
module below with the following modifications.
-
It should be able to accept a custom drink instead of
"soda"
. -
It should be able to accept a custom container instead of
"bottles"
. - It should be able to accept a range of lyrics, and only return than range of lyrics.
For example,
BottlesOfBlank.on_the_wall(3..0, "pop", "cans")
[
"3 cans of pop on the wall.
3 cans of pop.
Take one down, pass it around.
2 cans of pop on the wall.",
"2 cans of pop on the wall.
2 cans of pop.
Take one down, pass it around.
1 can of pop on the wall.",
"1 can of pop on the wall.
1 can of pop.
Take one down, pass it around.
0 cans of pop on the wall.",
"No more cans of pop on the wall, no more cans of pop.
Go to the store and buy some more, 99 cans of pop on the wall.
"
]
You can assume any container will be provided in it’s plural form so a "can"
will always
be passed into the function as "cans"
. You only need to worry about containers whose plural form
ends in an s
.
ExUnit.start(auto_run: false)
defmodule Assertion do
use ExUnit.Case
test "" do
defmodule BottlesOfBlank do
def on_the_wall(range, beverage, container) do
end
end
result = BottlesOfBlank.on_the_wall(50..0, "pop", "cans")
assert result, "Implement the `on_the_wall/3` function."
assert is_list(result), "`on_the_wall/3` should return a list."
assert Enum.at(result, 0) ==
"50 cans of pop on the wall.\n50 cans of pop.\nTake one down, pass it around.\n49 cans of pop on the wall."
assert length(result) == 51, "There should be 51 total verses."
assert Enum.at(result, 48) ==
"2 cans of pop on the wall.\n2 cans of pop.\nTake one down, pass it around.\n1 can of pop on the wall."
assert Enum.at(result, 49) ==
"1 can of pop on the wall.\n1 can of pop.\nTake one down, pass it around.\n0 cans of pop on the wall."
assert Enum.at(result, 50) ==
"No more cans of pop on the wall, no more cans of pop.\nGo to the store and buy some more, 99 cans of pop on the wall."
end
end
ExUnit.run()
# Make variables and modules defined in the test available.
# Also allows for exploration using the output of the cell.
defmodule BottlesOfBlank do
def on_the_wall(range, beverage, container) do
end
end
Commit Your Progress
Run the following in your command line from the project folder to track and save your progress in a Git commit.
$ git add .
$ git commit -m "finish bottles of soda exercise"