diff --git a/.formatter.exs b/.formatter.exs index bf133c11db..38861f8552 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,3 +1,4 @@ [ - inputs: ["mix.exs", "{exercises,bin}/**/*.{ex,exs}"] + plugins: [MarkdownCodeBlockFormatter], + inputs: ["mix.exs", "{exercises,bin}/**/*.{ex,exs}", "{concepts,exercises,docs,reference}/**/*.md", "*.md"] ] diff --git a/concepts/anonymous-functions/about.md b/concepts/anonymous-functions/about.md index a5f3a7f1dc..aad2ed0664 100644 --- a/concepts/anonymous-functions/about.md +++ b/concepts/anonymous-functions/about.md @@ -32,7 +32,7 @@ Anonymous functions may be created with the [`&` capture shorthand][kernel-captu fn x, y -> abs(x) + abs(y) end # We can write: - & abs(&1) + abs(&2) + &(abs(&1) + abs(&2)) ``` - The `&` capture operator can also be used to [_capture_ existing named function][capture]: diff --git a/concepts/basics/introduction.md b/concepts/basics/introduction.md index 1a9aa515e8..961c4af62e 100644 --- a/concepts/basics/introduction.md +++ b/concepts/basics/introduction.md @@ -5,12 +5,16 @@ Elixir is a dynamically-typed language, meaning that the type of a variable is only checked at runtime. Using the match `=` operator, we can bind a value of any type to a variable name: ```elixir -count = 1 # Bound an integer value of 1 -count = 2 # You may re-bind variables +# Bound an integer value of 1 +count = 1 +# You may re-bind variables +count = 2 -count = false # You may re-bind any type to a variable +# You may re-bind any type to a variable +count = false -message = "Success!" # Strings can be created by enclosing characters within double quotes +# Strings can be created by enclosing characters within double quotes +message = "Success!" ``` ## Modules diff --git a/concepts/binaries/about.md b/concepts/binaries/about.md index 01decc82ac..e908f63e7d 100644 --- a/concepts/binaries/about.md +++ b/concepts/binaries/about.md @@ -11,7 +11,8 @@ ```elixir <<255>> == <<0xFF>> -<<256>> == <<0>> # Overflowing bits are truncated +# Overflowing bits are truncated +<<256>> == <<0>> <<256::size(16)>> == <<1, 0>> <<"Hello">> == <<72, 101, 108, 108, 111>> diff --git a/concepts/binaries/introduction.md b/concepts/binaries/introduction.md index 6e0233ef7a..6ec86d5d28 100644 --- a/concepts/binaries/introduction.md +++ b/concepts/binaries/introduction.md @@ -8,7 +8,8 @@ Binary literals are defined using the bitstring special form `<<>>`. When defini ```elixir <<255>> == <<0xFF>> -<<256>> == <<0>> # Overflowing bits are truncated +# Overflowing bits are truncated +<<256>> == <<0>> <<2, 4, 6, 8, 10, 12, 14, 16>> == <<0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10>> ``` diff --git a/concepts/booleans/about.md b/concepts/booleans/about.md index ff6ae139cc..d7eb0b9725 100644 --- a/concepts/booleans/about.md +++ b/concepts/booleans/about.md @@ -20,8 +20,11 @@ Boolean operators use _short-circuit evaluation_, which means that the expressio Each of the operators has a different precedence, where `not/1` is evaluated before `and/2` and `or/2`. Brackets can be used to evaluate one part of the expression before the others: ```elixir -not true and false # => false -not (true and false) # => true +not true and false +# => false + +not (true and false) +# => true ``` When writing a function that returns a boolean value, it is [idiomatic to end the function name][naming] with a `?`. The same convention can be used for variables that store boolean values. diff --git a/concepts/docs/about.md b/concepts/docs/about.md index 5d6569856f..6b9f02a9ef 100644 --- a/concepts/docs/about.md +++ b/concepts/docs/about.md @@ -74,6 +74,8 @@ If you have Elixir installed on your computer, you can use it in [the interactiv In `iex`, you can type [`h`][iex-h], followed by a space and a module name or a function name, to read its documentation. +[]: # (elixir-formatter-disable-next-block) + ```elixir iex()> h String.upcase/1 # def upcase(string, mode \\ :default) diff --git a/concepts/enum/about.md b/concepts/enum/about.md index 18e8fc1693..a2d216378f 100644 --- a/concepts/enum/about.md +++ b/concepts/enum/about.md @@ -47,6 +47,7 @@ Enum.reduce([4, 20, 31, 9, 2], nil, fn x, acc -> x <= acc -> acc end end) + # => 31 ``` diff --git a/concepts/exceptions/about.md b/concepts/exceptions/about.md index 8afeee223c..dedf7bae34 100644 --- a/concepts/exceptions/about.md +++ b/concepts/exceptions/about.md @@ -33,6 +33,7 @@ defmodule MyCustomizedError do case value do [] -> %MyCustomizedError{} + _ -> %MyCustomizedError{message: "Alert: " <> value} end diff --git a/concepts/exceptions/introduction.md b/concepts/exceptions/introduction.md index f07b804e69..1294358106 100644 --- a/concepts/exceptions/introduction.md +++ b/concepts/exceptions/introduction.md @@ -28,6 +28,7 @@ defmodule MyCustomizedError do case value do [] -> %MyCustomizedError{} + _ -> %MyCustomizedError{message: "Alert: " <> value} end diff --git a/concepts/file/about.md b/concepts/file/about.md index 720bc38189..5a80bbf6a4 100644 --- a/concepts/file/about.md +++ b/concepts/file/about.md @@ -58,7 +58,7 @@ Reading a file with [`File.read/1`][file-read] is going to load the whole file i ```elixir File.stream!("file.txt") -|> Stream.map(& &1 <> "!") +|> Stream.map(&(&1 <> "!")) |> Stream.into(File.stream!("new_file.txt")) |> Stream.run() ``` diff --git a/concepts/io/about.md b/concepts/io/about.md index 157a6333b8..a591c9b703 100644 --- a/concepts/io/about.md +++ b/concepts/io/about.md @@ -28,6 +28,7 @@ When this happens, you might want to use [`IO.inspect/2`][io-inspect] instead. |> IO.inspect(label: "step 1") |> String.downcase() |> IO.inspect(label: "step 2") + # > step 1: "HELLO" # > step 2: "hello" # => "hello" diff --git a/concepts/keyword-lists/about.md b/concepts/keyword-lists/about.md index 7d62a6c5f2..0ffa1d4df7 100644 --- a/concepts/keyword-lists/about.md +++ b/concepts/keyword-lists/about.md @@ -21,6 +21,8 @@ Keyword.keyword?([{"month", "April"}]) If you want to use characters other than letters, numbers, and `_` in the key, you need to wrap it in quotes. However, that does not make it a string - it is still an atom. +[]: # (elixir-formatter-disable-next-block) + ```elixir Keyword.keyword?(["day of week": "Monday"]) # => true @@ -59,6 +61,8 @@ if age >= 16, do: "beer", else: "no beer" This may look like `if` accepts two arguments, but the `do:` and `else:` pair is actually a single argument - a keyword list. The same code could be written as: +[]: # (elixir-formatter-disable-next-block) + ```elixir if age >= 16, [do: "beer", else: "no beer"] # or diff --git a/concepts/links/about.md b/concepts/links/about.md index 50b1050580..e1e7e33987 100644 --- a/concepts/links/about.md +++ b/concepts/links/about.md @@ -52,6 +52,7 @@ pid = spawn_link(fn -> :timer.sleep(50_000) end) self() |> Process.info() |> Keyword.get(:links) + # => [#PID<0.126.0>] ``` @@ -69,6 +70,7 @@ The current value of the flag can be checked using [`Process.info/1`][process-in pid |> Process.info() |> Keyword.get(:trap_exit) + # => false ``` diff --git a/concepts/list-comprehensions/about.md b/concepts/list-comprehensions/about.md index af34a2bfb3..3fc9ba7da5 100644 --- a/concepts/list-comprehensions/about.md +++ b/concepts/list-comprehensions/about.md @@ -2,10 +2,12 @@ [Comprehension][for] provide a facility for transforming _Enumerables_ easily and declaratively. They are _syntactic sugar_ for iterating through enumerables in Elixir. +[]: # (elixir-formatter-disable-next-block) + ```elixir for s <- ["a", "b", "hello", "c"], # 1. generator - String.length(s) == 1, # 2. filter - into: "", # 3. collectable + String.length(s) == 1, # 2. filter + into: "", # 3. collectable do: String.upcase(s) # => "ABC" @@ -29,6 +31,7 @@ for x <- [0, 1], y <- [0, 1] do {x, y} end + # => [{0, 0}, {0, 1}, {1, 0}, {1, 1}] ``` @@ -49,6 +52,7 @@ for pair <- [a: "string"], {atom, str} = pair do str end + # => ["string"] ``` diff --git a/concepts/list-comprehensions/introduction.md b/concepts/list-comprehensions/introduction.md index a654f3d560..eae7a8c9c5 100644 --- a/concepts/list-comprehensions/introduction.md +++ b/concepts/list-comprehensions/introduction.md @@ -23,6 +23,7 @@ for {atom, number} <- [a: 1, b: 2, c: 3, d: 4], rem(number, 2) == 0 do atom end + # => [:b, :d] ``` @@ -33,5 +34,6 @@ for x <- [0, 1], y <- [0, 1] do {x, y} end + # => [{0, 0}, {0, 1}, {1, 0}, {1, 1}] ``` diff --git a/concepts/lists/about.md b/concepts/lists/about.md index b9f9d1b88a..ccf5c213d3 100644 --- a/concepts/lists/about.md +++ b/concepts/lists/about.md @@ -14,11 +14,14 @@ Lists can be written in literal form, head-tail notation, (which uses the `cons` # Head-tail Notation [] -[1 | []] # same as [1] -[1 | [2 | [3 | []]]] # same as [1, 2, 3] +# same as [1] +[1 | []] +# same as [1, 2, 3] +[1 | [2 | [3 | []]]] # Mixed -[1 | [2, 3]] # same as [1, 2, 3] +# same as [1, 2, 3] +[1 | [2, 3]] ``` There can also be more than one element before the _cons_ (`|`) operator. @@ -46,7 +49,8 @@ We can achieve the same result by prepending an element to the reversed list, an [1, 2, 3] ++ [4] ++ [5] ++ [6] # Prepend to the start of a list (faster, due to the nature of linked lists) -[6 | [5 | [4 | [3, 2, 1]]]] # then reverse! +[6 | [5 | [4 | [3, 2, 1]]]] +# then reverse! ``` There are several common `Kernel` functions for lists: diff --git a/concepts/maps/about.md b/concepts/maps/about.md index 2c1d51e235..c7a3d8388d 100644 --- a/concepts/maps/about.md +++ b/concepts/maps/about.md @@ -20,8 +20,8 @@ # A map with the string key "a" associated to the float value 2.0 %{"a" => 2.0} - # A map with the map key %{} with the list value [1,2,3] - %{%{} => [1,2,3]} + # A map with the map key %{} with the list value [1 ,2, 3] + %{%{} => [1, 2, 3]} # A map with keys of different types %{:a => 1, "b" => 2} diff --git a/concepts/module-attributes-as-constants/introduction.md b/concepts/module-attributes-as-constants/introduction.md index 623db4fb44..aa4e8aa6a5 100644 --- a/concepts/module-attributes-as-constants/introduction.md +++ b/concepts/module-attributes-as-constants/introduction.md @@ -4,7 +4,6 @@ In Elixir, we can define module attributes which can be used as constants in our ```elixir defmodule Example do - # Defines the attribute as the value 1 @constant_number 1 diff --git a/concepts/multiple-clause-functions/introduction.md b/concepts/multiple-clause-functions/introduction.md index 1d72bbc5bf..48b6d33071 100644 --- a/concepts/multiple-clause-functions/introduction.md +++ b/concepts/multiple-clause-functions/introduction.md @@ -8,6 +8,7 @@ Elixir offers _multiple function clauses_ and _guards_ to write: def number(n) when n == 7 do "Awesome, that's my favorite" end + def number(_n) do "That's not my favorite" end diff --git a/concepts/nil/about.md b/concepts/nil/about.md index 4ebc3249bc..ac2e2ee4fa 100644 --- a/concepts/nil/about.md +++ b/concepts/nil/about.md @@ -9,6 +9,8 @@ favorite_color = nil `nil` is an atom, but it is usually written as `nil`, not `:nil`. The boolean values `true` and `false` are atoms too. +[]: # (elixir-formatter-disable-next-block) + ```elixir nil === :nil # => true diff --git a/concepts/pipe-operator/about.md b/concepts/pipe-operator/about.md index 4b10af8dd1..2db9d65318 100644 --- a/concepts/pipe-operator/about.md +++ b/concepts/pipe-operator/about.md @@ -31,7 +31,7 @@ It is a matter of personal preference when to use the pipe operator and when not ```elixir # do - String.split("hello" , "") + String.split("hello", "") # don't "hello" |> String.split("") diff --git a/concepts/pipe-operator/introduction.md b/concepts/pipe-operator/introduction.md index fcf44c9fad..47a9ef8608 100644 --- a/concepts/pipe-operator/introduction.md +++ b/concepts/pipe-operator/introduction.md @@ -6,5 +6,6 @@ The `|>` operator is called the pipe operator. It can be used to chain function "hello" |> String.upcase() |> Kernel.<>("?!") + # => "HELLO?!" ``` diff --git a/concepts/ranges/about.md b/concepts/ranges/about.md index cc8eff88d6..9e0eb1470e 100644 --- a/concepts/ranges/about.md +++ b/concepts/ranges/about.md @@ -14,7 +14,7 @@ Enum.to_list(9..1) # => [9, 8, 7, 6, 5, 4, 3, 2, 1] -Enum.map(?A..?F, & <<&1>>) +Enum.map(?A..?F, &<<&1>>) ["A", "B", "C", "D", "E", "F"] ``` diff --git a/concepts/strings/about.md b/concepts/strings/about.md index 05a6f49cda..a3df56eab8 100644 --- a/concepts/strings/about.md +++ b/concepts/strings/about.md @@ -30,6 +30,7 @@ Any Elixir expression is valid inside the interpolation. If a string is given, t # => "And lists, too!" "But not functions: #{fn x -> x end}" + # => ** (Protocol.UndefinedError) protocol String.Chars not implemented for #Function<7.126501267/1 in :erl_eval.expr/5> of type Function # (elixir 1.10.1) lib/string/chars.ex:3: String.Chars.impl_for!/1 # (elixir 1.10.1) lib/string/chars.ex:22: String.Chars.to_string/1 diff --git a/concepts/tail-call-recursion/about.md b/concepts/tail-call-recursion/about.md index 98323b4bb1..0b18a08b70 100644 --- a/concepts/tail-call-recursion/about.md +++ b/concepts/tail-call-recursion/about.md @@ -29,6 +29,7 @@ Tail-recursive functions allow for [tail call optimization][tail-call-optimizati def reverse(list), do: do_reverse(list, []) defp do_reverse([], acc), do: acc + defp do_reverse([head | tail], acc) do do_reverse(tail, [head | acc]) end diff --git a/concepts/tasks/about.md b/concepts/tasks/about.md index bcaaf70f3d..10116fbdc6 100644 --- a/concepts/tasks/about.md +++ b/concepts/tasks/about.md @@ -98,6 +98,7 @@ If you need to run tasks that perform different operations, you might need `Task inputs |> Enum.map(&Task.async(fn -> function.(&1) end)) |> Task.await_many(1_000) + # => ** (exit) exited in: Task.await_many([...], 1000) # ** (EXIT) time out # (elixir 1.11.3) lib/task.ex:725: Task.await_many/5 diff --git a/concepts/try-rescue-else-after/about.md b/concepts/try-rescue-else-after/about.md index dd44ba5385..e946a966b6 100644 --- a/concepts/try-rescue-else-after/about.md +++ b/concepts/try-rescue-else-after/about.md @@ -18,5 +18,6 @@ else after :some_action end + # => :success ``` diff --git a/concepts/try-rescue-else-after/introduction.md b/concepts/try-rescue-else-after/introduction.md index cd7948f03e..8f286d7106 100644 --- a/concepts/try-rescue-else-after/introduction.md +++ b/concepts/try-rescue-else-after/introduction.md @@ -18,5 +18,6 @@ else after :some_action end + # => :success ``` diff --git a/concepts/try-rescue/about.md b/concepts/try-rescue/about.md index ab4829a993..d1df449ef2 100644 --- a/concepts/try-rescue/about.md +++ b/concepts/try-rescue/about.md @@ -4,6 +4,8 @@ For example: +[]: # (elixir-formatter-disable-next-block) + ```elixir try do #1 raise RuntimeError, "error" #2 diff --git a/concepts/try-rescue/introduction.md b/concepts/try-rescue/introduction.md index 16ca70cc80..70c0b6d711 100644 --- a/concepts/try-rescue/introduction.md +++ b/concepts/try-rescue/introduction.md @@ -2,6 +2,8 @@ Elixir provides a construct for rescuing from errors using `try .. rescue` +[]: # (elixir-formatter-disable-next-block) + ```elixir try do #1 raise RuntimeError, "error" #2 diff --git a/concepts/with/about.md b/concepts/with/about.md index 47f0f0e755..7624146963 100644 --- a/concepts/with/about.md +++ b/concepts/with/about.md @@ -8,10 +8,15 @@ Let's say that you want to validate a username with several checks. You might re case check_ascii(username) do {:ok, username} -> case check_starts_with_letter(username) do - {:ok, username} -> {:ok, username} - {:error, "usernames may only start with a letter"} = err -> err - end - {:error, "usernames may only contain ascii letters"} = err -> err + {:ok, username} -> + {:ok, username} + + {:error, "usernames may only start with a letter"} = err -> + err + end + + {:error, "usernames may only contain ascii letters"} = err -> + err end ``` diff --git a/docs/REPRESENTER_NORMALIZATIONS.md b/docs/REPRESENTER_NORMALIZATIONS.md index be7a40f580..6065f1cf97 100644 --- a/docs/REPRESENTER_NORMALIZATIONS.md +++ b/docs/REPRESENTER_NORMALIZATIONS.md @@ -87,6 +87,8 @@ Types are written without. ### Before +[]: # (elixir-formatter-disable-next-block) + ```elixir defmodule Fake do @type foo() :: integer() | atom diff --git a/docs/TESTS.md b/docs/TESTS.md index 9cc51579ff..f02141eba2 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -71,6 +71,8 @@ Multiple tests may be executed by giving multiple line numbers separated by `:`. For example, given a file with the following content with line numbers: +[]: # (elixir-formatter-disable-next-block) + ```elixir test "Test 1" do # 1 # test implementation # 2-6 @@ -151,7 +153,8 @@ dependency to the `mix.exs` file for your problem. ```elixir defp deps do - [{:dialyxir, "~> 0.4", only: [:dev]}] # <-- Add this + # Add this: + [{:dialyxir, "~> 0.4", only: [:dev]}] end ``` @@ -173,7 +176,7 @@ and Erlang types. To create a plt with sensible defaults run: $ mix dialyzer --plt ``` -Finally it can be run with: +Finally, it can be run with: ```bash $ mix dialyzer @@ -190,7 +193,7 @@ implementation of the `Bob` exercise. ```elixir defmodule Bob do - @spec hey(input :: String.t) :: String.t + @spec hey(input :: String.t()) :: String.t() def hey(input) do 1 end diff --git a/exercises/concept/basketball-website/.docs/instructions.md b/exercises/concept/basketball-website/.docs/instructions.md index d69dc9e8b6..25587f8e26 100644 --- a/exercises/concept/basketball-website/.docs/instructions.md +++ b/exercises/concept/basketball-website/.docs/instructions.md @@ -20,6 +20,7 @@ data = %{ } } } + BasketballWebsite.extract_from_path(data, "team_mascot.animal") # => "bear" BasketballWebsite.extract_from_path(data, "team_mascot.colors") diff --git a/exercises/concept/boutique-inventory/.docs/instructions.md b/exercises/concept/boutique-inventory/.docs/instructions.md index bb9d7c6c00..b714b7beec 100644 --- a/exercises/concept/boutique-inventory/.docs/instructions.md +++ b/exercises/concept/boutique-inventory/.docs/instructions.md @@ -23,6 +23,7 @@ BoutiqueInventory.sort_by_price([ %{price: 50, name: "Black Short Skirt", quantity_by_size: %{}}, %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}} ]) + # => [ # %{price: 20, name: "Bamboo Socks Cats", quantity_by_size: %{}}, # %{price: 50, name: "Red Short Skirt", quantity_by_size: %{}}, @@ -44,6 +45,7 @@ BoutiqueInventory.with_missing_price([ %{price: nil, name: "Denim Skirt", quantity_by_size: %{}}, %{price: 40, name: "Orange T-shirt", quantity_by_size: %{}} ]) + # => [ # %{price: nil, name: "Denim Pants", quantity_by_size: %{}}, # %{price: nil, name: "Denim Skirt", quantity_by_size: %{}} @@ -67,6 +69,7 @@ BoutiqueInventory.update_names( "T-shirt", "Tee" ) + # => [ # %{price: 40, name: "Black Tee", quantity_by_size: %{}}, # %{price: 70, name: "Denim Pants", quantity_by_size: %{}}, @@ -84,19 +87,19 @@ Implement the `increase_quantity/2` function. It should take a single item and a ```elixir BoutiqueInventory.increase_quantity( - %{ - name: "Polka Dot Skirt", - price: 68, - quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4} - }, - 6 + %{ + name: "Polka Dot Skirt", + price: 68, + quantity_by_size: %{s: 3, m: 5, l: 3, xl: 4} + }, + 6 ) + # => %{ # name: "Polka Dot Skirt", # price: 68, # quantity_by_size: %{l: 9, m: 11, s: 9, xl: 10} # } - ``` ## 5. Calculate the item's total quantity @@ -111,5 +114,6 @@ BoutiqueInventory.total_quantity(%{ price: 62, quantity_by_size: %{s: 3, m: 6, l: 5, xl: 2} }) + # => 16 ``` diff --git a/exercises/concept/boutique-suggestions/.docs/instructions.md b/exercises/concept/boutique-suggestions/.docs/instructions.md index 2107950fdc..009c0f4f02 100644 --- a/exercises/concept/boutique-suggestions/.docs/instructions.md +++ b/exercises/concept/boutique-suggestions/.docs/instructions.md @@ -21,10 +21,12 @@ tops = [ %{item_name: "Dress shirt"}, %{item_name: "Casual shirt"} ] + bottoms = [ %{item_name: "Jeans"}, %{item_name: "Dress trousers"} ] + BoutiqueSuggestions.get_combinations(tops, bottoms) # => [ # {%{item_name: "Dress shirt"}, %{item_name: "Jeans"}}, @@ -43,10 +45,12 @@ tops = [ %{item_name: "Dress shirt", base_color: "blue"}, %{item_name: "Casual shirt", base_color: "black"} ] + bottoms = [ %{item_name: "Jeans", base_color: "blue"}, %{item_name: "Dress trousers", base_color: "black"} ] + BoutiqueSuggestions.get_combinations(tops, bottoms) # => [ # {%{item_name: "Dress shirt", base_color: "blue"}, @@ -67,10 +71,12 @@ tops = [ %{item_name: "Dress shirt", base_color: "blue", price: 35}, %{item_name: "Casual shirt", base_color: "black", price: 20} ] + bottoms = [ %{item_name: "Jeans", base_color: "blue", price: 30}, %{item_name: "Dress trousers", base_color: "black", price: 75} ] + BoutiqueSuggestions.get_combinations(tops, bottoms, maximum_price: 50) # => [ # {%{item_name: "Casual shirt", base_color: "black", price: 20}, diff --git a/exercises/concept/boutique-suggestions/.docs/introduction.md b/exercises/concept/boutique-suggestions/.docs/introduction.md index e18e4175d7..35f1a0ab8f 100644 --- a/exercises/concept/boutique-suggestions/.docs/introduction.md +++ b/exercises/concept/boutique-suggestions/.docs/introduction.md @@ -25,6 +25,7 @@ for {atom, number} <- [a: 1, b: 2, c: 3, d: 4], rem(number, 2) == 0 do atom end + # => [:b, :d] ``` @@ -35,5 +36,6 @@ for x <- [0, 1], y <- [0, 1] do {x, y} end + # => [{0, 0}, {0, 1}, {1, 0}, {1, 1}] ``` diff --git a/exercises/concept/dancing-dots/.docs/instructions.md b/exercises/concept/dancing-dots/.docs/instructions.md index a42ddd519a..887dd890b0 100644 --- a/exercises/concept/dancing-dots/.docs/instructions.md +++ b/exercises/concept/dancing-dots/.docs/instructions.md @@ -25,7 +25,7 @@ defmodule MyCustomAnimation do use DancingDots.Animation end -MyCustomAnimation.init([some_option: true]) +MyCustomAnimation.init(some_option: true) # => {:ok, [some_option: true]} ``` @@ -62,15 +62,15 @@ Implement the `handle_frame/3` callback. It should return the dot with its radiu Frames are counted from `1`. The dot passed to `handle_frame/3` is always the dot in its original state, not in the state from the previous frame. ```elixir -DancingDots.Zoom.init([velocity: nil]) +DancingDots.Zoom.init(velocity: nil) # => {:error, "The :velocity option is required, and its value must be a number. Got: nil"} dot = %DancingDots.Dot{x: 100, y: 100, radius: 24, opacity: 1} -DancingDots.Zoom.handle_frame(dot, 1, [velocity: 10]) +DancingDots.Zoom.handle_frame(dot, 1, velocity: 10) # => %DancingDots.Dot{radius: 24, opacity: 1, x: 100, y: 100} -DancingDots.Zoom.handle_frame(dot, 2, [velocity: 10]) +DancingDots.Zoom.handle_frame(dot, 2, velocity: 10) # => %DancingDots.Dot{radius: 34, opacity: 1, x: 100, y: 100} ``` diff --git a/exercises/concept/date-parser/.docs/instructions.md b/exercises/concept/date-parser/.docs/instructions.md index ba3db53794..58046f79ae 100644 --- a/exercises/concept/date-parser/.docs/instructions.md +++ b/exercises/concept/date-parser/.docs/instructions.md @@ -40,6 +40,7 @@ Implement `capture_day/0`, `capture_month/0`, `capture_year/0`, `capture_day_nam DateParser.capture_month_name() |> Regex.compile!() |> Regex.named_captures("December") + # => %{"month_name" => "December"} ``` @@ -55,6 +56,7 @@ Implement `capture_numeric_date/0`, `capture_month_name_date()`, and `capture_da DateParser.capture_numeric_date() |> Regex.compile!() |> Regex.named_captures("01/01/1970") + # => %{"day" => "01", "month" => "01", "year" => "1970"} ``` @@ -70,6 +72,7 @@ Implement `match_numeric_date/0`, `match_month_name_date/0`, and `match_day_mont DateParser.match_day_month_name_date() |> Regex.named_captures("Thursday, January 1, 1970") + # => %{ # "day" => "1", # "day_name" => "Thursday", diff --git a/exercises/concept/file-sniffer/.docs/introduction.md b/exercises/concept/file-sniffer/.docs/introduction.md index 25123ef198..f3e5998e6a 100644 --- a/exercises/concept/file-sniffer/.docs/introduction.md +++ b/exercises/concept/file-sniffer/.docs/introduction.md @@ -10,7 +10,8 @@ Binary literals are defined using the bitstring special form `<<>>`. When defini ```elixir <<255>> == <<0xFF>> -<<256>> == <<0>> # Overflowing bits are truncated +# Overflowing bits are truncated +<<256>> == <<0>> <<2, 4, 6, 8, 10, 12, 14, 16>> == <<0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10>> ``` diff --git a/exercises/concept/guessing-game/.docs/introduction.md b/exercises/concept/guessing-game/.docs/introduction.md index 543f06af11..cfc100cfab 100644 --- a/exercises/concept/guessing-game/.docs/introduction.md +++ b/exercises/concept/guessing-game/.docs/introduction.md @@ -10,6 +10,7 @@ Elixir offers _multiple function clauses_ and _guards_ to write: def number(n) when n == 7 do "Awesome, that's my favorite" end + def number(_n) do "That's not my favorite" end diff --git a/exercises/concept/high-school-sweetheart/.docs/introduction.md b/exercises/concept/high-school-sweetheart/.docs/introduction.md index ccf6c17810..a37c58e8ac 100644 --- a/exercises/concept/high-school-sweetheart/.docs/introduction.md +++ b/exercises/concept/high-school-sweetheart/.docs/introduction.md @@ -48,5 +48,6 @@ The `|>` operator is called the pipe operator. It can be used to chain function "hello" |> String.upcase() |> Kernel.<>("?!") + # => "HELLO?!" ``` diff --git a/exercises/concept/high-score/.docs/introduction.md b/exercises/concept/high-score/.docs/introduction.md index c479aee95f..ec6f7105c3 100644 --- a/exercises/concept/high-score/.docs/introduction.md +++ b/exercises/concept/high-score/.docs/introduction.md @@ -33,7 +33,6 @@ In Elixir, we can define module attributes which can be used as constants in our ```elixir defmodule Example do - # Defines the attribute as the value 1 @constant_number 1 diff --git a/exercises/concept/lasagna/.docs/introduction.md b/exercises/concept/lasagna/.docs/introduction.md index c1fb2b6cfd..903618685e 100644 --- a/exercises/concept/lasagna/.docs/introduction.md +++ b/exercises/concept/lasagna/.docs/introduction.md @@ -7,12 +7,16 @@ Elixir is a dynamically-typed language, meaning that the type of a variable is only checked at runtime. Using the match `=` operator, we can bind a value of any type to a variable name: ```elixir -count = 1 # Bound an integer value of 1 -count = 2 # You may re-bind variables +# Bound an integer value of 1 +count = 1 +# You may re-bind variables +count = 2 -count = false # You may re-bind any type to a variable +# You may re-bind any type to a variable +count = false -message = "Success!" # Strings can be created by enclosing characters within double quotes +# Strings can be created by enclosing characters within double quotes +message = "Success!" ``` ### Modules diff --git a/exercises/concept/newsletter/.docs/instructions.md b/exercises/concept/newsletter/.docs/instructions.md index 69653e3e97..1a59605dd1 100644 --- a/exercises/concept/newsletter/.docs/instructions.md +++ b/exercises/concept/newsletter/.docs/instructions.md @@ -52,5 +52,6 @@ Newsletter.send_newsletter( "newsletter_issue1_log.txt", fn email -> :ok end ) + # => :ok ``` diff --git a/exercises/concept/remote-control-car/.docs/instructions.md b/exercises/concept/remote-control-car/.docs/instructions.md index 7c7c2ac789..8d25d7f6fd 100644 --- a/exercises/concept/remote-control-car/.docs/instructions.md +++ b/exercises/concept/remote-control-car/.docs/instructions.md @@ -73,12 +73,12 @@ Implement the `RemoteControlCar.drive/1` function that: ```elixir RemoteControlCar.new("Red") |> RemoteControlCar.drive() + # => %RemoteControlCar{ # battery_percentage: 99, # distance_driven_in_meters: 20, # nickname: "Red" # } - ``` Make sure the function only accepts a `RemoteControlCar` struct as the argument. @@ -94,6 +94,7 @@ Update the `RemoteControlCar.drive/1` function to not increase the distance driv nickname: "Red" } |> RemoteControlCar.drive() + # => %RemoteControlCar{ # battery_percentage: 0, # distance_driven_in_meters: 1980, diff --git a/exercises/concept/rpn-calculator-inspection/.docs/instructions.md b/exercises/concept/rpn-calculator-inspection/.docs/instructions.md index b8cb78280c..f715e626c2 100644 --- a/exercises/concept/rpn-calculator-inspection/.docs/instructions.md +++ b/exercises/concept/rpn-calculator-inspection/.docs/instructions.md @@ -39,6 +39,7 @@ RPNCalculatorInspection.await_reliability_check_result( %{input: "5 7 -", pid: pid}, %{} ) + # => %{"5 7 -" => :ok} # when there are no messages in the process inbox @@ -46,6 +47,7 @@ RPNCalculatorInspection.await_reliability_check_result( %{input: "3 2 *", pid: pid}, %{"5 7 -" => :ok} ) + # => %{"5 7 -" => :ok, "3 2 *" => :timeout} ``` @@ -61,7 +63,7 @@ The function should return a map with the results of reliability checks of all t ```elixir fake_broken_calculator = fn input -> - if String.ends_with?(input, "*"), do: raise "oops" + if String.ends_with?(input, "*"), do: raise("oops") end inputs = ["2 3 +", "10 3 *", "20 2 /"] diff --git a/exercises/concept/rpn-calculator-output/.docs/introduction.md b/exercises/concept/rpn-calculator-output/.docs/introduction.md index 7f6b7d6328..e866ad96b4 100644 --- a/exercises/concept/rpn-calculator-output/.docs/introduction.md +++ b/exercises/concept/rpn-calculator-output/.docs/introduction.md @@ -20,6 +20,7 @@ else after :some_action end + # => :success ``` diff --git a/exercises/concept/rpn-calculator/.docs/introduction.md b/exercises/concept/rpn-calculator/.docs/introduction.md index 39d514da53..0daf260f7a 100644 --- a/exercises/concept/rpn-calculator/.docs/introduction.md +++ b/exercises/concept/rpn-calculator/.docs/introduction.md @@ -15,6 +15,8 @@ Map.fetch!(%{a: 1}, :b) Elixir provides a construct for rescuing from errors using `try .. rescue` +[]: # (elixir-formatter-disable-next-block) + ```elixir try do #1 raise RuntimeError, "error" #2 diff --git a/exercises/concept/stack-underflow/.docs/introduction.md b/exercises/concept/stack-underflow/.docs/introduction.md index 449b84a429..8a2c27022d 100644 --- a/exercises/concept/stack-underflow/.docs/introduction.md +++ b/exercises/concept/stack-underflow/.docs/introduction.md @@ -30,6 +30,7 @@ defmodule MyCustomizedError do case value do [] -> %MyCustomizedError{} + _ -> %MyCustomizedError{message: "Alert: " <> value} end diff --git a/exercises/concept/take-a-number-deluxe/.docs/instructions.md b/exercises/concept/take-a-number-deluxe/.docs/instructions.md index b4fec99a98..ef3b222e0f 100644 --- a/exercises/concept/take-a-number-deluxe/.docs/instructions.md +++ b/exercises/concept/take-a-number-deluxe/.docs/instructions.md @@ -113,11 +113,12 @@ Implement a `GenServer` callback to handle the `:timeout` message that will be s Make sure to also handle any unexpected messages by ignoring them. ```elixir -{:ok, machine} = TakeANumberDeluxe.start_link( - min_number: 1, - max_number: 10, - auto_shutdown_timeout: :timer.hours(2) -) +{:ok, machine} = + TakeANumberDeluxe.start_link( + min_number: 1, + max_number: 10, + auto_shutdown_timeout: :timer.hours(2) + ) # after 3 hours... diff --git a/exercises/concept/take-a-number/.docs/instructions.md b/exercises/concept/take-a-number/.docs/instructions.md index 901219e175..ad6bbaaffc 100644 --- a/exercises/concept/take-a-number/.docs/instructions.md +++ b/exercises/concept/take-a-number/.docs/instructions.md @@ -24,6 +24,7 @@ send(machine_pid, {:report_state, self()}) receive do msg -> msg end + # => 0 ``` @@ -38,6 +39,7 @@ send(machine_pid, {:take_a_number, self()}) receive do msg -> msg end + # => 1 ``` diff --git a/exercises/concept/wine-cellar/.docs/instructions.md b/exercises/concept/wine-cellar/.docs/instructions.md index de3cf0548e..f109e5f471 100644 --- a/exercises/concept/wine-cellar/.docs/instructions.md +++ b/exercises/concept/wine-cellar/.docs/instructions.md @@ -41,6 +41,7 @@ WineCellar.filter( ], :white ) + # => [ # {"Chardonnay", 2015, "Italy"}, # {"Pinot grigio", 2017, "Germany"} @@ -64,6 +65,7 @@ WineCellar.filter( :white, year: 2015 ) + # => [ # {"Chardonnay", 2015, "Italy"} # ] @@ -89,5 +91,6 @@ WineCellar.filter( year: 2015, country: "Germany" ) + # => [] ``` diff --git a/exercises/practice/leap/.approaches/clauses/content.md b/exercises/practice/leap/.approaches/clauses/content.md index 03601d59f1..809c319859 100644 --- a/exercises/practice/leap/.approaches/clauses/content.md +++ b/exercises/practice/leap/.approaches/clauses/content.md @@ -18,6 +18,8 @@ While in the [operators approach][operators-approach], it was possible to reorde In our case, the three guards in the function clauses are as follows: +[]: # (elixir-formatter-disable-next-block) + ```elixir when rem(year, 400) == 0 when rem(year, 100) == 0 @@ -26,6 +28,8 @@ when rem(year, 4) == 0 But because of the order they are evaluated in, they are equivalent to: +[]: # (elixir-formatter-disable-next-block) + ```elixir when rem(year, 400) == 0 when rem(year, 100) == 0 and not rem(year, 400) == 0 diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md index be5e0faaaa..a3e7432059 100644 --- a/exercises/practice/leap/.approaches/introduction.md +++ b/exercises/practice/leap/.approaches/introduction.md @@ -29,7 +29,7 @@ A year is a leap year if We can use [boolean operators][boolean-operators] to combine the checks, for example, like so: ```elixir -rem(year, 5) == 0 and not rem(year, 100) == 0 or rem(year, 400) == 0 +(rem(year, 5) == 0 and not rem(year, 100) == 0) or rem(year, 400) == 0 ``` In the [boolean operators approach][operators-approach] we discuss the details of the solution. It includes variations of the operators and their precedence. diff --git a/exercises/practice/leap/.approaches/operators/content.md b/exercises/practice/leap/.approaches/operators/content.md index 1b43836f66..e7ff2ab29f 100644 --- a/exercises/practice/leap/.approaches/operators/content.md +++ b/exercises/practice/leap/.approaches/operators/content.md @@ -4,7 +4,7 @@ defmodule Year do @spec leap_year?(non_neg_integer) :: boolean def leap_year?(year) do - rem(year, 4) == 0 and not rem(year, 100) == 0 or rem(year, 400) == 0 + (rem(year, 4) == 0 and not rem(year, 100) == 0) or rem(year, 400) == 0 end end ``` @@ -25,6 +25,8 @@ However, if `left` is *false*, `right` has to be evaluated to determine the outc ## Precedence of operators +[]: # (elixir-formatter-disable-next-block) + Another thing to consider when using Boolean operators is their precedence. ```elixir true or false and false @@ -51,7 +53,7 @@ The relaxed versions `!`, `&&`, `||` require the first argument to be only [trut In the case of this exercise, both types will work equally well, so the solution could be: ```elixir def leap_year?(year) do - rem(year, 4) == 0 && !(rem(year, 100) == 0) || rem(year, 400) == 0 + (rem(year, 4) == 0 && !(rem(year, 100) == 0)) || rem(year, 400) == 0 end ``` @@ -60,7 +62,7 @@ end The `leap_year?` function could be written like so: ```elixir def leap_year?(year) do - rem(year, 4) == 0 and not rem(year, 100) == 0 or rem(year, 400) == 0 + (rem(year, 4) == 0 and not rem(year, 100) == 0) or rem(year, 400) == 0 end ``` @@ -71,7 +73,7 @@ We are explicitly checking the reminder, comparing it to zero. defp divides?(number, divisor), do: rem(number, divisor) == 0 def leap_year?(year) do - divides?(year, 4) and not divides?(year, 100) or divides?(year, 400) + (divides?(year, 4) and not divides?(year, 100)) or divides?(year, 400) end ``` @@ -87,7 +89,7 @@ def leap_year?(year) do by4? = divides?(year, 4) by100? = divides?(year, 100) by400? = divides?(year, 400) - by4? and not by100? or by400? + (by4? and not by100?) or by400? end ``` @@ -95,4 +97,4 @@ All versions of the code will work. Which one to choose is often a personal or s [hexdocs-booleans]: https://hexdocs.pm/elixir/basic-types.html#booleans-and-nil [hexdocs-truthy]: https://hexdocs.pm/elixir/Kernel.html#module-truthy-and-falsy-values -[exercism-booleans]: https://exercism.org/tracks/elixir/concepts/booleans \ No newline at end of file +[exercism-booleans]: https://exercism.org/tracks/elixir/concepts/booleans diff --git a/exercises/practice/zipper/hints/hint_3.md b/exercises/practice/zipper/hints/hint_3.md index 3d84b9781e..ffc95db4a9 100644 --- a/exercises/practice/zipper/hints/hint_3.md +++ b/exercises/practice/zipper/hints/hint_3.md @@ -1,15 +1,16 @@ # hint 3 ```elixir -@type trail :: { :left, any, BinTree.t, trail } - | { :right, any, BinTree.t, trail } - | :top +@type trail :: + {:left, any, BinTree.t(), trail} + | {:right, any, BinTree.t(), trail} + | :top ``` or ```elixir -@type trail :: [ { :left, any, BinTree.t } | { :right, any, BinTree.t } ] +@type trail :: [{:left, any, BinTree.t()} | {:right, any, BinTree.t()}] ``` The immediate parent should be the easiest to access. diff --git a/mix.exs b/mix.exs index 5dfe338a0c..f55ae19d19 100644 --- a/mix.exs +++ b/mix.exs @@ -23,6 +23,9 @@ defmodule ExercismTestRunner.Mixfile do end defp deps do - [{:dialyxir, "~> 1.3.0", runtime: false}] + [ + {:dialyxir, "~> 1.3.0", runtime: false}, + {:markdown_code_block_formatter, "~> 0.1.0", runtime: false} + ] end end diff --git a/mix.lock b/mix.lock index 1d5ea5427f..2ee642d82c 100644 --- a/mix.lock +++ b/mix.lock @@ -1,4 +1,5 @@ %{ "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "markdown_code_block_formatter": {:hex, :markdown_code_block_formatter, "0.1.0", "1eb35408f0ce2cbd40086fea5bbb2aebbb4805ffc2c967f9e54aa724fa4bd222", [:mix], [], "hexpm", "ce27a7c7497074c48941c1d74ab9c39a08db31f2875b867c6d5671d7d70682b0"}, }