Archive for June 16th, 2009

Functional Programming Battles GOTOzilla

Steve Wellens had a recent blog post arguing for the use of a goto in C# (see: Why goto Still Exists in C#). Steve had a series of methods he wants to execute, but he wants to stop if any given method returns false. At the end of the post, Steve decided that the following code with goto was better than setting boolean variables:

Functional programming battles the GOTO // DoProcess using goto
void DoProcess3()
{
    LOG("DoProcess Started...");

    if (Step1() == false)
        goto EXIT;
    if (Step2() == false)
        goto EXIT;
    if (Step3() == false)
        goto EXIT;
    if (Step4() == false)
        goto EXIT;
    if (Step5() == false)
        goto EXIT;

EXIT:
    LOG("DoProcess Finished");
}

In the comments, a remark from a different Steve stood out. Steve suggested using an array of Func<bool>. The comment didn’t generate any further discussion, but it’s worthy to call out.

I don’t think the problem with the above code is with the goto per-se. I think the problem is how the code conflates “what to do” with “how to do it”. In this scenario both are a little bit tricky. Let’s assume we might need to add, remove, or change the order of the method calls. But, the method calls are so intertwined with conditional checks and goto statements that it obscures the process. Using an array of Func<bool> is a simple approach, yet it still manages to create a data structure that isolates “what to do”.

void Process()
{
    Func<bool>[] steps =
    {
        Step1,
        Step2,
        Step3,
        Step4,
        Step5
    };

    ExecuteStepsUntilFirstFailure(steps);
}

You could argue that all this code does is push the problem of “how to do it” further down the stack. That’s true, but we’ve still managed to separate “what” from “how”, and that’s a big win for maintaining this code. The simplest thing that could possibly work for “how” would be:

void ExecuteStepsUntilFirstFailure(IEnumerable<Func<bool>> steps)
{
    steps.All(step => step() == true);
}

The All operator is documented as stopping as soon as a result can be determined, so the above code is equivalent to the following:

void ExecuteStepsUntilFirstFailure(IEnumerable<Func<bool>> steps)
{
    foreach (var step in steps)
    {
        if (step() == false)
        {
            break;
        }
    }
}

With this approach it’s easy to change the order of the steps, or to add steps and delete steps, without worrying about missing a goto or conditional check. The next step up in complexity (excuse the pun) would be to create a Step class and encapsulate the Func with other metadata and state. I’m sure you could also imagine the execution phase relying on an IStepExector interface as the base for executing steps under a transaction, or with step-level logging, or even in parallel – and all this without changing how the steps are arranged. Take this to an extreme, and you’ll have a technology like Windows Workflow Foundation. :)

The ability of functional and declarative programming to separate the “what” and the “how” is powerful, but you don’t need a new language, and you can start simple. In this scenario it’s another tool you can use to save your city from the goto-zilla monster.

What do you think?

Comments Off more...

Using ASP.NET 3.5′s ListView and DataPager Controls: Inserting Data

The ListView control is similar to the GridView control in many ways: both display a set of records, both support built-in sorting, paging, editing, and deleting functionality with minimal effort. The ListView differs from the GridView in two key ways:

  • Rather than using fields, the ListView is rendered via templates, which offers the page developer much finer control over the emitted markup, and
  • The ListView supports built-in inserting support

The first installment in this series explored the ListView's template-based rendering. This installment looks at how to use the ListView's inserting functionality.

In a nutshell, inserting data from the ListView requires two steps: defining the inserting interface via the InsertItemTemplate and specifying where the inserting interface should go via the InsertItemPosition property. Much like with editing data from within the ListView, the InsertItemTemplate can contain two-way databinding statements when using a data source control to get the inputs entered by the user from the ListView's inserting interface into the parameters of the data source control. And like with the editing and deleting workflows, you can programmatically examine and modify the user's submitted data before inserting the data, cancelling the operation altogether if needed.

This article walks through the steps for creating a ListView that allows users to insert records. It also shows how to optionally cancel the inserting workflow based on programmatic logic. Read on to learn more!

(It is assumed that the reader is familiar with how to insert data using a data source control. If this is not the case, please first read Accessing and Updating Data in ASP.NET: Inserting Data.)
Read More >

Comments Off more...

WinForms Rating Control: Now Shipping

If you’ve been waiting around for a good WinForms Rating control, then you’re in luck with the current release of DevExpress WinForms Gauges. The XtraGauges Suite.

image

