Short Guide on Programming

Introduction

This is a quick summary of guidelines of how to learn a programming language using perl as the example. It is meant for people who are brand new to programming and developing on unix systems. There is nothing in here about version control, or agile or working in large groups or any of the heady software engineering subjects. It’s meant to be just a signpost to get someone started as quickly as possible.

Find a book

Find a book you like that gives you good information on the basics of the language and walks you through a couple of examples. Pick one and read it. I like the “Learning Perl” by O’Reilly but I have used others. The others I have used were mainly for reference. After a while you will just be copying an pasting from your own code and the examples you find on the internet. But to get you started quickly a beginners book and some allocation of time is mandatory. For LEarning PErl I found that if you read thorugh the first 13 chapters, whihc is an easy read, then you will probably know enough to produce some pretty useful code. The rest is for reference and large projects.

Find a good site or multiple sites

There are a lot of websites devoted to perl. You can get lost in them. Google gives pretty good results if you ask the question properly.

http://perl-begin.org/tutorials/bad-elements/ – this will help you avoid bad code, but not write good code.
http://www.perlmonks.org – all perl roads lead to the monastery. Might as well get to know it now.
search engines for everything and anything else.

Form

When you are writing serious code which is code that you are going to be using many times
Use a good starting form. There are many. But basically the form is divided into sections, mine are usually divided into the following. But the main points is, pick a usable way of organizing your code, be consistent in that organization and stick with it.

Header
Notes
Includes
Globals
Subroutines
Main
Getoptions
Subroutine calls

Here is an example:

: # use perl -w
eval '                PERL=/usr/local/bin/perl;
        [ -x $PERL ] || PERL=/usr/bin/perl;
        exec $PERL -S $0 ${1+"$@"}'
  if 0;

#!perl     # just a comment now

# Program         :
# Author          : Michael Simoni
# Purpose         :
# Date            :
################################################################################
# CVS Information
# $Source: $
# $Author: $
# $Date: $
# $Id: $
# $Revision: $
################################################################################
# Notes
################################################################################
$| = 1;
use strict;
use English;
#use Term::Cap;
#use Benchmark;
#use Term::ReadKey;
#use Getopt::Std;
use Getopt::Long;
use Data::Dumper;
#use File::Copy;
#use File::Basename;
use Sys::Hostname;
#use Net::IP;
#use String::Random;
#use Config::IniFiles;
#use Switch;
################################################################################
# Globals
################################################################################
my $hostname   = hostname();    # always the current host
my $DEBUG      = 0;

################################################################################
# print helpful information
################################################################################
sub usage()
{
    print <<EOD;
Usage:
$0:   -h
      where:
        -d debug mode
        -h print this message
EOD
}
################################################################################
# print a line
################################################################################
sub print_line( $ )
{
    my ($character) = @_;
    for ( my $i = 1 ; $i <= 78 ; $i++ )
    {
        print "$character";
    }
    print "\n";
}
################################################################################
# Main
################################################################################
#$binddn   = shift @ARGV;
my $length_argv = @ARGV;    # check on correct number of command line paramters
################################################################################
#####################
# parse command line
#####################
if ( $length_argv < 1 )
{
    usage;
    exit;
}

GetOptions(
    "file_data=s"  => \@data_file,    # -f <file> -f <file> or -f <file,file>
    "debug"        => \$DEBUG,
    "help"         => \$HELP,
);

if ($HELP)
{
    usage();
    exit;
}
if (@data_file)
{
    #$file_info = get_data( \@data_file );
}
else
{
    print "ERROR: need an input file. Exiting.";
    exit;
}
if ($DEBUG)
{

    #$Data::Dumper::Varname = "file_info";
    #print Dumper( $variable ) . "\n";
    #$Data::Dumper::Varname = "VAR";
}

exit;

IDE – Integrated Development environment

Basically an IDE is an editor. A really fancy code editor. There are many IDE’s that will help you produce good form. I just use vim and perltidy for perl scripts
If you are at home there is a perl IDE for vim.
http://www.vim.org/scripts/script.php?script_id=556

Maintainability

