Just a Little Program... to be sure. · 7 days ago by Dylan Doxey
Some things are just obviously correct and you go about your business doing things the correct way until one day you realize there's a better way.
For example, you're going about your business, about to populate an array with regex matches and you might wonder, "Does it really need to be done in a loop?"
1 #!/usr/bin/perl -Tw
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6
7 my $text = "
8 abc123abc
9 abc123abc
10 abc123abc
11 abc123abc
12 ";
13
14 my $regex = qr{ ( \d+ ) }xms;
15
16 {
17 my @matches = $text =~ $regex;
18
19 print 'A: ' . Dumper( \@matches ) . "\n";
20 }
21 {
22 my @matches = $text =~ m/$regex/g;
23
24 print 'B: ' . Dumper( \@matches ) . "\n";
25 }
26 {
27 my @matches;
28 while ( $text =~ m/$regex/g ) {
29
30 push @matches, $1;
31 }
32
33 print 'C: ' . Dumper( \@matches ) . "\n";
34 }
If you're still reading, then it's probably not obvious to you... as it now is to me.
Long story short, here's what you get:
1 A: $VAR1 = [ 2 '123' 3 ]; 4 5 B: $VAR1 = [ 6 '123', 7 '123', 8 '123', 9 '123' 10 ]; 11 12 C: $VAR1 = [ 13 '123', 14 '123', 15 '123', 16 '123' 17 ];
Happy computing.

Permutations · 11 days ago by Dylan Doxey
Last night was was thinking to myself, "Self, I sure would like a list of all the permutations of these characters in a string of size n."
That's the point when I set myself to work and produced this little snippet of code.
1 sub permute {
2 my ($letters_ra,$size) = @_;
3
4 return
5 if not $size;
6
7 my $words_ra = permute( $letters_ra, $size - 1 );
8
9 return $letters_ra
10 if not @{ $words_ra || [] };
11
12 my @words;
13
14 for my $word (@{ $words_ra }) {
15
16 for my $letter (@{ $letters_ra }) {
17
18 push @words, "$letter$word";
19 }
20 }
21
22 return \@words;
23 }
Yea, that gets the job done.
27 # create a list of a-z
28 my @letters = map { chr $_ } ( 97 .. 122 );
29
30 # create a list of all four letter words
31 my $words_ra = permute( \@letters, 4 );
Now that we've got this list laying around, let's see if we can register any of them as domains.
35 use LWP::Simple qw( get );
36
37 WORD:
38 for my $word (@{ $words_ra }) {
39
40 my $json = get( "http://instantdomainsearch.com/services/quick/?name=$word" );
41
42 my ($com,$net,$org) = $json =~ m{'name':'$word','com':'(\w+)','net':'(\w+)','org':'(\w+)'}xms;
43
44 next WORD
45 if "$com$net$org" eq 'uuu';
46
47 print "$word: com:$com, net:$net, org:$org\n";
48 }
That's going to be 264 domain lookups which average around 1 second per. That should take about 42 hours to run.
I've found that just because instantdomainsearch.com reports it as available, doesn't mean it's available.
Happy computing.

