Tuesday, April 16, 2019

A Handy Companion for the Classic Red and Gold Haggadah

With Passover quickly approaching, I've been on the lookout for interesting materials to share at our seder. One such discovery: a transliteration of the classic Red and Gold Rabbi Nathan Goldberg Haggadah that we use at our seder. I think this is a clever way to let those who don't read Hebrew participate in the festivities. For example, here's the transliteration of the 10 plagues:

The pages even match up to the 1963 edition of the Haggadah I grabbed off our shelf.

The publisher of Rabbi Goldberg's haggadah describe it so:

The definitive and most recognizable Haggadah in English. This has become the standard for most synagogues, schools, and homes.

Rabbi Nathan Goldberg's Passover Haggadah comes with an accessible English translation, clear instructions, and numbered lines so everyone can follow along in Hebrew or in English.

And from my perspective, this is true: it is the standard. It's the one I've been using my whole life. And yet, I can find no notable history of the haggadah on the web. Compare that to the similarly compact and universal text: the Maxwell House Haggadah. There's a colorful history associated with that text. Yet, the web is silent on old Red and Gold. How could this be? Could the Goldberg story really just be simple: it's an affordable, relatively easy to follow, simple text?

In a holiday so rich with meaning and minutia, surely we can't leave it at that. Can we?

Friday, April 12, 2019

The Embarrassingly Simple Source for An Up To Date Windows Version of emacs

I recently replaced my no-name mini PC with a might-as-well-be-no-name Kingdel NC860 mini PC. These fanless desktop computers have a great form factor, dual monitor support, plenty of USB ports and a bare-bones feel that I love. Credit goes to Coding Horror for inspiring my first purchase of this type of device.

I've recently switched from Firefox to Chrome as my primary browser of choice, and 1password as my password manager. The result: installing Chrome and logging in using both my Work and Personal e-mail meant that my web-based life was essentially setup. Installing Cygwin, Gimp and AutoHotKey meant that I had a nearly complete dev environment. All that was left to do was to install emacs.

At this point, I usually Google around to find the latest version of Windows friendly emacs, often ending up on this sourceforge site. On a whim, however, I thought I'd try something different: I installed emacs via cygwin.

My expectation was that I'd get a console only emacs. And my assumption was totally wrong. I ended up with the same Windows friendly emacs I'm used to, except a whole slew of issues had been resolved. I'm used to emacs operating in terms of Windows drive paths, while cygwin works in terms of a unix'y path mapping. By using a cygwin based emacs, the two environments are now in sync.

A number of issues with eshell were magically fixed, too. #! detection and signal handling (hitting Control-c) in eshell wasn't reliable in my old Windows emacs setup, whereas it's working well under cygwin based emacs.

Finally, the cygwin version of emacs is as up to date as the GNU site offers: version 26.1.

Why didn't I try this years ago?

It blows my mind that I can go from new PC to working dev environment in 15 minutes and zero dollars spent on software.

Friday, April 05, 2019

Dusting off my Microsoft Word Programming Skills

When it comes to programmatically working with documents, I'm all about Google Docs, Sheets and Slides. But I recently found myself needing to step over to the Dark Side and write some code to interact with Microsoft Word. After a quick Visual Basic for Applications (VBA) refresher, I managed to eek out the code I needed. Surprisingly, I found myself impressed by the capabilities VBA offers. The API is massive and appears to let you automate nearly everything related to Word Docs. I suppose being an ancient and archaic incredibly mature product has its benefits.

In the interest of leaving breadcrumbs for myself, or for helping some other soul who finds themselves needing to write some Word VBA code, I'm publishing a bit of test code I wrote while tackling my project. It's CS 101 level stuff: iterate through the currently selected table and display the max and min numeric values found. But given how rusty my VBA skills are, working through this example was quite helpful.

Here's the code:

Sub TableInfo()
    minVal = 0
    maxValue = 0
    
    Dim t As Table
    If Selection.Tables.Count > 0 Then
        Set t = Selection.Tables(1)
        t.Range.Copy
        For Each r In t.Rows

            For Each c In r.Cells
                v = Left$(c, Len(c) - 2)
                v = Replace(v, "$", "")
                v = Replace(v, ",", "")
                If IsNumeric(v) Then
                    If Val(v) > maxValue Then
                        maxValue = Val(v)
                    End If
                    If minValue = 0 Or Val(v) < minValue Then
                        minValue = Val(v)
                    End If
                End If
                    
            Next
        Next
        MsgBox "Min: $" & Format(minValue, "##,##") & ", Max: $" & Format(maxValue, "##,##")
    Else
        MsgBox "You're not currently on a table."
    End If
