Showing posts with label technology. Show all posts
Showing posts with label technology. Show all posts

Thursday, June 5, 2014

Quick Thoughts on Wearable Technology

In the past couple of years, wearable technology has been the new buzzword in the ICT world. After "cloud", which turned out to be much simpler than it first sounded, and "big data", which remains too complicated an idea for mere mortals even today, one wonders how "wearable technology" will fare. So far, we have not seen anything beyond fancy gadgets for the youthful rich, including smartwatches and activity trackers (mainly writstbands). At one point, smartglasses held a lot of promise, as they had the potential to literally change the way we see the world. But the most promising one of the lot, Google Glass, is yet to take off in a big way. Even though the official release is expected to happen later in 2014, the product has not caught the imagination of the general public. Also, there are many concerns around safety (accidents caused by distracted drivers), privacy (recording videos without permission) and etiquette (quietly checking mail or social media during conversations). In the long run, Google Glass or its descendants may overcome these difficulties and gain widespread acceptance. But as of today, in most parts of the world, wearable technology remains more a concept than a reality.

Thursday, May 8, 2014

Quick Thoughts on Mobile UX

Mobile UIs haven't changed a lot in the dozen odd years that I've been using cellphones. My first phone, a Nokia 3310, had an icon-based menu that I struggled to navigate using physical keys. My current Android smartphone still has an icon-based menu, albeit one I can navigate more easily using a touch screen. Although I can now access most applications straight from my multiple home screens and the quick launch bar of my Android phone, the navigation paradigm essentially remains the same. With the possible exception of Windows 8, most mobile operating systems have failed to take full advantage of the touch screen to make the mobile user experience easier and more intuitive. This is where Panasonic's Gesture Play navigation promises to bring about a sea change. Though the company is yet to release more details about this new feature in their upcoming P31 phone, the ads that have been shown on TV do look promising.


Tuesday, May 6, 2014

JIRA (not Jeera)

Of late, every company that I speak to during my job search asks me if I have worked on JIRA. Since the only Jeera I have known is the humble cumin seed, used in many delicious Indian dishes like Jeera Rice, I decided to read up on this particular web-based software, which is used for issue tracking, software development and project management. Developed by an Australian company called Atlassian, JIRA has been around since 2002 and was originally made for issue management. JIRA’s flexible plugin architecture has spawned many integrations developed by the JIRA development community and third parties. It is available in desktop, hosted (Cloud) and mobile versions.

After taking a demo on the Atlassian website, I can tell you that JIRA remains at heart an issue tracking tool. But by defining "issue" in various ways like Defect, Requirement or User Story, you can use JIRA for bug tracking, general project management or Agile project management respectively. JIRA can be used for creating tasks, assigning tasks, tracking the task status, recording time spent on each task and generating status reports.

JIRA Agile (formerly GreenHopper) is an add-on for Scrum or Kanban teams. The easy user interface helps your team easily adopt Agile project management. Bonfire is another add-on that helps QA teams test Web applications. They can take screenshots with the Bonfire browser extension and tag them to Test Sessions, which are the central place in a JIRA project to track manual testing of a Defect, Requirement or User Story.

Atlassian offers various software development tools that are integrated into JIRA. Their team collaboration software, called Confluence, is designed to be used in conjunction with JIRA. JIRA even has a Service Desk module to streamline customer requests. Finally, Atlassian has a marketplace with more than a thousand add-ons available to extend JIRA and use it for more activities related to your daily project management needs.

Friday, April 18, 2014

Republishing Stuck Blogger Posts

This post is slightly off-topic for this blog but it can be classified as technical and also, I want to share this workaround with other users of the Blogger Android app. I managed to find it on the Google Product Forums but it's not an easy one to reach.

Sometimes, especially while traveling, you lose your net connection just before you hit "Publish" on a post. This causes the post to be forever stuck in "publishing" status. You aren't able to republish it even after your net connection gets restored, because the post is "greyed out" in the app.

In such cases, you can use the below workaround after your net connection is restored:

"User would need to use both thumbs as you are trying to force the system to do something with one while clicking on the affected post at the same time. User can hit any published/draft post with left thumb and follow it quickly with tapping on affected row with right thumb. It should happen quickly so that the published/draft post actually doesn't get the tap and rather the affected post row registers a tap event." Now edit the post just like any other draft and publish it.

Friday, March 28, 2014

3D Printing for Dummies

What is 3D printing: As per Wikipedia, "3D printing or Additive manufacturing is a process of making a three-dimensional solid object of virtually any shape from a digital model." It uses an additive process, where successive layers of material are laid down by a 3D printer in different shapes, based on a computer-generated 3D model of an object.

