Friday, June 15, 2018

The Graduate

Tis the season for graduations, and yesterday we attend B's. We're so proud of her and know she's going to kill it in college!

I have to hand it to Arlington, they ran their high-school graduation with military grade precision. It started and stopped as promised, and that included the variables of two student speakers and reading 400 student names. I was also impressed to see that the graduation was MC'd by a student. That was a nice touch and spoke to the maturity of the class (or at least one member of the class).

As for the pic of her brother, well, that's just a bonus. Enjoy!

A Brute Force Solution to the Penniless Pilgrim Riddle

The Kids Should See This posted a challenge known as the Penniless Pilgrim Riddle. There's a video describing the riddle as well as the solution below. Here's a summary of the puzzle.

Consider this map and your current location:

The rules are as follows:

  • You start off with a tax of $4.00
  • Every time you walk a block the tax owed is modified. Go east add 2, go west subtract 2, go north multiply by 2, go south divide by 2.
  • You can't walk the same block more than once.

How can you go from the position shown on the map to the bottom right hand corner with an ending tax of $0.00?

On the surface, this doesn't seam possible. Every block you walk south, taking you closer to the end point, incurs a 2x penalty.

After pondering this puzzle for a few minutes I decided to write code to find me a solution. That counts as solving it, right?

My approach was to do a brute force attack on the problem. The poor pilgrim would have to walk every possible combination of legal routes until he found one that worked. The complete code I wrote is here. However, these two functions capture the essence of my solution.

