Sunday, December 20, 2009

Compare Google, Bing and Yahoo webmaster tools – who indexes faster?


Well, we all know that these giants provide search-engines which make our life better, by pointing us to the right web pages that we’re searching for. They have their own crawlers to find out what all of these web pages has as contents and to index (assuming that you know what is indexing) them. To assist this process, they all have webmaster tools too, so that web site owners can submit and update the information related to the websites they own to these search engines using sitemaps. The following list shows their webmaster tools and the links to them, as currently available.

Google Google Webmaster Tools http://www.google.com/webmasters/
Bing Webmaster Center http://www.bing.com/webmaster
Yahoo! Site Explorer http://siteexplorer.search.yahoo.com/

Following is my experience with the above tools and the inference based on them, which might be totally different from yours and can change from time to time.

The First Experience:
    For one of my website, a standard sitemap was created and was submitted to all of these webmaster tools almost at the same time. To be precise, Sitemap was submitted to Google and Bing on the same day and was submitted to Yahoo few days later.

Result:
    Google indexed the pages first which happened with few days and started showing them in their search results. Bing took slightly more than a week to index them while Yahoo totally ignored them.

The second experience:
    After around 2 months, the site had to be moved to another domain, which means another URL. The same content had to be placed in the new links. For the sake of indexing, the old domain was kept alive with only the updated sitemap (removed old links) and the content was moved to the new website with a sitemap of its own. Again, both the website’s sitemap was submitted to these tools at the same time.

Result:
    Here again, Google found my new website within a week and started showing them as indexed. It took slightly more than a week for Google to remove my old website links from their list. For Bing, even after two months, my old website links are still showing up in results and nothing from my new website is indexed. Yahoo Site Explorer is the simple one here, since nothing from my websites has been indexed in their list until now.

Conclusion:
    May be, there are technicalities involved based on moving the same content among websites OR the dependency of various aspects that controls the indexing process for search engines is too complex to accommodate the above scenario OR the other tools does well in other scenarios. But, whatever that is, for a user, for a specific content, based on the previous and the experiences stated above, it is found Google comes up with result of your sitemap submission first regardless of whether that is positive or negative. For a moment, I thought that we are going to have multiple options for web searches. But, it looks like I will have to stick with Google for updated results.

Friday, December 18, 2009

Get and Set values for all form elements using JavaScript


Here, we will cover the basic logic to retrieve and set values for various HTML form elements using a sample JavaScript code.

This discussion assumes that you are familiar with the methods like document.getElementById, document.getElementsByName etc.. to find and load the element for further processing. For a quick note, if it is assumed that you have a textbox with id, ‘myText’, then that text can be accessed by document.getElementsById(‘myText’).

The logic is pretty simple and is based on the concept that each element has it’s own individual property to be set. Below is the table that shows just that.

Element Type Property to be used Comments
checkbox checked  
hidden value  
radio checked  
text value  
textarea value  
select-one selected
OR
selectedIndex
This is a dropdown. It can be either set by setting the ‘selected’ property of the options collection OR setting the selectedIndex property of the dropdown itself.
select-multiple selected
OR
selectedIndex
This is multi-select dropdown which is created using multiple="multiple" for a select tag. Works similar to select-one.

To get the value of a particular element, use it’s appropriate property based on the type of the element being processed. The below code shows how that can be done in a simple manner. Note that the select-multiple returns an array of selected values. This code is presented in simple if..else syntax for simplicity. Provide error catching mechanism as necessary.

function getValue(element)//returns the value
{
if (element==null) return null;
var returnValue;
if (element.type=="select-one")
{
//dropdown (select-one)
returnValue = element.options[element.selectedIndex].value;
}
else if (element.type=="select-multiple")
{
//multi-select drop down
var returnArray = new Array();
for(var i = 0; i < element.options.length; i++)
{
if(element.options[i].selected == true)
{
returnArray.push(element.options[i].value);
}
}
return returnArray;
}
else if (element.type=="checkbox")
{
//checkbox element
returnValue = Boolean(element.checked);
}
else if (element.type=="radio")
{
//radio element
returnValue = Boolean(element.checked);
}
else
{
//text, textarea, hidden
returnValue = element.value;
}
return returnValue;
}

