Computer Scientist, Graduate Student, and Geek

Category: Development

Reading Arguments from the Command Line with Perl

August 21, 2012

The variable $#ARGV contains a count of the number of command line arguments. The count is zero-based (i.e., -1 means no arguments, 0 means one argument, 1 means two arguments, etc.), and it does not include the script name.

The actual argument values are stored in the array $ARGV, e.g., the first argument can be accessed using $ARGV[0].

Categories: Development

Tags: perl


Perl Code for Processing CSV Files

July 30, 2012

Below is a sample Perl script containing many constructs that I commonly use to process output in the form of a comma-separated value (CSV) file.

use strict;

# Read from standard in, one line at a time
while (my $line=<STDIN>)
{
    # Trim trailing newline
    chomp $line; 

    # Create an array from a line of comma-separated values
    my @cols = split(/,/,$line);
}

Categories: Development

Tags: perl


View Object Signatures in Python

February 15, 2011

You can typically view the signature of an object (i.e. a list of its instance files and methods) using the dir method.For example, the python segment below

class Foo:
    def __init__(self):
        self.first = 'Aaron'
        self.last = 'Gember'

f = Foo()
dir(f)

results in the following output from dir

['__doc__', '__init__', '__module__', 'first', 'last']

Categories: Development

Tags: python


Mercurial Over SSH

April 12, 2010

To clone a Mercurial (hg) repository over SSH, use the command

hg clone ssh://hostname/path/to/repo
replacing hostname with the hostname of the computer who you would like to connect to via SSH to obtain the repository and path/to/repo with the path to the repository, relative to your home directory. To use a directory relative to the root directory of the remote host, add additional slash after the hostname
hg clone ssh://hostname//path/to/repo

Categories: Development, Linux

Tags: mercurial, ssh


Installing Phidgets in Fedora

January 27, 2010

Phidgets are boards for sensing and control projects that are managed via a USB connection to a computer. I use the Phidget Interface Kit 0/0/4 for my Christmas light controllers. To control the boards from a Linux workstation, it is necessary to install the Phidgets driver. To allow connectivity to Phidgets from Fedora 12 (or Fedora 10 or 11):

  1. Download the Phidget source: http://www.phidgets.com/drivers.php
  2. Untar the contents and change to the phidget21 directory.
  3. Run make, then sudo make install.
  4. Copy the udev configuration file to the appropriate location.
    sudo cp udev/99-phidgets.rules /etc/udev/rules.d/
  5. Restart udev.
    sudo /etc/init.d/udev-post reload
  6. Connect (or unplug and reconnect) the Phidget board to an available USB port.

I typically control the Phidget board using Python. To install the necessary Python modules:

  1. Download the Python module source: http://www.phidgets.com/programming_resources.php
  2. Unzip the module.
  3. Move the Phidgets directory to the standard location for Python modules.
    sudo mv Phidgets/ /usr/lib64/python2.6/

Categories: Development, Linux

Tags: fedora, phidgets, python


Revert Commit in Subversion

January 21, 2010

In the directory you want to revert, run:

svn merge -r HEAD:[revision number before bad commit] .
svn commit

Categories: Development, Linux

Tags: subversion


Preventing Auto-Padding in C Structures

January 05, 2010

Most networking applications written in C use structures to easily access the data in a packet header. If all the pieces are appropriately word aligned (i.e. one or more sequential parts of the header total 4-bytes in length), then a regular C structure works just fine. The standard IP, TCP, and UDP headers are all word aligned.

However, the custom packet header I was using for a project was not word aligned. Using a regular structure without any special notation, caused the GNU C compiler (gcc) to automatically add padding to the structure to force one or more sequential variables to be 4-byte aligned. But, the packet should not contain this extra padding. The parts of the header need to be "packed."

To force an entire structure to be packed, add

__attribute__((packed))
at the end of the structure definition. For example:
struct mine { 
short a;
int b;
}__attribute__((packed));

It is important to note that not all architectures will allow "packed" structures. Most RISC architectures require that variables be word-aligned, and generate a fault when memory is read across two words. The x86 and x86_64 architectures allow non-word-aligned variables for backwards compatibility to earlier processor versions. Wikipedia has more details on data structure alignment.

