Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Saturday, August 18, 2012

edX: College-quality computer science education


A soft  drum roll can be heard throughout the realm. It slowly grows louder as a herald appears on your screen. The Announcer sounds her trumpet, clears her throat. Drums stop and she exclaims:

    - "The blog heretofore known as 'Damien Learns Perl' is now to be referred to as 'Damien Learns Programming'. This broader title means greater variety and more life (or so it is hoped) to the speculations and musings of an eternal student of computer programming."

Crowd cheers.

    - "No camel was hurt in this process. Go home and spread the good word."

The herald lets out a content sigh then disappears in a puff.


-------

I feel like writing about other topics than just Perl. I contemplated starting a new blog for a few seconds but it made more sense to give a new direction to this site.


Evolve or become irrelevant

This could be the motto of the computing/computer science/IT industry.
Tools keep popping out of thin air, new programming languages are invented, operating systems evolve rapidly, new devices appear that can be programmed, etc.
Those changes answer people's ever demanding requests.

You want to keep up but how to go about updating your skills?

The best motivator is to build something that you need. When my wife became pregnant, I started to build a "Baby Tracker" app to learn C++ and to keep tab on the baby's vaccination schedule, teeth growth, stool color, etc. I eventually abandoned the project because (believe it or not) taking actual care of my first daughter became a higher priority. By the time I had bandwidth again, the "baby tracker" need was moot.
Having a purpose makes you want to keep learning and carry on after you have hit a few too many obstacles.

This self-learning path resembles an obstacle course: the end line is visible but you first have to jump over all those hurdles to attain it.

Another way to learn new skills is through online education. Several sites already exist that put emphasis on learning in a fun way:

  • Codecademy (for beginning web programmers)
  • Khan Academy (originally created to teach mathematics but now proposing many subjects, including computer science)
  • Memrise (to help you learn vocabulary for new languages, including programming languages)
  • LCodeTHW (despite its name, offers a great way to start learning about programming)
  • etc.
Those are quality sites and I encourage you to visit them if you are looking for a first acquaintance with a new topic.
However, I want to share here something that I am truly excited about: online computer science college-quality education for free. Back in 2000 I got involved in the PEOI project whose mission was to bring professional education online to the masses (provided access to an internet link). The site still exists but the design has not evolved since its creation and course content was created by volunteers. Its noble goal though has found a champion today: edX.


Get a quality education

edX is a joint online interactive educational project from MIT, Berkeley and Harvard University, some of the best US universities. You can earn certificates along with knowledge. New classes are about to start this fall and include:

So go forth and upgrade your computing education. 
Evolve and ride the relevance wave!



edX: College-quality computer science education


A soft  drum roll can be heard throughout the realm. It slowly grows louder as a herald appears on your screen. The Announcer sounds her trumpet, clears her throat. Drums stop and she exclaims:

    - "The blog heretofore known as 'Damien Learns Perl' is now to be referred to as 'Damien Learns Programming'. This broader title means greater variety and more life (or so it is hoped) to the speculations and musings of an eternal student of computer programming."

Crowd cheers.

    - "No camel was hurt in this process. Go home and spread the good word."

The herald lets out a content sigh then disappears in a puff.


-------

I feel like writing about other topics than just Perl. I contemplated starting a new blog for a few seconds but it made more sense to give a new direction to this site.


Evolve or become irrelevant

This could be the motto of the computing/computer science/IT industry.
Tools keep popping out of thin air, new programming languages are invented, operating systems evolve rapidly, new devices appear that can be programmed, etc.
Those changes answer people's ever demanding requests.

You want to keep up but how to go about updating your skills?

The best motivator is to build something that you need. When my wife became pregnant, I started to build a "Baby Tracker" app to learn C++ and to keep tab on the baby's vaccination schedule, teeth growth, stool color, etc. I eventually abandoned the project because (believe it or not) taking actual care of my first daughter became a higher priority. By the time I had bandwidth again, the "baby tracker" need was moot.
Having a purpose makes you want to keep learning and carry on after you have hit a few too many obstacles.

This self-learning path resembles an obstacle course: the end line is visible but you first have to jump over all those hurdles to attain it.

Another way to learn new skills is through online education. Several sites already exist that put emphasis on learning in a fun way:

  • Codecademy (for beginning web programmers)
  • Khan Academy (originally created to teach mathematics but now proposing many subjects, including computer science)
  • Memrise (to help you learn vocabulary for new languages, including programming languages)
  • LCodeTHW (despite its name, offers a great way to start learning about programming)
  • etc.
Those are quality sites and I encourage you to visit them if you are looking for a first acquaintance with a new topic.
However, I want to share here something that I am truly excited about: online computer science college-quality education for free. Back in 2000 I got involved in the PEOI project whose mission was to bring professional education online to the masses (provided access to an internet link). The site still exists but the design has not evolved since its creation and course content was created by volunteers. Its noble goal though has found a champion today: edX.


Get a quality education

edX is a joint online interactive educational project from MIT, Berkeley and Harvard University, some of the best US universities. You can earn certificates along with knowledge. New classes are about to start this fall and include:

So go forth and upgrade your computing education. 
Evolve and ride the relevance wave!



Monday, March 30, 2009

wxPerl: adding a GUI to the twitter script (part 1)

So far, I've only dabbled with Perl console applications. There is nothing wrong about them, and if you come from the Linux world you are probably quite familiar with running a program from the command line.
The standard Windows users however may not be as comfortable around CLI (Command Line interface) apps as they are around Graphical User Interface (GUI) programs.

I. Describing the need
  • The first need is to provide a simple GUI interface. I am tired of opening a shell, going to the script directory and typing something like:
    perl twit.pl -s "I am so lazy" -a
    every time I want to update my Twitter and Identica messages. I just want to type my text and click on a "Send" button.
  • Monitor the number of characters being typed so that it doesn't go over the 140-character limit.
  • Provide a standalone application that my mom would find easy to use.
  • I would also like to have the possibility of removing the last post for both Twitter and Identica, in case of a spelling mistake detected after sending the update for example.
II. Technical choices
From using Padre, wxPerl is already installed on my system in the form of the Wx module. I'll hence be using it (and it will help me understand the innards of Padre as a bonus).
Other options for GUI librairies would be Tk and Win32::GUI (the last one for Windows only obviously).