End Sub

And here's a screenshot, note the new toolbar item I added:

You can download the Word file containing the code here. Happy Hacking!

Wednesday, April 03, 2019

One Big Gun, and Other Surprises Along DC's Waterfront

Everytime I think I've exhausted DC's esoterica, I'm reminded just how packed with random stuff this city is. Next time you're at a Nats Game, consider taking a less than a mile stroll along the pristine Anacostia Riverwalk Trail to 38.871800,-76.994906. Standing at these coordinates you'll be able to glimpse some truly remarkable Military hardware.

There's a Vietnam era Swift Boat you can approach and inspect:

Swift Boats have an unlikely origin story and played a critical role in Vietnam:

The U.S. Navy found what they were looking for in the Gulf of Mexico. Oil rig workers off the coast of Louisiana and Texas were shuttled to and from the rigs in strong aluminum boats built by Seward Seacraft Company of Louisiana. The taxi boats were sturdy, quiet and with a draft of 3 ½ feet, powered by two diesel engines with twin screws and speeds up to 28 knots. With the addition of weapons and living amenities, they were the perfect craft for patrolling the waterways of Vietnam.
...
Swift boats patrolled the waterways, interrupted enemy supply lines, and participated in complex insertion and extraction operations, while enduring monsoons, riverbank ambushes, mines laid by the Viet Cong, and difficult nighttime operations. Swift boat Sailors brought the naval fight inland and had a decisive role in the fight against the Viet Cong.

There's also the conning tower of the USS Balao, a WWII submarine. Despite earning 9 battle stars while operating during WWII, the sub's claim to fame is related to its movie, not military, career.

It’s real claim to fame came when Balao starred in the popular war comedy Operation Petticoat alongside Cary Grant.

The role itself was a little self-effacing. In the movie a Japanese bomber damages Balao and the submariners repairing it find they have nothing but red and white anti-corrosive paint. When they patch the sub up the gleaming new paint job is hot pink.

Audiences in 1959 screamed with delight at the prospect. The battle-hardened old sea salts of the U.S. Navy in pink? It was unthinkable. “We blushed when we asked for it and almost fainted when the Navy said okay,” the films producer explained in 1959.

Perhaps the most remarkable benefit of taking this walk is the opportunity to see "one of the largest artillery pieces in the world." That's right, parked among other employee vehicles is one of the few surviving World War I Railroad Guns. The 14"/50 caliber gun was originally deployed on battleships, but was mounted on a railroad car to help the Allies compete with German artillery superiority.

Mounting a big 'ol gun on a railroad car wasn't a WWI invention. This approach to fire superiority was conjured up during the Civil War:

The “railroad battery” was first used in Maj. Gen. George B. McClellan’s Peninsula campaign in 1862. Confederates bolted a 32-pounder Brooke naval rifle to a flatcar protected by an iron casemate, the finished car looking much like a land version of the ironclad CSS Virginia. It engaged in artillery duels before the Battle of Fair Oaks.

The Union used similar railroad mountings during the 1864 siege of Petersburg. The most famous of these was Dictator, a thirteen-inch seacoast mortar on an eight-wheeled flatcar. Lobbing 218-pound shells as far as forty-two hundred yards, this behemoth bombarded Southern batteries and bombproofs with telling effect.

While the lifespan of Railway Guns was relatively brief, for a time they were a dominant force:

Before the rise of bombers, missiles, and precision munitions, investments in railroad guns were perhaps justified. In World War I, the guns frequently proved to be fort-cracking artillery par excellence, and superb for long-range bombardment. By the 1930s, their days were numbered: armed forces turned to air power to shatter fortresses (and the guns themselves); to drop paratroops behind fortified lines; and to sever rail links, the guns’ umbilical cord. Ponderous size, camouflage difficulties, and logistical constraints all made the guns vulnerable to air attack. While a viable role remained for cannon artillery on many battlefields into the early twenty-first century, World War II’s end rang the death knell for super-heavy artillery, of which the railroad gun marked the apotheosis.

So did I find it, DC's most unusual site? Knowing this city, not by a longshot.

Tuesday, April 02, 2019

Grabbing an Ionic APK for the Truly Lazy

One of the micro annoyances I encounter with Ionic is the process of sharing an Android debug APK. After running ionic cordova build android I'm left with app-debug.apk under the android platform directory. Copying this file to the correctly named location isn't hard, but it always takes me a few extra heartbeats to do it right. Where's does the APK live again? Should I use _'s or -'s in the final name? What's the version of this app? and so on. Not hard, not even tedious, but always annoying.