Some day you will need to read the code or hand it off. Be nice to yourself and anyone else by being neat.

  1. Use perltidy or the equivalent for your language if it is available. Always.  If you don’t have a tidy program for your code, then be tidy your self. Remember, when you don’t know what you are doing, do it neatly. That’s always good advice.
  2. Write code to be maintainable first , fast is always secondary. Memory and CPUs are cheap so use them. I have discovered that you will more than likely write fast code if you write maintainable code. It seems to be a natural consequence.
  3. Use explanatory notes above your functions in a visually striking comment header. It is so much easier when you are going back and reviewing code.
  4. Use comments.
  5. Use variables that say what the mean.

Use structured programming

All structured programming  means is break your problem down into logical parts and put them into subroutines or functions or methods or objects. Basically, group your code so it’s organized.

The basic form of all programming goes like this:

Read the data into structures (get all data at once)
Store the data
Manipulate  the data
Output the data

Learn about hashes, that’s where the real power is.
Learn about Data::Dumper

RC files

These go in your home directory.

cat .perltidyrc

-bl -l=200 –se

I’m not sure where I got this vimrc file. If I ever find out I will give credit where credit is due.
cat .vimrc

" use visual bell instead of beeping
set vb

" incremental search
set incsearch

" syntax highlighting – use the default that makes the most sense
"set bg=light
set bg=dark
syntax on

" mouse scrolling – just for fun. I don't use it.
"set mouse=a


" autoindent
"autocmd FileType perl set autoindent|set smartindent

" 4 space tabs
autocmd FileType perl set tabstop=4|set shiftwidth=4|set expandtab|set softtabstop=4

" show matching brackets
autocmd FileType perl set showmatch

" show line numbers
" autocmd FileType perl set number

" check perl code with :make
autocmd FileType perl set makeprg=perl\ -c\ %\ $*
autocmd FileType perl set errorformat=%f:%l:%m
autocmd FileType perl set autowrite

" Start mapping stuff
:map <F8> !G sort -u<CR>

" dont use Q for Ex mode
map Q :q

" make tab in v mode ident code
vmap <tab> >gv
vmap <s-tab> <gv

" make tab in normal mode ident code
nmap <tab> I<tab><esc>
nmap <s-tab> ^i<bs><esc>

" paste mode - this will avoid unexpected effects when you
" cut or copy some text from one window and paste it in Vim.
set pastetoggle=<F11>

" comment/uncomment blocks of code (in vmode)
vmap _c :s/^/#/gi<Enter>
vmap _C :s/^#//gi<Enter>

" my perl includes pod
let perl_include_pod = 1

" syntax color complex things like @{${"foo"}}
let perl_extended_vars = 1

" Tidy selected lines (or entire file) with _t:
nnoremap <silent> _t :%!perltidy -q<Enter>
vnoremap <silent> _t :!perltidy -q<Enter>


" Deparse obfuscated code
nnoremap <silent> _d :.!perl -MO=Deparse 2>/dev/null<cr>
vnoremap <silent> _d :!perl -MO=Deparse 2>/dev/null<cr>

" Uncomment the color scheme below to use a different default
":runtime! colors/evening.vim
":runtime! colors/blue.vim
":runtime! colors/darkblue.vim
":runtime! colors/default.vim
":runtime! colors/delek.vim
":runtime! colors/desert.vim
":runtime! colors/elflord.vim
":runtime! colors/koehler.vim
":runtime! colors/morning.vim
":runtime! colors/murphy.vim
":runtime! colors/pablo.vim
":runtime! colors/peachpuff.vim
":runtime! colors/ron.vim
":runtime! colors/shine.vim
":runtime! colors/torte.vim
":runtime! colors/zellner.vim

Demo code.

It might have errors in it as  homework for the student.

#!/usr/bin/perl
#: # use perl -w
##eval '                PERL=/usr/local/bin/perl;
#        [ -x $PERL ] || PERL=/usr/bin/perl;
#        exec $PERL -S $0 ${1+"$@"}'
#  if 0;

# Program         :
# Author          : Michael Simoni
# Purpose         : One line description and only one line.
# Date            : in vim use :r !date then shift-j
################################################################################
# CVS or SVN Information
# $Source: $
# $Author: $
# $Date: $
# $Id: $
# $Revision: $
################################################################################
# Notes
# this is just a demo script to demonstrate coding form
################################################################################
$| = 1;

#use v5.14;
use strict;