(define (try direction x y owed walked)
  (solve (next-x x direction)
         (next-y y direction)
         (case direction
           ((south) (* owed 2))
           ((north) (/ owed 2))
           ((east) (+ owed 2))
           ((west) (- owed 2)))
         (cons (next-street x y direction)
(define (solve x y owed walked)
  (cond ((arrived? x y) (list (= owed 0) owed (reverse walked)))
         (let loop ((options
                       (if (can-walk-north? x y walked) '(north) '())
                       (if (can-walk-south? x y walked) '(south) '())
                       (if (can-walk-east? x y walked) '(east) '())
                       (if (can-walk-west? x y walked) '(west) '())))))
           (cond ((null? options)
                  (list #f owed walked))
                  (let ((attempt (try (car options) x y owed walked)))
                    (if (car attempt)
                      (loop (cdr options))))))))))

solve takes in a current x/y position, current tax owed and a history of the blocks that have been walked. The function figures out which possible directions are legal to walk, and then calls try on the first one. try updates the state of pilgrim and then calls solve. solve returns false if the pilgrim didn't reach the destination, or reached the destination with a tax greater than zero. If try returns false, solve goes on and tries the next direction it found as valid. When all possible directions are exhausted, solve gives up returning false.

To find a solution to this riddle I kicked off solve like so:

(solve 2 4 4 '("3,4-4,4" "2,4-3,4"))

This invocation accounts for the fact that the pilgrim starts at 2,4 with a $4.00 tax. The list of blocks walked is a notation that names every street in the grid. It does so by combining the x,y coordinates of the street's end points. The smaller coordinate is always listed first. This insures that regardless of how the pilgrim approaches a road, it will be named properly.

I kicked off the above on my Galaxy S9+ under Termux and waited. A minute or so later, I had this output:

The pilgrim arrived at 0,0 with a $0.00 tax; it worked! The list of street names tells me the route that pilgrim took to get there. I transcribed the streets to a piece of scrap paper and arrived at a visual display of my discovered route:

I had a feeling that the grid size was small enough in this problem that a brute force attack would work, and it did.

There's something poetic about a recursive solution like this. So many attempts are made, yet the code to try all these attempts is relatively terse.

Definitely take the time to watch the video and accompanying solution. Most importantly, it walks you through the process of teasing out a valid route using little more than simple observation. It's inspirational: maybe next time I won't be so impatient and jump right to coding. But still, this was some fun code to write!

Wednesday, June 13, 2018

Pupusas on the Pike - Fried Cheese Perfection

Are they the best Pupusas on the Pike? I'm not an authority on pupusas, so I can't really say. But man, were the cheese and squash pupusas from Sofia's Pupuseria delicious! They were freshly made, which meant we had to be patient, but boy were they worth the wait.

If you find yourself in the area, and have a craving for something fried and cheesy (and who doesn't have that craving at all times?), you should stop by. Your taste buds will thank me!

Tuesday, June 12, 2018

An Ideal Soundtrack My Amtrak Adventure

Last week, as I was sitting in the Amtrak waiting area at Union Station, it occurred to me that I could try tuning in to the behind the scenes operations. I did a quick Google search for Amtrak radio frequencies and this page came up. I plugged my SDR dongle into my Linux laptop and kicked off this rtl_fm command:

  rtl_fm -f 160440000 -l 20| \
   tee ~/dl/chatter.raw |  \
   play -t raw -r 24k  -es -b 16 -c 1 -V1 -

Along with a burst of static, I could clearly hear radio traffic! I quickly ran through squelch values, and found that -l 200 kept the static at bay. Here's a sample of what I heard:

The relative calm of the waiting area contrasted nicely with the near continuous discussion over the radio.

It seems that whenever I get inspired to listen in on radio traffic, I spend nearly all my time trying to dial in the right frequency; usually giving up before I hear anything. But not this time, everything just worked!

Pulling away from the station, I found that the traffic ceased. As we approached other stations, I tried to tune in again. rtl_fm supports monitoring multiple frequencies at once, making for a command line radio scanner. Here's a command line I used to listen in on multiple Amtrak channels:

 rtl_fm -f 160.425M -f 160.650M -l 200 | tee ~/dl/chatter.raw | \
   play -t raw -r 24k  -es -b 16 -c 1 -V1 

And here's a command line that scans nearly all 100 of the known Amtrak channels:

rtl_fm -l 200 \
-f 159.81M -f 159.93M -f 160.05M -f 160.185M -f 160.2M -f 160.215M -f 160.23M \
-f 160.245M -f 160.26M -f 160.275M -f 160.29M -f 160.305M -f 160.32M -f 160.335M \
-f 160.35M -f 160.365M -f 160.38M -f 160.395M -f 160.41M -f 160.425M -f 160.44M \
-f 160.455M -f 160.47M -f 160.485M -f 160.5M -f 160.515M -f 160.53M -f 160.545M \
-f 160.56M -f 160.575M -f 160.59M -f 160.605M -f 160.62M -f 160.635M -f 160.65M \
-f 160.665M -f 160.68M -f 160.695M -f 160.71M -f 160.725M -f 160.74M -f 160.755M \
-f 160.77M -f 160.785M -f 160.8M -f 160.815M -f 160.83M -f 160.845M -f 160.86M \
-f 160.875M -f 160.89M -f 160.905M -f 160.92M -f 160.935M -f 160.95M -f 160.965M \
-f 160.98M -f 160.995M -f 161.01M -f 161.025M -f 161.04M -f 161.055M -f 161.07M \
-f 161.085M -f 161.1M -f 161.115M -f 161.13M -f 161.145M -f 161.16M -f 161.175M \
-f 161.19M -f 161.205M -f 161.22M -f 161.235M -f 161.25M -f 161.265M -f 161.28M \
-f 161.295M -f 161.31M -f 161.325M -f 161.34M -f 161.355M -f 161.37M -f 161.385M \
-f 161.4M -f 161.415M -f 161.43M -f 161.445M -f 161.46M -f 161.475M -f 161.49M \
-f 161.505M -f 161.52M -f 161.535M -f 161.55M -f 161.565M | tee ~/dl/chatter.raw | \
   play -t raw -r 24k  -es -b 16 -c 1 -V1 

Though, I have no idea how practical a list of frequencies this long is.

There's something empowering about listening to behind the scenes radio traffic. It's like glimpsing a secret world while your fellow waiting-room dwellers are none the wiser. I don't ride Amtrak frequently, but next time I do I'll arrive ready to tune in.

Monday, June 11, 2018

Frogs, Family and Fun - Visiting The National Arboretum

I've been to the National Arboretum in DC a number of times: alone with Shira, with my Mother-in-Law and Ron, with our running buddy and probably other times as well. It's always a good time. But yesterday's visit with our 7 and 10 year old cousins was definitely a unique and awesome experience. (Oh, and Ryan and Andrea, you guys were fun, too!)

I got a hands on education in the in the delicate arts of frog catching, caterpillar hunting, dragonfly spotting, tree climbing and honey-suckle gathering. For my part, I got to educate the boys about Milk Weed, and found a number of Monarch Butterflies enjoying their delicacy of choice. I felt like a kid who was getting in the best possible mischief.

I can see I still have a lot to learn about enjoying the outdoors, and I look forward to these young gurus teaching me their many skills!

Friday, June 08, 2018

High School Graduation - A Truly Sweet Simcha

A huge Mazel Tov to M on her high school graduation. What a treat it was to see her leading the Anthem and Hatikva for the festivities. And the fact that said festivities had one of the most amazing dinner/dessert spreads I've ever seen didn't hurt.

E started teaching me to how to play PUBG Mobile, though at this point I'm pretty much a lost cause. I can't seem to get past the fact that the character starts off this battle wearing nothing but boxer shorts. Don't get me wrong: programming from home should definitely be pants optional, but combat? Oh well, I'm sure there's more to the story.

What a fun time and I know M's going to crush it in college! We're so proud of her.

Wednesday, June 06, 2018

Meet Gesty, The Musical Micro:Bit

One of the quintessential projects for the micro:bit is to create a musical instrument of some sort. This usually involves implementing a crude version of a theremin, often by using a light sensor or potentiometer to control the sound. I've implemented my own take on this, using the Tinkertools Electro-Theremin tutorial as helpful inspiration.

Here's my code:

let debug     = true;
let nextNote  = input.runningTime();

if(debug) {
  OLED.init(64, 128);

basic.forever(() => {
  let now = input.runningTime();
  let roll = 90 + input.rotation(Rotation.Roll);
  let pitch = 90 + input.rotation(Rotation.Pitch)
  let right = roll / 36;
  let down = pitch / 36;
  let freq = 131 + (roll * 5);
  let rest = 20;
  let duration = pitch * 3;
  let fudge    = pins.analogReadPin(AnalogPin.P1);

  led.plot(right, down);

  if(now > nextNote) {
    nextNote = input.runningTime() + duration + rest;
    music.playTone(freq + (input.buttonIsPressed(Button.A) ? fudge  : 0) , 
                   duration + (input.buttonIsPressed(Button.B) ? fudge  : 0));
  if(debug) {
    OLED.showString(roll + "/" + freq + "::" + pitch + "/" + duration + "::" + fudge);

(You can find the full source code here.)

I'm using the left-right roll of the micro:bit to determine the note frequency, and the forward-back pitch of the micro:bit to determine note duration. By tilting the micro:bit in various directions, you can generate different musical effects.

But wait, there's more!

I've implemented a simple UI using the 5x5 LED grid on the micro:bit. As you tilt micro:bit in the various directions, the relevant LED lights up showing how far to the left/right or forward/back you are. I also added the potentiometer that came with the Tinkercademy kit to turn the A and B buttons on the micro:bit into overrides. You can dial in a value on the potentiometer then press A to modify the current frequency or B to modify the current direction. Finally, I'm using the tiny screen that comes with the Tinkercademy kit for debugging output.

I was pleased at how accurate the data from input.rotation(...) is. And it's downright amazing how simple the Tinkercademy kit is to operate. I plugged in a few piece of hardware and was making noise in no time.

To prove this all works, check out the video below. Warning: I've got no idea how to get Gesty, the Musical Micro:Bit to, actually make pleasing music. So for now, it just makes mind numbing screeches. Enjoy!

Tuesday, June 05, 2018

It's All Connected - Adventures in Blockchain Implementation

Programming Praxis followed up its hashing implementation exercise with a challenge that uses this newly crafted code. The idea is to implement a blockchain. The only thing I know about crypto currencies like Bitcoin is that they're all about blockchains. I figured I'd tackle this exercise and then use my new found knowledge to quit my day job and become a crypto currency day trader.

After a few minutes with this exercise, I realized my plans of striking it digitally rich would have to wait. Implementing blockchains would be: (a) simple to do, and (b) not put me any closer to understanding Bitcoin.

A blockchain is a cleverly crafted list of items, where each item contains a hashed value that matches the previous item. If any of the items on the list are tampered with, the hashs won't match and the blockchain will be trivially noted as compromised.

As a contrived example, consider this list of readings from the Potomac River water Gauge:

(define water-guage-levels 
  '("USGS    2018-06-04 00:00    EST    70200    P    7.78    P"
    "USGS    2018-06-04 00:15    EST    70600    P    7.80    P"
    "USGS    2018-06-04 00:30    EST    70900    P    7.81    P"
    "USGS    2018-06-04 00:45    EST    71500    P    7.84    P"
    "USGS    2018-06-04 01:00    EST    72300    P    7.88    P"
    "USGS    2018-06-04 01:15    EST    72500    P    7.89    P"
    "USGS    2018-06-04 01:30    EST    73300    P    7.93    P"
    "USGS    2018-06-04 01:45    EST    74200    P    7.97    P"
    "USGS    2018-06-04 02:00    EST    75000    P    8.01    P"
    "USGS    2018-06-04 02:15    EST    76100    P    8.06    P"
    "USGS    2018-06-04 02:30    EST    76500    P    8.08    P"
    "USGS    2018-06-04 02:45    EST    77400    P    8.12    P"
    "USGS    2018-06-04 03:00    EST    79100    P    8.20    P"
    "USGS    2018-06-04 03:15    EST    79800    P    8.23    P"
    "USGS    2018-06-04 03:30    EST    81100    P    8.29    P"
    "USGS    2018-06-04 03:45    EST    82500    P    8.35    P"))

If I published this list, and someone came along with a similar yet tweaked list, who's would you believe?

Now suppose I publish this list as a blockchain:

> (define water-guage-levels-bc
  (fold (lambda (entry bc)
          (bc-adjoin bc entry))

> (bc-show water-guage-levels-bc)
(16 "USGS    2018-06-04 03:45    EST    82500    P    8.35    P" "8671b82a1a8d1c9ff668c11b133c4c67" "1b3df4a71fe0c8fbd3ed6ddf9f39193a")
(15 "USGS    2018-06-04 03:30    EST    81100    P    8.29    P" "a294e5e636810aa425c1c5e1f497893" "8671b82a1a8d1c9ff668c11b133c4c67")
(14 "USGS    2018-06-04 03:15    EST    79800    P    8.23    P" "fe60902aa25d4cbe978169a3bbc8cb6" "a294e5e636810aa425c1c5e1f497893")
(13 "USGS    2018-06-04 03:00    EST    79100    P    8.20    P" "c3fcd4c796b0a923aa857d1e9e80792" "fe60902aa25d4cbe978169a3bbc8cb6")
(12 "USGS    2018-06-04 02:45    EST    77400    P    8.12    P" "45423288514717ecc5829ad011e657dd" "c3fcd4c796b0a923aa857d1e9e80792")
(11 "USGS    2018-06-04 02:30    EST    76500    P    8.08    P" "c125bd9184f97dc149363a8b05766ec" "45423288514717ecc5829ad011e657dd")
(10 "USGS    2018-06-04 02:15    EST    76100    P    8.06    P" "105fb72524937269e0a75e2d3512ab49" "c125bd9184f97dc149363a8b05766ec")
(9 "USGS    2018-06-04 02:00    EST    75000    P    8.01    P" "52ab9918616a5742262e928cf4fdc4" "105fb72524937269e0a75e2d3512ab49")
(8 "USGS    2018-06-04 01:45    EST    74200    P    7.97    P" "b67c5dd2c33111f4fc48d7312a1812f" "52ab9918616a5742262e928cf4fdc4")
(7 "USGS    2018-06-04 01:30    EST    73300    P    7.93    P" "dbca959d4ec7d930d3537d4516df4198" "b67c5dd2c33111f4fc48d7312a1812f")
(6 "USGS    2018-06-04 01:15    EST    72500    P    7.89    P" "f03e16843cca2258a127d7f495ab2d8" "dbca959d4ec7d930d3537d4516df4198")
(5 "USGS    2018-06-04 01:00    EST    72300    P    7.88    P" "4263d01116c6c42d12c3b17197ffadd5" "f03e16843cca2258a127d7f495ab2d8")
(4 "USGS    2018-06-04 00:45    EST    71500    P    7.84    P" "629f057e62534baaa0b14e6f4fd8a" "4263d01116c6c42d12c3b17197ffadd5")
(3 "USGS    2018-06-04 00:30    EST    70900    P    7.81    P" "beaf7199fac22cfc8f565120133a342d" "629f057e62534baaa0b14e6f4fd8a")
(2 "USGS    2018-06-04 00:15    EST    70600    P    7.80    P" "dcba2a9715e2e5ce4e27a19e1c69f3d" "beaf7199fac22cfc8f565120133a342d")
(1 "USGS    2018-06-04 00:00    EST    70200    P    7.78    P" "7f4e55deaa11a9a796adedebbb50b0" "dcba2a9715e2e5ce4e27a19e1c69f3d")
(0 "Genesis Block" "0" "7f4e55deaa11a9a796adedebbb50b0")

It's the same data, but now hashes link each item in the chain. If an attacker attempted to publish a hacked version (say they change 7.97 to 7.92), then the hashes would no longer match and the blockchain would be outed as an obvious fraud. Another useful property of blockchains is that I can continue to append new readings without weakening the integrity of previous entries.

As to how this powers Bitcoin, well your guess is as good as mine. Implementing a crypto-currency will have to be another exercise for another day. In the mean time, check out the source code of my solution and enjoy this video that details What Bitcoin is and How It Works.

Monday, June 04, 2018

Dabbling in Computational Magic: Pearson Hashing

Hashing is one of the closest things we have to magic in the computer world. Imagine I told you that I could turn any piece of text, from a single letter to the entire Bible, into a unique 32 character string. Impossible! you'd say: one can generate an infinite number of strings, yet 32 characters is a fixed space. And yet, this is exactly what hashing algorithms like MD5 deliver.* In short, magic.

(Not sure why this is exciting? Consider how much value we get from finger prints, which behave much like hashes. They're not perfect, but they do a great job of uniquely identifing and verifying a person. The same can be said about hashes and data.)

Programming Praxis has an excellent exercise on the topic: Pearson Hashing which is a fun way to understand how hashing works.

The paper that describes Pearson Hashing is only 4 pages long and quite readable. I highly recommend printing it out and spending some quality time with it.

Pearson Hashing isn't quite as magical as MD5: its promise isn't a unique number for any piece of text. Instead, it maps arbitrary text to a number between 0 and 255 in an essentially random fashion. It does have some useful properties: text that's similar produces completely different Person Hashing values and text that uses the same characters but in a different order also produce different values. You can imagine using Pearson Hashing as a rough check to make sure text hasn't been tampered with or other sanity checks.

The implementation of Pearson Hashing is almost trivial:

(define (pearson-hash text)
    (let loop ((hash 0)
               (chars (map char->integer (string->list text))))
      (cond ((null? chars) hash)
             (loop (vector-ref (*T*) (bitwise-xor hash (car chars)))
                   (cdr chars))))))

I say almost trivial, because the algorithm calls for the construction of a randomly permuted table of values. I found that generating this random table took far more time than the implementation of the hash algorithm. You can find my full implementation here.

To make the exercise more interesting, I branched out a bit and implemented a few variations of pearson-hashing. These include:

  • simple-hash: described in the Pearson Hashing paper as an algorithm that uses an even simpler approach to hashing.
  • pearson-hash-mod: rather than use bitwise-xor to derive the next hash value, this approach uses mod 256.
  • lr-pearson-hash: the Pearson Hashing paper describes an approach to generating larger range hash values. That is, a wider range than just 0 - 255.

I grabbed a list of the top 10,000 English words identified by Google and used it to compare each of the hashing functions above.

My comparison is weak, but still somewhat informative.

As promised, the Pearson Hashing variations always give a different hash on similar text, even if an anagram is used (the simple-hash fails this test). The pair of numbers after the hashing tests represent the max and min bucket size from hashing the 10,000 words from Google. If hashing the 10,000 words was perfectly distributed, then each of the 256 hash values would get 39 or so words associated with them. You can see that all the hashing algorithms were in that neighborhood, with Pearson Hashing being slightly better than the simple-hash approach.

My test also shows that if I use the Pearson Hashing algorithm and generate 40 bit values (that is, I run pearson-hash 5 times for each string) then each of the 10,000 words get a unique hash value. MD5 works in terms of 128 bit values, which I could approximate by running the running pearson-hashing algorithm 16 times. I've got no idea how MD5 works, but I imagine generating 128 bit Pearson Hash values would start to get me into the neighborhood of the magic hashing I initially described.

*Note: MD5 isn't as secure as the I'm making it out to be. There are known issues. There are stronger hashes currently available. I expect those will be obsolete one day, too. MD5 is good enough for our purposes.

Friday, June 01, 2018

They're Kosher and Travel Friendly - But How Do They Taste?

This summer we're traveling internationally with our niece and nephew who keep stricter Kosher than Shira and I do. To add to the complexity, my nephew is diabetic. The optimist in me thinks we'll have no problem making do with local foods. For part of the trip, we'll be near cities with Kosher Restaurants, which mean the supermarkets in these areas should have hekshered products. In my mind's eye, we'll stock up with food at these locations and will have no problems when we're off the beaten path.

But I've traveled enough to know that things rarely go as planned. As a bit of insurance, we plan to bring alone some key staples: bread, tuna packets, peanut butter, etc. While planning this out, I decided to do a bit of research about Kosher shelf stable prepackaged meals. Think airplane food meets MRE's. I found a few interesting leads on the web, but the cost and nutritional profile of the food (not to mention past experience with Airplane food) lead me to more or less drop the idea.

Then, while we were shopping for Passover at Shalom Kosher, I stumbled on an isle full of refrigeration-free boxed meals. There were a number of different brands, and within those brands, quite a few meal choices. I called Shira over to take a look. The thought of having a zero-effort meal, ready to go for the kids was nice. And as she patiently looked through each food option, she noticed a wide nutritional range. Sure, some where packed with fat and sugar, but others seemed downright healthy. Shira carefully selected a few diabetic-friendly options and we added them to our Passover purchases.

We're still a couple months off from our trip, but Shira reminded me that if we want to depend on these meals we better actually try them. So earlier this week, that's what we did. We busted out a 'Stuffed Chicken' and a 'Vegetarian Pepper Steak' and heated them up. Below, you'll find my review of these culinary wonders. We have a few more meal options to try, however, I'm fairly optimistic that we'll bringing along a few of these meals as a backup. The elegant way they solve a potentially tricky situation makes up for the cost of the meals and the pain of schlepping them (or perhaps mailing them there ahead of time?).

Stay tuned, as I try more of the meals, I'll add them below.

Meal Mart: Stuff Chicken with Rice & Mushrooms

My first thought was that this meal was high in fat and calories, but at 25g and 460 calories, if it really is what you eat for dinner it's probably reasonable. And at 7 net grams of carbs, it passes Shira's can I feed this to a Kosher Diabetic test. And check it out: 48g of protein--nice, right?

You can heat the meal up in the microwave or by dropping it into hot water.

As for the taste: it's pretty good. It's not going to win any awards, but I imagine a kid that eats chicken would eat this. As the number of carbs on the box suggest, there isn't a whole lot of Rice & Mushrooms in this dish. Again, if you have a kid who likes chicken, but is not into rice or mushrooms, this dish would probably work.

Would I travel with it? Yes.

La Briute: Vegetarian Pepper Steak

This meal appears to be a nutritional wonder: 280 calories, a measly 1.5g of fat, 13 net grams of carbs and a whopping 50g of protein. It also comes with a self heating mechanism. We followed the provided instructions, and sure enough, the food was piping hot. I realize this is standard protocol for military MREs, but having never seen a self heating meal at work, I've got to say I'm impressed.

So the meal looks great on paper and heats itself up. Where's the catch? You know exactly where the catch is: taste. I peeled back the film on the top of the meal and was greeted by an unusual odor. It didn't help that the food looked like one congealed block. I mixed up the contents a bit and took a bite. The best I can say is that it was edible. The vegetarian pepper steak didn't really taste bad, but it also didn't exactly taste like food. Shira couldn't even stomach a bite. I ended up eating the meal, but I wouldn't want to depend on a kid being so indulgent.

Would I travel with it? No. If the meal has the nutritional profile you're after, go for it. But there other La Briute options that are self heating and hopefully taste better.

Wednesday, May 30, 2018

Taming the Chaos - A Custom Bag Organizer Solution

I've got a day trip coming up that has the unusual distinction of requiring me to bring a laptop (usually I get by with my folding Bluetooth keyboard and cell phone). This means that I'll face a common bag conundrum: bring one bag, mainly my briefcase, and have all the items from my man-bag haphazardly tossed in. Or bring two bags, my briefcase and man-bag, and worry about keeping track of two bags.

With my burgeoning sewing skills, it occurred to me that I may be able to add structure to my briefcase by creating an insert. This would give me the organization I'm after, and allow me to keep track of a single bag. Because the insert I'm sewing would be customized to the shape of the bag, it would fit my gear efficiently. (Yes, it occurred me that I was effectively re-creating a purse organizer. And no, I'm not bothered by this at all.)

I busted out my briefcase, took some measurements and sewed together a large nylon pocket:

I typically carry four categories of gear: everyday (hand sanitizer, snacks, etc.), first-aid (pills and various forms of tape), electronics (keyboard, power bank, etc.) and hiking (Bic lighter, space blanket, etc.). My plan was to section off the large pocket into 4 areas. However, it just wasn't wide enough for this, so I had to settle on sewing it into thirds.

To my surprise and delight, the gear all fit. And what's more, when packed, the insert fit neatly into the bag:

As I finished sewing the initial pouch it hit me that I should have made the bag 1" larger. And I bet with some effort, I could find a way to make a 4 pouch system.

But still, I think the result will be quite functional and I'm psyched to try it out on my next trip.

Assuming this approach works, I plan to create a version that's customized to fit in the large day-pack I use for traveling. You better believe I'm going to measure that one with more care.

One inch I'm telling you...I was off by one friggin inch. Classic.


Related Posts with Thumbnails