Monday, December 2, 2013

Domain Modelling a.k.a. Object-Oriented Programming

Our industry created a new term for Object-Oriented Programming (combination of noun and behavior), it's called Domain Modelling. There's no problem with that, it gives us a richer vocabulary for something that closely resembles the real-world or the problem-at-hand. It will just be a source of confusion when we misuse the same vocabulary for something else.


Domain model models both nouns and behaviors. However, many thought that domain models are just all about nouns. This is where the confusion starts, if we remove the behavior from the domain model where do we place the behavior/business logic that acts on the noun? Should the domain model really just be a mere state repository?


With that confusion, a new term is coined to emphasize a domain model without behaviors, this kind of domain model is now called anemic domain model. And the domain model (that should inherently have behaviors in the first place) with behavior is now called rich domain model.


Had we not invented the term domain modelling; we might call the new OOP, that is an OOP with behavior, as Rich Object-Oriented Programming.


Modelling the real world is getting funny :-)


Here's the anemic computer model:

class Computer
{
    public int ComputerId { get; set; }

    public double Speed { get; set; }
    
    public double BaseSpeed { get; set; }
    
    public double MaxSpeed { get; set; }
}

Its behavior is in ComputerService.


class ComputerService
{
     public bool Overclock(Computer c, double multiplier)
     {
         bool safeToOverclock = false;
         
         double newSpeed = c.BaseSpeed * multiplier;
         if (newSpeed <= c.MaxSpeed) 
         {
             c.Speed = newSpeed;
             safeToOverclock = true;
         }
         
         return safeToOverclock;
     }
}


The problem with separating the behavior from its object is it's more difficult to identify the codes we can re-use. We tend to make duplicate codes if we don't know that there's an existing implementation already that act as an intelligent front-end(e.g. service) for the anemic domain model. Trying to discover the code we can re-use on a domain model(er.. rich domain model)? It's right there on the class! Just type dot character after the class instance, the model's behavior jumps out on intellisense/autocomplete, the model's intelligence is integrated right there on the model, a one-stop-shop feel.


This is the proper domain modelling for computer, this is now called a Rich Domain Model. A model with behavior, an object with behavior yay! Should we call this Rich OOP too?


class Computer
{
    public int ComputerId { get; set; }

    public double Speed { get; set; }

    public double BaseSpeed { get; set; }    

    public double MaxSpeed { get; set; }
    
    public bool Overclock(double multiplier)
    {
         bool safeToOverclock = false;
         
         double newSpeed = this.BaseSpeed * multiplier;
         if (newSpeed <= this.MaxSpeed) 
         {
             this.Speed = newSpeed;
             safeToOverclock = true;
         }
         
         return safeToOverclock;
     }
    
}



Let's practice Domain Model, er.. scratch that, let's practice Rich Domain Model! let's practice OOP!


Happy Computing! ツ

Thursday, November 7, 2013

AngularJS: Karma and Jasmine

This is a primer on javascript unit testing, however there's no AngularJS in this post. But since I got to know Karma and Jasmine by way of AngularJS and I intend to use Karma and Jasmine for AngularJS, I decided to include AngularJS in the title ツ


Installation steps:

* Install nodejs: http://nodejs.org/dist/v0.10.21/node-v0.10.21.pkg
* Go to Terminal, logon as administrator, type: sudo bash
* Type: npm install -g karma


I followed the instruction here: http://www.tuesdaydeveloper.com/2013/06/angularjs-testing-with-karma-and-jasmine/, but since I just wanted to check a working example of karma + jasmine first, I decided to make the testing really very basic. After the karma successfully installed, exit out of administrator, create a sampletest directory placed in your home directory, while at commandline:

$ mkdir ~/sampletest
$ cd ~/sampletest






In the same directory, create a file named test.js, this file will be monitored as we specified *.js during karma config initialization.

function helloWorld(){
    return "This will fail the test"; 
}

describe("Hello world",function(){ 
    it("says hello", function() {
        var s = helloWorld();
        expect(s).toEqual("Hello world!"); 
    });
});

Then start karma:
$ karma start

If you specified a different filename during karma config settings initialization (e.g., karma init karmahin.ka.sana.config.js), put the name of the config file in karma start, e.g., karma start karmahin.ka.sana.config.js

As soon as karma is started, you shall see there's a failing test:




Change the helloWorld() function's return value to "Hello world!"
As soon as you save your file test.js on TextEdit(any editor), you shall see a passed test:



The test is an actual testing of javascript within the browser, try to change the return value of helloWorld() function to a prompt dialog:

function helloWorld() {
    return window.prompt("What's your greet?", "Hi world!");
}

As soon as you hit save, you'll see the browser will refresh and prompts you for an input:


Just press enter, then you'll see a failing test:


This is a great productivity booster on your development workflow. You can see breaking changes as soon as you save your file. There's no need to compile your app in order to unit test it; as soon as you save your file, it is tested on-the-fly! Bye bye compiler tax!



Happy Computing! ツ

Tuesday, October 15, 2013

Use IMMUTABLE on PostgreSQL function to avoid optimization fence

I thought this is the PostgreSQL equivalent of SQL Server's efficient inline table-valued function:
create or replace function get_orgs() returns table
(
ID int,
Favorite int
)
as
$$ 
    select p.person_id, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then p.person_id / 0 else 7 end
    ) eorg(ounits) on true
$$ language sql;


Using that function on this expression..
select p.*, o.* 
from person p
join get_orgs() o on p.person_id = o.ID
where p.person_id < 4
..produces a divide-by-zero error on PostgreSQL, while SQL Server does not materializes the rows that are greater than or equal to 4, hence this doesn't produce an error on SQL Server:

ERROR:  division by zero
CONTEXT:  SQL function "get_orgs" statement 1

********** Error **********

ERROR: division by zero
SQL state: 22012
Context: SQL function "get_orgs" statement 1


To achieve the same optimized execution plan of SQL Server on PostgreSQL, must add IMMUTABLE on the function:
create or replace function get_orgs() returns table
(
ID int,
Favorite int
)
as
$$ 
    select person_id, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then p.person_id / 0 else 7 end
    ) eorg(ounits) on true
$$ language sql IMMUTABLE;
When that function is used on the the query above, it doesn't yield divide-by-zero anymore, it's now efficient, it doesn't eager load the function's result, it's like the function is inlined on the query itself, the query that joins to the IMMUTABLE function behaves like a table-deriving query, very efficient, no divide-by-zero will occur, i.e., the RDBMS just expand the function's query to other query, divide-by-zero error won't happen, to wit:
select p.*, o.* 
from person p
join
(
    select p.person_id as ID, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then p.person_id / 0 else 7 end
    ) eorg(ounits) on true
)
o on p.person_id = o.ID
where p.person_id < 4;
Produces this output, has no divide by zero error:
 person_id | lastname  |  firstname   | nickname | favorite_number | id | favorite 
-----------+-----------+--------------+----------+-----------------+----+----------
         2 | mccartney | james paul   | paul     |                 |  2 |        7
         3 | harrison  | george       |          |                 |  3 |        7
         1 | lemon     | john winston | john     |                 |  1 |        7
(3 rows)
However, PostgreSQL, unlike SQL Server, has an optimization fence on its CTE, i.e., PostgreSQL eagerly loads the result of the CTE. SQL Server's CTE is more efficient than PostgreSQL's CTE on this regard:
with o as
(
    select p.person_id as ID, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then p.person_id / 0 else 7 end
    ) eorg(ounits) on true
)
select p.*, o.* 
from person p
join o on p.person_id = o.ID
where p.person_id < 4;
That CTE yields the following error on Postgresql, a proof that Postgresql eagerly load the result of the CTE; while on SQL Server it has no error, SQL Server doesn't eagerly load the result of CTE, a proof that SQL Server sees CTE as subject to execution plan rather than an eager-loading mechanism to fetch the results. Eagerly-loaded results has no chance to be optimized, as it looks like a blackbox from the caller, the caller can't optimize what's inside
ERROR:  division by zero

********** Error **********

ERROR: division by zero
SQL state: 22012
If we will follow C language principle design, I wishes PostgreSQL to use an existing keyword to indicate we don't want an optimization fence on a CTE:
with o immutable as
(
    select p.person_id as ID, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then p.person_id / 0 else 7 end
    ) eorg(ounits) on true
)
select p.*, o.* 
from person p
join o on p.person_id = o.ID
where p.person_id < 4;
If a CTE's query can be re-used, the query is better be made as view instead, a query inside a view don't have optimization fence too, i.e., it also behaves as table-deriving query, view's query just get expanded to other query, this won't produce divide-by-zero error:
create or replace view vw_get_orgs as
    select person_id as ID, eorg.ounits
    from person p
    join lateral
    (
        select case when p.person_id = 4 then person_id / 0 else 7 end
    ) eorg(ounits) on true;


select p.*, o.* 
from person p
join vw_get_orgs o on p.person_id = o.ID
where p.person_id < 4;


Happy Computing! ツ

Very efficient JSON in PostgreSQL

From this old approach:

  select array_to_json(array_agg(row_to_json(t))) 
  from (select firstname, lastname, favorite_number from person) t;


To this new one:
  select json_agg(t)
  from (select firstname, lastname, favorite_number from person) t;

Sunday, October 13, 2013

Sunday, October 6, 2013

Bye bye C#, PHP, Java, Ruby. You are so long, and thanks for all the fish*

