Hexa's Blog

Comparison of LinkList,Tuples, Maps, HashDict and Keyword Comparison in Elixir

01/12/2015 Elixir

1. Tuples It’s an order collection of values. There is a tip for using Tuples, a typical tuples has two to four elements

  • Once created, a tuples cannot be modified, the only thing we can do is matching(assigning) variable with new tuple.
  • If the number of tuple element is great,(probably greater than 4 elements), programmer should use Map

2. List (LinkList) The list of Elixir is link-list, there are some features/specification that you should noted.

  • It is easy to travel from head to tail, but expensive to get to particular element for example a[22]. You will have to loop via 21 elements.
  • It’s easy to add an new element to a link-list to the head or tail.

3. Keyword List Keyword list is a list of tuples of pair values. An example below explain the keyword list.

[name: "Linh", age: 2]
[{:name, "Linh}, {:age, 2}]
  • Keyword list allows duplicated key value, because in fact, it’s a list

4. Map Map is used to save collection with a pair of key and value. Unlike keyword list, Map does not allow duplicated keys. Accessing a map by:

states = %{ "AL" => "Alabama", "WI" => "Wisconsin" }
states["AL"]

Excel file, replace special character single quotes which besides numbers

27/11/2015 etc

I have work with spreadsheet gem on ruby, Sometime I do realize that in the LibreOffice, the content is something like '24%, the character single quote refers to a string. However, I want a number instead. A possible way to convert them without programming is Find and Replace. However it does not easy as I say because the character ' is a special character in LibreOffice, you have to use regular expression to work with this.

There is a solution to convert string to number in such case is using replace function name Find and Replace C-h in LibreOffice. In the Search for text, type ^.; in the Replace with, type $. In the other options, please tick on Regular expressions. Finally, you can choose replace or replace all.

Elixir Cheatsheet

20/11/2015 cheatsheet

This is cheatsheet for Elixir, it’s a not a summary of this language, this article all about tweak, remember note for Elixir language.

1. For loop Given that, we we a list of map

people = [
  %{name: "Linh", age: 22},
  %{name: "Son", age: 18},
  %{name: "Long", age: 15},
]
for person <- people, do: (
  IO.inspect person
)

Elixir supports a for conditional loop.

for person = %{age: tuoi}<- people, tuoi < 20, do: (
  IO.inspect person
)

2. Update a map

old_map = %{attr1: 1, attr2: 2 }
new_map = %{old_map | attr1:  3}

3. Struct Generate Struct

defmodule Subscriber do
  defstruct name: "", paid: false, over_18: true
end

sub1 = %Subcriber{}
sub2 = %Subcriber{name: "sub2", paid: true, over_18: false}

Use Struct attribute

sub1.name
sub2.name
sub2[:name]

Update attr in a struct

sub2 = %Subcriber{name: "sub2", paid: true, over_18: false}
sub2 = %{sub2 | name: "Another sub2"}

#alternative solution:
put_in(sub2.name, "new_name")

JavaScript, rounding number after decimal

30/09/2015 etc

Given that, you have to work with many decimal number for example: 0.335, 0.345, 0.2, 96.6666. And then you want to round those number 2 digits after decimal. The most general way is to used toFix(). However, the behavior of toFix() is not good. Let test with value 0.335 and 0.345.

0.335.toFix(2) --> 0.33, we expected 0.33
0.345.tiFix(2) --> 0.35, we expected 0.34 FAIL!!!

The better solution is that, we try to use the first two digit after decimal, the only issue is that, these two digit up/down are depend on the third digit, perhaps the fifth one. Number 44 is to solve this issue. Any number x.a-b-c-d which has c-d >= 56, the b will be round up by one.

var num = 0.335
var numX10000 = num * 10000;  --> 3350
var Math.floor((numX10000 + 44) / 100) --> 3350 + 44 = 3394, floor of 3394/100 = 33

var num = 0.345
var numX10000 = num * 10000;  --> 3450
var Math.floor((numX10000 + 44) / 100) --> 3450 + 44 = 3494, floor of 3494/100 = 34

A good solution come up with a compact function which can help you use in any time.

function long_round_number(number, digit){
  var multiplier = Math.pow(10, digit + 2);
  var multiple_number = Math.floor(number * multiplier)
  var roundup_number = multiple_number + 44;
  var return_value = Math.floor(roundup_number / 100) / Math.pow(10, digit)
  return return_value;
}

function roundNumber(number, digit){
  var multiplier = Math.pow(10, digit + 2);
  var new_number = Math.floor(multiplier * number) + 44;
  return  Math.floor(new_number / 100) / Math.pow(10, digit);
}

Add new methods to exist resource routes as collection in Rails

10/09/2015 Ruby on Rails 4

Rails does support built-in CRUD with RESTful. It provides default url for developers. However, there could be a time that developer want to add more method/action to work with exist routes. Hence, this is solution.

This is a default setting for resources of pictures

resources :pictures

This is modification with new upload method which use GET protocol.

resources :pictures do
  collection do
    get 'upload', to: 'pictures#upload'
  end
end

Chrome, Firefox, Conkeror redirecting to advertise websites

01/09/2015 etc

My browsers always automatically redirect to advertise website. That’s a pain in my ass. In particular, While I am reading software API, it change my current pages to another ad pages. Seemingly, someone did change my default dns to advertise dns server.

1. Change the DNS Set the current dns to google dns: 8.8.8.8, 8.8.4.4

2. Reset the Network Manager

sudo systemclt restart NetworkManager

After finished this step, firefox should work well

3. Remove cache in Google Chrome

## Go to ~/.cache/google-chrome
cd ~/.cache/google-chrome/Default
## remove file in Cache directory
rm Cache/*
## remove file in Media Cache directory
rm Media\ Cache/*

4. Remove cached in Conkeror

## move to dir of conkeror cache
cd ~/.cache/conkeror.mozdev.org/conkeror
## remove all cached
rm -rf *

Summary of block, process and lambda in Ruby

17/08/2015 cheatsheet

There are three ways to group trunk of code in Ruby which are block, process and lambda. Each of them behave differently from others. This post is all about the differences of them and its examples and use cases.

|-------------------------+--------------------+-------------+------------------------|
| Characteristics         | Process            | Block       | Lambda                 |
|-------------------------+--------------------+-------------+------------------------|
| Object                  | yes                | no          | yes                    |
|-------------------------+--------------------+-------------+------------------------|
| Number of arguments*    | many               | 1           | many                   |
|-------------------------+--------------------+-------------+------------------------|
| Checking number of args | no                 | identifying | yes                    |
|-------------------------+--------------------+-------------+------------------------|
| Return behavior         | affect outer scope | identifying | not affect outer scope |
|-------------------------+--------------------+-------------+------------------------|

Basic usage

 # block
 def test_function(&a)
   a.call
 end

 test_function {
   p "it's block"
 }
 # lambda
 lam = lambda{
   p "it's lambda"
 }
 lam.call #OR#
 test_function(lam)

 # Process
 pro = Proc.new {
   p "it's proc"
 }
 pro.call #OR#
 test_function(pro)

Object or not

  • Block is not an object, cannot execute directly, it need to be passed to a method
  • Proc and Lambda are objects, its instance can be execute directly

Number of block, proc and lambda passed in parameter field

  • Block: A method can use only one block which passed in the parameter fields. Well, obviously, block is a kind of anonymous function. If there are two passing in parameter field. How could interpreter understand when should it use this or that block. Meanwhile, a method can only use one block or anonymous function which is passed in parameter field.

  • Proc and Lambda: In fact, these two are identical and it’s object instances. On the other words, you are passing object in parameter field. Hence, pass them as many as you want.

Return behaviour

  • Block: return cannot be used within a block. Here is an article about block break and next behaviours
  • Lambda: return instruction within a block only suspend instruction execute within the block. It does not suspend outer method.
  • Process: return instruction also affect the outer scope. It suspends the outer method directly.

Checking number of arguments passing to block, process, lambda

|-------+-------+---------+--------|
|       | Block | Process | Lambda |
|-------+-------+---------+--------|
| check | no    | no      | yes    |
|-------+-------+---------+--------|

Reference

Generate entity relationship based on model, Ruby on rails

07/08/2015 Ruby on Rails 4

During this time, I am in an internship program. There is a big concern, I have to work with a very big project, and there is no documentation. The number of tables in project’s database is more than 20, still no documentation.

A big nightmare for an intern one. It’s important to make an entity relationship diagram, at least with a hope that I can get cope easily with the project.

Game on!, There is a gem named erd - url

Setup and Installation

  • Install graphviz (fedora)
sudo dnf install -y graphviz
  • Add gem erd to gem file
group :development do
  gem "rails-erd"
end
  • Install bundle
bundle install

Configuration

Configuration file will be loaded at ~/.erdconfig or ...project_rails/.erdconfig, file config in the root of project will take higher priority than in the home directory.

attributes:
  - content
  - foreign_key
  - inheritance
disconnected: true
filename: erd
filetype: pdf
indirect: true
inheritance: false
markup: true
notation: simple
orientation: horizontal
polymorphism: false
sort: true
warn: true
title: sample title
exclude: null
prepend_primary: false

Generating entity diagram file

Entity diagram will be generated in the root directory of project.

bundle exec erd

Highchart, forcing dual yAxis to have common zero

28/07/2015 etc

Highchart is a common javascript library which use to display graph with many beautiful features, however, there is a small need in use of highchart.js. It’s about having dual yAxis, and how to balance common zero between two yAxis.

There is no built-in feature that can help you deal with this solution but changing the min, max value via setExtremes() method.

I did write a small method which can help solve this problem, small but achievable. github

How to use

  1. Given that, on the html there is a div which is used for highcharts, this div is only for rendering graph for example $("#graph")
  2. After include the balancezero.js, you can test by running the command on the web console balanceZeroRoot(dom_element) or for example balanceZeroRoot($("#graph"))
  3. By default, there is exist behavior for show and hide plots, you need to modify those default behavior to work with balancezero.js. For each kind of graph, there is exist option name legendItemClick for example link
plotOptions: { // shared option on plottin the graph
  series: {
    borderColor: '#000000',
    pointStart: Date.parse(data.start_date),
    pointEnd: Date.parse(data.end_date),
    pointInterval: 24 * 3600 * 1000,
    groupPadding: 0, // group for each point on the x-axis
    shadow: false,
    animation: false,
    events: {
      legendItemClick: function(){
        if(this.visible == true){
          this.setVisible(false, false);
        }else {
          this.setVisible(true, false);
        }
        balanceZeroRoot(YOUR_GRAPH_DOM_ELEMENT);
        return false;
        }
    }
  }
}
  • In addition, there is also a need to load balanceZeroRoot() right after data loaded. There are many kind of graph, the code below is an example about chart type
chart: {
  events: {
    load: function (){
      balanceZeroRoot(YOUR_GRAPH_DOM_ELEMENT);
    }
  }
}

Note

  • The demand to have common zero for dual yAxis has been there for 2 years link , however there is no good solution which fit for me even the one from the admin of highcharts, the plugin does not work perfectly.

  • Highcharts’s admin response: link, jsfiddle link

Emacs, Ruby On Rails Configuration

16/05/2015 Ruby on Rails 4

Robe

1. Source: link 2. Features

  • Jump to read the documentation of methods
  • Complete the symbol at point, actually, it will show a list of available method for given character or class

3. Interactive Function

  • M-. to jump to the definition
  • M-, to jump back
  • C-c C-d to see the documentation
  • C-c C-k to refresh Rails environment
  • C-M-i to complete the symbol at point
  • ruby-load-file to update ruby file

Highlight Indentation

1. Source link 2. Feature

  • Color the method columns (scope)
  • User can differentiate current scope to upper and lower scope 3. Variables
(set-face-background 'highlight-indentation-face "#808080")
(set-face-background 'highlight-indentation-current-column-face "#e5e5e5")

4. Interactive Functions

  • highlight-indentation-current-column-mode: current column will be highlighted only or with particular colors.
  • highlight-indentation-mode: highlight all columns.

Ruby-Flymake

1. Source link 2. Feature

  • checking syntax

Reference List

  • Emacs configuration for rails,link