Mycroft

Wrong Mycroft.

The right Mycroft is an open-source AI speech-enabled personal assistant. That’s a mouthful, but it’s synonymous with one more familiar word: Alexa. Or maybe you prefer Siri. Or Cortana. Or Hey Google, even though that’s two words.

It’s an ambitious project, going up against giants like Amazon, Apple, Microsoft, and Google. But like all good open-source projects, they’re giving it a genuine, honest try.

And the key selling point is… privacy and transparency. They don’t have anything to sell you, so they don’t record them for marketing purposes. The code for all the skills is freely available, so you can inspect it, change it, improve it.

And yeah, it already exists. It’s not just a dream project. Admittedly, the Mark I unit looked a little too cutesy:

But they’ve already raised over $425,000 on IndiGogo for the creation of the Mark II speaker unit, which looks a lot more professional, and more in line with what’s on the market right now:

It can still do smiley faces and whatnot, but it looks a lot more like the rest of the smart-speaker units out there. And again, it’s all open-source, even the hardware. They’ll sell you a development kit that’s just the screen and the guts and let you create your own enclosure. 3D printing interest anyone?

There’s also a prototype desktop widget for your KDE Linux desktop. You can say, “Hey Mycroft” and it perks up and performs a Wikipedia search, gets the weather, etc. Well, it’s supposed to. I’m still in the process of getting it to work. The first hurdle was getting my laptop’s microphone enabled, but that’s not really Mycroft’s fault. The documentation for running this on your computer is a little sparse, at least for this desktop widget. And it’s got a few bugs, like displaying the weather in degrees Kelvin:

I think this has the potential to be a very cool project. I’ve already submitted a bit of code to it, a simple script to help install some of the needed software. But it’s still something. We’ll see if they accept it. Likewise, I’m going to see if I can find the degrees-Kelvin glitch and patch it. It’s the least I can do, considering I submitted a bug report featuring Joe Strummer.

I don’t have it working right just yet. Every time I try to speak to it, it thinks I’m saying “pair my device”. Hmm.

But it’s another cool project to experiment with; something new to try.

And isn’t that what it’s all about, in the end?

Propaganda: Processing Begins

The Image Processing Division of Bundito Heavy Industries reports success in analyzing the first batch of Propaganda tiles.

Terminal output attached as proof of life.

UPDATE (19:03)

I’ve crunched through all 19 (or is it 18.5?) volumes of the Propaganda tiles and stored all the color information in a SQLite database. I’ve got the three most-prominent colors in each image extracted and filed away. There are a total of 1,047 tiles, by the way.

The next trick will be matching that color data to a color chosen by a user. Since it’s unlikely that the user choice will hit an exact match, I need to find colors that are close to the user’s picked color. Finding colors that are close isn’t a straightforward endeavor. There’s going to be more math tomorrow. Lots more math.

In the mean time, I got feedback on some bug fixes I’d submitted for KDE. Henrik has more guidance and specific methods he’d like me to employ. More learning!

 

Acer Aspire E15

With my interest in Linux growing, I decided it was time to get a machine dedicated to running KDE directly. I already had my machine in the basement, which I connected to using NoMachine. It’s an excellent (free!) product if you want to remotely control another computer. I was able to run a reasonably-high quality connection from my MacBook Pro at 1680×1050. The connection never lags on NoMachine; it dials back the quality temporarily when the screen gets busy. That meant that scrolling through long directory listings or pages of source code would go blurry for a moment, then sharpen up. But it still wasn’t like a realtime, live screen. There was always a hint of softness and filtering to the display. Plus, if the thing crashed (more like, if I crashed it), I’d have to go downstairs, climb over bicycles and boxes of CDs, and power on my ancient LCD monitor to see what happened. I know, such a trauma.

But I digress.

After spending my vacation downtime doing research, I settled on the Acer Aspire E15 (specifically model E5-576G-5762; there are multitudes named “E15”). It’s got an Intel Core i5 quad-core processor, 8GB of RAM, a 2GB NVIDIA graphics card, a full 1920×1080 screen, and a 256GB solid-state drive. It shipped with Windows 10 Home pre-installed, so the $599 price tag certainly included the infamous “Microsoft Tax” for an operating system I didn’t want and planned to erase.

