Wednesday, November 25, 2009

Tips for Reading Source Code

Reading time is longer than the writing time and most programmers will lose focus along the way (some even fall asleep) especially if they are reading monstrous legacy code. There are several reasons why, in no particular order,


1. Procrastination
Programmer: [Wandering mind… Facebook… Twitter…] “Oh man, I have a brilliant idea, I’m going to read more on that… I’ll set aside this crap first and try to come up something innovative.”


2. Impatient
Programmer: “I hate this crap, ugly legacy code, it sucks! Can I just have the documents and rewrite everything from scratch?”
Project Manager: “Unfortunately, the source code is the only document we have.”


3. Interruptions
Team mate: “Hey! Can I have 5 seconds from you? I’m getting a NullPointerException, this is weird, I had everything initialized!”
Programmer: “Are you sure? Hold on, let me check that, you might have some methods returning null.”


4. Discontented -
Programmer: “What is this elementary code? This isn’t challenging, I want more challenge!”


etc.


You need to know what your goals are before reading the code. Start by asking these questions to your self and if you find out that you are losing focus along the way, just ask these questions again, it will help you get back on track.


1. Am I going to fix a bug?
2. Is this code implementing an API?
3. Am I going to add a new feature?
4. Am I just being curious to know the logic behind the code and nothing special?


Often times, you will be able to grasp the logic behind the code by running the program first. Consider the diagram below.


INPUT -> PROCESS -> OUTPUT


Being able to understand the INPUT and the OUTPUT, the PROCESS part will follow easily.

Saturday, November 14, 2009

Installing Go in Ubuntu Jaunty

Processor: x86
Operating System: Ubuntu Linux 9.04 Jaunty Jackalope


1. CONFIGURE THE ENVIRONMENT
Set the necessary variables in your .bashrc that is if you are using bash. Assuming you have a 386-descendant processor and you want to keep the installation clean in an external disk (/media/disk).



# Google Go Programming Language Settings
export GOROOT=/media/disk/go
export GOARCH=386
export GOOS=linux
export GOBIN=/media/disk/go/bin

2. INSTALL MERCURIAL.
Easy.



$ sudo easy_install mercurial

Install process,



Searching for mercurial
Reading http://pypi.python.org/simple/mercurial/
Reading http://www.selenic.com/mercurial
Best match: mercurial 1.3.1
Downloading http://mercurial.selenic.com/release/mercurial-1.3.1.tar.gz
Processing mercurial-1.3.1.tar.gz
Running mercurial-1.3.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-a3YaRd/mercurial-1.3.1/egg-dist-tmp-VyNqd2
zip_safe flag not set; analyzing archive contents...
mercurial.lsprof: module references __file__
mercurial.templater: module references __file__
mercurial.extensions: module references __file__
mercurial.i18n: module references __file__
Adding mercurial 1.3.1 to easy-install.pth file
Installing hg script to /usr/local/bin

Installed /usr/local/lib/python2.6/dist-packages/mercurial-1.3.1-py2.6-linux-i686.egg
Processing dependencies for mercurial
Finished processing dependencies for mercurial


3. CHECKOUT GO USING MERCURIAL



$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

Checkout process,



requesting all changes
adding changesets
adding manifests
adding file changes
added 4016 changesets with 16888 changes to 2931 files
updating working directory
1640 files updated, 0 files merged, 0 files removed, 0 files unresolved

4. BUILD GO



$ cd $GOROOT/src
$ ./all.bash

Build process,



--- cd pkg/exp/ogle
rm -rf *.[568vqo] *.a [568vq].out *.cgo[12].go *.cgo[34].c *.so _obj _test _testmain.go ogle
8g -o _go_.8 abort.go arch.go cmd.go event.go frame.go goroutine.go rruntime.go rtype.go rvalue.go process.go vars.go
rm -f _obj/exp/ogle.a
gopack grc _obj/exp/ogle.a _go_.8
8g -I_obj main.go
8l -L_obj -o ogle main.8

real 0m2.264s
user 0m1.496s
sys 0m0.136s

--- cd ../doc/progs

real 0m4.430s
user 0m3.144s
sys 0m0.444s

--- cd ../test/bench
fasta
reverse-complement
nbody
binary-tree
binary-tree-freelist
fannkuch
regex-dna
spectral-norm
k-nucleotide
mandelbrot
meteor-contest
pidigits
threadring
chameneosredux