To set the value, it’s just the reverse process, which is shown below.

function setValue(element, value)//return whether the set was successful.
{
if (element==null) return false;
if (value==null) return false;
var returnValue;
if (element.type=="select-one")
{
//dropdown (select-one)
for(var i = 0; i < element.options.length; i++)
{
if(element.options[i].value == value)
{
element.selectedIndex = i;
returnValue = true;
break;
}
}
}
else if (element.type=="select-multiple")
{
//multi-select drop down, expects the value to be an array of selected values
for(var j = 0; j < value.length; j++)
{
for(var i = 0; i < element.options.length; i++)
{
if(element.options[i].value == value[j])
{
element.options[i].selected = true;
break;
}
}
}
returnValue = true;
}
else if (element.type=="checkbox")
{
//checkbox element
element.checked = Boolean(value);
returnValue = true;
}
else if (element.type=="radio")
{
//radio element
element.checked = Boolean(value);
returnValue = true;
}
else
{
//text, textarea, hidden
element.value = value;
returnValue = true;
}
return returnValue;
}

Additional thoughts:
If, the controls are rendered from an ASP.net application, there may be times where the value from a Label control is to be set or retrieved. Since a Label is rendered as a SPAN element, this can be done by enhancing the code for checking the nodeName OR tagName (or any appropriate property) and using innerHTML to set or get the value of the SPAN element.


Friday, December 11, 2009

Simple and advanced methods for creating thumbnail images in .net using c#


When I stumbled upon GetThumbnailImage method available in the Image class for the first time, I immediately went ahead with the thought that now I have a native and efficient way to create thumbnails. I used a code similar to what shown below.

Option 1: using GetThumbnailImage

private Image getThumbNailUsingGetThumbnailImage(string fileName)
{
Image img = Image.FromFile(fileName);
return img.GetThumbnailImage(300, 300, null, IntPtr.Zero);
}

The result was quick. But, soon it was found that this will not work as efficiently as I expected. The biggest problem was that when the image got edited by any of the image editing tools out there, the thumbnail creation went wrong. It was because of the reason that GetThumbnailImage was depending up on the image metadata as it was set when the image got created. If the image thumbnail property is not getting modified by your image editing tool, GetThumbnailImage will fail to get the right thumbnail. Below is a similar method that retrieves the thumbnail from the PropertyItem collection of an image.

Option 2: Using PropertyItem

private Image createThumbFromProperty(string file)
{
Image image = new Bitmap(file);
Image Thumb = null;
PropertyItem[] propItems = image.PropertyItems;
foreach (PropertyItem propItem in propItems)
{
if (propItem.Id == 0x501B)
{
byte[] imageBytes = propItem.Value;
MemoryStream stream = new MemoryStream(imageBytes.Length);
stream.Write(imageBytes, 0, imageBytes.Length);
Thumb = Image.FromStream(stream);
break;
}
}
return Thumb;
}

Thus started a lookout for a performance-improved simple way to achieve this which resulted in the following methods. Basically, these methods used GDI+. The logic seems pretty simple, which is to create another small in-memory based on the size of the thumbnail needed. It breaks down to this.

1. Load the original image
2. Get the proportional size of the image based on the original Image size and target thumbnail size
3. Redraw the image to the new canvas

A sample code for this is shown below

Option 3: Using GDI+ for simple thumbnail
private Image getThumbNail(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
Image im = Image.FromStream(fs);
Size szMax = new Size(300, 300);
Size sz = getProportionalSize(szMax, im.Size);
// superior image quality
Bitmap bmpResized = new Bitmap(sz.Width, sz.Height);
using (Graphics g = Graphics.FromImage(bmpResized))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(
im,
new Rectangle(Point.Empty, sz),
new Rectangle(Point.Empty, im.Size),
GraphicsUnit.Pixel);
}
im.Dispose(); im = null;
fs.Close(); fs.Dispose(); fs = null;
return bmpResized;
}