I told my friend(whose career is built around PHP) about AngularJS, like everybody else who discovered the joys of using AngularJS, he's very excited learning something revolutionary. He shared that one time he's learning AngularJS up to 3 AM.




What he likes in AngularJS is the PHP's role in a web application development is taking a backseat, and the realization that he doesn't even need PHP at all, any server-side languages that can serve JSON would do, be it from C#, Java, Ruby and whathaveyou. He also don't like it that PHP and HTML are being interwoven too much. I don't know if Mark Zuckerberg shares the same sentiment.


One thing is for sure though, given that interweaving PHP and HTML is unavoidable, the integration should feel natural and make the integration cross-site-scripting-attack-proof. Facebook took a page from ASP.NET MVC Razor capabilities on this matter, Facebok created XHP. With XHP, they made interweaving PHP and HTML very seamless, PHP's output is now automatically HTML-escaped too, cross-site-scripting attacks can be avoided. Of course, I'm just massaging the ego of ASP.NET MVC programmers here, open-source folks doesn't need our innovations :-) Seamless integration between programming language and markup language is something everyone are pining for ever since everyone moved to web for rapid application development. I digress.




It's not surprising that AngularJS is the easiest to use JavaScript MVC framework, given that Misko Hevery created AngularJS as an easy-to-use framework for his JSON service business, which is priced by the megabyte. JSON service is a bad kind of business though, if they really wanted to earn well they should serve XML instead of JSON :D



While everyone is abuzz and getting nerdgasmic with the release of iPhone 5S last September 10, I'm eagerly anticipating and excited on the release of PostgreSQL 9.3 last September 9. JSON in PostgreSQL is becoming more and more a first-class language construct, API-wise and syntax-wise.



As for the reason why the excitement and how it relates to AngularJS, let's get to the core principle of AngularJS:


Every web-application is really just once complex marshaling problem. We marshal data from the DB, through the HTTP into the heap and to the DOM for the user to read, and then we do it all again in reverse order. At first this is fun, but after you build few applications, you very quickly get tired of marshaling your data through these layers, and I wanted to do something about it. -- Misko Hevery



While my friend is happy with lesser role of PHP in a web application development using AngularJS, any server-side languages for that matter, I'm stoked at the idea that we don't even need server-side languages at all. If only RDBMSes can expose RESTful services the way ServiceStack, ASP.NET Web API, WCF, JAX-RS and Recess Framework can do, the days of server-side languages would be numbered. Bye bye C#, PHP, Java, Ruby, you are so long, and thanks for all the fish.



RDBMS RESTful? I'm fancying that. But before we get there, let's see how easy it is to make web applications with AngularJS and the supercharged PostgreSQL JSON functionalities.



Here's how easy it is to serve JSON with PostgreSQL:

northwind=# with company_summary_info as 
(
    select c."CustomerID", c."CompanyName", c."ContactName"
    from customers c where c."ContactName" like 'A%'
)
select json_agg(i.*)
from company_summary_info i;
                                                 json_agg                                                  
-----------------------------------------------------------------------------------------------------------
 [{"CustomerID":"ANATR","CompanyName":"Ana Trujillo Emparedados y helados","ContactName":"Ana Trujillo"}, +
  {"CustomerID":"ANTON","CompanyName":"Antonio Moreno Taquería","ContactName":"Antonio Moreno"},          +
  {"CustomerID":"EASTC","CompanyName":"Eastern Connection","ContactName":"Ann Devon"},                    +
  {"CustomerID":"FAMIA","CompanyName":"Familia Arquibaldo","ContactName":"Aria Cruz"},                    +
  {"CustomerID":"GOURL","CompanyName":"Gourmet Lanchonetes","ContactName":"André Fonseca"},               +
  {"CustomerID":"LAMAI","CompanyName":"La maison d'Asie","ContactName":"Annette Roulet"},                 +
  {"CustomerID":"MORGK","CompanyName":"Morgenstern Gesundkost","ContactName":"Alexander Feuer"},          +
  {"CustomerID":"ROMEY","CompanyName":"Romero y tomillo","ContactName":"Alejandra Camino"},               +
  {"CustomerID":"SPLIR","CompanyName":"Split Rail Beer & Ale","ContactName":"Art Braunschweiger"},        +
  {"CustomerID":"TRADH","CompanyName":"Tradição Hipermercados","ContactName":"Anabela Domingues"}]
(1 row)


Very easy.


The plus signs doesn't turn up in actual JSON result, it's just presented that way by PostgreSQL's commandline tool. The type returned is not a string, PostgreSQL has a JSON datatype. Being a first-class data type that it is, you can manipulate it further with PostgreSQL's superb JSON API and operators.




Returning a JSON paged result(along with total records count) with the latest PostgreSQL:

create or replace function get_customers(p_pageNumber int, p_pageSize int) returns json
as
$$
begin

return (
    with src as
    (
        select c."CustomerID", c."CompanyName", c."ContactTitle", c."ContactName", c."City"
        from customers c
        order by c."CompanyName"
    ),
    paged as
    (
        select * 
        from src
        offset ((p_pageNumber - 1) * p_pageSize)        
        limit p_pageSize
    ),
    returnedJson as
    (
        select  
            (select json_agg(p.*) from paged p) as list,
            (select count(*) from src) as count
    )
    select row_to_json(r.*) from returnedJson r
);  
    
end;
$$ language 'plpgsql';    
 
 


Sample result:

northwind=# select get_customers(1,10);
                                                                            get_customers                                                                            
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
 {"list":[{"CustomerID":"ALFKI","CompanyName":"Alfreds Futterkiste","ContactTitle":"Sales Representative","ContactName":"Maria Anders","City":"Berlin"},            +
  {"CustomerID":"ANATR","CompanyName":"Ana Trujillo Emparedados y helados","ContactTitle":"Owner","ContactName":"Ana Trujillo","City":"México D.F."},               +
  {"CustomerID":"ANTON","CompanyName":"Antonio Moreno Taquería","ContactTitle":"Owner","ContactName":"Antonio Moreno","City":"México D.F."},                        +
  {"CustomerID":"AROUT","CompanyName":"Around the Horn","ContactTitle":"Sales Representative","ContactName":"Thomas Hardy","City":"London"},                        +
  {"CustomerID":"BSBEV","CompanyName":"B's Beverages","ContactTitle":"Sales Representative","ContactName":"Victoria Ashworth","City":"London"},                     +
  {"CustomerID":"BERGS","CompanyName":"Berglunds snabbköp","ContactTitle":"Order Administrator","ContactName":"Christina Berglund","City":"Luleå"},                 +
  {"CustomerID":"BLAUS","CompanyName":"Blauer See Delikatessen","ContactTitle":"Sales Representative","ContactName":"Hanna Moos","City":"Mannheim"},                +
  {"CustomerID":"BLONP","CompanyName":"Blondesddsl père et fils","ContactTitle":"Marketing Manager","ContactName":"Frédérique Citeaux","City":"Strasbourg"},        +
  {"CustomerID":"BONAP","CompanyName":"Bon app'","ContactTitle":"Owner","ContactName":"Laurence Lebihan","City":"Marseille"},                                       +
  {"CustomerID":"BOTTM","CompanyName":"Bottom-Dollar Markets","ContactTitle":"Accounting Manager","ContactName":"Elizabeth Lincoln","City":"Tsawassen"}],"count":91}
(1 row)


Here's how to extract the values from JSON:

create or replace function save_customer(p_customer json) returns json
as
$$
begin
    
    if not exists(
        select * from customers
        where "CustomerID" = p_customer->>'CustomerID') then

        insert into customers
        ("CustomerID","CompanyName","ContactName","ContactTitle","City",
        "Region", "PostalCode", "Country", "Phone", "Fax"
        )   
        select
            p_customer->>'CustomerID',
            p_customer->>'CompanyName',
            p_customer->>'ContactName',
            p_customer->>'ContactTitle',
            p_customer->>'City',
            '', -- Region
            '', -- PostalCode
            '', -- Country
            '', -- Phone
            ''; -- Fax
                        
    else

        update Customers set    
            "CompanyName" = p_customer->>'CompanyName',
            "ContactName" = p_customer->>'ContactName',
            "ContactTitle" = p_customer->>'ContactTitle',
            "City" = p_customer->>'City'            
        where "CustomerID" = p_customer->>'CustomerID';
        
    end if;

    return (with src as
    (
        select c."CustomerID", c."CompanyName", c."ContactTitle", c."ContactName", c."City"
        from customers c
        where c."CustomerID" = p_customer->>'CustomerID'
        order by c."CompanyName"
    )
    select row_to_json(c.*) from src c);

end;
$$ language 'plpgsql';


Now, how about our PHP web developers? What is now the use of their decades-long experience on PHP? Following code is the thinnest and fastest marshaller of data to your web app, courtesy of PostgreSQL's superb JSON functionality


Serving paged results:

<?php 
    header('Access-Control-Allow-Headers: Content-Type, application/json, X-Requested-With');
    header("Access-Control-Allow-Origin: *"); 

    $pageNumber = $_GET["PageNumber"];
    $pageSize = $_GET["PageSize"];
    
    $con = pg_connect("host=localhost port=5433 dbname=northwind user=postgres password=opensesame93");

    $res = pg_query_params($con, "select get_customers($1,$2)", array($pageNumber, $pageSize));
    
    if ($res) {
        $row = pg_fetch_row($res);
        echo $row[0];
    }
    else {
        echo "Error";       
    }
?>


Serving persistence requests:

<?php 

    header('Access-Control-Allow-Headers: Content-Type, application/json, X-Requested-With');
    header("Access-Control-Allow-Origin: *"); 
    
    $con = pg_connect("host=localhost port=5433 dbname=northwind user=postgres password=opensesame93");

    
    $data = file_get_contents("php://input");   
    
    /*  
    $getData = json_decode($data);  
    $CompanyName = $getData->CompanyName;
    */
        
    $res = pg_query_params($con, "select save_customer($1)", array($data));
        
    if ($res) {
        $row = pg_fetch_row($res);
        echo $row[0];
    }
    else {
        echo "Error";       
    }
  
?>


For our web designer bretheren, they would be delighted that there's no more server-side languages that gets in the way between them and their beloved HTML and CSS, they could change the tags and css to their heart's content as long they keep in mind some basic HTML principles like ng-repeat and moustache tags. With AngularJS, web designer could now work in parallel and independently from web developers.


Customers.html
<!DOCTYPE html>
<html ng-app="sampleApp">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="angularjs-twitter-bootstrap/assets/bootstrap.css"/>

    <script src="angularjs/angular.min.js"></script>

    <script src="angularjs-twitter-bootstrap/ui-bootstrap-0.6.0.min.js"></script>

    <script src="app.js"></script>

    <title></title>
</head>
<body ng-controller="CustomersCtrl">

<p>PostgreSQL loved by DBAs and Application Developers alike</p>


<div class="form-inline">
    <div class="btn-group">
    <button type="button" class="btn btn-default btn-sm" ng-click="prevPage()" ng-disabled="!(pageNumber > 1)">Previous</button>
        <button type="button" class="btn btn-default btn-sm"  ng-click="nextPage()" ng-disabled="isLastPage()">Next</button>
    </div>

    <input type="number" ng-model="pageNumber" ng-change="getCustomers()" style="width:50px">
    <select ng-model="pageSize" ng-options="opt for opt in pageSizeOptions" ng-change="getCustomers()"></select>
</div>


<p></p>


<div class="panel panel-default">
    <div class="panel-heading">Customers: {{customers.count}}</div>
    <table class="table">
        <thead>
            <th>
                <i class="icon-large icon-plus-sign" style="width: 20px"></i>
            </th>
            <th>Company</th>
            <th>Contact Title</th>
            <th>Contact</th>
            <th>City</th>
        </thead>

        <tbody>
            <tr ng-repeat="c in customers.list">
                <td ng-click="showForm(c)"
                    style="cursor: pointer;">
                    <i  class="icon-large icon-pencil"
                        style="width: 20px">
                     </i>
                </td>
                <td>{{c.CompanyName}}</td>
                <td>{{c.ContactTitle}}</td>
                <td>{{c.ContactName}}</td>
                <td>{{c.City}}</td>
            </tr>
        </tbody>

    </table>
</div>


</body>

</html>


CustomersForm.html
<div class="modal-header">
    <h3>{{Customer.CustomerID}}</h3>
</div>
<div class="modal-body">

    <div class="form-inline">
    Company: <input type="text" ng-model="Customer.CompanyName">
    </div>


</div>
<div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>


Here's the AngularJS code, the glue framework. This is now where the battle-scarred web application developers need to turn their discipline to:

var theApp = angular.module('sampleApp', ['ui.bootstrap']);


theApp
    .controller('CustomersCtrl',['$scope','$http', '$modal', function ($scope, $http, $modal) {

        $scope.customers = { count: 0 };
        $scope.pageNumber = 1;
        $scope.pageSize = 10;
        $scope.pageSizeOptions = [5, 10, 15, 20, 25];


        $scope.pageNumber = 1;



        $scope.getCustomers = function() {
            var pageNumber = $scope.pageNumber;
            var pageSize = $scope.pageSize;

            $http({
                url: 'http://192.168.254.100/getCustomers.php',
                method: 'GET',
                params: { PageNumber: pageNumber, PageSize : pageSize }
            }).success(function (data, status, headers, config) {
                    $scope.customers = data;
            }).error(function(data, status, headers, config) {
                    $scope.message = "error";
            });

        }



        $scope.showForm = function(customer) {
            var modalInstance = $modal.open({
                templateUrl: 'CustomersForm.html',
                controller: 'CustomersFormCtrl',
                resolve: {
                    Customer: function () {
                        return angular.copy(customer);
                    },
                    refresher : function() {
                        return $scope.refresh;
                    }
                }
            });
        };

        $scope.refresh = function() {
            $scope.getCustomers();
        };


        $scope.nextPage = function() {
            ++$scope.pageNumber;
            $scope.getCustomers();
        };

        $scope.prevPage = function() {
            if ($scope.pageNumber == 1) return;
            --$scope.pageNumber;
            $scope.getCustomers();
        };

        $scope.isLastPage = function() {
            return Math.ceil($scope.customers.count / $scope.pageSize) == $scope.pageNumber;
        };



        $scope.getCustomers();


    }])

    .controller('CustomersFormCtrl', ['$scope','$http', '$modalInstance', 'Customer', 'refresher',
        function ($scope, $http, $modalInstance, Customer, refresher) {

        $scope.Customer = Customer;


        $scope.ok = function () {

            $http({
                url: 'http://192.168.254.100/saveCustomer.php',
                method: 'POST',
                data: $scope.Customer,
                headers: {'Content-Type': "application/json"}
            }).success(function (data, status, headers, config) {

                $modalInstance.dismiss('ok');
                refresher();

            }).error(function(data, status, headers, config) {

                // called asynchronously if an error occurs
                // or server returns response with an error status.

                $scope.message = "error";
            });


        };

        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };

    }]);


* The humor of the phrase is not lost on me. The phrase was alluded to what the dolphin said on Hitchhiker's Guide To The Galaxy. Dolphin, being a MySQL mascot, could have titled this blog post as "So long, and thanks for all the dolphins" lol



Happy Coding! ツ

Wednesday, October 2, 2013

Access-Control-Allow-Headers error

Should not be done separately:

header('Access-Control-Allow-Headers: Content-Type, application/json');
header('Access-Control-Allow-Headers: X-Requested-With'); 


All access should be included on one setting:
header('Access-Control-Allow-Headers: Content-Type, application/json, X-Requested-With');

Saturday, September 21, 2013

Gravity Always Wins

It's very common that when CRT monitor is being rotated (turning to portrait mode) while it is turned on it becomes discolorized, the color tends to go back to normal after a few minutes. So when rotating a CRT monitor, it's better to turn it off first. The components of a CRT monitor which are very heavy, tend to be stressed when rotating the CRT monitor, the stressing effect is more pronounced when you are rotating the CRT monitor while it's turned on.


That discoloration doesn't happen on modern LCDs, so it's surprising when a colleague is rotating his LCD monitor, the screen color is turning yellowish. There got to be an explanation for the discoloration, and why most often it's yellowish, why not some color like fuschia? :p


I have a pivot-capable LCD monitor at home, but there's no discoloration happening even I'm rotating the LCD while the power is on.


So what's the difference between the LCD at home and office? The LCD in our office happens to use VGA cable instead of HDMI or DVI. VGA cables tend to loosen when not screwed tightly. And those pins in VGA cable has their own color task. Those pins carries signals for colors. For the illustration:



So that's the explanation for the yellow. When rotating a VGA cable-equipped LCD monitor, the VGA cable is loosening a bit, the RED and GREEN pin still sticks, while the BLUE is loosening a bit when the VGA cable is being oriented vertically. RED + GREEN === YELLOW, that's for 90 degree. When rotating to 180 degree the screen discolorized to CYAN, i.e., the RED loosens, leaving the display with just two color signals instead, GREEN and BLUE, which when combined becomes CYAN.

As for why discoloration doesn't happen on HDMI and DVI for that matter, both cables are not analog, i.e. they don't carry signals, what they carries are data instead. So there's no such thing on an HDMI-equipped LCD for a BLUE pin that loosens while rotating it.



Happy Coding! ツ

Monday, September 9, 2013

SQL Server Said, PostgreSQL Said. APPLY and LATERAL

SQL Server CROSS APPLY:
select m.*, elder.*
from Member m
cross apply
(
    select top 1 ElderBirthDate = x.BirthDate
    from Member x 
    where x.BirthDate < m.BirthDate 
    order by x.BirthDate desc
) as elder
order by m.BirthDate
Equivalent on PostgreSQL:
select m.*, elder.*
from Member m
join lateral 
(
    select x.BirthDate as ElderBirthDate, x.FirstName as ElderFirstName
    from Member x 
    where x.BirthDate < m.BirthDate 
    order by x.BirthDate desc
 limit 1
) as elder on true -- Though PostgreSQL's LATERAL offers more flexibility than SQL Server's APPLY, I haven't yet found a use case to use a condition on LATERAL, hence the hardcoded true
order by m.BirthDate
Note, a JOIN LATERAL(explicitly INNER JOIN LATERAL) with a condition of always true, is essentially a cross join. We can rewrite the PostgreSQL code above as follows:
select m.*, elder.*
from Member m
cross join lateral 
(
    select x.BirthDate as ElderBirthDate, x.FirstName as ElderFirstName
    from Member x 
    where x.BirthDate < m.BirthDate 
    order by x.BirthDate desc
    limit 1
) as elder -- we don't need to put any condition here anymore since this is a cross join
order by m.BirthDate
SQL Server OUTER APPLY:
select m.*, elder.*
from Member m
outer apply
(
    select top 1 ElderBirthDate = x.BirthDate, ElderFirstname = x.Firstname
    from Member x 
    where x.BirthDate < m.BirthDate 
    order by x.BirthDate desc
) as elder
order by m.BirthDate
Equivalent on PostgreSQL:
select m.*, elder.*
from Member m
left join lateral 
(
    select x.BirthDate as ElderBirthDate, x.FirstName as ElderFirstName
    from Member x 
    where x.BirthDate < m.BirthDate 
    order by x.BirthDate desc
    limit 1
) as elder on true -- Though PostgreSQL's LATERAL offers more flexibility than SQL Server's APPLY, I haven't yet found a use case to use a condition on LATERAL, hence the hardcoded true
order by m.BirthDate
Related: http://www.ienablemuch.com/2012/04/outer-apply-walkthrough.html


