List of The Dresden Files books

Quick list of the The Dresden Files books.

Number Title Paperback release date
1 Storm Front April 1, 2000
2 Fool Moon January 1, 2001
3 Grave Peril September 1, 2001
4 Summer Knight September 3, 2002
5 Death Masks August 5, 2003
6 Blood Rites August 2, 2004
7 Dead Beat May 2, 2006
8 Proven Guilty February 6, 2007
9 White Night February 5, 2008
10 Small Favor May 3, 2009
11 Turn Coat March 3, 2010
12 Changes March 11, 2011
13 Ghost Story August 7, 2012
14 Cold Days September 3, 2013
15 Skin Game March 5, 2015
16 Peace Talks July 14, 2020
17 Battle Ground September 29, 2020
Leave A Reply

Console release dates

Nintendo

System NA Release Years between
NES 1985-10-18
SNES 1991-08-23 5.8
N64 1996-09-29 5.1
Gamecube 2001-11-18 5.1
Wii 2006-11-19 5.0
WiiU 2012-11-18 5.9
Switch 2017-03-03 4.3

Microsoft

System NA Release Years between
Xbox 2001-11-15
360 2005-11-22 4.0
XB1 2013-11-22 8.0
XBSX 2020-11-10 6.9

Sony

System NA Release Years between
PS1 1995-09-09
PS2 2000-10-26 5.1
PS3 2006-11-17 6.0
PS4 2013-11-15 6.9
PS5 2020-11-12 6.9
Leave A Reply

Perl: Natural sort part deux

If you want to sort an array naturally (the way a human would) you can use Perl's sort() function, but use a custom sort method:

my @input  = qw(foo foo250 foo12 foo23 bar999 bar7 bar17 bar99 18);
my @sorted = sort { &natural } @in;

print join(", ", @sorted);
sub natural {
    # Separate the word and numeric parts
    my ($word_a, $num_a) = $a =~ /(.*?)(\d+|$)/;
    my ($word_b, $num_b) = $b =~ /(.*?)(\d+|$)/;

    #print "$a / $b: $word_a, $num_a, $word_b, $num_b\n";

    # If the words are diff it's an alpha sort on the words
    if ($word_a ne $word_b) {
        return $word_a cmp $word_b;
    # Words are the same, numeric sort the number part
    } else {
        return ($num_a || 0) <=> ($num_b || 0);
    }
}

See also: Natural Sort

Leave A Reply

Perl: Simple .ini parser

I wrote a simple .ini parsing function in Perl.

my $hash_ref = parse_ini("/tmp/config.ini");

sub parse_ini {
    open (my $INI, "<", $_[0]) or return undef;

    my $ret     = {};
    my $section = "_";

    while (my $line = readline($INI)) {
        if ($line =~ /^\[(.+?)\]/) { # Section heading
            $section = $1;
        } elsif ($line =~ /^(\w.*?)\s*=\s*"?(.*?)"?\s*$/) { # Key/Value pair
            $ret->{$section}->{$1} = $2;
        }
    }

    return $ret;
}
Leave A Reply

PHP: Serve file for download

If you want to a simple way to serve a file for download in PHP you can use this function:

function serve_file($filepath) {
    $filename = basename($filepath);

    if (headers_sent()) {
        die("Cannot output file because output already started");
    }

    $mime_type = mime_content_type($filepath);
    header("Content-type: $mime_type");
    header("Content-Disposition: attachment; filename=\"$filename\"");

    readfile($filepath);

    exit(0);
}
Leave A Reply

Perl: Loop through an array and extract pairs of variables

I had an array that I wanted to iterate through and extract pairs of variables. I found this pretty neat way to do that:

Perl:

my @arr = ("red", "green", "blue", "yellow", "orange", "purple");

while (@arr) {
    my ($x, $y) = splice(@arr, 0, 2);
    print "$x:$y\n";
}

I found a bunch of different ways to do this, and benchmarked them.

PHP:

$arr = ["red", "green", "blue", "yellow", "orange", "purple"];

while ($arr) {
    [$x, $y] = array_splice($arr, 0, 2);
    print "$x:$y<br />";
}

Note: You need to be careful you have an even number of elements or you will get undefined variable errors.

Leave A Reply

Perl: Glob recursively

I wrote a simple function to let you glob a directory recursively. It's limited to a single path/glob pattern, but that's good enough for now.

use File::Find;

my @files = globr("/etc/*.cfg");

sub globr {
    my ($str)       = @_;
    my ($dir,$glob) = $str =~ m/(.*\/)(.*)/;

    $dir  ||= './'; # Only a glob, so assume current dir
    $glob ||= $str; # No dir only a glob: *.pl

    # Find all the dirs in the target dir so we can recurse through them later
    my (@ret, @dirs);
    find( { wanted => sub { if (-d $_) { push(@dirs, $_) } }, no_chdir => 1 }, $dir);

    # Go through each dir we found above and glob in them for matching files
    foreach my $dir (@dirs) {
        my @g = glob("$dir/$glob");
        push(@ret, @g);
    }

    return @ret;
}

See also: Find files recursively

Leave A Reply

Perl: Prepend a script before script execution

