Python: Null coallesce on a list

I have a small list in Python, and I need to get the 2nd element of that list, or a default value if it's not present. All the other languages (PHP, Perl, Javascript) I'm used to have a simple null coallescing operator that makes it simple, but not Python. I got tired of writing it out every time to so I wrote a simple wrapper function:

x = [1,2,3]

# Get the 3rd item from x
y = list_item_default(x, 2, -1) # 3
# Get the 7th (non-existent) item from x
y = list_item_default(x, 7, -1) # -1
# Get an item from a list, or a default value if the array isn't big enough
def list_item_default(mylist, num, default = None):
    if num > len(mylist) - 1:
        return default
    else:
        return mylist[num]

If there is a better, simpler, built-in way I'm open to hearing it.

Leave A Reply

Linux: fd is a much better file search

Linux has had the find command since the 1970s. It was probably great in it's day, but it's not very modern and isn't the most intuitive tool. I found fd (sometimes called fd-find) which is infinitely better and easier to use. If you're looking for a simple way to search your filesystem, it's the way to go.

fd-find is hosted on Github.

Leave A Reply

Arduino: Get IP and MAC address

Here is a quick way to get the IP address and/or MAC address from your Arduino device as a String.

String get_mac_addr() {
    uint8_t mac[6];
    WiFi.macAddress(mac); // Put the addr in mac

    char buf[18] = "";
    snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    return (String)buf;
}
String get_ip_addr() {
    IPAddress ip = WiFi.localIP();

    char buf[16];
    snprintf(buf, sizeof(buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

    return (String)buf;
}
Leave A Reply

Arduino: Connect to WiFi

Quicky helper function to connect to WiFi on Arduino so I don't have to re-invent the wheel every time I start a new project.

void init_wifi(const char *ssid, const char *password) {
    WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500); Serial.print(".");
    }

    Serial.printf("\r\nConnected to: \"%s\"\r\n",ssid);
    Serial.print("IP address  : "); Serial.println(WiFi.localIP());
    Serial.print("MAC address : "); Serial.println(WiFi.macAddress().c_str());
}
Leave A Reply

Arduino: ESP32-S2 USB modes

I picked up some new ESP32-S2 boards to play around with. These newer boards come with native USB on board, instead of a separate USB to serial chip to handle communications. With this new chip, there are some new USB acronyms in the Arduino menus. I kept getting them confused so I looked them all up and am committing them here for future reference.

Mode Explanation
USB DFU Device Firmware Upgrade: Upload mode
USB CDC Communication and Data Control: UART/Serial mode
USB MSC Mass storage device class
USB HID Human Interface Device: Mouse/Keyboard emulation
Leave A Reply

Comparison table for ESP boards

Simplified table of ESP boards with components I care about.

ESP8266 ESP32 ESP32-S2 ESP32-S3 ESP32-C3
GPIO 17 34 43 45 22
CPU 1x @ 160Mhz 2x @ 240Mhz 1x @ 240Mhz 2x @ 240Mhz 1x @ 160Mhz
Architecture Tensilica Tensilica Tensilica Tensilica RISC-V
RAM 160K 520K 320K 512K 400K
Touch Pins 0 10 14 14 0
Bluetooth No 4.2 No 5.0 5.0
USB OTG No No Yes Yes No

More details and Espressif product comparison

Note: Assume about eight pins are used internally to connect flash and other peripherals.

Leave A Reply

Force SSH to ask for a password and skip keys

Normally I use SSH keys (with a password) to login to remote machines. Today I needed to force SSH to use a password to verify a change. Here is the command:

ssh -o PubkeyAuthentication=no user@server.domain.com

Leave A Reply

Books of 2023

List of books I read in 2023. Also see the list of 2022. The date indicated denotes the date I started reading the book.

2023-01-04 - The Twisted Ones by T. Kingfisher - 385 pages by
2023-01-29 - A Psalm For The Wild-built by Becky Chambers - 147 pages
2023-01-31 - 1984 by George Orwell - 298 pages
2023-02-08 - The House In The Cerulean Sea by T. J. Klune - 385 pages
2023-02-27 - A Court Of Thorns And Roses by Sarah J. Maas - 416 pages
2023-03-31 - The Cat Who Saw Red by Lilian Jackson Braun - 249 pages
2023-04-02 - Parable Of The Sower by Octavia E. Butler - 329 pages
2023-05-27 - Chapterhouse Dune by Frank Herbert - 493 pages

Xanth

2023-01-10 - Isle Of View - Xanth #13 by Piers Anthony - 344 pages
2023-02-15 - Question Quest - Xanth #14 by Piers Anthony - 338 pages
2023-03-06 - The Color Of Her Panties - Xanth #15 by Piers Anthony - 342 pages
2023-04-18 - Demons Don't Dream - Xanth #16 by Piers Anthony - 340 pages
2023-05-12 - Harpy Thyme by Piers Anthony - 342 pages

Harry Potter

2023-01-15 - Harry Potter And The Sorcerer's Stone by J. K. Rowling - 309 pages
2023-02-04 - Harry Potter And The Chamber Of Secrets by J. K. Rowling - 341 pages
2023-03-10 - Harry Potter And The Prisoner Of Azkaban by J. K. Rowling - 435 pages
2023-04-07 - Harry Potter And The Goblet Of Fire by J. K. Rowling - 734 pages
2023-05-02 - Harry Potter And The Order Of The Phoenix by J. K. Rowling - 870 pages