private Size getProportionalSize(Size szMax, Size szReal)
{
int nWidth;
int nHeight;
double sMaxRatio;
double sRealRatio;

if (szMax.Width < 1 || szMax.Height < 1 || szReal.Width < 1 || szReal.Height < 1)
return Size.Empty;

sMaxRatio = (double)szMax.Width / (double)szMax.Height;
sRealRatio = (double)szReal.Width / (double)szReal.Height;

if (sMaxRatio < sRealRatio)
{
nWidth = Math.Min(szMax.Width, szReal.Width);
nHeight = (int)Math.Round(nWidth / sRealRatio);
}
else
{
nHeight = Math.Min(szMax.Height, szReal.Height);
nWidth = (int)Math.Round(nHeight * sRealRatio);
}

return new Size(nWidth, nHeight);
}

Now that we know how to draw things on the Bitmap (canvas), we can play around and create framed thumbnails as shown below. The code below will create a frame effect around the thumbnail.

Option 4: Using GDI+ for framed thumbnail
private Image getThumbNailWithFrame(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
Image im = Image.FromStream(fs);
Size szMax = new Size(300, 300);
Size sz = getProportionalSize(szMax, im.Size);
// superior image quality
Bitmap bmpResized = new Bitmap(sz.Width, sz.Height);
using (Graphics g = Graphics.FromImage(bmpResized))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.White, 0, 0, sz.Width, sz.Height);
int FrameWidth = 5;//decides the frame border width
g.DrawRectangle(new Pen(Color.Silver, FrameWidth - 2), 0, 0, sz.Width - 1, sz.Height - 1);
FrameWidth += 5;//decide the frame width
g.DrawImage(im, new Rectangle(FrameWidth, FrameWidth, sz.Width - FrameWidth * 2, sz.Height - FrameWidth * 2), new Rectangle(Point.Empty, im.Size), GraphicsUnit.Pixel);
}
im.Dispose(); im = null;
fs.Close(); fs.Dispose(); fs = null;
return bmpResized;
}

We can even extend this concept to create shades around the generated thumbnail. The below code demonstrates that on a white background.

Option 5: Using GDI+ for shaded thumbnail

private Image createThumbnailUsingGDI(ref Image imgPhoto, int destWidth, int destHeight)
{
int sourceX = 0;
int sourceY = 0;

int destX = 0;
int destY = 0;
int sourceWidth = imgPhoto.Width;
int sourceHeight = imgPhoto.Height;

Bitmap b = new Bitmap(destWidth, destHeight);

Graphics grPhoto = Graphics.FromImage(b);

grPhoto.FillRectangle(Brushes.DarkGray, new Rectangle(destX, destY, destWidth, destHeight));
grPhoto.DrawLine(new Pen(Brushes.LightGray), new Point(0, destHeight - 1), new Point(destWidth, destHeight - 1));
grPhoto.DrawLine(new Pen(Brushes.LightGray), new Point(destWidth - 1, 0), new Point(destWidth - 1, destHeight));
//shade right
grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - 3, 0, 7, 2));
grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - 2, 0, 7, 4));
grPhoto.FillRectangle(Brushes.White, new Rectangle(destWidth - 1, 0, 7, 6));

//shade botton
grPhoto.FillRectangle(Brushes.White, new Rectangle(0, destHeight - 3, 2, 7));
grPhoto.FillRectangle(Brushes.White, new Rectangle(0, destHeight - 2, 4, 7));
grPhoto.FillRectangle(Brushes.White, new Rectangle(0, destHeight - 1, 6, 7));
grPhoto.DrawImage(imgPhoto, new Rectangle(destX + 2, destY + 2, destWidth - 7, destHeight - 7), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);

grPhoto.Dispose();
return b;

}

These methods do provides some flexibility and they are efficient enough for small scale applications. But, if we're talking about large number of images where memory and performance are critical factors, these may not suffice. We can fine tune the above methods by any/all of the following approaches and of course, lot others.

1. Having proper "using" keywords
2. making sure that the objects are destroyed properly
3. Having the thumbnail creating method loaded as static so that is always ready for you.
4. Get yourself equipped with knowledge on Graphics class which has numerous drawing capabilities and various brushes.

Once you have your thumbnail generation code ready, use it with extensive multi-threading concepts to give the user a pleasant feeling. If you're looking for any basic threading knowledge, look at my other article here.

I know, there may be few who might be hoping that we could've had something simple like GetThumbnailImage which didn't had any pitfalls. Well, there may be. System.Windows.Media.Imaging might be the place to look at for these capabilities.