I've done this enough that it was time to write a script to do the job. My strategy assumes that the location of the APK is constant and that the destination file name and version can be found in config.xml. Here's the script to grab the APK:

#!/bin/bash

##
## Script to help with ionic dev
##

action=$1

case "$action" in
  grab-apk)
    name=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets  -t -v '/x:widget/x:name' config.xml)
    version=$(xmlstarlet sel -N x=http://www.w3.org/ns/widgets  -t -v '/x:widget/@version' config.xml)
    cp -v platforms/android/app/build/outputs/apk/debug/app-debug.apk ~/dl/$name-$version.apk
    ;;

  *)
    echo "Usage: {grab-apk}"
    exit 1
    ;;
esac

And here's what it looks like while running:

$ ionicassist grab-apk
`platforms/android/app/build/outputs/apk/debug/app-debug.apk' -> `/home/ben/dl/Foo-3.16.1.apk'

xmlstarlet is the obvious tool to use to grab info from config.xml. I'm always tripped up by the use of namespaces in the XML and XSLT, which meant writing the above script took a bit of extra debugging time. If nothing else, the above code is a helpful reminder to me as to how to navigate a document with namespaces.

Use and enjoy!

Friday, March 29, 2019

Fun With Lycra

MattShafter had a nifty video on creating simple mesh shoulder strap pockets. I picked up some of the fabric he mentioned (1209C Heavy Lycra Mesh) and last night had a chance to experiment with it. I don't have a need for shoulder strap pockets, so I whipped up a quick zippered pouch instead. This exercise let me play with the new fabric and gave me a chance to face the puzzle that is installing a zipper.

Here's the pouch coming together:

I wrapped the edges of the mesh in bright yellow fabric in the hopes of making the seams more robust. It appears to have worked. The catch: the zipper area shows some ratty edges of the yellow fabric which I definitely lose style points for. Personally, I'm just glad I managed to install a functional zipper with its right-side out.

The finished bag isn't much to look at, but it holds a surprising amount of volume. Also, the mesh has a durable feel to it. Here's me packing the pouch with a bunch of my EDC stuff crammed into it:

I'm not sure what I'll use this pouch for, nor am I sure what I'll tackle next with this material. But I'm impressed with its stretch, durability and general forgiveness in the hands of a newbie.

Here's the video that inspired me:

Thursday, March 28, 2019

Stealthy Caloric Motivation

I've found noshing while running, even on relatively short runs, can have a big impact. Sure, it may be mainly placebo effect, but popping a snack when you're dragging can provide a surprising uplift. I came across this list of running gear hacks, and noted the following suggestion:

Want to boost the carrying capacity of your favorite pair of running shorts? Line the waistline with several safety pins—a dirt-cheap, hands-free method for toting your house key, energy gels, mini Ziplocs of electrolyte mix or salt tabs, or even empty food or gel wrappers. Pro tip: pin items to the inside of your shorts’ waistline to avoid them bouncing around while you run.

For my last three runs, I've pinned some sort of snack to the inside of my short's waistband. Jelly Belly Sports Beans are ideal because they're compact and low profile. Other foods stored in portion control Ziploc style bags work, too. Because the snack is kept on the inside of my shorts bounce is kept to a minimum.

The result is a backup source of caloric motivation that's essentially invisible until I need it. And best of all, if you've got a safety pin or two lying around the house, the setup is free.

Tuesday, March 26, 2019

Improvised Direction Finding Using A Clock, Some Math and A Pocket Friendly Chart

It's 10:42am last Sunday and the sun is shining brightly. I'm curious how closely I can calculated my direction using the sun and my watch. I snap these pics as a control:

Both my compass and cell phone agree: the sun has a current heading of 128°.

If I plug my location and precise time into the formulas to calculate solar azimuth the result matches my field readings:

If I create a chart with the day's azimuth's calculated on the half our, I can derive an accurate estimate:

While reassuring (yay, math and my programming works!), both these approaches aren't ideal. If I have the means to execute the full series of solar math calculations, then I probably have my cell phone which has a compass and GPS built in. Using the sun to verify these readings is handy, though not essential. The daily cheat-sheet is useful for specific days (say, we're on a weekend backpacking trip) but requires planning to be of use.

A more general solution is a chart like this one:

This chart provides the sunrise time and azimuth, hours of daylight and solar sweep for an entire year. It does so in 1 week increments. The chart is small enough that I can tuck it in my pocket notebook and ignore it until needed. Using this data and some basic math, I can estimate the solar azimuth for March 24th at 10:42am:

