My Sublime config

It doesn’t take long to prepare for a sublime config. Since I am always a big fan of sublime, been using it on every machine and every project I have encountered with. I realized that every time I put up an IDE environment, it took me some time to remember and collect handy packages I am familiar with. So I decided to paste my sublime config in order to future auto-provision the environment.

To start with, go to Package Control: Advanced Install Package

Then paste below comma-separated package list,

And most importantly in all step above, just to check the Package Control installation script in


My Aria2 Config

Aria2 is popular in downloading files.

And RPC mode combine with WebUI makes aria2 more feasible in managing downloads.

(Web UI Repo:

Here is what I have been using for the aria2 conf


Docker LEMP stack build

Docker is great. It provides lightweight virtualization with almost zero overhead.

And out here are tons of articles about docker best practice It has short-versioned bullet points as below,

  1. Containers should be ephemeral
  2. Use a .dockerignore file
  3. Avoid installing unnecessary packages
  4. Each container should have only one concern as “one process per container” may not be all-time true.
  5. Minimize the number of layers
  6. Sort multi-line arguments
  7. Build cache

Given docker is so good to have, I took an initiative with the intention of putting general PHP development env into docker. So I built a small git repo about docker lemp stack.

Github Hanswang/docker-lemp

From this repo, we take use of docker-compose.

Mac Terminal Config

Here is the terminal config of ~/.bash_profile

export CLICOLOR=1

alias ls='ls -GF'
alias ll='ls -lsah'

if [ -f $(brew --prefix)/etc/bash_completion ]; then
  . $(brew --prefix)/etc/bash_completion

export PS1="\e[0;33m\]\t\[\e[m\] 🖖🏼  \e[0;36m\]\w\[\e[m\]:\n $ "

As you probably noticed, we need the bash-completion from brew by following,

brew install bash-completion

And furthermore, to complete the outlook, we need the color scheme from below repo.

git clone

Jupyter with Spark Setup

Recently doing a poc for work, learnt one thing or two about jupyter and spark. Here is the environmental summary I experienced

  • jupyter version 4.2.1
  • spark version 2.0.2 with hadoop2.7
  • python version 2.7.12
  • docker version 1.11.2, build b9f10c9/1.11.2

Simplified version – Docker

# pull the docker image from jupyter org
docker pull jupyter/all-spark-notebook
# run the image with the name & data dir you want to mount
docker run -d --name hans-notebook -v <local_src_dir>:/home/data -p 8888:8888 jupyter/all-spark-notebook

A little bit complicated version – manual setup

  1. Manual installation of each components
    #create virtualenv
    virtualenv jupyter_poc
    source ./jupyter_poc/bin/activate
    #install jupyter
    pip install jupyter
    #generate jupyter config file by running
    jupyter notebook --generate-config
    #download spark
    #un-zip the file
    tar -zxvf spark-2.0.2-bin-hadoop2.7.tgz .
  2. In the jupyter config file, we need to simple initial setup for file ~/.jupyter/

    #open up the ip
    c.NotebookApp.ip = '*'
    #disable browser opening since its not localhost dev
    c.NotebookApp.open_browser = False
    #specify the port
    c.NotebookApp.port = 8888
    #temp disable the password token
    c.NotebookApp.token = u''
  3. After downloading spark, we need to export it in the PATH in ~/.bash_profile ( or ~/.bashrc )

    export PATH
    export SPARK_HOME=$HOME/spark-2.0.2-bin-hadoop2.7
    export PYSPARK_SUBMIT_ARGS='--master local[*] pyspark-shell'
  4. Also we need to introduce pyspark into jupyter python env in ~/.ipython/profile_default/startup/

    import os
    import sys
    spark_home = os.environ.get("SPARK_HOME")
    if not spark_home:
        raise ValueError('SPARK_HOME environment varialble is not set')
    sys.path.insert(0, os.path.join(spark_home, 'python'))
    sys.path.insert(0, os.path.join(spark_home, 'python/lib/'))
    execfile(os.path.join(spark_home, 'python/pyspark/'))

After these setup, just open the <ip>:8888 on the browser, the jupyter welcome page should be shown.
Happy coding with spark! 😛

Great reading about relation with press for new product launch

In order to reach out for the product to targeted customers, the press plays a vital role. How to reach out? I found an interesting reading today at here

This article enlightened me about generating news instead of bragging about the feature of your product.

News is timely. It makes more sense to talk about it today rather than tomorrow. News attracts attention now and that’s what reporters want

And what’s more, in the comments, further explanation says,

Journalists don’t want to advertise your startup for free, they care about writing a story that entertains and educates their readers. Feed one to them.

Back to the article, it highlighted 4 bullet points to tackle this problem in right direction.

  1. Generate News
    • Product Launches and Features
    • Product/Sales Milestones
    • Significant BD Deals or Customers
    • Fundraising
  2. Make Your Own Press Contacts
  3. Pitch Those Contacts an Exclusive
  4. Share News at a Consistent Cadence
  5. Just like BD, don’t expect to get every meeting and story. When a reporter says “no”, ask yourself why.

Also here is a very interesting tools for EDM,

Pitch templates using different angles

Difference between Docker And Vagrant

Very good read about Difference between Docker and Vagrant

I see docker as application container while vagrant as vitual-machine management tools.

So in terms of performance of booting up application, docker is faster than vagrant.

To be continued…

Handy script to work with PDF files

PDF is commonly used printing file format. Creating & organising it might be a bit hard if without Acrobat Pro’s help.

Today I discovered some open source lib to manipulate PDF files, including Creating, Splitting, Merging, and Re-Ordering PDF pages.

Below is the script line for creating PDF,

echo 'Hello World!' | enscript -B -o - | ps2pdf - content.pdf

-B for enscript omit the header for the output

Here is the script for re-ordering the raw PDF into a book-style printable version.


if [ $# -ne 2 ] ; then
    echo "Invalid input supplied, please choose input PDF and page counts"
    echo "    example : ./ <input.pdf> <pageCount>"
    exit 1

echo "Formatting begins ... "

let "blankPageCount = $pageCount % 4"

# Check if blank page padding needed, if so create one
if [ $blankPageCount -ne 0 ] ; then
    echo ' ' | ps2pdf - blank.pdf 

# setup each fold loop - one fold means one print page
let "foldCount = $pageCount / 4"

echo "    total $foldCount printing slides generated";
echo "    with $blankPageCount blank pages";

while [ $startFold -lt $foldCount ] ; do
    let "coverPrintpage = $startFold * 4 + 4"
    let "leftPrintpage = $startFold * 4 + 1"
    let "backPrintpage = $startFold * 4 + 3"
    pageOrganizor="$pageOrganizor A$coverPrintpage A$leftPrintpage-$backPrintpage"
    let "startFold += 1"

if [ $blankPageCount -eq 0 ] ; then
    cmd="pdftk A=$file cat$pageOrganizor output fmt_output.pdf"
elif [ $blankPageCount -eq 3 ] ; then
    let "blankStartPage = $pageCount-2"
    cmd="pdftk A=$file B=blank.pdf cat$pageOrganizor B A$blankStartPage-$pageCount output fmt_output.pdf"
elif [ $blankPageCount -eq 2 ] ; then
    let "blankStartPage = $pageCount-1"
    cmd="pdftk A=$file B=blank.pdf cat$pageOrganizor B A$blankStartPage A$pageCount B output fmt_output.pdf"
    cmd="pdftk A=$file B=blank.pdf cat$pageOrganizor B A$pageCount B B output fmt_output.pdf"

echo "Merging pdfs ... "

# cleanning up
echo "Cleanup and done"
if [ -e "blank.pdf" ] ; then
    rm blank.pdf

The seven rules of a great git commit message

  1. Separate subject from body with a blank line
  2. Limit the subject line to 50 characters
  3. Capitalize the subject line
  4. >Do not end the subject line with a period
  5. Use the imperative mood in the subject line
  6. Wrap the body at 72 characters
  7. Use the body to explain what and why vs. how

Play with Laravel Elixir

An easily configured tool for frontend build

Setting up production-ready frontend package could be time consuming and boring. If we use RequireJS with AMD mode, then it could easily bury you in the deep configuration of dependencies, GruntFile setting and file structure exclusion for source control. Luckily, we got Laravel Elixir with Gulp.

So to start with, we got the code in package.json:

  "devDependencies": {
    "gulp": "^3.8.8",
    "laravel-elixir": "*"

This is the basic packages it required. to add more (e.g. bootstrap-sass), just list more in the dependecies (diff from devDependencies). Next step is,

npm install

Then after relevant packages are installed, next one is to config gulpfile.js to customize frontend package. To start with,

elixir(function(mix) {
    // or sass
    // mix.sass('app.scss');

The less or sass source code folder would be in




The rest of interesting API could be,

// compile multiple less (or sass) file into one app.css
mix.less(['app.less', 'src1.less', '../vendor/lib1.less']);

// concat multiple js script into one js file (name specified or otherwise app.js by default)
   ], 'public/js/dst.js', sourceDir)

// copy dump files from one dir to dest dir
   .copy('srcDir', 'dstDir')

// interesting API for stamping version on files, laravel embeded elixir('file') function related
   .version(['file1.css', 'file2.js']);

Other 2 important console API should be remembered.

gulp watch

This is a monitoring script to detect any source file changes, and apply gulp script on them.


gulp --production

This is to do the minifying and uglyfying on source to make output production ready.