Why is it so useful: Wikipedia points out that 3D printing is useful right "from pre-production (i.e. rapid prototyping) to full-scale production (i.e. rapid manufacturing), in addition to tooling applications and post-production customization." Unlike traditional subtractive methods of manufacturing, there is less material wastage in case of 3D printing.

How is it important: Mark Fleming claims that "Medicine will forever be changed as new bioprinters actually print human tissue for both pharmaceutical testing and eventually entire organs and bones." Also, he says, "experimental, massive 3D printers are printing concrete structures, with the goal of someday creating entire buildings with a 3D printer."

Who uses 3D printing: TechRepublic reports that "A growing number of innovative companies are experimenting with 3D printers, propelling the technology closer to the mainstream market." These include major companies like General Electric, Boeing, Ford, Nike, Hasbro and Hershey's. Many hobbyists also use personal 3D printers in their homes.

Where to from here: As 3D printers become less expensive, more companies and even individuals will start adopting it. As Fleming puts it, 3D printing "is a disruptive technology of mammoth proportions, with effects on energy use, waste, customization, product availability, art, medicine, construction, the sciences, and of course manufacturing."

Thursday, March 27, 2014

Big Data for Dummies

What is Big Data: As per Wikipedia, "Big data is the term for a collection of data sets so large and complex that it becomes difficult to process using on-hand database management tools or traditional data processing applications. The challenges include capture, curation, storage, search, sharing, transfer, analysis and visualization". In 2001, industry analyst Doug Laney defined Big Data in terms of 3 Vs: high Volume, high Velocity and high Variety. Business Analytics firm SAS considers two additional factors: high Variability and high Complexity.

Where does Big Data Come From: Wikipedia says, "Data sets grow in size in part because they are increasingly being gathered by ubiquitous information-sensing mobile devices, aerial sensory technologies (remote sensing), software logs, cameras, microphones, radio-frequency identification readers, and wireless sensor networks." According to McKinsey, "The increasing volume and detail of information captured by enterprises, the rise of multimedia, social media, and the Internet of Things will fuel exponential growth in data for the foreseeable future."

Who works with Big Data: Again from Wikipedia, "Scientists regularly encounter limitations due to large data sets in many areas, including meteorology, genomics, connectomics, complex physics simulations, and biological and environmental research. The limitations also affect Internet search, finance and business informatics." Another category of Big Data users are law enforcement agencies across the world who have to work with multiple local databases containing different categories of information about various criminals and terrorists.

Why Big Data Matters: McKinsey maintains that "From the standpoint of competitiveness and the potential capture of value, all companies need to take big data seriously." SAS believes that organizations can analyze Big Data "to find answers that enable 1) cost reductions, 2) time reductions, 3) new product development and optimized offerings, and 4) smarter business decision making". They have given the example of UPS who started analyzing Big Data in the 1980s, long before the term was coined, and used it to achieve major savings.

How to work with Big Data: Since Big Data can't be processed by traditional database management tools or data processing applications, a new set of applications have evolved to specifically deal with Big Data. Some examples are Hadoop (by the Apache Foundation), MongoDB and Splunk. From a hardware point of view, practitioners of Big Data analytics prefer the faster and cheaper Direct-attached storage (DAS) over the traditional shared storage architectures such as Storage area network (SAN) and Network-attached storage (NAS).

Whether Big Data matters to You: Some companies claim that Big Data analysis is the hottest new practice in the field of BI today. McKinsey predicts that "By 2018, the United States alone could face a shortage of 140,000 to 190,000 people with deep analytical skills as well as 1.5 million managers and analysts with the know-how to use the analysis of big data to make effective decisions." Clearly, if you an IT employee at a technical or lower-to-middle management level, knowledge of Big Data analytics could help you in the future.

Wednesday, December 11, 2013

RoR Music Database Project

Finally, I've created a Rails + SQLite version of my favorite practice project - the Music Database. This one looks very different from my other (Perl, Python, PHP, ASP, ASPX) implementations of the project - as Ruby is an object-oriented language, I tried to model the application as closely as possible to real life. Usually I store the details of each song in a row of the database table, with the album details (Album Name, Year, Artist Name) being repeated for multiple songs. But here I made Album the primary model and Song a secondary one. So the user has to first create an album and then add multiple songs to it. Here are the steps I followed, once I had the design ready in my mind:

  rails new MusicDatabase
  cd MusicDatabase
  rails generate scaffold Album albumname:string albumartist:string albumyear:datetime
  rake db:migrate

Edit the file "config\routes.rb" to open "views\albums\index" by default, by adding the line:
  root :to => "albums#index"

rails generate model Song songname:string album:references
rake db:migrate
rails generate controller Songs index show new edit

Edit the file "controllers\song_controller.rb" to have the standard methods for showing, adding, editing and deleting songs