I start by estimating sunrise time, azimuth, hours of daylight and sweep for March 24th. This day isn't on the chart, but the 26th is so I interpolate from there. I then calculate solar noon. This is the point where half the hours of daylight have been consumed, and the azimuth is 180°. I convert the target time of day, 10:42am, to a number of hours after sunrise. Using a simple proportion I can now solve for the number of degrees the sun has traveled between sunrise and 10:45am:

6.015hr             3.5hr
-------       =     -----
  92°                 x°

x = 53.5°

Adding the number of degrees the sun has traveled since sunrise (53.5°) to the sunrise azimuth (88°); yields my estimated position: 141°.

My first thought was: yikes! 141° is quite a ways off from 128°. However, looking at a compass convinced me this error is acceptable. Both approaches suggest that the sun is in the South-East on March 24th at 10:42am. If I had no GPS or compass to go off of this information would be invaluable.

I wouldn't want to survey property or search for hidden treasure using this chart, but as a zero-weight, battery-less, method for calculating direction I think it works.

Here's the Google Spreadsheet that powers this chart.

Monday, March 25, 2019

Etched in Stone

I ran by the Department of Justice yesterday, and noticed the quote etched in the wall: Lawn Alone Can Give Us Freedom. Deep, I thought. I rounded the corner and found TV crews prepared for breaking news related to the Mueller Report. Just a normal day here in DC.

Friday, March 22, 2019

The River Was Angry That Day My Friends

Typically, running along Holmes Run is a placid affair. You get the woods for ambiance, the paved trail for convenience and the stream crossings to make the whole experience feel like an authentic adventure. But not yesterday. Yesterday the river was angry. The day's worth of rain turned the calm stream into a torrent.

I had planned to run along Holmes Run, but found the following view at the first stream crossing:

I took one look at those whitecaps, snapped a few pics, and ran back the other way.

Thursday, March 21, 2019

Review: Ready Player One

I listened to the audiobook version of Ready Player One by Ernest Cline and really enjoyed it. The only hints of the plot I had were from a movie preview, so I assumed the book would be a shallow excuse to revel in 1980's pop-culture. And while the book definitely elevates the 80's, it touches on deeper themes as well. Add to this the puppy-love story, and I found the book both thought provoking and entertaining.

I liked how Cline weaves solutions into the storyline, much like Christian Cantrell does in Containment. Don't give me a Ted Talk on how virtual schools can help level the playing field and reduce the scourge of bullying, show me by having your main character attend and thrive at one. The samegoes for the book's anti-obesity strategy.

Mostly I enjoyed pondering the philosophical questions posed in the book. It's a common theme in Sci-Fi: the Earth has become unsustainable, so we flee to another planet. In Ready Player One humanity has fled online. Is this the equivalent of finding a new planet? Or has humanity locked itself in a cage? If your virtual reality is nearly your entire self, then does it become your reality? The book poses these questions and leaves room for debate. Notably, our main character is both at home in the digital universe, and yet has flashes of pure desolation when he ponders his choices.

I was a kid during the 80's, so I got a number of the references (my older brother would no doubt get more), including some of the game references. I can proudly say I've logged hours of Gorf and used to play on our Commodore 64. With that said, much of the 80's pop-culture references whizzed over my head. And not being a gamer, I didn't really ponder the book through that lens. More than once I thought how crazy the plot device of having the future obsessively study the 80's is. But I stuck with the book, so I guess it works.

I found the pacing of the book slow at times. I kept waiting for it to skip ahead in the contest, but no, it plodded along in no hurry. And I found the story occasionally tested just how much belief I could suspend, as there were moments when the technology and social structure envisioned were just more than I could buy.

Ultimately, the questions Ready Player One raises aren't really some far off future concern. For all of recorded history, there have been those trapped in circumstances that are far bleaker than the book imagines. Using little more than books and letters, one could imagine constructing an alternate reality to thrive in. The Internet has vastly simplified the process, and now I can be so much cooler online than in real life. Should we be embracing these virtual lives even more, or use this as a wake up call to unplug? And what does it mean that I'm publishing these words on my blog, rather than preaching them to friends over dinner?

So many questions.

Update: A thought I've had since posting this reviews: one way to look at 'Ready Player One' is as a sort of super-early prequel to 'The Matrix'. Consider how The Matrix is described:

Morpheus awakens Neo to the real world, a ravaged wasteland where most of humanity have been captured by a race of machines that live off of the humans' body heat and electrochemical energy and who imprison their minds within an artificial reality known as the Matrix.

In Ready Player One society is opting to plug itself in to the virtual reality known as the Oasis. It seems plausible that given enough generations, people will opt to skip the real world altogether and live completely in the Oasis. At some point, the world may simply not know there's a real reality out there.