Happy Coding! ツ

Monday, September 2, 2013

Yes please, pass the smart data structure

“Smart data structures and dumb code works a lot better than the other way around” -- http://stackoverflow.com/questions/2953867/example-of-eric-raymonds-smart-data-structures-principle



“If the data structures are quality tools, they will make the rest of the code easier and cheaper to write. By having high quality data structures, you reduce the effort required for the rest of the code.” -- http://stackoverflow.com/questions/2953867/example-of-eric-raymonds-smart-data-structures-principle



“Show me your code and conceal your data structures, and I shall continue to be mystified. Show me your data structures, and I won’t usually need your code; it’ll be obvious.” -- http://blog.mongolab.com/2012/08/why-is-mongodb-wildly-popular/



“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” -- http://programmers.stackexchange.com/questions/163185/torvalds-quote-about-good-programmer



Don’t fell in love with code so much. Love smart and intuitive data structure instead, achieving that, the code almost writes itself. The smarter the data structure one have, the lesser the code one needs to write.



For example, if you have the following bar chart:



If you are passing the ordinal (this.x) of the clicked bar chart to the service, i.e. Goals = 0, Self-Assessment = 1, Review = 2, etc., your code need to interpret on the service layer what was clicked by the user. And what's more annoying is if there are some gaps in the chart, say the chart can be customized, the Self-Assessment is not present on the chart, the rest of the bar charts need to have their ordinal be adjusted too. Goals = 0, Review = 1, Objective = 2, etc. So on the service layer, the code should not blindly interpret that 1 is equal to Self-Assessment, as 1 is now a Review.


If the data being passed to service is not smart, the code on the service need to re-interpret the meaning of the data being passed to it, the code on the service need to be very smart, this makes the code very brittle when there are regular changes on the app.


We should make the data smarter, it would result to lesser code, small and straightforward code is easier to read and debug. One way to make the value being passed from bar chart to service smarter is to generate a corresponding array when the bar charts are generated. So instead of passing the ordinal...


events: {
    click : function() {
                  
        
        // pass the ordinal value this.x to service layer via ajax
        
    }
}


...do this instead:
var sections = ['G','S','R','O','F']; // dynamically-generated

.
.
.

events: {
    click : function() {
                  
   
        var section = sections[this.x]; // use a smarter data structure, use something that has a semantics upfront

        // pass the section value to service layer via ajax
        
    }
}


Accomplishing that, the code on the service layer won't have a need to re-interpret the meaning of the value being passed to it. Call the usage of smarter data structure a domain-driven development if you will, a dumb data structure such as ordinal doesn't carry any semantics, the quality of the code will suffer consequently.





Happy Coding! ツ

Friday, August 30, 2013

Old dog employing old tricks

I downloaded a code from this tutorial: http://maniacdev.com/2010/08/beginners-iphone-action-game-tutorial


But when compiling, this has an error:
// zero out memory. (do not overwrite isa & mPoolPredecessor, thus "+2" and "-8")
memset((id)object + 2, 0, malloc_size(object) - 8);


The error:
Arithmetic on pointer to interface 'id', which is not a constant size for this architecture and platform


Presumably, that works on older version of Xcode or Objective-C. This is how I was able to make it run:
// zero out memory. (do not overwrite isa & mPoolPredecessor, thus "+2" and "-8")
memset((id) (((int *)object) + 2), 0, malloc_size(object) - 8);



Happy Computing! ツ

Saturday, August 17, 2013

Agile vs Waterfall

Earliest known record of Agile Practice

Winston Churchill on agile: "It is a mistake to look too far ahead. Only one link of the chain of destiny can be handled at a time." -- CompSciFact



Contrast that with waterfall:

"It's called Waterfall project methodology because the products fall downward." - natashairizarry



The reply to waterfall is just as good:

@shanselman @natashairizarry "you end up going over the top and, after a long drop where everything breaks, no one wants to do it again" -- frequentlyrare

Sunday, August 4, 2013

Learning

"Learning Haskell even though you don't use it for work is just like running, cycling, and swimming even though you aren't a pro triathlete." -- https://twitter.com/raganwald/status/333945282226184192

Notable comment:

"@raganwald True for all new modalities. Learn orthogonal to what you know, increase the dimensionality of your mind!" -- https://twitter.com/drsteveplatt/status/335804367070445569


There's a chatter in office about the usefulness(or perceived non-usefulness) of Pluralsight account for all engineers. There are some engineers who thinks it's not useful for them, perhaps they are just learning what they already know. There are tons of courses on Pluralsight that can increase the dimensionality of your mind, don't get stuck with one form of knowledge.


Pluralsight is an apt name, it's where we can see many forms of knowledge.

Sunday, July 28, 2013

Xcode 4.5.2 IBOutlet not showing on context menu

IBOutlet will not appear when you show contextual menu on Label:





Context menu must be done on File's Owner:

Friday, July 12, 2013

Seamless dynamic SQL using PostgreSQL

Have you seen seamless dynamic query on a SQL Server function?

Neither do I, so I will show to you a PostgreSQL approach.

To cut to the chase, here's the query:

create or replace function DynamicSql(p_fields varchar)
    returns table
    (    
        "YouKnowMyName" varchar,
        "LookupTheNumber" int
    ) as    
$$
declare
    sql varchar;    
begin

    sql = 'select ' || p_fields || ' from employees';
    
    return query execute sql;
end;
$$ language 'plpgsql';

select * from DynamicSql(' "LastName", "EmployeeID" ' );
select * from DynamicSql(' "FirstName", "EmployeeID" ' );

Look Ma! No Drama!



Contrast that on how it is done on other database *cough* Sql Server Table-Valued Function via CLR *cough*:

http://www.ienablemuch.com/2013/07/streaming-table-valued-function-via-clr.html

Darn, that's a long cough, gotta use my IntelliCare and go to Saint Luke's Medical Center


Accomplishing dynamic SQL on a Table-Valued Function via CLR is too ceremonial and has too much drama, y'know you gotta need to accomplish all of these: FillRowMethodName, Streaming Table-Valued Functions via yield return, assembly signing, sp_configure 'clr enabled', create asymmetric key, grant external access, blah blah and all that shiznit.


Microsoft should be included on the list of featured PostgreSQL users given that Microsoft bought Skype. I Love Technology!


"You already trust PostgreSQL, you just may not know it yet..." -- http://www.2ndquadrant.com/en/who-uses-postgresql/

Happy Coding! ツ

Wednesday, July 10, 2013

Transposing columns to rows.

You have already probably done some crosstab query from your favorite RDBMS, i.e. the rows are transposed to columns.

But how about a reverse crosstab(a.k.a. reverse pivot)? You got columns that you wanted to transpose to rows.

That is, you need to display this...

testdb-# 

with p as
(
    select *, firstname || ' ' || lastname as fullname 
    from person 
)
select * from p;


 person_id | lastname  |  firstname   | nickname | favorite_number |       fullname       
-----------+-----------+--------------+----------+-----------------+----------------------
         1 | lennon    | john winston | john     |                 | john winston lennon
         2 | mccartney | james paul   | paul     |                 | james paul mccartney
         3 | harrison  | george       |          |                 | george harrison
         4 | starr     | richard      | ringo    |              10 | richard starr
(4 rows)


...as this:
person_id  |      field      |        value         
-----------+-----------------+----------------------
         1 | favorite_number | 
         1 | firstname       | john winston
         1 | fullname        | john winston lennon
         1 | lastname        | lennon
         1 | nickname        | john
         1 | person_id       | 1
         2 | favorite_number | 
         2 | firstname       | james paul
         2 | fullname        | james paul mccartney
         2 | lastname        | mccartney
         2 | nickname        | paul
         2 | person_id       | 2
         3 | favorite_number | 
         3 | firstname       | george
         3 | fullname        | george harrison
         3 | lastname        | harrison
         3 | nickname        | 
         3 | person_id       | 3
         4 | favorite_number | 10
         4 | firstname       | richard
         4 | fullname        | richard starr
         4 | lastname        | starr
         4 | nickname        | ringo
         4 | person_id       | 4
(24 rows)

On other RDBMS, you got to do this query:
with p as
(
    select *, firstname || ' ' || lastname as fullname 
    from person 
)
select 
    person_id,
    'firstname' as field,
    firstname as value
from p
union all
select 
    person_id,
    'firstname' as field,
    firstname as value
from p
union all
select 
    person_id,
    'lastname' as field,
    firstname as value
from p
union all
select 
    person_id,
    'nickname' as field,
    nickname as value
from p
union all
select 
    person_id,
    'fullname' as field,
    fullname as value
from p
union all
select 
    person_id,
    'favorite_number' as field,
    favorite_number::text as value
