Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assinment 3 #34

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 44 additions & 27 deletions ex01.exs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,35 @@ defmodule Ex01 do
2 is the program well laid out, appropriately using indentation,
blank lines, vertical alignment
"""

def counter(value \\ 0) do

receive do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-2 layout

please indent the block of code under the {:next, from} line.

{:next, from} ->
send from , {:next_is, value}
counter(value+1)
end
end


def new_counter(value) do
pid = spawn(Ex01, :counter, [value])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-2

This generates a warning

-1 layout

end


def next_value(from) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-2 layout

Layout is really an important part of programming, because it aids understanding.

send from , {:next, self}
receivemessg
end

def receivemessg do
receive do
{:next_is, value} -> value
end
end
end


ExUnit.start()

defmodule Test do
Expand All @@ -41,35 +64,29 @@ defmodule Test do
# This test assumes you have a function `counter` that can be spawned
# and which handles the `{:next, from}` message

# test "basic message interface" do
# count = spawn Ex01, :counter, []
# send count, { :next, self }
# receive do
# { :next_is, value } ->
# assert value == 0
# end
#
# send count, { :next, self }
# receive do
# { :next_is, value } ->
# assert value == 1
# end
# end
test "basic message interface" do
count = spawn Ex01, :counter, []
send count, { :next, self }
receive do
{ :next_is, value } ->
assert value == 0
end

send count, { :next, self }
receive do
{ :next_is, value } ->
assert value == 1
end
end

# then uncomment this one
# Now we add two new functions to Ex01 that wrap the use of
# that counter function, making the overall API cleaner

# test "higher level API interface" do
# count = Ex01.new_counter(5)
# assert Ex01.next_value(count) == 5
# assert Ex01.next_value(count) == 6
# end

end





test "higher level API interface" do
count = Ex01.new_counter(5)
assert Ex01.next_value(count) == 5
assert Ex01.next_value(count) == 6
end

end
68 changes: 47 additions & 21 deletions ex02.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@

defmodule Ex02 do

def start_link(value \\0) do
{:ok,count} = Agent.start_link(fn -> value end)
end

def new_counter(value) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-2 idiomatic

I'm not sure why you add an extra start_link function.

Also, your new_counter function returns {:ok, pid}, but the :ok is
not useful anywhere. It should rally just return the pid:

def new_counter(value) do
  {:ok,count} = Agent.start_link(fn -> value end)
  count
end

start_link(value)
end

def next_value({:ok,count}) do
localCount = Agent.get(count,&(&1))
Agent.update(count, &(&1+1))
localCount
end

def new_global_counter() do
Agent.start( fn -> 0 end, name: Global_count)
end

def global_next_value() do
localCount = Agent.get(Global_count, &(&1))
Agent.update(Global_count, &(&1+1))
localCount
end

end

ExUnit.start()
Expand All @@ -23,7 +47,8 @@ defmodule Test do
2 is the program well laid out, appropriately using indentation,
blank lines, vertical alignment
"""




@doc """
First uncomment this test. Here you will be inserting code
Expand All @@ -32,26 +57,27 @@ defmodule Test do
Replace the placeholders with your code.
"""

# test "counter using an agent" do
# { :ok, counter } = « your code »
#
# value = « your code »
# assert value == 0
#
# value = « your code »
# assert value == 1
# end


test "counter using an agent" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-5

This code contains a race condition, because it does a get followed by an update. Imagine two processes getting the next value at the same time. Both do a get, and both receive the same value.

{ :ok, counter } = Agent.start_link(fn -> 0 end)
value = Agent.get(counter, &(&1))
assert value == 0
Agent.update(counter, &(&1)+1)
value = Agent.get(counter, &(&1))
assert value == 1
end

@doc """
Next, uncomment this test, and add code to the Ex02 module at the
top of this file to make those tests run.
"""

# test "higher level API interface" do
# count = Ex02.new_counter(5)
# assert Ex02.next_value(count) == 5
# assert Ex02.next_value(count) == 6
# end
test "higher level API interface" do
count = Ex02.new_counter(5)
assert Ex02.next_value(count) == 5
assert Ex02.next_value(count) == 6
end

@doc """
Last (for this exercise), we'll create a global counter by adding
Expand All @@ -60,12 +86,12 @@ defmodule Test do
that agent into calls to `global_next_value`?
"""

# test "global counter" do
# Ex02.new_global_counter
# assert Ex02.global_next_value == 0
# assert Ex02.global_next_value == 1
# assert Ex02.global_next_value == 2
# end
test "global counter" do
Ex02.new_global_counter
assert Ex02.global_next_value == 0
assert Ex02.global_next_value == 1
assert Ex02.global_next_value == 2
end
end


Expand Down
26 changes: 18 additions & 8 deletions ex03.exs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ defmodule Ex03 do

Pragmatics
4 does the code compile and run
5 does it produce the correct results on any valid data
5 does it produce the correct results on any valid data

Tested
if tests are provided as part of the assignment:
5 all pass
if tests are provided as part of the assignment:
5 all pass

Aesthetics
4 is the program written in an idiomatic style that uses
Expand All @@ -58,10 +58,20 @@ defmodule Ex03 do
5 elegant use of language features or libraries

"""
def pmap(collection, process_count, function) do

def pmap(collection, process_count, function) do
« your code here »
end
count_value = Enum.count(collection)/process_count
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-4 idiomatic

You should use pipelines, rather than temporary variables here.

float_count = Float.ceil(count_value)
count = round(float_count)

# Returns list containing count items

list = Enum.chunk(collection, count, count,[])
new_list = Enum.map(list, fn value -> Task.async(fn -> Enum.map(value, function) end) end)
list = Enum.map(new_list, fn value -> Task.await(value) end)
Enum.concat(list)

end

end

Expand Down Expand Up @@ -96,5 +106,5 @@ defmodule TestEx03 do
assert result2 == result1
assert time2 < time1 * 0.8
end
end

end