My point: the dystopian universe of The Matrix need not come about due to vengeful aliens. As Ready Player One hints at, society is more than glad to lock itself in a virtual cage.

Wednesday, March 20, 2019

pick-one: a (very) lightweight image collaboration tool

Last week I wanted a small group of folks to weigh in on a particular design decision. Surely I thought, there's a tool out there I can use to run a quick poll of the various mockups. Alas, searching didn't turn up a usable solution. I found sophisticated tools for collaborating on designs, as well as simple tools for creating image based polls. The design tools were overkill, and the image polls were crude and ad filled. What I wanted was something like doodle.com, but for images, not scheduling. With no great options, I decided to build my own. I give you: pick-one.

Here's an example of using pick-one in action. Suppose I wanted to find out which bridge pic of mine a group of people prefer. I upload the source photos to a directory accessible to pick-one and then send out a link with that directory name in the URL. In this case the URL is http://code.benjisimon.com/pick-one/?s=bridges. Clicking on the link shows an overview of the photos:

Clicking on any of the images will zoom in:

Each image is automatically overlaid with a consistent letter. Folks I've emailed can reply with a quick 'C' if that's their choice.

You can find the source code for pick-one here. I'm not in love with the fact that it requires you upload images. A smart enhancement would be to pull the images from a Google Album, Google Drive Folder or Amazon S3 Bucket. Once this is done, the system should be far more usable.

I'm still convinced that there's a lightweight tool out there that will let me poll my audience. But until I trip over it (or better yet, you tell me about it in the comments), I'll keep enhancing pick-one.

Tuesday, March 19, 2019

Learn the Lessons, Avoid the Pain | The Catalog of Failed Attempts

Yesterday, Shira came home and found me in a glum mood. The problem I explained, was that Jupiter's YoYo attempt of the PCT had ended in failure. Mind you, I don't really know Jupiter, his failure happened over a year ago and from comments I see that he's fine and heading out on the trail soon. Still, if an uplifting story or song can raise your mood, then surely it's reasonable that a failed attempt should bring you down. That's just quality film making.

Jupiter, however, is self aware enough to know that this failure doesn't define him. As he explains:

I'm obviously not happy about the outcome of this hike but I am happy that it can share a story not often shown. I like to think about it as if it's skateboarding. Those guys fall and fall and fall. But ya know the strongest get back up and try again. Our 'trick' is just on a longer timescale but the lesson is the same.

It's in this spirit that I was glad I watched Jupiter's story and was glad to add him to my Catalog of Failed Attempts (CFA). The CFA exists for an obvious reason: if experience is the best teacher then learning from other's failures is an invaluable (and pain free!) opportunity.

You might think it's a bit harsh to keep a list of people's failed attempts, but I think it showcases an important trend. Everyone on the list has and will continue to have amazing accomplishments. Take Jupiter. Sure, his PCT adventure didn't go as planned. But neither did his first thru hike attempt of the AT. After that trail, he successfully completed the 4,800 mile Eastern Continental Trail. I'd love it as much as the next person if we could have our failures early (or better yet, not at all!) and be done with them. But as long as you're leaving your comfort zone failure is very much an option.

At its core, the catalog is all about embracing and learning from failure, not dreading it.

Any attempts you can suggest adding to my list?

Thursday, March 14, 2019

Building a Better Barometer

Picture it: We're a 1000 miles from nowhere, it's 3pm, and we're staring at a trail map. Should we push forward and tackle the mountain pass ahead of us, or should we play it safe and take it on the next day? If only we had a way of knowing if the current weather was going to hold. Then it hits me: I can consult my phone's barometer to help predict the weather.

I bust out my phone, Bluetooth keyboard, and start up Termux. I then run tail -24 ~/storage/shared/Tasker/pressure.txt | baro to see the last 24 hour's barometric pressure readings. We huddle around my phone, trying to make sense of this raw data.

There are a number of things wrong with the above scenario. Top among them, the awkwardness of using my baro shell script. Fortunately, it's not hard to make this script far more practical.

First off, I discovered spark, a command line sparkline generator. Sparklines are an Edward Tufte invention that's used to help visualize data. Here's how Tufte defines sparklines:

A sparkline is a small intense, simple, word-sized graphic with typographic resolution. Sparklines mean that graphics are no longer cartoonish special occasions with captions and boxes, but rather sparkline graphics can be everywhere a word or number can be: embedded in a sentence, table, headline, map, spreadsheet, graphic. Data graphics should have the resolution of typography.

