Sid Ngeth's Blog A blog about anything (but mostly development)

Drawing Graphics in Elm

I’m learning how to write games in Elm and there does not seem to be very many resources updated for Elm 0.18. The old Graphics module has been moved out of elm-lang/core and into evancz/elm-graphics which might cause some confusion/compilation errors when looking at older examples.

The elm-graphics package gives us modules that interface with HTML 5 Canvas API. So lets see how we can draw something basic to the browser. In my later posts we will continue to build upon this program.

Make sure you have the required packages installed in your project directory:

elm package install elm-lang/html
elm package install evancz/elm-graphics

Summary:

We learned how to render a “canvas” on the screen by using Element.toHtml which takes an Element created by Collage.collage. While the Collage mainly deals with free form graphics, the Element and Text Modules can help you plug in various other types of graphics into your collage once converted into a form. I recommend checking out the elm-graphics documentation to see what other Forms you can create in your collages. So far, drawing graphics to the screen may seem somewhat tedious as it is in most other libraries. Elm’s architecture will start to shine in its simplicity in how updates and events are handled in your app.

Refactoring Part 1

You may hear many developers groan at working on a legacy code base out of control versus a greenfield project. However, I believe working in a large legacy codebase provides a wonderful opportunity to improve your refactoring skills.

This will be a series of connected blog posts on refactoring real world code at my current job. I’ve attempted to obfuscate the code to make it more generic and not tied to my company but the spirit should be the same. Hopefully you are able to notice these issues in your own code and improve it.

So the first thing I did was run the flog gem(it essentially scores an ABC metric: Assignments, Branches, Calls) on my app/ folder and tackled the highest rated file which not suprisingly, was a controller:

91.1: flog total
91.1: flog/method average

91.1: RaterController#index            app/controllers/rater_controller.rb:3-2

I will go ahead and make the commentary before you look at the wall of abomination. At first glance the code is so dense that it is not clear at all what we’re trying to do in the index action.

I hope this can convince you on the importance of having cleanly formatted code right off the bat. While it’s a very small file, it contains immense complexity. The code smells I wanted to refactor in this first attempt:

1) Long method

It’s a 24 line index action method. Cannot tell at glance what it’s doing.

2) Single Responsibility Principle violation

While it’s reasonable to have a controller to delegate rating different objects, it can get out of control to put that logic directly in the controller. We could at first just perform Extract Method but that would just be shuffling complexity within the file and does not let us take advantage of fixing the next issue.

3) Case statement that type checks and Open/Close Principle Violation

We observe an if-else block that kept getting piled on as more domain objects were needed to be rated

class RaterController < AuthenticatedUserController

  def index
    @title = I18n.t 'rater.title'
    @active_rating   = manager_selection_is_self? ? params[:employee_rating   ] : params[:manager_rating]
    @inactive_rating = manager_selection_is_self? ? params[:manager_rating] : params[:employee_rating   ]
    @fullscreen_form_action = ''

    if params[:rated_item_type] == 'movies'
      movie = Movie.find(params[:id])
      @rated_item = MoviePresenter.new movie
      @fullscreen_form_action = rate_movie_path(id: movie.id, is_self: manager_selection_is_self?)
    elsif params[:rated_item_type] == 'books'
      book = Book.find(params[:id])

      ratee = manager_selection_is_self? ? current_user.id : selected_user.id
      rater = current_user.id

      @fullscreen_form_action = rate_book_path(id: Book.id, rater:rater, ratee: ratee, manager_rating: params[:manager_rating], employee_rating:params[:employee_rating])

      @rated_item = BookPresenter.new Book, selected_user_id: @selected_user_id
    elsif params[:rated_item_type] == 'restaurants'
      @fullscreen_form_action = rate_restaurants_path(id: selected_user.id, is_self: manager_selection_is_self?, rater_id: current_user.id, old_employee_rating: params[:employee_rating], old_manager_rating: params[:manager_rating])
      @rated_item = RestaurantRating.new(selected_user)
    end

    render layout: 'fullscreen_form_dialog'
  end

end

You probably didn’t even bother to try and understand what was going on above, huh? Here is the refactored code with changes in comments