To build the standalone application, I have Perl2Exe in mind. However, I have not done much research on the subject yet. If you want to tell about your favorite choice in the comments section, I'll select from the list (or I might open a poll). Documention for the Wx module also mentions PAR and Perl2App.

II. Design the UI
Here's the list of needed elements:
  • Text box to enter up to 140 characters (2 lines of 70?)
  • 2 check boxes for twitter
  • 2 check boxes for identica
  • 1 "Send" button
  • 1 "Delete Last" button
  • 1 menu item to create/open login file
Let's try to lay it out in Paint first:

Drawing of the GUI
  • Errors will be displayed through message boxes.
  • In the Login menu, choices will be:
    - "Select Login File": window opens asking for file location. Default location used at start up.
    Parses selected file and displays error message if format not recognized.
    Stores login + password for whatever social website is recognized
    Back in the main form, Twitter and/or Identica boxes are greyed out if no login is found.
    No login/password encryption planned for the moment
    - "Edit Login File" : window first pops up asking for login file location.
    Allows the login file to be edited from the application.
  • The Twitter and Identi.ca boxes of the "Status" area will both be checked by default (if logins are provided)
  • Not sure how I'm going to implement the "Delete Last" functionality yet. There is a destroy_status() method in the Net::Twitter module. I'll have to read the doc.
Reviewing the design, I am wondering about the double Twitter and Identica checkboxes. Wouldn't one set be enough? Unless each set is updated in parallel: setting the top (resp. bottom) Twitter box would also set the bottom (resp. top) Twitter box. What's your take on this?

I'd like to use Test Driven Development for this little project but I have no experience in either TDD or writing tests for Perl applications.

For TDD, I know that you must first write a test, check that it fails, code so that the test succeeds then write the next test. Once some tests are written and pass, you can improve the program's code knowing that you have a test suite ready to check that all the features still work. That's about the extent of my knowledge on this subject but it sounds like fun :)

Concerning the tests themselves, I've read through Modern Perl Book's recent posts on testing but it hasn't sunk in with me yet. I guess I'll have to start by looking into this.

Larry Wall's quote of the day:
"The whole intent of Perl 5's module system was to encourage the growth of Perl culture rather than the Perl core."


wxPerl: adding a GUI to the twitter script (part 1)

So far, I've only dabbled with Perl console applications. There is nothing wrong about them, and if you come from the Linux world you are probably quite familiar with running a program from the command line.
The standard Windows users however may not be as comfortable around CLI (Command Line interface) apps as they are around Graphical User Interface (GUI) programs.

I. Describing the need
  • The first need is to provide a simple GUI interface. I am tired of opening a shell, going to the script directory and typing something like:
    perl twit.pl -s "I am so lazy" -a
    every time I want to update my Twitter and Identica messages. I just want to type my text and click on a "Send" button.
  • Monitor the number of characters being typed so that it doesn't go over the 140-character limit.
  • Provide a standalone application that my mom would find easy to use.
  • I would also like to have the possibility of removing the last post for both Twitter and Identica, in case of a spelling mistake detected after sending the update for example.
II. Technical choices
From using Padre, wxPerl is already installed on my system in the form of the Wx module. I'll hence be using it (and it will help me understand the innards of Padre as a bonus).
Other options for GUI librairies would be Tk and Win32::GUI (the last one for Windows only obviously).

To build the standalone application, I have Perl2Exe in mind. However, I have not done much research on the subject yet. If you want to tell about your favorite choice in the comments section, I'll select from the list (or I might open a poll). Documention for the Wx module also mentions PAR and Perl2App.

II. Design the UI
Here's the list of needed elements:
  • Text box to enter up to 140 characters (2 lines of 70?)
  • 2 check boxes for twitter
  • 2 check boxes for identica
  • 1 "Send" button
  • 1 "Delete Last" button
  • 1 menu item to create/open login file
Let's try to lay it out in Paint first:

Drawing of the GUI
  • Errors will be displayed through message boxes.
  • In the Login menu, choices will be:
    - "Select Login File": window opens asking for file location. Default location used at start up.
    Parses selected file and displays error message if format not recognized.
    Stores login + password for whatever social website is recognized
    Back in the main form, Twitter and/or Identica boxes are greyed out if no login is found.
    No login/password encryption planned for the moment
    - "Edit Login File" : window first pops up asking for login file location.
    Allows the login file to be edited from the application.
  • The Twitter and Identi.ca boxes of the "Status" area will both be checked by default (if logins are provided)
  • Not sure how I'm going to implement the "Delete Last" functionality yet. There is a destroy_status() method in the Net::Twitter module. I'll have to read the doc.
Reviewing the design, I am wondering about the double Twitter and Identica checkboxes. Wouldn't one set be enough? Unless each set is updated in parallel: setting the top (resp. bottom) Twitter box would also set the bottom (resp. top) Twitter box. What's your take on this?

I'd like to use Test Driven Development for this little project but I have no experience in either TDD or writing tests for Perl applications.

For TDD, I know that you must first write a test, check that it fails, code so that the test succeeds then write the next test. Once some tests are written and pass, you can improve the program's code knowing that you have a test suite ready to check that all the features still work. That's about the extent of my knowledge on this subject but it sounds like fun :)

Concerning the tests themselves, I've read through Modern Perl Book's recent posts on testing but it hasn't sunk in with me yet. I guess I'll have to start by looking into this.

Larry Wall's quote of the day:
"The whole intent of Perl 5's module system was to encourage the growth of Perl culture rather than the Perl core."


Saturday, February 28, 2009

Improving the twit perl script

As I spent some time on twit.pl v0.2.0, I also tried to improve on the Perl template for new scripts.

New Perl that I learned
Today, I'll try to explain the new concepts first and then show the code.
  • "$0": This is dollar-zero. It is a special Perl variable to indicate the name of the file containing the perl script being executed
  • The x operator repeats a string pattern.
    print "*" x 10; and print "**********"; are equivalent
  • defined will return false if a variable is undef and true if it has a value.
  • @ARGV is a reserved Perl array that contains the list of arguments passed on the command line.
    Help if (@ARGV == 0); will call the Help subroutine if the list of arguments is empty, i.e. if you just type "perl twit.pl" at the command line.
    Note that checking @ARGV must be performed before the call to GetOptions which will empty the argument list.
  • You can tell the GetOption procedure to directly call a subroutine when a specific argument is passed at the command line. See for example "version" => \&Version. When -v or --version is added after the script name, you will see the version number of the script and exit the program.