Featuring the ability to connect with several input controls like a radio group or a slider, the Rating control has sharp graphics and versatility.

The image above shows the rating control in action. You can see this demo by:

  1. Opening the ‘DemoCenter’ application in the DevExpress folder and
  2. selecting the ‘New Presets’ option of the ‘XtraGauges Main Demo’
  3. [General folder location]: C:\Program Files\DevExpress 2009.1\Components\Demos\DXperience\Bin\

Full source code for the rating control demo is also available in your local DevExpress folder (see item #3 for typical folder location). Available in the DXperience 2008 volume 3 release (and above) you can get your hands on the WinForms Rating control right away.

StarStarThanks to the loyal readers who commented by asking about a WinForms Rating control on the recent ASP.NET Rating control announcement!

DXperience? What's That?

DXperience is the .NET developer's secret weapon. Get full access to a complete suite of professional components that let you instantly drop in new features, designer styles and fast performance for your applications. Try a fully-functional version of DXperience for free now: http://www.devexpress.com/Downloads/NET/


How To Create Your Own Stats Program (JavaScript, AJAX, PHP)


When creating a website, one main goal is to attract visitors. Traffic generation is a necessity for monetary purposes, showing off your work, or just expressing your thoughts. There are many ways to create traffic for your website. Search engines, social bookmarking, and word of mouth are just a few examples. But how do you know whether this traffic is genuine? How do you know if your visitors are coming back for a second time?


Web Statistics

These questions have raised the concept of web statistics. Often times, webmasters use certain programs, such as Google Analytics or Awstats, to complete this job for them. These programs obtain a wide variety of information about visitors to a site. They find page views, visits, unique visitors, browsers, IP addresses, and much more. But how exactly is this accomplished? Follow along as we present a tutorial on how to create your own web statistics program using PHP, JavaScript, AJAX, and SQLite.

View Demo of your Own Stats Program

To begin, let’s start with some simple HTML markup that will act as the page we are tracking:

<!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" dir="ltr" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Web Statistics</title>
</head>
<body>

<h2 id="complete"></h2>

</body>
</html>

The h2#complete element will be filled dynamically with JavaScript once the page view has successfully been tracked by our web statistics. To initiate this tracking, we can use jQuery and an AJAX request:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
	// Set the data text
	var dataText = 'page=<?php echo $_SERVER['REQUEST_URI']; ?>&referrer=<?php echo $_SERVER['HTTP_REFERER']; ?>';

	// Create the AJAX request
	$.ajax({
		type: "POST",                    // Using the POST method
		url: "/process.php",             // The file to call
		data: dataText,                  // Our data to pass
		success: function() {            // What to do on success
			$('#complete').html( 'Your page view has been added to the statistics!' );
		}
	});
});
</script> 

Consider the above code step by step:

  • When the DOM is ready, we first set our dataText. This text is in query string format and will be sent as data to process.php, which will track this page view.
  • We then create an AJAX request that uses the POST method to send form data.
  • Our form data (dataText) is then sent to process.php in the root of our server.
  • Once this request is completed, the h2#complete element is filled with a successful notice

Our next job is to write process.php. Its main goal is to obtain information about the web statistics and store it in a database. Since our database has not yet been made, we must create a simple file, install.php, which will do this for us:

SQLite Database

<?php
	# Open the database
	$handle = sqlite_open( $_SERVER['DOCUMENT_ROOT'].'stats.db', 0666, $sqliteError ) or die(  $sqliteError  );

	# Set the command to create a table
	$sqlCreateTable = "CREATE TABLE stats(page text UNIQUE, ip text, views UNSIGNED int DEFAULT 0, referrer text DEFAULT '')";

	# Execute it
	sqlite_exec( $handle, $sqlCreateTable );

	# Print that we are done
	echo 'Finished!';
?>

This code is mostly straightforward. It opens up a database (stats.db) in the root of the server and creates a database for it. The string inside $sqlCreateTable is a SQLite command that makes our statistics table. This table contains four colums: Page, IP Address, Views, and Referrer:

  • Page is a String that contains the page being viewed as a relative link (i.e. /index.php).
  • IP Address is also a String that contains a list of IP Addresses that visited this page. It is in the format of numVisits1(IP Address1) numVisits2(IP Address2) numVisits3(IP Address3) etc. For example, if we obtained 10 visits from 74.35.286.15 and 5 visits from 86.31.23.78 (hypothetical ip addresses), this String would be "10(74.25.286.15) 5(86.31.23.78)".
  • Views is an integer containing the number of times the page has been viewed.
  • Referrer is a String in the same format as IP Address. It contains all referrers to this page and how many referrals have been made.