Booting From a Thumb-Drive? · 175 days ago by Dylan Doxey
Who needs it? That's just bragging rights for nerds!
That is, unless you need it.
I bought the Shuttle SA76G2 bare bones system, AMD Pantheon II, and 4GB of memory. This should make a nice little desktop workstation.
I slapped it all together, started it up, and popped in the Ubuntu 9.04 install disk. I entered the BIOS setup and set the the book disk priority to go to CDROM first.
That should do it. Right?
Wrong.
Evidently this machine doesn't support ISOLINUX, and therefore won't boot from the Ubuntu installer disk.
Cutting a long story short -- I found the solution in using a Smart Boot Manager image to boot the machine on a thumb-drive, which in turn presents you with a menu asking what your preferred boot device is.
Yes!
The procedure goes a little something like this:
- working from another fully functional machine ...
- pop in the thumb drive
- unmount the thumb drive
- format the thumb drive (presumed necessary)
- install the Smart Boot Manager image -- sbm.bin
- remove the thumb drive
- stick it in the crippled machine (assuming crippled can be defined as lacking ISOLINUX support)
- put the Ubuntu install disk in
- fire it up
- if necessary, ensure that USB devices are in the boot device sequence
- allow boot process to go about its business
- wait for the SBM boot device selection menu
- select the CDROM
- observe normal CDROM booting occur before your very eyes
The key component here is the sbm.bin Smart Boot Manager image file which I found by poking around on the Ubuntu install disk.
/media/cdrom/install/sbm.bin
Those of you who may have worked with Chilton's automotive repair manuals might have noticed the occasional directive such as, "Next remove the exhaust manifold." But as you proceed it is immediately apparent that this operation deserves more than a casual one line mention. This would be the case above when I stated, "install the Smart Boot Manager image -- sbm.bin".
Here's a play by play.
After plugging the thumb drive in, you'll need to know what device it is. (You'll be pleased to know that it's really really hard to accidentally format your primary boot device in Linux.)
dylan@doxey.org:~/Desktop$ sudo fdisk -l
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x000c4861
Device Boot Start End Blocks Id System
/dev/sda1 * 1 59483 477797166 83 Linux
/dev/sda2 59484 60801 10586835 5 Extended
/dev/sda5 59484 60801 10586803+ 82 Linux swap / Solaris
Note: sector size is 4096 (not 512)
Disk /dev/sdc: 7952 MB, 7952142336 bytes
217 heads, 32 sectors/track, 279 cylinders
Units = cylinders of 6944 * 4096 = 28442624 bytes
Disk identifier: 0x20202020
Device Boot Start End Blocks Id System
/dev/sdc1 1 280 7765508 b W95 FAT32
Partition 1 has different physical/logical beginnings (non-Linux?):
phys=(0, 1, 1) logical=(0, 1, 32)
Partition 1 has different physical/logical endings:
phys=(120, 216, 32) logical=(279, 126, 32)
Disk /dev/sdb: 129 MB, 129236992 bytes
8 heads, 32 sectors/track, 986 cylinders
Units = cylinders of 256 * 512 = 131072 bytes
Disk identifier: 0xfd266c52
Device Boot Start End Blocks Id System
/dev/sdb1 * 1 986 126192 6 FAT16
That's the little bugger at the bottom: /dev/sdb1. (I think there is probably a better way to identify your thumb drive. But you can be pretty sure by removing the thumb drive and observing fdisk -l one more time. In my case there's just nothing else that would be FAT 16. Gosh!)
Doing fdisk -l is generally an intert action -- but you do need to do it as root to see anything useful.
Format the thumb drive.
dylan@doxey.org:~/Desktop$ sudo mkfs.ext3 /dev/sdb1 mke2fs 1.41.4 (27-Jan-2009) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 251968 inodes, 1007612 blocks 50380 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=1031798784 31 block groups 32768 blocks per group, 32768 fragments per group 8128 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 36 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
Obviously there's nothing inert about formatting a storage device. But you'll find it's hard to format something you didn't mean to.
Now add the SBM image.
dylan@doxey.org:~/Desktop$ sudo dd if=/media/cdrom/install/sbm.bin of=/dev/sdb1 2880+0 records in 2880+0 records out 1474560 bytes (1.5 MB) copied, 0.934536 s, 1.6 MB/s
Now your thumb drive is suitable for booting up and providing an alternate means of directing the machine which device to boot from.
Now that's something worth bragging about!
Happy computing.