Please note that this article is for learning purposes. If you are here for quick code to be used for production purposes, please look elsewhere.

Reference:
http://danbystrom.se

Saturday, November 21, 2009

How events are detected and triggered by ASP.net server during Form Submit or Postback

Remember those days when we had only a single communication to the server where we had to handle all the related events? We were not having the flexibility to attach events to each and every control and use specific event handlers in the server that time. Well, we all know those days are long gone after ASP.net came in. Given the fact that the underlying communication architecture between the client browser and server remains almost the same, have you ever wondered how ASP.net managed to attach these events and call the appropriate event handler method in the server. If you're curious, go ahead with this article. We will try to understand the basics of what is going on and how we can override and use them, in case the need arises.

Here is sample asp.net page with one text box control and two server (runat="server") buttons that has server events. They are having their default properties.

Here is the designer code:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="postback.aspx.cs" Inherits="postback" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Events and Postback</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button 1" />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Button 2" />
</div>
</form>
</body>
</html>

Here is the server code:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class postback : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text = "1";
}
protected void Button2_Click(object sender, EventArgs e)
{
TextBox1.Text = "2";
}
}


Here is client source code that was pushed by ASP.net:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Events and Postback
</title></head>
<body>
<form name="form1" method="post" action="postback.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTk0MTQ1MTcxMWRkFKmiofOm3t+a1FeTyiSsorNM4sk=" />
</div>

<div>

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAKWt63zDALs0bLrBgKM54rGBgK7q7GGCNoGUvTkiMJt3F6eDcqfS57GMOdl" />
</div>
<div>
<input name="TextBox1" type="text" id="TextBox1" />
<input type="submit" name="Button1" value="Button 1" id="Button1" />
<input type="submit" name="Button2" value="Button 2" id="Button2" />
</div>
</form>
</body>
</html>


Wait, here there are some additional hidden variables auto rendered by ASP.net. Let's skip that part for now and see that our buttons are rendered as submit buttons. This is because of the reason that the Button's UseSubmitBehavior property was true, which is the default setting. Here for every events like an ENTER press in the textbox or CLICK in any of the buttons, there is a submit happening to the server. The form post data already has the information regarding the events, based on which ASP.net can process and call the appropriate event associated.


Now, let's change the UseSubmitBehavior property for the first button and see what happens.

Designer code:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="postback.aspx.cs" Inherits="postback" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Events and Postback</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button 1" UseSubmitBehavior="False" />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Button 2" />
</div>
</form>
</body>
</html>


Server code:
[This is same as the previous server code]

Client source code that was pushed by ASP.net:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
Events and Postback
</title></head>
<body>
<form name="form1" method="post" action="postback.aspx" id="form1">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTk0MTQ1MTcxMWRkFKmiofOm3t+a1FeTyiSsorNM4sk=" />
</div>

<script type="text/javascript"> 
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>


<div>

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAKWt63zDALs0bLrBgKM54rGBgK7q7GGCNoGUvTkiMJt3F6eDcqfS57GMOdl" />
</div>
<div>
<input name="TextBox1" type="text" id="TextBox1" />
<input type="button" name="Button1" value="Button 1" onclick="javascript:__doPostBack('Button1','')" id="Button1" />
<input type="submit" name="Button2" value="Button 2" id="Button2" />
</div>
</form>
</body>
</html>


We can see that there is more code from server. There are few more hidden variables and some Javascript coding. The ones that we are interested in are "__EVENTTARGET", "__EVENTARGUMENT" and the "__doPostBack" function that seems to be mimicking a submit operation. This particular function is being associated to the button to which we set a false UseSubmitBehavior. The same button is now rendered as a BUTTON type. From this, we can cut down all the drama that was happening above and infer the logic as below:

ASP. net’s event handling logic:
1. Controls that are tied with a server event are rendered with a client JavaScript event associated.
2. This client code mimics a server submit operation after filling the hidden variables [Note that the name is being filled in "__EVENTTARGET" field.
3. The ASP.net server, when receives the post data, process the hidden variables to understand the event was triggered from a non-submit button and calls the method associated to the event.

Now that we've got a glimpse of what is happening, let's try to go a little deeper. By having a small code in the Page_Load event, as shown below, we can actually get these parameters. There are multiple ways to get these. Here is one:

protected void Page_Load(object sender, EventArgs e)
{
string eventControlName = Request.Params.Get("__EVENTTARGET");
string eventArguments = Request.Params.Get("__EVENTARGUMENT");

}


It may seem that there is pretty much a straight forward process and we can go ahead with our implementations thinking that this will work always. But, it doesn't. Even though pretty basic, there are some quirks and points to be noted. Below are few among them.
a. By any means if you disable this control in the client before a submit operation, submit to the server will not happen. That is, for example, if a button gets disabled on its click event, in the client, the submit will not happen at all. The good news is that, now that we know that this happens through our favorite function "__doPostBack", we can call the same from your client code, if needed.
b. If none of these controls have their visible property set to false, the server will not render with those functions and associate them. It is understandable that we don't need to do anything with an invisible control. But, in case, if you're looking for a "__doPostBack" function and you cannot find it, this may be a reason.
c. For dynamic controls with server events, these ideas will come handy, because now we now, how to identify, trigger and disable the events and its arguments.

Note: For the sake of simplicity, I haven't covered the events related to other controls and their arguments. Also, the hidden controls "__VIEWSTATE" and “__EVENTVALIDATION" does play a role in the server communication. So, if you're looking for extended information, try searching for those two. ASP.net may change this logic in future versions. Watch out for that too.

Sunday, November 15, 2009

Elephants with Ornaments (Nettipattam), accompanied by Panchavadyam

This happens in God's own Country, Kerala, India. The Hindu Gods (usually a symbol called ‘Thidambu’, which has the power and goodness of the God) visits the neighborhood. A group of elephants are used for this purpose and the biggest elephant in the group is the chosen one to carry the God. These elephants are decorated with gold coated (Some times made of Gold) ornaments called "Nettipattam". They are accompanied by an orchestra consisting of traditional instruments which is named as "Panchavadyam". The same is also done when there is an important ceremony in the temple. Below are few snaps on these.

For more information, search for Thrissur pooram on the web, which is the biggest among these.







































Nettipattam

Thursday, October 29, 2009

Two dimensional Array (Table Array) Multiple column sorting using JavaScript

Here is a JavaScript implementation for multi-column ascending sort on a table array.

Below is the code for this.
var tempArray = new Array();
//main function
function do2DArraySort(arrayToBeSorted, sortColumnArray)
{
if (arrayToBeSorted == "undefined" || arrayToBeSorted == "null") return arrayToBeSorted;
if (arrayToBeSorted.length == 0) return arrayToBeSorted;
if (sortColumnArray.length == 0) return arrayToBeSorted;
tempArray = arrayToBeSorted; 
var totalLength = sortColumnArray.length; 
for(var m = 0; m < totalLength; m++)
{
if (m == 0)
{   
doBubbleSort(tempArray, tempArray.length, sortColumnArray[m]);         
}
else
{     
doMultipleSort(tempArray, sortColumnArray[m], sortColumnArray[m-1]);
}
} 
return tempArray;
}

//basic bubble sort implementation
function doBubbleSort(arrayName, length, element) 
{
for (var i = 0; i < (length-1); i++)
{
for (var j = i+1; j < length; j++)            
{
if (arrayName[j][element] < arrayName[i][element]) 
{
var dummy = arrayName[i];
arrayName[i] = arrayName[j];
arrayName[j] = dummy;
}
}
}  
}

//appends an array content to the original array
function addToArray(originalArray, addArray)
{
if (addArray.length != 0)
{
var curLength = 0;
curLength = originalArray.length;
var maxLength = 0;
maxLength = curLength + addArray.length;  
var itrerateArray = 0;
for (var r = curLength; r < maxLength; r++)
{   
originalArray[r] = addArray[itrerateArray];
itrerateArray++;
}
}
}

//check if a value exists in a single dimensional array
function checkIfExists(arrayToSearch, valueToSearch)
{
if (arrayToSearch == "undefined" || arrayToSearch == "null") return false;
if (arrayToSearch.length == 0) return false;
for (var k = 0; k < arrayToSearch.length; k++)
{
if (arrayToSearch[k] == valueToSearch)
return true;
}
return false;
}

//sorts an 2D array based on the distinct values of the previous column
function doMultipleSort(sortedArray, currentCol, prevCol)
{
var resultArray = new Array(); 
var newdistinctValuesArray = new Array();
//finding distinct previous column values 
for (var n = 0; n < sortedArray.length; n++)
{ 
if (checkIfExists(newdistinctValuesArray, sortedArray[n][prevCol]) == false)
newdistinctValuesArray.push(sortedArray[n][prevCol]);
}  
var recCursor = 0;
var newTempArray = new Array(); var toStoreArray = 0; 
//for each of the distinct values
for (var pp = 0; pp < newdistinctValuesArray.length; pp++)
{
toStoreArray = 0;
newTempArray = new Array();  
//find the rows with the same previous column value
for (var qq = recCursor; qq < sortedArray.length; qq++)
{
if (sortedArray[qq][prevCol] != newdistinctValuesArray[pp]) break;
newTempArray[toStoreArray] = sortedArray[qq];
toStoreArray++; recCursor++;
}
//sort the row based on the current column   
doBubbleSort(newTempArray, newTempArray.length, currentCol);
//append it to the result array
addToArray(resultArray, newTempArray);
}
tempArray = resultArray;
}
The above code can be stored as TableArrayMultipleSort.js for our example usage shown below:
<html>
<head>
<title>Invoking Multiple Array Sort</title>
<script language="javascript" src="TableArrayMultipleSort.js" type="text/javascript"></script>
</head>
<body>
<script language="javascript" type="text/javascript">
function createSampleArray()
{ 
var myArr = new Array( 
new Array("Ashley","13","Male","Texas"),
new Array("Smith", "32", "Male","Colorado"),
new Array("Jane", "21", "Female","South Carolina"),
new Array("Anna", "12", "Female","Maryland"),
new Array("Ashley","13","Male","Delaware"),
new Array("Ashley","46","Male","Newyork")
); 
return myArr;
}
function showDataByRow(arrayToBeShown)
{
for(var a=0;a<arrayToBeShown.length;a++)
{
document.write(arrayToBeShown[a]+"<br>");
}
}
document.write("<b>Original Array: (Input)</b>" + "<br><br>");
showDataByRow(createSampleArray());
document.write("<br><br><br>");
var sortColumnArray = new Array('0','1','3'); 

document.write("<b>Sorted Array: (Output)</b><br>Order: First column, then by second column and then by Last Column" + "<br><br>");
showDataByRow(do2DArraySort(createSampleArray(),sortColumnArray));
</script>
</body>
</html>
When the above code is executed, this will show the input table array and output table array as shown below. Original Array: (Input)
Ashley,13,Male,Texas
Smith,32,Male,Colorado
Jane,21,Female,South Carolina
Anna,12,Female,Maryland
Ashley,13,Male,Delaware
Ashley,46,Male,Newyork
Sorted Array: (Output) Order: First column, then by second column and then by Last Column
Anna,12,Female,Maryland
Ashley,13,Male,Delaware
Ashley,13,Male,Texas
Ashley,46,Male,Newyork
Jane,21,Female,South Carolina
Smith,32,Male,Colorado
Enhancements: 1. The code can be enhanced to accomodate sort order for each of the sort columns by having a seperate array to specify that.
2. It can be relooked for performance improvements and enhanced variable handling.
3. There are few issues related to null/empty-value, if it exists in any of the columns being sorted.


Note: The objective of this article is to assist in learning the Javascript array concepts and it's usage. This code is not intended to be used for production purposes as it is not written with that aspect in mind. So, if you want to use it, use it at your own risk.

Sunday, October 25, 2009

Large Grasshopper

This big one was just sitting there having all the food that he can; finished a major portion of the plant's leaves. It's pretty colorful and is around 9.5 cm long.

If someone, who study these, is looking for a nice snap of this one, here it is. Please comment on the scientific name so that others can find this.



















































Wednesday, October 21, 2009

Threading in .net - for Beginners


Method 1: Using ThreadPool.QueueUserWorkItem

There may be scenarios, in which you want to have an asynchronous operation to be performed without the need of a handle on the function being called. For example, this can be an audit log or a process log operation which can be a background process while your main application performs the important operations. There is a simple single line code to achieve this using ThreadPool.QueueUserWorkItem call. Typical usage is as follows.


private void button1_Click(object sender, EventArgs e)
{
string argument = "Process started";
ThreadPool.QueueUserWorkItem(new WaitCallback(WriteLog), input);
}

private void WriteLog(object o)
{
string argument = o as string;
// Your code to log the argument
}

In this method:
1. With a single line code, you are getting the basic benefits of threading without having to worry about creating, managing and terminating a threaded operation.
2. QueueUserWorkItem call is in control of .net runtime. You will not be able to control the time at which it gets executed.
3. You cannot control the state and priority of the function being executed.

Method 2. Using ThreadStart, ParameterizedThreadStart and Thread

Below is another method that will give more control on your asynchronous operation.

a) Without having a Parameter