And now onto process.php:

# Connect to the database
$handle = sqlite_open( $_SERVER['DOCUMENT_ROOT'].'/stats.db', 0666, $sqliteError ) or die( $sqliteError );

# Use the same-origin policy to prevent cross-site scripting (XSS) attacks
# Remember to replace http://yourdomain.com/ with your actual domain
if( strpos( $_SERVER['HTTP_REFERER'], 'http://yourdomain.com/' ) !== 0 ) {
     die( "Do not call this script manually or from an external source." );
}

# Obtain the necessary information, strip HTML tags, and escape the string for backup proetection
$page = sqlite_escape_string( strip_tags( $_POST['page'] ) );
$referrer = sqlite_escape_string( strip_tags( $_POST['referrer'] ) );
$ip = sqlite_escape_string( strip_tags( $_SERVER['REMOTE_ADDR'] ) );

# Query the database so we can update old information
$sqlGet = 'SELECT * FROM stats WHERE page = \''.$page.'\'';
$result = sqlite_query( $handle, $sqlGet );

This first snippet connects to our stats database and gets the information we need for the current visit. It also queries the database and obtains any information previously stored. We use this information to create an updated table.

The next job is to find old information:

Old Statistics

# Set up a few variables to hold old information
$views = 0;
$ips = '';
$referrers = '';

# Check if old information exists
if( $result && ( $info = sqlite_fetch_array( $result ) ) ) {
	# Get this information
	$views = $info['views'];
	$ips = $info['ip'].' ';
	if( $info['referrer'] )
		$referrers = $info['referrer'].' ';

	# Set a flag to state that old information was found
	$flag = true;
}

The above code finds all previous information in our table. This is vital, as we need to update the number of views (increase it by one), IP addresses, and referrers.

# Create arrays for all referrers and ip addresses
$ref_num = array();
$ip_num = array();

# Find each referrer
$values = split( ' ', $referrers );

# Set a regular expression string to parse the referrer
$regex = '%(\d+)\((.*?)\)%';

# Loop through each referrer
foreach( $values as $value ) {
	# Find the number of referrals and the URL of the referrer
	preg_match( $regex, $value, $matches );

	# If the two exist
	if( $matches[1] && $matches[2] )
		# Set the corresponding value in the array ( referrer link -> number of referrals )
		$ref_num[$matches[2]] = intval( $matches[1] );
}

# If there is a referrer on this visit
if( $referrer )
	# Add it to the array
	$ref_num[$referrer]++;

# Get the IPs
$values = split( ' ', $ips );

# Repeat the same process as above
foreach( $values as $value ) {
	# Find the information
	preg_match( $regex, $value, $matches );

	# Make sure it exists
	if( $matches[1] && $matches[2] )
		# Add it to the array
		$ip_num[$matches[2]] = intval( $matches[1] );
}

# Update the array with the current IP.
$ip_num[$ip]++;

The above two loops are very similar. They take in the information from the database and parse it with regular expressions. Once this information is parsed, it is stored in an array. Each array is then updated with the information from the current visit. This information can then be used to create the final String:

# Reset the $ips string
$ips = '';

# Loop through all the information
foreach( $ip_num as $key => $val ) {
	# Append it to the string (separated by a space)
	$ips .= $val.'('.$key.') ';
}

# Trim the String
$ips = trim( $ips );

# Reset the $referrers string
$referrers = '';

# Loop through all the information
foreach( $ref_num as $key => $val ) {
	# Append it
	$referrers .= $val.'('.$key.') ';
}

# Trim the string
$referrers = trim( $referrers );

The final strings are now created. IPs and Referrers are in the form: “numVisits1(IP/Referrer1) numVisits2(IP/Referrer2) etc.” For example, the following could be the referrer String:

5(http://www.noupe.com) 10(http://css-tricks.com)

It means that 5 referrals came from http://www.noupe.com and 10 came from http://css-tricks.com. This format saves space and is easy to parse as web statistics.

Now for the final few lines:

# Update the number of views
$views++;

# If we did obtain information from the database
# (the database already contains some information about this page)
if( $flag )
	# Update it
	$sqlCmd = 'UPDATE stats SET ip=\''.$ips.'\', views=\''.$views.'\', referrer=\''.$referrers.'\' WHERE page=\''.$page.'\'';

# Otherwise
else
	# Insert a new value into it
	$sqlCmd = 'INSERT INTO stats(page, ip, views, referrer) VALUES (\''.$page.'\', \''.$ips.'\',\''.$views.'\',\''.$referrers.'\')';

# Execute the commands
sqlite_exec( $handle, $sqlCmd );

That’s all there is to it for process.php. As a review, it finds the IP Address and Referrer of the visitor, uses the values to create two Strings, increases the number of views of the page by one, and places all of these values into the database.

There is now only one task left. We have to display the web statistics. Let’s call the following file display.php:

Display The Statistics

<!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" dir="ltr" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Web Statistics Display</title>
</head>
<body>

<?php
	# Open up the database
	$handle = sqlite_open( $_SERVER['DOCUMENT_ROOT'].'/stats.db', 0666, $sqliteError ) or die( $sqliteError );

	# Get all the statistics
	$sqlGet = 'SELECT * FROM stats';
	$result = sqlite_query( $handle, $sqlGet );

	# Create an unordered list
	echo "<ul>\n";

	# If there are results
	if( $result ) {
		$page_views = 0;
		$unique_visitors = 0;

		# Fetch them
		while( ($info = sqlite_fetch_array( $result ) ) ) {
			# Get the page, views, IPs, and referrers
			$page = $info['page'];
			$views = $info['views'];
			$ips = $info['ip'];
			$referrers = $info['referrer'];

			# Print out a list element with the $page/$views information
			if( $views == 1 )
				echo "\t<li>\n\t\t<p>$page was viewed $views time:</p>\n";
			else
				echo "\t<li>\n\t\t<p>$page was viewed $views times:</p>\n";

			# Update the number of page views
			$page_views += $views;

			# Parse the data of IPs and Referrers using process.php's code
			preg_match_all( '%(\d+)\((.*?)\)%', $ips, $matches );

			# Find the size of the data
			$size = count( $matches[1] );

			# Create a sub list
			echo "\t\t<ul>\n";

			# Loop through all the IPs
			for( $i = 0; $i < $size; $i++ ) {
				# Find the number of visits
				$num = $matches[1][$i];

				# Find the IP address
				$ip = $matches[2][$i];

				# Print the info in a list element
				if( $num == 1 )
					echo "\t\t\t<li>$num time by $ip</li>\n";
				else
					echo "\t\t\t<li>$num times by $ip</li>\n";

				# Update the number of unique visitors
				$unique_visitors++;
			}

			# Repeat the whole process for referrers
			preg_match_all( '%(\d+)\((.*?)\)%', $referrers, $matches );
			$size = count( $matches[1] );

			# Loop through each one
			for( $i = 0; $i < $size; $i++ ) {
				$num = $matches[1][$i];
				$referrer = $matches[2][$i];

				# Print out the info
				if( $num == 1 )
					echo "\t\t\t<li>$num referral by $referrer</li>\n";
				else
					echo "\t\t\t<li>$num referrals by $referrer</li>\n";
			}

			# End the sub-list
			echo "\t\t</ul>\n";

			# End the list element
			echo "\t</li>\n";
		}

		echo "\t<li>Total unique visitors: $unique_visitors</li>\n";
		echo "\t<li>Total page views: $page_views</li>\n";
	}

	# End the unordered list
	echo "</ul>\n";

	# Close the database
	sqlite_close($handle);
?>

</body>
</html>

It may seem daunting, but it is very similar to process.php. It parses the page, views, ip addresses, and referrers from the database. It then continues to output these in an unordered list format.

The final output is as follows:

Final Web Statistics

View Demo of your Own Stats Program

Thank you for reading and good luck!

Author: Karthik Viswanathan

Karthik Viswanathan is a high-school student who loves to program and create websites. You can view Karthik’s work on his two blogs, Resource Mania and Lateral Code. He has also developed a PHP library for traversing HTML documents, which can be found here.

Write for Us! We are looking for exciting and creative articles, if you want to contribute, just send us an email.

Comments Off more...

Opera Unite – Web Server Inside Web Browser

Opera Unite is an upcoming new technology that will turn any computer or device running Opera 10 into a Web server. This will allow anyone to serve and share content and services directly from their own computers in the form of intuitive applications (Opera Unite Services).

  • Sponsored Links

  •  

    June 2009
    M T W T F S S
    « May   Jul »
    1234567
    891011121314
    15161718192021
    22232425262728
    2930  
  • .

    Copyright © 1996-2010 Answer My Query. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress