diff --git a/README.md b/README.md index 0b84d9d..16f21bc 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,8 @@ Once you have it cloned, open the `index.html` file to view the presentation. At Tests are provided for the exercises as well as some of the examples. Uncomment them if necessary and run all tests with `$ mix test` in the root folder. -## Take Home Exercise -TODO - -## Recommended Reading -- Pattern Matching In Elixir -- elixir-lang.org getting started guide -- Programming Elixir (paid) -- Elementary Elixir, cool stuff including running code on coworkers machine +## Further Reading +- [Elixir Getting Started Guide](http://elixir-lang.org/getting-started/introduction.html) +- [Elixir School](http://elixirschool.com/) +- [Pattern Matching In Elixir](https://quickleft.com/blog/pattern-matching-elixir/) +- [Programming Elixir (paid)](https://pragprog.com/book/elixir12/programming-elixir-1-2) diff --git a/index.html b/index.html index 54dd826..8973e45 100644 --- a/index.html +++ b/index.html @@ -43,16 +43,22 @@
-

Elixir Basics Workshop

-

Workshop given at Boulder Elixir on January 28th, 2016.

-
+

Welcome To Boulder Elixir!

+

To get set up:

+

+#1 (optional)
+# You can fork the repo first if you'd like, so it's your own copy
+# url: github.com/boulder-elixir/elixir-basics-workshop
 
-        
-

Preliminary Questions

-
    -
  • Format: workshops, presentations, both?
  • -
  • Timing: last Thursday of every month?
  • -
+#2 Clone the repo +git clone + https://github.com/boulder-elixir/elixir-basics-workshop.git + +#3 Open the project in your text editor + +#4 Open your terminal and navigate to the project folder +
+

Ask if you need help!

@@ -66,6 +72,15 @@

