2014-11-03

Four "C" of the Clean Code

Recently I am reading the book "Clean code" again. I have found there are 4 characteristics of the clean code. 

The 4 characters of the clean code should have:  
  • Controllable
  • Comprehensible
  • Convenient
  • Consistent 



Controllable


If there only just one concept to be remembered, it should be this one. 
If the program can be controlled by you, the author of the code or other who involved, this program will be a good program. 

For a controllable program, which is the program can be easily understood, changed, adding new features, and easy to debug. 
The more code involved, the more uncontrollable. It will become the "Gordian Knot.


Comprehensible:

Every program we write have two group of audiences; 
First is the machine, compiler, syntax checker, …., they will transfer our programs to executable;
Second is us, human being; The program should be readable so that we could understand and work on it. 
There are many chances that our programs will be read by someone else or yourself later. 
Therefore it is important to make the code comprehensible. 


Convenient:

While making a large program, we may involve a lots of code. Therefore, we need to arrange the code so that it helps to do thing fast. 

Here some examples:
- Find the libraries and functions available in the project and how to use it
- Quickly navigate to the class or method we want to go. 
- Easy to remember the classes involved

To do so, we need to adopt a good naming contention and code style.


Consistent

As we know, many words in English can refer to a similar meaning; One frequent met example in coding: number of X, count of X, size of X;  In order to prevent our code audience getting confused or mislead, we need to make sure the same word have the same meaning;
If you use "count" as the suffix telling how many, keep to use it over your class. 




2014-09-11

TDDccx3 1.1.0 - New Submenu UI developed.

The submenu of TDDccx3 is modified:





In the new design, we want to decrease the interference of the test components;
So the following changes are made
- Top toolbar is removed 
- Provide a Hide/Show button to hide/show the menu items
- Menu can be moved to wherever you want
- Toggle Stat is placed in the menu items;

The change is just made and not yet well test. It will be polished and tested soon. 

Available at:



2014-09-02

A day in my coding life.

Here is a short sharing of my daily coding life.

While arrived to office, prepare the basic first, breakfast, water and tea;

Then first thing first, I starts with a simple prayer and listening to biblical messages.

And then I read some industrial news from Twitter, Google Plus, Techcrunch, ... to get updated;

Next I prepare:
- Spotify (provide music for my concentration)
- Tomato.es (For Pomodoro Technique, one of time management skill)
- Trello (For task management)
- Evernote (for note taking and daily planning)

And then Tomato Clock starts, several 25 minutes session begin:

Every 25 minutes, I will focus on my different coding works:

  • Planning : Fail to plan, plan to fail. Always keep works being planned.
  • Program Design : Design is the origin, without a design, it will be very hard to code. 
  • Write and Run Code 
  • Refactor and Documentation : It help to re-organise what I have done
  • Sharing to other coders
  • Learn something new 
  • Testing : More test, more bugs unveiled and quality UP. 


While my team members are all there, we start the daily SCRUM to update the progress of each others.

A day of coding if full of fun and challenges !!!

Wish you enjoy your work and coding as well.









2014-08-06

SDK & Open Source used in my iOS project (2014)

In my recent iOS project, we have used a lots of open source code and SDK like many app do;

Here is the list of them:


  • CrashlyticsCrash Logging
  • Google Analytics: User Analytics: 
  • Parse: Push Notification Helper
  • EGORefreshTableHeaderView: PullToRefresh
  • SDWebImage: ImageView using URL
  • UIImage+ImageEffects: Making Blur Effect
  • UIImage+animatedGIF: Playing animated GIF in UIImageView
  • GCPlaceholderTextView: placeholder show in TextView
  • URBMediaFocusViewController: Enlarge the thumbnail image
  • YDSlider: Slider for audio player
  • JSONKit: JSON Helper
  • ASIHTTPLibrary: Asynchronous HTTP Request
  • TTAttributedLabel: Make UILabel having clickable link


Thanks for the developers of the above project! These save us a lot of time.

2014-07-13

TDDLib (cocos2d-x 3) updated: Improved UI

My TDD Testing framework for cocos2d-x 3.0 is updated.



Changes:
- Modified UI
- Filter test without the need to touch the "Find" button
- Add Background colour setting (help to check coloured elements)

Source: https://github.com/tklee1975/tddlib_cocos2dx3

2014-07-11