My reading and research told me that upon arrival, I should let Windows 10 do its painstaking update processes. Apparently Windows is the only way to update the BIOS on this machine; Acer doesn’t provide any other option. So I let it grind away for the better part of three hours performing updates. Meanwhile, I downloaded the latest developer edition of KDE neon and put it on a bootable USB drive. Once the updates finished, I made a Windows Rescue Disk on another USB drive (I really need to put labels on those…) and prepared to install Linux.

Linux on laptops has traditionally been a tricky proposition. If there’s not a problem with the touchpad, there will be hassles with the WiFi adapter. Or things like not going into suspend mode when you close the lid. There’s so much varied hardware in the world that even the agile open-source community can’t keep tabs on all of it. Which is why I did so much research and bugged so many people on Reddit, Ask Ubuntu, the KDE forums, and elsewhere. Finally I got a handful of partial answers, which I pieced together and decided this machine would work.

Booting from the USB stick was easy and simple. The install was quick and uneventful. I considered shrinking the Windows 10 partition down to the bare minimum and keeping it available as a boot option if I needed it, but at only 256GB, I wanted all the bytes I’d paid for. Plus, I had the bootable recovery USB stick if I needed it (I really need to label that).

The machine booted into KDE quickly and the touchpad and backlit keyboard worked flawlessly, with no headaches. The WiFi, though, was giving me trouble. I kept losing the connection, having to rejoin the network, and then endure awful speeds as I tried to search for the issue. I ended up tethering the laptop to my iPhone over Bluetooth and using the phone’s connection for a while. That worked great.

I narrowed the problem down to two suspects: the WiFi broadcast channel, or the repeater I had plugged in. Changing the WiFi channel made no difference. Once I yanked the repeater out of the wall, the machine snapped to life and browsing the web and downloading updates ran at full speed. I think the repeater and the main router were on different channels, which was causing a sort of interference. Apparently other devices and operating systems can negotiate this, but not the Linux drivers. I need to get that repeater reconnected and reconfigured – I may have reintroduced a problem on my wife’s MacBook Air. But I don’t think so. The Air is a tricky little sucker when it comes to WiFi – troubleshooting it for her in the past (without the repeater, or on hotel WiFi) has proven that much.

The only additional package I had to install was TLP – Advanced Power Management For Linux. It added or enabled kernel modules for full power management support, like dimming the screen when on battery power, or going into suspend mode when shutting the lid.

Music playback is pretty lousy. It’s got typical laptop speakers with no bass and tinny highs. I’d like to connect to my Amazon Echo as an external Bluetooth speaker, but I’ve got some work to do there. The laptop is insisting on pairing with a PIN, which the Echo doesn’t support. PIN-pairing is old-school Bluetooth, and this laptop supposedly supports the almost-latest version of Bluetooth. I’ll get back to you on this.

The screen is nice and sharp, much sharper than the NoMachine connection I was used to. Everything scrolls smoothly and crisply. I’m very pleased. I can’t find which laptop review site said this machine has a lousy display, but they need to clean their eyeballs. I don’t know about off-angle viewing, since I’m the only one using it. I won’t find out how good the screen is in daylight for another couple of months. But I’m perfectly happy. A full 1920×1080 (IPS) display in this price range is uncommon.

The keyboard is a little squishy, as is clicking the trackpad. But this is a $599 mid-tier laptop, not a $2500 MacBook. The body is plastic, not aircraft-grade machined aluminum. But these are compromises I can definitely live with.

So far, my fears about the laptop being underpowered are wrong. Even with a dozen open browser tabs, Thunderbird email, and a music player all running, I haven’t hit the wall on memory or speed yet. I’ve been able to compile code quickly and effortlessly.

In short, a few minor bumps in the road, but I’m overall very pleased. It’s been but a few days, but I’ve made sure they were thorough days with plenty of testing.

And after I peeled off the last of the stickers, no signs of Windows anywhere. Except this damned key on the keyboard…

The Propaganda Tiles, Math Edition

UIn the previous entry in the Propaganda Tiles series, I wrote about the history of the tiles, and my plans to sort them by color. It turns out this requires a dramatic amount of mathematics, almost all of which are miles above my head.

The primary field that works on this kind of image processing is the computer vision branch of artificial intelligence research. Luckily, there’s the OpenCV library – a vast collection of resources and program code – to help out. It’s another one of those remarkable open-source community-run projects that rivals any commercial solution.