#use warnings;

use FindBin qw($Bin);    # path to bin directory from where script was invoked
use lib "$Bin/../lib";
my $basename = $FindBin::Script;    #basename of script from which perl was invoked

#Local libaries with common perl libraries that I use, parallel to bin
use utillib;
use mydblib;

# all other perl modules go here
#use Proc::PID::File;
use Benchmark;
use File::Basename;
use Getopt::Long;

#use Smart::Comments;

################################################################################
# Globals
################################################################################
my $hostname = hostname();    # always the current host
my $DEBUG    = 0;
my $HELP     = 0;

################################################################################
# print helpful information
################################################################################
sub usage()
{
    print <<EOD;
Usage:
$0:   -f file -f file .... -d -h
      where:
        -f <file> -f <file>
        -d debug mode
        -h print this message
EOD
}
################################################################################
# remove duplicats from an array
# yes its only one line, but its an eyesore of a line and its easer to read
# uniq then the code below.
################################################################################
sub uniq ( $ )
{
    return keys %{ { map { $_ => 1 } @_ } };
}
################################################################################
# read in a file of host names or ip addresses
# the hostname should be fully qualified.
# Load the data into an hash
# expect:  a file name
# returns: reference to hash
#################################################################################
sub load_data( $ )
{
    my ($files) = @_;
    my $data_line;
    my %data = ();

    foreach my $filename (@$files)
    {
        #print "$filename\n";
        open DATA, "$filename" or die "Could not open $filename: $!\n";

        #my $linecount = 0;
        while ( $data_line = <DATA> )
        {
            #$linecount++;
            #print STDERR "$linecount           \r";
            chomp($data_line);
            $data_line =~ s/^\s+|\s+$//;    #strip leading and trailing blanks
            next if $data_line =~ /^#|^;/ or $data_line =~ /^\s*$/; #skip comments and blank lines

            $data_line =~ tr/A-Z/a-z/;    # lowercase everything

            #print "$data_line\n" if $DEBUG;
            $data{"$data_line"} = {
                #"host_label" => $error_code ? $data_line : $host_label,
                "domain_name" => "find domain name and put it here",
                "error_code"  => "if you encountered an error, indicate it with a numerical code here",
                "error_text"  => "put any associated error text here",
            };
        }
        close(DATA);
    }

    #print Dumper(\%data) . "\n" if $DEBUG;
    return \%data;
}
################################################################################
# Main
################################################################################
my $length_argv = @ARGV;    # check on correct number of command line paramters
my $host_info;              # refernc to a hash. generated by load_data
my @file_data = ();         #a list of data files to read in
################################################################################
#####################
# parse command line
#####################
if ( $length_argv < 1 )
{
    usage;
    exit;
}

GetOptions(
    "file_data=s" => \@file_data,    # -f <file> -f <file> or -f <file,file>
    "debug"       => \$DEBUG,
    "help"        => \$HELP,
);

if ($HELP)
{
    usage();
    exit;
}
if (@file_data)
{
    $host_info = load_data( \@file_data );
    foreach my $host ( keys %$host_info )
    {
        print "key: $host  " . ${$host_info}{$host}{host_label} . "\n";

    }
}
else
{
    print "ERROR: need an input file. Exiting.";
    exit;
}
if ($DEBUG)
{

    $Data::Dumper::Varname = "file_info";
    print Dumper($host_info) . "\n";
    $Data::Dumper::Varname = "VAR";
}

exit;

Appendix

vi/vim tricks

Vi can do a lot of things. See the vimrc file above. Throughout the day, I mostly use the following. For everything else, find a good reference. There are plenty on the net.
This should get you up and running as soon as possible.

movment commands

w
#
*
%
h,j.k.l,
0 (zero) and $
shift -a

editing commands

I,a,shift -a
cw
:%s/pattern/replace/g
:x,ys/pattern/replace/g
          $ - means end of file in the preceding range

shift-d
[n]x 
[n]dw
dd
yy
[n]yy
[n]dd

Special editing

e!
w!
w, w! wq, q, q!
:r !shellcmd
!G
v

[n]i {type one character, hit escape}
example: 80i#[esc]

Happy Programming!

 


Leave a Reply

Your email address will not be published. Required fields are marked *

*