from p
order by person_id, field


That's very tedious.


If you are using Postgres, luckily there is a better way:

with p as
(
    select *, firstname || ' ' || lastname as fullname 
    from person 
)
select
    person_id,
    skeys(hstore(p)) as field, svals(hstore(p)) as value 
from p
order by person_id, field

That's more maintainable, even if you add another column on the main query, your key value pair query need not be modified.



There's another approach (darn, PostgreSQL is too flexible! :D)
with p as
(
    select *, firstname || ' ' || lastname as fullname 
    from person 
)
select 
    p.person_id,
    unnest(array['person_id', 'favorite_number', 'firstname','fullname','lastname', 'nickname']) as field_label,
    unnest(array[cast(p.person_id as text), cast(p.favorite_number as text), p.firstname, p.fullname, p.lastname, p.nickname])  as field_value
from p
order by p.person_id, field_label



That's it folks. Happy Computing! ツ


Data Source:
create table person
(
 person_id serial not null primary key,
 lastname text not null,
 firstname text not null,
 nickname text null,
 favorite_number int null
);
 
 
insert into person(lastname,firstname,nickname, favorite_number) values
('lennon','john winston','john',default),
('mccartney','james paul','paul',default),
('harrison','george',default,default),
('starr','richard','ringo', 10);

Sunday, July 7, 2013

Seamless numeric localization with AngularJS

Have you seen seamless numeric localization with jQuery?

Neither do I, so I'll just offer you an AngularJS approach.

To make an input locale-aware we just need to add an attribute to make it capable as such. And make a directive for that attribute.

Localization with AngularJS is very easy. And we don't have to change anything on the controller to make it work on other language.

To make an input locale-aware we just need to add an attribute to make it capable as such. And make a directive for that attribute.


Old code:
<input type="text" ng-model="untaintedNumber"/>

Locale-aware code:
<input type="text" ng-model="untaintedNumber" numeric decimal-places="decPlaces" ng-change="showInLog()">



This is the definition for numeric and decimal-places attribute:

module.directive('numeric', function($filter, $locale) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
        
            var decN = scope.$eval(attr.decimalPlaces); // this is the decimal-places attribute

        
            // http://stackoverflow.com/questions/10454518/javascript-how-to-retrieve-the-number-of-decimals-of-a-string-number
            function theDecimalPlaces(num) {
                   var match = (''+num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
                   if (!match) { return 0; }
                      return Math.max(
                       0,
                       // Number of digits right of decimal point.
                       (match[1] ? match[1].length : 0)
                       // Adjust for scientific notation.
                       - (match[2] ? +match[2] : 0));
            }
        
            function fromUser(text) {                   
                var x = text.replaceAll($locale.NUMBER_FORMATS.GROUP_SEP, '');
                var y = x.replaceAll($locale.NUMBER_FORMATS.DECIMAL_SEP, '.');
                                           
                return Number(y); // return a model-centric value from user input y
            }

            function toUser(n) {
                return $filter('number')(n, decN); // locale-aware formatting
            }
        
            ngModel.$parsers.push(fromUser);
            ngModel.$formatters.push(toUser);
        
            element.bind('blur', function() {
                element.val(toUser(ngModel.$modelValue));
            });
        
            element.bind('focus', function() {            
                var n = ngModel.$modelValue;
                var formattedN = $filter('number')(n, theDecimalPlaces(n));
                element.val(formattedN);
            });
        
        } // link
    }; // return
}); // module


String replaceAll definition:

String.prototype.replaceAll = function(stringToFind,stringToReplace){
    if (stringToFind === stringToReplace) return this;

    var temp = this;
    var index = temp.indexOf(stringToFind);
        while(index != -1){
            temp = temp.replace(stringToFind,stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
};


This is the controller, nothing needed be changed. The controller action changeValue keeps the old code.

function Demo($scope) {

    $scope.decPlaces = 2;

    $scope.untaintedNumber = 1234567.8912;

    $scope.changeValue = function() {
    
        // The model didn't change to string type, hence we can do business as usual with numbers.
        // The proof that it doesn't even change to string type is we don't even need 
        // to use parseFloat on the untaintedNumber when adding a 7 on it. 
        // Otherwise if the model's type mutated to string type, 
        // the plus operator will be interpreted as concatenation operator: http://jsfiddle.net/vuYZp/
        // Luckily we are using AngularJS :-)        
        $scope.untaintedNumber = $scope.untaintedNumber + 7;
    
        // contrast that with jQuery where everything are string:
        // you need to call both $('elem').val() and Globalize's parseFloat, 
        // then to set the value back, you need to call Globalize's format.
    
        /*              
        var floatValue = Globalize.parseFloat($('#uxInput').val());
        floatValue = floatValue * 2;        
        var strValue = Globalize.format(floatValue, "n4");
        $('#uxInput').val(strValue);
        */
    
    };

    $scope.showInLog = function() {
        console.log($scope.untaintedNumber);     
    };

}


Live Code: http://jsfiddle.net/F5PuQ/

Wednesday, July 3, 2013

Do you have a seek sense? Can you see dead code?

The original query is redacted to protect the innocent.

What's wrong with the following query? Can you spot the dead code?

create table tosses
(
  attempt int identity(1,1) primary key,
  fate char(1),
  constraint ck_tosses check(fate in ('H','T') or fate is null)
);

insert into tosses(fate) values
('H'),
('H'),
(null),
('T'),
(null),
('H'),
('T');

select
    attempt,
    fate,
    case fate 
    when 'H' then 'Head' 
    when 'T' then 'Tail'
    when null then 'Fate not yet determined'
    else 'http://9gag.com/gag/4380545'
    end as fate_result
from tosses

Live code: http://www.sqlfiddle.com/#!3/6a61e/2

The output of that is this:



| ATTEMPT |   FATE |                 FATE_RESULT |
--------------------------------------------------
|       1 |      H |                        Head |
|       2 |      H |                        Head |
|       3 | (null) | http://9gag.com/gag/4380545 |
|       4 |      T |                        Tail |
|       5 | (null) | http://9gag.com/gag/4380545 |
|       6 |      H |                        Head |
|       7 |      T |                        Tail |

The dead code is the WHEN NULL, the else part on the query above is just a decoy ツ To correct the dead code, we should change the WHEN NULL to WHEN fate IS NULL
select
    attempt,
    fate,
    case when fate is null then 'Fate not yet determined'
    else
        case fate 
        when 'H' then 'Head' 
        when 'T' then 'Tail'
        else 'http://9gag.com/gag/4380545'
        end
    end as fate_result
from tosses

Live code: http://www.sqlfiddle.com/#!3/6a61e/3

Output:
| ATTEMPT |   FATE |             FATE_RESULT |
----------------------------------------------
|       1 |      H |                    Head |
|       2 |      H |                    Head |
|       3 | (null) | Fate not yet determined |
|       4 |      T |                    Tail |
|       5 | (null) | Fate not yet determined |
|       6 |      H |                    Head |
|       7 |      T |                    Tail |  

You can also do the other form of CASE expression:
select
    attempt,
    fate,

    case
    when fate = 'H' then 'Head'
    when fate = 'T' then 'Tail'
    when fate is null then 'Fate not yet determined'
    else 'http://9gag.com/gag/4380545'    
    end as fate_result

from tosses

Live code: http://www.sqlfiddle.com/#!3/6a61e/4

Output:
| ATTEMPT |   FATE |             FATE_RESULT |
----------------------------------------------
|       1 |      H |                    Head |
|       2 |      H |                    Head |
|       3 | (null) | Fate not yet determined |
|       4 |      T |                    Tail |
|       5 | (null) | Fate not yet determined |
|       6 |      H |                    Head |
|       7 |      T |                    Tail |  


On both form of the correct query above, the dead code in that query is no longer the NULL scenario, the dead code is the ELSE part as we have CHECK constraint in place.


Happy Coding! ツ

Wednesday, June 26, 2013

Kendo UI team made a beautiful AngularJS API

Kendo UI team's first foray on making an AngularJS API for Kendo UI. Angular Kendo UI v 0.0.9


function MyController($scope) {
  $scope.model = kendo.observable({
    var things = [ "Thing 1", "Thing 2", "Thing 3" ]
  });
}

// page
// No need to call bind, the AngularJS directive does it for you
<select id="things" data-role="dropdownlist" data-model="model" data-bind="source: things">
</select>


After pondering their Angular API above and feeling happy but not satisfied, they might have said something along these lines "Darn, that's not intuitive! Let's scrap MVVM observable noises and all that shiznit, JSON objects should be directly bindable to our widgets". Thus upon realizing that, Kendo UI Developer Relations team (their relationship to users/developers must be very important to give their team a name like that) made a second attempt to make their Angular API beautiful and less obnoxious by removing the observable thingie, and let the component users feel the magic by enabling the JSON objects be directly bindable to their Kendo widgets.


Contrast the above API with the following more intuitive API. This is the API that even a CTO would love to develop things around. Angular Kendo UI v 0.5.0


function MyController($scope) {
  $scope.things = [ "Thing 1", "Thing 2", "Thing 3" ]
}

<select kendo-drop-down-list k-data-source="things" k-option-label="'Select A Thing'" ></select>


Happy But Not Satisfied Coding! ツ


Read the rest at: http://www.kendoui.com/blogs/teamblog/posts/13-06-24/announcing-angular-kendo-ui.aspx

Wednesday, June 19, 2013

Web development for non-masochists. Even a CTO enjoys doing it

When a CTO realizes that most web developers are masochists for generating HTML at server-side technologies (I'm looking at you ASP.NET, ASP.NET MVC, JSF, Struts, Spring MVC and whathaveyou), he'll write an article showing us how to reduce boilerplate codes with AngularJS. A CTO can simplify web development and make it looks like a child's play:


"When your CTO goes off on a tangent and writes his own @angularjs directives and whitepaper. http://www.codeproject.com/Articles/607873/Extending-HTML-with-AngularJS-Directives … #wijmo #ComponentOne" -- https://twitter.com/b4nn0n/status/347020882511818752



"AngularJS + Kendo UI Grid: deferred data source, inline editing w/ two way data binding http://plnkr.co/edit/MBjO2QBkpDoqDGD2NDR2?p=preview" -- https://twitter.com/kevinhillinger/statuses/325949992378454016



CTOs should not know AngularJS, it will give them the impression that web development is very easy, the impression is valid however ツ





Happy Coding! ツ

Sunday, June 2, 2013

The Unwritten Rule, or When Should We Use Our Best Judgement

Those who want everything be in written rule, are those who have zero tolerance when some of their colleagues deviate a bit from the project's "standards." Those are the same kind of people who loves to maintain a whitelist of stuff that should be conformed to instead of just maintaining a blacklist of stuff that can't be violated.



The wife, daughter and I went some place and rode a train. There's a designated car(or is it called a coach or carriage?) of the train for women, children and elderly. Even it's not explicitly stated or written, a father can go with his family on that specially designated train's car. And mind you, I'm not an elderly, if you don't believe, you get off my lawn! A whitelist kind of person would love to make it explicit that a father can go with his family on that specially designated part of the train



To make the point more dramatic, imagine you are an employee or when you were/are still a student. It will be annoying as hell if some authoritarian opted for a whitelist of websites you can only visit, instead of just maintaining a blacklist. Does it sit well with you if the internet in your company or home has a whitelist of websites that you can only visit?



The world is abound with very creative people, don't stifle their creativity, don't make it hard for them to hone their craft. Don't make a laundry list of things that they can only do or use; instead, just maintain a list of things that people can't do or use.



So if someone or a colleague said to you, "oh we cannot do that, we have a prescribed list of things that we can only do and should be adhered to", ask the person if he/she is a whitelist kind of person or a blacklist one. And if it could help, ask his/her personality compass. So at least you can understand the person, not that you need/don't need to believe the person, but at least you can understand the person and make the right approach when dealing with them.



#ZeroTolerance policies are absurd because they, by definition, exclude the application of #CommonSense. -- https://twitter.com/bryancostanich/status/337286120851251202



I would rather mentally note 10 things I can't do, than remember 100 things I can only do. I'm not a religious person, but I believe the Bible's Ten Commandments format makes sense, basically it's just a blacklist of things that we should not do, easier to remember and follow. Everything else are mostly subjective

Thursday, May 16, 2013

SELECT DISTINCT, a code smell

I was about to write why we should avoid SELECT DISTINCT, as it looks like a red flag that there’s some wrong in logic of the query. DISTINCT looks like a case of Hope-Driven-Development, hoping that DISTINCT won’t kill performance, and hoping it’s sufficient enough to eliminate the error in the logic of the query; and certainly, Hope Is Not a Strategy. We tend to use DISTINCT, either there’s something wrong in the logic of the query and/or when the database is not properly normalized. Fortunately, there are already plenty of articles that explains this SQL anomaly very well





* In 9 out of 10 cases when I encountered a "Select distinct", the programmer tried to remove duplicate rows caused by joins along multiple too-many associations (AKA cartesian product). This not only is bad programming style, it might also kill performance. -- http://arnosoftwaredev.blogspot.com.au/2011/01/is-select-distinct-code-smell.html




* A SELECT DISTINCT query is frequently a "code smell"; it indicates that something is not quite right. That is because using the DISTINCT keyword means that redundant data is being pulled from the database and then discarded. Usually it is better to rewrite the query's FROM and WHERE clauses to use a subquery to filter the data correctly so that you only get back what you want. -- http://www.databasejournal.com/features/postgresql/article.php/3437821/SELECT-DISTINCT-A-SQL-Case-Study.htm




* Use of “SELECT DISTINCT” to mask a join problem (Nick Harrison) -- https://www.simple-talk.com/blogs/2010/11/22/listing-common-sql-code-smells/




* The SELECT DISTINCT is rarely used in a properly designed schema. It is a “code smell”, symptom and not proof -- http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=159603



Good read: http://c2.com/cgi/wiki?SelectDistinctIsaCodeSmell



Happy Coding! ツ

Wednesday, May 15, 2013

Database convention that prevents confusions

Don't do it like this:
Order:
    OrderId     PK
    Date
    Description



LineItem:
    LineItemId  PK  
    OrderId     FK
    ProductId   FK
    Qty
    UnitPrice
    Amount


To the uninitiated, the LineItem table will look like an standalone table, wherein OrderId will seems like a ProductId column too. Meaning, LineItem's OrderId seems something that can be changed by the user (e.g. via dropdown). Where in actual application, the OrderId on LineItem is something that is set by the app and not being set by the user, not visible to user.



To emphasize that the LineItem only makes sense within the domain of Order and is not a standalone table, and consequently emphasizing that the LineItem's OrderId is not a user-selectable value, move the OrderId before the LineItemId primary key. That is, any foreign key that is before the primary key, should be treated as immutable foreign key.


LineItem table will now look like this:
LineItem:
    OrderId     FK
    LineItemId  PK  
    ProductId   FK
    Qty
    UnitPrice
    Amount             





Placing the immutable foreign key before the primary key is also especially useful when you have a third table(e.g. Preference) on which the defined relationship is not readily apparent. For example:
Product:
    ProductId       PK
    ProductName
    
    
Reseller:
    ResellerId      PK
    ResellerName 
    

Preference:
    PreferenceId    PK
    ProductId       FK
    ResellerId      FK
    PreferenceLevel


If you have a third table that has an unclear name and renaming the table is not an option (e.g. brownfield projects), you can at least move the owning FK before the primary key to emphasize the ownership of Preference table.


For example, if you are a supplier of products and you want to keep track your preferred resellers on each of your product, it's good to structure your Preference table like this:
Preference
    ProductId       FK
    PreferenceId    PK
    ResellerId      FK
    PreferenceLevel


In that case, moving the ProductId before the PreferenceId primary key indicates that the owning entity of the Preference table is the Product table. Hence the PreferenceLevel on that table design, indicates your most preferred resellers for your given product down to the least preferred.



Likewise, if you move the ResellerId before the PreferenceId primary key:
Preference
    ResellerId      FK
    PreferenceId    PK  
    ProductId       FK
    PreferenceLevel


The PreferenceLevel value on that design indicates the most preferred products by a given reseller to buy from you, down to their least preferred. The owning entity on that Preference table is the Reseller


This is just one of the many simple database conventions you can apply to your database, and it can surely help anyone who will read and need to understand your domain entities' relationships.




Lastly, if you have a third table like this:
BookAuthor:
     BookAuthorId
     BookId
     AuthorId


It can also be named as AuthorBook:
AuthorBook:
     AuthorBookId
     AuthorId
     BookId



The third table can be named either way, this is usually called a junction table, this defines a many-to-many relationship, there is no one single owner of the junction table. The junction table is owned by both Book and Author entity. And the columns can be arranged either way too.


To emphasize that there is no single ownership of the junction table. Design your own convention to emphasize non-single ownership. First you can define the third table primary key be the first column of the table, and the two other columns as unique composite. You can also designate some naming convention, e.g. you can name the table like this:

Author_assoc_Book:
     Author_assoc_Book_Id
     AuthorId
     BookId

It's ok to give name your junction table a weird name, as junction tables without payload are usually hidden and not mapped to your ORM classes. On the example above, we put the word assoc between Author and Book, you can choose your own naming convention to emphasize the junction-ness of the table, just be consistent on the naming convention. On the order of entities on the junction table name, since there is no one single owner of the junction table, we can opt to just arrange the name of the two tables on the junction table name based on their alphabetical order to emphasize non-sole-ownership. So Author comes before Book, giving the junction table a name of Author_assoc_Book, not Book_assoc_Author. Likewise with the their columns arrangement, it's alphabetically arranged too, hence AuthorId comes before BookId.


Happy Coding! ツ

Sunday, May 12, 2013

NuGet on other platforms

How to use NuGet on other platforms, e.g. Mac, Linux, FreeBSD, etc

http://www.codedistillers.com/rui/2013/01/09/net-web-dev-on-mac-nuget-monodevelop-nancy/


Other platforms are good for developers who are moonlighting as astronauts, or if you are just simply a disenfranchised Windows developer


And oh, another Linux device is powering a satellite

Friday, May 10, 2013

Brownfield Projects Woes

Maintaining brownfield projects is a myth, especially if it reeks of technical debts. So they tend to be rewritten, and voila! a greenfield project!



5 reasons to use AngularJS in the corporate app world in order to avoid rewriting brownfield projects



And this is the coolness B-) On-the-fly unit test:



“By using Karma Test Runner given to you by the AngularJS generators in Yeoman, you can have your unit tests running all the time in the background, that way if you change anything and hit save, your tests will automatically re-run and you will know if you are breaking something, where you are breaking it, and if the tests are built correctly maybe even why you are breaking it.”

Saturday, May 4, 2013

Earworm, I kept humming the instrumental intro of Eat Bulaga

These past few weeks I keep humming the instrumental intro of Eat Bulaga while I'm coding, which only recently I was able to unlock the reason why. The instrumental intro of Eat Bulaga is eerily similar to Sing a Song.


Here's the line I keep humming on Sing a Song:


"Don't worry if it's not good enough" -- http://www.metrolyrics.com/sing-lyrics-lea-salonga.html


Very similar to Eat Bulaga's instrumental intro.


Subconciously, I'm singing a very developer-centric song. So the next time you hear someone humming Eat Bulaga, that doesn't automatically translate to them being an Eat Bulaga fan(not that I have a problem on people being a partisan of a given primetime show or TV network :)). For all we know, those developers are subconsciously seeking enlightenment on the quality of their work.


Code quality should be tempered with the reality of the deadlines. Code quality is important, but it's not a be-all and end-all of an application development. There's also this thing called Time-to-Market.


"Quality in development is important, but it has to be scaled appropriately" -- http://haacked.com/archive/2010/08/26/not-paid-to-write-code.aspx


Of course, code quality and time-to-market (that's deadline for us who are not on the frontlines) are not mutually exclusive. Both are achievable, when torn between those two, just remember that perfect is the enemy of the good. And there's the Pareto Principle that could guide us on achieving both.
And don't even tell you're a perfectionist. That's a humblebrag masquerading as a virtue. There are more people way more perfectionist than you, and that would reduce you to a mere humblebragger



So there's the feel-good tune of Eat Bulaga, the feel of the music resonates with developers ;-)


Happy Coding! ツ

XY Problem. If someone is looking for a fix on Y, ask them first: "What's the X?"

Nope, XY problem doesn't mean men are troubles lol


There are certain class of developers that are too enamored with their codes, that when they ask for help they will proudly show their codes first and ask help on those codes, rather than stating the problem itself first


So what is XY problem? That's the terminology for the scenario above.


"The X-Y Problem, as it is sometimes called, is a mental block which leads to enormous amounts of wasted time and energy, both on the part of people asking for help, and on the part of those providing help. It often goes something like this:

* User wants to do X.
* User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.
* User doesn't know how to do Y either.
* User asks for help with Y.
* Others try to help user with Y, but are confused because Y seems like a strange problem to want to solve.
* After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.
" -- http://mywiki.wooledge.org/XyProblem


So the next time around, before you even show how awesome your coding skills are, remember first that other people's time and energy are important, don't let it go wasted. Tell your X first, before you even show your Y.


Friends don't let friends waste time or energy on fixing the Y when a Y could even be discarded and go for a better solution when X is stated first.


The best code is no code at all. Code, especially the longer ones, distracts us from stating the intent/problem of the application.



Some developers just love to provide solution, even if it meant not writing a single line of code. They'll just purchase a Microsoft Word and sell it to you with a nice markup for their troubles heading to a software shop, and sip Pina Coladas on the beach the rest of the day. Ok, a lot of context is missing here, that's why this paragraph looks weird. See the XY problem connection on this paragraph? Y often looks weird if X is not stated. For the X, head to this blog post: http://haacked.com/archive/2010/08/26/not-paid-to-write-code.aspx



Other good sources on XY problem:

http://blog.spitfiremanagement.com/2013/04/10/avoid-the-xy-problem/


http://daniel-lange.com/archives/69-The-XY-problem-in-IT-management.html


"The XY problem is when you need to do X, and you think you can use Y to do X, so you ask about how to do Y, when what you really should do is state what your X problem is. There may be a Z solution that is even better than Y, but nobody can suggest it if X is never mentioned." -- http://meta.stackoverflow.com/questions/66377/what-is-the-xy-problem

Thursday, May 2, 2013

The last vestige of me thinking in imperative manner

SQL is a declarative language, but there are some imperative code lurking in an SQL query. Case in point:

select d.*, p.product_name
from order_detail d
join product p on p.product_id = d.product_id

Did you spot the imperative code there?

I still think of the second table and first table in terms of inner loop being compared to an outer loop, hence p.product_id = d.product_id. I should forget how things work under-the-hood, forget the loops, and be comfortable with a more declarative-looking code: d.product_id = p.product_id

Wednesday, April 24, 2013

JavaScript alphabet song

If JavaScript has an alphabet or elementary song, I think this is the one:

1: function foo(){} foo(); // calls foo 
2: foo = function(){}; foo(); // calls foo 
3: ( function(){} )(); // calls the anonymous function

Objective C's C#'s lambda

So we are missing C#'s Where lambda, which allows us to generalize a filter pattern, instead of creating new function everytime we need a new kind filter. On my last post about C#'s extension method, we have defined a function that filters all the odd elements, and everytime we have a new kind of filter, say get all the even elements, we will need to introduce another method called evenElements, think of all possible variations of filter and duplicated amount of code in those functions.


How about instead of creating a new method whenever a new set of condition would be required, we generalize the method's functionality and allows us to pass any kind of filters.

Luckily for C# transitioners, Objective C has a lambda, which is called blocks.


So with blocks, it allows us to create building blocks for generalized routine, e.g. filter.


So instead of creating another method that filters all the even numbers, we will just create a generalized lambda method that allows us to pass any filter condition. First, we should create the signature of the lambda in the .h file:

-(NSMutableArray*) where: (bool (^)(NSNumber *)) expr;



This is the lambda parameter on NSMutableArray's where Category(Extension Method in C#'s parlance):

(bool (^)(NSNumber *)) expr;


In Objective-C, the method's parameter has the following syntax, open parenthesis, type, close parenthesis, and the name of the parameter. So the name of the parameter is expr. So our type is:

bool (^)(NSNumber *)


The caret(^) denotes that the type is a lambda type, and that lambda signature allows us to receive an NSNumber parameter, and allows us to return a boolean type. So that's just it. Can't take but notice that it's a bit ironic that given the Objective-C's messaging mechanism (where the message's parameter is denoted by a colon), its lambda syntax takes the function signature form (similar to JavaScript lambda or C#'s Func/delegate) instead of its usual messaging mechanism syntax. I think Objective-C lambda code will look very convoluted if its lambda syntax resembles Objective-C messaging rather than the simpler function signature.


Here's the implementation of the lambda signature above, note that we simply invoke the expr by adding an open parenthesis, parameter, and close parenthesis. Which is a homey function syntax, not the messaging style syntax of Objective-C

-(NSMutableArray*) where: (bool (^)(NSNumber *)) expr {
    NSMutableArray *x = [NSMutableArray array];
    
    
    for(NSNumber *number in self) {
        if (expr(number)) { // we invoke the expr lambda
            [x addObject: number];
        }
    }
    
    return x;
}


If you are curious, yes this doesn't work:
if ([expr number]) {
    [x addObject: number];
}


Then here's how we use the lambda implementation:

void demoArray()
{
    @autoreleasepool {
        
        NSMutableArray *items = [NSMutableArray array];
        
        [items addObject: [NSNumber numberWithInteger:42]];

        
        [items addObject: [NSNumber numberWithInteger:11]];
        [items addObject: [NSNumber numberWithInteger:5]];
        [items addObject: [NSNumber numberWithInteger:1976]];
        
        
        for(NSNumber *number in [items oddElements]) {
            printf("\n%d", number.intValue);
        }
        
        
        
        printf("All even numbers:\n");
        for(NSNumber *number in [items where: ^(NSNumber *n) { return (bool)(n.intValue % 2 == 0 ); } ]) {
            printf("\n%d", number.intValue);
        }
    
    }
}


Output:
All even numbers:

42
1976


We want to list all odd numbers less than 100?
void demoArray()
{
    @autoreleasepool {
        
        NSMutableArray *items = [NSMutableArray array];
        
        [items addObject: [NSNumber numberWithInteger:42]];

        
        [items addObject: [NSNumber numberWithInteger:11]];
        [items addObject: [NSNumber numberWithInteger:5]];
        [items addObject: [NSNumber numberWithInteger:1976]];
        
        
        
        for(NSNumber *number in [items where: ^(NSNumber *n) { return (bool)(n.intValue % 2 == 1 && n.intValue <= 100 ); } ]) {
            printf("\n%d", number.intValue);
        }
    
    }
}
Output:
11
5

Saturday, April 20, 2013

Objective-C's C# Extension Method

...is called Categories.


NSMutableArray+Selector.h:
#import <Foundation/Foundation.h>

@interface NSMutableArray (Selector)

-(NSMutableArray*) oddElements;

@end


NSMutableArray+Selector.m
#import "NSMutableArray+Selector.h"

@implementation NSMutableArray (Selector)

-(NSMutableArray *) oddElements {
    
    NSMutableArray *x = [NSMutableArray array];
    
    for(NSNumber *number in self) {
        if (number.intValue % 2 == 1) {
            [x addObject: number];
        }
    }
    
    return x;
    
}

@end


To use the categories:
#include <CoreFoundation/CoreFoundation.h>


#include "ThePerson.h"

#include "NSMutableArray+Selector.h"

void demoArray()
{
    @autoreleasepool {
        
        NSMutableArray *items = [NSMutableArray array];
        
        [items addObject: [NSNumber numberWithInteger:42]];
        
        [items addObject: [NSNumber numberWithInteger:11]];
        [items addObject: [NSNumber numberWithInteger:5]];
        [items addObject: [NSNumber numberWithInteger:1976]];
        
        
        for(NSNumber *number in [items oddElements]) {
            printf("\n%d", number.intValue);
        }
    
    }
}


int main(int argc, const char * argv[])
{
    demoArray();

    return 0;
}

List in Objective-C

void demoArray()
{
    @autoreleasepool {
        
        NSMutableArray *items = [NSMutableArray array];
        
        [items addObject: [NSNumber numberWithInteger:42]];
        
        [items addObject: [NSNumber numberWithInteger:11]];
        [items addObject: [NSNumber numberWithInteger:5]];
        [items addObject: [NSNumber numberWithInteger:1976]];
        
        
        for(NSNumber *number in items) {
            printf("\n%d", number.intValue);
        }
    
    }
}

Wednesday, April 17, 2013

Objective C's C# auto-implemented properties

Missing C#'s auto-implemented properties?

For the uninitiated, here's what auto-implemented properties in C# looks like:

public class ThePerson 
{
    public int HatedNumber {get; set;}
}


That syntax spares the developer from incessant creations of backing field for property and explicitly coding the property's getter and setter
public class The Person 
{
 int _hatedNumber;
 public int HatedNumber
 {
    get 
    { 
        return _hatedNumber;
    }
    set 
    { 
        _hatedNumber = hatedNumber;
    }
 }


Writing that things over and over easily gets old, hence the creation of auto-implemented properties in the language. Auto-implemented properties creates codes for you behind-the-scenes, rather than the you writing the repetitive and boring stuff



Objective-C has analogous mechanism to that C#'s auto-implemented property

ThePerson.h:
#import *<Cocoa/Cocoa.h>

@interface ThePerson : NSObject {
}

    @property int hatedNumber;

@end

ThePerson.m:
#import "ThePerson.h"

@implementation ThePerson

    @synthesize hatedNumber;

@end


It behaves exactly the same as in C#, i.e. you don't have to write explicit setter and getter code for your property. And you can still use the property as if dot notation was not invented, i.e. you can still invoke its setter explicitly [objectInstanceHere setHatedNumber]

#include <CoreFoundation/CoreFoundation.h>


#include "ThePerson.h"

int main(int argc, const char * argv[])
{

    // insert code here...
    
    ThePerson* p = [ThePerson new];
    
    ThePerson* q = [ThePerson new];
    
    ThePerson *x;

    
    x = p;
    [x setHatedNumber:4]; // classic way
    
    x = q;
    x.hatedNumber = 13; // modern way
    
    
    
    printf("%d\n", [p hatedNumber]); // classic way
    printf("%d\n", p.hatedNumber); // modern way
    
    printf("%d\n", [q hatedNumber]); // classic way
    printf("%d\n", q.hatedNumber); // modern way
    


    return 0;
}





Happy Computing! ツ


UPDATE

On Xcode 4.4, synthesize keyword is not needed anymore when creating automatic properties, and by default it automatically creates a backing field for your property, which name is prefixed by an underscore followed by the property name. I would prefer it not exposing any backing field, just like with the automatic property in C#

Tuesday, April 16, 2013

Objective C's class and property

main.m

#include <CoreFoundation/CoreFoundation.h>


#include "ThePerson.h"

int main(int argc, const char * argv[])
{

    // insert code here...
    
    ThePerson* p = [ThePerson new];
    
    ThePerson* q = [ThePerson new];
    
    ThePerson *x;

    
    x = p;
    [x setFavoriteNumber:7]; // classic way
    
    x = q;
    x.favoriteNumber = 6; // modern. neater syntax, lesser friction. calls the method setFavoriteNumber
    
    
  
    printf("%d\n", [p favoriteNumber]); // classic way
    printf("%d\n", p.favoriteNumber); // modern way
    
    printf("%d\n", [q favoriteNumber]); // classic way
    printf("%d\n", q.favoriteNumber); // modern way
    

    return 0;
}



The class mechanism for Objective C uses the interface keyword. Then we put the backing field inside the curly bracket. And all the method signature after the curly bracket.

Person.h
#import <Cocoa/Cocoa.h>

@interface ThePerson : NSObject {
    int _favoriteNumber;
}


-(int) favoriteNumber; 
-(void) setFavoriteNumber: (int) input;



@end


Person.m
#import "ThePerson.h"

@implementation ThePerson


-(int)favoriteNumber {
    return _favoriteNumber;
}

-(void) setFavoriteNumber:(int)input {
    printf("Set is Called\n");
    _favoriteNumber = input;
}

@end

Monday, April 15, 2013

Remove breakpoint in Objective-C

Drag and drop the breakpoint anywhere, and poof!

http://stackoverflow.com/questions/10016890/thread-1-stopped-at-breakpoint-error-when-initializing-an-nsurl-object/10016939#10016939

Sunday, April 7, 2013

Gaps to islands

On an old post, I discussed how island and gaps algorithms work: http://www.anicehumble.com/2012/08/monitoring-perfect-attendance.html

On this post, I will discuss the exact reverse of that.

Given the following data:


CREATE TABLE y
 ("id" int, "val" varchar(1))
;
 
INSERT INTO y
 ("id", "val")
VALUES
 (1, 'a'),
 (4, 'b')
;

CREATE TABLE x
 ("id" int)
;
 
INSERT INTO x
 ("id")
VALUES
 (1),
 (2),
 (3),
 (4),
 (5)
;

with z as
(
select x.id, y.val
from x
left join y on y.id = x.id
)
select  *
from z
order by id ;


| ID |    VAL |
---------------
|  1 |      a |
|  2 | (null) |
|  3 | (null) |
|  4 |      b |
|  5 | (null) |  


Requirement is to cluster those gaps together:
| ID | VAL |
------------
|  1 |   a |
|  2 |   a |
|  3 |   a |
|  4 |   b |
|  5 |   b |


The easiest way to solve that is to use windowing function, i.e. use first_value on each group. First thing first, we must devise a way to group those gaps together. We can do that by counting over the id's order. COUNT doesn't count nulls, hence COUNT will be able to group nulls to a previous non-null, COUNT will maintain the same count as long as it is encountering nulls. To illustrate:


with z as
(
  select       
      x.id, y.val,
     count(y.val) over(order by x.id ) as grp
  from x
  left join y on y.id = x.id
)
select *
from z
order by id ;


Output:
| ID |    VAL | GRP |
---------------------
|  1 |      a |   1 |
|  2 | (null) |   1 |
|  3 | (null) |   1 |
|  4 |      b |   2 |
|  5 | (null) |   2 |  


Now that we designated a grouping number for related data, getting the first value among the group shall just be a simple undertaking, use first_value from the partition of grp

with z as
(
  select       
      x.id, y.val,
     count(y.val) over(order by x.id ) as grp
  from x
  left join y on y.id = x.id
)
select 
  id, val, grp, first_value(val) over(partition by grp order by id)
from z;


Output:

| ID |    VAL | GRP | FIRST_VALUE |
-----------------------------------
|  1 |      a |   1 |           a |
|  2 | (null) |   1 |           a |
|  3 | (null) |   1 |           a |
|  4 |      b |   2 |           b |
|  5 | (null) |   2 |           b |

Saturday, April 6, 2013

MVCC

Entity Framework 6 database creation defaults to MVCC now:

Default transaction isolation level is changed to READ_COMMITTED_SNAPSHOT for databases created using Code First, potentially allowing for more scalability and fewer deadlocks. -- http://entityframework.codeplex.com/wikipage?title=specs


On related news:

Want to see an SQL Server DBA nerdgasm'd? Let him/her use Postgresql, it's an RDBMS (that like Oracle) on which the supported concurrency model is MVCC, so you'll get fewer deadlocks on your database:

http://www.youtube.com/watch?v=Rl_-lKxSBm4


Is your database OOP-deprived? See the demo of inheritance using Postgresql on the video above

Microsoft uses Postgresql too, we know Microsoft bought Skype. Skype uses Postgresql

Instagram uses Postgresql too

Friday, March 15, 2013

AngularJS code for the day...

...have no code at all:

<div ng-app ng-init="r=128; g=128; b=128;">
    <div class="block" style="background-color: rgb({{r}}, {{g}}, {{b}});"></div>
    <input type="range" min="0" max="255" step="1" ng-model="r">
    <input type="range" min="0" max="255" step="1" ng-model="g">
    <input type="range" min="0" max="255" step="1" ng-model="b">
    <p>Drag the sliders</p>
        
         
    R: {{r}}<br/>
    G: {{g}}<br/>
    B: {{b}}<br/>
</div>
 


Darn, HTML should be bolted with model from the get-go.

Live code: http://jsfiddle.net/Jpk7x/35/



Manually manipulating DOM elements makes me remember this classic physicist joke:


"It would be a poor thing to be an atom in a universe without
physicists. A physicist is an atom's way of knowing about atoms"



What physicists are to atom, front-end developers are to HTML.


"It would be a poor thing to be an HTML in a universe without
front-end developers. A front-end developer is an HTML’s way of making itself dynamic"



Poor us, the unsuspecting slaves of HTML, we think we are the master of them, but in fact it's the other way around. For non-clientside-mvc-mvvm-using front-end developers, we still have to manually manipulate DOM with our jQuery / document.getElementByBlah skills



Note: Try the jsfiddle example above on HTML5-capable browser only, e.g. Chrome



input type=range is rendered as slider on HTML5-capable browser.



If a browser doesn't recognize range, you can use other slider tags, Wijmo slider for example. Wijmo's AngularJS slider is just as code-less as its HTML5-cousin range:

http://demo.componentone.com/wijmo/using-angular/index.html