Elixir/Erlang interop games

Today’s exercise was related to calculating next imaginary meetup date. Rules for next date might be something along “every first friday”, “last saturday” etc.

It seems that Elixir decided to leave all Date stuff to Erlang, so today I learned how to use Erlang from Elixir. Nice! For this exercise, the Erlang’s calendar offered all the needed functions. And this is how it is used:

defp matches_weekday?(date, weekday) do
  weekdays = %{
    :monday => 1,
    :tuesday => 2,
    :wednesday => 3,
    :thursday => 4,
    :friday => 5,
    :saturday => 6,
    :sunday => 7
  }

  :calendar.day_of_the_week(date) == weekdays[weekday]
end

So, you just need to prefix the desired module with “:” and off you go. Very nice! Still have to find out how ti include custom Erlang libraries, but that was not needed here, so until next time.

Another thing I learned is how to invoke aribtrary function in run time. E.g. for this exercise, I had a set of policies to filter matched week¬†days against. E.g. for “meetup falls on 2nd tuesday” I’d first filter out all tuesdays for the given month, and then fetch the 2nd date from the list. For another rule, e.g. “last saturday”, I’d filter out saturdays and get the last one. And I hated the idea of some giant case pattern, so decided to:

  • store those functions in a map, let’s call them filters or rule matching policies
  • fetch policy appropriate to given schedule rule
  • apply the policy to matching weekdays

And, no surprise there, there is the Kernel.apply/2 method that does just that, applies a function to a set of arguments. Let’s see it in action:

defp filter_by_schedule(dates, schedule) do
  schedule_filter = %{
    :first => &first/1,
    :second => &second/1,
    :third => &third/1,
    :fourth => &fourth/1,
    :last => &last/1,
    :teenth => &teenth/1
  }[schedule]

  schedule_filter |> apply([dates])
end

defp first(dates) do
  dates |> hd
end

defp second(dates) do
  dates |> Enum.at(1)
end

defp third(dates) do
  dates |> Enum.at(2)
end

defp fourth(dates) do
  dates |> Enum.at(3)
end

defp last(dates) do
  dates |> Enum.reverse |> hd
end

defp teenth(dates) do
  dates |> Enum.find(fn({_, _, day}) ->
    day >= 13 && day <= 19
  end)
end

So basically, the schedule filter policy is extracted from the map that maps schedule type to appropriate filter function. And the rest is easy ūüôā

You can find the complete solution at exercism.io or Github.

Tagged , ,

Transform Elixir

In¬†“Grading (with) Elixir” I complained¬†that using Enum.reduce/3 was a bit cumbersome for a simple transform of map values. Funny enough,¬†the¬†last exercism.io problem I’ve been playing with, the Transform part of¬†ETL kind of hints¬†why Enum.reduce/3 is just the right tool for the job after all. Let see why.

The exercise describes a problem in which you need to take old scrabble scoring system and convert it to the new one. The old system groups letters by their value (point) while the new one requires letters to be the keys and point their respective values, to make scoring a more enjoyable process.

So, basically, we¬†need to take old scoring data and transform it to the new one. Let’s see how:

def transform(input) do
  input |> Enum.reduce(%{}, fn({value, keys}, acc) ->
    keys |> Enum.map(&({String.downcase(&1), value})) |> Enum.into(acc)
  end)
end

So this time, we just take the input stream, and transform the input’s values into value => key tuple list, and pack all of that into a single map.

And¬†vuala, the reduce now makes much more sense ūüôā

As always, you can find the complete example @ Github.

And as a parting quote, here’s a¬†“deja vu” situation described from that same exercise:

Extract-Transform-Load (ETL) is a fancy way of saying, “We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so we’re going to migrate this.”

(Typically, this is followed by, “We’re only going to need to run this once.” That’s then typically followed by much forehead slapping and moaning about how stupid we could possibly be.)

If I had a dime for every time it actually happened! ūüôā

 

Tagged , ,

Grading (with) Elixir

The last Elixir exercise from exercism.io was short but sweet. It involved working with maps and an interesting problem of transforming one map to another, while changing the inner structure of map value(s).

To make things concrete, the task was to, starting with people grouped by grades, build the same grade grouped list of people, but this time sort them alphabetically. So, one would start with:

%{4 => ["Christopher","Jennifer", "Bart"], 6 => ["Kareem", "Anna"]}

and expect the sorted map:

%{4 => ["Bart", "Christopher","Jennifer"], 6 => ["Anna", "Kareem"]}

Now, this isn’t much of an issue code wise, but I¬†expected there to be a method like Enum.map/2¬†that would “remap” the values easily, but there isn’t. So, the only viable solution I could find was to actually use Enum.reduce/3:

@spec sort(Dict) :: Dict.t
def sort(db) do
  db |> Enum.reduce(%{}, fn({grade, names}, acc) ->
    Map.put(acc, grade, Enum.sort(names))
  end)
end

This essentially introduces an accumulator map that gets filled with same keys and transformed values. Nice, but kind of disappointed it didn’t support direct mapping.

EDIT: Per Martin’s hint, there is a way to use Enum.map/2, but one needs to use it in combination with Enum.into/2, like this:

@spec sort(Dict) :: Dict.t
def sort(db) do
 db |> Enum.map(fn({grade, names}) -> {grade, Enum.sort(names)} end) |> Enum.into(%{})
end

Another thing that became obvious today was that the ternary operator macro is a function, and you can use it like:

if(condition, do: x, else: y)

or

if condition, do: x, else: y

A subtle difference, but can help with readability. E.g. the last one is going to need () around it in some complex expressions.

And finally, another nice thing (comming from Javascript and Ruby I really like it) is that you can use “||” like this:

@spec grade(Dict.t, pos_integer) :: [String]
def grade(db, grade) do
  db[grade] || []
end

So, if there is a key in the map, get it’s value, otherwise return some default value, an empty list in this case.

And, as always, you can find the entire code sample at Github project.

Tagged , ,

Hello, is Elixir there?

So, another day, another … well, sorry, I just can’t find something funnier to start with! Anyway, this time it’s the “hey, let’s format some phone numbers, but let’s do it for US only” kind of problem.

And today, the highlights are:

Tuples & pattern matching

Let’s say that you have a function that knows how to split a phone number into meaningful parts (hmm, I wonder where did I get that idea?!). So you might end up with code area of that phone number, prefix and finally line number.

The question is, how do you pass that information around? Well, aside from structs, you can just use tuples. Just wrap values in curly braces and that’s it:

defp split(phone) do
  {code(phone), prefix(phone), line(phone)}
end

This effectively means that the output might be something like {“123”, “456”, “7890”}. The good thing about that, as opposed to using for example a list, is that you can easily access each member, by index, or just use pattern matching to extract values, like this:

def pretty(phone) do
  {code, prefix, line} = split(phone)
  "(#{code}) #{prefix}-#{line}"
end

That way, it’s pretty easy to pass¬†multiple results around.

Guard clauses

Until now, I didn’t really have a use for those. But, this time, the sort of¬†complex number format and validation rules complicate things, and guard clauses help with the reasoning.

def number(raw) do
  case raw |> String.replace(~r/\W/, "") |> to_char_list do
    phone when length(phone) == 11 and hd(phone) == ?1 ->
      tl(phone)
    phone when length(phone) != 10 ->
      '0000000000'
    phone ->
      phone
  end |> to_string
end

This way, the rules become easy to follow. And situations like “if phone length is 11 and starts with ‘1’, then it’s a valid number but¬†remove the ‘1’ before moving on” become easy to write and follow quite nicely the natural language.

Doctest

Doctest is a great thing all modern languages support. The idea is to write examples as part of a function documentation, and have test execute those very examples. So, the phrase “the tests are the code’s documentation”¬†comes to life in a splendid manner ūüôā

This specific exercism.io¬†problem had some of those already in the supplied exercise code, and I wanted to use those tests as well. If we were to use `mix`, then it would be easy, since the tool would set up¬†everything for us. But,¬†since exercism.io problems are meant to offer as little distraction as possible, you can’t use it out of the box.

Fortunately, there is a work around. You just need to:

  • add `doctest Phone` to the test file / module, as shown here
  • build source file, because otherwise doctest will not find the documentation
  • run tests as usual

So, for the last 2 steps, just create a shell script that does that for you. For example:

elixirc phone_number.exs && elixir phone_number_test.exs

Elixirc compiles the code, creating a beam file, tests load it and use it to run the tests / examples from documentation. And oh, forgot to show an example of such a test:

  @doc """
  Remove formatting from a phone number.

  ## Examples
  iex> Phone.number("123-456-7890")
  "1234567890"
  """
  def number(raw) do
  end

And, when executed, it reports like this:

$ ./test.sh
PhoneTest
  * doc at Phone.number/1 (4) (0.7ms)

Finished in 0.1 seconds (0.1s on load, 0.01s on tests)
1 tests, 0 failures

Randomized with seed 543612

That’s it folks!

Here’s a Github issue that related to all of this.

You can find the entire phone number solution here.

P.S. All pun intended ūüôā

Tagged , , ,

Elixir genome

Today a triplet of Elixir problems solved ūüôā They are all “human genome” related¬†this time:

Aside from regular enjoyment while working with Elixir (remember? fun, fun, fun !!!), I’ve learned¬†that you can give the head and tail in argument an assignment / name. Simplifies code definitely, here’s an example:

  def hamming_distance(strand1 = [h1|t1], strand2 = [h2|t2]) do
    if length(strand1) != length(strand2) do
      nil
    else
      hamming_distance(t1, t2) + (if h1 == h2, do: 0, else: 1)
    end
  end

As you can see, in the above function, I needed both a complete list, e.g. strand1, but also it’s head an tail. Of course, I could have used the hd/1 and tl/1 functions, but it looks far cleaner this way, at least for me.

Another cool code style I started using more is the function capturing feature:

  def histogram_with_zip(strand) do
    strand!(strand)
    Enum.zip(@nucleotides, Enum.map(@nucleotides, &(count_wo_check(strand, &1)))) |> Enum.into(%{})
  end

  defp strand!(strand) do
    strand |> Enum.map(&(nucleotide!(&1)))
  end

Basically, it allows you to use a short hand for fn(x) -> do_something(x);. It makes the code more compact and easier to read. Of course, one should not overdo it, but for now I quite like the looks of it.

Tagged , ,

A little word play in Elixir

Another day, another exercise. This time it’s the oldie but goldie, anagram detection. For the innocent ones, taken from problem’s readme:

Write a program that, given a word and a list of possible anagrams, selects the correct sublist.
Given "listen" and a list of candidates like "enlists" "google" "inlets" "banana" the program should return a list containing "inlets".

And¬†here’s one possible¬†take on it:

defmodule Anagram do
  @doc """
  Returns all candidates that are anagrams of, but not equal to, 'base'.
  """
  @spec match(String.t, [String.t]) :: [String.t]
  def match(base, candidates) do
    candidates |> Enum.filter(fn(candidate) ->
      !equal?(base, candidate) && anagram?(base, candidate)
    end)
  end

  defp equal?(base, candidate) do
    String.downcase(base) == String.downcase(candidate)
  end

  defp anagram?(base, candidate) do
    hash(base) == hash(candidate)
  end

  defp hash(string) do
    string |> String.downcase |> String.split("") |> Enum.sort
  end
end
Tagged , ,

Another day, another Elixir fun exercise :-)

So today I’ve done another simple exercise, the¬†http://exercism.io/exercises/elixir/sublist/readme, or how to determine if a list is a equal, sublist, superlist or unequal to another list. So, without further ado, here’s my take on it:

defmodule Sublist do
  @doc """
  Returns whether the first list is a sublist or a superlist of the second list
  and if not whether it is equal or unequal to the second list.
  """
  def compare(a, b) do
    cond do
      a === b ->
        :equal
      length(a) <= length(b) && is_sublist(a, b)->
        :sublist
      is_sublist(b, a) ->
        :superlist
      true ->
        :unequal
    end
  end

  defp is_sublist(a, b) do
    cond do
      length(a) > length(b) ->
        false
      a === Enum.take(b, length(a)) ->
        true
      true ->
        is_sublist(a, tl(b))
    end
  end
end
Tagged , ,

Elixir fun times !!!

So lately I’ve been in Javascriptland and things have started to look all the same. Not that it’s dull, but I just needed something to pull me out of the daily chores. So, I finally decided to start having serious fun in Elixir. Enter¬†Exercism! It’s a cool place with a bunch of simple (or not so) prepared excercises that can get you into a language. Also, there’s an option to nitpick about the code with other members. Sort of code review but with no obligation, only good stuff comming out ūüôā Anyway, there’s a bunch of other languages to choose from but I’ll be dabbling in Elixir for now. Just finished a¬†problem with recreating the usual list operation, without help from native modules.¬†For example, how to create the map or reduce! A fun fun fun exercise! And just something that shows how simple things can get in functional style. Take a look¬†and let me know what you think, or even better, check in with Excercism and nitpick about it ūüôā P.S. I’ll be posting the solution to Github as well.

Tagged , ,

Kafka & Storm integration talk

This¬†June¬†I had the pleasure of attending the annual DORS/CLUC conference in Zagreb. It’s a convention¬†for the¬†Croatian Linux users group devoted to open systems in general. There was a bunch of interesting talks¬†but my favorite of the day was definitely¬†Mario Borna Mjertan, an elementary school student that’s been using Linux (as a user and as a developer) for 6 years already. Talking about a real interest in computers ūüôā

Also, I had the pleasure of talking about integrating Kafka & Storm at my dev shop. The basic idea was to build a system that can process incoming data stream (in the range of about 5,000 events per second) and build end user dashboard data (trends, current submit rate etc.) in near real-time. In the talk I gave a short intro to the technology stack and basic concepts but also an overview of bottlenecks and issues we experienced along the way.

Below you can find the video of the talk:

And the related slides:

Video can also be found here.

Tagged , , , , , , ,

jQuery UI slider for dynamic content

On¬†one of the projects I’ve worked on,¬†we used jQuery UI slider for dynamic content.¬†The slider’s handle needed to¬†resize¬†according to that dynamically loaded content.

The main issue was that with the usual suggested ways to do it,¬†there was¬†a jump for first mouse initiated movement on the slider. That rather ugly behavior is related to the slider’s¬†requirement that the slider bar and handle parent must be of same width[1]. That, in combination with the¬†requirement¬†to¬†give the handle a half margin offset[2] due to handle sizing, causes that ugly jump to occur.

This is how the default setup looks like:

jquery-ui-slider-dynamic-content-before

You can see that the bar and the handle parent are of the same size. Slider is initialized on bar element.

The fix is rather simple. Instead of initializing the slider on bar element, do it on ui-handle-helper-parent. Then you can size that element as needed, and the slider does not exhibit the ugly jump. The ui-handle-helper-parent element needs to be centered in bar and a bit of custom styling is needed, but in the end it works nicely. This is how the setup looks like after the fix:

jquery-ui-slider-dynamic-content-after

Due to peculiar¬†sizing¬†of the¬†ui-handle-helper-parent element, another fix was needed as well. When clicking¬†on the area of bar element that the¬†ui-handle-helper-parent element doesn’t cover, the¬†slider value needs to be recalculated and set accordingly. All of these changes and fixes are packaged in the DynamicSlider[4] component and there is a working example[3].

Resources:

  1. Jquery UI Scroll Bar not fitting the contents
  2. jQuery UI slider jumps
  3. A working example @ CodePen
  4. The gist of the example
Tagged , , ,