Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
julienXX committed Aug 4, 2013
0 parents commit ba086ca
Show file tree
Hide file tree
Showing 216 changed files with 3,715 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Exercices from the book Programming Elixir: Functional |> Concurrent |> Pragmatic |> Fun by Dave Thomas
11 changes: 11 additions & 0 deletions control/case.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
case File.open("case.ex") do

{ :ok, file } ->
IO.puts "First line: #{IO.read(file, :line)}"

{ :error, reason } ->
IO.puts "Failed to open file: #{reason}"

end


19 changes: 19 additions & 0 deletions control/case1.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defrecord Person, name: "", state: nil, likes: "nothing" do
def as_string(record) do
"#{record.name} lives in #{record.state} and likes #{record.likes}"
end
end

defmodule Users do
dave = Person.new name: "Dave", state: "TX", likes: "programming"

case dave do

Person[state: "TX"] = record ->
IO.puts Person.as_string record

_ ->
IO.puts "No matches"

end
end
16 changes: 16 additions & 0 deletions control/case2.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defrecord Person, name: "", age: 0

defmodule Bouncer do

dave = Person.new name: "Dave", age: 27

case dave do

record = Person[age: age] when is_number(age) and age >= 21 ->
IO.puts "You are cleared to enter the Foo Bar, #{record.name}"

_ ->
IO.puts "Sorry, no admission"

end
end
4 changes: 4 additions & 0 deletions control/case3.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
case 1 do
x when x > 1 -> IO.puts "1"
x when x > 0 -> IO.puts "2"
end
21 changes: 21 additions & 0 deletions control/fizzbuzz.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule FizzBuzz do

def upto(n) when n > 0, do: _upto(1, n, [])

defp _upto(_current, 0, result), do: Enum.reverse result

defp _upto(current, left, result) do
next_answer =
cond do
rem(current, 3) == 0 and rem(current, 5) == 0 ->
"FizzBuzz"
rem(current, 3) == 0 ->
"Fizz"
rem(current, 5) == 0 ->
"Buzz"
true ->
current
end
_upto(current+1, left-1, [ next_answer | result ])
end
end
21 changes: 21 additions & 0 deletions control/fizzbuzz1.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule FizzBuzz do

def upto(n) when n > 0, do: _downto(n, [])

defp _downto(0, result), do: result

defp _downto(current, result) do
next_answer =
cond do
rem(current, 3) == 0 and rem(current, 5) == 0 ->
"FizzBuzz"
rem(current, 3) == 0 ->
"Fizz"
rem(current, 5) == 0 ->
"Buzz"
true ->
current
end
_downto(current-1, [ next_answer | result ])
end
end
19 changes: 19 additions & 0 deletions control/fizzbuzz2.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule FizzBuzz do

def upto(n) when n > 0 do
1..n |> Enum.map(&fizzbuzz/1)
end

defp fizzbuzz(n) do
cond do
rem(n, 3) == 0 and rem(n, 5) == 0 ->
"FizzBuzz"
rem(n, 3) == 0 ->
"Fizz"
rem(n, 5) == 0 ->
"Buzz"
true ->
n
end
end
end
12 changes: 12 additions & 0 deletions control/fizzbuzz3.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule FizzBuzz do

def upto(n) when n > 0 do
1..n |> Enum.map(&fizzbuzz/1)
end

defp fizzbuzz(n) when rem(n, 3) == 0 and rem(n, 5) == 0, do: "FizzBuzz"
defp fizzbuzz(n) when rem(n, 3) == 0, do: "Fizz"
defp fizzbuzz(n) when rem(n, 5) == 0, do: "Buzz"
defp fizzbuzz(n), do: n

end
Binary file added enum/Elixir.Seq.beam
Binary file not shown.
3 changes: 3 additions & 0 deletions enum/longest_line.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
IO.puts File.read!("/usr/share/dict/words")
|> String.split
|> Enum.max(&String.length/1)
5 changes: 5 additions & 0 deletions enum/pipeline.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[ 1, 2, 3, 4, 5 ]
|> Enum.map(&(&1*&1))
|> Enum.with_index
|> Enum.map(fn {value, index} -> value - index end)
|> IO.inspect #=> [1,3,7,13,21]
5 changes: 5 additions & 0 deletions enum/stream1.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[1,2,3,4]
|> Stream.map(&(&1*&1))
|> Stream.map(&(&1+1))
|> Stream.filter(fn x -> rem(x,2) == 1 end)
|> Enum.to_list
3 changes: 3 additions & 0 deletions enum/stream2.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
IO.puts File.open!("/usr/share/dict/words")
|> IO.stream
|> Enum.max(&String.length/1)
25 changes: 25 additions & 0 deletions exceptions/catch.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule Catch do

def start(n) do
try do
incite(n)
catch
:exit, code -> "Exited with code #{inspect code}"
:throw, value -> "throw called with #{inspect value}"
what, value -> "Caught #{inspect what} with #{inspect value}"
end
end


defp incite(1) do
exit(99)
end

defp incite(2) do
throw {:animal, "wombat"}
end

defp incite(3) do
:erlang.error "Oh no!"
end
end
25 changes: 25 additions & 0 deletions exceptions/defexception.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defexception KinectProtocolError,
message: "Kinect protocol error",
can_retry: false
do
def full_message(me) do
"Kinect failed: #{me.message}, retriable: #{me.can_retry}"
end
end

defmodule B do

