Monday, April 1, 2013

Messing with GD::Image

I spent the other day tweaking GD::Image to plot the I quadrant of a cartesian plane for me. I learned some basic things about Perl again, so I thought I would share them.


Plotting the Square Root

So the issue with this was that it was upside down. This is due to GD--and just about every other image creation and manipulation program--considering the top left corner to be (0,0). X corresponds to the width and Y corresponds to the height. We fix this by mapping the Y to the $height - ($x ** 2). The next thing that needed overcome was widening the view of these points so it seems "zoomed in." This was accomplished by multiplying each point in @x_point by 10 after calculating the @y_point from it.
Before multiplying x by 10
After multiplying x by 10 

Then, I was trying to connect each point with lines. The error I had lied in the fact that the order in which lines are connected matters. The default rule for sort is to sort by character alone. This left me connecting the points in a strange fashion. If the points were ordered by ASCII value...

I was trying to debug this, which generated some interesting pictures. I started by making sure the x coordinates were only going to my mapped origin (0, $height). This made a feather-like fractal I suppose. The next picture is an attempt which always plotted the same y coordinate but changed x coordinates. These were still being sorted in the wrong order. After that, I properly ordered the keys. And then the final product was me allowing the y coordinate to change too.

 



























After that, I started playing with some random points. This was taken from the rand() function. The last two are different zoom factors.
 



Saturday, March 16, 2013

Chomp vs Chop in Perl

use strict;
use warnings;

#The difference between chomp and chop is that chomp only removes newlines

my $test = "123\n";
print "Original: " . $test . " Chomped: " . chomp($test);

#chop doesn't care what it removes
do {
    print "Iterating: $test\n";
} while (chop($test) ne "");

#outputs:
#Original: 123
# Chomped: 1Iterating: 123
#Iterating: 12
#Iterating: 1
#Iterating:
Next is a slightly more elegant way to take user input and chop the last part of it. End the loop with ^D or ^C (EOF will give you a undefined error that we fix in the next bit of code).
use strict;
use warnings;

while (chomp(my $test = <STDIN>)) {
    last if $test eq "";
    do {
        print "$test\n";
    } while (chop($test) ne "");
}
#outputs:
#antidisestablishmentarianism
#antidisestablishmentarianism
#antidisestablishmentarianis
#antidisestablishmentariani
#antidisestablishmentarian
#antidisestablishmentaria
#antidisestablishmentari
#antidisestablishmentar
#antidisestablishmenta
#antidisestablishment
#antidisestablishmen
#antidisestablishme
#antidisestablishm
#antidisestablish
#antidisestablis
#antidisestabli
#antidisestabl
#antidisestab
#antidisesta
#antidisest
#antidises
#antidise
#antidis
#antidi
#antid
#anti
#ant
#an
#a
#
The following will make a very inefficient reverse function, but as you can see chop's return value is the tail of the string.
use strict;
use warnings;

my @reverso = ();
while (defined (my $test = <STDIN>)) {
    chomp($test);
    last if $test eq "";
    my $tail;
    do {
        print "$test\n";
        $tail = chop($test);
        push @reverso, $tail;
    } while ($tail ne "");
}

print @reverso;
#end the loop with EOF!
#msinairatnemhsilbatsesiditna

Friday, March 15, 2013

What I Learned about Perl Today

Today I ran into an issue where I needed to redirect STDERR to STDOUT in a Perl script. So, I figured the easiest way would be to redirect those two files somehow. Perl provides a relatively elegant way to do so. Running open(STDERR, '>&STDOUT') will do the trick by overwriting the STDERR filehandle with a duplicate of the STDOUT filehandle in writing mode. In the Perl open documentation, the examples show the programmer saving the previous STDERR filehandle and restoring it at the end of the interactions, but I didn't require any such thing because the script ends after execution.