I’m a low-key video game collector. Mostly because I just like games, and end up holding on to the junk I buy for each console generation. I’ll occasionally venture on to eBay to pick up the random retro title. Plus I worked at a used game store for a while back in college, which helped my collection immensely.
Sometimes, however, I don’t exactly remember where I picked up a particular piece of kit. Maybe it was scrounged from a rando on craigslist, or I found a good deal online. Who can know these things, exactly? Regardless, I have a top-loading NES, and am unsure of the origin. All I know is that recently, it’s the only working NES system that I own. I use the word “working” loosely, here. The system would power on, but would only show static. After leaving the unit running for 10 minutes or so, the video and sound would slowly start working again. Not the worst thing in the world, but kind of annoying.
I’d heard that similar problems could be caused by bad capacitors, so I figured I’d try a DIY fix. Searching around online produced one of many small hobbyist shops that specializes in retro game tech: Mortoff Games. Amid many DIY products, they sell a complete capacitor replacement kit for NES systems. I’ve got rudimentary soldering skills (and it’s only five capacitors), so I thought I’d give it a shot.
The general process is to remove the solder around the existing parts, using solder wick or a solder sucker, then replace each component. My wick was almost completely ineffective in removing the existing solder from the PDB, but I persevered. Trolling YouTube for “howto” videos produced the advice that adding a small amount of additional solder can help trigger the wicking action. I think part of the problem was that the board is so thick, too. Next time, I might try a solder sucker. Putting the replacement capacitors back in place was way easier.
Amazingly enough, after I put everything back inside the case, it worked! The unit powers on with perfect, crisp video and sound. For a beginner-level project, it was definitely a success. I’ve been introducing the kids to some older games, now that the system is working reliably. I just hope this isn’t the start of more re-capping projects…
So, after a very, very long time, I’ve decided to come back to my neglected website. A few years ago, when I was working at Nationwide Children’s Hospital, I had more than enough time to spare to learn basic system administration and write blog posts. However, since coming (back) to CoverMyMeds, I had less desire to work with computers outside of the regular 9-5. Late last year, however, I ended up switching teams, and while the new team is good, the work just isn’t as satisfying as it used to be (I could probably write a whole essay on that, but we’ll save it for another time). Therefore I’ve started itching to do “extracurricular” activities.
One of the things on my list has been to ditch ReCAPTCHA from my lame commenting system. The main reason is that, in general, I’m de-Googling. I was an early Google user (snagged my preferred username on Gmail by signing up on April 1st, 2004; remember how folks thought 1GB of storage was an April Fool’s joke?), but they’ve transformed from the scrappy tech-nerd underdog to a giant data-sucking behemoth. I’ve been taking steps to preserve my online privacy by installing browser add-ons such as uBlock Origin, which really enhances my web experience — with the unfortunate side effect that some sites break, because they expect certain JavaScript trackers to be present. This includes ReCAPTCHA. ReCAPTCHA is mostly a black box, but in general it forces users to help train Google image recognition, and in part seems to determine your “human-ness” by your activity on Google properties. I don’t really want this for myself, so it also doesn’t make sense for me to force it on the few folks who might stumble across this site.
Following a recommendation on Twitter led me to hCaptcha. It’s basically a privacy-enhancing alternative to ReCAPTCHA — it uses similar checks to prevent abuse, but is not helping Google hoover up all the datums. Of course, hCaptcha makes it pretty easy to change a few lines and start using their service. In making the change, I struggled more with updating the super old versions of the Ruby libraries running the comments app, rather than with any hCaptcha problems. I’d recommend giving it a shot!
Recently I was tasked with developing an Apple Watch extension for an existing
iOS app. Since I have no interest in Apple Watch, I’d never taken the time to
use one, or investigate the development process. After about a month of banging
my head against the keyboard (in a metaphorical sense), I thought I would
complain about my experience on the intarnets.
First of all, Xcode won’t install development builds if the watch is locked, and the watch
locks itself on sleep when not being worn. So you basically have to be wear it
in order to do any sort of active development. Annoying if wearing something on
your wrist is irritating whilst typing.
Speaking of wearing the watch: the plastic band which is included with the cheapest watch is the absolute
worst. To secure the clasp, you need to thread the loose end of the strap in
such a way that the rubbery exterior rubs right against your wrist, catching
and pulling out every arm hair in its path.
When testing a watch app on the actual device, the app never launches automatically.
Xcode says it is running, but there’s no indication on the watch itself. My
technique here is to open an unreleated app, which seems to trigger something
and remind the watch that it’s supposed to be running the development target.
The watch simulator is no better. Apple Watch has two modes of interaction: touch and “Force Touch.” The simulator’s
default option is to differentiate between the two by using Apple’s new pressure-sensitive
trackpads (if available). Problem is, it doesn’t work. Then you need to switch
input modes by using a keyboard shortcut. Except the shortcut doesn’t always
work either. When trying to bring up a context menu, I’ll Cmd+Shift+2 to trigger
a “deep press,” then tap the simulator, and nothing happens. It seems to randomly
work on the 3rd or 4th try.
Communication between the watch and phone is slow and/or buggy. Even on the
simulator! I guess maybe they’re trying to totally emulate real-world behavior,
which in that case kudos all around. I will randomly get WCErrorCodeMessageReplyTimedOut
errors, then do the exact same thing a second later and have it work flawlessly.
Speaking of communication, you’ll probably want/need to communicate with the
parent iOS app from a number of the different views in your watch app. Problem
here is that only one WatchKit class can receive messages from the phone. So
you end up making your extension delegate the message-sending delegate as well,
and handle communication within the watch app by sending notifications everywhere.
For a simple app it might not be so bad, but that sort of architecture gets
unwieldy rather quickly. Maybe I’m just a dummy, but Apple’s documentation sure
doesn’t mention any other potential design patterns.
Speaking of documentation, Apple’s documentation is… not great. Many times there was no differentiation
between watchOS 2 and watchOS 3 APIs. I spent a ton of time finding out that
it is impossible to share UserDefaults between watch and phone. Problem is, it used
to be possible, and so I fiddled about implementing “solutions” that never worked.
I ran into two issues that the documentation makes no mention about. I don’t often ask questions on Stack Overflow, but did
for these particularproblems.
The answers I got were underwhelming, to say the least.
Basically, the entire process was death-by-one-thousand-cuts frustrating. I wasn’t
bullish on the entire concept of smartwatches, and if this is what the “best”
has to offer, I might be put off it for good.
Recently I had need of a way to find how “similar” a collection of images were. A classic
way to diff images is to take one, invert it’s colors, then draw it over the
second at 50% opacity. It’s pretty easy to do this in CSS.
If both images are the same, the resulting combination will be perfectly grey (rgb(128, 128, 128)).
Since we’re JavaScripting all the things
these days, I figured that this technique could be implemented in JS. Fortunately, HTML’s
<canvas> element has APIs that allow for easy access to raw pixel data of an
image. You can call getImageData on a canvas context, which will return an
object that contains an array of RGBA values for each pixel in the image. Using
that data, it’s easy to invert the image a canvas displays (subtract each color
value from 255), and also compare the resulting combined image.
The only real annoying bit is synchronizing loading each image, and also determining
how long the entire diff process took. To that end, I created a giant array of
promises, each of which was itself a promise for loading/comparing two images.
The resolution of the giant promise array concludes with a timestamp comparision.
Where sources is an array of image URLs, and results is an array of integers,
indicating similarity between two images in the source array. A value close to
zero indicates the two images are very similar, while a value closer to 128 shows
that they are very different.
The only downside to implementing this type of algorithm in JavaScript is that
it can take a very long time to compare two large images, as you are iterating
over each pixel in the image, twice. For two 8 megapixel images (e.g. taken by
your iPhone 5), that is 32 million pixels. As a proof of concept/toy/small
image diffing tool, it works pretty nicely though.
I was reminiscing to a co-worker about my time in Japan, and told him a story
that I’m not sure I’ve ever told anyone else. So, why not regale the internet
with pointless personal anecdotes?
For those who don’t know, I taught ESL in Japan from the summer of 2004-2005.
Somehow I had ended
up connecting with the owner of a private school that was located in
Utsunomiya.
Definitely something of a backwater locale, even though it’s only 60 miles
away from Tokyo. Most of my teaching was in the main office that was close to
the center of the city, but I also had to regularly commute to a satellite
office that was in nearby Tochigi
(bizarrely, on a rail line operated by a department store). The school I worked
for, being a small family-run business, had all ages of students: I sometimes
“taught” preschool kids, and my oldest student was a guy in his 80s (whenever
he missed a class I worried that he had died).
One of my students at this satellite office was a junior high student named
Moe (pronounced moh-ay). She was actually one of my better students; since
she was more fluent in English, our lessons were more high-level, and therefore
less boring for me. Towards the end of the 2005 school year, my Japanese co-worker
and I had finished a lesson with Moe, when she invited us both to a concert that
her school band was giving. While my co-worker demurred, I thought, “Why not?”
and told her I’d go (toward the end of my year-long contract, I’d determined
that I was not going to stay in Japan, so attempted to have a “try anything”
attitude during my remaining time).
The concert was on a Sunday, and the day before I was working in the Tochigi
office as usual (yes, I had to work on Saturdays,
and got Sunday/Monday off). Imagine my bemusement/concern when, at the end of the
day, my co-worker suddenly pulls out a giant bouquet of flowers. “Here, you can
give these to Moe.” she blathered. I worried about what people might think of a
20-something foreigner giving flowers to a young female student, but felt
obligated at the same time. Cursing her under my breath, I took the bouquet,
trying not to think about what I was going to do with it.
The next day, for the first time ever, I took the train to Tochigi for non-work-related
purposes, and walked to the school. It felt pretty weird to be commuting on my
day off. I ended up stuffing those damn flowers into my backpack, and figured
I’d worry about them later. As I walked into the school auditorium’s foyer, I
could almost hear people’s necks snapping as they turned to look at me. Of course,
I was the only non-Japanese person there. And I don’t know why I didn’t think of
it before, but of course it was an all girls school. The awkwardness of my
presence had just increased exponentially. I brazened it out and found an
inconspicuous seat near the back.
From what I remember, the concert itself was actually enjoyable. I didn’t go in
expecting too much (remembering my own school-age band concerts), but as you
might imagine, the Japanese always seem to take things to the next level. Not only was
the music played impeccably, they also threw in some choreographed movement with
their instruments.
After the thing ended, the students dispersed into the audience to receive
congratulations from their various family members, and I had to deliver that
albatross-like bouquet. Fortunately, I was able to hand it over pretty
inconspicuously, thanks to the crowd.
After the meet ‘n greet, the students were called back up to the stage for a
group photo. Imagine my chagrin when the photographer, seeing a white guy hanging
around, yelled, “Who’s he with?” When it became known that I was Moe’s English
teacher, he told me to get up on the stage for a photo, a suggestion that was
enthusiastically received by the girls themselves. “Jeez, you’re tall!” I
remember one remarking.
So, somewhere in Tochigi, there’s a photo of an all-girls junior high jazz band
with a nerdy guy standing in the middle of the group, trying desperately not to
look as awkward as he feels. Good times 😅.