Stories
Slash Boxes
Comments

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

ziggy (25)

ziggy
  (email not shown publicly)
AOL IM: ziggyatpanix (Add Buddy, Send Message)

Journal of ziggy (25)

Thursday January 13, 2005
11:09 PM

Laziness, Impatience, and avoiding Excel

[ #22707 ]
It's that time of year again -- drafting up an annual budget.

At first, I fired up dc to get some back-of-the-envelope numbers. But then I wasn't sure if I had done the math properly. Time to find a better tool.

But I hate Excel. Every time I use it, I feel like I spend more time fighting with the tool than actually getting stuff done. The solution? Why, Perl of course!

#!/usr/bin/perl -w

use strict;

my $total = 0;   ## start with a clean balance

sub income ($$) {
    my ($type, $amount) = @_;

    $total += $amount;
    printf "%20s: +%6d %7d\n", $type, $amount, $total;
}

sub expense ($$) {
    my ($type, $amount) = @_;

    $total -= $amount;
    printf "%20s: -%6d %7d\n", $type, $amount, $total;
}

The rest of the script is self-documenting:

income "Yak Milking", 1000 * 12;  ## 1 yak, $1000/month

expense "Hosting",   100 * 12;
expense "DSL",   70 * 12;
expense "Electricity",  100 * 12;
expense "PowerBook", 3500;
expense "Mac mini", 599   ## G4, 1.42 GHz
                  + 425   ## 1GB RAM
                  + 149   ## AppleCare
                  +  58   ## Kbd + mouse
                  + 999   ## 20" cinema display
;
expense "iPod",   500;
expense "iTunes Music Store", 30 * 12;
expense "ORA Books", 120 * 12;
expense "Jolt", 20 * 3 * 12;   ## three cases / month

...as is the output:

$ perl expenses.pl
         Yak Milking: + 12000   12000
             Hosting: -  1200   10800
                 DSL: -   840    9960
         Electricity: -  1200    8760
           PowerBook: -  3500    5260
            Mac mini: -  2230    3030
                iPod: -   500    2530
  iTunes Music Store: -   360    2170
           ORA Books: -  1440     730
                Jolt: -   720      10

Hm...maybe I better rethink this career in yak milking.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • print "You can't have one\n" for @fromApple;
  • Mmm, neat! I wanted to get one little bit of syntactic sugar in there, but that made it more complicated than I was hoping:

    use strict;
    use warnings;

    package Calc;

    use base 'Exporter';
    our @EXPORT = qw( income expense monthly );

    sub income {
        my ( $type, $amount ) = @_;
        __PACKAGE__->new( $type, $amount );
    }

    sub expense {
        my ( $type, $amount ) = @_;
        __PACKAGE__->new( $type, -$amount );
    }

    sub monthly {
        my $self = shift;
        $self->{

    • That's a really good idea. Here's a different approach:

      no strict 'refs';
      sub monthly ($$$) {
          my ($function, $type, $amount) = @_;
          &$function($type, $amount * 12);
      }

      sub quarterly ($$$) {
          my ($function, $type, $amount) = @_;
          &$function($type, $amount * 4);
      }

      sub biweekly ($$$) {
          my ($function, $type, $amount) = @_;
          &$function($type, $amount * 26);
      }

      sub weekly ($$$) {
          my ($function, $type, $amount) = @_;

      • Yuck. I don't think the Schemers have much more appreciation for symrefs than the Perlistas. :-)

        The difference is I wanted to be able to easily throw more qualifiers into the mix:

        sub bi {
            my $self = shift;
            $self->{ amt } /= 2;
            return $self;
        }

        # and later:

        bi monthly expense Whatever => 100;

        It didn't start out OO. Initially I tried to just pass closures up the call chain. That didn't work too well though: I had to check wantarray everywhere to do the printin