Showing posts with label General Knowledge. Show all posts
Showing posts with label General Knowledge. Show all posts

Sunday, October 25, 2009

What happens when you type in a URL into the browser ...

These are the processes taken place.
[Immense credits to EXPRESS HOST PRO for the detailed explanation]
Step 1: Request a record
You begin by asking your computer to resolve a hostname, such as visiting 'http://www.google.com' in a web browser. The first place your computer looks is its local DNS cache, which stores DNS information that the computer has recently retrieved.

Step 2: Ask the Recursive DNS servers
If the records are not stored locally, your computer queries (or contacts) your ISP's recursive DNS servers. These machines perform the legwork of DNS queries on behalf of their customers. The recursive DNS servers have their own caches, which they check before continuing with the query.

Step 3: Ask the Root DNS servers
If the recursive DNS servers do not have the record cached, they contact the root nameservers. These thirteen nameservers contain pointers for all of the Top-Level Domains (TLDs), such as '.com', '.net' and '.org'. If you are looking for 'www.google.com.', the root nameservers look at the TLD for the domain - 'www.google.com'- and direct the query to the TLD DNS nameservers responsible for all '.com' pointers.

Step 4: Ask the TLD DNS servers
The TLD DNS servers do not store the DNS records for individual domains; instead, they keep track of the authoritative nameservers for all the domains within their TLD. The TLD DNS servers look at the next part of the query from right to left - 'www.google.com' - then direct the query to the authoritative nameservers for 'google.com'.

Step 5: Ask the Authoritative DNS servers
Authoritative nameservers contain all of the DNS records for a given domain, such as host records (which store IP addresses), MX records (which identify nameservers for a domain), and so on. Since you are looking for the IP address of 'www.google.com', the recursive server queries the authoritative nameservers and asks for the host record for 'www.google.com'.

Step 6: Retrieving the record
The recursive DNS server receives the host record for 'www.google.com' from the authoritative nameservers, and stores the record in its local cache. If anyone else requests the host record for 'www.google.com', the recursive servers will already have the answer, and will not need to go through the lookup process again until the record expires from cache.

Step 7: The Answer!
Finally, the recursive server gives the host record back to your computer. Your computer stores the record in its cache, reads the IP address from the record, then passes this information to the web browser. Your browser then opens a connection to the IP address '72.14.207.99' on port 80 (for HTTP), and our webserver passes the web page to your browser, which displays Google.

You may visit the original content at this URL.

Here's my understanding to the processes:

We type in a URL and hit GO.
The browser translates the URL into an IP address.
In order to do that, the browser contacts DNS to resolve the IP address.
The browser checks if the IP address is cached.
If not, it makes a DNS query to my ISP's DNS server.
DNS replies back with the IP address of the site.
Browser opens TCP connection to the server at port 80.
Displays the content in browser.
Stores the IP address in the DNS cache for future use.
When the browser is closed, TCP connection is terminated.

The HTTP request being made is a GET request.
Correct me if I'm wrong.

Wednesday, October 21, 2009

Traversing Folder and Files

Here is an updated code to inform you if the file or folder specified does not exists. You may take a look at the original code at this article.


public void traverseFilesFolders () {
if (referencedFile.exists()) {
traverseFilesFolders(referencedFile);
} else {
System.out.println("File or Folder does not exist");
}
}

Final vs Finally vs Finalize

A short note for myself:

Final: used for defining a class non-subclassable, and making a member variable as a
constant which cannot be modified, and declare a method non-overridable.

Finally: to provide the capability to execute code no matter whether or
not an exception is thrown or caught in the try-catch exception handler.

Finalize: helps in garbage collection to clean up objects that are no longer required. Usualy Java will do the garbage collection automatically.

Monday, October 19, 2009

Java Reflection