Class level decleration


private Thread t = null;


This can be used for later tracking of the thread being executed.

private void button2_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(WriteStartLog);
t = new Thread(ts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start();
}

private void WriteStartLog()
{
// Your code to log the process start
}


To track the thread, the thread object can be used. A sample usage is provided below:

private void button3_Click(object sender, EventArgs e)
{
if (t != null)
{
if (t.IsAlive)
t.Abort();
}
}


b) Passing parameters using ParameterizedThreadStart

When parameters are to be passed to the invoked method, this can be done using ParameterizedThreadStart using the medium as objects.



private void button2_Click(object sender, EventArgs e)
{
ParameterizedThreadStart pts = new ParameterizedThreadStart(WriteLog);
t = new Thread(pts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start("Process started");
}


private void WriteLog(object o)
{
string argument = o as string;
// Your code to log the argument
}

Now that we have covered the basic skeleton of our article, let’s see the other important aspects of threading.

Handling ThreadAbortException

There might be a need to abort the thread being executed at any instant of time. This can happen due to the user cancellation of the process or any other action like the primary thread being closed due to a various reason. At these scenarios (even when there is no need), it is mandatory to have a ThreadAbortException to be handled in the method which is being called. This can be as follows:



private void WriteLog()
{
try
{
// Your code to log the argument
}
catch (ThreadAbortException tae)
{
//handles the thread abort exception
//code to cleanup - let know the user that thread got cancelled, if necessary.
}
catch (Exception e)
{
//handle other exceptions
}
}


Communicating between main and background thread.

Consider, this scenario:
You are having a background thread to create thumbnails for pictures in a folder. For each thumbnail being created, you have to draw it on the form. That is, to communicate from the background thread to the parent thread with the output from the background thread. This is pretty simple using delegates. Here it is how it’s done.

Class level declarations:


private delegate void addPictureBox2Main_Delegate(PictureBox pbb);
private Thread t = null;



private void button2_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(LoadImageThumbNails);
t = new Thread(ts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start();
}

private void LoadImageThumbNails()
{
try
{
//for each of the thumbnails being created
//generate picturebox with thumbnail here
PictureBox pb = //function to load thumbnail
this.Invoke(new addPictureBox2Main_Delegate(addPictureBox2Main), new Object[] { pb });
}
catch (ThreadAbortException tae)
{
//handles the thread abort exception
//code to cleanup - let know the user that thread got cancelled, if necessary.
}
catch (Exception e)
{
//hanlde other exceptions
}
}


private void addPictureBox2Main(PictureBox pb)
{
//add the picture box pb to the parent control as needed
}


** Code samples are in C#**

Note: This article only covers the basic aspect of threading and it aims to help beginners understand the threading concepts. There is more to it. So, keep learning.

Saturday, March 7, 2009

Clocks showing United States (US) timings and a Meeting planner for a specific date

I've been seeing my sales and implementation colleagues in India looking at different sites to found out the current time at various US time zones. There is always confusions when daylight saving settings comes in to the picture. To help this situation, here is a page that will show a nice little map from worldatalas.com along with their current timings. These timings are pulled from worldtimeserver.com.

Here is the link:
http://sanalks.com/clocks.htm

There is also a meeting planner link at the bottom which can be used to determine the time for a time zone at a particular date. This is especially useful for scheduling meetings.