Thanks to this shell script you can add Bash terminal to the list of places sparklines can appear. The spark command reads data from stdin and generates a corresponding mini bar graph. Here's an example of me filling a data file with 100 random numbers and then graphing the results.

The other missing piece of the puzzle is an ability to run my baro command with ease. The Termux:Widget app has me covered there. Termux:Widget allows you to add a widget to your home screen that scans the ~/.shortcuts directory. Every file found in that directory shows up as a command in the widget. Pressing on the script name launches the corresponding command. Here's my ~/.shortcuts/show_pressure script:

bin=$HOME/util/bin

hours=24
cd ~/storage/shared/Tasker
tail -$hours pressure.txt | $bin/baro
tail -$hours pressure.txt | $bin/baro -d | $bin/spark
tail -$hours pressure.txt | $bin/baro -s

Combining spark and Termux:Widget means that I can now view my local barometric pressure by clicking over to my widget screen and pressing show_pressure:

Do we push on, or setup camp? Who knows. But at least consulting the barometer is now effortless.

Wednesday, March 13, 2019

Review: Phantom Warriors

I've mentioned before how riveting a read Phantom Warriors by Gary Linderer was, and I recently finished book 2 in the series. Bottom line: I continue to be in awe of the stories Linderer tells.

Phantom Warriors chronicles the life of various Long Range Reconnaissance Patrols (LRRP) during the Vietnam War. While LRRPs were occasionally used for offensive means, the majority of their missions focused on collecting field intelligence. As modern a war as Vietnam was, the most reliable way to assess the state of affairs on the ground was to send in highly trained pros. A mission typically lasted for days, and even the smallest misstep could reveal the team's position and put them in an overwhelmingly bad position. You can read about some of tactics they used to stay safe here,

The grit, courage, fearlessness that were so prominent in book 1 continue in book 2. In this latest book, however, I got a more complete picture of the challenges LRRPs face. We meet soldiers and commanding officers who are more liability than asset. We find our teams of heroes not just under fire from the enemy, but from poor decision making and distrust by their own leaders. It's one thing to call for an extraction and be told that no helicopters are available. It's altogether a different story to be denied assistance because senior command doesn't truly believe you need it, or doesn't believe the contact with enemy even occurred.

This is an ugly side of war, but it's no less a reality than the other challenges LRRPs had to deal with.

Book 2 follows the same recipe set out in book 1. Each chapter begins with a fairly technical state of the war at the time of the mission, followed by a short introduction to each individual going out on the patrol. You're then treated to a blow by blow account of the mission, which may last hours or days; may be without incident or contain a bloody firefight; and may end with everyone safe or significant loss of life. You have the privilege to watch each story unfold, all while rooting for the team to make it back in one piece.

It's worth noting that the overview given at the start of each chapter was almost my undoing. I picked up Phantom Warriors a couple times only to put it down because I found the content so bland. But once I read on I realized just how short-sighted I'd been. The text naming each soldier in the patrol, while less exciting than the mission description, is just as important. It goes a long way towards reminding me that this isn't some fictional account. These were real people in a very real war.

These are legendary heroes, with a story that hasn't been widely told. Pick it up today, you'll be glad you did.

Tuesday, March 12, 2019

Digits, Aspirin and an NFC Powered Cheatsheet

This past weekend we got recertified in CPR and first aid, and so the time was right for me to take stock and up my first aid game. Here are three changes I've made as a result.

I've gotten into the habit of handwriting key phone numbers in the back of my pocket notebook. That way if I lose my phone I've got a fighting chance of contacting loved ones. To this list I added Poison Control (800-222-1222) and the National Suicide Prevention Lifeline (800-273-8255). Hopefully I'll never need either of these, but should one of them be necessary, I want the quickest access possible.

I've been vaguely aware of the recommendation that if someone is having heart attack symptoms they should take an Aspirin. This advice appears to be legit, and have added 4 tablets of 325mg Aspirin to my kit.

A day of CPR and first aid training is helpful, but those skills are awfully perishable. To help retain them we're given a quick reference guide. I pondered the best way to store this guide and came up with the following.

First, I copied the salient details of guide into a plain old .html file. After storing this file locally on my phone I setup a trivial Tasker action that opens this file in a browser. I then setup two quick ways to access this Tasker action: the first is a widget on my home screen, and the second is a via an NFC tag that's placed in the first aid kit itself. I'm not sure how practical this second method is, but it's pretty sweet to hover my phone over my first-aid kit and have a cheatsheet pop-up in response.

Will this NFC tag approach work in a high-stress emergency scenario? Probably not. But it does make launching the file easy and if I do that every couple months for a quick review, that alone will be helpful.