Fixing undesired outline of Label in cocos2d-x 3.0

Recently, when I work on my TDDLib project, I found that the Label of cocos2d-x 3.0 show the Label with an undesired outline which isn't I want to (The first label shown below).



After several google search, I found the solution to fix it (The second label shown above).

It's simple, just call the blend of the Label to BlendFunc::ALPHA_PREMULTIPLIED.
Code: label->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED

Source example:
std::string sysFont = "GillSans";

std::string test1 = "No BlendFunc";
std::string test2 = "ALPHA_PREMULTIPLIED";

Label *label;
Color3B textColor = Color3B(200, 245, 245);

// First Label (Undesired outline)
label = Label::createWithSystemFont(test1, sysFont, 40);
label->setColor(textColor);
label->setPosition(Point(250, 300));
addChild(label);

// Second Label (Fixed outline)
label = Label::createWithSystemFont(test2, sysFont, 40);
label->setColor(textColor);
label->setPosition(Point(250, 200));
label->setBlendFunc(BlendFunc::ALPHA_PREMULTIPLIED);

addChild(label);











2014-07-09

Using AutoResize in iOS App Development

When programming the UI of an application, we are inevitable to program an UI with dynamic width and height;




Real Example:
A view contain a footer and content with different text length, some cause 1 lines, so cause 2 lines;



Dynamic Layout in iOS


There are several ways to handle this kind dynamic layout in iOS programming, one of my favourite is using "Auto Resize Mask", it help to adjust the size of the subview and help the subviews sticking to the four borders;


Autoresizing mask constants


Mask related to the auto size
UIViewAutoresizingFlexibleHeight
UIViewAutoresizingFlexibleWidth

Mask related to auto positioning
UIViewAutoresizingFlexibleLeftMargin
UIViewAutoresizingFlexibleRightMargin
UIViewAutoresizingFlexibleBottomMargin
UIViewAutoresizingFlexibleTopMargin

Also see: Diagram about the mask

Note: We don't need type those mask value, usually we work with the interface builder

Tips of using AutoResize


  1. Use with Interface Builder, you can preview the appearance on how it works.
  2. Uncheck the "AutoLayout" of your XIB in interface builder.
  3. Don't modify the size and position on views which are well "autosized", just modify the superview size.

Deal with Autoresize bugs

  • Find out which layout component are resize as you expect and double check the autoresize setting.
  • Check the adjusted size in the layoutSubview method.
  • Can use NSStringFromCGRect to convert the view.frame to String which is easy to print out.



Reference

Adjusting the Size and Position of Views at Runtime (Apple Doc)

2014-05-28

Implementation of "Post count" of HashTag with Mysql stored proc

Recently, I am making a feature similar to Instagram HashTag search in my app, which is searching the hashtag with post count with the given keyword.

To do this, I try to keep the post count in the Tag record and get it when do the search. However, to complete this, I need to handle the way to increase the count when a new post is created.

To do so, I had chosen using stored proc to do this task.


What’s and Why stored procedure ? 


Combine several SQL in a named procedure. It can make the application code more simple.

Before using procedure:
We need to use two SQLs to handle
UPDATE table SET count = count + 1 WHERE tag = ‘myTag’
SELECT count FROM table WHERE tag = ‘myTag’

After using procedure:
Just simply use the following SQL
CALL increase_post_count(‘myTag’)

Stored procedure of “Increase Post count” 


Define the procedure 

DELIMITER //
CREATE PROCEDURE inc_post_count
(
   IN inputTag VARCHAR(100)
)
BEGIN
    UPDATE tbl_hashtag SET postCount = postCount + 1 WHERE tag = inputTag ;
    SELECT postCount FROM tbl_hashtag WHERE tag = inputTag ;
END //
DELIMITER ;

Note: The above statement is working mysql client but not in phpMyAdmin

Using the procedure
CALL inc_post_count(‘MyTag’) 


2014-05-22

TDDLib for cocos2d-x-3.0 go public

I am going to put my Unit Test Framework for cocos2d-x 3.0 to open source (github). If you are a lover of TDD or Unit Test, you may love it. 

Github: https://github.com/tklee1975/tddlib_cocos2dx3

Currently, I am writing some documents about how to setup the library in your project and how to add a new test. If you are interested and like this project, please let me know.  


Testing "testSprite"


Testing "testLabel"

2014-05-18