I’ll be using some of the OpenCV libraries to process the Propaganda tiles and extract the top three colors in each image, along with the percentage of each. This will be done with a technique called k-means clustering, and this is how it works:

That’s from Wikipedia. I really have no idea what it means. I ain’t never had enough education to learn such fancy math. Heck, I couldn’t even get WordPress to draw a border around the image, so I had to replace it manually.

I realized this morning that searching for tiles based on a chosen color would be complicated. A color is a three-dimensional value, the most common being the levels of red, green, and blue. In the web world, these are expressed as a set of hexadecimal (base-16) numbers, like #a47eb1. That’s a4 (164) for red, 7e (126) for blue, and b1 (177) for green. These combine to make a sort of lavender purple color:

But it dawned on me that I can’t just “add X to blue” to find similar colors, because just moving along the blue scale isn’t helpful. If you take this color and fiddle with only the blue value, it ranges from purple to orange. Adding to or subtracting from all three colors just moves you closer to white or black. Not helpful.

There’s another way to represent colors: HSV, which stands for hue, shade, and value. This method is a lot less intuitive than red, green, and blue. The distinctions between hue, shade, and value are more difficult to grasp, at least for me. The Wikipedia page for HSV (and its cousin, HSL) runs to fifteen printed pages and includes diagrams like this:

 

Which is pretty, and it also makes a kind of sense of the whole HSV concept. But then the math comes in. Again. And you run into things like this:

It’s all three-dimensional computation, polar coordinates, vectors, and other mathematical concepts that are beyond my ability comprehend.

Luckily, I’m using OpenCV to do this work. It has a community of users. Users who are helpful and friendly. I asked my question on the OpenCV forums and got some helpful tips. It appears I don’t have any choice but to learn some of this math if I want my project to succeed. Or I at least need to understand how to use the OpenCV functions. Specifically something called flann. I’ll get back to you once I figure it out.

In the mean time, happy Propaganda to all, and thanks to the OpenCV members who shared their knowledge.

 

The Propaganda Tiles

This is a Propaganda tile.

It’s one of about 1,000 different square images that can be tiled edge-to-edge for a seamless effect. They make great desktop wallpaper.

They were created around 2001 by a Linux advocate named Bowie J. Poag. He wanted to prove the point that a Linux desktop could be every bit as visually attractive as a Mac or Windows desktop. In fact, he wrapped the roughly 17 volumes of Propaganda images in a nutty retro-scifi fantasy tale, starring JFK, who’d faked his death in order to promote Linux through the use of stunning imagery.

The Propaganda Tiles, while once relatively common, have now become a kind of urban legend. A subset of them was apparently shipped with Red Hat Linux at some point. It’s unclear if anyone has a definitive full set. I’ve kept my own copy on various flash drives and backup services for years. I found a set on GitHub to compare against. I compared my set against that and there were omissions and duplicates. I found another copy that still had them separated into the 17 (or is it 18?) individual volumes.

What no one seems to have, though, is that satirical JFK story. It apparently got lost while everyone was most interested in preserving the images themselves. I’ve searched all my copies. I’ve searched the multiple sets I found online. I’ve tried digging through the Internet Wayback Machine to find the original Propaganda site – which has been gone for about 15 years.

While the Propaganda tiles make for great wallpaper or other texturing projects, they’ve got one quirk that makes them difficult to use: their names. The swirly blue tile above is All-Good-People-3. There’s also an All-Good-People-2, which looks like this:

If you examine it closely, it’s the same geometric pattern, but with a different color palette. That’s the one naming rule that stayed consistent throughout all the Propaganda volumes. A trailing number indicated a color variation. Some have as many as 8 variations. But they all have nonsensical names. I don’t know how Bowie chose them. I like to think it’s some kind of surrealist non-statement. The only meaning is the one the viewer assigns to it.

The nonsense names are half the fun when browsing the tiles, but when you’re actively trying to choose a couple to use as wallpaper, it can be frustrating. You can’t remember which one was the cool blue one about two dozen clicks ago. Sure, you could expand your file browser into “preview” mode, but we’re still talking about a collection of over a thousand images.

So I’ve got a plan. And a programming project.