def talk_to_kinect, do: raise KinectProtocolError, message: "usb unplugged", can_retry: true
def schedule_retry, do: IO.puts "Retrying in 10 seconds"

def start do
try do
talk_to_kinect
rescue
error in [KinectProtocolError] ->
IO.puts error.full_message
if error.can_retry, do: schedule_retry
end
end
end

37 changes: 37 additions & 0 deletions exceptions/exception.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule Boom do

def start(n) do
try do
raise_error(n)
rescue
[ FunctionClauseError, RuntimeError ] ->
IO.puts "no function match or runtime error"
error in [ArithmeticError] ->
IO.puts "Uh, oh! Arithmetic error: #{error.message}"
raise error, [ message: "too late, we're doomed"], System.stacktrace
other_errors ->
IO.puts "Disaster! #{other_errors.message}"
after
IO.puts "DONE!"
end
end

defp raise_error(0) do
IO.puts "No error"
end

defp raise_error(1) do
IO.puts "About to divide by zero"
1 / 0
end

defp raise_error(2) do
IO.puts "About to call a function that doesn't exist"
raise_error(99)
end

defp raise_error(3) do
IO.puts "About to try creating a directory with no permission"
File.mkdir!("/not_allowed")
end
end
6 changes: 6 additions & 0 deletions first_steps/handle_open.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
handle_open = function do
{:ok, file} -> "First line: #{IO.read(file, :line)}"
{_, error} -> "Error: #{:file.format_error(error)}"
end
IO.puts handle_open.(File.open("Rakefile")) # call with a file that exists
IO.puts handle_open.(File.open("nonexistent")) # and then with one that doesn't
1 change: 1 addition & 0 deletions intro/hello.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
IO.puts "Hello, World!"
4 changes: 4 additions & 0 deletions lists/mylist.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
defmodule MyList do
def len([]), do: 0
def len([head|tail]), do: 1 + len(tail)
end
14 changes: 14 additions & 0 deletions lists/mylist1.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule MyList do
def len([]), do: 0
def len([_head | tail]), do: 1 + len(tail)

def square([]), do: []
def square([ head | tail ]), do: [ head*head | square(tail) ]

def add_1([]), do: []
def add_1([ head | tail ]), do: [ head+1 | add_1(tail) ]

def map([], _func), do: []
def map([ head | tail ], func), do: [ func.(head) | map(tail, func) ]

end
5 changes: 5 additions & 0 deletions lists/played.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
matches = [ { :leeds, :liverpool }, { :leeds, :man_city }, { :liverpool, :man_city }, { :liverpool, :stoke },
{ :westbrom, :liverpool }, { :westbrom, :leeds } ]

lc { home, _ } inlist matches, { _, away } inlist matches, do: { home, away }

9 changes: 9 additions & 0 deletions lists/reduce.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule MyList do
def reduce([], value, _) do
value
end
def reduce([head | tail], value, fun) do
reduce(tail, fun.(head, value), fun)
end
end

30 changes: 30 additions & 0 deletions lists/reduce1.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule MyList do

@type element :: any
@type value :: any
@type collection :: [ element ]

@doc """
Takes a list, an accumulator value, and a function. Applies the function
to each element of the list in turn, also passing it the current accumulator
value. The value returned by the function becomes the new accumulator.
Returns the final value of the accumulator.
## Examples
iex> MyList.reduce([1,2,3,4,5], 0, &(&1 + &2))
15
iex> MyList.reduce([1,2,3,4,5], 1, &(&1 * &2))
120
"""
@spec reduce(collection, value, (element,value -> value)) :: value

def reduce([head | tail], value, fun) do
reduce(tail, fun.(head, value), fun)
end
def reduce([], value, _) do
value
end
end

5 changes: 5 additions & 0 deletions lists/sum.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule MyList do
def sum([], total), do: total
def sum([ head | tail ], total), do: sum(tail, head+total)
end

5 changes: 5 additions & 0 deletions lists/sum1.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule MyList do
def sum([], total // 0) do total end
def sum([ head | tail ], total // 0) do sum(tail, head+total) end
end

9 changes: 9 additions & 0 deletions lists/sum2.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule MyList do

def sum(list), do: _sum(list, 0)

# private methods
defp _sum([], total), do: total
defp _sum([ head | tail ], total), do: _sum(tail, head+total)
end

7 changes: 7 additions & 0 deletions lists/swap.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule Swapper do

def swap([]), do: []
def swap([ a, b | tail ]), do: [ b, a | swap(tail) ]
def swap([_]), do: raise "Can't swap a list with an odd number of elements"

end
24 changes: 24 additions & 0 deletions lists/weather.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule WeatherHistory do

def test_data do
[
[1366225622, 26, 15, 0.125],
[1366225622, 27, 15, 0.45],
[1366225622, 28, 21, 0.25],
[1366229222, 26, 19, 0.081],
[1366229222, 27, 17, 0.468],
[1366229222, 28, 15, 0.60],
[1366232822, 26, 22, 0.095],
[1366232822, 27, 21, 0.05],
[1366232822, 28, 24, 0.03],
[1366236422, 26, 17, 0.025]
]
end

def for_location_27([]), do: []
def for_location_27([ [time, 27, temp, rain ] | tail]) do
[ [time, 27, temp, rain] | for_location_27(tail) ]
end
def for_location_27([ _ | tail]), do: for_location_27(tail)

end
Loading

0 comments on commit ba086ca

Please sign in to comment.