The Reflection API allows the user to get the complete, but not limited to, information about classes, constructors, interfaces and methods that are being used. There are many things we can achieve with this API and the methods are:
getInterfaces()
getName()
getClass()
getSuperclass()
getMethods()
getFields()
getConstructors()

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionTool {

private static final String padding = "\t";

public void retrieveInterfaces(){
System.out.println("Retrieve Interface(s):");
for (Class anInterface: java.util.Date.class.getInterfaces()) {
System.out.println(padding + anInterface);
}
}

public void retrieveName(){
System.out.println("Retrieve Name of Class:");
System.out.println(padding + java.util.concurrent.atomic.AtomicInteger.class.getName());
}

public void retrieveClass(){
System.out.println("Retrieve Runtime Class:");
System.out.println(padding + java.util.zip.CRC32.class.getClass());
}

public void retrieveSuperClass(){
System.out.println("Retrieve Superclass:");
System.out.println(padding + java.util.zip.CRC32.class.getClass().getSuperclass());
}

public void retrieveMethods(){
System.out.println("Retrieve Methods:");
for (Method aMethod: java.util.List.class.getMethods()) {
System.out.println(padding + aMethod);
}
}

public void retrieveFields(){
System.out.println("Retrieve Fields:");
for (Field aField: java.lang.Double.class.getFields()) {
System.out.println(padding + aField);
}
}

public void retrieveConstructors(){
System.out.println("Retrieve Constructors:");
for (Constructor aConstructor: java.lang.Double.class.getConstructors()) {
System.out.println(padding + aConstructor);
}
}

public static void main(String[] args) {
ReflectionTool rt = new ReflectionTool();
rt.retrieveInterfaces();
rt.retrieveName();
rt.retrieveClass();
rt.retrieveSuperClass();
rt.retrieveMethods();
rt.retrieveFields();
rt.retrieveConstructors();
}
}

The output of the code is as follow. Nothing fancy, nothing complicated. Everything is straightforward.

Retrieve Interface(s):
interface java.io.Serializable
interface java.lang.Cloneable
interface java.lang.Comparable
Retrieve Name of Class:
java.util.concurrent.atomic.AtomicInteger
Retrieve Runtime Class:
class java.lang.Class
Retrieve Superclass:
class java.lang.Object
Retrieve Methods:
public abstract int java.util.List.hashCode()
public abstract boolean java.util.List.equals(java.lang.Object)
public abstract java.lang.Object java.util.List.get(int)
public abstract boolean java.util.List.add(java.lang.Object)
public abstract void java.util.List.add(int,java.lang.Object)
public abstract int java.util.List.indexOf(java.lang.Object)
public abstract void java.util.List.clear()
public abstract int java.util.List.lastIndexOf(java.lang.Object)
public abstract boolean java.util.List.contains(java.lang.Object)
public abstract boolean java.util.List.addAll(java.util.Collection)
public abstract boolean java.util.List.addAll(int,java.util.Collection)
public abstract int java.util.List.size()
public abstract java.lang.Object[] java.util.List.toArray()
public abstract java.lang.Object[] java.util.List.toArray(java.lang.Object[])
public abstract java.util.Iterator java.util.List.iterator()
public abstract java.lang.Object java.util.List.set(int,java.lang.Object)
public abstract boolean java.util.List.remove(java.lang.Object)
public abstract java.lang.Object java.util.List.remove(int)
public abstract boolean java.util.List.isEmpty()
public abstract boolean java.util.List.containsAll(java.util.Collection)
public abstract boolean java.util.List.removeAll(java.util.Collection)
public abstract boolean java.util.List.retainAll(java.util.Collection)
public abstract java.util.List java.util.List.subList(int,int)
public abstract java.util.ListIterator java.util.List.listIterator()
public abstract java.util.ListIterator java.util.List.listIterator(int)
Retrieve Fields:
public static final double java.lang.Double.POSITIVE_INFINITY
public static final double java.lang.Double.NEGATIVE_INFINITY
public static final double java.lang.Double.NaN
public static final double java.lang.Double.MAX_VALUE
public static final double java.lang.Double.MIN_VALUE
public static final int java.lang.Double.SIZE
public static final java.lang.Class java.lang.Double.TYPE
Retrieve Constructors:
public java.lang.Double(double)
public java.lang.Double(java.lang.String) throws java.lang.NumberFormatException