Finally, here's a couple snapshots of my EDC first aid kit. A good bit of it is little more than meds and tape, which can truly work wonders. The gloves, CPR face shield and tourniquet are a nod to the fact that very bad things can happen when we least expect it. The ear plugs are because I kept showing up at concerts unprepared and kids today play their music too dang loud.

Friday, March 08, 2019

Weather Prediction Like It's 1850

I've been wearing one of Shira's old watches and I've become fascinated by the weather function. Without any connection to the web and minimal sensors, it boldy offers predictions. See, it's going to be partly sunny today! (OK, that's not the boldest of predictions I suppose.)

How does it do that?

The watch in question is an old tech4o model that fits in the Altitude-Barometer-Compass class of watches, so called ABC watches. Back in the day, these were high tech and provided next level features when compared to a typical sport watch.

My hunch was that the sensor powering the predictions is the barometer. This fascinating article on the topic Fair or Foul? How to Use a Barometer to Forecast the Weather confirmed my suspicion. What a game changer this must have been in the mid 1800's when suddenly forces that seemed godlike were reduced to quantifiable phenomena. Even now, when it seems like weather forecasting should be in the domain of scientists and super-computers, I find it remarkable that you can offer predictions, however crude, using one commonly available sensor. That's too cool.

Most of the time I'm only a few keystrokes away from knowing a precise forecast. That is, however, until I'm off in the woods and there's no cell or WiFi signal. In that case, having something like Shira's watch could be pretty handy. But what if I didn't want to depend on her watch? The Physics Toolbox App on my phone tells me that my Galaxy S9+ has a pressure sensor built in. Could I use my phone as glorified barometer?

Looking on the Android Play Store I found a number of apps that promise to turn my phone into a weather station. But many of them seem quite sketchy, and even the ones that look reputable leave me with questions of efficiency and battery life impact. Fortunately, there's a lighter-weight option than installing one of these apps: Tasker. When configured, Tasker will populate the variable %PRESSURE with the current value of the phone's pressure sensor. Capturing this variable in a simple text file is easy:

(Download this Tasker Profile)

You'll want to make sure that you've setup Tasker to monitor the pressure sensor. Also, in order for the %PRESSURE variable to be populated it needs be referenced by a profile. Or at least that's what I had to do to get the variable to be set.

I got a little overzealous and had Tasker capture the %PRESSURE every 5 minutes. I think hourly is probably sufficient. Regardless, after couple of days I had a data file filled with entries that looked like so:

1552003293:1026.6213

That's standard unix time and pressure in millibars. All that was left to do was to turn that text file into of something human friendly. I kicked off Termux, fired up emacs, and wrote the following script:

#!/usr/bin/env bash

##
## A script for working with barometric pressure data
##
## Assumes standard in is a stream of unix timestamps and barometric pressures
##
## See also:
## https://www.artofmanliness.com/articles/fair-or-foul-how-to-use-a-barometer/
## https://taskernet.com/shares/?user=AS35m8l5RQjTRe3TULACE9yEJktuWU6aAnSRKY16uyMSAb3bzu7qeuaheX4adap2hJHO4tg%3D&id=Profile%3APressure+Collection
## https://github.com/holman/spark
##
last=''

MODE=show

while getopts "d" OPTION ; do
  case $OPTION in
    d) MODE=data ;;
    *) echo "Usage: `basename $0` [-d]" ; exit 1 ;;
  esac
done

while read line ; do
  s=$(echo $line | cut -d: -f 1)
  v=$(echo $line | cut -d: -f 2)
  hg=$(echo "($v * 0.0295)" | bc)
  p=$(echo "($v * 0.0295 * 100)" | bc | sed 's/[.].*//')
  t=$(date "+%Y-%m-%d %H:%M" -d @$s)
  if [ $MODE = "data" ] ; then
    echo $p
  else
    if [ -z "$last" ] ; then
      c="?"
    else
      if [ "$last" -eq $p ] ; then
        c="-"
      elif [ "$last" -lt $p ] ; then
        c="^"
      else
        c="v"
      fi
    fi
    last=$p
    echo "$t $c ($hg)"
  fi
done

The script maps the stream of raw times and pressures into a readable timestamp, rising/falling/steady indicator and pressure in inHg. Consider the example below that tells me that after dipping overnight, the pressure has started rising this morning. That bodes well for today!

