From 8f5e61b910a47002c06e34c09503dc46e5d7bb9f Mon Sep 17 00:00:00 2001 From: kkirahvi Date: Mon, 30 Apr 2018 19:15:25 +0200 Subject: [PATCH 1/5] add alphabet characters generator --- .../printable_ascii_alphabet_character.ex | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 lib/orangeade/generator/printable_ascii_alphabet_character.ex diff --git a/lib/orangeade/generator/printable_ascii_alphabet_character.ex b/lib/orangeade/generator/printable_ascii_alphabet_character.ex new file mode 100644 index 0000000..357489c --- /dev/null +++ b/lib/orangeade/generator/printable_ascii_alphabet_character.ex @@ -0,0 +1,118 @@ +defmodule Orangeade.Generator.PrintableASCIIAphabetCharacter do + @moduledoc """ + Provides a function for creating a stream of ASCII alphabet characters. + """ + alias Caffeine.Stream + alias Orangeade.Generator.BoundNatural + alias Orangeade.Generator.PrintableASCIIAlphabetCharacter.Majuscule + alias Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule + + defmodule Majuscule do + @doc """ + Creates a stream of ASCII alphabet lowercase characters + + # Example + + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.Majuscule.stream(), + ...> 50) + 'XONEWENODTDIXCWMBIXFDMEPEUYHOIEWBCGVYTUVVYDQSHEMLB' + + """ + @spec stream() :: Caffeine.Stream.t() + def stream do + Caffeine.Stream.map(BoundNatural.stream(limit: length()), &to_majuscule/1) + end + + defp to_majuscule(n) do + n + lower_bound() + end + + defp length do + upper_bound() - lower_bound() + end + + def lower_bound do + ?A + end + + defp upper_bound do + ?Z + end + end + + defmodule Minuscule do + @doc """ + Creates a stream of ASCII alphabet lowercase characters + + # Example + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.Minuscule.stream(), + ...> 50) + 'onewenodtdixcwmbixfdmepeuyhoiewbcgvytuvvydqshemlbn' + + + """ + @spec stream() :: Caffeine.Stream.t() + def stream do + Caffeine.Stream.map(BoundNatural.stream(limit: length()), &to_minuscule/1) + end + + defp to_minuscule(n) do + n + lower_bound() + end + + def length do + upper_bound() - lower_bound() + end + + def lower_bound do + ?a + end + + defp upper_bound do + ?z + end + end + + @doc """ + Creates a stream of ASCII alphabet characters + + # Example + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.stream(), + ...> 50) + 'NeWeNoDtDiXcWmBiXfDmEpEuYhOiEwBcGvYtUvVyDqShEmLbNc' + + + """ + + @spec stream() :: Caffeine.Stream.t() + def stream do + base = BoundNatural.stream(limit: length()) + filter = BoundNatural.stream(limit: 2) + stream(base, filter) + end + + defp stream(base, filter) do + head = to_alphabet_character(Stream.head(base), Stream.head(filter)) + rest = fn -> stream(Stream.tail(base),Stream.tail(filter)) end + Caffeine.Stream.construct(head, rest) + end + + defp to_alphabet_character(base, filter) do + case filter do + 1 -> + base + Majuscule.lower_bound() + 0 -> + base + Minuscule.lower_bound() + end + end + + defp length do + Minuscule.length() + end + + + +end From 5d91a95413bb6d14c52d304b9e39af8e91b47364 Mon Sep 17 00:00:00 2001 From: kkirahvi Date: Mon, 30 Apr 2018 20:59:54 +0200 Subject: [PATCH 2/5] add atom generator --- lib/orangeade/generator/ascii_atom.ex | 50 +++++++++++++------ .../printable_ascii_alphabet_character.ex | 8 +-- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/orangeade/generator/ascii_atom.ex b/lib/orangeade/generator/ascii_atom.ex index d4a7e97..95c60ce 100644 --- a/lib/orangeade/generator/ascii_atom.ex +++ b/lib/orangeade/generator/ascii_atom.ex @@ -3,19 +3,19 @@ defmodule Orangeade.Generator.ASCIIAtom do Provides a function for creating a stream of ascii atoms. """ - alias Orangeade.Generator.ASCIIString - + alias Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule + alias Orangeade.Generator.BoundNatural + @doc """ Creates a stream of ascii atoms of max default length 10. ## Examples - iex(1)> s = Orangeade.Generator.ASCIIAtom.stream(max_word_length: 10) - [:! | #Function<1.23635164/0 in Caffeine.Stream.map/2>] - - iex(2)> Caffeine.Stream.take(s, 10) - [:!, :he, :"@E@?l{$w@", :"", :"7$O:!2[:-", :"", :LIB, :"G@[&!^7:", :"gp]f% W4S", - :"8qjg"] + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.ASCIIAtom.stream(), + ...> 10) + [:tmb, :segtesiutk, :x, :voyavicrif, :v, :alkx, :donewenox, :xibmwcxidt, :pemdf, + :ue] """ @spec stream() :: Caffeine.Stream.t() @@ -28,16 +28,38 @@ defmodule Orangeade.Generator.ASCIIAtom do ## Examples - iex(1)> s = Orangeade.Generator.ASCIIAtom.stream(max_word_length: 20) - [:! | #Function<1.23635164/0 in Caffeine.Stream.map/2>] + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.ASCIIAtom.stream(max_word_length: 20), + ...> 10) + [:segtesiutkt, :oyavicrifx, :v, :lkxv, :ibmwcxidtdonewenoxa, :hyuepemdfx, + :bweio, :sqdyvvutyvgc, :oasdodrbcnblmeh, :vrssfhhjsvlcbn] - iex(2)> Caffeine.Stream.take(s, 10) - [:!, :"he@E@?l{$w@7", :"$O:!2[:-LIBG@[&!^7:", :"gp]f% W4S8", :"qjgve,s@#", :"", - :"$}v", :"ul?B;(GLGZ_J9Ha>!B", :"%8#T]6q^i", :"D[hY"] """ @spec stream(max_word_length: non_neg_integer) :: Caffeine.Stream.t() def stream(max_word_length: l) do - Caffeine.Stream.map(ASCIIString.stream(max_word_length: l), &String.to_atom/1) + alphabet = Minuscule.stream() + lengths = BoundNatural.stream(limit: l) + stream(alphabet, lengths) + end + + defp stream(alphabet, lengths) do + {word, atail} = split(alphabet, Caffeine.Stream.head(lengths)) + rest = fn -> + stream(atail, Caffeine.Stream.tail(lengths)) end + Caffeine.Stream.construct(word, rest) + end + + defp split(alphabet, length) do + split([], length + 1, alphabet) + end + + defp split(word, 0, alphabet) do + {List.to_atom(word), alphabet} + end + + defp split(word, n, alphabet) do + split([Caffeine.Stream.head(alphabet)|word], n - 1, Caffeine.Stream.tail(alphabet)) end + end diff --git a/lib/orangeade/generator/printable_ascii_alphabet_character.ex b/lib/orangeade/generator/printable_ascii_alphabet_character.ex index 357489c..b786d4b 100644 --- a/lib/orangeade/generator/printable_ascii_alphabet_character.ex +++ b/lib/orangeade/generator/printable_ascii_alphabet_character.ex @@ -1,4 +1,4 @@ -defmodule Orangeade.Generator.PrintableASCIIAphabetCharacter do +defmodule Orangeade.Generator.PrintableASCIIAlphabetCharacter do @moduledoc """ Provides a function for creating a stream of ASCII alphabet characters. """ @@ -14,7 +14,7 @@ defmodule Orangeade.Generator.PrintableASCIIAphabetCharacter do # Example iex> Caffeine.Stream.take( - ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.Majuscule.stream(), + ...> Orangeade.Generator.PrintableASCIIAlphabetCharacter.Majuscule.stream(), ...> 50) 'XONEWENODTDIXCWMBIXFDMEPEUYHOIEWBCGVYTUVVYDQSHEMLB' @@ -47,7 +47,7 @@ defmodule Orangeade.Generator.PrintableASCIIAphabetCharacter do # Example iex> Caffeine.Stream.take( - ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.Minuscule.stream(), + ...> Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule.stream(), ...> 50) 'onewenodtdixcwmbixfdmepeuyhoiewbcgvytuvvydqshemlbn' @@ -80,7 +80,7 @@ defmodule Orangeade.Generator.PrintableASCIIAphabetCharacter do # Example iex> Caffeine.Stream.take( - ...> Orangeade.Generator.PrintableASCIIAphabetCharacter.stream(), + ...> Orangeade.Generator.PrintableASCIIAlphabetCharacter.stream(), ...> 50) 'NeWeNoDtDiXcWmBiXfDmEpEuYhOiEwBcGvYtUvVyDqShEmLbNc' From 80cdf4a72a0186b1c82e97b3c14c1d9ed1541d23 Mon Sep 17 00:00:00 2001 From: kkirahvi Date: Tue, 1 May 2018 14:01:20 +0200 Subject: [PATCH 3/5] tests for alphabet character and atom --- lib/orangeade/generator/ascii_atom.ex | 22 +++++++------- test/orangeade/generator/ascii_atom_test.exs | 12 +++++++- ...rintable_ascii_alphabet_character_test.exs | 29 +++++++++++++++++++ test/orangeade/generator/term_test.exs | 2 +- 4 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 test/orangeade/generator/printable_ascii_alphabet_character_test.exs diff --git a/lib/orangeade/generator/ascii_atom.ex b/lib/orangeade/generator/ascii_atom.ex index 95c60ce..b820dac 100644 --- a/lib/orangeade/generator/ascii_atom.ex +++ b/lib/orangeade/generator/ascii_atom.ex @@ -7,20 +7,19 @@ defmodule Orangeade.Generator.ASCIIAtom do alias Orangeade.Generator.BoundNatural @doc """ - Creates a stream of ascii atoms of max default length 10. + Creates a stream of ascii atoms of max default length 6. ## Examples - iex> Caffeine.Stream.take( - ...> Orangeade.Generator.ASCIIAtom.stream(), + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.ASCIIAtom.stream(), ...> 10) - [:tmb, :segtesiutk, :x, :voyavicrif, :v, :alkx, :donewenox, :xibmwcxidt, :pemdf, - :ue] + [:seg, :icrifx, :v, :voya, :kxv, :enoxal, :new, :xidtdo, :ibmwc, :pemdfx] """ @spec stream() :: Caffeine.Stream.t() def stream do - stream(max_word_length: 10) + stream(max_word_length: 6) end @doc """ @@ -28,12 +27,11 @@ defmodule Orangeade.Generator.ASCIIAtom do ## Examples - iex> Caffeine.Stream.take( - ...> Orangeade.Generator.ASCIIAtom.stream(max_word_length: 20), - ...> 10) - [:segtesiutkt, :oyavicrifx, :v, :lkxv, :ibmwcxidtdonewenoxa, :hyuepemdfx, - :bweio, :sqdyvvutyvgc, :oasdodrbcnblmeh, :vrssfhhjsvlcbn] - + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.ASCIIAtom.stream(max_word_length: 10), + ...> 10) + [:oyavicrif, :oxalkxvv, :wen, :done, :mwcxidt, :mdfxib, :yuepe, :yvgcbweioh, + :qdyvvut, :hs] """ @spec stream(max_word_length: non_neg_integer) :: Caffeine.Stream.t() diff --git a/test/orangeade/generator/ascii_atom_test.exs b/test/orangeade/generator/ascii_atom_test.exs index 20cc319..be13c33 100644 --- a/test/orangeade/generator/ascii_atom_test.exs +++ b/test/orangeade/generator/ascii_atom_test.exs @@ -4,9 +4,19 @@ defmodule Orangeade.Generator.ASCIIAtomTest do test "Check if first 10 generated elements are atoms" do list_of_elements = - ASCIIAtom.stream(max_word_length: 10) + ASCIIAtom.stream() |> Caffeine.Stream.take(10) assert Enum.all?(list_of_elements, &is_atom/1) end + + test "Check if atoms have default max word length not greater than 6" do + lengths_of_elements = + ASCIIAtom.stream() + |> Caffeine.Stream.take(10) + |> Enum.map(&Atom.to_charlist/1) + |> Enum.map(&length/1) + + refute Enum.any?(lengths_of_elements,fn e -> e > 6 end) + end end diff --git a/test/orangeade/generator/printable_ascii_alphabet_character_test.exs b/test/orangeade/generator/printable_ascii_alphabet_character_test.exs new file mode 100644 index 0000000..b535eb9 --- /dev/null +++ b/test/orangeade/generator/printable_ascii_alphabet_character_test.exs @@ -0,0 +1,29 @@ +defmodule Orangeade.Generator.PrintableASCIIAlphabetCharacterTest do + use ExUnit.Case + + test "Stream contains only alphabet characters" do + list = Orangeade.Generator.PrintableASCIIAlphabetCharacter.stream() + |> Caffeine.Stream.take(1_000) + + refute Enum.any?(list, fn e -> + e < ?A or (e > ?Z and e < ?a) or e > ?z end) + end + + test "Majuscule stream contains only uppercase characters" do + {min, max} = Orangeade.Generator.PrintableASCIIAlphabetCharacter.Majuscule.stream() + |> Caffeine.Stream.take(1_000) + |> Enum.min_max + + assert (?A <= min) and (max <= ?Z) + end + + + test "Minuscule stream contains only lowercase characters" do + {min, max} = Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule.stream() + |> Caffeine.Stream.take(1_000) + |> Enum.min_max + + assert (?a <= min) and (max <= ?z) + end + +end diff --git a/test/orangeade/generator/term_test.exs b/test/orangeade/generator/term_test.exs index fc8649c..3f43c1c 100644 --- a/test/orangeade/generator/term_test.exs +++ b/test/orangeade/generator/term_test.exs @@ -5,7 +5,7 @@ defmodule Orangeade.Generator.TermTest do test "Check if there are different data types in first 100 generated elements" do list_of_elements = Term.stream() - |> Caffeine.Stream.take(100) + |> Caffeine.Stream.take(200) list_of_conditions = [ Enum.any?(list_of_elements, &is_negative/1), From 579cdc8d881a5ac10741152931dbeab3e5468fb1 Mon Sep 17 00:00:00 2001 From: kkirahvi Date: Wed, 2 May 2018 18:17:11 +0200 Subject: [PATCH 4/5] fixing mudule names --- lib/orangeade/generator/atom.ex | 63 ++++++++++++++++++++++++++ test/orangeade/generator/atom_test.exs | 21 +++++++++ 2 files changed, 84 insertions(+) create mode 100644 lib/orangeade/generator/atom.ex create mode 100644 test/orangeade/generator/atom_test.exs diff --git a/lib/orangeade/generator/atom.ex b/lib/orangeade/generator/atom.ex new file mode 100644 index 0000000..a711264 --- /dev/null +++ b/lib/orangeade/generator/atom.ex @@ -0,0 +1,63 @@ +defmodule Orangeade.Generator.Atom do + @moduledoc """ + Provides a function for creating a stream of ascii atoms. + """ + + alias Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule + alias Orangeade.Generator.BoundNatural + + @doc """ + Creates a stream of ascii atoms of max default length 6. + + ## Examples + + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.Atom.stream(), + ...> 10) + [:seg, :icrifx, :v, :voya, :kxv, :enoxal, :new, :xidtdo, :ibmwc, :pemdfx] + + """ + @spec stream() :: Caffeine.Stream.t() + def stream do + stream(max_word_length: 6) + end + + @doc """ + Given a max word length creates a stream of ascii atoms. + + ## Examples + + iex> Caffeine.Stream.take( + ...> Orangeade.Generator.Atom.stream(max_word_length: 10), + ...> 10) + [:oyavicrif, :oxalkxvv, :wen, :done, :mwcxidt, :mdfxib, :yuepe, :yvgcbweioh, + :qdyvvut, :hs] + + """ + @spec stream(max_word_length: non_neg_integer) :: Caffeine.Stream.t() + def stream(max_word_length: l) do + alphabet = Minuscule.stream() + lengths = BoundNatural.stream(limit: l) + stream(alphabet, lengths) + end + + defp stream(alphabet, lengths) do + {word, atail} = split(alphabet, Caffeine.Stream.head(lengths)) + rest = fn -> + stream(atail, Caffeine.Stream.tail(lengths)) end + Caffeine.Stream.construct(word, rest) + end + + defp split(alphabet, length) do + split([], length + 1, alphabet) + end + + defp split(word, 0, alphabet) do + {List.to_atom(word), alphabet} + end + + defp split(word, n, alphabet) do + split([Caffeine.Stream.head(alphabet)|word], n - 1, Caffeine.Stream.tail(alphabet)) + end + +end diff --git a/test/orangeade/generator/atom_test.exs b/test/orangeade/generator/atom_test.exs new file mode 100644 index 0000000..6339321 --- /dev/null +++ b/test/orangeade/generator/atom_test.exs @@ -0,0 +1,21 @@ +defmodule Orangeade.Generator.AtomTest do + use ExUnit.Case + + test "Check if first 10 generated elements are atoms" do + list_of_elements = + Orangeade.Generator.Atom.stream() + |> Caffeine.Stream.take(10) + + assert Enum.all?(list_of_elements, &is_atom/1) + end + + test "Check if atoms have default max word length not greater than 6" do + lengths_of_elements = + Orangeade.Generator.Atom.stream() + |> Caffeine.Stream.take(10) + |> Enum.map(&Atom.to_charlist/1) + |> Enum.map(&length/1) + + refute Enum.any?(lengths_of_elements,fn e -> e > 6 end) + end +end From 742a9ec5b15bbe07cc86471d8db9908b80e0f931 Mon Sep 17 00:00:00 2001 From: kkirahvi Date: Wed, 2 May 2018 18:26:45 +0200 Subject: [PATCH 5/5] fixing module names --- lib/orangeade/generator/ascii_atom.ex | 54 ++++++-------------- test/orangeade/generator/ascii_atom_test.exs | 12 +---- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/lib/orangeade/generator/ascii_atom.ex b/lib/orangeade/generator/ascii_atom.ex index b820dac..d4a7e97 100644 --- a/lib/orangeade/generator/ascii_atom.ex +++ b/lib/orangeade/generator/ascii_atom.ex @@ -3,23 +3,24 @@ defmodule Orangeade.Generator.ASCIIAtom do Provides a function for creating a stream of ascii atoms. """ - alias Orangeade.Generator.PrintableASCIIAlphabetCharacter.Minuscule - alias Orangeade.Generator.BoundNatural - + alias Orangeade.Generator.ASCIIString + @doc """ - Creates a stream of ascii atoms of max default length 6. + Creates a stream of ascii atoms of max default length 10. ## Examples - iex> Caffeine.Stream.take( - ...> Orangeade.Generator.ASCIIAtom.stream(), - ...> 10) - [:seg, :icrifx, :v, :voya, :kxv, :enoxal, :new, :xidtdo, :ibmwc, :pemdfx] + iex(1)> s = Orangeade.Generator.ASCIIAtom.stream(max_word_length: 10) + [:! | #Function<1.23635164/0 in Caffeine.Stream.map/2>] + + iex(2)> Caffeine.Stream.take(s, 10) + [:!, :he, :"@E@?l{$w@", :"", :"7$O:!2[:-", :"", :LIB, :"G@[&!^7:", :"gp]f% W4S", + :"8qjg"] """ @spec stream() :: Caffeine.Stream.t() def stream do - stream(max_word_length: 6) + stream(max_word_length: 10) end @doc """ @@ -27,37 +28,16 @@ defmodule Orangeade.Generator.ASCIIAtom do ## Examples - iex> Caffeine.Stream.take( - ...> Orangeade.Generator.ASCIIAtom.stream(max_word_length: 10), - ...> 10) - [:oyavicrif, :oxalkxvv, :wen, :done, :mwcxidt, :mdfxib, :yuepe, :yvgcbweioh, - :qdyvvut, :hs] + iex(1)> s = Orangeade.Generator.ASCIIAtom.stream(max_word_length: 20) + [:! | #Function<1.23635164/0 in Caffeine.Stream.map/2>] + + iex(2)> Caffeine.Stream.take(s, 10) + [:!, :"he@E@?l{$w@7", :"$O:!2[:-LIBG@[&!^7:", :"gp]f% W4S8", :"qjgve,s@#", :"", + :"$}v", :"ul?B;(GLGZ_J9Ha>!B", :"%8#T]6q^i", :"D[hY"] """ @spec stream(max_word_length: non_neg_integer) :: Caffeine.Stream.t() def stream(max_word_length: l) do - alphabet = Minuscule.stream() - lengths = BoundNatural.stream(limit: l) - stream(alphabet, lengths) - end - - defp stream(alphabet, lengths) do - {word, atail} = split(alphabet, Caffeine.Stream.head(lengths)) - rest = fn -> - stream(atail, Caffeine.Stream.tail(lengths)) end - Caffeine.Stream.construct(word, rest) - end - - defp split(alphabet, length) do - split([], length + 1, alphabet) - end - - defp split(word, 0, alphabet) do - {List.to_atom(word), alphabet} - end - - defp split(word, n, alphabet) do - split([Caffeine.Stream.head(alphabet)|word], n - 1, Caffeine.Stream.tail(alphabet)) + Caffeine.Stream.map(ASCIIString.stream(max_word_length: l), &String.to_atom/1) end - end diff --git a/test/orangeade/generator/ascii_atom_test.exs b/test/orangeade/generator/ascii_atom_test.exs index be13c33..20cc319 100644 --- a/test/orangeade/generator/ascii_atom_test.exs +++ b/test/orangeade/generator/ascii_atom_test.exs @@ -4,19 +4,9 @@ defmodule Orangeade.Generator.ASCIIAtomTest do test "Check if first 10 generated elements are atoms" do list_of_elements = - ASCIIAtom.stream() + ASCIIAtom.stream(max_word_length: 10) |> Caffeine.Stream.take(10) assert Enum.all?(list_of_elements, &is_atom/1) end - - test "Check if atoms have default max word length not greater than 6" do - lengths_of_elements = - ASCIIAtom.stream() - |> Caffeine.Stream.take(10) - |> Enum.map(&Atom.to_charlist/1) - |> Enum.map(&length/1) - - refute Enum.any?(lengths_of_elements,fn e -> e > 6 end) - end end