(The original source of this solution is: http://tuxsudh.blogspot.com/2005/05/structure-packing-in-gcc.html)

Categories: Development, Networking

Tags: c


Including Code Blocks in LaTeX

September 23, 2009

I recently had a need to include a block of C code in a report I was writing in LaTeX. I discovered the listings package provides mechanisms for nicely displaying code. Include the package in your file by placing

\usepackage{listings}

somewhere before your \begin{document}. Wherever you want the block of C code (or code in a multitude of other supported languages) insert

\begin{lstlisting}[language=C,frame=single]
CODE GOES HERE
\end{lstlisting}

You can specify other options besides language and frame. For more details on the package see the LaTex Wikibook.

Categories: Development

Tags: latex


Adding a Line to the Top of a File with Sed

August 25, 2009

I recently needed to add a copyright notice to the top of multiple Java files. In the directory where the files were located I ran the command

sed -e '1i\/* Copyright (C) 2009 Aaron Gember. */\n' -i *.java

The -e option tells sed to execute the "script" in single quotes ('). The script is the line in which to insert (1 to insert at the time), the command to insert (i\), the text to insert (/* Copyright (C) 2009 Aaron Gember. */), and a newline to add a blank line (\n). The -i options tells sed to edit the files in place - i.e. change the existing files, don't create new ones. The files to change are all Java files (*.java).

Categories: Development, Linux

Tags: java, sed


Multiple Letter Mail Merge in Word 2007

August 07, 2009

I recently assisted someone with a mail-merge in Microsoft Word 2007 for a letter whose content depended on a person's interests. I started with three different components (all in the same directory):

  1. An Excel spreadsheet containing the name, address, and area of interest for everyone who should receive the letter.
  2. A Word document with the top of the letter (date, address block, and greeting).
  3. Word documents with a different letter body and signature for each area of interest. The documents were each named for the area of interest as stored in the spreadsheet.

In the Word document containing the top of the letter, I setup a mail-merge. The source data was the Excel spreadsheet. I inserted the necessary merge fields for the top of the letter. I also inserted the area of interest field surrounded by four equal signs (=) in the place where the body should go.

====<< Area_Of_Interest >>====

In the same document I wrote a macro to do the following:

  1. Complete the merge to a new document
  2. Find the first occurrence of ====*==== in the document, where * was a wild card for the area of interest
  3. Remove the equal signs and area of interest
  4. Insert one of the body and signature Word documents using the area of interest to determine the file name
  5. Go back to step #2 and repeat until no more occurrences of ====*==== exist
In the end, I had each letter with the appropriate address block, greeting, and letter body based on the data in the Excel spreadsheet. Below is the VBA code for the macro.

Sub InsertLetter()
Dim dept
Dim aRange
Dim done
Dim filename

'Execute mail merge
With ActiveDocument.MailMerge
    .Destination = wdSendToNewDocument
    .Execute
End With

'Search entire document for special tags
done = False
Selection.SetRange ActiveDocument.Range.Start, ActiveDocument.Range.End

'Continue searching document until no more tags are found
Do While (Not done)
    'Execute search
    With Selection.Find
        .Text = "====*===="
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = True
        .MatchWildcards = True
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute

    'If tag is found, get value of tag
    If (Selection.Find.Found) Then
        dept = ActiveWindow.ActivePane.Selection
        dept = Left(dept, Len(dept) - 4)
        dept = Right(dept, Len(dept) - 4)
        filename = dept + ".doc"

        'Verify document to insert (replacing tag) exists and insert
        If (Dir(filename) <> "") Then
            ActiveWindow.ActivePane.Selection = ""
            Set aRange = ActiveWindow.ActivePane.Selection
            aRange.Start = aRange.End
            aRange.InsertFile filename:=filename
            'Display and put error message in document if file does not exist
        Else
            MsgBox "No letter found for department: " + dept, vbExclamation
            ActiveWindow.ActivePane.Selection = "No letter found for department: " _
                + dept
        End If

        'Update search range to search the rest of the document
        Selection.SetRange Selection.End, ActiveDocument.Range.End
    Else
        done = True
    End If
Loop
End Sub

Categories: Development

Tags: excel, mail merge, word