Why Elixir?

  • High up-time
  • Hot code reloading
  • Runs on BEAM (Erlang), 30 years battle tested
  • +
  • Over 2 Million Concurrent Connections
  • + +
    + +
    +

    Meetup Format & Timing

    +
    @@ -75,7 +90,7 @@

    Workshop Goals

  • Learn basic syntax & how to work with Elixir
  • Be able to solve simple problems
  • Be exposed to Elixir's core features
  • -
  • Be inspired to go home and learn more
  • +
  • Be inspired to go home and learn more
  • @@ -129,7 +144,7 @@

    Pattern Matching

    -

    Exercise

    +

    Exercise 1

    1. Load iex
    2. Assign 42 to a single variable
    3. @@ -137,11 +152,12 @@

      Exercise

    4. Try to assign values to the tuple {:ok, value, message} that DON'T pattern match

    -

    -

    Take 5 minutes. Josh and I will be walking around. If you have a question, raise your hand.

    +

    Take 5 minutes. Josh and I will be walking around.

    +

    If you have a question, raise your hand or ask your neighbor.

    -

    Exercise Answer

    +

    Exercise 1 Answer

    
     iex> value = 42
     42
    @@ -193,18 +209,15 @@ 

    Case Statements With Pattern Matching

    -

    Exercise

    +

    Exercise 2

    1. Write a case statement that handles the tuples {:ok, 42} and {:error, nil}.
    2. Add a catch-all condition (underscore)
    -

    -

    -

    Take 10 minutes. Josh and I will be walking around.

    -

    If you have a question, raise your hand or ask your neighbor.

    -

    Exercise Answer

    +

    Exercise 2 Answer

    
     iex> case {:ok, 42} do
     ...>   {:ok, value} -> value
    @@ -292,29 +305,26 @@ 

    Pipe Character

    Similar to Unix pipe

    Takes output of first function and passes as first argument to next function

    
    -iex(13)> Enum.map([1, 2, 3], fn x -> x + 1 end) |> Enum.take(1)
    -[2]
    +iex(13)> [1, 2, 3] |> Enum.take(1)
    +[1]
     
     # equivalent to
    -list = Enum.map([1, 2, 3], fn x -> x + 1 end)
    -Enum.take(list, 1)
    +iex(14)> Enum.take([1, 2, 3], 1)
    +[1]
               
    -

    Exercise

    +

    Exercise 3

    1. Combine two lists
    2. Use Enum.map to square this list of numbers: [1, 2, 3, 4]
    3. Using the code from #2 and the pipe character, square a list of numbers and then shuffle them using Enum.shuffle()
    -

    -

    -

    Take 5 minutes. Josh and I will be walking around.

    -

    If you have a question, raise your hand or ask your neighbor.

    -

    Exercise Answer

    +

    Exercise 3 Answer

    
     iex> [1, 2, 3] ++ [3, 4, 5]
     [1, 2, 3, 3, 4, 5]
    @@ -367,19 +377,17 @@ 

    Enum With Maps

    -

    Exercise

    +

    Exercise 4

    1. Given the map %{a: 1, b: 2}, add the element c: 3. Hint: Use Map.put(enum, key, value)
    2. Use Enum.filter(enum, function) to get all items in %{a: 3, b: 12, c: 9, d: 15} where value is greater than 10.
    3. Using pipes and Enum.take(enum, number), modify code in #1 to only return 1 item.

    Hint: Use {key, value} to extract the keys and values in your anonymous function

    -

    -

    -

    Take 10 minutes. Josh and I will be walking around.

    -

    Exercise Answer

    +

    Exercise 4 Answer

    
     iex> map = %{a: 3, b: 12, c: 9, d: 15}
     %{a: 3, b: 12, c: 9, d: 15}
    @@ -441,19 +449,17 @@ 

    Private Functions

    -

    Exercise

    +

    Exercise 5

    1. Add a sum function that sums every number in a list
    2. Uncomment the tests for sum in test/workshop_test.exs and make them pass

    Hint: use Enum.reduce(enum, 0, fn (num, accumulator))

    Run tests with mix test in console.

    -

    -

    -

    Take 10 minutes. Josh and I will be walking around.

    -

    Exercise Answer

    +

    Exercise 5 Answer

    
     def sum(list) do
       Enum.reduce(list, 0, fn (num, acc) -> num + acc end)
    @@ -483,33 +489,53 @@ 

    Pattern Matching With Functions

    -

    Exercise

    -

    Let's write a variation of FizzBuzz!

    +

    Function Guards

    +

    You can further restrict if a function is called with a guard clause

    +
    
    +# lib/workshop.exs
    +defmodule Workshop do
    +  ...
    +
    +  def guarded_divide(dividend, divisor) when divisor > 0 do
    +    dividend / divisor
    +  end
    +
    +end
    +          
    +
    + +
    +

    Exercise 6

    +

    Let's write FizzBuzz!

      -
    1. Write multiple versions of the function fizzbuzz
    2. -
    3. If called with 3, return "Fizz"
    4. -
    5. If called with 5, return "Buzz"
    6. -
    7. If called with anything else, simply return what was passed in
    8. +
    9. Write multiple versions of the function fizzbuzz(n)
    10. +
    11. If n is divisible by 3, return "Fizz"
    12. +
    13. If n is divisible by 5, return "Buzz"
    14. +
    15. If n is divisible by 3 and 5, return "FizzBuzz"
    16. +
    17. If n doesn't match any case above, simply return what was passed in

    Uncomment and run tests with mix test.

    -

    -

    -

    Take 10 minutes. Josh and I will be walking around.

    -

    If you have a question, raise your hand or ask your neighbor.

    +

    Hint: To check a remainder use rem(number, 3)

    +

    Hint: The first function defined is the first to match

    -

    Exercise Answer

    +

    Exercise 6 Answer

    
    -def fizzbuzz(3) do
    +def fizzbuzz(n) when rem(n, 3) == 0 and rem(n, 5) == 0 do
    +  "FizzBuzz"
    +end
    +
    +def fizzbuzz(n) when rem(n, 3) == 0 do
       "Fizz"
     end
     
    -def fizzbuzz(5) do
    +def fizzbuzz(n) when rem(n, 5) == 0 do
       "Buzz"
     end
     
    -def fizzbuzz(val) do
    -  val
    +def fizzbuzz(n) do
    +  n
     end
               
    @@ -643,7 +669,7 @@

    In iex

    -

    Exercise

    +

    Exercise 7

    Using recursion and pattern matching, write the function square_list which squares a list of numbers

    1. Define your base case (handle empty list)
    2. @@ -655,7 +681,7 @@

      Exercise

    -

    Exercise Answer

    +

    Exercise 7 Answer

    
     def square_list([]) do
       []
    @@ -674,9 +700,17 @@ 

    Discussion

    Other thoughts?

    +
    +

    Group Sites & Chat

    +

    GitHub: https://github.com/boulder-elixir

    +

    Elixir Slack Group, there's a #boulder channel

    +

    Feel free to message me at tracehelms

    +

    Sign Up: https://elixir-slackin.herokuapp.com/

    +
    +

    Next Time

    -

    Presentations: message me if you want to talk

    +

    Let me know if you want to give a presentation!

    diff --git a/lib/workshop.ex b/lib/workshop.ex index f6e885b..2f46420 100644 --- a/lib/workshop.ex +++ b/lib/workshop.ex @@ -18,6 +18,10 @@ defmodule Workshop do dividend / divisor end + def guarded_divide(dividend, divisor) when divisor > 0 do + dividend / divisor + end + def add_one([]) do [] end diff --git a/test/workshop_test.exs b/test/workshop_test.exs index fc7ba4f..b47b214 100644 --- a/test/workshop_test.exs +++ b/test/workshop_test.exs @@ -16,6 +16,14 @@ defmodule WorkshopTest do assert W.divide(4, 2) == 2.0 end + test "guarded divide doesn't let you divide by zero" do + assert_raise(FunctionClauseError, ~r/no function clause matching/, fn -> W.guarded_divide(2, 0) end) + end + + test "guarded divide divides two numbers" do + assert W.guarded_divide(4, 2) == 2.0 + end + test "add_one handles empty list" do assert W.add_one([]) == [] end @@ -39,10 +47,11 @@ defmodule WorkshopTest do # # test "fizzbuzz" do # assert W.fizzbuzz(3) == "Fizz" + # assert W.fizzbuzz(6) == "Fizz" # assert W.fizzbuzz(5) == "Buzz" - # - # assert W.fizzbuzz(15) == 15 - # assert W.fizzbuzz(0) == 0 + # assert W.fizzbuzz(10) == "Buzz" + # assert W.fizzbuzz(15) == "FizzBuzz" + # assert W.fizzbuzz(225) == "FizzBuzz" # assert W.fizzbuzz("a") == "a" # end #