Sunday, December 8, 2013

Object-Oriented Programming in JavaScript

Access Modifiers

It is a convention in JavaScript that a class member whose name starting with an underscore is "private", that is, it is intended for internal use and should not be considered part of the public API of the class. However, one can in fact define a de facto private members using closures. In the following example, new MyClass will return an object with only the properties assigned to this object and in the prototype object of the class.
var MyClass = (function () {
    // private static field
    var counter = 0;

    // constructor
    var ctor = function (_name) {
        // private instance field
        var _id = ++counter;
        // public instance method
        // Private instance members can only be accessed this way
        this.getName = function () { return _name }; // readonly
        this.getID = function () { return _id }; // readonly
    };
    // public instance method (shared across instances)
    // Note that class methods cannot access instance members.
    ctor.prototype.toString = function () {
        return 'Hi! My my name is ' + this.getName()
        + ', my id is ' + this.getID()
        + ' and there are ' + counter + ' instances in total.'
    };
    // public static method
    ctor.getNumInstances = function () { return counter };
    return ctor;
})();
// Error: cannot access id outside ctor
MyClass.prototype.setID = function(id){ this.id = id; }

Inheritance

Javascript doesn't exactly have subclass objects, but prototype is a useful workaround to make a "base class" object of certain functions that act as objects. For example:
/* Definition of class Person */
var Person = function(name) {
    this.name = name;    
    this.canTalk = true;
    this.greet = function() {
        if (this.canTalk) console.log("Hi, I'm " + this.name);        
    };
};
/* Definition of subclass Employee */
var Employee = (function() {
    var ctor = function(name, title) {
        // call parent constructor
        Person.call(this, name);
        // initializations for Emplyee        
        this.title = title;
    };
    // store the method before overriding it
    var _greet = ctor.greet || Person.prototype.greet;

    // overriding parent's method
    ctor.prototype.greet = function() {
        // call the original method
        _greet.apply(this, arguments); 
        console.log("I'm a " + this.title);        
    };
    // setup the prototype chain
    ctor.prototype = Object.create(Person.prototype);
    ctor.prototype.constructor = ctor; // repair the inherited constructor
    return ctor;
})();

References and Resources

