tags:

views:

114

answers:

1

Hey,

I'm trying to write a program that will calculate the dividends of stocks. I did this without a subroutine. Right now, I'm trying to modify it so it can run using a recursive routine. Any help with this? Because I'm not so good at this.

Here's the original script + a pathetic attempt.

print "A stock xyz's price is now $100. It has 3.78% dividend. You have 1000 of it and reinvest the dividend into the stock.\n"; 

my %hash; 
@stocknum = 1000; 
@dividend = 6780; 

while ($#dividend != 20) { 
    $a = $dividend[-1]; 
    $stock = $stocknum[-1]; 
    $div_total= $stock*100*0.0678; 

    $stock_total = $stock + int($a/100); 
    push (@stocknum, $stock_total);  
    push (@dividend, $div_total); 

    if ($#dividend == 20) { 
        last; 
    } 
} 

shift (@dividend); 
$stock_num = $stocknum[-1]; 
$div = $stock_num*100*0.0678; 
push (@dividend, $div); 
@hash{@stocknum} = @dividend; 

foreach $key(sort keys %hash) { 
    print "Stock number: $key\t"."Dividend: $hash{$key}\n";  
}  

$dividend=0.0378; 
+5  A: 

I don't think you want recursion. I think you just want to loop over the number of cycles of payouts that you're after. It looks like you're getting all mixed up with arrays for some reason.

print <<'HERE';
A stock xyz's price is now $100. It has 6.78% dividend. 
You have 1000 of it and reinvest the dividend into the stock.

HERE

my $shares   = 1000;
my $price    =  100;
my $dividend =    6.78 / 100;
my $cycles   = $ARGV[0] || 20;

foreach ( 1 .. $cycles ) {
    local $cycle      = $_;
    local $payout     = $shares * $dividend * $price;
    local $new_shares = $payout / $price;

    write();

    $shares += $new_shares;
    }

format STDOUT =
@###    @####.######    @#####.#######    @##.######  @####.######
$cycle, $shares,          $payout,          $new_shares, $shares+$new_shares, 
.

format STDOUT_TOP =
                        @##.####%
                        $dividend
Cycle   Shares          Payout          New Shares  Total Shares
----------------------------------------------------------------
.

This gives me the output:

A stock xyz's price is now $100. It has 6.78% dividend. 
You have 1000 of it and reinvest the dividend into the stock.

                          0.0678%
Cycle   Shares          Payout          New Shares  Total Shares
----------------------------------------------------------------
   1     1000.000000      6780.0000000     67.800000   1067.800000
   2     1067.800000      7239.6840000     72.396840   1140.196840
   3     1140.196840      7730.5345752     77.305346   1217.502186
   4     1217.502186      8254.6648194     82.546648   1300.048834
   5     1300.048834      8814.3310942     88.143311   1388.192145
   6     1388.192145      9411.9427423     94.119427   1482.311572
   7     1482.311572     10050.0724603    100.500725   1582.812297
   8     1582.812297     10731.4673731    107.314674   1690.126971
   9     1690.126971     11459.0608610    114.590609   1804.717579
  10     1804.717579     12235.9851873    122.359852   1927.077431
  11     1927.077431     13065.5849830    130.655850   2057.733281
  12     2057.733281     13951.4316449    139.514316   2197.247597
  13     2197.247597     14897.3387104    148.973387   2346.220985
  14     2346.220985     15907.3782750    159.073783   2505.294767
  15     2505.294767     16985.8985220    169.858985   2675.153752
  16     2675.153752     18137.5424418    181.375424   2856.529177
  17     2856.529177     19367.2678194    193.672678   3050.201855
  18     3050.201855     20680.3685775    206.803686   3257.005541
  19     3257.005541     22082.4975671    220.824976   3477.830517
  20     3477.830517     23579.6909021    235.796909   3713.627426

Don't worry about my use of format; I've had that on the brain this weekend since I rewrote some perlfaq stuff about it then also turned it into Use formats to create paginated, plaintext reports. You could just as easily created the output with printf:

print <<'HERE';
A stock xyz's price is now $100. It has 6.78% dividend. 
You have 1000 of it and reinvest the dividend into the stock.

Cycle   Shares          Payout          New Shares  Total Shares
----------------------------------------------------------------
HERE

my $shares   = 1000;
my $price    =  100;
my $dividend =    6.78 / 100;
my $cycles   = $ARGV[0] || 20;

foreach ( 1 .. $cycles ) {
    my $payout     = $shares * $dividend * $price;
    my $new_shares = $payout / $price;

    printf "%4d   %12.6f    %12.6f    %10.6f  %12.6f\n",
        $_, $shares, $payout, $new_shares, $shares + $new_shares;

    $shares += $new_shares;
    }

As a side note, you really don't ever want recursion, and especially not in Perl if you can help it. Other languages get away with it because they know how to unroll your recursion to turn it into an iterative process. Perl, being a dynamic language, can't really do that because it doesn't know if the subroutine will have the same definition on the next go around. It's nice as a computer science topic because it makes the programming marginally easier and they know it all works out in the end. I think I talk about this in Mastering Perl somewhere, but Mark Jason Dominus covers it extensively in Higher-Order Perl. Basically, instead of recursion you use a queue, which is a better skill to practice anyway.

brian d foy