I tracked down the code needed to analyze images and identify the most predominant colors. I thought this would be a simple, if time-consuming process. I was wrong. In order to do it efficiently involves some complex math and statistical processing, most of which is covered by the computer-vision branch of artificial intelligence programming. The mathematics are way, way, above my grade, so I found a site that had a ready-to-use, free-to-use library to do the processing. I ran a handful of Propaganda tiles through it and saw that it would give me exactly what I wanted: the dominant colors in an image. along with the ratios.

So my plan is this:

  • Process all the images through the analysis tool, getting the top three (or five?) colors in each image
  • Stuff all this into a database
  • Code up an application that lets a user choose a color from a color-picking dialog (you’ve all seen those)
  • Find the best-matching Propaganda tiles by looking for that color in the database
  • Look for high-contrast or low-contrast tiles by comparing the “distance” between the predominant colors. A high-contrast tile will have a secondary color that’s vastly different than the most-common color. Think blue with yellow. A low-contrast tile will have similar shades of blue as all the predominant colors – not much distance between.
  • Allow the user to flag tiles as favorites.
  • Set their desktop wallpaper directly from the application, if I can.
  • Preserve Bowie J. Poag’s original tone of conquering the world through more attractive Linux wallpaper.

I believe this project will be called Propaganda For Plasma, as I’ll be using the KDE and Plasma frameworks to code the application. (The initial image analysis will be done in bulk beforehand, using Python, which seems to be the language of choice for the computer-vision crowd.)

And I’ll finally be able to do what I’ve wanted to – browse the Propaganda tiles by color. I love abstract backgrounds, but I’m picky about my colors. I’ve been getting through life well enough up to this point, but it’s a good project.

If I can make it all work, I may even stop using my folder of photos of The Clash as wallpaper.

Or not.

But at least I’ll get to spend more time with the Propaganda tiles.

Henrik

Spectacle is KDE’s program for taking screenshots. I’d been pointed to its list of “junior jobs” – open bugs that should be fixable by new, aspiring, still-learning, wannabe contributors.

I chose one that sounded interesting and within my ability to fix. It involved adding a command to prevent the display of a popup window that confirmed that a screenshot had been captured. All the code was already in place; all I needed to do was add (or fix) that switch.

And I did that.

But then I started to do more. While fixing “nonotify”, I came across other functions that didn’t seem to be working, or not working properly. I proceeded to rewrite the help messages. I reworked and rearranged the input commands. I even added something I openly disclosed as feeling like a hack to make something else work.

I submitted my patch and waited for a reply.

And this is how I met Henrik. He’s what amounts to the project manager for Spectacle. Naturally, he’d be the one reviewing and approving my patch.

He reviewed it. But he didn’t approve.

I realized that I’d vastly overstepped my bounds. The bugfix assignment was a simple one. I didn’t stop where I should have. I got overly ambitious and added all those other “fixes” and “improvements”. Without a plan. Without understanding the bigger picture (no pun intended).

I was immediately intimidated by his disapproval. I felt like I was in over my head. I felt like a student who’d blown an assignment by not following the directions.

But it turns out that Henrik is actually a really good guy. We set aside the mess I’d submitted and he gave me other, simpler, tasks.

One was to figure out the cause of some warnings being generated by the automated compiler system. It’s name is Jenkins. Whenever a piece of KDE software is published, the Jenkins system compiles it, runs a bunch of tests on the code, and reports back all the successes and failures. It also logs any warnings – questionable code that could indicate a problem, but isn’t an error.

I looked at them and again thought they’d be easy fixes. Two lines of code needed, to wrap up and finish blocks of commands. I inserted them, compiled the program myself, verified there were no more compiler warning, and posted my fix.

Henrik took a look at what I’d added. He hadn’t had a chance to download my patch and try it himself, but he wanted to make sure I understood what I’d changed. I’m still learning C++ and how it handles common programming concepts. It’s different than other languages I’d learned. That’s where those warnings come from – program statements that aren’t errors, but are questionable and deserve review.

Henrik helped me understand exactly how this programming construct works (a switch/case decision block, for those interested in the gory details). He directed me to an online example and asked me to dissect it. I stated that one usage was incorrect and should be considered an error. Henrik reiterated that it’s not an error if the programmer wanted the end result that the code produced. It may not be good form or coded according to project standards, but it’s not an error. Hence the compiler warning. Not an error.

He also had me trace the sequence of events that occur in the program surrounding one of the warnings I’d silenced. It was an arduous task for an untrained C++ programmer, following the bouncing ball as it moved between blocks of code in numerous files.