twit_0_2_0.pl
To use version 0.2.0, you have to add -t (for twitter), -i (for identica) or -a (for both, also works if you choose -t -i) to the command line.

#!/usr/bin/perl
use 5.10.0; # To be able to use "say" function
use strict; # Pragma to add restrictions to Perl rules
use warnings; # Pragma to add warnings at compile and run-time
use Getopt::Long; # To parse the command line
use Net::Twitter; # API to twitter.com and identi.ca

my $PROG_NAME = $0; # $0 contains the name of the file containing the Perl script being executed
my $VERSION = "v0.2.0";
my $VersionDate = "February 21st 2009";

# ------------------------------------------------------------------------------
# Name : Help
# Comment : displays list of available options
# Input : no argument to command line or "-h" or "--help"
# Output : help screen and exit program
# ------------------------------------------------------------------------------
sub Help {
print "
Usage:
perl $PROG_NAME [-options]

Options:
-a, --all : send message to all supported macroblogging sites
-f, --file : file containing the login information for each site
-h, --help : this help screen
-i, --identica : send message to identi.ca
-s, --status : status (message) to send
-t, --twitter : send message to twitter.com
-v, --version : displays version information

$PROG_NAME help
";
print "-" x (length ($PROG_NAME) + 5);
print "
$PROG_NAME sends a status update to either twitter.com or identi.ca (or both) from the command line.
If -t is specified (for example), it will send the update to twitter.com.
If -a is passed, then your status on both twitter and identica will be updated.

Format of login files
---------------------
$PROG_NAME will first try to find \"twit.txt\" located in the current directory.
You can also use the --file option to tell $PROG_NAME where to find your login information.
- Lines starting with '#' are comments and will be ignored by the script
- The last line starting with \"Twitter\" will be parsed for username and password.
Each of these fields must be separated by a semi-column ':'
- Same thing with \"Identica\"

Examples:
---------
- perl twit.pl -s \"Using Padre on Linux\" -f \"~/secretstuff/mytwitterpassword.txt\" -a
Updates both twitter and identica status with login info from specified file
- perl twit.pl -s \"This is Vistaaaaaa\" -i
Updates identica status only

$PROG_NAME uses the following modules:
- Getopt::Long
- Net::Twitter
";
exit;
} # End of Help

# ------------------------------------------------------------------------------
# Name : version
# Comment : displays script's version number
# Input : --
# Output : version number screen and exit program
# ------------------------------------------------------------------------------
sub Version {
print "
$PROG_NAME version: $VERSION
Date : $VersionDate
Author: dlp

Get the latest version from here:
http://sites.google.com/site/damienlearnsperl/DLP-scripts
";
exit;
} # end of Version

# ------------------------------------------------------------------------------
# Name : CreateObject
# Comment : Creates and returns an instance of the Net::Twitter class
# Input : - Input string with value
# "twitter" -> twitter.com instance
# "identica" -> identi.ca instance
# all other values return an error
# - Hash with "UserName" and "Password"
# Output : Object newly created or 0 if error
# ------------------------------------------------------------------------------
sub CreateObject {
my $SiteInstance = 0;
my $NameString = shift;
my %Login = @_;

$NameString =~ tr/A-Z/a-z/;
if ($NameString eq "twitter") {
$SiteInstance = Net::Twitter->new(username => $Login{"UserName"}, password => $Login{"Password"});
}
elsif ($NameString eq "identica") {
$SiteInstance = Net::Twitter->new(identica => 1, username => $Login{"UserName"}, password => $Login{"Password"});
}
return $SiteInstance;
} # End of CreateObject

# ------------------------------------------------------------------------------
# Name : SendUpdate
# Comment : Sends update to Twitter object
# Input : - Net::Twitter object
# - message string
# Output : string "OK" if successful update, string "FAIL" otherwise
# ------------------------------------------------------------------------------
sub SendUpdate {
my $Site = shift;
my $Message = shift;
my $SiteName = ($Site->{identica})?"identi.ca":"twitter.com";

#There's a hard limit on the size of twits for both twitter and identica
if (!defined $Message) {
return "$SiteName update: FAILED (no message)";
}
if (length $Message > 140) {
return "$SiteName update: FAILED (message over 140 characters)";
}

if ($Site->update($Message)) {
return "$SiteName update: OK";
}
else {
return "$SiteName update: FAIL";
}
} #End of SendUpdate

# ------------------------------------------------------------------------------
# Name : SendMessage
# Comment : Sends message to chosen macroblogging site
# Input : $_[0] = Input string with value
# "twitter" -> twitter.com instance
# "identica" -> identi.ca instance
# $_[1] = Message string to be sent
# $_[2] = Hash with "UserName" and "Password" elements
# Output : Return string: "Error" if couldn't create object or string from SendUpdate
# ------------------------------------------------------------------------------
sub SendMessage {
my $ReturnString;
my $Instance;
my ($SiteName, $Message, %Login) = @_;

$Instance = CreateObject($SiteName, %Login);
if ($Instance) {
$ReturnString = SendUpdate($Instance, $Message);
}
else {
$ReturnString = "Error with $SiteName creation process";
}
return $ReturnString;
} #End of SendMessage

# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------
my $Status;
my $PasswordFile;
my %TwitLogin;
my %IdenticaLogin;
my $TwitterUse; # 1-> send to twitter, 0 -> do not send
my $IdenticaUse; # 1-> send to identica, 0 -> do not send

Help if (@ARGV == 0);

#Parse command line arguments
GetOptions ("all" => sub {$TwitterUse = 1; $IdenticaUse = 1},
"status=s" => \$Status,
"file=s" => \$PasswordFile,
"help" => \&Help,
"identica" => \$IdenticaUse,
"twitter" => \$TwitterUse,
"version" => \&Version);