I need to prepend some code before I run my Perl script. In my prepended script I will set some debug variables and add some debugging subroutines. The easiest way I've found to do this is with the -I and -M parameters. This allows you to set an include directory, and a specific module to be loaded before your script starts.

I was able to create a debug.pm in my /tmp/ directory and prepend it to my Perl script like this:

perl -I/tmp/ -Mdebug my_script.pl

This tells Perl to add /tmp/ to the list of locations to look for modules, and then to load the module debug. Then you simply make a debug.pm that includes the global variables you want to include and your main script will be able to read them.

Leave A Reply

Oral Rehydration Solution Recipes

I found these recipes on a post related to Liquid I.V. and Drip Drop. I'm going to copy them here just in case.

Orange juice base

3/4 tsp salt
8 tsp sugar
1 cup unsweetened orange juice without pulp
4 1/2 cups of water

Grape juice base

1/2 cup juice
3 1/2 cups water
1/2 tsp salt

Gatorade base

Choose any flavor, except red
2 cups Gatorade
2 cups water
1/2 tsp salt

Apple juice base

1 cup of juice
3 cups of water
1/2 tsp salt

Leave A Reply

Perl: Find files recursively

I needed to search recursively through a directory structure for files that matched a specific pattern. The simplest way that I found was using File::Find. I wrote a simple wrapper function to make searching simpler and more straight-forward. It uses regular expression matching so it should be quite flexible.

# All the files that end in .pl
my @perl_files = find_recurse(qr/\.pl$/, "/home/user/");
# Anything with kitten in the name
my @kittens    = find_recurse(qr/kitten/, "/home/user/");
# All .mp3 and .ogg files
my @aud_files  = find_recurse(qr/\.(mp3|ogg)$/, "/home/user/");
# Search two directories
my @cfg_files  = find_recurse(qr/\.cfg$/, ("/tmp/", "/etc/"));
use File::Find;

# Recursively search for files matching a pattern
sub find_recurse {
    my ($pattern, @dirs) = @_;
    if (!@dirs) {
        @dirs = (".");
    }

    my @ret = ();
    find(sub { if (/$pattern/) { push(@ret, $File::Find::name) } }, @dirs);

    return @ret;
}
Leave A Reply

Disable Caps Lock and Num Lock

The only time I ever hit the Caps Lock key is by accident. When I do it messes up everything that I'm working on and I have to go back and fix things. Same thing with Num Lock! If you use these quick xmodmap commands you can disable those keys and avoid some headaches.

# Disable: Capslock, Numlock
xmodmap -e "keycode 66 ="
xmodmap -e "keycode 77 ="
Leave A Reply

Winamp: Opus plugin for Winamp

Winamp will always have a special place in my heart. Luckily it's still semi-maintained and runs great on Windows 10. It plays a bunch of audio file types out of the box, but lacks .opus support. Luckily someone wrote a plug-in to read opus files.

I've mirrored it here just in case.

Leave A Reply

Perl: Parse Linux log time strings

Linux has a common date/time format used in logs that looks like May 4 01:04:16. Often I will need to parse that into a unixtime so I wrote a function to do it so I won't have to reinvent the wheel next time:

use Time::Piece;

my $epoch = linux_timestr("May  4 01:04:16");

sub linux_timestr {
    my $time_str = shift();
    # Since this string type doesn't include the year we append the current
    # year to make the calculations correct. Otherwise we get 1970
    my $year     = (localtime())[5] + 1900;
    $time_str   .= " $year";

    my $format = "%b %d %H:%M:%S %Y";
    my $x      = localtime->strptime($time_str, $format);

    return $x->epoch();
}

Other common formats are cdate and ISO 8601

# cdate
my $x = localtime->strptime("Sat May  8 21:24:31 2021", "%a %b %d %H:%M:%S %Y");
# ISO 8601
my $y = localtime->strptime("2000-02-29T12:34:56", "%Y-%m-%dT%H:%M:%S");
Leave A Reply

PHP: Either function because PHP lacks a good "or"

PHP lacks a good "or" comparison operator. Neither the or operator, nor the || return a value. I wrote a function that will take two (or more) variables and return the first one that has a non-zero value.

$limit = $array_count || 15;       // true (bad!)
$limit = either($array_count, 15); // 15 (good!)

function either() {
    $items = func_get_args();

    // Return the first non-empty item
    foreach ($items as $x) {
        if (!empty($x)) {
            return $x;
        }
    }

    return null;
}
Leave A Reply

Perl: Rounding a number

If you need to round a number in Perl you can use the POSIX method round(). If for some reason you don't want to use the POSIX method I wrote a pure Perl version of round() that is pretty fast.

use POSIX;

my $num = 3.14156;

print(POSIX::round($num)); # 3
print(round($num));        # 3

sub round {
    my $num = shift();

    if ($num < 0) {
        $ret = int($num - 0.5);
    } else {
        $ret = int($num + 0.5);
    }

    return $ret;
}

Along with round, sometimes you want "round to the nearest X", which I also implemented:

sub nearest {
    my ($num, $nearest) = @_;

    my $div = $num / $nearest;
    my $ret = round($div) * $nearest;

    return $ret;
}
Leave A Reply