Friday, October 16, 2009

Traversing Folders and Files Recursively

Both files and folders are represented as File object in the java.io package. We are recognizing if an object is a file by using the method "isFile()" and a folder with the method "isDirectory()".

import java.io.File;

public class FilesFoldersTraversal {

private final char SEPARATOR = File.separatorChar;
private File originalFile;
private File referencedFile;
private String pad = null;
private String absolutePathOriginalFile = null;

public FilesFoldersTraversal(String inputFileString) {
File inputFile = new File(inputFileString);
originalFile = inputFile;
referencedFile = inputFile;
absolutePathOriginalFile = originalFile.getAbsolutePath();
}

public void traverseFilesFolders () {
traverseFilesFolders(referencedFile);
}

private void traverseFilesFolders(File referencedFile){
if (referencedFile.isDirectory()){
pad = getPadding(referencedFile);
processFolders(referencedFile);
}
else if (referencedFile.isFile()){
processFiles(referencedFile);
}
}

private void processFolders(File referencedFile){
System.out.println(pad + "Folder: " + referencedFile.getName());
File listFiles[] = referencedFile.listFiles();
for(File singleFile : listFiles){
traverseFilesFolders(singleFile);
}
}

private void processFiles(File referencedFile){
System.out.println(pad + " " + "File: " + referencedFile.getName());
}

private String getPadding(File referencedFile){
String padding = "";
String fileAbsolutePath = referencedFile.getAbsolutePath();
String filePathSubString = fileAbsolutePath.substring(absolutePathOriginalFile.length(), fileAbsolutePath.length());

int index = 0;
int subStringLength = filePathSubString.length();
while (index < subStringLength) {
if (filePathSubString.charAt(index) == SEPARATOR){
padding += " ";
}
index++;
}

return padding;
}

public static void main(String[] args) {
FilesFoldersTraversal fft = new FilesFoldersTraversal("/Users/YOUR_USER_NAME/Documents");
fft.traverseFilesFolders();
}

}
There are many interesting things you can do with the example shown. You may add a few lines of codes to compile a list of files of a specific file extension, for example ".txt" or ".class".

Monday, October 5, 2009

Detailed explanation of using XSL to scrape ISO country codes

