Thursday, December 13, 2012

Ternary in python

xxx = ..... something
msg = xxx if xxx  else  "hello world"

or better:
msg = xxx or "hello world"

Saturday, December 8, 2012

Install Archlinux on KVM, and ssh to play with it

Today, I've installed Archlinux on KVM virtual machine. I tried do it some times before but never done because the feeling something will be complicated with format HDD / config anything by hand. The truth is, it's nothing more than learn some simple command.

create a virtual machine and install archlinux on it:

root@lappy: ~ # virt-install --connect qemu:///system --name archfirst --ram 512 --disk path=~/archfirst.img,size=8 --cdrom=/home/hvn/Downloads/archlinux-2012.08.04-dual.iso

Friday, November 16, 2012

Quick look into Python default modules

Have you ever seen code in Python default modules, let's take a look:

First, find out where are they with "locate" command:

hvn@lappy: / $ locate subprocess

we've locate subprocess module, which has a name specific enough. All python default module are in /usr/lib/python2.7/

Thursday, November 8, 2012

Nose – Fix nosetests finding 0 tests

Ran 0 tests in 0.000s

Just recheck, your test file  must have "test" in filename

Sunday, October 14, 2012

Language, language, language... I want to be a polyglot

I've tried many time to get Function Programming but I can't. Just learn some syntax then forgot all because it's very hard to get them if you don't really use them.

Of cause, everyone will argue, Haskell or a dialect of LISP?
Some answer can be found here:

Haskell like, Smalltalk. They are so pure, and you should learn them for learning many thing.

"Haskell and Lisp are two totally different beasts.
Haskell is kindof "pure functional programming in an ivory tower"
Lisp is kindof "code-is-data / data-is-code / make your own language constructs". You can manipulate your code in whatever way you can imagine.
They are very different. Both share the "functional programming" aspect, but that's really a tiny little common point compared to their differences. Just try them out and you will see how different they are!"

so go for haskell first, then lisp.
Happy coding!

One thing I hate about Haskell is its compile (ghc) is too heavy weight!

Saturday, October 13, 2012

[BASH] Count frequency of each letter in an English document

use only coreutils of Linux

first, convert all upper to lower by tr command, then grep with -o option, sort, uniq, then sort again!

hvn@lappy:~/Downloads$ tr '[:upper:]' '[:lower:]' <  prideandprejudice.txt | grep -o [a-z] | sort -nr | uniq -c | sort -nr
  71194 e
  48159 t
  42695 a
  41379 o
  38944 i
  38721 n
  34582 h
  33870 s
  33468 r
  22843 d
  22071 l
  15510 u
  15124 m
  14060 c
  13033 y
  12573 w
  12381 f
  10444 g
   9363 b
   8683 p
   5840 v
   3342 k
    970 j
    938 z
    867 x
    638 q

Tuesday, September 18, 2012

SSH into a VM from host machine

I'm using Virtualbox 4.1.2 on Ubuntu 12.04 LTS
After installed an Ubuntu server 12.04 into a VM machine, I want to ssh to it.

1. Config network
The fastest way to do this is enable a new adapter, attach it to Bridged Adapter. You have to turn off your VM. Then choose setting

Add caption

Start your VM. Now you need to config ip address for new interface:

Sunday, September 16, 2012

[Python] with - context manager

1. Context manager
Context manager : là một đối tượng chịu trách nhiệm đóng resource khi resource ấy không cần dùng nữa.

Khi sử dụng context manager, người dùng (developer) sẽ chỉ cần khai báo và sử dụng resource, không cần lo phải đóng nó lại.

file là một ví dụ, bình thường khi dùng file, ta sẽ phải mở - dùng - đóng. Từ phiên bản python2.5 trở đi, file đã được implement để trở thành 1 context manager. Khi dùng nó với câu lệnh with, ta không cần đóng nó nữa:

>>> with open("/etc/hosts") as f:
'\tlappy\n::1\t\tlappy ip6-localhost ip6-loopback\nfe00::0\t\tip6-localnet\nff00::0\t\tip6-mcastprefix\nff02::1\t\tip6-allnodes\nff02::2\t\tip6-allrouters\n\n'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file

Wednesday, August 15, 2012

Python assigment, shallow copy, and deep copy

I 've copy many text from below links, but deleted them all. Never copy, never copy, never copy ^6^

Below links are MUST read, if you really use python

Must read, because you will write python code, not C/Java...
Code Like a Pythonista
Must read, to get to know about mutable and immutable object. Things seem not important to beginner but will cause many problems if you don't really understand it.
Must read, because you must understand how does assigment, shallow and deep copy work.

If you dont, prepace to face many bug because lack of knowledge :)

"numbers, strings and tuples are immutable, while dictionaries and lists are mutable."

Tuesday, August 7, 2012

Why crontab does not work?

I've try to set my python script run daily use crontab.
If your dont know what is cron, learn it now:

If your crontab is working well now, skip this post. Otherwise, try to figure out why it does not work.

0. Find out whether cron daemon running or not

hvn@squeeze:~/Apps/birth-reminder$ pgrep cron

Monday, August 6, 2012

Python When and Where

When to use XYZ
Where to use ABC

Answer them all here.

(update later)


Python global

global (readonly):
a good approach:
- If you have only 1 file: declare global variables at the top.
- If you have many files use them: write all that variables to a config file, use ConfigParser to read them in.

global (not-readonly):
pass it around! don't use global

SO: you should never use global keyword

Wednesday, August 1, 2012

[FIXBUG] depends ... but ... is not going to be installed

Cài lại vim vì bản vim đang dùng không hỗ trợ copy ra clipboard.

Làm sao biết?
mở vim ra, gõ :version
tìm xem chữ  xterm_clipboard trước nó là dấu + hay -.
Nếu - là không hỗ trợ (không compile với parameter xterm_clipboard).

Thế nên phải cài vim-gtk hoặc vim-gnome. Nhưng khi gõ sudo apt-get install vim-gnome nó báo lỗi như sau:
depends vim-common (= 2:7.3.429-2ubuntu2) but 2:7.3.429-2ubuntu2.1 is to be installed
các xử sự với tất cả các lỗi kiểu depends ... but ... is not going to be installed như sau

gỡ hết ra và cài lại:
sudo apt-get purge vim
sudo apt-get remove vim-common
sudo apt-get autoremove

rồi cài lại là ok

Tuesday, July 31, 2012

HTTP header

Firefox :

wget -d
d = debug

curl -v
v = verbose

Change wget agent

using with wget -U 'AGENT' to check whether wget work.

hvn@hvnatvcc: ~/python/NetChecker/bin $ wget

hvn@hvnatvcc: ~/python/NetChecker/bin $ wget -U 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1' 

return other result

Friday, July 27, 2012

Python buildout

The official document quite ugly:

You should follow below tuts to get understanding what id does:

Deploy using zc.buildout and PythonPaste  (if you know flask "just a little", this will help you full understand what it do,)

Then, you can turn back to read the official document

What does zc.buildout do?
Basically, it install packages that you specified in buildout.cfg. So you can develop/deploy isolate to other project, and futhermore, you can help someone has the same environment as yours.

What is build out :
Quoting the Buildout website, "Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.". Buildout originated from the Zope/Plone community to automate deployment of customized instances of their software. Lead by Jim Fulton, CTO of Zope Corporation, Buildout became a stable and mature product over the years.
Buildout is used in SlapOS to define which software must be executed on a Slave Node. It has a key role in SlapOS industrial successes. Without it, SlapOS could not exist. However, buildout is also often misunderstood - sometimes purposely - by observers who criticize its use in SlapOS. Many people still do not realize that there is no possible software standard on the Cloud and that buildout is the solution to this impossibility. Experts know for example that any large scale production system which is operated on the Cloud (ex. a social network system) or privately (ex. a banking software) uses patched software. Relational databases are patched to meet performance requirements of given applications as soon as data grows. If a Cloud operating system does not provide the possibility to patch about any of its software components, it is simply unusable for large scale production applications. SlapOS is usable because its definition of what is a software is based on the possibility of patching any dependent software component.


Nói chung với buildout bạn sẽ:
- Phát triển các phần mềm trên môi trường độc lập (tương tự virtualenv). Tức ở project này bạn dùng package A, phiên bản B còn ở project khác dùng package C phiên bản D. (ở A dùng python2.5 còn ở C dùng python2.7 chẳng han)
- Không cần quyền root để cài các package
- Tự động thiết lập môi trường giống hệt ở mọi nơi chỉ cần file buildout.cfg
- Tạm thế.

Thursday, July 26, 2012

Introduction to finance

đã enrolll lớp này
và sẽ take note tất cả ra đây :D

insist on clear understanding

Finance is the study of value, not money\
Money is just tool
Value creatation: 2 components: time & uncertainly
Will learn a framework
Finance = art + science

time value of money
decision criteria
bonds and stocks
uncertainty & risk

understand WHY they work the way they do

time value of money:

PV = present value
FV = future value
N :  number of period (#)
r = Interest rate (%) > 0

Book: theory of interest

love for example, is something that you can't put a dollar sign. That's why it's awesome

Wednesday, July 25, 2012

Code then fail...

Lesson for to day: (some best practice i've leart from my experiences)

  1. Every Python function should return a value if it supposed to return a value. You should explicit return None. (Explicit is better than implicit - PEP 20)
    "So if a function is supposed to return a value, then I make sure all code paths have a return, and that the return has a value, even if it is None.
    If a function "doesn't" return a value, that is, if it is never called by someone using its return value, then it's ok to end without a return, and if I need to return early, I use the bare form, return."
  2.  pdb not work on multithreading
  3. careful with copy. Understand when you need deepcopy
  4. You should know how to use debuger, it will save your life one day.
  5. Debugger and unittest will show it value when you found your bug. When you fail!

Friday, July 20, 2012

Debian Squeeze (i386 & amd64)

Install skype 4 on squeeze (ix86 / amd64) 
Installing skype on Debian Squeeze
How to install Skype 4.0 on Debian Squeeze
root@HVNLappy:/home/hvn/Downloads# sudo dpkg -i skype-debian_4.0.0.8-1_i386.deb
sudo: unable to resolve host HVNLappy
(Reading database ... 67004 files and directories currently installed.)
Preparing to replace skype (using skype-debian_4.0.0.8-1_i386.deb) ...
Unpacking replacement skype ...
dpkg: dependency problems prevent configuration of skype:
 skype depends on libqt4-dbus (>= 4:4.5.3); however:
  Package libqt4-dbus is not installed.
 skype depends on libqt4-network (>= 4:4.5.3); however:
  Package libqt4-network is not installed.
 skype depends on libqt4-xml (>= 4:4.5.3); however:
  Package libqt4-xml is not installed.
 skype depends on libqtcore4 (>= 4:4.6.1); however:
  Package libqtcore4 is not installed.
 skype depends on libqtgui4 (>= 4:4.6.1); however:
  Package libqtgui4 is not installed.
dpkg: error processing skype (--install):
 dependency problems - leaving unconfigured
Processing triggers for gnome-menus ...
Processing triggers for desktop-file-utils ...
Errors were encountered while processing:
root@HVNLappy:/home/hvn/Downloads# sudo apt-get install libqtgui4
sudo: unable to resolve host HVNLappy
Reading package lists... Done
Building dependency tree      
Reading state information... Done
You might want to run 'apt-get -f install' to correct these:
The following packages have unmet dependencies:
 libqtgui4 : Depends: libaudio2 but it is not going to be installed
             Depends: libfontconfig1 (>= 2.9.0) but 2.8.0-2.1 is to be installed
             Depends: libjpeg8 (>= 8c) but it is not going to be installed
             Depends: libmng1 (>= 1.0.10) but it is not going to be installed
             Depends: libqtcore4 (= 4:4.8.2-1) but it is not going to be installed
             Depends: libtiff4 (> 3.9.5-3~) but 3.9.4-5 is to be installed
             PreDepends: multiarch-support but it is not going to be installed
 skype : Depends: libqt4-dbus (>= 4:4.5.3) but it is not going to be installed
         Depends: libqt4-network (>= 4:4.5.3) but it is not going to be installed
         Depends: libqt4-xml (>= 4:4.5.3) but it is not going to be installed
         Depends: libqtcore4 (>= 4:4.6.1) but it is not going to be installed
E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).
root@HVNLappy:/home/hvn/Downloads# apt-get -f install

Tự challenge mình với việc cài Debian 6.0.5 Squeeze 64 , không giao diện và rồi... đầu hàng. Thế nhưng những kinh nghiệm trả giá bằng thời gian thì phải giữ lại.

 Chọn chỉ cài phần core + gói cho laptop, không tự động config mạng.
Sau khi cài xong, việc đầu tiên là làm cho có mạng, ở đây là mạng dây.

sửa file /etc/network/interfaces

thêm vào dòng
auto eth0
iface eth0 inet dhcp

#Cho wifi
auto wlan0
iface wlan0 inet dhcp
wpa-ssid ten_mang_wifi
wpa-psk password

 sau đó lấy quyền root chạy /etc/init.d/networking restart
ifup / ifdown ten_iface
Eg: ifup wlan0

nếu vẫn không được thì gõ lệnh : dhclient
Cài sudo (thường có sẵn trong đĩa nên ko cần dơwn):
sửa file : /etc/sudoers
thêm dòng
hvn    ALL=(ALL) ALL dưới dòng  (hvn là tên user)
# User privilege specification
root    ALL=(ALL) ALL
Để có giao diện:
cài xorg (hình như chỉ cần cài mỗi xorg-server thôi, lúc cài nó tống hết nên ko chắc.
Sau đó phải cài 1 desktop manager.Ở đây mình chọn gdm
apt-get install gdm

rồi cài 1 window manager, lựa chọn là i3
apt-get installl i3

do squeeze là bản stable của debian, với tinh thần stable một cách bảo thủ của họ thì bạn hòan toàn khó có thể sống 1 cách "on the edge" được. Để cài 1 số phiên bản mới hơn của 1 số phần mềm, hãy sửa lại trong file /etc/apt/sources.list , thay

deb squeeze main
deb wheezy main
deb sid main

bạn chỉ nên thay rồi apt-get update, cài xong app mình cần rồi chuyển lại về squeeze, việc chạy lẫn lộn giữa các bản thế này nhiều khi khiến hệ thống mất đi tính stable và có thể bị hỏng =.=

Debian là một os tốt cho những thứ cần tính ổn định cao như làm server, còn để làm desktop, có lẽ bạn nên dùng Ubuntu để được dùng những phần mềm mới hơn mà tính ổn định của 1 desktop vẫn được đảm bảo. Giảm thiểu thời gian config những thứ ko cần thiết.

Khó khăn  ~.~
bản 64bit:
1. ko tìm được FF bản stable trên trang của Firefox
2. cài ibus không được vì dependency
3. sau 1 hồi đánh vật cũng cài được skype, nó cần thư viện ia32libs. Phải chọn source từ wheezy mới có.
-> bỏ, không chơi bản này nữa.

Skype 4.0 lại bị dependency vào libqt...Gõ như đoạn đầu bài này là giải quyết được.
resolv.conf rewritten each time reboot

open file: /etc/dhcp/dhclient.conf
$ sudo gedit /etc/dhcp/dhclient.conf 
remove comment from line:
# prepend domain-name-servers;
prepend domain-name-servers,;
note the trailing semicolon

add service start at boot:

add command to file: /etc/rc.local

Saturday, July 14, 2012

Nhật ký ArchLinux - KISS

vì thích cái triết lý của Arch từ lâu mà đã down đĩa cài về. Install xong nhưng vứt 1 xó vì không có thời gian mò.

A simple, lightweight distribution 

the Arch Philosophy, perhaps best summarized by the acronym KISS for Keep It Simple, Stupid. 

nay lại chả muốn làm gì, ngồi nghịch arch tiếp cho vui :D 


Monday, June 11, 2012

OpenOffice và trải nghiệm kinh khủng

OpenOffice (OO) là bộ Office miễn phí mã nguồn mở được cài sẵn trên hầu hết mọi phiên bản của Ubuntu. Nếu không phải làm những việc "nghiêm trọng" thì bạn có thể chơi với nó. Nhưng nếu phải làm 1 cái đồ án chẳng hạn thì lời khuyên là bạn nên dùng M$ Office 2003 - 2007 hoặc dùng Latex để khỏi phải trải qua những giây phút kinh khủng ấy :D

Bài viết này là bài đầu tiên cũng như cuối cùng cho OpenOffice, từ giở trở đi sẽ học viết bằng LaTex.

-1. Kinh nghiệm chung, ko liên quan đến OO là dù soạn thảo bằng cái gì thì bạn cũng nên chọn CỠ GIẤY, căn lề trước khi gõ bất kỳ dòng nào vào đó. (Format -> Page)
0. Kinh nghiệm chung cho việc dùng phần mềm miễn phí/ mã nguồn mở: dùng phiên bản Stable mới nhất để tránh gặp phải những lỗi ngớ ngẩn đốt cháy những giây phút quý báu của cuộc đời bạn.

1. Tạo dòng kẻ ngang cho header và gạch trên cho footer:
- Bấm vào khung của header/footer. Chuột phải chọn -> paragraph... rồi vào tab border.
2. Nếu gặp lỗi không thể để con trỏ xuống dưới 1 cái table trong writer để gõ:
- Cut cái bảng ấy đi. Gõ enter vài cái rồi paste nó lại lên trên các dòng vừa enter vào.
3. Numbering and bullet: Nếu bạn đang gõ 1, tiếp theo là 2 bằng chế độ numbering, khi bạn cần thì sẽ phải ra 3 ,4 (chuột phải -> chọn use previous numbering...) . Nếu giữa khoảng 2 -> 3 của bạn có sử kiểu numbering khác (như -  đầu dòng chẳng hạn) bạn sẽ không thể nối tiếp cái danh mục 12 34 của mình được
- Dùng cái chổi, bôi vào dòng 1 hay 2 rồi quét cho 3 và 4.
4. Làm mục lục bằng OpenOffice.
Có 1 khái niệm bạn cần biết là outline. Outline là thể hiện của cái "đề mục" của bạn trong mục lục. Để chọn outline cho dòng bạn đang dùng, đặt chuột ở dòng đó, chuột phải chọn paragraph -> outline -> chọn level. Đừng chọn paragraph style... bạn sẽ đau đầu đấy :D
5. Viết formula:
Muốn viết tổng sigma từ i = 1 đến n thì hãy gõ vào : sum from i=1 to n abc, cái panel bạn  chọn không làm đúng việc này.
Căn giữa công thức:
chuột phải , chọn đâu đó ko nhớ nữa :D chọn 1 dòng là as character. Rồi bấm Ctrl E để căn giữa như chữ bình thường.
Xuống dòng trong công thức:
newline "=" nhớ có dấu ngoặc kép. Căn chỉnh vị trí trong công thức thì dùng alignl arignr arignc.

Thursday, May 31, 2012

Friday, May 11, 2012


Đã chán ngán cái việc suốt ngày so sánh ngôn ngữ này, phần mềm kia, framework nọ, OS ấy. Tất cả để tìm ra cái tốt nhất, rồi sau đó là không làm gì tiếp =.=/

Just pick up one, and go with it!

Sunday, April 29, 2012

PHP experiences


- khi viết câu select từ DB, nên dùng tablename.field thay vì `fieldname`
TODO: check xem khác nhau những gì?

- Datepicker nên dùng cái này cho nhanh:
sau khi lấy giá trị từ $_POST thì dùng strtotime($val)  để chuyển từ YYYY-MM-DD sang timestamp

Saturday, March 24, 2012

[Linux] Cài server cho 1 máy tính không có màn hình

Thực sự là 1 trải nghiệm mới sẽ cố hoàn thành trong tuần này.
Nhiệm vụ là thiết lập 1 server lên 1 cái case máy tính cũ, không có màn hình.

Sẽ viết tổng kết khi xong.

Dụng cụ cần thiết:

1 cái null modem cable
1 em laptop hay máy tính khác có cổng serial để cắm cái dây trên.
1 case máy tính sẽ được cài server


Thursday, March 22, 2012

[Android] Con đường tìm kiếm... tên nhà mạng

đúng là cả 1 con đường... vì thật vất vả.

nếu 2 method API cung cấp mà lấy được tên nhà mạng thì không có gì để nói: đó là
Telephony...    getNetworkOperatorName() getSimOperatorName()

có nhiều trường hợp kết quả trả về sẽ không giống những gì bạn cần lấy - tên nhà mạng sim bạn đang dùng - dòng chữ hiện ở thanh status bar đã kéo xuống hay ngoài lock screen.

Mò từ android open source, 2 chỗ nói trên đều lấy tên nhà mạng từ chỗ khác, dùng các class không được public ra api... sẽ cố dùng reflect để mò ra nó sau.$java$$android@2.3.7_r1@com$android$systemui$statusbar$

Quá trình tìm hiểu phát hiện ra rằng code open source của android có nhiều phần khác biệt với code SDK đưa vào sản phẩm thật. Điển hình là phần lấy tên nhà mạng này @@

Wednesday, March 21, 2012

Thuốc - ăn uống

Vịt là thức ăn bổ dưỡng, trị được nhiều bệnh, nhưng không dùng cho người bị cảm cúm, người tiêu chảy nên dùng hạn chế.

trứng vịt vị ngọt, tính mát, có tác dụng tư âm, giáng hỏa, thanh nhiệt, hóa đàm; dùng chữa bệnh ho khan, ít đờm, ho do phế âm hư. Còn thịt vịt tính hàn, có tác dụng tư âm, dưỡng vị. Thịt vịt chữa các chứng bệnh tiểu tiện bất lợi, nhiệt bệnh, hư lao; bổ ngũ tạng và thủy đạo. 

Thursday, March 15, 2012

Automate Android Dev

Vài tip nhỏ

Auto1: adb connect siêu tốc (on Linux)
Một lệnh bạn thường xuyên phải sử dụng khi test trên máy thật qua AdbWireless

adb connect 192.168.1.x

dùng để adb vào 1 máy trong mạng.

C1: thêm vào ~/.bashrc dòng
alias 'adbc=adb connect'

C2: (tớ đang dùng :D ): viết 1 cái script nhỏ nội dung như sau:



adb connect $IP$1

đặt tên là adbc, chmod a+x adbc để nó chạy được. Copy file vào 1 thư mục nào đó (vd /usr/bin/) hoặc thêm thư mục hiện thời của bạn vào biến PATH (export $PATH=$PATH:dia_chi_hien_thoi)

giờ thì chỉ cần gõ adbc 7, bạn sẽ gửi lệnh adb connect :D

Vì bạn thường xuyên sử dụng log để test nên hãy thêm dòng này vào template của Eclipse:

Windows > Preferences > Java > Editor > Templates

tạo 1 template mới:
Log.d(TAG, "${enclosing_method}");

dòng này sẽ tự tạo 1 dòng log với tên của method mà bạn ghi nó. TAG là 1 constant nên được đặt trước, thường là tên package của chương trình.

Saturday, March 10, 2012

Một Mình

a songI like :D 

by Thanh Tùng
Gió nhớ gì ngẩn ngơ ngoài hiên
Mưa nhớ gì thì thầm ngoài hiên
Bao đêm tôi đã một mình nhớ em
Ðêm nay tôi lại một mình

[ Lyrics from: ]
Nhớ em vội vàng trong nắng trưa
Áo phơi trời đổ cơn mưa
Bâng khuâng khi con đang còn nhỏ
Tan ca bố có đón đưa

Nhớ em giọt mồ hôi tóc mai
Gió sương mòn cả hai vai
Ðôi chân chênh vênh con đường nhỏ
Nghiêng nghiêng bóng em gầy

Vắng em còn lại tôi với tôi
Lá khô mùa này lại rơi
Thương em mênh mông chân trời lạ
Bơ vơ chốn xa xôi

Vắng em đời còn ai với ai
Ngất ngây men rượu say
Ðêm đêm liêu xiêu con đường nhỏ
Cô đơn, cùng với tôi về.....

Wednesday, March 7, 2012

Android learning path

1. Sqlite3
2. ListView and Adapter
3. Content Provider
4. Testing
5. PhoneGap
6. Naming convention + better code / understand
7. Agile android.

Friday, March 2, 2012

[Android] Preferences

Preferences là 1 cách để lưu trữ các tùy chọn của người dùng trong chương trình, quyết định trạng thái của chươgn trình. Nó được chứa trong 1 file xml , mỗi chương trình đều có 1 file preferences mặc định với tên : tên_của_package_preferences

public static SharedPreferences getDefaultSharedPreferences(Context context) {
    return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
private static String getDefaultSharedPreferencesName(Context context) {
    return context.getPackageName() + "_preferences";
private static int getDefaultSharedPreferencesMode() {
    return Context.MODE_PRIVATE;

Thay vì phải truyền các extra qua intent để gửi các thông tin sang activity khác, bạn có thể lưu vào preferences rồi lấy ra lúc cần thiết, việc lưu vào preferences được thực hiện 1 cách "tức thì" nên bạn sẽ không bao giờ phải lo rằng lúc gọi để lấy thông tin từ preference ra thì nó chưa kịp lưu giá trị được gửi vào trước đó :D

Tốt nhất là nên dùng preferences mặc định (tránh những lỗi có thể xảy - gõ sai tên file chẳng hạn ) và tạo 1 class theo singleton pattern với các method set - get các giá trị cần lưu trữ để dễ dàng truy cập lúc cần.


Saturday, February 25, 2012

[Java] Access modifier

Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N

Common Lisp and Emacs

Tập tành đú đởn.

Cài clisp
Cài emacs
Cài slime
Config 1 tí, nhớ đừng dùng vim đã auto closed :))

tạo folder:
mkdir ~/.slime

ghi dòng sau vào file ~/.emacs

;;; Lisp (SLIME) interaction
(setq inferior-lisp-program "clisp")
(add-to-list 'load-path "~/.slime")
(require 'slime)
(global-font-lock-mode t)
(show-paren-mode 1)
(add-hook 'lisp-mode-hook '(lambda ()
      (local-set-key (kbd "RET") 'newline-and-indent))) 

Từ terminal gõ: emacs -nw
Meta-X slime

Chiến thôi :))

[Java] Assert and Exception

How to use?
Use assert /ə'sə:t/ as a comment, to TEST a comment
You should now use an assertion whenever you would have written a comment that asserts an invariant.
   if (i % 3 == 0) {
    } else if (i % 3 == 1) {
    } else {
        assert i % 3 == 2 : i;
assert for test/debugging, not error-checking
  • use exceptions when checking parameters passed to public or protected methods and constructors
  • use exceptions when interacting with the user or when you expect the client code to recover from an exceptional situation
  • use exceptions to address problems that might occur
  • use assertions when checking pre-conditions, post-conditions and invariants of private/internal code
  • use assertions to provide feedback to yourself or your developer team
  • use assertions when checking for things that are very unlikely to happen otherwise it means that there is a serious flaw in your application
  • use assertions to state things that you (supposedly) know to be true
In other words, exceptions address the robustness of your application while assertions address its correctness.
Assertions are designed to be cheap to write, you can use them almost everywhere and I'm using this rule of thumb: the more an assertion statement looks stupid, the more valuable it is and the more information it embeds. When debugging a program that does not behave the right way, you will surely check the more obvious failure possibilities based on your experience. Then you will check for problems that just cannot happen: this is exactly when assertions help a lot and save time.

Friday, February 24, 2012

[Java] Static method

As defined, power is stateless and has no side effects on any enclosing class so it should be declared static.

Friday, February 10, 2012

[Android] Tổng kết kinh nghiệm làm việc với các loại View

1. Bạn muốn tạo OptionsMenu có khả năng thay đổi?
SOLUTION: sử dụng onPrepareOptionsMenu(Menu menu) thay vì onCreateOptionsMenu

2. Khi nào thì cần extend một View?
SOLUTION: có lẽ bạn chỉ cần 1 loại View mới khi hình ảnh của bạn thường xuyên thay đổi hoặc thật là quái dị :)) khác biệt với các View mà android đã cung cấp. Với những thao tác với 1 View bạn muốn làm như: di chuyển, thay đổi kích cỡ, độ trong suốt thì bạn vẫn chưa cần phải extend 1 View. 

Friday, February 3, 2012

onStart, onCreate.... trình tự chạy của các lệnh

Biết mỗi activity đều implement các method như onCreate, onStart... nhưng có chắc bạn nắm chính xác trình tự chạy của chúng. Hãy làm 1 bài test nhỏ như sau để kiểm nghiệm:

Tạo 1 activity chính, 1 activity 2. Ta implement các method

và đặt log ở tất cả các method này trong cả 2 activity.

Chạy chương trình , bấm nút chuyển từ Activity chính sang Activity 2. Kết quả thu được như sau:

D/AndroidRuntime(  468): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
D/AndroidRuntime(  468): CheckJNI is ON
D/AndroidRuntime(  468): --- registering native functions ---
I/ActivityManager(   59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.aps.test/.OrderTestActivity }
D/AndroidRuntime(  468): Shutting down VM
D/dalvikvm(  468): Debugger has detached; object registry had 1 entries
I/AndroidRuntime(  468): NOTE: attach of thread 'Binder Thread #3' failed
D/dalvikvm(  436): GC_EXPLICIT freed 1421 objects / 94480 bytes in 1668ms
D/ACT1    (  436): onCreate
D/ACT1    (  436): onStart
D/ACT1    (  436): onResume

I/ActivityManager(   59): Displayed activity com.aps.test/.OrderTestActivity: 523 ms (total 523 ms)
I/ActivityManager(   59): Starting activity: Intent { cmp=com.aps.test/.Act2 }
D/ACT1    (  436): onPause
D/ACT2    (  436): onStart
D/ACT2    (  436): onResume

I/ActivityManager(   59): Displayed activity com.aps.test/.Act2: 391 ms (total 391 ms)
D/ACT1    (  436): onStop
W/KeyCharacterMap(  436): No keyboard for id 0
W/KeyCharacterMap(  436): Using default keymap: /system/usr/keychars/qwerty.kcm.bin

D/ACT2    (  436): onPause
D/ACT1    (  436): onRestart
D/ACT1    (  436): onStart
D/ACT1    (  436): onResume
D/ACT2    (  436): onStop
D/ACT2    (  436): onDestroy 

D/ACT1    (  436): onPause
D/ACT1    (  436): onStop
D/ACT1    (  436): onDestroy

Thật quá rõ ràng ^^
PS: để lấy log ra file text trên linux: adb logcat -d > log


Android SharedPreferences

Q: mỗi package có 1 defaultSharedPreferences?

A: Sai!
Cả 1 App chỉ có 1 defaultSharedPreferences.

Theo bài này:

Thì mỗi ứng dụng có 1 defaultSharedPreferences với tên là tên của package ứng dụng + _preferences
(Chú ý: getPackageName() trả về tên của package của App - là package được khai báo trong file Manifest chứ không phải các package con)

public static SharedPreferences getDefaultSharedPreferences(Context context) {
    return context.getSharedPreferences( 
private static String getDefaultSharedPreferencesName(Context context) {
    return context.getPackageName() + "_preferences";
private static int getDefaultSharedPreferencesMode() {
    return Context.MODE_PRIVATE;

Tuesday, January 31, 2012

Eclipse tips

1. Switch between "tabs"
Want to change to next tab?
Using Ctrl E or Ctrl Shift E is so ugly.
Use Ctrl Shift Tab, then use navigator left or right. When done, press Tab.

2. Switch Perspective
Ctrl F7

Wednesday, January 11, 2012

[Android] Tổng kết kinh nghiệm làm việc với service và activity

1. Một service có thể vẽ hình, đặt nó trên tất cả các View khác  và nhận event khi user touch vào màn hình nhờ thiết lập qua WindowManager.LayoutParams. Event service nhận được duy nhất là MotionEvent.ACTION_OUTSIDE.

2. Tọa độ khi bắt event bằng service bắt đầu từ (0,0) tại vị trí góc trên trái, dưới StatusBar. Trong StatusBar thì tọa độ y của nó là âm (từ -25 đến 0). Tọa độ bắt bằng View trong Activity bắt đầu từ (0,25) cũng tại điểm góc trên trái dưới StatusBar vừa nói. Bởi thế phải cộng thêm 25 vào tọa độ lấy được từ service nếu muốn sử dụng nó cho Activity.

3. Khi 1 activity không được active nữa (mở 1 activity khác từ nó), hệ thống gọi method onStop() trên nó. Hàm này khác với onDestroy (thoát bằng back...)

4. Nếu service của bạn có "nguy cơ" sẽ tương tác với Activity, tốt nhất là nên implement các method onBind, onUnbind. Chú ý nếu implement onBind mà ko implement onUnbind có thể dẫn đến lỗi "leaks service hay binder j đó"

5. Nếu cần update UI, nhớ dùng view.invalidate()

6. method bindService()  không phải là hàm cho kết quả "ngay lập tức" nên nếu dùng instance của service trả về qua binder để gọi method của service sẽ bị lỗi service đó là null.
Khắc phục: không gọi API của service ngay lập tức (vd 2 dòng này cùng nằm trong onCreate() chẳng hạn). Có thể gọi API trong onConnected, hay bindService trong onCreate()/onStart() và gọi API trong 1 listener nào đó.

Tuesday, January 10, 2012

Android: avoiding memory leaks

In summary, to avoid context-related memory leaks, remember the following:
  • Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
  • Try using the context-application instead of a context-activity
  • Avoid non-static inner classes in an activity if you don't control their life cycle, use a static inner class and make a weak reference to the activity inside. The solution to this issue is to use a static inner class with a WeakReference to the outer class, as done in ViewRoot and its W inner class for instance
  • A garbage collector is not an insurance against memory leaks

Friday, January 6, 2012

Android: Frequent mistakes/bugs

(Use Eclipse)
1. When you setOnClickListener on a button, Eclipse requests you change it to other method...
SOLUTION: import android.view.View.OnClickListener;

2. When you write only a service. Installed it into VD and you don't see its start icon. Although you can see that service in "Setting> App Manager> Running Service"
SOLUTION: Create an activity.

3. You edited some file but Eclipse keeps warning you have errors.  
SOLUTION: clean you project : Menu >Project >Clean

4. Some activities or services not run?
SOLUTION: Add them to AndroidManifest

5. You logged something but don't see them?
SOLUTION: Choose device which using by logcat.

6.You use Toast  but it not show on your screen
SOLUTION: did you forget .show() method?

7. Eclipse: Can't bind to local 8600 for debugger.
SOLUTION: In addition to adding " localhost" to your hosts file, make the following changes in Eclipse.
Under Window -> Preferences -> Android -> DDMS:
  • Set Base local debugger port to "8601"
  • Check the box that says "Use ADBHOST" and the value should be ""
Then, call adb kill-server followed by adb start-server  
After done, if it still not work. Restart your computer

8. Bug when you want to change your UI
SOLUTION: Use  View.invalidate();

9.Error : NoSuchFieldError R$id...
SOLUTION: change that xml layout

10. Connect adb with you device  on Linux. Enter adb devices and get "Unknow device"
SOLUTION: sudo adb kill-server, sudo adb start-server, sudo adb service

11. Eclipse stops responding when changing to DDMS perspective

SOLUTION: The problem was that AVD hanged somewhere at 27% and then I couldn't do really anything with Eclipse. The problem is somewhere in the AVD and re-installing the AVD didn't help me.
Instead this seems to work every time:
  • Start virtual device from Eclipse's Window -> AVD menu
  • Then right click the project and "Debug as -> Android Application"
Here you never need to close the virtual device and it's also a lot faster to use it this way.

12. You are working with dialog and some view inside it not work

SOLUTION: make sure that you are work with approriate views. Maybe some findViewById() should be yourDialog.findViewById();

13. JUnit test
Logcat: Test run failed: Test run incomplete. Expected 1 tests, received 0

SOLUTION: you were using the wrong constructor. Eclipse auto generate the code and it created this:

public LoginTest(String pkg, Class<Login> activityClass) {
    super(pkg, Login.class);

change it to this:

public LoginTest() {
    super("pkg_name", Login.class);

note that all your test function must be start with test and its modifier is public
public void testPreconditions() {

14. Eclipse hangs on loading workbench (after .adt...)
remove .snap file from <<workspace_dir>>/.metadata/.plugins/org.eclipse.core.resources/ 
then run eclipse -clean

15. Create hotkey for commit current file with Subclipse
In order to get the shortcuts to work, you must go to Window > Customize Perspective, then under the Command Groups Availability tab, check the SVN option. It may require a restart of Eclipse, but the Subclipse keyboard shortcuts will now work.

Then create a key binding for 'Commit'
(under Preferences... General->Keys, search for Commit). Then you just need to click on the row SVN  and hit a key combination => Ok

16. Error on gen folder
check your res files, all filename must start with alphabet, not number.

17. Can't install your app on real device but emulator
Check your manifest, is there any duplicate activity?

Thursday, January 5, 2012

Open source android app

Android with Proguard

Proguard shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names.

To use Proguard, you should use SDK 2.3.3 (API 10). If you wrote your project in API < 10, you should upgrade it:
android update project --name MyApp --target 2 --path ./MyAppProject

to get the target,run command:
android list targets
Then config your project to use Proguard:

For more android command:

If you use Eclipse, choose File>Export to release your project in .apk file.
You should see proguard directory in your project directory after exported.

NOTE: you should keep mapping.txt file each time you release. It helps debug your app later.

Don't not mean can't

When someone say don't or impossible, it doesn't mean you CAN'T

Android tips, exp

By me, for me  :))
1. Remove all Log to speed up your App when release.
 Xóa tối đa số Log bạn tạo ra khi viết trước khi release để tăng tốc.
2. Try to use Log instead of print (if you come from C, Java).
Tập sử dụng Log thay vì print ra các kết quả để check xem bạn viết đúng hay không. Log rất tiện lợi.

3. Đọc error log TỪ TRÊN XUỐNG. Sau đó mới xem caused by...