Map API - Looking for Places around a location

If we are talking about location based application, first of all, we think of GPS or LBS! However LBS only can tell us the coordinate (latitude and longitude) of your current location. It cannot tell you the place that you are standing at.

Thus, we need to work with Map API to get things done.


Features of the Map API


  • Given a location (latitude, longitude) , and then tell you the places near that location;
  • Given a name or name prefix with the location, and then tell you the places that match;
In short, with the help of the Map API + LBS, we are able to tell the possible places to users where they are currently at. 

What's Place?


The most basic and natural form about an location is just the coordinate (latitude, longitude); Imagine that you are at an unknown sea, the only possible information is just the coordinate.
However, the most of the cases, users aren't the sailors, coordinate mean nothing to them. So need the detail about that location, such as the street name, building name, country, etc. 

Geocoding vs Place Search


In the Map APIs, there are kind of information can be retrieved by the coordinate. 
First is the geocoding information, which it is the formal addresses near that coordinates. The method of this process is called "Geocoding". 

Example:
coordinate: 38.889772, -77.042771addresses:
  • 1964 Independence Avenue Southwest, Washington, DC 20227, USA
  • Washington, DC 20245, USA

Second is that place information, which are the places such as  shops, route, hospital, etc. This kind of information include the name of the entity and the address of that.  

Example:
coordinate: 38.889772, -77.042771places:
  • Constitution Gardens (Constitution Gardens, Washington, DC 20024, USA)
  • West Potomac Park (Southwest Washington, Washington, DC, USA)

For my own application, I use Place Search instead of Geocode because it is more understood by the end users.

Available Map API


For my selection, the best are Google Map API or FourSquare API; And there are still many selections available;











2014-05-11

Cocos2d-x 3.0 Setup (Include Git & Github support)

Recently, I am going to try the latest cocos2d-x 3.0 final version. Here is the note to use cocos2d-x 3.0 with the source control of Git & Github;





Steps to setup



1. Download and zip cocos2d-x 