It should end with the following lines,



--- cd ../test
0 known bugs; 0 unexpected bugs

5. ENJOY!

Thursday, November 12, 2009

Are you treating your computer better than yourself?

Yes, I am guilty. Most of us are not aware that we are treating our computers better than ourselves. We often juggle tasks like a computer processor. It has been proven by experts recently that multitasking drops IQ. The Dumb Little Man has some cool tips for us.


Read the article, Are You Treating Your Computer Better Than You Treat Yourself?

Wednesday, November 11, 2009

The Go Programming Language

Good day! Try out [The Go Programming Language].


As quoted from its home page,


Go is …


… simple



package main

import "fmt"

func main() {
fmt.Printf("Hello, 世界\n")
}

… fast
Go compilers produce fast code fast. Typical builds take a fraction of a second yet the resulting programs run nearly as quickly as comparable C or C++ code.


… safe
Go is type safe and memory safe. Go has pointers but no pointer arithmetic. For random access, use slices, which know their limits.


… concurrent
Go promotes writing systems and servers as sets of lightweight communicating processes, called goroutines, with strong support from the language. Run thousands of goroutines if you want—and say good-bye to stack overflows.


… fun
Go has fast builds, clean syntax, garbage collection, methods for any type, and run-time reflection. It feels like a dynamic language but has the speed and safety of a static language. It’s a joy to use.


… open source


Install Go! Click [here].



I have relocated back to Blogsome

For some reasons, sorry for the confusion. Here is my blog - [Digital Stronghold]

I have relocated to WordPress

Here is my new blog site - [Digital Stronghold].

Monday, November 09, 2009

POSIX cksum algorithm in Java

Most Unix programs rely on cksum for checking duplicate files. If you happen to migrate programs doing that, you need to make sure that you’ll be using the same algorithm for the same functionality of course.


Here is the [cksum algorithm] and here is the [cksum man] page.


The class below is implementing the java.util.zip.Checksum interface for extensibility.



/**
* Compute the checksum of a data stream using the
* POSIX cksum algorithm.
*/
public class Cksum implements Checksum {

/**
* The checksum value.
*/
private int value;

/**
* The length of the stream.
*/
private int length;

/**
* The cksum payload.
*/
private final int[] payload = {
0x00000000,
0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80,
0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A,
0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629,
0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C,
0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E,
0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65,
0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8,
0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2,
0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74,
0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21,
0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A,
0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087,
0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D,
0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE,
0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB,
0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09,
0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF,
0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
};

/**
* Checksum constructor, reset checksum.
*/
public Cksum() {
super();
reset();
}

/**
* Reset the checksum.
*/
public final void reset() {
value = 0;
length = 0;
}

/**
* Update checksum value using a byte.
*
* @param byteRead is the byte read to include in the computation.
*/
public void update(final byte byteRead) {
value = (value << 8 ) ^ payload[ ((value >> 24) ^ byteRead) & 0xFF];
length++;
}

/**
* Update checksum value using an int.
*
* @param byteRead is the byte read in int form to include in the computation.
*/
public void update(final int byteRead) {
update((byte)(byteRead & 0xFF));
}

/**
* Get the cksum checksum value.
* a 2.5 GB file (length=2684354560), filled with random
* bytes (Java seed=0), returns a cksum value of 128656372
*
* @return the cksum value.
*/
public final long getValue() {

// store both length and value to temps,
// so we can launch getValue() multiple times
long tmpLength = length;
int tmpValue = value;

// include the length of the file to the checksum value
for (; tmpLength != 0; tmpLength >> = 8 ) {
tmpValue = (tmpValue << 8 ) ^ payload[((tmpValue >> 24) ^ (int)(tmpLength & 0xFF)) & 0xFF];
}

return (~tmpValue & 0xFFFFFFFFL);
}

/**
* Get the size of the stream.
*
* @return the size of the stream in bytes.
*/
public final long getLength() {
return length;
}

/**
* Get the value in byte array form.
*
* @return the checksum value in byte array form.
*/
public final byte[] getByteArray() {
final long localValue = getValue();
return new byte[]
{(byte)((localValue >> 24)&0xff),
(byte)((localValue >> 16)&0xff),
(byte)((localValue >> 8 )&0xff),
(byte)(localValue&0xff)};
}

/**
* Method to work with java.util.zip.Checksum calls.
*/
@Override
public void update(final byte[] b, final int off, final int len) {
for (int i = off; i < len + off; i++) {
update(b[i]);
}
}
}

