42 Astounding Scripts

MacOS uses Perl, Python, AppleScript, and Automator and you can write scripts in all of these. Build a talking alarm. Roll dice. Preflight your social media comments. Play music and create ASCII art. Get your retro on and bring your Macintosh into the world of tomorrow with 42 Astoundingly Useful Scripts and Automations for the Macintosh!

Jerry Stratton

Good structure in a program can bring as much esthetic satisfaction as good structure in a painting. — Duane M. Palyka (Computer Painting)

Let mortal tongues awake—Wednesday, June 29th, 2022

Samuel Francis Smith’s America is a staple patriotic song at religious gatherings around Independence Day and other patriotic holidays. It’s more commonly known as “My Country, ’Tis of Thee” because “America” appears only obliquely in the lyrics as “Thy name I love” in the second verse. It is short, otherwise direct, and a wonderful combination of looking forward to liberty and looking backward to what that liberty cost.

Smith wrote America in 1831, when some people could still remember the events of the revolution and some were beginning to recognize the likelihood of further bloodshed in the name of liberty. He lived past our Civil War, and wrote hymns to the freedom secured through that great sacrifice, too.

The first four lyrics rise from the birth of liberty, through the physical country, to hope for the spread of liberty, and end on a plea to God as the author of liberty to preserve and protect our country as a free country.

The several verses added later going into more detail about the beauties of our land seem excessively inventorical. The original second verse handles our country’s physical beauty just fine. I see no need to belabor the point. This is a hymn, after all, but not only that, one of the beauties of the hymn is it’s simplicity. Making it really long kills part of what makes it a great and memorable hymn.

The lyrics in my 1925 Hymns of Praise Number Two are:

    • My country, ’tis of thee,
    • Sweet land of liberty,
    • Of thee I sing;
    • Land where my fathers died,
    • Land of the pilgrims’ pride,
    • From every mountain side
    • Let freedom ring!
    • My native country, thee,
    • Land of the noble free,
    • Thy name I love;
    • I love thy rocks and rills,
    • Thy woods and templed hills;
    • My heart with rapture thrills
    • Like that above.
    • Let music swell the breeze,
    • And ring from all the trees
    • Sweet freedom’s song;
    • Let mortal tongues awake;
    • Let all that breathe partake;
    • Let rocks their silence break,
    • The sound prolong.
    • Our fathers’ God to Thee,
    • Author of liberty,
    • To Thee we sing;
    • Long may our land be bright
    • With freedom’s holy light;
    • Protect us by Thy might,
    • Great God our King.
Print to any device—including screen—with no conditionals—Tuesday, June 28th, 2022

Like many old computers, the TRS-80 Color Computer assigned a device number to the screen that most people never used.

Allen Huffman has a great overview of device numbers on the TRS-80 Color Computer. It turns out you can print to the screen just like you print to a printer, to tape, or to disk. This can make for very simple code when you have something that might need to be displayed on a choice of devices.

No premature optimization—Wednesday, June 15th, 2022

I’m still learning amazing things about Perl. I have a recipe search—it’s in the book—that includes tags such as “s” for “sour milk”, so I can find recipes that use sour milk when I have some. In another window as I’m writing this, I decided I don’t want to have to remember the codes, so I added the ability to use --tag "sour milk" (or whatever) in addition to --tag S. It works perfectly.

But it can’t be working. I have a test line that prints on every iteration through the loop, and the test print only prints once. For all the thousands of recipes it’s searching, I only see “HELLO WORLD” one time.

[toggle code]

  • sub tagMatches {
    • my @recipeTags = @_;
    • #allow either 1-2 letter code or full name
    • foreach my $term (@tagsWanted) {
        • if (length($term) > 2) {
          • print "HELLO WORLD\n";
          • my $tagKey = lc($term);
          • $term = $tagIndex{$tagKey};
          • die("Unknown tag $tagKey\n") if $term eq '';
        • }
        • $term = uc($term);
        • return 0 if !grep(/^$term$/, @recipeTags);
    • }
    • return 1;
  • }

That’s a simplified version of the actual subroutine. It can’t be run without the rest of the code. Here’s a simpler example that can be run on its own:

[toggle code]

  • #!/usr/bin/perl</p>
  • @secrets = ('door', 'floor', 'food', 'grass', 'hand', 'heart', 'key', 'lamp', 'smile', 'tree');
  • foreach $secret (@secrets) {
    • foreach $word (@ARGV) {
      • if ($word =~ m/[A-Z!-\/?]/) {
        • print "Normalizing $word\n";
        • $word = lc($word);
        • $word =~ s/[!-\/?]//g;
      • }
      • print "You've said the secret word, “$word”!\n" if $word eq $secret;
    • }
  • }

This extremely contrived example has a list of secrets. For every item on the command line, it loops through that list of secrets. Within that outer loop, it loops over the list of items on the command line. It ensures that everything is lowercase and that there is no punctuation before testing to see if that item is a secret word.

ISBN (128) Barcode generator for macOS—Wednesday, May 25th, 2022
Southern Living Index back cover

There are currently four code generators within CIFilter. The QR code generator that I wrote about earlier is probably the most useful for general use, although the Aztec code generator has some interesting potential for encoding more text into smaller spaces. There’s also a PDF417 barcode generator, commonly used for id cards and passes.

There is also a Code 128 barcode generator, commonly used for UPC codes on books. If you publish a book on Amazon, for example, Amazon gives you the option of putting your own barcode on the back of the book. Otherwise, their barcode will go on without regard for your back cover image.

I recently wrote a script to create an ISBN barcode (Zip file, 3.0 KB) because I wanted to place my own barcode on my Unofficial Index to the Southern Living Cookbook Library. The code for creating a Code 128 barcode in Swift is pretty much exactly the same as for creating a QR code in Swift.

[toggle code]

  • //generate barcode
  • let isbnData = isbn.data(using: String.Encoding.utf8)
  • var isbnImage:CIImage? = nil
  • if let barcodeFilter = CIFilter(name: "CICode128BarcodeGenerator") {
    • barcodeFilter.setValue(isbnData, forKey: "inputMessage")
    • barcodeFilter.setValue(0.0, forKey: "inputQuietSpace")
    • isbnImage = barcodeFilter.outputImage?.transformed(by:CGAffineTransform(scaleX: scale, y: 1.6*scale))
  • } else {
    • print("Unable to get barcode generator")
    • exit(0)
  • }

Just as with the QR code, the string to be encoded (in this case, in the variable isbn) must be converted to raw NSData.1

I set the quiet space around the barcode to zero, because I’m going to handle the whitespace later using padding. The default barcode is very thin, and will have to be very wide to meet Amazon’s height requirements, so I scale the height of the barcode up by 60% more than its width.

My Swift barcode creator replaces a much simpler Python version:

Older posts