I apologize if you couldn't understand how I managed to scrape the country codes from the ISO website as mentioned in my previous article. Here are the detailed steps to scrape the codes accordingly. You'll need 3 things to achieve the goal: manual editing (I know it's primitive otherwise you are more than welcomed to write your HTML tag stripper to recognize the elements in the web page), XML file and XSL file.

[1] Copy the table element:
- Copy the entire table element that contains the country names and codes

[2] Editing the XML file:
- Open an empty file
- Save it as "countries.xml"
- Add this line at the top of the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="countries.xsl"?>
- Paste the table element you copied earlier
- Remove the table row that contains "Country names" and "ISO 3166-1-alpha-2 code"
- The screenshot is as below:[3] Editing the XSL file:
- Copy the XPath codes I demonstrated in this article
- Save it as "countries.xsl"

[4] You are all set!
- Here is the sample output translating the XML using XPath

Sunday, September 13, 2009

Binary Tree and its popular methods

This is something convenient I think to do a brief revision on Binary Tree other than reading about it on Wikipedia. This implementation demonstrates the construction of binary tree with some elements and the typical methods related to it such as:
[1] Pre-Order Traversal
[2] In-Order Traversal
[3] Post-Order Traversal
[4] Getting the size of the binary tree
[5] Get the minimum value
[6] Get the maximum value
[7] Get root value
[8] Inserting new elements

My implementation does not include duplication of elements. You may copy the code and test it yourself.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class BinaryTree {

private static class TreeNode {
TreeNode left;
TreeNode right;
int nodeValue;
TreeNode(int data) {
left = null;
right = null;
nodeValue = data;
}
}

private TreeNode root;

public BinaryTree() {
root = null;
}

public void constructBinaryTreeHardCoded() {
root = null;

root = new TreeNode(6);
//root = insertData(root, 6);

root = insertData(root, 2);
root = insertData(root, 7);
root = insertData(root, 1);
root = insertData(root, 4);
root = insertData(root, 9);
root = insertData(root, 3);
root = insertData(root, 5);
root = insertData(root, 8);
}

public void testHarness(){
root = null;

Random rand = new Random();
int rootValue = rand.nextInt( 20 ) + 1;
root = new TreeNode(rootValue);
System.out.println("Random seeded root value: " + rootValue);
int numberOfNodes = rand.nextInt( 18 ) + 1;
System.out.println("Random number of children to be generated: " + numberOfNodes);
for (int i = 0; i < numberOfNodes; i++) {
int randValue = rand.nextInt( 30 ) + 1;
System.out.println("Inserting: " + randValue);
root = insertData(root, randValue);
}
}

public TreeNode insertData(TreeNode node, int data) {
if (node == null) {
node = new TreeNode(data);
} else {
if (data < node.nodeValue) {
if (node.left != null) {
node.left = insertData(node.left, data);
} else {
node.left = new TreeNode(data);
System.out.println("Inserted " + data + " to the left of " + node.nodeValue);
}
} else if (data > node.nodeValue) {
if (node.right != null) {
node.right = insertData(node.right, data);
} else {
node.right = new TreeNode(data);
System.out.println("Inserted " + data + " to the right of " + node.nodeValue);
}
} else {
System.out.println("Not inserting " + data + " because it already exists in the tree");
}
}
return(node);
}

public boolean isIdenticalTree(BinaryTree comparedTree) {
return (isIdenticalTree(root, comparedTree.root));
}

private boolean isIdenticalTree(TreeNode first, TreeNode second) {
if (first == null && second == null) {
return true;
} else if (first != null && second != null) {
return (
first.nodeValue == second.nodeValue &&
isIdenticalTree(first.left, second.left) &&
isIdenticalTree(first.right, second.right)
);
} else {
return false;
}
}

public int getSize() {
return(setSize(root));
}

private int setSize(TreeNode node) {
if (node == null) {
return 0;
} else {
return(setSize(node.left) + 1 + setSize(node.right));
}
}

public void printTreeTraversal() {
System.out.print("Inorder Traversal: ");
printInOrder(root);
System.out.print("\nPreorder Traversal: ");
printPreOrder(root);
System.out.print("\nPostorder Traversal: ");
printPostOrder(root);
System.out.println();
}


private void printInOrder(TreeNode node) {
if (node == null) {
return;
}
printInOrder(node.left);
visitTreeNode(node);
printInOrder(node.right);
}

private void printPreOrder(TreeNode node) {
if (node == null) {
return;
}
visitTreeNode(node);
printPreOrder(node.left);
printPreOrder(node.right);
}

private void printPostOrder(TreeNode node) {
if (node == null) {
return;
}
printPostOrder(node.left);
printPostOrder(node.right);
visitTreeNode(node);
}

private void visitTreeNode(TreeNode node){
System.out.print(node.nodeValue + " ");
}

public int getMinValue() {
return (getMinValue(root));
}

private int getMinValue(TreeNode node) {
while (node.left != null) {
node = node.left;
}
return (node.nodeValue);
}


public int getMaxValue() {
return (getMaxValue(root));
}

private int getMaxValue(TreeNode node) {
while (node.right != null) {
node = node.right;
}
return (node.nodeValue);
}

public int getMaxDepth() {
int depth = getMaxDepth(root);
return ((depth > 0) ? (depth - 1) : 0);
}

private int getMaxDepth(TreeNode node) {
if (node == null) {
return 0;
} else {
int leftDepth = getMaxDepth(node.left);
int rightDepth = getMaxDepth(node.right);
return (((leftDepth > rightDepth) ? leftDepth : rightDepth) + 1);
}
}

public boolean containsData(int data) {
return(containsData(root, data));
}

private boolean containsData(TreeNode node, int data) {
if (node == null) {
return false;
}
if (data == node.nodeValue) {
return true;
} else if (data < node.nodeValue) {
return(containsData(node.left, data));
} else {
return(containsData(node.right, data));
}
}

public int getRootValue(){
return root.nodeValue;
}

public boolean containsSumInPath(int total) {
return( containsSumInPath(root, total) );
}

private boolean containsSumInPath(TreeNode node, int total) {
if (node == null) {
return(total == 0);
} else {
int remainder = total - node.nodeValue;
if (containsSumInPath(node.left, remainder) || containsSumInPath(node.right, remainder)) {
addPaths( remainder, node.nodeValue, total);
}
return(containsSumInPath(node.left, remainder) || containsSumInPath(node.right, remainder));
}
}

private ArrayList path = new ArrayList();

private void addPaths(int remainder, int currentNodeValue, int total){
if (!path.contains(currentNodeValue)) {
path.add(currentNodeValue);
}
}

public ArrayList getSumOfPath(){
Collections.reverse(path);
return path;
}

public static void main(String[] args) {
BinaryTree bTree1 = new BinaryTree();
BinaryTree bTree2 = new BinaryTree();

bTree1.constructBinaryTreeHardCoded();
System.out.println("Size of the binary tree: " + bTree1.getSize());
System.out.println("Root value in the binary tree: " + bTree1.getRootValue());
System.out.println("Smallest value in the binary tree: " + bTree1.getMinValue());
System.out.println("Largest value in the binary tree: " + bTree1.getMaxValue());
System.out.println("Maximum depth of the binary tree: " + bTree1.getMaxDepth());
System.out.println("Contains node value 4: " + bTree1.containsData(4));
System.out.println("Path has sum of 30: " + bTree1.containsSumInPath(30) + " = " + bTree1.getSumOfPath());
bTree1.printTreeTraversal();

System.out.println();

bTree2.testHarness();
System.out.println("Size of the binary tree: " + bTree2.getSize());
System.out.println("Root value in the binary tree: " + bTree2.getRootValue());
System.out.println("Smallest value in the binary tree: " + bTree2.getMinValue());
System.out.println("Largest value in the binary tree: " + bTree2.getMaxValue());
System.out.println("Maximum depth of the binary tree: " + bTree2.getMaxDepth());
System.out.println("Contains node value 11: " + bTree2.containsData(11));

Random rand = new Random();
int find = rand.nextInt( 30 ) + 1;
System.out.println("Path has sum of "+ find +": " + bTree2.containsSumInPath(find) + " = " + bTree2.getSumOfPath());
bTree2.printTreeTraversal();

System.out.println("Are identical binary trees: " + bTree1.isIdenticalTree(bTree2));

System.out.println("\nChanged elements in binary tree");
bTree2.constructBinaryTreeHardCoded();
System.out.println("Are identical binary trees: " + bTree1.isIdenticalTree(bTree2));
}
}

Saturday, September 12, 2009

Scraping ISO 3166-1-alpha-2 country codes

I have written a simple XSL to scrape the ISO 2-letter country codes from the ISO website First I copied the table that contains the country names and codes and then I constructed the XSL. This is how the XSL looks like:UPDATE:
Please insert the breakline HTML element in the if block after the translate statement. Because without it, the country codes won't be displayed in separate lines. I have written another blog entry about scraping the codes. Please take a look here.

Sunday, August 23, 2009

Recursion vs iteration

Situations not to use recursion:
- recomputation of values (fibonacci, factorial, GCD)
- exhaust memory very quickly

Advisable to use iteration or memoization, instead, if you are so keen and persistent to implement recursion.

Sunday, August 16, 2009

How to record the behavior of Internet users

I would like to discuss about this interesting topic which is sometimes wrongly perceived by many people as a menacing way practiced by some, if not many, Internet companies to invade one's privacy. I supposed there is a huge gap or the level of understanding that separates the consumers and the business people.

The technological perspective that I am illustrating in this article is about implementing "click-tracking". For software engineers that really know and understand whatever they are implementing, the server has no control over the dynamic HTML pages once the bits and bytes are presented to the end-users. For now, do we agree unanimously at this stage?

Great, thank you for agreeing to my thoughts! If so, I shall elaborate further about how "click-tracking" is implemented, especially at the anchor element <a> in the HTML document. There are at least three significant ways to track the links the users are clicking. I am taking an online video company as an example.

[1] Redirecting users to different servlets
This is the most common way to track user clicks. Imagine you are a registered user and while your session is still active:
1. You do a keyword search
2. You get a compiled list of result items in the result page
(eg: http://www.example.com/search/?q=keyword_string&pg=1)
3. You click at the link you think is most relevant to you
(eg: http://www.example.com/view/?videoID=12345678)
4. You enjoy watching the selected video
5. You demand for more videos and you reiterate step 1 again.
But WAIT ... what laymen do not know is that while they are busy with their viewing activities, the servers are busy harvesting the clicks of the links. Technically speaking, the servlet that is related to the URL request will update the user database with the unique video IDs, which I think is the most important element. Many interesting things can take place from here and one of them is to count the number of viewed videos.

[2] AJAX
Some of you might have this question popping in your mind "But what if the page is loaded dynamically using AJAX?". The implementation is actually quite similar to the one mentioned previously but with a slightly different flavor. By using AJAX, you can implement an asynchronous method to pass the video ID as an argument to the servlet using GET or POST method. The servlet will then take care of the rest without the user knowing whatever happens behind the scene (or their clicks are monitored).

[3] Javascript / AJAX
The other method to perform "click-track" is by using Javascript. This is used in the scenario where the search result page contains links that redirect users to the original sources and not within their domain. In other words, a totally different URL altogether. A GET or POST method is used to send the data back to the server.

While the 3 suggested implementations seem similar, they are actually not the same. I hope you find this article a good read and insightful about performing "click-track".

Friday, June 5, 2009

Solving Palindrome Using Recursion

This is a follow-up article about solving palindrome using recursion. While we solved this problem previously using iteration (link to previous article), I am demonstrating the way of solving it in a recursive manner.

public static void isPalindromeRecursive(String text){
text = text.toLowerCase().replaceAll("[\\W\\_*]", "");
if (helperFunction(text, 0, text.length()-1)) {
System.out.println("Is a Palindrome");
} else {
System.out.println("Is not a Palindrome");
}
}

private static boolean helperFunction(String input, int leftIndex, int rightIndex){
if (leftIndex < rightIndex) {
if (!(input.charAt(leftIndex) == input.charAt(rightIndex))) {
return false;
}
leftIndex++;
rightIndex--;
helperFunction(input, leftIndex, rightIndex);
}
return true;
}

Friday, May 29, 2009

Swapping 2 Integers

I believe many of us out there came across, at least once in their lifetime, the problem to swap two numbers. Here are the three sample solutions that I could think to swap two numbers.
Solution A:

temp = a;
a = b;
b = temp;
Solution A introduces an additional auxiliary variable called "temp" in the code to hold one of the values (either a or b) which increases the footprint of the compiled class.
Solution B:

a = a ^ b;
b = b ^ a;
a = a ^ b;
Solution B on the other side swaps two numbers using bitwise operation. The XOR (Exclusive OR) is introduced in this code.
Solution C:

a = a + b;
b = a - b;
a = a - b;
Last but not least, Solution C swaps two numbers using arithmetic operations, both addition and subtraction.
Conclusion: In terms of speed, I would personally rank Solution B being the fastest, Solution C the second fastest and Solution A the slowest. (B -> C -> A)

Monday, May 11, 2009

CoffeeCup HTML Editor

This is a HTML Editor that you may want to give it a try. I love to use this application because, first of all, it is absolutely free. You can get it right here for free without any cost! Here is a screenshot of how their website looks like.

Most of the time, free stuffs are not actually free. Some companies will insist to get at least your email address in order to download their "free" software. For those of you that might be wondering why some companies tempt you to give them your email address or phone number, the reason being that your contact information will be harvested by spammers or so called business affiliates. Do not fall into that trap. Privacy is becoming more and more invaded these days. CoffeeCup does not ask for your email address nor telephone number. You will just need to download this HTML Editor from their website and the application is up and running. No strings attached!

I have tested this application and it is loaded with many interesting features including syntax highlighting. It also allows you to preview your HTML design in the same window. Since I have started to tinker with PHP at my playground, the editor is able to highlight the PHP statements nicely. The most important feature, for me personally, to use this application, is the FTP which is used to perform file uploads and downloads. No more paying a hefty sum of money to buy FrontPage or Dreamweaver - IDEs that helps you most of the frontend but leave you clueless about the underlying HTML codes.

Other than that, the interface is very intuitive. Everything that I wanted to do is within my estimation, which means that I know intuitively what buttons to point and click or which drop down menu to look at, the first time I was using this application. This is true when I configured the FTP settings.

But hey, since CoffeeCup HTML Editor is free, you should not expect that it is very feature-packed just like those off-the-shelf HTML editors. I have mentioned the pros earlier so here are some of the disadvantages. I have only came across one - CoffeeCup HTML Editor is only available for Windows and that is sad.

Anyway, this is the link again to download CoffeeCup HTML Editor. Have fun trying it!

DISCLAIMER: I am recommending CoffeeCup HTML Editor as a software developer that has tried its features and I think it is useful for other web developer and I do not receive any endorsement fee from CoffeeCup to write this article :)

Friday, May 8, 2009

The syntax highlighter

I believe some of my readers might be thinking to themselves how does Nicholas wraps around the codes that he demonstrates in his blog entries in a text area filled with interleaving colors. It also comes with the copying feature and viewing the codes in plain texts. Many thanks to Alex Gorbatchev for this wonderful Javascript library that allows us to read codes more easily in blogs or online journals. This is his website if you would want to take a look at his work. Or you can actually go to Google Code website to download the package. There are several steps for you to follow if you want to get your codes display nicely in the encapsulated and decorated text area.

[1] Go to the syntaxhighlighter website at Google Code to download the latest version of the Javascript library.


[2] Download the compressed file and unzip it in your remote hosting. I may suggest Google Apps to host the uncompressed files. You will have to use WinRAR to unzip the contents. I rename the folder called "dp.SyntaxHighlighter" to "SyntaxHighlighter". There are 2 folders that I make use in the uncompressed file namely "Styles" and "Scripts".

[3] Edit your blog template to insert these lines of codes, preferably at the footer part of the template that reads "<!-- end outer-wrapper --> ".

[4] The next step is to try inserting your code snippets into this textarea
<textarea name="code" class="javascript" cols="60" rows="10">
  code...
  code...
  code...
</textarea>

Hope you have fun trying this out! :)

Tuesday, May 5, 2009

Palindrome

A palindrome is a word or phrase that reads the same forward as it does backward. Some of the simple examples are "kayak", "Hannah" and "refer" if we would like to know how do palindromic words look like. There are also palindrome-like phrases such as "Dennis and Edna sinned" and "Draw pupil's lip upward".

It would not be too difficult to determine algorithmically if a word or sentence is a palindrome. There are many ways to solve it but we also need to consider if our solution is not computationally expensive.

I have thought of a simple and yet an efficient solution to our discussion. This is a static method that strips off the punctuations and also white character spacings. The method returns a boolean value true if the input string is a palindrome otherwise it returns false.

public static boolean isPalindrome(String text){
//Sets an index at the far left of the word or phrase
int leftIndex = 0;

//Converts input text into lower case and remove
//any single non-alphanumeric and underscore
text = text.toLowerCase().replaceAll("[\\W\\_*]", "");

//Sets an index at the far right of the word or phrase
int rightIndex = text.length()-1;
while (leftIndex < rightIndex) {
if (!(text.charAt(leftIndex) == text.charAt(rightIndex))) {
//returns a false and get out from the while loop
return false;
}

//gets the indexes from both sides closer
leftIndex++;
rightIndex--;
}
//returns a true if all the characters mirrors to each other
return true;
}