Parsing HTML · 270 days ago by Dylan Doxey
Did you every think to yourself, "I wish I could split this HTML document up into an array of tokens with descriptive keys."?
Well, it's occurred to me. So here's what I came up with.
package Dox::Parser;
use strict;
use warnings;
{
use Carp;
use File::Slurp qw( slurp );
}
my (%TYPE_REGEX_FOR,@TYPES);
{
use Readonly;
# HTML identifiers may have : or - such as xml:lang or http-equiv.
# No recognition of mixed case HTML identifiers such as <Body> or <Title>.
my $ident_re = qr{ (?: [a-z:-]+ | [A-Z:-]+ ) }xms;
# Quoted strings may contain backlash escaped quotes
my $q_str_re = qr{ ' (?: [\\]['] | [^'] )* ' }xms;
my $qq_str_re = qr{ " (?: [\\]["] | [^"] )* " }xms;
Readonly %TYPE_REGEX_FOR => (
terminal_tag => qr{ ( < \s* / \s* $ident_re [^>]* > ) }xms,
begin_tag => qr{ ( < \s* $ident_re ) }xms,
end_tag => qr{ ( /? > ) }xms,
template_code => qr{ ( \[% \s* .+? \s* %\] ) }xms,
open_comment => qr{ ( <!-- ) }xms,
close_comment => qr{ ( --> ) }xms,
open_doctype => qr{ ( <!DOCTYPE ) \s }xms,
attribute => qr{ ( $ident_re \s*=\s* (?: $q_str_re | $qq_str_re ) ) [\s/>] }xms,
html_word => qr{ ( $ident_re ) \s }xms,
quoted_string => qr{ ( $q_str_re | $qq_str_re ) }xms,
whitespace => qr{ ( \s+ ) }xms,
content => qr{ ( [^<]+? ) (?: \[ [%] | [<] ) }xms,
);
# The priority of types in evaluating
# the leading characters of the HTML string.
Readonly @TYPES => qw(
open_doctype
open_comment
close_comment
whitespace
terminal_tag
begin_tag
end_tag
attribute
html_word
quoted_string
template_code
content
);
}
sub new {
my ($class,$filename) = @_;
croak "can't find $filename\n"
if !stat $filename;
# Memory usage concerns? Sorry. :(
my $html = slurp( $filename );
my $self = bless {
html => $html,
last_token => [],
}, $class;
return $self;
}
sub next_token {
my $self = shift;
my $html = $self->{html};
for my $type (@TYPES) {
my $regex = $TYPE_REGEX_FOR{$type};
if ( $html =~ m/\A $regex /xms ) {
my $token = $1;
$self->{html} = substr $html, length $token;
push @{ $self->{last_token} }, $token;
return { type => $type, token => $token, };
}
}
return;
}
sub push_back {
my ($self,$token) = @_;
$self->{html} = $token . $self->{html};
return length $token;
}
1;
Here's a little program, which I like to call parser_tester.pl, which demonstrates this baby in action.
#!/usr/bin/perl
use strict;
use warnings;
{
use lib qw( . );
use Dox::Parser;
use File::Slurp qw( write_file );
use Term::ANSIColor qw( :constants );
}
my %filename = (
before => 'document.html',
after => 'parsed_document.html',
);
my $document_text = "";
my $parser = Dox::Parser->new( $filename{before} );
while ( my $token_rh = $parser->next_token() ) {
print "{" . $token_rh->{token} . "}";
print GREEN, "(" . $token_rh->{type} . ")", RESET;
print "\n";
$document_text .= $token_rh->{token};
}
write_file( $filename{after}, $document_text );
print RED, BOLD, "\ncreated $filename{after}\n\n", RESET;
1;
When you run parser_tester.pl you'll get an enumeration of the parsed HTML tokens, each in curly brackets, and the named token type in green (thanks to Term::ANSIColor). This program assumes you've got your sample HTML in document.html, and it will subsequently create parsed_document.html. The two files ought to be identical, which indicates the parser successfully identified all of the tokens and didn't forget anything.
Coming next: Dox::FSA -- a Finite State Automaton module which can be applied to make sense of the token stream so you can do correct and useful modifications to the HTML document.

Knowing Your File System · 285 days ago by Dylan Doxey
For a quick assessment of your drive space distribution and usage use the df command.
dylan@dev.doxey.org$: ~ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/root 15G 14G 661M 96% / varrun 2.0G 56K 2.0G 1% /var/run varlock 2.0G 0 2.0G 0% /var/lock udev 2.0G 40K 2.0G 1% /dev devshm 2.0G 0 2.0G 0% /dev/shm /dev/sda1 237M 24M 201M 11% /boot /dev/mapper/home 440G 7.8G 410G 2% /home
The -h switch indicates human readable mode.
Gosh, looks like I ought to move some of my junk under /home.
For a more granular display of where the bulk of your stuff is, use the du command.
dylan@dev.doxey.org$: ~ du -h --max-depth=1 52K ./.subversion 7.6G ./rep 9.5M ./sandbox 45M ./.cpan 4.0K ./.gnupg 64K ./bin 128K ./.vim 7.7G .
Again, the -h switch gives you the easier to read numeric values.
The --max-depth option let's you control the depth of the display. The default is unlimited depth.

My Other xorg.conf · 317 days ago by Dylan Doxey
This is the xorg.conf from my workstation at home.
# xorg.conf (X.Org X Window System server configuration file) # # You should use dexconf or another such tool for creating a "real" xorg.conf # For example: # sudo dpkg-reconfigure -phigh xserver-xorg Section "Module" Load "glx" Load "v4l" EndSection Section "Monitor" Identifier "Primary Monitor" Vendorname "BenQ" ModelName "FP202W" HorizSync 31-81 VertRefresh 56-76 Option "DPMS" UseModes "BenQ Modes" Gamma 1.0 EndSection Section "Monitor" Identifier "Secondary Monitor" Vendorname "BenQ" ModelName "FP202W" HorizSync 31-81 VertRefresh 56-76 Option "DPMS" UseModes "BenQ Modes" Gamma 1.0 EndSection Section "Screen" Identifier "Primary Screen" Device "nVidia GeForce" Monitor "Primary Monitor" DefaultDepth 24 SubSection "Display" Depth 24 Modes "1680x1050" "1600x1024" "1600x1000" "1400x1050" "1280x1024" "1440x900" "1280x960" "1366x768" "1280x800" "1152x864" "1280x768" "1024x768" "1280x600" "1024x600" "800x600" "768x576" "640x480" EndSubSection EndSection Section "Screen" Identifier "Secondary Screen" Device "nVidia GeForce" Monitor "Secondary Monitor" Defaultdepth 24 SubSection "Display" Depth 24 Modes "1680x1050" "1600x1024" "1600x1000" "1400x1050" "1280x1024" "1440x900" "1280x960" "1366x768" "1280x800" "1152x864" "1280x768" "1024x768" "1280x600" "1024x600" "800x600" "768x576" "640x480" EndSubSection EndSection Section "Device" Identifier "nVidia GeForce" Boardname "nVidia GeForce 7 Series" BusId "PCI:02:00:0" Screen 0 Vendorname "NVIDIA" Option "TwinView" "true" Option "MetaModes" "1680x1050,1680x1050" Option "HorizSync" "DFP-0: 31-81; DFP-1: 31-81" Option "VertRefresh" "DFP-0: 56-76; DFP-1: 56-76" Option "TwinViewOrientation" "DFP-1 LeftOf DFP-0" Option "ConnectedMonitor" "DFP-0,DFP-1" Driver "nvidia" Option "NoLogo" "True" EndSection Section "ServerLayout" Identifier "Default Layout" Screen 0 "Primary Screen" 0 0 Screen 1 "Secondary Screen" RightOf "Primary Screen" EndSection Section "ServerFlags" Option "DefaultServerLayout" "Default Layout" Option "Xinerama" "false" EndSection Section "Modes" Identifier "BenQ Modes" Modeline "1680x1050" 119.00 1680 1728 1760 1840 1050 1053 1059 1080 Modeline "1680x1050" 184.27 1680 1792 1976 2272 1050 1051 1054 1096 Modeline "1680x1050" 181.61 1680 1792 1976 2272 1050 1051 1054 1095 Modeline "1680x1050" 178.96 1680 1792 1976 2272 1050 1051 1054 1094 Modeline "1600x1024" 171.97 1600 1712 1888 2176 1024 1025 1028 1068 Modeline "1600x1024" 168.40 1600 1704 1880 2160 1024 1025 1028 1068 Modeline "1600x1024" 165.94 1600 1704 1880 2160 1024 1025 1028 1067 Modeline "1600x1000" 166.71 1600 1704 1880 2160 1000 1001 1004 1043 Modeline "1600x1000" 164.46 1600 1704 1880 2160 1000 1001 1004 1043 Modeline "1600x1000" 162.05 1600 1704 1880 2160 1000 1001 1004 1042 Modeline "1400x1050" 153.77 1400 1496 1648 1896 1050 1051 1054 1096 Modeline "1400x1050" 151.56 1400 1496 1648 1896 1050 1051 1054 1095 Modeline "1400x1050" 149.34 1400 1496 1648 1896 1050 1051 1054 1094 Modeline "1280x1024" 136.57 1280 1368 1504 1728 1024 1025 1028 1068 Modeline "1280x1024" 134.72 1280 1368 1504 1728 1024 1025 1028 1068 Modeline "1280x1024" 132.75 1280 1368 1504 1728 1024 1025 1028 1067 Modeline "1440x900" 134.52 1440 1536 1688 1936 900 901 904 939 Modeline "1440x900" 132.71 1440 1536 1688 1936 900 901 904 939 Modeline "1440x900" 130.75 1440 1536 1688 1936 900 901 904 938 Modeline "1280x960" 128.13 1280 1368 1504 1728 960 961 964 1002 Modeline "1280x960" 126.27 1280 1368 1504 1728 960 961 964 1001 Modeline "1280x960" 124.54 1280 1368 1504 1728 960 961 964 1001 Modeline "1366x768" 107.78 1368 1448 1592 1816 768 769 772 802 Modeline "1366x768" 106.19 1368 1448 1592 1816 768 769 772 801 Modeline "1366x768" 104.73 1368 1448 1592 1816 768 769 772 801 Modeline "1280x800" 105.78 1280 1360 1496 1712 800 801 804 835 Modeline "1280x800" 104.35 1280 1360 1496 1712 800 801 804 835 Modeline "1280x800" 102.80 1280 1360 1496 1712 800 801 804 834 Modeline "1152x864" 103.59 1152 1224 1352 1552 864 865 868 902 Modeline "1152x864" 102.08 1152 1224 1352 1552 864 865 868 901 Modeline "1152x864" 99.64 1152 1224 1344 1536 864 865 868 901 Modeline "1280x768" 101.60 1280 1360 1496 1712 768 769 772 802 Modeline "1280x768" 99.17 1280 1352 1488 1696 768 769 772 801 Modeline "1280x768" 97.81 1280 1352 1488 1696 768 769 772 801 Modeline "1024x768" 80.71 1024 1080 1192 1360 768 769 772 802 Modeline "1024x768" 79.52 1024 1080 1192 1360 768 769 772 801 Modeline "1024x768" 78.43 1024 1080 1192 1360 768 769 772 801 Modeline "1280x600" 77.82 1280 1344 1480 1680 600 601 604 626 Modeline "1280x600" 76.04 1280 1336 1472 1664 600 601 604 626 Modeline "1280x600" 75.00 1280 1336 1472 1664 600 601 604 626 Modeline "1024x600" 62.26 1024 1080 1184 1344 600 601 604 626 Modeline "1024x600" 61.42 1024 1080 1184 1344 600 601 604 626 Modeline "1024x600" 59.86 1024 1072 1176 1328 600 601 604 626 Modeline "800x600" 48.18 800 840 920 1040 600 601 604 626 Modeline "800x600" 47.53 800 840 920 1040 600 601 604 626 Modeline "800x600" 46.87 800 840 920 1040 600 601 604 626 Modeline "768x576" 44.83 768 808 888 1008 576 577 580 601 Modeline "768x576" 43.52 768 800 880 992 576 577 580 601 Modeline "768x576" 42.93 768 800 880 992 576 577 580 601 Modeline "640x480" 30.25 640 664 728 816 480 481 484 501 Modeline "640x480" 29.84 640 664 728 816 480 481 484 501 Modeline "640x480" 29.43 640 664 728 816 480 481 484 501 EndSection

Jaunty Jackalope Coming Soon · 322 days ago by Dylan Doxey
I did a fresh install on my Acer TravelMate 4200.
My first impressions:
- very attractive default login page
- wireless manager is more refined and convenient than ever
- installing restricted codecs for mplayer is pretty convenient
More to come as the impulses to write about it come.

My latest xorg.conf · 329 days ago by Dylan Doxey
I had to basically write this from scratch when I recently did a fresh Kubuntu install. Let's make sure that doesn't happen again.
# xorg.conf
Section "Module"
Load "glx"
Load "kbd"
Load "mouse"
EndSection
Section "InputDevice"
Identifier "The Keyboard"
Driver "kbd"
Option "CoreKeyboard"
Option "XkbRules" "xorg"
Option "XkbModel" "pc105"
Option "XkbLayout" "us"
EndSection
Section "InputDevice"
Identifier "The Mouse"
Driver "mouse"
Option "CorePointer"
EndSection
Section "Monitor"
Identifier "Left Monitor"
VendorName "DELL"
ModelName "DELL 1907FP"
HorizSync 30.0 - 81.0
VertRefresh 56.0 - 76.0
EndSection
Section "Monitor"
Identifier "Right Monitor"
VendorName "DELL"
ModelName "DELL 1907FP"
HorizSync 30.0 - 81.0
VertRefresh 56.0 - 76.0
EndSection
Section "Screen"
Identifier "Right Screen"
Monitor "Right Monitor"
Device "Video Card A"
Option "TwinView" "True"
DefaultDepth 24
EndSection
Section "Screen"
Identifier "Left Screen"
Monitor "Left Monitor"
Device "Video Card B"
Option "TwinView" "True"
EndSection
Section "Device"
Identifier "Video Card A"
BusID "PCI:1:0:0"
Screen 0
VendorName "nVidia Corporation"
BoardName "GeForce 7300 LE"
Driver "nvidia"
Option "NoLogo" "True"
EndSection
Section "Device"
Identifier "Video Card B"
BusID "PCI:1:0:0"
Screen 1
VendorName "nVidia Corporation"
BoardName "GeForce 7300 LE"
Driver "nvidia"
Option "NoLogo" "True"
EndSection
Section "ServerLayout"
Identifier "Default Layout"
Screen 0 "Right Screen"
Screen 1 "Left Screen" LeftOf "Right Screen"
InputDevice "The Keyboard" "CoreKeyboard"
InputDevice "The Mouse" "CorePointer"
EndSection
Section "ServerFlags"
Option "Xinerama" "0"
DefaultServerLayout "Default Layout"
EndSection

Charile Rose · 358 days ago by Dylan Doxey
I've taken quite a liking to watching Charlie Rose.
A conversation with Reid Hoffman of LinkedIn
http://www.charlierose.com/view/interview/10128
A conversation with Marissa Mayer, V.P. of Search Product and User Experience, Google
http://www.charlierose.com/view/interview/10129
A conversation with entrepreneur and software engineer Marc Andreessen
http://www.charlierose.com/view/interview/10093
A conversation with Evan Williams, Co-founder of Twitter.com
http://www.charlierose.com/view/interview/10118
A conversation with Jen-Hsun Huang, CEO Nvidia
http://www.charlierose.com/view/interview/10060
A conversation with Chris DeWolfe And Tom Anderson, founders of Myspace.com
http://www.charlierose.com/view/interview/10054
A conversation with Arianna Huffington
http://www.charlierose.com/view/interview/9705
A conversation with Eric Schmidt, CEO of Google
http://www.charlierose.com/view/interview/10131
A conversation with Jeff Bezos, Amazon.com
http://www.charlierose.com/view/interview/10105

Like ZipRealty.com... almost? · 447 days ago by Dylan Doxey
I like ziprealty.com because it's not trying to impress you with all the wistles, bells and gadgets.
You can set some criterion, search, and look at results.
But I want more. Well, actually I want less. I want fewer things distracting me and cluttering up the page.
So I wrote this GreaseMonkey script to help out.
Features:
- Strips nearly all superfluous text and up-sell promos.
- House detail links open in another window/tab.
- House address headers link to Google Maps on detail view.
- My Homes view has a tidy list suitable for cut & paste into an email for your agent.
ZipRealty give you enough information that you can nearly do your agent's job for him/her. And why not? I enjoy browsing the houses and composing my weekend visit lists.
Happy house shopping!

