Archive

Archive for the ‘Programming’ Category

Array min, max with Coffeescript

September 19, 2012 Leave a comment

Quite simple actually:


Array::max=->
  Math.max.apply(null, this)

Array::min=->
  Math.min.apply(null, this)

a=[6, 5, 17, -3, 4.5]
console.log a.max()
console.log a.min()

Outputs:
17
-3

Categories: coffeescript, Programming

Calling initialization function only once with this js trick

September 12, 2012 Leave a comment

There are times when an initialization function in a js object needs to be called only once. Here’s one of the solutions I came up with. When F.paint() is called, a check on the initialization tag (need_init) is performed. need_init remains undefined until init() is called for the first time.

The code:

var F=(function() {
	var self=this;

	var init=function() {
		console.log('Initialized.');
		self.need_init=false;
	}
	return {
		paint: function() {
			if(typeof self.need_init==='undefined') {
				init();
			}
			console.log('Now I am ready to paint.');
		}
	};
})();

F.paint();
F.paint();
F.paint();

Output from the above example:
Initialized.
Now I am ready to paint.
Now I am ready to paint.
Now I am ready to paint.

Enjoy coding.

Categories: javascript, Programming

PHP: removed trailing zeros from numeric strings (code illustration)

June 14, 2012 Leave a comment
<?php
	$nums=array('1.0', '2.300', '4', '5.9000');

	echo "Original format:\n";
	foreach($nums as $num) {
		echo "$num\n";
	}

	echo "\nTrailing zeros removed:\n";
	foreach($nums as $num) {
		echo ($num+0)."\n";
	}

Output:
Original format:
1.0
2.300
4
5.9000

Trailing zeros removed:
1
2.3
4
5.9

Categories: php, Programming

Learning CoffeeScript

June 10, 2012 2 comments

Practice 1: Define a Student class, make some new instances and classify them into two arrays based on the student scores

class Student
    constructor:(@gender, @score)->

s1=new Student('M', 45)
s2=new Student('F', 78)
s3=new Student('F', 59)
s4=new Student('M', 99)

passed=[]
failed=[]
(if s.score>59 then passed else failed).push s for s in [s1, s2, s3, s4]
console.log passed
console.log failed

Practice 2: Array filtering

pr=(items, lbl)->
    console.log "==#{lbl}=="
    for item, i in items
        console.log "Item #{i}: #{item}"
    false

a=[1..9]

odd=(item for item in a when item%2)
even=(item for item in a when item%2==0)
double=(item*2 for item in a)

pr odd, "odd"
pr even, "even"
pr double, "double"

Practice 3: more about class

class Candidate
    constructor:(@approval_rate)->

class Election
    elect:(candidate)->
        candidate.approval_rate>0.5


e=new Election
console.log e.elect( new Candidate(0.34) )
console.log e.elect( new Candidate(0.59) )

Practice 4: serial_maker (based on
JavaScript: The Good Parts by Douglas Crockford
Chap 4.12)

class SerialMaker
    constructor:(@prefix='Q', @start=0)->
    gen_seq:()->
        @start+=1
        @prefix+@start

sm=new SerialMaker('SQ')
console.log sm.gen_seq()
console.log sm.gen_seq()
console.log sm.gen_seq()

Practice 5: (added 7/12/2012) Self-invoking constructor

class Person
    constructor:(name='no name')->
        return new Person(name) if !(@ instanceof Person)
        @name=name

    id:->
        return @name

    isrich:true


p1=Person('Freedom')
# or the above line can be written as 
# p1=new Person('Freedom')
# the result is exactly the same and the
# benefit is user doesn't need to worry about forgetting using the "new" keyword
console.log p1.id() + ','+ p1.isrich

Reference: http://arcturo.github.com/library/coffeescript/index.html

Categories: coffeescript, Programming

Javascript OOP design pattern

January 29, 2012 Leave a comment

I’ve been using the following programming pattern whenever I need to write some client-side javascript:

( function() {
    if(!window.Foo) window.Foo={};
    function some_priv_func() {
        // define a private function (not accessible from
        // outside of the enclosure)
        alert('this is a private function');
    }
    function some_pub_func() {
        // calling some_priv_func()
        some_private_func();
    }
    window.Foo.some_pub_func=some_pub_func;
} )();

In the above example I create a Foo object and expose one function some_pub_func, which can be invoked by calling Foo.some_pub_func(). Enclosure is used to avoid name-space conflicts. It’s worth noting that the some_priv_func can not be accessed from outside of the enclosure.

I recently discovered a better way to program the OOP way in Jtavascript through Hands-on Node.js (page 100) and I would like to share with you this technique. Let’s look at code:

( function() {
    if(!window.Foo2) {
        window.Foo2=function(options) {
            // to avoid getting confused when using
            // 'this' in member functions
            var self=this;
            self.options=options;
            function some_priv_func() {
                // define a private function (not accessible from
                // outside of the enclosure)
                alert('this is a private function');
            }
            self.some_pub_func=function() {
                // calling some_priv_func()
                some_priv_func();
            }
        };
        window.Foo2.create=function(options) {
            return new Foo2(options);
        }
    }
} )();

Foo2.create() is made so one can initialise a Foo2 instance without using the “new” keyword. You can use Foo2 in ways like the following:

var f2=new Foo2( { name: 'the new guy' } ); // as if Foo2.create doesn't exist

or

var f2=Foo2.create( { name: 'the new guy' } );

For demonstration purpose I also expose the member options to the public allowing it be accessed and changed. A better way to handle this is to use the jQuery extend function. (Assuming jQuery is being used)

            ...
            var self=this;
            var defaults={
                name: 'no name'
            };
            // merge settings in options to defaults
            $.extend(defaults, options);
            function some_priv_func() {
            ...

So if one initialises Foo2 without any options ( var f2=Foo2.create() ), defaults will have its default value {name: ‘no name’}. Or it can be overwritten by providing a parameter.
The benefit of this is the exposing of member options (using defaults instead, which is not accessible outside of Foo2) is avoided.

Categories: javascript, Programming

Print color in shell terminal

January 25, 2012 Leave a comment

Sometimes you might want to print something with color in a text terminal (by color I mean something other than the default text color). Put the following shell function to your ~/.bash_profile and you are go to good.

cecho() {
    case $2 in
        red) code=31;;
        blue) code=34;;
        green) code=32;;
        cyan) code=36;;
        purple) code=35;;
        brown) code=33;;
        white) code=37;;
        *) code=30;;
    esac
    printf "\e[01;${code}m$1\e[0m\n"
}

Some examples:

cecho hello cyan
cecho "something needs your attention" brown
cecho "there's something terribly wrong, have to abort now" red
cecho "this looks so pale" white
cecho "will purple work too?" purple
cecho goodbye blue

The above commands should output something like this ($TERM setting xterm-256color, tested on both OS X 10.7.2 and Ubuntu 11.10 64bit Server):

Categories: Bash, Programming

Build a simple PHP template with str_replace()

January 5, 2012 Leave a comment

You are given a task to notify a list of customers regarding their pin setting changes through their email address on file. There are many ways to accomplish this in PHP. One way I found quite interesting is through a simple php function str_replace. Let me demo through the following example (only showing how the message body is constructed, the email address part should be easy to take care of):

<?php
        /* main.php */
        function build_key($key) {
                return '{{'.$key.'}}';
        }

        function gen_msg($format_str, $arr) {
                $keys=array_map(build_key, array_keys($arr));
                // $keys can also be generated by using the following code
                // but I found using array_map is more elegant and fun
                // $keys=array();
                // foreach(array_keys($arr) as $k) {
                //      array_push($keys, '{{'.$k.'}}');
                // }

                return str_replace( $keys, array_values($arr), $format_str);
        }

        // here's the template
        $template="Dear {{user}}, your pin number has been changed to {{pin}}.";

        // here's the data, hard-coded in this example but it can be pulled from external sources as well
        $data=array(
                array( 'user'=>'John Smith', 'pin'=>'1234' ),
                array( 'user'=>'Mr. S', 'pin'=>'9999' ),
                array( 'user'=>'Customer', 'pin'=>'****' )
        );

        foreach($data as $d) {
                printf("%s\n", gen_msg($template, $d));
        }

Run the above code through php (cli) will output the following:

Dear John Smith, your pin number has been changed to 1234.
Dear Mr. S, your pin number has been changed to 9999.
Dear Customer, your pin number has been changed to ****.

[ Update ] I also added an OOP implementation of the above code, if you are interested you can checkout my code on github.

Categories: php, Programming

Combine regular expression and conditional statements in BASH

January 1, 2012 2 comments

As we all know we can use conditional statements in BASH. For example, show usage if number of arguments is 0:

#!/usr/bin/env bash
if [ $# -eq 0 ]; then
    echo "Usage: $0 start|stop|restart"
    exit 0
fi
echo "going to run with \$1=$1"

We might also want to use regular expression to test if $1 is start, stop or restart if $# is no longer 0:

#!/usr/bin/env bash
function usage() {
    echo "Usage: $0 start|stop|restart"
}
if [ $# -eq 0 ]; then
    usage
    exit 0
fi

if [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
    usage
    exit 0
fi
echo "going to run with \$1=$1"

But wouldn’t it be nice if the tests can be combined together. With bash operator || the above code can be written as:

#!/usr/bin/env bash
function usage() {
    echo "Usage: $0 start|stop|restart"
}   
if [ $# -eq 0 ] || [[ ! $1 =~ ^(start|stop|restart)$ ]]; then
    usage
    exit 0
fi  
echo "going to run with \$1=$1"

One more example using operator && instead:

#!/usr/bin/env bash
if [ -d ~/a_folder ] && [[ $1 =~ ^(install|remove)$ ]]; then
    echo "going to $1 something" 
else
    echo "Folder ~/a_folder doesn't exist or you specified the wrong parameter:"
    echo "Usage: $0 install|remove" 
    exit 0
fi  
Categories: Bash, Programming

MySQL: select data whose certain column contains the specified values only

December 23, 2011 2 comments

This problem could be best described by an example as below:

select * from mytbl;
+------+------+
| k    | v    |
+------+------+
| A    | 1    |
| A    | 2    |
| A    | 3    |
| B    | 1    |
| B    | 3    |
| C    | 1    |
| C    | 3    |
| C    | 4    |
| E    | 2    |
| E    | 1    |
| F    | 5    |
+------+------+

k, v are both char(10), not null.

I want to find out records whose v column is either 1 or 3 [and only 1 or 3, therefore in the above example the only qualified records are ('B', '1') and ('B', '3')]. This is just a simplified version of the problem I faced at work recently and I did find someone posting the similar question on Internet but I forgot to bookmark the url and I didn’t find its solutions interesting hence I pulled my hair a bit and came up with the following solution using group_concat and regexp:

select k, group_concat(distinct v order by v) as g from mytbl group by k having g regexp '^(1,?)?(3)?$';
+------+------+
| k    | g    |
+------+------+
| B    | 1,3  |
+------+------+

If the requirement becomes v is either 1, 3 or 4 (again, 1, 3 or 4 only),

select k, group_concat(distinct v order by v) as g from mytbl group by k having g regexp '^(1,?)?(3,?)?(4)?$';
+------+-------+
| k    | g     |
+------+-------+
| B    | 1,3   |
| C    | 1,3,4 |
+------+-------+
Categories: mysql, Programming

Play with randomness in MySQL

December 2, 2011 1 comment

Some of you might know about the rand() function in MySQL — it randomly generates float point number between 0 and 1. Most of the time we use it to generate results that we want to be in random order. For example,

We have a people table that has the following records:

select * from people;
+-----------+
| name      |
+-----------+
| Bob       |
| Alice     |
| Kim       |
| Tom       |
| Jerry     |
| Linda     |
| Fransisco |
| Zack      |
| Peter     |
+-----------+

We are going to pick 3 persons out of the list randomly, so we do a

mysql> select * from people order by rand() limit 3;
+------+
| name |
+------+
| Zack |
| Bob  |
| Kim  |
+------+

The above query should return (most likely) different result every time. Next I am going to make it a little more interesting. Let’s say I have another table named prize which contains a list of prizes:

select * from prize;
+-----------------+
| name            |
+-----------------+
| Pencil          |
| Coffee grinder  |
| iPad            |
| GPS watch       |
| Yoga mat        |
| 2 movie tickets |
+-----------------+

What we want to do is to assign a randomly picked prize to each person in the people table (assuming the same prize can be assigned to more than one person as there are fewer number of prizes than number of people), here’s the query

select o.*, (select name from prize order by rand() limit 1) as prize from people o;

This would return something like the following (again the result will be most like different if you try it):

+-----------+-----------------+
| name      | prize           |
+-----------+-----------------+
| Bob       | iPad            |
| Alice     | Yoga mat        |
| Kim       | GPS watch       |
| Tom       | GPS watch       |
| Jerry     | iPad            |
| Linda     | GPS watch       |
| Fransisco | Pencil          |
| Zack      | 2 movie tickets |
| Peter     | GPS watch       |
+-----------+-----------------+

For your convenience you can use the following sql statements to generate the tables with data populated:

CREATE TABLE `people` (
  `name` varchar(30) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `people` VALUES ('Bob'),('Alice'),('Kim'),('Tom'),('Jerry'),('Linda'),('Fransisco'),('Zack'),('Peter');

CREATE TABLE `prize` (
  `name` varchar(50) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `prize` VALUES ('Pencil'),('Coffee grinder'),('iPad'),('GPS watch'),('Yoga mat'),('2 movie tickets');
Categories: mysql, Programming
Follow

Get every new post delivered to your Inbox.