# Read Password file passed as argument or twit.txt by default
$PasswordFile = "twit.txt" unless ($PasswordFile);
open(LOGINFILE, $PasswordFile) or die "Cannot open \"$PasswordFile\" file: $!\n";
while () {
my $line = $_;
my $PlaceHolder;

chomp $line; # Remove trailing newline character
next if ($line =~ m/^#/); # Ignore lines starting with '#'
if ($line =~ m/^twitter/i) { # /^ indicates the beginning of the line
($PlaceHolder, $TwitLogin{"UserName"}, $TwitLogin{"Password"}) = split (/:/, $line);
}
if ($line =~ m/^identica/i) { # /i to ignore alphabetic case
($PlaceHolder, $IdenticaLogin{"UserName"}, $IdenticaLogin{"Password"}) = split (/:/, $line);
}
}
close (LOGINFILE);

say SendMessage("Twitter", $Status, %TwitLogin) if ($TwitterUse);
say SendMessage("Identica", $Status, %IdenticaLogin) if ($IdenticaUse);
Help if (!defined ($TwitterUse) && !defined ($IdenticaUse));

__END__
To do:
- Use POD format for comments
- Simple GUI interface (1 text box + 1 check box for each Twitter and Identi.ca + 1 "Send" button)
- Create executable file for standalone use without need of a Perl interpreter

History:
...
v0.2.0 (2009/02/21): Added --twitter (-t) and --identica (-i) command line options to select site for updates
Added --help (-h) and --version (-v) command line options
Added undefined argument check for $Message in SendUpdate().
It is getting a bit long to post the whole script on this blog. You can still find the latest version to download here.
There are better ways to include help and comments in code. I will talk about POD soon.

Larry Wall quote of the day:
"We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise."

Possible next posts:
  • Perl template - Part II: Adding Help and Version procedures
  • Perl help resources
  • Improving on twit.pl: Graphical User interface
  • POD
  • Install Google Analytics on your Blogger blog and stats for DLP

Improving the twit perl script

As I spent some time on twit.pl v0.2.0, I also tried to improve on the Perl template for new scripts.

New Perl that I learned
Today, I'll try to explain the new concepts first and then show the code.
  • "$0": This is dollar-zero. It is a special Perl variable to indicate the name of the file containing the perl script being executed
  • The x operator repeats a string pattern.
    print "*" x 10; and print "**********"; are equivalent
  • defined will return false if a variable is undef and true if it has a value.
  • @ARGV is a reserved Perl array that contains the list of arguments passed on the command line.
    Help if (@ARGV == 0); will call the Help subroutine if the list of arguments is empty, i.e. if you just type "perl twit.pl" at the command line.
    Note that checking @ARGV must be performed before the call to GetOptions which will empty the argument list.
  • You can tell the GetOption procedure to directly call a subroutine when a specific argument is passed at the command line. See for example "version" => \&Version. When -v or --version is added after the script name, you will see the version number of the script and exit the program.
twit_0_2_0.pl
To use version 0.2.0, you have to add -t (for twitter), -i (for identica) or -a (for both, also works if you choose -t -i) to the command line.

#!/usr/bin/perl
use 5.10.0; # To be able to use "say" function
use strict; # Pragma to add restrictions to Perl rules
use warnings; # Pragma to add warnings at compile and run-time
use Getopt::Long; # To parse the command line
use Net::Twitter; # API to twitter.com and identi.ca

my $PROG_NAME = $0; # $0 contains the name of the file containing the Perl script being executed
my $VERSION = "v0.2.0";
my $VersionDate = "February 21st 2009";

# ------------------------------------------------------------------------------
# Name : Help
# Comment : displays list of available options
# Input : no argument to command line or "-h" or "--help"
# Output : help screen and exit program
# ------------------------------------------------------------------------------
sub Help {
print "
Usage:
perl $PROG_NAME [-options]

Options:
-a, --all : send message to all supported macroblogging sites
-f, --file : file containing the login information for each site
-h, --help : this help screen
-i, --identica : send message to identi.ca
-s, --status : status (message) to send
-t, --twitter : send message to twitter.com
-v, --version : displays version information

$PROG_NAME help
";
print "-" x (length ($PROG_NAME) + 5);
print "
$PROG_NAME sends a status update to either twitter.com or identi.ca (or both) from the command line.
If -t is specified (for example), it will send the update to twitter.com.
If -a is passed, then your status on both twitter and identica will be updated.

Format of login files
---------------------
$PROG_NAME will first try to find \"twit.txt\" located in the current directory.
You can also use the --file option to tell $PROG_NAME where to find your login information.
- Lines starting with '#' are comments and will be ignored by the script
- The last line starting with \"Twitter\" will be parsed for username and password.
Each of these fields must be separated by a semi-column ':'
- Same thing with \"Identica\"

Examples:
---------
- perl twit.pl -s \"Using Padre on Linux\" -f \"~/secretstuff/mytwitterpassword.txt\" -a
Updates both twitter and identica status with login info from specified file
- perl twit.pl -s \"This is Vistaaaaaa\" -i
Updates identica status only

$PROG_NAME uses the following modules:
- Getopt::Long
- Net::Twitter
";
exit;
} # End of Help

# ------------------------------------------------------------------------------
# Name : version
# Comment : displays script's version number
# Input : --
# Output : version number screen and exit program
# ------------------------------------------------------------------------------
sub Version {
print "
$PROG_NAME version: $VERSION
Date : $VersionDate
Author: dlp

Get the latest version from here:
http://sites.google.com/site/damienlearnsperl/DLP-scripts
";
exit;
} # end of Version

# ------------------------------------------------------------------------------
# Name : CreateObject
# Comment : Creates and returns an instance of the Net::Twitter class
# Input : - Input string with value
# "twitter" -> twitter.com instance
# "identica" -> identi.ca instance
# all other values return an error
# - Hash with "UserName" and "Password"
# Output : Object newly created or 0 if error
# ------------------------------------------------------------------------------
sub CreateObject {
my $SiteInstance = 0;
my $NameString = shift;
my %Login = @_;

$NameString =~ tr/A-Z/a-z/;
if ($NameString eq "twitter") {
$SiteInstance = Net::Twitter->new(username => $Login{"UserName"}, password => $Login{"Password"});
}
elsif ($NameString eq "identica") {
$SiteInstance = Net::Twitter->new(identica => 1, username => $Login{"UserName"}, password => $Login{"Password"});
}
return $SiteInstance;
} # End of CreateObject

# ------------------------------------------------------------------------------
# Name : SendUpdate
# Comment : Sends update to Twitter object
# Input : - Net::Twitter object
# - message string
# Output : string "OK" if successful update, string "FAIL" otherwise
# ------------------------------------------------------------------------------
sub SendUpdate {
my $Site = shift;
my $Message = shift;
my $SiteName = ($Site->{identica})?"identi.ca":"twitter.com";

#There's a hard limit on the size of twits for both twitter and identica
if (!defined $Message) {
return "$SiteName update: FAILED (no message)";
}
if (length $Message > 140) {
return "$SiteName update: FAILED (message over 140 characters)";
}

if ($Site->update($Message)) {
return "$SiteName update: OK";
}
else {
return "$SiteName update: FAIL";
}
} #End of SendUpdate

# ------------------------------------------------------------------------------
# Name : SendMessage
# Comment : Sends message to chosen macroblogging site
# Input : $_[0] = Input string with value
# "twitter" -> twitter.com instance
# "identica" -> identi.ca instance
# $_[1] = Message string to be sent
# $_[2] = Hash with "UserName" and "Password" elements
# Output : Return string: "Error" if couldn't create object or string from SendUpdate
# ------------------------------------------------------------------------------
sub SendMessage {
my $ReturnString;
my $Instance;
my ($SiteName, $Message, %Login) = @_;

$Instance = CreateObject($SiteName, %Login);
if ($Instance) {
$ReturnString = SendUpdate($Instance, $Message);
}
else {
$ReturnString = "Error with $SiteName creation process";
}
return $ReturnString;
} #End of SendMessage

# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------
my $Status;
my $PasswordFile;
my %TwitLogin;
my %IdenticaLogin;
my $TwitterUse; # 1-> send to twitter, 0 -> do not send
my $IdenticaUse; # 1-> send to identica, 0 -> do not send

Help if (@ARGV == 0);

#Parse command line arguments
GetOptions ("all" => sub {$TwitterUse = 1; $IdenticaUse = 1},
"status=s" => \$Status,
"file=s" => \$PasswordFile,
"help" => \&Help,
"identica" => \$IdenticaUse,
"twitter" => \$TwitterUse,
"version" => \&Version);

# Read Password file passed as argument or twit.txt by default
$PasswordFile = "twit.txt" unless ($PasswordFile);
open(LOGINFILE, $PasswordFile) or die "Cannot open \"$PasswordFile\" file: $!\n";
while () {
my $line = $_;
my $PlaceHolder;

chomp $line; # Remove trailing newline character
next if ($line =~ m/^#/); # Ignore lines starting with '#'
if ($line =~ m/^twitter/i) { # /^ indicates the beginning of the line
($PlaceHolder, $TwitLogin{"UserName"}, $TwitLogin{"Password"}) = split (/:/, $line);
}
if ($line =~ m/^identica/i) { # /i to ignore alphabetic case
($PlaceHolder, $IdenticaLogin{"UserName"}, $IdenticaLogin{"Password"}) = split (/:/, $line);
}
}
close (LOGINFILE);

say SendMessage("Twitter", $Status, %TwitLogin) if ($TwitterUse);
say SendMessage("Identica", $Status, %IdenticaLogin) if ($IdenticaUse);
Help if (!defined ($TwitterUse) && !defined ($IdenticaUse));

__END__
To do:
- Use POD format for comments
- Simple GUI interface (1 text box + 1 check box for each Twitter and Identi.ca + 1 "Send" button)
- Create executable file for standalone use without need of a Perl interpreter

History:
...
v0.2.0 (2009/02/21): Added --twitter (-t) and --identica (-i) command line options to select site for updates
Added --help (-h) and --version (-v) command line options
Added undefined argument check for $Message in SendUpdate().
It is getting a bit long to post the whole script on this blog. You can still find the latest version to download here.
There are better ways to include help and comments in code. I will talk about POD soon.

Larry Wall quote of the day:
"We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise."

Possible next posts:
  • Perl template - Part II: Adding Help and Version procedures
  • Perl help resources
  • Improving on twit.pl: Graphical User interface
  • POD
  • Install Google Analytics on your Blogger blog and stats for DLP

Sunday, January 25, 2009

RankSearch - Part II: parsing the Perl command line

RankSearch: The design
The design of our little script is laid out in the comment header from last post:

1. Get the parameters from the user
  • In a first version, ensure that all parameters are filled
  • Later, we can provide a default value for the search engine (Google)
  • Or even display all the results for a list of supported search engines
2. Launch an http request with the parameters given by the user
  • Spawn a process able to communicate back to our script
  • It will probably be in the form of "http:\\$engine-blabla-search_criteria-moreblabla"
  • Need to investigate different urls for different search engines
3. Parse and display the results transmitted by the http process
  • Search for the target URL
  • Keep track of rank count
  • Launch new http request with updated page number if target not found
  • Display result to user
Today, I'll strike off the first item of the list. Time to get interactive!
In order to ease the handling of user input, I discovered that Perl includes the Getopt::Long module by default. The link on CPAN will show you all possible uses of the module.
One must be careful not to omit the "\" character before the variable name (like I did at first).
We'll only use string (character chain) inputs:
use Getopt::Long;
GetOptions (" engine="s" => \$SearchEngine);
This will store in $SearchEngine the parameter entered from the following perl command line:
perl "$(FULL_CURRENT_PATH)" --engine www.google.com --target damienlearnsperl.blogspot.com --keyword "learn perl"
or
perl "$(FULL_CURRENT_PATH)" -engine www.google.com -target damienlearnsperl.blogspot.com -keyword "learn perl"
or even
perl "$(FULL_CURRENT_PATH)" -e www.google.com -t damienlearnsperl.blogspot.com -k "learn perl"
(provided you only have one entry in Getoptions starting with "e")

Here's the script:
#!/usr/bin/perl -w
# --------------------------------------------------
# File : RankSearch.pl
# Author : DLP
# Date : January 24th 2009
# Object : Looks in a search engine what is the rank
# for a given website and a given keyword
# Input : - Search engine URL, eg. "www.google.com"
# - URL of website to monitor
# - Search expression to investigate
# Bugs : None
# To do : - Launch http request
# - Read html result
# - Analyse result and display website rank
# --------------------------------------------------
use strict;
use Getopt::Long; #Load module

# Global variable
my $PROG_NAME = "RankSearch";
my $VERSION = "v0.0.1";
my $PROG_DATE = "January 24th 2009";

# --------------------------------------------------
# Main program
# --------------------------------------------------
# More global variables
my $SearchEngine = "";
my $TargetURL = "";
my $Keyword = "";

#Parse command line arguments
GetOptions ("engine=s" => \$SearchEngine, #string
"target=s" => \$TargetURL,
"keyword=s" => \$Keyword);

# Check user input
if ($SearchEngine eq "" ||
$TargetURL eq "" || $Keyword eq "")
{
print "
You must enter a valid string for:
--engine = search engine URL
--target = the target of the search
--keyword = the search criteria
";
exit;
}

print "
$TargetURL is ranked nth on the $SearchEngine
search engine for the \"$Keyword\" criteria.";

__END__
Jan 24 2009 (0.0.1): first version of RankSearch
Jan 25 2009 (0.0.2): get params from command line

After getting the parameters, we check to see if anything was entered at all.
If $SearchEngine, $TargetURL or $Keyword are still empty chains (or undefined) then we print an error message and exit the program (the operator for a logical OR is "||" or.. "or"! I don't get the differences yet).

In Notepad++ you can modify the execute command line (via the F6 shortcut) to:
perl "$(FULL_CURRENT_PATH)" -e www.google.com --target damienlearnsperl.blogspot.com --keyword learn perl

This result will appear as:

Notepad++ execution console
Note that the criteria entered by the user was "learn perl" and it was displayed as "learn" by the script. We'll just have to make sure that double quotes (") are used when the string input has a blank space.

French expression of the day:
"Ce que femme veut, Dieu le veut": A woman's will is God's will
As you can see, God and strong-minded women are universal.

Next posts:
  • More about CPAN
  • Our first Perl program - Part III: Launch a HTTP request
  • How to install Google Analytics on your Blogger blog
  • Our first Perl program - Part IV: Read results from a HTML page
  • Perl help resources
  • Our first Perl program - Part V: Result analysis
  • POD
  • Our first Perl program - Part VI: Add a GUI interface

RankSearch - Part II: parsing the Perl command line

RankSearch: The design
The design of our little script is laid out in the comment header from last post:

1. Get the parameters from the user
  • In a first version, ensure that all parameters are filled
  • Later, we can provide a default value for the search engine (Google)
  • Or even display all the results for a list of supported search engines
2. Launch an http request with the parameters given by the user
  • Spawn a process able to communicate back to our script
  • It will probably be in the form of "http:\\$engine-blabla-search_criteria-moreblabla"
  • Need to investigate different urls for different search engines
3. Parse and display the results transmitted by the http process
  • Search for the target URL
  • Keep track of rank count
  • Launch new http request with updated page number if target not found
  • Display result to user
Today, I'll strike off the first item of the list. Time to get interactive!
In order to ease the handling of user input, I discovered that Perl includes the Getopt::Long module by default. The link on CPAN will show you all possible uses of the module.
One must be careful not to omit the "\" character before the variable name (like I did at first).
We'll only use string (character chain) inputs:
use Getopt::Long;
GetOptions (" engine="s" => \$SearchEngine);
This will store in $SearchEngine the parameter entered from the following perl command line:
perl "$(FULL_CURRENT_PATH)" --engine www.google.com --target damienlearnsperl.blogspot.com --keyword "learn perl"
or
perl "$(FULL_CURRENT_PATH)" -engine www.google.com -target damienlearnsperl.blogspot.com -keyword "learn perl"
or even
perl "$(FULL_CURRENT_PATH)" -e www.google.com -t damienlearnsperl.blogspot.com -k "learn perl"
(provided you only have one entry in Getoptions starting with "e")

Here's the script:
#!/usr/bin/perl -w
# --------------------------------------------------
# File   : RankSearch.pl
# Author : DLP
# Date   : January 24th 2009
# Object : Looks in a search engine what is the rank
#          for a given website and a given keyword
# Input  : - Search engine URL, eg. "www.google.com"
#          - URL of website to monitor
#          - Search expression to investigate
# Bugs   : None
# To do  : - Launch http request
#          - Read html result
#          - Analyse result and display website rank
# --------------------------------------------------
use strict;
use Getopt::Long;   #Load module

# Global variable
my $PROG_NAME = "RankSearch";
my $VERSION   = "v0.0.1";
my $PROG_DATE = "January 24th 2009";

# --------------------------------------------------
# Main program
# --------------------------------------------------
# More global variables
my $SearchEngine = "";
my $TargetURL = "";
my $Keyword = "";

#Parse command line arguments
GetOptions ("engine=s"  => \$SearchEngine,  #string
    "target=s"  => \$TargetURL,
    "keyword=s" => \$Keyword);

# Check user input
if ($SearchEngine eq "" ||
$TargetURL eq "" || $Keyword eq "")
{
print "
You must enter a valid string for:
--engine  = search engine URL
--target  = the target of the search
--keyword = the search criteria
";
exit;
}

print "
$TargetURL is ranked nth on the $SearchEngine
search engine for the \"$Keyword\" criteria.";

__END__
Jan 24 2009 (0.0.1): first version of RankSearch
Jan 25 2009 (0.0.2): get params from command line

After getting the parameters, we check to see if anything was entered at all.
If $SearchEngine, $TargetURL or $Keyword are still empty chains (or undefined) then we print an error message and exit the program (the operator for a logical OR is "||" or.. "or"! I don't get the differences yet).

In Notepad++ you can modify the execute command line (via the F6 shortcut) to:
perl "$(FULL_CURRENT_PATH)" -e www.google.com --target damienlearnsperl.blogspot.com --keyword learn perl

This result will appear as:

Notepad++ execution console
Note that the criteria entered by the user was "learn perl" and it was displayed as "learn" by the script. We'll just have to make sure that double quotes (") are used when the string input has a blank space.

French expression of the day:
"Ce que femme veut, Dieu le veut": A woman's will is God's will
As you can see, God and strong-minded women are universal.

Next posts:
  • More about CPAN
  • Our first Perl program - Part III: Launch a HTTP request
  • How to install Google Analytics on your Blogger blog
  • Our first Perl program - Part IV: Read results from a HTML page
  • Perl help resources
  • Our first Perl program - Part V: Result analysis
  • POD
  • Our first Perl program - Part VI: Add a GUI interface

Saturday, January 24, 2009

Retrieve the search rank for your blog automatically

I was reading the latest article over at Pretty Your Blog yesterday and it gave me an idea for a first script. The FileInfo program that I wanted to present is already written and I may come back to it later. The RankSearch project that I have in mind will be written from the ground up so you'll be able to monitor the progress as I crawl towards completion. I hope you'll pitch in as well!

RankSearch: The need
Kelly wrote in Pretty Your Blog:
I ran another (unofficial) experiment; I did a google search for frugal blog. And the result? Almost Frugal was on the 13th page of search results.
It is very likely that Kelly clicked on the next link at the bottom of each Google page until she found her blog's reference (by the way, if you are interested in improving your blog, you may want to visit Pretty Your Blog often :).
What if we could write a Perl script that automatically returns the Google rank based for any URL on a given keyword? That's the idea behind RankSearch.pl

RankSearch: The specifications
The script will have to be as generic as possible and would take 3 input parameters:
- Search engine URL (eg: "www.google.com" or "www.yahoo.com")
- URL of the blog you want to check the ranking for (eg: "almostfrugal.com")
- The search criteria you are investigating (eg: "frugal blog")

The output result will be a simple message of the type:
almostfrugal.com is ranked 7th on the google search engine for the "frugal blog" criteria.

It will run on Windows and Linux environments
Do you see anything else to add?

And here is the template for it:
#!/usr/bin/perl -w
# ----------------------------------------
# File : RankSearch.pl
# Author : DLP
# Date : January 24th 2009
# Object : Looks in a search engine what is the rank
# for a given website and a given keyword
# Input : - Search engine URL, eg. "www.google.com"
# - URL of website to monitor
# - Search expression to investigate
# Bugs : None
# To do : - Read input and store in script variable
# - Launch http request
# - Read html result
# - Analyse result and display website rank
# ----------------------------------------
use strict;

my $PROG_NAME = "RankSearch";
my $VERSION = "v0.0.1";
my $PROG_DATE = "January 24th 2009";

print "$PROG_NAME $VERSION from $PROG_DATE.\n";

__END__
Jan 24 2009: first version of RankSearch

French word of the day:
"économe": frugal

New posts:
  • Our first Perl program - Part II: parsing the Perl command line
  • More about CPAN
  • Our first Perl program - Part III: Launch a HTTP request
  • How to install Google Analytics on your Blogger blog
  • Our first Perl program - Part IV: Read results from a HTML page
  • Perl help resources
  • Our first Perl program - Part V: Result analysis
  • Our first Perl program - Part VI: Add a GUI interface

Retrieve the search rank for your blog automatically

I was reading the latest article over at Pretty Your Blog yesterday and it gave me an idea for a first script. The FileInfo program that I wanted to present is already written and I may come back to it later. The RankSearch project that I have in mind will be written from the ground up so you'll be able to monitor the progress as I crawl towards completion. I hope you'll pitch in as well!

RankSearch: The need
Kelly wrote in Pretty Your Blog:
I ran another (unofficial) experiment; I did a google search for frugal blog. And the result? Almost Frugal was on the 13th page of search results.
It is very likely that Kelly clicked on the next link at the bottom of each Google page until she found her blog's reference (by the way, if you are interested in improving your blog, you may want to visit Pretty Your Blog often :).
What if we could write a Perl script that automatically returns the Google rank based for any URL on a given keyword? That's the idea behind RankSearch.pl

RankSearch: The specifications
The script will have to be as generic as possible and would take 3 input parameters:
- Search engine URL (eg: "www.google.com" or "www.yahoo.com")
- URL of the blog you want to check the ranking for (eg: "almostfrugal.com")
- The search criteria you are investigating (eg: "frugal blog")

The output result will be a simple message of the type:
almostfrugal.com is ranked 7th on the google search engine for the "frugal blog" criteria.

It will run on Windows and Linux environments
Do you see anything else to add?

And here is the template for it:
#!/usr/bin/perl -w
# ----------------------------------------
# File : RankSearch.pl
# Author : DLP
# Date : January 24th 2009
# Object : Looks in a search engine what is the rank
# for a given website and a given keyword
# Input : - Search engine URL, eg. "www.google.com"
# - URL of website to monitor
# - Search expression to investigate
# Bugs : None
# To do : - Read input and store in script variable
# - Launch http request
# - Read html result
# - Analyse result and display website rank
# ----------------------------------------
use strict;

my $PROG_NAME = "RankSearch";
my $VERSION = "v0.0.1";
my $PROG_DATE = "January 24th 2009";

print "$PROG_NAME $VERSION from $PROG_DATE.\n";

__END__
Jan 24 2009: first version of RankSearch

French word of the day:
"économe": frugal

New posts:
  • Our first Perl program - Part II: parsing the Perl command line
  • More about CPAN
  • Our first Perl program - Part III: Launch a HTTP request
  • How to install Google Analytics on your Blogger blog
  • Our first Perl program - Part IV: Read results from a HTML page
  • Perl help resources
  • Our first Perl program - Part V: Result analysis
  • Our first Perl program - Part VI: Add a GUI interface

Sunday, January 18, 2009

A Perl template - Part I: The Basics

The hardest thing when it comes to programming is to sit in front of a blank screen and wonder how to start coding.
Good programming practices tell you to design your application before you type the first line of code.
Some program methodologies (Extreme Programming for example) will have you create the tests before you work on your main project.

For now, I am just going to present the very basics of Perl. The goal of the next few posts will be to build a very simple script skeleton. This template will serve as a base for a new project (and eliminate the dreaded white screen).

Enough talking, here is our first Perl program:

Type the above line in Notepadd++ and save the file as skeleton.pl.
The .pl extension means that the file is a Perl script.
Then open a DOS shell (cmd.exe) and type

C:\Perl\usr>skeleton.pl
This is easy
C:\Perl\usr>

The .pl file is executed by the C:\strawberry\perl\bin interpreter (if its correct location is in your PATH environment variable. Check how to see that here).
The print command displays a line on the standard output which is the DOS shell on your computer screen by default.

This program would run on Windows only. For Linux machines, you have to tell the computer where to find the Perl interpreter. Because we want our scripts to run on any machine (portability), we'll rewrite our first example with a few additions:

The first line starts with what is called a she-bang: #!
On Unix systems, it tells the operating system what the type of the file is and where to find the interpreter.
use warnings;
This line tells the Perl interpreter to give warnings for bad practices.

All lines starting with a # are comments.

The semi-column (;) at the end of non-comment lines are used to separate Perl statements. This is why the last ; can be omitted (but it is better to keep it in case you add more lines to the bottom of your file later).

The __END__ token tells the Perl parser to consider this line as the end of the program. Anything you write after it will not be considered a part of the Perl program and ignored.
You can use this knowledge to add some documentation at the bottom of your file.

French expression of the day:
"C'est le premier pas qui compte": The first step is always the hardest.

Next posts:
  • Perl development tools - Part II: setting up Notepad++
  • Our first Perl program - Part II: parsing the Perl command line
  • More about CPAN
  • Our first Perl program - Part III: Add a GUI interface
  • How to install Google Analytics on your Blogger blog
  • First version of FileInfo script

A Perl template - Part I: The Basics

The hardest thing when it comes to programming is to sit in front of a blank screen and wonder how to start coding.
Good programming practices tell you to design your application before you type the first line of code.
Some program methodologies (Extreme Programming for example) will have you create the tests before you work on your main project.

For now, I am just going to present the very basics of Perl. The goal of the next few posts will be to build a very simple script skeleton. This template will serve as a base for a new project (and eliminate the dreaded white screen).

Enough talking, here is our first Perl program:

Type the above line in Notepadd++ and save the file as skeleton.pl.
The .pl extension means that the file is a Perl script.
Then open a DOS shell (cmd.exe) and type

C:\Perl\usr>skeleton.pl
This is easy
C:\Perl\usr>

The .pl file is executed by the C:\strawberry\perl\bin interpreter (if its correct location is in your PATH environment variable. Check how to see that here).
The print command displays a line on the standard output which is the DOS shell on your computer screen by default.

This program would run on Windows only. For Linux machines, you have to tell the computer where to find the Perl interpreter. Because we want our scripts to run on any machine (portability), we'll rewrite our first example with a few additions:

The first line starts with what is called a she-bang: #!
On Unix systems, it tells the operating system what the type of the file is and where to find the interpreter.
use warnings;
This line tells the Perl interpreter to give warnings for bad practices.

All lines starting with a # are comments.

The semi-column (;) at the end of non-comment lines are used to separate Perl statements. This is why the last ; can be omitted (but it is better to keep it in case you add more lines to the bottom of your file later).

The __END__ token tells the Perl parser to consider this line as the end of the program. Anything you write after it will not be considered a part of the Perl program and ignored.
You can use this knowledge to add some documentation at the bottom of your file.

French expression of the day:
"C'est le premier pas qui compte": The first step is always the hardest.

Next posts:
  • Perl development tools - Part II: setting up Notepad++
  • Our first Perl program - Part II: parsing the Perl command line
  • More about CPAN
  • Our first Perl program - Part III: Add a GUI interface
  • How to install Google Analytics on your Blogger blog
  • First version of FileInfo script

Thursday, January 15, 2009

Perl development tools - Part I: the text editor

Like the smith with a hammer, a forge and an anvil, the would-be programmer needs tools to perform his trade. Thankfully, only a few of them are required to program in Perl (none of which is an anvil).

The most basic tool is an advanced text editor. You could write Perl scripts using Notepad but there are free alternatives that make programming much more comfortable. To reuse our smithy analogy, the better the tools, the quickest and sturdiest your work will be.

There are scores of free text editors and you are welcome to choose any of your liking.
Personally, I will be using Notepad++:

Notepad++ logo- It supports Perl syntax highlighting
- It has regular expression capabilities
- It is an open source project.
- You can install plugins to add more functionalities

Download the editor's installation file from here. You can also get the zip version. The latest available version at the time of this post is Notepad++ 5.1.4.

We'll see later how to fine-tune the configuration of the editor. Notepad++ is one of the more popular choices and is used for a wide range of programming languages.

French expression of the day:
"C'est en forgeant qu'on devient forgeron": Practice makes perfect (litterally: It is by forging that one becomes a smith)

Next posts:
  • More about the Strawberry Perl distribution
  • No follow links
  • How to install the Strawberry Perl distribution and set up your Windows development's environment?
  • How to install Google Analytics on your Blogger blog
  • Hello World program
  • First version of FileInfo script

Perl development tools - Part I: the text editor

Like the smith with a hammer, a forge and an anvil, the would-be programmer needs tools to perform his trade. Thankfully, only a few of them are required to program in Perl (none of which is an anvil).

The most basic tool is an advanced text editor. You could write Perl scripts using Notepad but there are free alternatives that make programming much more comfortable. To reuse our smithy analogy, the better the tools, the quickest and sturdiest your work will be.

There are scores of free text editors and you are welcome to choose any of your liking.
Personally, I will be using Notepad++:

Notepad++ logo- It supports Perl syntax highlighting
- It has regular expression capabilities
- It is an open source project.
- You can install plugins to add more functionalities

Download the editor's installation file from here. You can also get the zip version. The latest available version at the time of this post is Notepad++ 5.1.4.

We'll see later how to fine-tune the configuration of the editor. Notepad++ is one of the more popular choices and is used for a wide range of programming languages.

French expression of the day:
"C'est en forgeant qu'on devient forgeron": Practice makes perfect (litterally: It is by forging that one becomes a smith)

Next posts:
  • More about the Strawberry Perl distribution
  • No follow links
  • How to install the Strawberry Perl distribution and set up your Windows development's environment?
  • How to install Google Analytics on your Blogger blog
  • Hello World program
  • First version of FileInfo script