1. Introduction to Object-Oriented JavaScript
2. Prototypes Are Not Classes
3. Constructors in JavaScript objects
4. Douglas Crockford: Advanced JavaScript (Video)
5. Constructors Considered Mildly Confusing
JavaScript The Definitive Guide, 6th Edition,  Chapter 9
(http://js-bits.blogspot.com.au/2010/08/javascript-inheritance-done-right.html)

Friday, December 6, 2013

CoffeeScript and LiveScript

I am familiar with JavaScript, and I am interested in CoffeeScript and LiveScript. I really need some good tutorials before I get enough brevity to use them in my projects.

Functional Programming in JavaScript using LiveScript and prelude.ls

Tuesday, November 26, 2013

Pitfalls for JavaScript beginners

Eval. According to ES5, indirect calls to eval like var a = eval; a(code) or (0, eval)(code) or window.eval(code) are treated as a global evals, i.e., they can't access or declare variables in the lexical scope. For example,
var x=1; (function(){ var x=0; (eval)("console.log(x)"); })();   // prints 0
var x=1; (function(){ var x=0; (0,eval)("console.log(x)"); })(); // prints 1
You can check this post by Juriy Zaytsev for more information about global eval. According to another post of the same author, which examines the delete operator and eval, you can also delete a variable declared in eval:
(function (){ var x = 10; return delete x; })()          // false
(function (){ eval('var x = 10;'); return delete x; })() // true
In words, eval-introduced bindings do not have the DontDelete property set on them, so they can be deleted unlike proper lexical variables. Note that the behaviours of eval will change if strict mode is used.

Variable scope. In JavaScript, variables declared by var are scoped by closures, not by blocks. In particular, variables declared in a block can overwrite a global variable. This feature may confuse programmers familiar with languages such as C++ and Java, where variables are scoped by blocks.
var name = "Joe";
if(true) { var name = "Jack" }        // name is "Jack" now
(function() { var name = "Joe" })()  // name is still "Jack"
One therefore has to use a closure to declare a genuine local variable. The let keyword introduced in ECMA 6 declares block-scoped variables and helps avoid this pitfall.

Binding vs assignment. In most imperative languages including JavaScript, variable declaration creates a reference to a mutable value. In the following example, variable i enclosed in the anonymous function points to a value which is mutated by further iterations of the loop.
for (var i=0; i<3; ++i) {
  if(i==1) setTimeout(function (){ console.log(i) }, 1000);
}// prints 3
To capture the value of i at creation time, we can exploit a feature of JavaScript that functions are called by value when the parameters are of primitive types. In the following, the value of i is copied to parameter j when the anonymous function is created. Thus the value of i is captured as expected.
for (var i=0; i<3; ++i) {
  if(i==1) setTimeout((function (j){ 
      return function (){ console.log(j) }
  })(i), 1000);
}// prints 1
In general, binding creates a new variable within the current context, while assignment changes the value of an existing variable within the narrowest scope. In languages such as SML and Go, you can use different syntactic rules to choose between binding and assignment. In JavaScript, the "=" symbol always denotes an assignment. One however can bind a variable through a call-by-value function parameter, as is shown in above example.

Function declaration. When a JavaScript program executes, it runs with context (variable bindings, call stack, etc) and process (statements to be invoked in sequence). Declarations contribute to the context when the execution scope is entered. They are different from statements and are not subject to the order in which statements are invoked. In the following example, function foo is returned even though the code that defines it is unreachable at runtime:
(function (){
  return foo; function foo(){} 
})();
In ES5, function declarations are forbidden within non-function blocks (such as an if block). However, all browsers allow them and interpret them in different ways. For example, consider
(function (){
  if(false) { function foo(){} } return foo;
})();
In Firefox, the function declaration is interpreted as a statement. Thus foo is not defined when it is returned, which would cause a runtime error. In IE, Chrome and Safari, however, the function is returned as expected with standard function declarations.

Declaration hoist. In JavaScript, declarations of functions and variables are hoisted (moved) to the beginning of their innermost enclosing scope. Note that it is the declaration that got hoisted, not the assignment expressions. In the following example, the global variable x is shadowed by the local one due to declaration hoist.
var x = 0;
(function (){ 
  console.log(x);
  var x = 1;
})() // prints "undefined"
equals
to
var x = 0;
(function (){
  var x;
  console.log(x);
  x = 1;
})() // prints "undefined" 
When a function declaration is hoisted, the entire function definition is lifted with it. The following example shows an interested consequence of the difference between hoisting variable declaration and function declaration:
(function (){
  function foo() { return 0 }
  return foo();
  function foo() { return 1 }
})(); // returns 1
(function (){
  var foo = function (){ return 0 }
  return foo();
  var foo = function (){ return 1 }
})(); // returns 0
In the left snippet, the definition of the second foo is hoisted and thus shadows that of the first foo. In the right snippet, only the declaration of the second foo is hoisted, and this doesn't change the result of the first assignment. See also the "function declaration" paragraph.

Array allocation. JavaScript arrays should be treated as a special hash table. When you initialize an array with a statement like var a = new Array(10), you don't allocate a memory of 10 cells as you do in Java and C++. Instead, you create an Array object with length property of value 10. You can use any type of keys to store any type of values in an array, e.g., a[-1] = 1, a["fruit"] = "apple", etc. The length property of an array is updated automatically to accommodate the largest non-negative integer key of its contained values. Whatever the keys are, an array traversal only visit the values with non-negative integer keys explicitly assigned, as is shown in this code: (see this thread for more details)
var a = new Array();
a[-1] = a["a"] = a[11] = 1;
console.log(a.length); // prints 12
// Map traversal: visit all keys ever set
for(var key in a) { if(a.hasOwnProperty(key) console.log(key + ': ' + a[key]) }
// Array traversal: visit all valid array indices
a.forEach(function (val, index){ console.log(index + ': ' + val) }) // prints "11: 1"
To actual allocate a memory block of 10 cells, use Array.apply(null, Array(10)). To assign initial values to an array, use either this trick or utility functions such as _.range of underscore.js.

Trailing comma. ES3 does not allow a trailing comma when defining an object literal. For example, we should write {foo1:"bar1",foo2:"bar2"} instead of {foo1:"bar1",foo2:"bar2",}. However, most browsers (except IE) go against the spec and allow both usages. ES5 resolved this issue by going with the majority and legitimizing the trailing comma in the spec. Note that a trailing comma is still not allowed in JSON according to ES5. Thus '{foo:"bar",}' does not represent a valid JSON object.

Non-commutative operators. Check this table for a detailed list of the surprising behaviors of operators +, *, == and ===. These behaviors result from JavaScript's eccentric type coercion rules. One can make use of these coercion rules to write extremely puzzling code, see this script for instance. If you are not that familiar with these rules, be extremely careful when you have to do arithmetic operations over objects of different types.

Discrete floating point. Numbers in JavaScript are internally stored in double-precision floating-point format. Hence, not all numbers can be exactly represented, even for those falling in the seeming reasonable range. For example,
var x = 9999999999999999;   // x == 10000000000000000
var eq = (.3 == .1 + .2);   // eq is false because .1 + .2 == .30000000000000004
If you need to check equality between numbers, you have to take relative error into account, e.g.:
function eq(x, y) { // x and y are numbers
  return (x==y) || (!(x>0)^(y>0) && Math.abs(x - y) < Number.EPSILON) 
}

(more to come in the future)

Wednesday, November 13, 2013

ECMAScript 5.1 Spec

The official specification: the HTML version

Some annotated versions: Version 1, Version 2 (in the same format as above)

JavaScript: The Definitive Guide: PDF

Thursday, November 7, 2013

Testing, Simulation, and Formal Methods

Testing, simulation, and formal methods are three common techniques in verification. However, distinguishment between them is not very clear to many people working in other CS disciplines. I found two examples in Wang Farn's slides very helpful in explaining their differences──the three techniques are visualized by three correspondent approaches to answer the following two questions.

Q: Do the 3 angles in every triangle sum to 180 ?

Testing (check all triangles you see)
  • Expensive 
  • Low coverage
  • Late in development cycles
Simulation (check all triangles you draw)
  • Economic 
  • Low coverage
  • Don't know what you haven't seen
Formal Verification (prove it)
  • Expensive
  • 100% coverage
  • Proofs may be automatically verified

Q: What is the robustness of a new design of call?
  • Testing (let real cars hit a real wall)
  • Simulation (let virtual cars hit a virtual wall)
  • Formal Verification (verify the car models)
Wang Yin also wrote a blog article trying to explain the difference between testing and static analysis (one of the popular formal methods) in plain words.

Thursday, October 31, 2013

The OOP Enssences in JavaScript

Instantization

// The following code shows how Firefox implements the "new" operator
function Point(x, y){ 
    this.x = x; this.y = y;
}
function ObjectFactory(){
    var obj = {};
    var Constructor = Array.prototype.shift.call( arguments );
    if(typeof Constructor.prototype === 'number')
        obj.__proto__ =  Object.prototype;
    else
        obj.__proto__ =  Constructor.prototype;
    var ret = Constructor.apply(obj, arguments);
    return typeof ret === 'object' ? ret : obj;
}

// This is equivalent to: var p = new Point(0, 0);
var p = ObjectFactory(Point, 0, 0);

Inheritance

// The following code is generated by CoffeeScript to 
// implement subclass inheritance
var __extends = function(child, parent) {
    for (var key in parent) {
      if (Object.prototype.hasOwnProperty.call(parent, key)) {
        child[key] = parent[key];
      }
    }
    function ctor() { this.constructor = child; }
    ctor.prototype = parent.prototype;
    child.prototype = new ctor;
    child.__super__ = parent.prototype;
    return child;
};

// Our code
var Person = function(name) {
    console.log('Hi, I am ' + name + '!'); 
    this.name = function(){ return name };
};
var Student = function() {
    Student.__super__.constructor.apply(this, arguments);
};
__extends(Student, Person);    // make Student a subclass of Person
var me = new Student('Eric');  // "Hi, I am Eric!"
console.log(me.name());        // "Eric"

Wednesday, October 30, 2013

Seeded PRNG in JavaScript

Below is a multiply-with-carry (MWC) random generator with a pretty long period, adapted from wikipedia Random Number Generators:
// Takes any integer
Math.seed = function(s) {
    var m_w = s;
    var m_z = 987654321;
    var mask = 0xffffffff;
    return function() 
    // Returns number between 0 (inclusive) and 1.0 (exclusive),
    // just like Math.random().
    {
        m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
        m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
        var result = ((m_z << 16) + m_w) & mask;
        result /= 4294967296;
        return result + 0.5;
    }
}
Another fast and simple PRNG, without magic numbers:
Math.seed = function(s) {
    return function() {
        s = Math.sin(s) * 10000;
        return s - Math.floor(s);
    };
};
You can replace the default PRNG of JavaScript by, e.g.,
Math.random = Math.seed(Math.round(Math.seed(42)*10000));

Reference

1. http://stackoverflow.com/questions/521295/javascript-random-seeds/521323
2. https://github.com/davidbau/seedrandom

Monday, October 28, 2013

Lo-Dash v.s. Underscore

A breakdown of the advantages of Lo-Dash over Underscore:
http://kitcambridge.be/blog/say-hello-to-lo-dash/

The creator of Lo-Dash explain why it is a superior choice to Underscore:
http://stackoverflow.com/questions/13789618/differences-between-lodash-and-underscore

Lo-Dash v.s. Underscore benchmarks: http://jsperf.com/lodash-underscore

One may wonder that, since Lo-Dash is intended to be a superset compatible to Underscore from the beginning of design, why not contribute to Underscore directly, e.g. by merging the new features back into Underscore, instead of developing a new library? This thread in GitHub may serve as an answer to the question.

Thursday, October 24, 2013

Reset MySQL slave when it is out of sync

2019/01/24:
Fix bin-log when the log files are missing:
https://www.redips.net/mysql/replication-slave-relay-log-corrupted/

Slave side:
# stop all slaves before resetting the master
(mysql) STOP SLAVE;

Master side:
# set the master database to read-only
(mysql) FLUSH TABLES WITH READ LOCK;

# backup the current database
(bash) mysqldump -u root -p -databases db1 db2 | bzip2 > /tmp/bak.sql.bz

# reset the binary logs
(mysql) RESET MASTER;

Slave side:
(bash) scp -r ericpony@XXX.XXX.XXX.XXX:/tmp/bak.sql.bz /tmp

# load the current database from master
(mysql) SOURCE /tmp/bak.sql.bz;

# reset the binary logs
(mysql) RESET SLAVE;

# restart slave
(mysql) START SLAVE;

Master side:
# unlock the master database
(mysql) UNLOCK TABLES;

Slave side:
# check if everything is ok
(mysql) SHOW SLAVE STATUS \G

Reference

http://www.cnblogs.com/sunyuxun/archive/2012/09/13/2683338.html

Install Node.js on Ubuntu

Using Launchpad repo by Chris Lea just run following commands:

apt-get install python-software-properties
apt-add-repository ppa:chris-lea/node.js
apt-get update

apt-get install nodejs npm

Tuesday, October 1, 2013

Git notes

Create a new git from remote
make project_dir
cd project_dir
git remote add origin remote-project-path
git pull origin master
Set local upstream to remote branch
git branch --set-upstream master origin/master
Merge without adding "merge branch ... " message to log
git pull --rebase origin master
Merge without modifying log
git add .
git commit -m 'push to stash'
git pull --rebase origin master
(fix rebase conflict)
git reset HEAD~1
Rewind file state to last commit (changes are discarded, dangerous)
git checkout -- file-to-rewind
Unstate file changes and keep changes
git reset HEAD file-to-unstage
Undo last N commits
git reset --soft HEAD~N # keep changes
git reset --hard HEAD~N # discard changes (dangerous)
Modify the commit log.  See here for details.
git rebase --interactive hash-of-the-parent-commit
git push --force  # may cause issues if remote changes are pulled
Generate a changelog from git log
# list representation
git log --no-merges --pretty=format:' - %s'

# graphical representation
git log --graph --pretty=format:'%s - %Cred%h%Creset  %Cgreen(%cr)%Creset %an' --abbrev-commit --date=relative
Maintain a sub-repository using the subtree merging strategy: see this script.
usage: ./subtree ACTION (ARGS...)
 Actions  Arguments
 -------  -----------------------------------------------
  init    (root_git)
  create  subtree-name subtree-dir subtree-git (subtree-branch)
  update  subtree-name subtree-dir
  push    subtree-name
Create a new branch with clean history
git checkout --orphan new-branch
git rm -rf .
Force pull and overwrite local files:
git fetch --all
git reset --hard origin/master
git pull origin master

Resources

http://blog.wu-boy.com/tag/git/
A successful Git branching model

Tuesday, September 24, 2013

My First Nontrivial Haskell Program

:{
let perm x = _perm x []
    _perm [] [] = [[]]
    _perm [] ys = []
    _perm (x:xs) ys = map (\t -> x:t) (_perm (xs++ys) []) ++ _perm xs (x:ys)
:}

Sunday, September 8, 2013

Setup Python 2.7.6 and 3.3.3 on CentOS 6.4

Source

Introduction

More often than not, as a developer you will be responsible for managing the server(s) your application runs on to a certain degree. When it comes to choosing the operating system, especially for production, going with a sound choice such as CentOS can be a tempting (safe) bet for the future.
When you get started with CentOS, however, you will be surprised to see that Python still is at version 2.6 (or even 2.4.3) and it should not be used by deployed applications regardless as it is reserved for system's use.
In this DigitalOcean article, we are going to talk about downloading and setting up Python (2.7.6 and 3.3.3) without breaking the system's default 2.6 (or 2.4). It is rather important to not to get involved with that as critical system tools such as YUM depend on it. Furthermore, we will install two popular must-have Python companions pip and virtualenv.
After we are done, you will be able to simultaneously use either versions of Python on your CentOS 6.4 or 5.8 VPS, create and use virtual environments and finally, download and manage Python packages for each version.

CentOS and Its Design Choices

Before we get on with the installation, let's talk about CentOS.
Why does CentOS ship with older versions of applications?
CentOS is derived from RHEL (Red Hat Enterprise Linux). The target clientele for these two distributions consist of businesses, which require the systems to be up and running the most stable way for many years.
Therefore, the main reason here is the desire for stability for the system, achieved by supplying tested and more stable versions of applications. The philosophy behind "if it ain't broke, don't fix it" is heavily applied here.
Why do deployment libraries / applications need to be installed separately?
CentOS by default does not come with many tools, and the ones that are supplied are used by the system applications (e.g. YUM). Extreme care must be paid before changing or modifying them or their dependencies if you wish to keep your system running smoothly without breaking anything neither now or in future.
Do not assume the tools shipped with the operating system are for your use, and start making the habit of setting up all you need on your own.
Using this simple-to-follow tutorial, you will be able to use any version of Python and it will also teach you how to install almost any other application - from the source - as well.

Preparing The System and Installing Python

Like many other applications you will encounter, installation of Python on CentOS consists of a few (simple) stages, starting with updating the system and followed by actually getting Python for any desired version and proceeding with the set up process.
Remember: You can see all available releases of Python by checking out the Releases page. Using the instructions here, you should be able to install any or all of them.
Note: This guide should be valid for CentOS version 6.5 as well as 5.8 and 6.4.

Updating The Default CentOS Applications

Before we begin with the installation, let's make sure to update the default system applications to have the latest versions available.
Run the following command to update the system applications:
yum -y update

Preparing The System for Development Installations

CentOS distributions are lean - perhaps, a little too lean - meaning they do not come with many of the popular applications and tools that you are likely to need.
This is an intentional design choice. For our installations, however, we are going to need some libraries and tools (i.e. development [related] tools) not shipped by default. Therefore, we need to get them downloaded and installed before we continue.
There are two ways of getting the development tools on your system using the package manager yum:
Option #1 (not recommended) consists of downloading these tools (e.g. make, gcc etc.) one-by-one. It is followed by trying to develop something and highly-likely running into errors midway through - because you will have forgotten another package so you will switch back to downloading.
The recommended and sane way of doing this is following Option #2: simply downloading a bunch of tools by a single command with yum software groups.
YUM Software Groups
YUM Software Groups consist of bunch of commonly used tools (applications) bundled together, ready for download all at the same time via execution of a single command and stating a group name. Using YUM, you can even download multiple groups together.
The group in question for us is the Development Tools.

How to Install Development Tools using YUM on CentOS

In order to get the necessary development tools, run the following:
yum groupinstall -y development
or;
yum groupinstall -y 'development tools'
Note: The former (shorter) version might not work on older distributions of CentOS.
To download some additional packages which are handy:
yum install -y zlib-dev openssl-devel sqlite-devel bzip2-devel
Remember: Albeit optional, these "handy" tools are very much required for most of the tasks that you will come across in future. Unless they are installed in advance, Python, during compilation, will not be able to link to them.

Python Installation Procedure From Source

Setting up Python on our system will consist of 3 stages and 4 tools:
  1. Downloading the compressed source code package (wget),
  2. Extracting the files from this package (tar),
  3. Configuring and building the application (autoconf (configure) / make).
GNU wget
GNU's “wget” is an application used to download files over various protocols (such as HTTP, FTP). Despite being missing from the older versions of CentOS, it now comes by default.
Example Usage for wgetwget [URL]
GNU Tar
GNU's Tar is basically a file archive creation and manipulation tool. Using various options available, it is possible to create compressed packages as well as extracting them at a later time.
Example Usage for tartar [options] [arguments]
GNU autoconf and GNU make
GNU autoconf and make are two different tools, (mostly) used together to configure the source code before building and installing applications.
We will:
  • Use ./configure to configure everything before installation
  • Use make to connect libraries and the source before
  • Using make install - altinstall in our case - to build (compile) source code to create binary files and install the application on our system as configured using ./configure.
To learn more about autoconf, consider reading its manual.
To learn more about make, consider reading its manual.

Downloading, Building (Compiling) and Installing Python

In this section, all the instructions given can be used to download any version of Python. You will just need to replace the version stated (which is “2.7.6” in the example below) with the version you require (e.g. “3.3.3”). You can install and use multiple versions at the same time. Although, you will need to specify their version during the execution (i.e. instead of python, you will need to use python2.7 or python3.3).
Downloading the Source Archive
Let's begin with retrieving the (compressed) archive containing Python source code. We will target --version 2.7.6.
wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tar.xz
Example for version 3.3.3:
wget http://www.python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz
[Optional Step] XZ tools:
This file is compressed using XZ library. Your system, depending on its version, might not have it. If that is the case, run the following to install XZ library:
 yum install xz-libs
Extracting the Compressed Source Archive
This process consists of two steps: first decoding the XZ archive, followed by extracting the tar.
# Let's decode (-d) the XZ encoded tar archive:
xz -d Python-2.7.6.tar.xz


# Now we can perform the extraction:
tar -xvf Python-2.7.6.tar
Example for version 3.3.3:
xz -d Python-3.3.3.tar.xz
tar -xvf Python-3.3.3.tar

Configuring and Installation


Before building the source, we need to make sure that all the dependencies are there and prepare the environment. This is achieved automatically by using ./configure to handle the task for us.
# Enter the file directory:
cd Python-2.7.6

# Start the configuration (setting the installation directory)
# By default files are installed in /usr/local.
# You can modify the --prefix to modify it (e.g. for $HOME).
./configure --prefix=/usr/local    
Example for version 3.3.3:
cd Python-3.3.3    
./configure
This procedure should execute without any hiccups - as we have downloaded all the necessary tools and applications. When it is complete, we will be ready to move on to the next step: building and installing.

Building and Installing


After configuring everything for the system we are working on, we can continue with building (compiling) the source and installing the application. Normally, one would use “make install”; however, in order not to override system defaults - replacing the Python already used by the system - we will use make altinstall.
# Let's build (compile) the source
# This procedure can take awhile (~a few minutes)
make

# After building everything:
make altinstall
Example for version 3.3.3:
make && make altinstall   # <--- Two commands joint together
[Optional Step] Adding New Python Installation Location to PATH
Note: If you have followed the instructions using the default settings, you should not have the need to go through this section. However, if you have chosen a different path than /usr/local to install Python, you will need to perform the following to be able to run it without explicitly stating its full [installation] path each time.
Once the installation is complete, we can access the generated binaries (i.e. the Python interpreter for the version we have chosen) only by specifying its full location (path) (e.g. /usr/local/bin/python2.7) - unless of course the path exists already in the PATH variable (i.e. the variable which tells contains information on where to look for files stated).
If you would like to be able to access the newly installed Python interpreter without explicitly telling each and every time where to look for it, its path needs to be appended to PATH variable:
# Example: export PATH="[/path/to/installation]:$PATH"
export PATH="/usr/local/bin:$PATH"
To learn more about PATH, consider reading PATH definition at The Linux Information Project.

Setting Up Common Python Tools pip and virtualenv

Having installed Python, we can now finalize completing the basics for application production and deployment. For this, we will set up two of the most commonly used tools: pip package manager andvirtualenv environment manager.
If you are interested in learning more about these two tools or just quickly refreshing your knowledge, consider reading Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages.

Installing pip on CentOS Using a New Python Installation

Before installing pip, we need to get its only external dependency - setuptools.
From the article on virtualenv and pip:
It [setuptools] builds on the (standard) functionality of Python's distribution utilities toolset called distutils. Given that distils is provided by default, all we need left is setuptools.
Execute the following commands to install setuptools:
This will install it for version 2.7.6
# Let's download the installation file using wget:
wget --no-check-certificate https://pypi.python.org/packages/source/s/setuptools/setuptools-1.4.2.tar.gz

# Extract the files from the archive:
tar -xvf setuptools-1.4.2.tar.gz

# Enter the extracted directory:
cd setuptools-1.4.2

# Install setuptools using the Python we've installed (2.7.6)
python2.7 setup.py install
Installing pip itself is a very simple process afterwards. We will make use of the instructions from the article mentioned above to have it downloaded and installed automatically and securely using cURL library.
Note: To learn more about cURL, you can refer to the section explaining it here.
Let's download the setup files for pip and have Python (2.7) install it:
This will install it for version 2.7.6
curl https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py | python2.7 -
To learn about how to use pip, please refer to the article on Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages.

Installing virtualenv on CentOS Using a New Python Installation

Now that we have pip the package manager ready, getting virtualenv on the system is a breeze.
Run the following command to download and install virtualenv:
pip install virtualenv
To learn about how to use virtualenv, please refer to the article on Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages.

Sunday, June 16, 2013

Setting SSH public-key login in 5 seconds

Local (the computer to log in from):
ssh-keygen -t dsa

Remote (the computer to log in):
cat ~/.ssh/id_dsa.pub | ssh -l REMOTE_USER REMOTE_SERVER 'cat >> ~/.ssh/authorized_keys'


That's it!

Sunday, April 21, 2013

Wired behavior of NaN in Java...

float x = Float.NaN
Float X = new Float(x)
System.out.println(x == x)      // false
System.out.println(X.equals(X)) // true

....WTF?