Simply following the instruction at cocos2d-x official site ( http://www.cocos2d-x.org/download) to download.


2. Setup the directory structure 


The following is my structure related to the cocos2dx
  • /w/cocos2dx/engine - Place the cocos2d core at here. (The pack of the cocos2d-x project will be placed here)
  • /w/cocos2dx/project - The project directory, where is my code placed at.
  • /w/cocos2dx/script/ -  The script files simplify some task. (will discuss later)


3. Run the setup 


Just run the following commands

cd /w/cocos2dx/engine/./setup.py

It will change your .bash_profile to add some environment variable

Prepare the following information:  

  • ANDROID_SDK_ROOT
  • ANT_ROOT

4. Create a new project using script


Use the following command to make a new project :
cd /w/cocos2dx/engine/tools/bin/cocos_console/./cocos.py new -p ken.game -l cpp Example1 -d /w/cocos2dx/project/


5. (optional) Trim down the project size

Since every project made by the cocos.py will make a copy of the cocos2d engine inside the project. If you want to share the engine code among different projects, we can do steps below; However, if you are going to hack the engine code and don't affect other project, you shouldn't do that. One more point, this action will place the cocos2d engine source code outside the source control scope. (Pro: save space;  Con: change won't be logged)

Just do the following to keep the project smaller
mv ./cocos2d ../ln -s ../cocos2d ./cocos2d


6. Setup GIT 



Do the following step to setup GIT. 
  • Install Git. (suppose Xcode will help to install the git, but it doesn't happened. just go to http://git-scm.com/ to download it) 
  • Add the .gitignore to the project directorycd /w/cocos2dx/cp ./script/.gitignore project/Example1
  • Git initialisation
    run "git init" in your project directory
  • Add to SourceTree (SourceTree is a GUI version of Git. available at http://www.sourcetreeapp.com/)Select "Add Working copy" and the select the project directory (w/cocos2dx/project/Example1)
  • Commit the work at SourceTree


7. Sync with Github 


In the previous step, we just put the source code to the local repository; It will be more safe if we put the source on the remote location. Here, I select github. Besides github, there are many alternatives such as you setup your own git remote server or using bitbucket. 

There are the steps to setup repository in github.


     
  • Create a repository in www.github.com. (Assume that you are already registered) and copy-and-paste the git url.
  • Open SourceTree and select your project to add a remote location- Select the project.
    - Choose "Repository -> Repository Setting" in the menu.
    - Select the "Remotes" Tab.
    - Click the "Add" button; It will show the "Add Remote" Popup.
    -  Enter "origin" in "Remote Name" and the given github url in "Remote Path"
  • Pull the master branch to github (origin location)

8. Start coding and Enjoy it


Open the project in Xcode, build and Run it. 


2014-04-24

Making python module with C++ using boost.python (mac)


1. Install Python 

For most of the case, the python is already installed.
The paths of my mac are as followings:
  • bin: /usr/bin/python2.7
  • include:  /System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7
  • library: /usr/lib/python2.7
  • archive library:  /usr/lib/python2.7/lib/libpython.a

2. Install boost

Download boost at http://www.boost.org/users/download/
Build the library: 
./bootstrap.sh
and 
./b2 install

When success, can find the include and library in the following path:
include path: /usr/local/boost/boost/
library path:  /usr/local/boost/stage/lib

3. Create the hello world program
Find out the detail in boost.python doc; it is clear.
http://www.boost.org/doc/libs/1_55_0/libs/python/doc/tutorial/doc/html/index.html

4. Build the program to share library


Create a make script as follows:
--------------------------------------------------------------------------------------------------------------
#!/bin/sh

BOOST_ROOT=/usr/local/boost
PYTHON_ROOT=/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7

LD_LIBRARY_PATH=/usr/local/boost/stage/lib
PYTHON_LIBRARY_PATH=/usr/lib/python2.7/lib

echo $PYTHON_ROOT

g++ -c hello.cpp -I $PYTHON_ROOT -I $BOOST_ROOT
g++ -shared -o hello.so hello.o -lboost_python -lpython \
     -L $LD_LIBRARY_PATH \
     -L $PYTHON_LIBRARY_PATH

--------------------------------------------------------------------------------------------------------------
and run it.

Note:
  • to compile successfully, need to define the correct python and boost include path
  • to link successfully, need to define the boost.python and python library location



5. Play the module in python

First, need configure the environment so that python know boost.python
DYLD_LIBRARY_PATH=$BOOST_ROOT/stage/lib

Then run ‘python’ and type 
import hello
print hello_ext.greet()



If the DYLD_LIBRARY_PATH not define, may receive the following error message:
Library not loaded: libboost_python.dylib




2014-04-15

Make your Mysql friendly to Emoji character

In my last projects, Mysql is usually UTF-8 as the core encoding. However, it is not good for my current project now because we will play with Emoji Character;

Emoji Character is using an extended utf-8 Encoding, called UTF-8 mb4 (utf8mb4).

If inserting string with Emoji Character, the mysql will alert "incorrect string" and make the SQL fail.
To fix this, we need to:

  • Change the database and table to utf8mb4 encoding 
  • Change the connection encoding to utf8mb4 as well

External Reference:
  • http://mathiasbynens.be/notes/mysql-utf8mb4
  • http://info.michael-simons.eu/2013/01/21/java-mysql-and-multi-byte-utf-8-support/
  • http://my.oschina.net/wingyiu/blog/153357

2014-03-17

Calculate the distance between two geo locations

We are developing a location based app and we encounter a problem about the geo location yesterday. Which is "how to get the distance between two points in the map". It seem to be easy if using our usual XY coordination system (the Cartesian coordinate). However, the inputs are the latitude and longitude, not the unit of meter;



Formula:

acos( 
   cos(a.lat) x cos(a.long) x cos(b.lat) x cos(b.long) 
   + cos(a.lat) x sin(a.long) x  cos(b.lat) x sin(b.long)
   + sin(a.lat)*sin(b.lat)
)  x  earth.radius

Where:

a.lat, a.long  = latitude and longitude of the 1st point ( in radians)
b.lat, b.long  = latitude and longitude of the 2nd point ( in radians)
earth.radius = the radius of the earth;  (which is: 3443.9 nautical miles or 6378 km)


Source Code (in java):


public static double distanceBetween(double lat1, double long1, double lat2, double long2)
{
 double rLat1 = Math.toRadians(lat1);
 double rLong1 = Math.toRadians(long1);
 double rLat2 = Math.toRadians(lat2);
 double rLong2 = Math.toRadians(long2);
  
 double part1 = Math.cos(rLat1) * Math.cos(rLong1) * Math.cos(rLat2) * Math.cos(rLong2);
 double part2 = Math.cos(rLat1) * Math.sin(rLong1) * Math.cos(rLat2) * Math.sin(rLong2);
 double part3 = Math.sin(rLat1) * Math.sin(rLat2);
 
 return Math.acos(part1 + part2 + part3) * RADIUS;
}

Reference: 

There are more documentation talking about the distance calculation, also google provide API to do so.




2014-03-16

Abnormal java.net.UnknownHostException on resin

Recently, I encountered a problem while I am calling to Google API in my java code running on Resin. The problem is that: The http call raise an UnknownHostException;



It doesn't caused by Java itself because the UnitTest show it is correct.
It doesn't caused by Resin because it work in my development platform.

So what go wrong? Finally, I has discovered it is wrong in the staging server environment;
The /etc/hosts isn't configured as the resin want to. (... maybe it is the problem of resin too ..)

To fix it:
- type "hostname" to find your hostname . e.g "my.pc"
- edit /etc/hosts and add the line "127.0.0.1 my.pc"
- restart the server to make it effective

Notes:
- This problem may not be happened in all environment. My macbook doesn't have the problem.

Related Links:






2014-03-13

Make java connection pool auto reconnect

Recently we encountered a problem when using java db connection pool. The problem is that the connection is being closed by the DB server since it is already timeout. To due with this, need to configure two more parameters.

They are:
testOnBorrow  ;  define it as "true"
validationQuery ; define it as "SELECT 1 FROM dual" if you are also using MySQL

Yes, It is easy to config it. But how to test it? (Many sites may not give the answer). 

To verify the configuration is work, we can make a simple Unit Test;

Step 1: Make a failure case

Make an unit test base on the following code;


Properties p = new Properties(); 
prop.put("driver", "org.gjt.mm.mysql.Driver");
prop.put("url", "jdbc://localhost:3306/db");
prop.put("username", "user");
prop.put("password", "123456");
p.setProperties("testOnBorrow", "false");
p.setProperties("validationQuery", "");

BasicDataSource ds = BasicDataSourceFactory.createDataSource(prop);
ds.setMaxActive(1);
ds.setMaxIdle(1);
ds.setMinIdle(0);

Connection conn = ds.getConnection();
System.out.println("First connection");


System.out.println("Sleep start");
Thread.sleep(10000);
System.out.println("Sleep end");

Connection conn = ds.getConnection();
System.out.println("Second connection");


To make the connection fail at the second time, try to kill the connection in DB side while "Thread.sleep";


Step 2: Fix the failure 

Simply change "testOnBorrow=false" and "validationQuery=" to 
 "testOnBorrow=true" and "validationQuery=SELECT 1 FROM dual"

Then, run the test again. we will see "Second connection" show up instead of Exception message.



2014-01-27

Cocos2d-x Error: "Skipping selector 'onPopupYesPressed' since no CCBSelectorResolver is present."

Today, I failed to bind a button and the log said "Skipping selector 'onPopupYesPressed' since no CCBSelectorResolver is present.";

The reason is that simply because I forget to define the "Custom Class" name in CocosBuilder !! =.=

2014-01-23

制作游戏的难点


最近和友人談談各自製作遊戲的情況,發現真有點難; 


難一:難在找到志同道合及能力互補的團隊! 

難二:難在找出好的賣點! 

難三:難在製作出好的體驗! 

難四:難在把抽象的事情具體化!

難五:難在把設計實現出來! 

難六:難在放下主觀想法,拿起玩家的想法

游戏开发是梦幻的工业,这是事实,但是令一个事情,就做出好的游戏,是困难重重的,需要热情和能力兼备; 

真正製作的遊戲開發者,就是在不斷克服困難,不斷改进的勇者們!

2014-01-20

以恩典為年歲的冠冕@2013

剛過了的2013, 神給我和我家很多的恩典:

  • 醫治母親的大病 
  • 幫助天藍媽媽能有力量照顧天藍 
  • 天藍健康快樂地成長 
  • 我們更明白神的話和祂的恩典 
  • 為我們預備了裝修的費用和母親的醫藥費 
  • 轉了新工作,可以多些時間照顧天藍和太太 
  • 賜予我們聰明智慧,處理家事和公事
  • 爸媽租到一間又大又好的屋
  • 我們可以搬去大一點的屋