Finding the right bottle of wine for a particular customer is not an easy task.
As a tech-savvy restaurant owner, you decided to speed up the wine selection process by writing an app that will let guests filter your wines by their preferences.
On the welcome screen of your app, you want to display a short explanation of each wine color.
Implement the WineCellar.explain_colors/0 function. It takes no arguments and returns a keyword list with wine colors as keys and explanations as values.
A bottle of wine is represented as a 3-tuple of grape variety, year, and country of origin. The wines are stored by wine color in a keyword list.
Implement the WineCellar.filter/3 function. It should take a keyword list of wines, a color atom and a keyword list of options, with a default value of []. The function should return a list of wines of a given color.
Extend the WineCellar.filter/3 function. When given a :year option, the function should return a list of wines of a given color from a given year.
Use the already-implemented WineCellar.filter_by_year/2 function. It takes a list of wines and a year as arguments and returns a list of wines from a given year.
Extend the WineCellar.filter/3 function. When given a :country option, the function should return a list of wines of a given color from a given country.
Use the already-implemented WineCellar.filter_by_country/2 function. It takes a list of wines and a country as arguments and returns a list of wines from a given country.
Make sure that the function works when given both the :year and the :country option, in any order.
https://exercism.org/tracks/elixir/exercises/wine-cellar
defmodule WineCellar do
@moduledoc """
practice keyword lists
"""
@doc """
show the colors keyword lists
"""
@spec explain_colors :: keyword(String.t())
def explain_colors do
[
white: "Fermented without skin contact.",
red: "Fermented with skin contact using dark-colored grapes.",
rose: "Fermented with some skin contact, but not enough to qualify as a red wine.",
]
end
@doc """
filter keyword lists
"""
@spec filter(cellar :: keyword(tuple()), color :: atom(), opts :: keyword(number)) :: [tuple()]
def filter(cellar, color, opts \\ []) do
Keyword.get_values(cellar, color)
|> filter_by_year(opts[:year])
|> filter_by_country(opts[:country])
end
# def filter(cellar, color, opts \\ []) do
# year = opts[:year]
# country = opts[:country]
# wines = Keyword.get_values(cellar, color)
# wines = if (year), do: filter_by_year(wines, year), else: wines
# if (country), do: filter_by_country(wines, country), else: wines
# end
# The functions below do not need to be modified.
defp filter_by_year(wines, nil), do: wines
defp filter_by_year([], _year), do: []
defp filter_by_year([{_, year, _} = wine | tail], year) do
[wine | filter_by_year(tail, year)]
end
defp filter_by_year([{_, _, _} | tail], year) do
filter_by_year(tail, year)
end
defp filter_by_country(wines, nil), do: wines
defp filter_by_country([], _country), do: []
defp filter_by_country([{_, _, country} = wine | tail], country) do
[wine | filter_by_country(tail, country)]
end
defp filter_by_country([{_, _, _} | tail], country) do
filter_by_country(tail, country)
end
end