push to a referenced array
on Sep 27, 2008 at 16:10
|
2 replies
|
by biga
|
This useful function performs 'push' into a referenced array. It creates the array if it doesn't exist.
SYNOPSIS:
my $a={};
ref_push $a->{ARRAY}, "some", "list";
But the code is a bit obfuscated... %)
sub ref_push{$_[0]?push@{+shift},@_:shift@{$_[0]=[@_]}}
|
Generate uniform random partitions of a number
on Sep 25, 2008 at 12:00
|
1 reply
|
by ambrus
|
The following snippet shows how to generate uniform random partitions of a number fast.
Take the following definitions.
use strict;
my %npart; sub cntpart1 { my($n, $m) = @_; $n = 0+$n; $m = 0+$m; my $c
+ = \$npart{$n." ".$m}; defined($$c) and return $$c; $n <= 0 and retur
+n $$c = 1; my $s = 0; for my $k (1 .. ($m < $n ? $m : $n)) { $s += cn
+tpart1($n - $k, $k); } $$c = $s; }
sub randpart1 { my($n, $m) = @_; $n <= 0 and return; my($s, $k) = 0; f
+or my $j (1 .. ($m < $n ? $m : $n)) { my $p = cntpart1($n - $j, $j);
+rand($s += $p) < $p and $k = $j; } $k, randpart1($n - $k, $k); }
sub randpart { my($n) = @_; randpart1($n, $n); }
Then randpart($n) generates a random partition with uniform probablity among all partitions of the positive integer $n.
Update: You may want to add a no warnings "recursion";
Update 2008 sep 28: Limbic~Region referred me to his code RFC: Integer::Partition::Unrestricted which computes the number of partitions of any integer really fast. I'll have to read its implementation on whether it can help here.
|
generating random thruth-tables
on Sep 24, 2008 at 09:34
|
1 reply
|
by neniro
|
I needed a bunch of truth-tables, with random result-rows, as exercises for logical minimization. An easy task utilizing Perl:
perl -e "print sprintf('%03b',$_).' '.int(rand()+0.5).$/ for 0..7"
|
ISO 8601 week number
on Sep 11, 2008 at 06:09
|
2 replies
|
by wol
|
Many businesses operate along according to week numbers and ignore months completely, so perl-y business apps may need to calculate them. ("We synergise our assets in week 42, and leverage our ducks into line in week 45", etc)
It's possible to use the Date::Manip or POSIX modules, but they both have some caveats.
Seeing as I only found how to use the above after I'd rolled my own, I thought I'd share both the information and my own solution, so that (crossed fingers) Google might help anyone else needing the same...
Using POSIX:
$weekNum = POSIX::strftime("%V", gmtime time);
(However, this only works on systems where the POSIX implementation meets the "Single Unix" specification. Hence my system (WinXP) just returns "%V", which is less than useful...)
Using Date::Manip:
$weekNum = UnixDate(ParseDate("today"), "%W");
Using none of the above:
# Returns the week number of NOW
sub currentWeekNumber
{
# Get current year, day of year (0..364/5) day of week (0..6)
my ($year, $dayOfWeek, $dayOfYear) = (gmtime time)[5,6,7];
# Adjust DayOfWeek from American 0==Sunday, to ISO 0==Monday
# and year from "since 1900" to the real year
return weekNumber(($dayOfWeek + 6) % 7, $dayOfYear, $year + 1900);
}
# Returns the week number of the specified time
# Year is the real year
# Day of week is 0..6 where 0==Monday
# Day of year is 0..364 (or 365) where 0==Jan1
sub weekNumber
{
# Get parameters
my ($dayOfWeek, $dayOfYear, $year) = @_;
die if ($dayOfWeek < 0);
die if ($dayOfWeek > 6);
die if ($dayOfYear < 0);
die if ($dayOfYear >= 366);
die if ($year < 0);
# Locate the nearest Thursday
# (Done by locating the Monday at or before and going forwards 3 day
+s)
my $dayOfNearestThurs = $dayOfYear - $dayOfWeek + 3;
# Is nearest thursday in last year or next year?
if ($dayOfNearestThurs < 0)
{
# Nearest Thurs is last year
# We are at the start of the year
# Adjust by the number of days in LAST year
$dayOfNearestThurs += daysInYear($year-1);
}
my $daysInThisYear = daysInYear($year);
if ($dayOfNearestThurs > $daysInThisYear)
{
# Nearest Thurs is next year
# We are at the end of the year
# Adjust by the number of days in THIS year
$dayOfNearestThurs -= $daysInThisYear;
}
# Which week does the Thurs fall into?
my $weekNum = int ($dayOfNearestThurs / 7);
# Week numbering starts with 1
$weekNum += 1;
# Pad with 0s to force 2 digit representation
return substr "0"x2 . $weekNum, -2;
}
# Returns the number of...
sub daysInYear
{
return 366 unless $_[0] % 400;
return 365 unless $_[0] % 100;
return 366 unless $_[0] % 4;
return 365;
}
|
Copying a directory and its contents while displaying a status
on Aug 04, 2008 at 18:13
|
2 replies
|
by hiseldl
|
Uses File::Copy::Recursive, but wedges another 'copy' sub so that a progress bar, or some other hook, can be displayed or run.
update:
The real trick to this particular snippet is determining that File::Copy::Recursive uses File::Copy::copy, but the copy sub is imported into the File::Copy::Recursive namespace rather than its own namespace. If you try to hook File::Copy::copy, it will not work.
For completeness, thank you jdporter, here is what it would look like if Hook::LexWrap was used:
use Hook::LexWrap;
use File::Copy::Recursive qw(dircopy);
use strict;
use vars qw($dir_from $dir_to);
$dir_from = "/tmp/from";
$dir_to = "/tmp/to";
$|=1;
# Using Hook::LexWrap
my @dirs;
wrap *File::Copy::Recursive::copy,
pre => sub { @dirs = @_ },
post => sub { printf "copying %s to %s. \r", @dirs };
dircopy($dir_from, $dir_to);
print "\n";
use File::Copy::Recursive qw(dircopy);
use strict;
use vars qw($dir_from $dir_to *mycopy);
$dir_from = "/tmp/from";
$dir_to = "/tmp/to";
sub mycopy_func {
# call the original
&mycopy(@_);
# call my sub after
mycopy_showprogress(@_);
}
sub mycopy_showprogress {
# this could call anything to show progress or even
# to operate on the file being copied
printf "copying %s to %s. \r",@_;
}
$|=1;
# Add the hook
*mycopy = *File::Copy::Recursive::copy;
*File::Copy::Recursive::copy = *mycopy_func;
dircopy($dir_from, $dir_to);
print "\n";
|
Convert Gnome2::Canvas::Pixbuf to Image::Magick Array
on Jul 22, 2008 at 23:16
|
0 replies
|
by renegadex
|
This simple code will convert a Gnome2::Canvas::Pixbuf into a Image::Magick Array. Enjoy Perlmagick Programmers!
#Convert Gnome2::Canvas::Pixbuf To Image::Magick Array
sub convert_gnome2pixbuf_im {
my $pixbuf_g = shift;
print $pixbuf_g , "\n";
#Convert Gnome2::Canvas::Pixbuf To Gtk2::Gdk::Pixbuf
my $pixbuf = $pixbuf_g->get('pixbuf');
print $pixbuf , "\n";
#Convert Gtk2::Gdk::Pixbuf To BLOb
my $blob = $pixbuf->save_to_buffer('jpeg');
my $im = Image::Magick->new;
#Convert BLOb to Image::Magick Array
$im->BlobToImage($blob);
return $im
}
|
Keep FastCGI Processes Up and Running
on Jul 01, 2008 at 16:56
|
2 replies
|
by SouthFulcrum
|
A little script that checks to see if a site is up based on the response code; a response of 500 executes a shell script that kills and restarts the FastCGI processes whereas a response of 404 restarts the Web server. Oh, and keeps a little log.
#!/usr/bin/perl -w
use strict;
use WWW::Mechanize;
use DateTime;
my @urls = (
"http://mysite.net",
"http://myothersite.org"
);
# Command to execute the webrestart shell script
my $fcgi_restart = "./webrestart";
# Command to restart Lighttpd (may vary by distro)
my $lighttpd_restart = "/etc/init.d/lighttpd restart";
# Set the current date and time for the log file using DateTime from C
+PAN
my $date_time = DateTime->now;
# Set path to the log file you want to use
my $log = '/path/to/log.txt';
# Loop through each of your sites
foreach my $site (@urls) {
# Get the Status using WWW::Mechanize from CPAN
my $mech = WWW::Mechanize->new();
$mech->get( $site );
my $status = $mech->status($site);
# If there is a server error, we will restart all the FastCGI pro
+cesses.
if ($status == '500') {
system $fcgi_restart;
# Log this site failed and when
open(DAT,">>$log") || die("Cannot Open File");
print DAT "$site || $status || $date_time \n";
close DAT;
}
# If the site was not found, we will restart Lighttpd.
elsif ($status == '404') {
system $lighttpd_restart;
}
}
# Log that the sites were checked and when
open(DAT,">>$log") || die("Cannot Open File");
print DAT "Sites checked $date_time \n";
close DAT;
External shell script to kill and restart all FastCGI processes
# Thanks Russell Jurney <rjurney (at) lucision.com>
pkill -f fcgi
pkill -f fcgi-pm
pkill -9 -f fcgi
pkill -9 -f fcgi-pm
/path/to/mysite.net/fastcgi.pl -l /tmp/mysite.socket -n 3 -d
/path/to/myothersite.com/fastcgi.pl -l /tmp/mysite.socket -n 3 -d
|
Burrows-Wheeler transform
on Jul 01, 2008 at 13:48
|
1 reply
|
by shi
|
As told by wikipedia the one in the title is a transform useful when compressing data.
I spent some minutes on writing these snippets for direct and inverse transformation.
May any wise monk help shrinking the code, I'd be thankful and glad to see the results :)
$/="";$l=length($w=<>);map{print+chop}sort+map{substr"$w\0$w",$_,$l+1}
+0..$l
push@w,split//for<>;map{@_=sort@_;$_[$_]=$w[$_].$_[$_]for+0..$#w}0..$#
+w;print+grep{s/\0$//}@_
|
Regex tester
on Jun 27, 2008 at 11:45
|
3 replies
|
by oko1
|
This is something I made up for a quick tester of regexes against strings; since it remembers both, either one can be 'adjusted' as necessary. It shows not only whether the match succeeds but also anything that was captured by the memory parens. It works with stand-alone regexes, substitution expressions, and the 'tr' operator. It's not perfect - it's probably somewhat fragile - but it's worked well for me for several months now, happily parsing my regexes by the dozen. I hope others find it useful.
#!/usr/bin/perl -w
# Created by Ben Okopnik on Mon Mar 24 23:35:26 EDT 2008
# Regex Explorer
use strict qw/vars/;
use Term::ReadLine;
my $term = new Term::ReadLine 'Regex Explorer';
my $OUT = $term -> OUT || \*STDOUT;
print $OUT "Exit by entering an empty string at any prompt.\n\n";
{
my $string = $term->readline("String: ");
exit if $string =~ /^$/i;
my $regex = $term->readline("Regex: ");
exit if $regex =~ /^$/i;
if ($regex !~ /^\s*((?:y|tr|s|m)\W|\/)/){
print $OUT "The regex must be a valid match or a substitute ex
+pression.\n\n";
redo;
}
my $tr = $regex =~ /^\s*(?:y|tr)\W/ ? 1 : 0;
my $cap = $regex =~ /\([^?]/ ? 1 : 0;
# This eval should fail on anything except a match, subst, or tr
my $old_string = $string;
eval "\$string =~ $regex";
if ($@){
print $OUT "$@\n\n";
redo;
}
# Restore original after this eval
$string = $old_string;
# Variables declared in the eval must be escaped; those that aren'
+t
# will be interpreted in the scope of the surrounding script.
my $ret = eval qq%
my \$match = \$string =~ $regex;
my \$out = 'Matched: ' . (\$match ? "Yes" : "No");
if (\@+ > 1 && ! $tr && $cap){
\$out .= "\nCaptures:";
\$out .= qq" [#\$_: '" . (\${\$_} || '') . "']" for 1 .. \
+$#+;
}
return "\$out\n";
%; # End of eval
print $OUT $@ ? "\nERROR: $@\n" : "\nResult: $string\n$ret\n";
redo;
}
|
Portuguese code
on Jun 10, 2008 at 09:58
|
1 reply
|
by smokemachine
|
use perltugues;
inteiro: i, j;
texto: k;
inteiro: l;
para i (de 1 a 100 a cada 5) {
escreva i, quebra de linha;
k = "lalala";
escreva k, quebra de linha;
escreva j, quebra de linha;
}
enquanto(i >= j){
escreva 'i e j => ', i, " >= ", j++, quebra de linha;
}
escreva quebra de linha;
escreva de 0 a 50 a cada 10, quebra de linha;
|
|