Skip to content

Commit

Permalink
finishes example functionality #21
Browse files Browse the repository at this point in the history
  • Loading branch information
jackcarlisle committed Feb 10, 2017
1 parent ccb00fd commit 1e3c3f0
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 26 deletions.
101 changes: 89 additions & 12 deletions README.md
Expand Up @@ -566,32 +566,109 @@ end
mark after the name of the method.**

6. Pattern matching example: Let's create a function that takes a list of animals and
the number of animals you've seen and then returns the list of animals you have
still to see.
the number of animals that you'd like to see and then returns a list of animals.

```elixir
@doc """
remaining takes a list of zoo animals and the number of animals that
have already been viewed and returns a list of animals that you have left
to see
see_animals takes a list of zoo animals and the number of animals that
you want to see and then returns a list
## Examples
iex> zoo = Animals.create_zoo
iex> Animals.remaining(zoo, 2)
["gorilla", "elephant", "monkey", "giraffe"]
iex> Animals.see_animals(zoo, 2)
["monkey", "giraffe"]
"""
def remaining(zoo, count) do
def see_animals(zoo, count) do
# Enum.split returns a tuple so we have to pattern match on the result
# to get the value we want out
# The underscore before the "seen" means that we don't care about the value
# If this was left out then elixir would give a warning saying "seen" has
# not been used
{_seen, to_see} = Enum.split(zoo, count)
{_seen, to_see} = Enum.split(zoo, -count)
to_see
end
```

7. What if we want to save our list of animals to a file? Let's write a function
that will do this for us:

```elixir
@doc """
save takes a list of zoo animals and a filename and saves the list to that file
## Examples
iex> zoo = Animals.create_zoo
iex> Animals.save(zoo, "my_animals")
:ok
"""
def save(zoo, filename) do
# erlang is converting the zoo list to something that can be written to the
# file system
binary = :erlang.term_to_binary(zoo)
File.write(filename, binary)
end
```

In your command line run the following:

```bash
> zoo = Animals.create_zoo
> Animals.save(zoo, "my_animals")
```
This will create a new file in your file tree with the name of the file that
you specified in the function. It will contain some odd characters for example this
is what gets returned for our animals file:

`�lmlionmtigermgorillamelephantmmonkeymgiraffej`

8. Now let's write a function that will allow us to access that information again:

```elixir
@doc """
load takes filename and returns a list of animals if the file exists
## Examples
iex> Animals.load("my_animals")
["lion", "tiger", "gorilla", "elephant", "monkey", "giraffe"]
"""
def load(filename) do
# here we are running a case expression on the result of File.read(filename)
# if we receive an :ok then we want to return the list
# if we receive an error then we want to give the user an error-friendly message
case File.read(filename) do
{:ok, binary} -> :erlang.binary_to_term(binary)
{:error, _reason} -> "File does not exist"
end
end
```

9. Pipe Operator. What if we wanted to call some of our functions in succession
to another. Let's create a function that creates a zoo, randomises it and then
returns a selected number of animals to go and see:

```elixir
@doc """
selection takes a number, creates a zoo, randomises it and then returns a list
of animals of length selected
## Examples
iex> Animals.selection(2)
["gorilla", "giraffe"]
"""
def selection(number_of_animals) do
# We are using the pipe operator here. It takes the value returned from
# the expression and passes it down as the first argument in the expression
# below. see_animals takes two arguments but only one needs to be specified
# as the first is provided by the pipe operator
Animals.create_zoo
|> Animals.randomise
|> Animals.see_animals(number_of_animals)
end
```

## Resources

+ Crash Course in Elixir: http://elixir-lang.org/crash-course.html
Expand Down
73 changes: 59 additions & 14 deletions examples/animals/animals.ex
Expand Up @@ -44,23 +44,68 @@ defmodule Animals do
Enum.member?(zoo, animal)
end

@doc """
see_animals takes a list of zoo animals and the number of animals that
you want to see and then returns a list
## Examples
iex> zoo = Animals.create_zoo
iex> Animals.see_animals(zoo, 2)
["monkey", "giraffe"]
"""
def see_animals(zoo, count) do
# Enum.split returns a tuple so we have to pattern match on the result
# to get the value we want out
{_seen, to_see} = Enum.split(zoo, -count)
to_see
end

@doc """
save takes a list of zoo animals and a filename and saves the list to that file
## Examples
iex> zoo = Animals.create_zoo
iex> Animals.save(zoo, "my_animals")
:ok
"""
def save(zoo, filename) do
# erlang is converting the zoo list to something that can be written to the
# file system
binary = :erlang.term_to_binary(zoo)
File.write(filename, binary)
end

@doc """
load takes filename and returns a list of animals if the file exists
@doc """
remaining takes a list of zoo animals and the number of animals that
have already been viewed and returns a list of animals that you have left
to see
## Examples
## Examples
iex> Animals.load("my_animals")
["lion", "tiger", "gorilla", "elephant", "monkey", "giraffe"]
iex> zoo = Animals.create_zoo
iex> Animals.remaining(zoo, 2)
["gorilla", "elephant", "monkey", "giraffe"]
"""
def remaining(zoo, count) do
# Enum.split returns a tuple so we have to pattern match on the result
# to get the value we want out
{_seen, to_see} = Enum.split(zoo, count)
to_see
"""
def load(filename) do
case File.read(filename) do
{:ok, binary} -> :erlang.binary_to_term(binary)
{:error, _reason} -> "File does not exist"
end
end

@doc """
selection takes a number, creates a zoo, randomises it and then returns a list
of animals of length selected
## Examples
iex> Animals.selection(2)
["gorilla", "giraffe"]
"""
def selection(number_of_animals) do
Animals.create_zoo
|> Animals.randomise
|> Animals.see_animals(number_of_animals)
end
end

0 comments on commit 1e3c3f0

Please sign in to comment.