Sunday, November 08, 2009

HTTP reader in Java

While there are numerous ways of accessing web services, here is a primitive way of doing it. This is a simple class for reading HTTP responses. You can take advantage of this, classic examples are,


1. Reading twitter feeds for executing commands in a target machine
2. Getting the latest articles in a particular website
3. Translating through Google Translate
4. Arithmetic operations through Google
5. Currency conversion through Google


and more!


Here is the class.



/**
* Hyper-Text Transfer Protocol Reader.
*
* @author joset
*/
public final class HttpReader {

private Map<String, List<String>> responseHeader;
private URL responseUrl;
private String mimeType;
private String charset;
private Object content;
private int responseCode = -1;

/**
* Constructor requiring the URL string.
*/
public HttpReader(final String urlString)
throws MalformedURLException, IOException {
// open a connection.
final URL url = new URL(urlString);
final URLConnection urlConnection = url.openConnection();
if (!(urlConnection instanceof HttpURLConnection)) {
throw new IllegalArgumentException(
"URL protocol must be HTTP.");
}
final HttpURLConnection connection =
(HttpURLConnection) urlConnection;

// set up a request.
connection.setConnectTimeout(10000); // 10 sec
connection.setReadTimeout(10000); // 10 sec
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("user-agent", "spider");

// send the request.
connection.connect();

// get the response.
responseHeader = connection.getHeaderFields();
responseCode = connection.getResponseCode();
responseUrl = connection.getURL();
final int length = connection.getContentLength();
final String type = connection.getContentType();
if (type != null) {
final String[] parts = type.split(";");
mimeType = parts[0].trim();
for (int i = 1; i < parts.length && charset == null; i++) {
final String t = parts[i].trim();
final int index = t.toLowerCase().indexOf("charset=");
if (index != -1) {
charset = t.substring(index + 8 );
}
}
}

// get the content.
final InputStream stream = connection.getErrorStream();
if (stream != null) {
content = readStream(length, stream);
} else if ((content = connection.getContent()) != null &&
content instanceof InputStream) {
content = readStream(length, (InputStream) content);
}

// close connection.
connection.disconnect();
}

/**
* Read stream bytes and transcode.
*/
private Object readStream(final int length, final InputStream stream)
throws IOException {
final int buflen = Math.max(1024, Math.max(length, stream.available()));
byte[] buf = new byte[buflen];
byte[] bytes = null;

for (int nRead = stream.read(buf); nRead != -1; nRead = stream.read(buf)) {
if (bytes == null) {
bytes = buf;
buf = new byte[buflen];
continue;
}
final byte[] newBytes = new byte[bytes.length + nRead];
System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
System.arraycopy(buf, 0, newBytes, bytes.length, nRead);
bytes = newBytes;
}

if (charset == null) {
return bytes;
}
try {
return new String(bytes, charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return bytes;
}

/**
* Get the content.
*/
public Object getContent() {
return content;
}

/**
* Get the response code.
*/
public int getResponseCode() {
return responseCode;
}

/**
* Get the response header.
*/
public Map<String, List<String>> getHeaderFields() {
return responseHeader;
}

/**
* Get the URL of the received page.
*/
public URL getUrl() {
return responseUrl;
}

/**
* Get the MIME type.
*/
public String getMimeType() {
return mimeType;
}
}

Enjoy!



The young do not know enough to be prudent, and therefore they attempt the impossible — and achieve it, generation after generation. - Pearl S. Buck

Thursday, November 05, 2009

Delete files and directories recursively in Java

This post will teach you how to delete files and directories in Java recursively. There is nothing special in this post but I’m sure this will be useful especially for those who are just starting out their programming career in Java.



boolean deleteRecursively(final File file) {
if (file.exists()) {
final File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteRecursively(files[i]);
}
else {
files[i].delete();
}
}
}
return (file.delete());
}

This code was not tested. Please read the Java 6 File API documentation [here] for more information.


"Confidence means non-paralysis, a willingness to act, and act decisively, to start new things and cut failing ventures off." - Tom Peters