But I learned the lesson Henrik was teaching me. It’s important that I understand the inter-connectedness of these programs. How all the various modules interlock to make a working whole. That I can’t simply drop a one-line fix into a big program. Maybe that warning is just a warning and the code is correct. Maybe my fix wasn’t appropriate.

We left things there and I went off on vacation.

I didn’t feel bad about this exchange at all. I’d been tutored by a senior developer, someone very familiar with the product being operated upon. He was patient and even light-hearted at times. But he was rightfully strict. He knew – better than I did – that you can’t just throw fixes out there and presume they’re correct.

As it turns out, my “fix” breaks the program. Henrik has left it up to me to find what I did incorrectly. He offered his help at a variety of levels, ranging from simply telling me what’s wrong to allowing me the opportunity to track down the problem on my own. It’s a generous and patient offer. Remember that I’m just supposed to be chasing down warnings, not fixing bugs. But by doing so, I apparently introduced at least one new bug – a real one. One that crashes the program, even though Jenkins wouldn’t complain about the code.

I’m up for the challenge. I think. Henrik is willing to help. I need to learn and understand what I’m doing. If I’ve got someone who’s willing to let me learn and explore, I’m going to take that opportunity.

I don’t feel intimidated any longer. Instead, I’m grateful for the mentoring. It may be unofficial and in the middle of live software updates, but I’ll take any lessons that I can get.

When I worked in engineering, senior people jealously guarded their trade and rarely – if ever – took the time to teach and share. Their work involved the secrets of the pyramids, and we junior people weren’t worthy. It frustrated me to the point of mental and emotional exhaustion.

But that’s not what’s happening in the KDE world. I’m participating. I’m definitely not getting everything right on the first try, but I have people willing to help me. And teach me. Who’ll let me learn from my mistakes without abusing or insulting me.

That’s the key of the free and open-source software community. It’s a community. Everyone’s a volunteer, from the project manager to the newcomer, wannabe bug-squasher. Share your finished product, share your knowledge of programming.


As it turns out, I’ve worked out a revision to an earlier fix for Spectacle. I believe I’ve solved the problem in the way Henrik intended. I wrote up my findings for him and am waiting for his comments before submitting my code.

I’m learning. We’ll see how well it’s going in the next round of review.

Triaging Leads To Fixing

As that more-senior KDE contributor wrote on Reddit, keep looking through the bug reports. Maybe you’ll find one you can fix.

I spent some time going through the day’s bug reports, trying to confirm or replicate the reported error. I ran across a number of interesting problems. Some I could recreate, others I couldn’t.

At the same time, I was teaching myself how to code plasmoids. I made two just for my own use. One changes your screen resolution by querying xrandr, listing the available resolutions, and issuing the command following a mouse click. I needed it because I work by remote, and NoMachine wouldn’t always reconnect at my preferred resolution. I went ahead and added the ability to filter the resolution choices by aspect ratio (16:10, 16:9, etc.) It works pretty well.

The other checks uptime and displays your system uptime in a small horizontal panel widget. While doing this, I learned how to code regular expressions in JavaScript. I wanted the uptime display as condensed as possible, so I had to regex every possible variation that uptime would spit out. At this time, I was still tinkering with my machine a lot, and there was a lot of rebooting.

I ended up polishing them enough to submit them to store.kde.org for the world to download. Each one is sitting at the default 50% enthusiasm score, so ScreenRez and Uptimer didn’t exactly set the world on fire.

But I was learning QML, its quirks and complications.

I continued to work the day’s reported bugs, seeing what I could see. Then I found one. It seemed straightforward enough – a combo box in a plasmoid was too small and the option text was getting cut off. I figured I could fix it.

I spent a day hunting around, trying to figure out if I needed permission to work on it. Or to get it assigned to me, something like that. Finally someone on IRC told me, “You don’t need permission to fix something, just go fix it.”

And so I got to work. It was one of the stock plasmoids, so I made a copy of what was installed on my system and started picking it apart.

QML elements can be tricky to resize and align, at least in my limited experience. Since everything is a child of something else, various properties of the parent dictate how the child is going to behave. Just like real life, I guess. Getting that combo box to accept a size bigger than the default was trickier than I’d assumed.

But I finally got it. And fixed a related problem where the description of the chosen option wasn’t updating like it should. And even changed a default setting to a more sensible and less-random seeming number.