While my Tasker + Termux solution lacks the the cute icons Shira's watch provides, it makes up for this with something more valuable: simplicity. Tasker is giving me raw access to the sensor, and good old fashion unix scripting let's me process it. In other words, I've turned my $800 cell phone into a $20 barometer. Most importantly, whether I have Internet access or not, I can play armchair sea-captain and offer up weather predictions. Welcome to the 1850's baby!

Wednesday, March 06, 2019

Making More Minyans | A Software Solution to Increasing Attendance

For years I've wondered what code I could write to help improve attendance at my shul's Thursday morning minyan. For those not familiar with a minyan, the idea is that we have a weekly prayer service that runs regardless of how many people attend. If 10 Jewish adults are present then we can say a number of additional prayers. You can apply the logic of this post to any gathering that strives to have a quorum.

There are a number of competing requirements that minyan related software should meet:

  1. It should encourage people to attend without turning into a nag.
  2. It should be respectful of people's time and only call for a minyan when one is necessary.
  3. It should be a lightweight, frictionless system. Users shouldn't need to register an account or have to log in to interact with it.
  4. It should work equally well over mobile and desktop devices.
  5. It should be something I can build and maintain with a minimum of effort.
  6. It should both push information out to the community, as well as serve as a repository interested individuals can interact with.

Over the years, I've had glimpses of solutions to the above ("What if I made an SMS based ...") but I've never had a concrete plan.

And then a couple of weeks ago, while on a run, I had a flash of inspiration. I then sat down and coded an implementation in 45 minutes. This blog post will probably take longer to compose and edit! Here's what I did.

First, I created a new Google Sheet. I setup one place on the sheet to request a minyan and another place on the sheet to say you're attending. I made the sheet editable by all (so no login required) and protected all the cells except for the area I expected input. To simplify access, I created a custom redirect on the shul's website so that a URL like: http://myshul.com/minyan would take users to the spreadsheet.

Here's a screenshot of the sheet in action:

With just this sheet and URL created I solved a number of the above challenges. The system didn't require any registration or login and had a friendly URL. That's pretty frictionless, no? The system serves as a repository of information. On Wednesday night, folks can peek in and see how close we are to a minyan for the following day. Google Sheets works well on both Mobile and Desktop devices, so I was covered there too. And so far, the system had been effortless to build.

There were a couple of key pieces missing. First, the system doesn't push information out. Second, there's no obvious way to reset the sheet for the next week. On my run I imagined I'd have to write custom code to address these challenges. However, Google was one step ahead of me and provides easy fixes. The magic: Installable Triggers. Specifically, Time-drive Installable Triggers. Using these you can invoke a function on your Google Sheet at a recurring time. Essentially, it's cron for Google Apps. I setup two triggers: one happens two days before minyan and calls the notify function, and one happens an hour after minyan and calls reset. Here's the definition of the notify trigger:

All that was left to do was to write the notify and reset functions. reset I figured would be straightforward as it's little more than code to delete the contents of cells. But notify I intended to send e-mail. Would Google Sheets allow such an action? Again, things broke my way and the answer was a resounding Yes! Here's my implementation of notify and reset:

function reset() {
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = doc.getSheetByName("Minyan Tracker");
  var ranges = [ sheet.getRange("C5:C17"),
                sheet.getRange("E5:E17") ];
  ranges.forEach(function(r) {
    r.clearContent();
  });
}



function notify() {
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = doc.getSheetByName("Minyan Tracker");
  var needs = sheet.getRange("E5:E17");
  var requests = needs.getValues().map(function(row) {
    return row[0];
  }).filter(function(cell) { return cell != ''; });
  
  if(requests.length > 0) {         
    var body = "A Minyan was requested for Thursday morning. Can you attend?\n\n" +
             "If so, please visit: http://myshul.com/minyan or reply 'Yes' to this e-mail to let the community know.\n\n" +
             "Tired of getting these e-mails? Mail Ben Simon (benjisimon@gmail.com) and ask " +
             "to be removed the TMMR mailing list.";
    MailApp.sendEmail("minyan-notification@mylist.com", "[TMMR] Minyan Requested", body);
  }
}

I setup the minyan-notification e-mail list to include folks interested in attending minyans. I configured the e-mail list so the replies go back to the sender; Me. This means that recipients can signify their attendance by either clicking on the link within the e-mail, or hitting reply to the e-mail. What could be simpler than that?

notify only sends e-mail if someone has signed up requesting a minyan. The request list on the sheet, like the list of attendees, is cleared out weekly so it stays fresh. The result is a system that pushes out requests but is careful to do so only if a congregant has an explicit need.

It truly is amazing what you can accomplish using a Google Sheet, an e-mail list, a bit of code and some creativity.

LinkWithin

Related Posts with Thumbnails