2023-xx-xx - Harry Potter And The Half-blood Prince by J. K. Rowling - 652 pages
2023-xx-xx - Harry Potter And The Deathly Hallows by J. K. Rowling - 759 pages

Dresden Files

2023-01-20 - Cold Days - Dresden Files #13 by Jim Butcher - 614 pages
2023-02-18 - Skin Game - Dresden Files #14 by Jim Butcher - 600 pages
2023-03-16 - Ghost Story - Dresden Files #15 by Jim Butcher - 578 pages
2023-04-23 - Peace Talks - Dresden Files #16 by Jim Butcher - 496 pages
2023-05-17 - Battle Ground - Dresden Files #17 by Jim Butcher - 565 pages

2023-xx-xx - The Anthropocene Reviewed by John Green - 274 pages
2023-xx-xx - American Psycho by Bret Easton Ellis - 399 pages

Leave A Reply

PHP: Find the second (or third) occurrence of a substr in a string

I needed to find the second occurrence of a substring inside of a larger string. PHP has strpos() which gets you the first occurrence, but nothing beyond that. I wrote a wrapper function around strpos() to let you specify the number you want to find. Returns false if nothing is found.

function strpos_num(string $haystack, string $needle, int $num) {
    $offset = 0;
    $length = strlen($needle);
    $pos    = null;

    for ($i = 0; $i < $num; $i++) {
        $pos = strpos($haystack, $needle, $offset);

        // Short circuit continued lookups if we don't find anything
        if ($pos === false) { return false; }

        $offset = $pos + $length;
    }

    return $pos;
}
Leave A Reply

Perl: Human size in color

I use human_size() a lot in Perl, and sometimes it's nice to have a colored version. Here is a quick colorized version:

sub human_size_c {
    my $size = shift();
    if (!$size) { return undef; }

    if    ($size >= (1024**5) * 0.98) { $size = sprintf("\e[38;5;167m%.1fP\e[0m", $size / 1024**5); }
    elsif ($size >= (1024**4) * 0.98) { $size = sprintf("\e[38;5;105m%.1fT\e[0m", $size / 1024**4); }
    elsif ($size >= (1024**3) * 0.98) { $size = sprintf("\e[38;5;45m%.1fG\e[0m" , $size / 1024**3); }
    elsif ($size >= (1024**2) * 0.98) { $size = sprintf("\e[38;5;47m%.1fM\e[0m" , $size / 1024**2); }
    elsif ($size >= 1024)             { $size = sprintf("\e[38;5;226m%.1fK\e[0m", $size / 1024);    }
    elsif ($size >= 0)                { $size = sprintf("\e[38;5;160m%dB\e[0m"  , $size);           }

    return $size;
}

See also: Original human_size()

Leave A Reply

Perl: Remove an item from array

If you want to remove an item from an array you can use a inverse grep filter like this:

my @x = qw(foo bar baz orange);
@x    = grep { !/orange/ } @x;

or

my @x = qw(foo bar baz orange);
@x    = grep { $_ ne 'orange' } @x;
Leave A Reply

Perl: Read from multiple files with one filehandle

I have a directory of data files I wanted to read line-by-line simply. You can loop through each file, open a filehandle, process the lines, close the filehandle, but that can be repetitive. Perl has a unique mechanism where it will iterate across all the files in the @ARGV array automatically. You can fake out the @ARGV array with your own list of files and then iterate accordingly:

local @ARGV = sort(glob("/tmp/data/*.txt"));

# Special ARGV filehandle reads all the files sequentially
while (my $line = readline(ARGV)) {
    print $line;
}
Leave A Reply

Perl: Creating a reference to a subroutine

Perl allows you to create a reference to subrouting and store it in a variable. This allows subroutines to be passed around to other functions. In Perl speak these are called coderefs. There are two ways to create them:

my $one = sub { print "Hello world!"; }
my $two = \&hello_world;

sub hello_world {
    print "Hello world!";
}

Calling a code reference is simple:

$coderef->(); # No params
$coderef->($param1, $param2);
Leave A Reply

Perl: Sort an array of IP addresses

I have a list of IP addresses that I want sorted in a human readable fashion. A simple sort() on a list of IPs will not work because the octets may be: one, two, or three digits long which confuses sort(). Here is a simple sorting function for a list of IP addresses:

my @ips    = qw(198.15.0.20 4.2.2.1 10.11.1.1 10.100.1.1 65.182.224.40);
my @sorted = sort by_ip_address @ips;
sub by_ip_address {
    return ip2long($a) <=> ip2long($b);
}

Note: You will need my ip2long() function for this to work.

Leave A Reply

Linux: Check if a process is running

You can list all the running processes on a Linux box with ps aux, but often you're looking for a specific process. This is pretty easily accomplished with grep:

ps aux | grep /usr/sbin/sshd

The problem with this is that you often pick up you own grep in the output:

$ ps aux | grep /usr/sbin/sshd
root         883  0.0  0.0  76640  7428 ?        Ss   Oct18   0:00 /usr/sbin/sshd -D -oCiphers...
bakers     11691  0.0  0.0  12148  1104 pts/0    S+   08:09   0:00 grep --color=auto /usr/sbin/sshd

The quick and dirty solution is to do some trickery with a regular expression and grep:

$ ps aux | grep -P '/usr/sbin/[s]shd'
root         883  0.0  0.0  76640  7428 ?        Ss   Oct18   0:00 /usr/sbin/sshd -D -oCiphers...

The square brackets tell grep to match a character class with only one character in it. This prevents grep from picking up itself, but still matches what you want.

Leave A Reply