This was Bug 390571, and I fixed it. I got a little education from David Edmundson, one of the Plasma & plasmoid gurus. It’ll be distributed as part of Plasma 5.13.


After years of using and admiring open-source software, I’d realized a small version of a personal goal: contributing something back. It’s a small fix to a minor widget for your desktop. I didn’t reinvent the wheel or cure cancer or radically shake up the world of KDE development. But should you choose to use Media Frame to display photos in a widget on your desktop, I had a hand it making it work right and be user-friendly.

That’s pretty cool.

Sidebar: Stockholm

I’m writing this from a hotel room in Stockholm. We’re on a break from life in the States, visiting chilly but pleasant Scandinavia. Yesterday was a 5-hour train ride from Copenhagen, via the ├śresund Bridge, as I first saw it in the Danish/Swedish crime series “The Bridge” (“Bron/Broen“).

There wasn’t much to see except snowy, wintry Swedish farmland, so I spent most of the journey shopping for a KDE laptop. Unfortunately, I had to settle for doing so over 3G; the train’s expected free WiFi wasn’t working. It matched a mixup with our seat reservations, which resulted in a few polite expressions of discontent from a few otherwise friendly Swedes.

I think I’ve settled on the Acer Aspire E15. It’s got a full keyboard (with keypad) and a proper IPS 1920×1080 full HD screen. It’s only got 8GB of RAM, but the processor is a quad-core eighth-gen i5. It’s got a 256GB SSD and room to expand. I think this will work for my first dedicated Linux laptop.

I asked for buying advice on Reddit, which led me to re-reading an earlier question I’d posed about how to get started participating with KDE.

The answer I got was thorough and comprehensive:

I now recognize the username as the same senior KDE contributor I’ve asked to mentor me as I learn. I’m following Nate’s method as best I can. Starting out small and making small fixes as I find them.

I’ll spell out the details of how this has been working in future posts. Now it’s time to go sightseeing.

Getting Hooked On KDE

It hasn’t been that long, but I’ve already forgotten what first got me hooked on KDE. I’d used Linux in the past, but only in a passing, utilitarian way. Something about KDE caught my eye, though. Maybe it was the eye candy of the Plasma desktop. Maybe it was learning that Plasma is powered by Qt technology, which I’d learned a bit of while tinkering with PyQt.

I had an ancient PC in my basement that was running Mint Linux, which I chose a year or so ago, reading that it was one of the easiest distros to get up and running. Its primary purpose was to be a Plex server, for streaming all my media.

The time came, though, when that old box couldn’t keep up with the large file sizes and higher resolution video files. I’d just gotten a 4K HDR television, so I wanted a machine that could stream and transcode effectively.

I bought a $400 AMD-powered desktop and connected it to an even-more-ancient 5:4 LCD monitor. I resumed connecting to it with VNC. After hooking up my external media drive, I realized it had more than enough power to transcode my movies and collection of Scandinavian crime shows.

I started to play more with Python, which led me to PyQt. I’d never programmed a GUI before, but I understood Python and could make it work.

I’m pretty sure that’s how it flowed. Python -> PyQt -> Qt -> KDE Plasma.

I was immediately jazzed by what I saw on the Plasma desktop. Widgets. Applets. Plasmoids. I learned those were written in Qt’s markup and layout language, QML. And the underlying logic could be straightforward JavaScript. Heck, I could learn those things.

And so I got to work learning something new.

A new start

I registered this domain back in 2007 and never did anything with it. I figure it’s time I did something – anything.

I’ve been paying hosting fees for 10+ years, although my provider, NearlyFreeSpeech.net, has made this as inexpensive as imaginable. Yes, that’s a plug, and no, I didn’t get anything for it.

And so, it’s a blog. I’m so cutting edge.

Over the past six months, my interest in technology and programming has re-emerged. I’ve been programming again. Originally in Python, now I’m trying to learn C++. I’ve gotten hooked by KDE, a Linux-based organization that’s created everything from a desktop environment to an incredible range of pro-quality, entirely-free software. They’ve been around more than 20 years, so something good must be going on.

I’m going to try documenting my journey, sharing what I learn as I go. I’m only a year away from turning 50, but I’ve still got so much to learn.

And so I figure I’ll bore the rest of you with the ins-and-outs of a graybeard old dog who’s trying to learn new tricks.