Edit the files under the "views\songs\" directory to have the standard forms for showing, adding, editing and deleting songs

In my case, because of the form code that I copied from the Rails tutorial, I also had to edit my Gemfile to include the line "gem 'dynamic_form'" and then do a "bundle install". And thus, I completed my Ruby on Rails "self test" by getting the Music Database project running successfully

Wednesday, December 4, 2013

Steps Taken to Revive Galaxy Tab 2 P3100

When my tab recently suffered a battery drainout issue, these are the steps I took to revive it:

Charge battery to 99%
Perform factory reset
Connect to Wi-Fi
Provide Samsung account settings
Provide Google account settings
Update Samsung apps
Power off
Insert SIM card and Micro SD card
Power on
Save GPRS settings
Install essential apps only (Clean Master, Facebook, Blogger, MyMail in my case)
Update stock Android and Samsung apps as needed
Add apps and widgets to home screen as needed

Friday, November 22, 2013

SOLVED: Rails with MySQL on Windows

For the last couple of days, I was struggling to get Rails to talk to MySQL on Windows. Though I was able to install the "mysql" gem, I got an error message when I tried to run the "rake db:create" command for creating the database tables needed for my model. Web searches revealed many detailed discussions on the problem, but no definite solution. Whatever approach I tried only resulted in a different error message. Finally, against the run of play (as cricket commentators would say), I was able to get things working. So here are the steps I followed, for the benefit of others who may be facing the same issue:

1. Install Ruby and Rails using the RailsInstaller - I used version 1.3, which provides Ruby 1.8.7 and Rails 3.0.7, along with other related packages like Bundler and DevKit

2. Install MySQL Community Server - I already had version 5.5.23

3. Install the mysql gem:

gem install mysql

4. Carefully read the message from the mysql gem installer - I got:

You've installed the binary version of mysql2. It was built using MySQL Connector/C version 6.0.2. It's recommended to use the exact same version to avoid potential issues.

At the time of building this gem, the necessary DLL files where available in the following download:

http://dev.mysql.com/get/Downloads/Connector-C/mysql-connector-c-noinstall-6.0.2-win32.zip/from/pick

And put lib\libmysql.dll file in your Ruby bin directory, for example C:\Ruby\bin

5. Download the exact same version of the MySQL C connector as mentioned in the message you see. Get the zip archive, not the MSI installer. Simply extract the "lib\libmysql.dll" file and put it in your "Ruby\bin" directory (you don't really need the rest of the C connector files).

6. Add a new line "gem mysql" to the Gem file of your Rails project.

7. Replace the (sqlite) contents of your config\database.yml file with:

development:
  adapter: mysql
  encoding: utf8
  database: blog_development
  pool: 5
  username: root
  password:
  socket: /tmp/mysql.sock

Now, when you run the "rake db:create" command, it should work without any issues. Even before that, you can test the MySQL connectivity using irb (the Interactive Ruby shell):

C:\Documents and Settings\User>irb
irb(main):001:0> require "Rubygems"
=> true
irb(main):002:0> require "mysql"
=> true
irb(main):003:0> Mysql.connect("localhost", "root", "", "phpwork")
=> #<Mysql:0x2cdfca8>
irb(main):004:0>

Tuesday, November 19, 2013

Hi, Ruby!

In the last couple of months, I've more or less completed my target of revising the basic concepts of Perl, Python and PHP. So I decided to check out a relatively newer member of the Open Source Programming Languages family. Ruby, along with the Rails framework that is based on it, has captured the imagination of web developers worldwide.

Ruby is said to be a truly object-oriented language that is easy to learn, and has rich libraries that are easy to extend. The Rails framework includes everything that you would need to create a database-driven web application using the MVC pattern. As it needs minimal configuration, you can develop applications faster than with other frameworks.

At least that's what the tutorials say. Today I'll put these statements to the test by (a) learning the basics of Ruby, (b) installing Ruby, (c) running a Hello World program, (d) running a simple Embedded Ruby program, (e) installing and testing the Rails framework, and (f) creating a Rails + MySQL version of my good ol' music database project.

Note that I'll follow the "Ruby on Rails Introduction" tutorial on tutorialspoint.com, which was the first Ruby tutorial I found, and use their sample code. After going through the first few pages of this tutorial, I installed Ruby from http://rubyinstaller.org/

I then tested the Hello World program and the simple Embedded Ruby program from the tutorial. Next, I tried to install the Rails framework using the "gem" utility that comes with Ruby. This utility can be used to install Ruby packages, called "Gems".

But I ran into an error during the Rails installation, due to the absence of the necessary build tools for the 'atomic' native gem. To get around this issue, I had to first install the Ruby Developer Kit. I downloaded the installer from the same URL as Ruby - http://rubyinstaller.org/ - and then followed the step by step installation instructions given by http://learnwebtutorials.com/.

(Note: An easier way is to visit the RailsInstaller website and install Ruby, Rails and many other packages at one go)

Next I had to create a demo Rails project as given in the tutorial, run the WEBrick web server that is bundled with Rails, and test the demo page from my browser. Note that the right command to create a demo Rails project is "rails new demo" and not "rails demo" as given in the tutorial. Also, the right commands to start the WEBrick web server are "cd demo" followed by "rails server". In both these cases, the commands given in the tutorialspoint.com web tutorial seem to be outdated ones.

Thus I've completed 5 of my 6 objectives for today, viz.: (a) learnt the basics of Ruby, (b) installed Ruby, (c) ran a Ruby Hello World program, (d) ran a simple Embedded Ruby program, and (e) installed and tested the Rails framework. Creating a Rails + MySQL version of my music database project will take more study and, quite possibly, a lot of trial and error. So I'll try and complete that objective later this week. Meanwhile let me search for some more good Ruby tutorials on the Web.

Friday, November 1, 2013

Excel output from Perl script

In an earlier post, I had explained how to output some tabular data from a PHP script into an Excel sheet using PHPExcel. Today, I shall explain the Perl equivalent, using a module named Spreadsheet::WriteExcel. This module can be easily installed using PPM. By looking at the documentation and the code examples, we can quickly rustle up our own Perl code to create an Excel sheet containing the songs data from our famous music database.

    # Create a new Excel workbook
    my $workbook = Spreadsheet::WriteExcel->new('music_list.xls');
    
    # Add a worksheet
    my $worksheet = $workbook->add_worksheet();
    
    #  Add and define a format for title row
    my $format = $workbook->add_format(); # Add a format
    $format->set_bold();
    $format->set_color('black');
    my $slate_grey = $workbook->set_custom_color(40, '#6D7B8D'); # slate grey color
    $format->set_bg_color($slate_grey);
    $format->set_align('center');
    
    # Write the Excel title row using the new format
    $worksheet->write(0, 0, "Song Title", $format);
    $worksheet->write(0, 1, "Artist Name", $format);
    $worksheet->write(0, 2, "Album Title", $format);
    $worksheet->write(0, 3, "Year Title", $format);
    
    # Increase the column width for clarity
    $worksheet->set_column('A:D', 25);

    # Define the format for the cell borders
    my $cell_border_format = $workbook->add_format(border => 1);

    if ($row_count == 0) {
        $worksheet->write(1, 0, "No records");
    } else {
        for (my $i=0; $i < $row_count; $i++) {
            # Write the actual table contents and also set the cell borders
            $worksheet->write($i+1, 0, $excel_content->{"a" . $i}, $cell_border_format);
            $worksheet->write($i+1, 1, $excel_content->{"b" . $i}, $cell_border_format);
            $worksheet->write($i+1, 2, $excel_content->{"c" . $i}, $cell_border_format);
            $worksheet->write($i+1, 3, $excel_content->{"d" . $i}, $cell_border_format);
        }
    }

One catch is that the Spreadsheet::WriteExcel module cannot overwrite an existing Excel file (by design, to avoid accidental data loss). So let us put in a bit of code to delete the existing file, if any.

    # Check if Excel file already exists
    if (-e 'music_list.xls') {
        # Try and delete old Excel file
        if (unlink('music_list.xls') == 0) {
            # Show error message if delete fails
            print "Old Excel file could not be deleted";

            # Show the HTML footers and exit
            &tail($dbh);
            exit(0);
        }
    }

Tuesday, October 22, 2013

Object-Oriented Programming in Perl

My first and last brush with Perl OO programming was back in 2008. I was in the Netherlands with a couple of colleagues, getting "KT" for a set of small e-commerce applications whose support was being outsourced to India. We were horrified to see that the code was object-oriented, with many layers of inheritance, which made it extremely difficult to learn. As part of the Knowledge Transfer, we were asked to create installers and use them to get the applications running on a new server. But we would inevitably run into errors, which would send us hunting from file to file and class to class to try and find the ultimate parent class. Even the Dutch team that had been supporting the code for a few years did not know the nitty-gritty of the inheritance - they  had only learnt enough to support the applications on a day to day basis.

Having learnt C++ and Java earlier, I had realized then that Perl is not the best language for object-oriented programming. But the fact that it supports OO means that you need to know the basics, just in case you face a situation like I did. There are many online tutorials available on the subject but the best ones come straight from the horse's mouth, viz: the perlootut tutorial and  the perlobj language reference. After going through these, you may feel confident enough to create your own class and then test it with a simple script. I first created a very basic class called Muzak to represent the songs from my music collection. Each Muzak object has up to 4 attributes - a song name (mandatory), artist name, album title and year. It has 1 method - artist() - that returns the artist name. I put the class in a Perl module called Muzak.

Muzak.pm

package Muzak;

# Constructor
sub new {
    my $class = shift;
    my ( $song, $artist, $album, $year ) = @_;
    
    if ($song eq "") {
        die "Muzak object requires at least Song Name attribute";
    }

    my $self = bless {
        song => $song,
        artist => $artist,
        album => $album,
        year => $year,
    }, $class;

    return $self;
}

# Method: Get artist
sub artist {
    my $self = shift;
    return $self->{artist};
}

1;

Note that the "1;" at the end of the .pm file is critical. If you miss it, the Perl interpreter will throw an error while testing the script, which would look like "Muzak.pm did not return a true value at test_muzak.pl line 6". Also note that the check for non-blank song name is also not mandatory to create a working class - it is just a logical check that I added.

test_muzak.pl

use Muzak;
use feature qw(say);

# Create new Muzak object with all 4 paramaters
my $muzak1 = Muzak->new('Aqualung', 'Jethro Tull', 'Aqualung', '1971');

# Print the song artist name
say "Artist1 is " . $muzak1->artist();

# Create new Muzak object with only 1 parameter
my $muzak2 = Muzak->new('Bouree');

# Try printing the song artist name
say "Artist2 is " . $muzak2->artist();

# Try creating new Muzak object with 0 parameters
my $muzak3 = Muzak->new();

# Try printing the song artist name
say "Artist3 is " . $muzak3->artist();

There's a lot more to explore in Perl OO programming. I can write code that is much more complicated, like those Dutch applications (which were created, if I remember correctly, by a UK firm). More importantly, I can write code that is more useful than just playing around with song details. But that's another day, another class, another blog post

Friday, October 18, 2013

Excel output from PHP script

Let's say you've written a PHP script that queries a data source (say a MySQL database) and displays the output in the browser. Now you want to export this data to an Excel sheet that the user can print or process further. What are the different ways of doing this?

The first way I ever learned was to simply set the PHP content type header, like "Content-type: application/vnd.ms-excel; name='excel'". This prompts the user to open or save an Excel sheet, which would contain our tabular content. But in this method, you would not have any control over the formatting of the Excel sheet, such as borders, fonts, colors, etc.

If you want to generate a well-formatted Excel sheet, you can use the PHP library called PHPExcel, which can be downloaded from here. Just copy part of the zip file contents (see the "install.txt" file) to a sub-directory on your web server document root and you can get going. It is easy to save your tabular content to an Excel file on the server, using PHPExcel.

The code required for creating the Excel file is fairly simple, and you can put it together by looking at the examples given in the PHPExcel zip file. If you get stuck, say on a formatting issue, you can always google the solution. PHPExcel seems to be quite popular and so, more likely than not, your question would have been answered on one of the coding forums.

Here is my code for saving my Music Database List content as an Excel file:

/* Include PHPExcel */
require_once '../../Classes/PHPExcel.php';

// Create new PHPExcel object
$objPHPExcel = new PHPExcel();

// Set document properties
$objPHPExcel->getProperties()->setCreator("Ajay Ramakrishnan")
    ->setLastModifiedBy("Ajay Ramakrishnan")
    ->setTitle("Music Database List")
    ->setSubject("Music Database List")
    ->setDescription("Music Database List, generated using PHPExcel.")
    ->setKeywords("Music Database PHPExcel")
    ->setCategory("Music Database List");

// Add title row to Excel file
$objPHPExcel->setActiveSheetIndex(0)
    ->setCellValue('A1', $a[0])
    ->setCellValue('B1', $b[0])
    ->setCellValue('C1', $c[0])
    ->setCellValue('D1', $d[0]);

// Set the title row font to bold and background color to light slate grey
$header_range = "A1:D1";
$objPHPExcel->getActiveSheet()->getStyle($header_range)->getFont()->setBold(true);
$bgColorArray = array(
                    'fill' => array(
                        'type' => PHPExcel_Style_Fill::FILL_SOLID,
                        'color' => array('rgb' => '6D7B8D')
                    )
                );
$objPHPExcel->getActiveSheet()->getStyle($header_range)->applyFromArray($bgColorArray);

// Loop through the existing data rows
for ($i=2; $i <= $row_count; $i++) {
    $objPHPExcel->setActiveSheetIndex(0)
        ->setCellValue('A' . $i, $a[$i-1])
        ->setCellValue('B' . $i, $b[$i-1])
        ->setCellValue('C' . $i, $c[$i-1])
        ->setCellValue('D' . $i, $d[$i-1]);
    }

// Resize the columns
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);
$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setAutoSize(true);

// Set the border for all the non-empty cells
$i = $i - 1;
$styleArray = array(
        'borders' => array(
            'left' => array(
                'style' => PHPExcel_Style_Border::BORDER_THIN,
            ),
            'right' => array(
                'style' => PHPExcel_Style_Border::BORDER_THIN,
            ),
            'top' => array(
                'style' => PHPExcel_Style_Border::BORDER_THIN,
            ),
            'bottom' => array(
                'style' => PHPExcel_Style_Border::BORDER_THIN,
            ),
        ),
    );
$objPHPExcel->getActiveSheet()->getStyle('A1:D' . $i)->applyFromArray($styleArray, False);

// Rename worksheet
$objPHPExcel->getActiveSheet()->setTitle('Music_DB_List');

// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$objPHPExcel->setActiveSheetIndex(0);

// Save Excel 2007 file
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));

Friday, October 4, 2013

Parsing HTML pages using Mojo::DOM

After my previous post, I successfully wrote a Perl script to parse an XML file that I had retrieved (from an RSS feed) using Perl and cURL. XML parsing and manipulation is simple enough, if you use the XML::Simple module. But what if the web page you are retrieving with Perl and cURL is an HTML page? And what if you have to make some changes to the HTML code before you render it in your browser? This would require a module that allows you to access individual DOM elements and even modify them. That is how I learned about the Mojo::DOM module, which is part of a package called Mojolicious that you can get on CPAN. Mojolicious calls itself "a next generation web framework for the Perl programming language". You can learn more on their website. Installing it on your machine is simple enough, using the command:

ppm install Mojolicious

Meanwhile, I decided to retrieve a particular web site's home page, make a couple of changes in the code, and render the same page in my browser. The changes were: 1) I would remove their Google analytics code, which was enclosed in a <script> tag pair, and (2) I would ensure that all references to stylesheets and images are prefixed with the URL of that particular web site, so that the web page in my browser appears identical to the original. Here are some of the interesting things that I learned about Mojo::DOM while completing this script, explained usingcode snippets:

$dom = Mojo::DOM->new->xml(0)->parse($response_body);

* Here I have created a new Mojo::DOM object, by parsing the response from my cURL call. The xml(0) is to tell Mojo::DOM to use HTML mode instead of XML mode

my @links = $domref->find('[href]')->each;

* Here I am telling Mojo::DOM to return all HTML tags having a 'href' attribute. I can then go through the @links array using foreach()

$_->attr(href => $linkhref);

* Here I am replacing the value of the 'href' attribute of a particular tag to a string $linkhref, which is actually a modified version of the original value

$_->replace_content($styletext);

* Here I am replacing the entire contents of a particular <style> tag pair with a modified version of the original contents. Interestingly the replace_content function has a bug - it replaces all instances of double quotes with the HTML entity code equivalent '&quot;', which may cause problems in the HTML output. So you need to change the HTML entity code back to double quotes before the end of the script

say "$domref";

* Here I am outputting the modified HTML code to the browser. For those who are not aware, say is the Perl equivalent of Java's println. It saves you the trouble of appending a "\n" at the end of every print statement. Using say requires the line "use feature qw(say);" along with your module declarations

Wednesday, September 25, 2013

Perl & Curl have my Head in a Whirl

I had recently written a PHP script to read a URL using cURL. Today, I thought I'd convert it into a Perl script. PHP has built in support for cURL, using functions like curl_init(), curl_exec() and curl_close(). In Perl, you have to install and use a CPAN module called WWW::Curl. At first glance, it seemed a simple task. But the problem is that on Windows, you can't simply download the module using the usual command "cpan WWW::Curl". You have to download the source file package and manually install the module. For this, you also need the source package of the cURL libraries. You can't just download and use the "curl" binary, the way you would if you just wanted to run the "curl" command from the DOS prompt. Anyway, here are the steps to follow...

* Ensure a C compiler is installed and available on the PATH. If not, get GCC by installing the Perl MinGW package:

ppm install MinGW

* Download the latest cURL libraries for mingw from the cURL website:

http://curl.haxx.se/download.html

* Unzip the folder somewhere (say C:\curl-7.32.0)

* Download the CPAN module WWW::CURL from CPAN:

http://search.cpan.org/~szbalint/WWW-Curl-4.15/

* Unizp the folder somewhere (say on your Desktop). Edit the Makefile.PL, making the following changes:

1. Comment the lines following the comment "This is a hack."

2. Change the "my @includes..." line to:

my @includes = qw(C://curl-7.32.0//include);

3. Change the "my ($cflags..." line to:

my ($cflags,$lflags, $ldflags) = ('-I"C://curl-7.32.0//include"','-L"C://curl-7.32.0//lib"','-lcurldll -lcurl');

 4. Change the "open(H_IN, "-|", "cpp"" line to:

my $cmd = "cpp $curl_h";
open(H_IN, $cmd) and $has_cpp++;

5. Change the "'LIBS'         => "$ldflags $lflags..." line to:

'LIBS'         => "$lflags $ldflags",        # e.g., '-lm'

* Note that this last change is very important, or else you'll spend 2 hours debugging a linker error - as I unfortunately did

* Run the command:

perl Makefile.PL

* Run the command:

dmake

* Run the command:

dmake install

* Try running your test Perl script. If you get an error, usually as a popup, that says "The procedure entry point ERR_remove_thread_state...", just add "C:\curl-7.32.0\bin" at the beginning of your PATH. This error occurs when your system picks up a wrong version of "libeay32.dll", probably from your installation of SSL VPN or some other application

* Another issue you could face is that your Perl script works fine from the command line but when you run it in Apache, you get an internal server error while loading the WWW::Curl Perl Module, which you can confirm by checking the Apache error log. This is because the "C:\curl-7.32.0\lib" folder is not in your PATH, and needs to be added

Now you're ready to go - write that Perl program to read a URL using cURL. Thanks to Niranjan Prithivraj, whose post was partially helpful during my installation. Hope this post would be useful to someone else, just like Niranjan's post helped me

Saturday, September 14, 2013

Defeat Browser Hijackers!

Ever faced a situation where you were careless while installing some software (mostly a free utility) and your browser got hijacked by ask.com? It not only changes your home page and default search provider, it also prevents you from changing the home page back to what you want. So, even if you change the home page from the "Settings" menu, you'll find that "search.ask.com" opens up the next time your start the browser. After an hour of effort, I finally found a permanent fix... Go to "Add/Remove Programs" and uninstall the application called "Movies Toolbar for Chrome (Dist. by Bandoo Media, Inc.)". Then go to your Chrome settings and change the home page once again, this time for good

Thursday, September 12, 2013

A Small XSLTip

While making some minor changes to my website recently, I encountered an interesting problem - that of displaying a URL on an XML-XSLT web page. But before I get into the problem and the solution, time for some introductions for the benefit of newbies...

XML: Extensible Markup Language (XML) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. It is a textual data format with strong Unicode support (more on Wikipedia)

XSLT: Extensible Stylesheet Language Transformations (XSLT ) is a language for transforming XML documents into other XML documents, or other objects such as HTML, plain text or XSL Formatting Objects for processing into other formats (more on Wikipedia)

My XML code was as follows:

 <lines>
  <line name="Company" linetext="Capgemini Consulting India Pvt. Ltd." />
  <line name="Description" linetext="Capgemini is a global leader in consulting, technology, outsourcing and local professional services. It employs more than 83,000 employees globally." />
  <line name="My tenure" linetext="2004-2012" />
  <line name="My role" linetext="Manager" />
  <line name="Comments" linetext="Cap was my first big break and the career growth I got was phenomenal. Indeed, the Capgemini stint totally changed me at a personal level." />
  <line name="Website" linetext="http://in.capgemini.com" />
 </lines>

The challenge was to ensure that the website name appeared as a valid URL, whereas the other lines appeared as plain text. This meant that the highlighted "line" with the "name" of "Website" had to be processed in a different way from all the other "lines". After some web searching, I came up with the following XSLT code for processing the "line" tags:

 <xsl:template match="line">
  <tr>
   <td width="30%" align="right" valign="middle" class="itemtext">
    <b><xsl:value-of select="@name" />:</b>
   </td>
   <td width="70%" align="left" valign="middle" class="itemtext">
    <xsl:if test="@name='Website'">
     <a href="{@linetext}"> 
      <xsl:value-of select="@linetext"/>
     </a>
    </xsl:if>
    <xsl:if test="@name!='Website'">
     <xsl:value-of select="@linetext" />
    </xsl:if>
   </td>
  </tr>
  <tr>
   <td colspan="2" align="center" valign="middle">&#160;</td>
  </tr>
 </xsl:template>

Hopefully the above XSLT code is self-explanatory. If not, feel free to contact me for a discussion

Wednesday, August 14, 2013

Tips on Converting PHP to Perl-CGI

The story today is very similar to yesterday's. Last month I created a new butterfly identification page for my personal website, using PHP and SQLite. By choosing some colors and patterns, newbies (in the butterfly field) can identify any butterflies they may have seen in the field. The page worked well on my desktop but when I uploaded it to Tripod, I realized that they support only Perl and not PHP. So I decided to convert the PHP page to Perl, without having to recode it from scratch. I started by making a copy of the ".php" file and renaming it to ".cgi". Then I made the below changes to convert the PHP code to Perl. Hope these tips would be useful to someone who reads this post.

* Added the Perl shebang line at the top of the page
* Added the standard line to print the content type
* Enclosed all other HTML code within multi-line prints
* Replaced all instances of the PHP "echo" with the Perl "print"
* Replaced the database connection PHP code with the corresponding Perl code
* Replaced the database query PHP code with the corresponding Perl code
* Added a subroutine for getting the CGI parameters, something that PHP automatically did
* Replaced the PHP built-in hash "%POST" to the hash "%form" created by my subroutine
* Replaced the square brackets used for PHP hashes with the curly brackets used in Perl
* Removed the single or double quotes that were used to reference the hash values in PHP
* Replaced the not equal to operator "<>" of PHP with the Perl equivalent "ne"

P.S.: After all that hard work, I found that Tripod does not support the use of DBI.pm. So finally I had to replace the dynamic butterfly identification page with an XML-XSLT page where the readers have to look at a table giving colors and patterns to try and figure out which butterfly they had seen. Well, such is life!

Tuesday, August 13, 2013

Tips on Converting Python-CGI to Perl-CGI

Last month I created a new feedback page for my personal website, using Python. It worked well on my desktop but when I uploaded it to Tripod, I realized that they support only Perl and not Python. So I decided to convert the feedback page to Perl, without having to recode it from scratch. The groundwork for this took some time, as I had to install Active Perl and brush up my Perl knowledge by tweaking a few old Perl-CGI scripts. Today I created a copy of the CGI script and made the below changes to convert it from Python to Perl. Hope these tips would be useful to someone who reads this post.

* Converted the shebang line from #!/Python27/python to #!/Perl/bin/perl
* Added a semi-colon after every line of Python (now Perl) code
* Added a $ sign before every Python (now Perl) scalar variable
* Converted the multi-line prints from Python format (print """) to Perl format (print <<HTML)
* Removed the Python import line for "sys"
* Removed the Python import line for "time". Used Perl's localtime() function to get date and time
* Removed the Python import line for "cgi". Used a downloaded Perl code snippet to get the CGI parameters, choosing  one that takes care of both GET and POST parameters
* Converted the Python "if-elif-else" syntax to the equivalent Perl "if-elsif-else" syntax
* Converted the Python "try-except" code for opening a text file to the normal Perl file opening code, as Perl does not currently support "try-except"
* Converted the single-line file open and read code of Python to the equivalent Perl code
* Converted the Python syntax [filename.write("abc")] for writing to text file to the equivalent Perl syntax [print FILENAME "abc"]
* Replaced Python's text concatenation operator "+" with the equivalent Perl operator "."
* Removed Python's str() function, as Perl automatically takes care of converting variables based on the context
* Ensured use of "eq" operator instead of "==" operator in "if" conditions involving string variables

Tuesday, July 30, 2013

Introduction to SharePoint

A part of our Projects team has been spun off into a SharePoint team, which will adapt and implement a particular CRM template for Indian as well as overseas customers. Since our architect is also a part of this new team, he was able to provide some Web links to help me understand what SharePoint is all about

Microsoft SharePoint is a Web application platform. Simply put, it is a tool to store, to manage and to retrieve information. This information could be text or MS Office documents or other files, like videos. The main strength of SharePoint is that even non-technical users can use it as well as develop applications using it

Initially, SharePoint was used for content management and document management on Intranets but recent versions are much more powerful. You can use Sites to store and manage information, and share it on the Intranet or Internet. You can use Communities to collaborate with colleagues. You can use Content management, including integration with your existing Microsoft Office documents. Search allows you to retrieve information quickly and to find people within your organization. Insights allow you to effectively obtain information stored in a different repository, within a certain useful context. SharePoint enables no-code integration of data, documents and processes to create Composite applications

The most basic element in SharePoint is an Item (calendar entry, task, contact) or a Document (Word, Excel, PDF). Both Items and Documents can have metadata associated with them. They can be arranged using Folders

Items are stored in Lists while Documents are stored in Libraries. A List or Library uses Views to display information. VIews depend on context but the standard view is as rows and columns. Each row represents an Item or Document while its metadata is displayed in the columns. Metadata can be grouped into Content Types

Each List or Library is part of a Site, which is a container for data. Sites can be Team Sites, Project Sites or Internet Web Sites. They can be arranged in hierarchies and collected into Site Collections with a Root Site at the top and common site settings. Each Site has a default page (Homepage), along with various other Pages

Sites are viewed using a web browser. Hence there are Web Applications, which can contain several Sites or Site Collections and are hosted on Web Servers. Multiple SharePoint servers can be grouped into a Sharepoint Farm

In short, SharePoint provides a solution to all your information management needs with a secure and remote access. Andreas Glaser's website provides some good SharePoint tutorials that are very useful for beginners. Note that the content of this post has been adapted from his pages, and the SharePoint Wikipedia page