class RaterController < AuthenticatedUserController
  def index
    @title                  = I18n.t 'rater.title'
    @active_rating          = active_rating?
    @inactive_rating        = inactive_rating?
    @fullscreen_form_action = ''

    # Extracted logic to object_rater method to do all the work
    @fullscreen_form_action, @rated_item = object_rater
    render layout: 'fullscreen_form_dialog'
  end

  private

  # Use a rater "factory" to instantiate specific raters
  # Note we are using convention over configuration here:
  # We assume that we have classes with name DomainItemRate
  def object_rater
    object_rater_class.new(rating_params).call
  end

  # The if-else can be removed now since we have a factory
  # that knows how to instantiate itself based off item type.
  # This takes advantage of Ruby's dynamic dispatching instead
  # instead of needing to type check.
  def object_rater_class
    "#{params[:rated_item_type]}Rate".classify.constantize
  end

  # Instantiate a Parameter Object to pass to rater
  def rating_params
    "#{rating_type_rating}".classify.constantize.new(params)
  end

  # Remaining methods are helpers to parse params
  def active_rating?
    # return active rating check based on user
  end

  def inactive_rating?
    # return inactive rating check based on user
  end

  def id
    params['id'].to_i
  end

  def employee_rating
    params[:employee_rating]
  end

  def manager_rating
    params[:manager_rating]
  end

  def ratee
    # return the ratee
  end

  def rater
   # return the rater
  end
end

We don’t have to modify the index action at all now and have a nice convention for maintaining new Rater types. We simply just implement a Rater class that “duck types” what the index action wants returned so we can maintain Open/Close principles.

Example Rater Class:

class BookRater
  def initialize(args)
    @id = args[:id].to_i
    @is_self = args[:is_self]
  end

  def call
    fullscreen_form_action = rate_book_path(id: book.id,
                                             is_self: @is_self)
    rated_item = BookPresenter.new book

    [fullscreen_form_action, rated_item]
  end

  private

  def book
    Book.find(id)
  end
end

Summary: We broke out the rating logic for each domain type into plain old Ruby objects(POROs) . We were able to instantiate these on the fly and remove the if-else type checking by utilizing a factory pattern to dynamically dispatch to our POROs.

Functional Programming in Ruby

Although I’ve been focusing learning functional programming through Elixir and Elm these days, it’s interesting to go back to the first programming language I love to see what it can do.

These are some examples of Ruby’s functional programming abilities taken from HackerRank’s Ruby challenges.

Ruby can support higher-order functions i.e. can take and pass functions as arguments through several mechanisms: Blocks, Procs, and Lambdas. I’m not going to go into super detail as there are plenty good posts already out there on the topic. But a basic primer goes as follows:

Passing a Block to a function as nameless method:

def calculate(a,b)
    yield(a, b)
end

puts calculate(15, 10) {|a, b| a - b} # 5

Assigning a Proc to a variable. Proc’s are like a “saved” block:

def foo(a, b, my_proc)
    my_proc.call(a, b)
end

add = proc {|x, y| x + y}

puts foo(15, 10, add) # 25

Very similar to Procs but differing how they return (see link mentioned beginning of post) out of a function call is Ruby’s lambda.

# the -> keyword is Ruby >= 1.9's lambda syntax
area = ->(a, b) { a * b }

x = 10.0; y = 20.0

area_rectangle = area.(x, y)
area_triangle = 0.5 * area.call(x, y)

puts area_rectangle     #200.0
puts area_triangle      #100.0

Let’s dig into an interesting example where we show partial function applications

def factorial(n)
    (1..n).inject(:*) || 1
end


combination = -> (n) do
    -> (r) do
        factorial(n) / (factorial(r) * factorial(n-r))
    end
end

#How many combinations in 52 card deck when taking 5 cards?
n = gets.to_i # Let's enter 52
r = gets.to_i # Let's enter 5
nCr = combination.(n) # returns a lambda object
puts nCr.(r) # call our lambda with 2nd argument to be applied, result is 2,598,960

So similar to partial function applications is the concept of currying. Currying is converting a single function of n arguments into n functions with a single argument each.

power_function = -> (x, z) {
    (x) ** z
}

base = gets.to_i
raise_to_power = power_function.curry.(base)

power = gets.to_i
puts raise_to_power.(power)

JS Map Implementation

This is my answer to one of the questions from Quora I stumbled upon concerning how to judge a good JS dev.

“JavaScript is a functional programming language. Give me an example of how you can use higher order functions in JavaScript to iterate over and apply a function to every element in an array. Do not use a for or while loop.”

I didn’t find that this particular challenge noted much advance knowledge of JS. But some key things it does touch on are adding prototype functions, loss of functional scope of ‘this’, and basic idea of how recursion works. Note: I am using some ES6 features and wrote it via a Jasmine test.

describe("map recursive implementation", () => {
  it("applies function over array", () => {

     // Let's add our function directly to all Array's via prototype
     // So we can make calls like [1,2,3].myMap(...)
     Array.prototype.myMap = function myMap(callback) {
      // function implicitly binded to the original calling object
      // i.e. [1,5,10,15].myMap(...)
      // therefore 'this' is equal to the array
      // so we can save this to a new variable called arr
      let arr = this;
      let newArray = [];

      function map(arr) {
        if(arr.length === 0) {
          console.log("DONE processing, new array is " + newArray)
          console.log(newArray.length);
          return newArray;
        }
        else {
          //process the head first
          console.log("processing head of array: " + arr[0])
          console.log("pushing: " + callback(arr[0]))
          newArray.push(callback(arr[0]))

          //process the rest of the list
          arr.shift()
          console.log("processing rest of list: " + arr)

          //recursive call here
          //we pass the new array which removed first processed item
          return map(arr, callback);
        }
      }

      return map(this);
    }


    let doubles = [1,5,10,15].myMap(function(x) {
      return x * 2;
    });

    expect(doubles).toEqual([2,10,20,30])
  })
})

Prototypes in Javascript

What is a prototype?

An object that exists on every function in javascript.

A function’s prototype: A function’s prototype is the object instance that will become the prototype for all objects created using this function as a constructor

An object’s prototype: An object’s prototype is the object instance from which the object is inherited.

var myFunc = function() {}
console.log(myFunc.prototype) // empty protototype object

var cat = {name: 'Fluffy'}
console.log(cat.__proto__); // note objects don't have a prototype but have a __proto__ object

function Cat(name, color) {
  this.name = name
  this.color = color
}

var fluffy = new Cat('Fluffy', 'White')

Cat.prototype.age = 3

console.log(Cat.prototype) // has a property age: 3
console.log(fluffy.__proto__) // has a property age: 3
console.log(Cat.prototype === fluffy.__proto__) // true - same prototype instance

var muffin = new Cat('Muffin', 'Brown')
console.log(muffin.__proto__) // has a property age: 3


fluffy.age = 4

//instance properties override prototype properties
console.log(fluffy.age) // 4
console.log(fluffy.__proto__.age) // 3

delete fluffy.age
console.log(fluffy.age) // 3 - looks up prototype chain

//Changing a Function's prototype
Cat.prototype = {age: 5}

var snowbell = new Cat('Snowbell', 'White')

console.log(fluffy.age) // 3 still refers to original prototype instance
console.log(muffin.age) // 3 still refers to original prototype instance
console.log(snowbell.age) // 5 gains new defined prototype
console.log(snowbell.age) // 5 gains new defined prototype

//Prototype chains
console.log(fluffy.__proto__) // Cat { age: 4 }
console.log(fluffy.__proto__.__proto__) // Object {}
console.log(fluffy.__proto__.__proto__.__proto__) // null

Prototypical inheritance

function Animal(voice) {
  this.voice = voice || 'grunt'
}

Animal.prototype.speak = function() {
  console.log('Grunt')
}

function Cat(name, color) {
  //call parent constructor for parent related initialization
  Animal.call(this, 'Meow')
  this.name = name
  this.color = color
}

Cat.prototype = Object.create(Animal.prototype) // Link the prototypes
Cat.prototype.constructor = Cat // Necessary to correct prototype chain references

var fluffy = new Cat('Fluffy', 'White')

fluffy.speak() // 'Grunt'

Inheritance using new ES6 class syntax

We have some syntatic sugar that makes it cleaner to set up inheritance

class Animal {
  constructor(voice) {
    this.voice = voice || 'grunt'
  }

  speak() {
    console.log(this.voice)
  }
}

class Cat extends Animal {
  constructor(name, color) {
    super('Meow')
    this.name = name
    this.color = color
  }
}

var fluffy = new Cat('Fluffy', 'White')
fluffy.speak() // "Meow"

An important note is that the constructor object is a class not a constructor function on the object.

Also, members of classes are not enumerable by default. E.g., the speak function will not show up on the Object.keys or loop over the properties of the Animal class.