Weighted Voting
Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.8.0", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"}
])
Navigation
Weighted Voting
In the previous Counting Votes exercise, we created a module to count a list of votes. For example, users would vote for their favorite animal to decide if :birds, :dogs, or :cats were more popular.
Now, you’re going to create a WeightedVoting.count/2 that can count the number of votes for a single value such as :dogs or :cats. provided in a keyword list.
WeightedVoting.count([cats: 10, dogs: 20, dogs: 20], :dogs)
40
You’re also going to create a WeightedVoting.tally/1 function that will count the votes provided in a keyword list, and return the results as a keyword list like so.
WeightedVoting.tally([cats: 10, dogs: 20, dogs: 20])
[cats: 10, dogs: 40]
Example Solution
defmodule WeightedVoting do
def count(votes, vote_to_count) do
Enum.reduce(votes, 0, fn {key, value}, acc ->
if key == vote_to_count do
acc + value
else
acc
end
end)
end
def tally(votes) do
Enum.reduce(votes, [], fn {key, vote_count}, acc ->
Keyword.update(acc, key, vote_count, fn existing_value ->
existing_value + vote_count
end)
end)
end
def tally_map(votes) do
Enum.reduce(votes, %{}, fn {key, vote_count}, acc ->
Map.update(acc, key, vote_count, fn existing_value ->
existing_value + vote_count
end)
end)
end
end
Implement the WeightedVoting module as documented below.
defmodule WeightedVoting do
@doc """
Count the total number of votes for some key in a keyword list.
## Examples
iex> WeightedVoting.count([dogs: 20, dogs: 10], :dogs)
30
iex> WeightedVoting.count([cats: 10, dogs: 20, dogs: 30], :dogs)
50
iex> WeightedVoting.count([cats: 10, dogs: 20, dogs: 10, cats: 30], :cats)
40
"""
def count(votes, vote_to_count) do
end
@doc """
Tally the total number of votes in a keyword list, and return
the results as a keyword list.
The keyword list should be sorted in alphabetical order.
## Examples
iex> WeightedVoting.tally([dogs: 20, dogs: 10])
[dogs: 30]
iex> WeightedVoting.tally([cats: 10, dogs: 20, dogs: 10])
[cats: 10, dogs: 30]
iex> WeightedVoting.tally([cats: 10, dogs: 20, cats: 20, dogs: 10, birds: 20])
[birds: 20, cats: 30, dogs: 30]
"""
def tally(votes) do
end
end
Bonus: Tally Map
Create a WeightedVoting.tally_map/1 function which returns a map instead of a keyword list.
You may copy the following code into the WeightedVoting module above to get started.
@doc """
Tally the total number of votes in a keyword list, and return
the results as a map.
## Examples
iex> WeightedVoting.tally_map([dogs: 20, dogs: 10])
%{dogs: 30}
iex> WeightedVoting.tally_map([cats: 10, dogs: 20, dogs: 10])
%{cats: 10, dogs: 30}
iex> WeightedVoting.tally_map([cats: 10, dogs: 20, cats: 20, dogs: 10, birds: 20])
%{birds: 20, cats: 30, dogs: 30}
"""
def tally_map(votes) do
end
Mark As Completed
file_name = Path.basename(Regex.replace(~r/#.+/, __ENV__.file, ""), ".livemd")
save_name =
case Path.basename(__DIR__) do
"reading" -> "weighted_voting_reading"
"exercises" -> "weighted_voting_exercise"
end
progress_path = __DIR__ <> "/../progress.json"
existing_progress = File.read!(progress_path) |> Jason.decode!()
default = Map.get(existing_progress, save_name, false)
form =
Kino.Control.form(
[
completed: input = Kino.Input.checkbox("Mark As Completed", default: default)
],
report_changes: true
)
Task.async(fn ->
for %{data: %{completed: completed}} <- Kino.Control.stream(form) do
File.write!(
progress_path,
Jason.encode!(Map.put(existing_progress, save_name, completed), pretty: true)
)
end
end)
form
Commit Your Progress
Run the following in your command line from the curriculum folder to track and save your progress in a Git commit.
Ensure that you do not already have undesired or unrelated changes by running git status or by checking the source control tab in Visual Studio Code.
$ git checkout -b weighted-voting-exercise
$ git add .
$ git commit -m "finish weighted voting exercise"
$ git push origin weighted-voting-exercise
Create a pull request from your weighted-voting-exercise branch to your solutions branch.
Please do not create a pull request to the DockYard Academy repository as this will spam our PR tracker.
DockYard Academy Students Only:
Notify your teacher by including @BrooklinJazz in your PR description to get feedback.
You (or your teacher) may merge your PR into your solutions branch after review.
If you are interested in joining the next academy cohort, sign up here to receive more news when it is available.
Up Next
| Previous | Next |
|---|---|
| Number Finder | Custom Enum With Reduce |