Friday, April 19, 2019

use your words, gadgets!

For a few year I've been partial to BeatsX headphones - honestly all wireless audio solutions lack gravitas - the Borg look of oldschool Bluetooth handsfree things, the double Uhura of Airpods - even over-the-ear big headphones look like earmuffs, or maybe Lobot from Empire Strikes Back. The "librarian eyeglass holder strap" look of BeatsX weren't so bad by comparison, and I liked how they use the same Apple W1 chip as Airpods - but you can take one out for a bit without having to hold it or put it away or have your music stop.

But I'd been through too many pairs - lost one, misplaced another, and then my main ones started losing sound on one side. (The build-quality / feel of them is great, but the durability just so-so.) So I went to Best Buy and discovered cheapish (~$30) earbuds of decent quality are now a thing! I bought a pair of Sony's WI-C300. This review agrees the sound quality is pretty decent, which is all I need - I tend to use other things for music, and have these for walking around to podcasts, and despite being a musician I'm not much of an audiophile.

Overall they aren't as comfortable as the BeatsX - the wire is a bit short, and that wire's skinniness is much less appealing than the Beats ribbon, and the buds don't have magnets (in theory useful to complete and secure the "necklace" feel when not in use, in practice it's just pleasing to have magnets to play with) but in one simple way it's much more comfortable - when you power them up, a chime plays and you hear a voice say "power on". As the things connect to your phone, another chime plays and it says "bluetooth connected".

That is SO much better than the little musical blurbles BeatsX play. There's kind of one that goes up to say "on" or something, and another to say "powering down", and maybe some chirp when it connected to the phone but I was always having to yank the control bit around to look and see if the little light on it was shining or not, because it was pretty ambiguous. (This is not helped on modern iPhones, where they don't have display area to spare to always show you if you're in headphones mode or not.)

Good old Bluetooth plus a voice explaining the status is way better than anything I thought I was getting from Apple's W1 chip plus nearly meaningless musical ditties! I think there's a simple UX takeaway here - just use words! (Ideally with an option to change languages, but I'd rather have a human language I didn't know than try to decode the musical language of Beats designers.)

Sunday, April 14, 2019

really old web design

I was looking at the late-90s rendition of my website, back when they were called "homepages" (Hooray for the Internet Archive Wayback machine! That site,along with the original versions of Google, Youtube, and Shazam, are things where the magnitude of what they were doing just flabbergasted me and still impresses.)

Anyway, I had to pull up the devtools inspector, because it wasn't clear at a glance how I achieved the layout of my photos page - it has a kind of pleasing irregularity to it. I knew it was tables, of course - turns out it's a rough two-column layout, with on-again-off-again use of the img align tag - I may have just been playing around with how to sort-of-align a set with portrait, landscape, and square cropped photos.

I'm thinking of this time in part because of the 25th anniversary of Tufts sQ!, my college acapella group. And I remembered that my early web designer self was strongly influenced by my camrade Erica's sQ Official Homepage - both the "columns but not rows design" and the use of transparent-background photo icons (in particular, the airplane on that page) were strong influences on my early sites.

Sometimes when I'm looking at my old raw HTML I'm delighted to see it all in caps - a habit I believe I got from Perl and other technical documentation at the time. )It's not clear if I had outgrown the habit when I designed that page)  These days it's unacceptably uncool (probably even deprecated, since xhtml-stuff was in all lower case, I think by mandate) - on par with using tables for simple flexible layouts - but honestly, in an age before fancy highlight editors, it made it very easy to discern what was content and what was markup...

Wednesday, April 10, 2019

the underbrush

As I go through and groom old blog entries and see just how many broken links predominate, how the old geek vision that "urls can be forever" is almost completely unrealized, but sometimes I can use a search engine to find a replacement for a yanked Youtube video, I realize that one purpose of Google is weeding out the underbrush of fallen sites, if search wasn't a constantly renewed process and we relied on old archives we'd be choked in a forest of dead wood.

Tuesday, April 9, 2019

UI hall of shame: Samsung NU8000 onscreen keyboard

Last December I bought myself a Christmas gift, a lovely 65" Samsung NU8000 television. (I miss my old projector, but given my space, this is the smallest size that still feels like a billboard, and Wirecutter likes the low-lag mode of these for videogames)

Overall its UI is pretty grand - much better than the older Samsung my mom has - all the apps are easy to get to and most are of good quality, and the shortcuts from the main screen generally make sense (and I'm not TOO worried about the data collection I'm sure this beast is running on me.) But the onscreen keyboard they use for some of their setup/config is THE #&$#(*$@& WORST, especially for entering a password. 

It's kind of a standard "use the cursor up/down/left/right, select the letters via an onscreen keyboard" (laid out like a normal typing keyboard) that video game console owners have put up with for a decade BUT -- 8 letters or so into typing a minium-length-8-character password, say -- once you select a letter, the space immediately to the left of the character you just typed becomes a checkbox, a short cut to "I'm all done".... so if you're bopping along, trying to efficiently enter your password, and it starts with "ireallyreally" in it... you enter the r of second really, that's the eighth character - meaning you've meant the minimal wifi password length, so then when you go to move the cursor to the left, you're not over the "e", you're about to select the "I'm all done" checkbox.

And you hit the center of the button thinking you're on the e, and the thing thinks you're done, and takes away the screen to try out your (of course incomplete) password, and you have no idea what is going on, but you're on a totally different screen entirely, and you don't know what the hell happened, so then maybe you repeat this dance two or three times, because it's such #$#(*@ STUPID HALF-BAKED DUMB@#$#@ INCOMPETENCE in trying to make a "helpful" - yet fundamentally unpredictable -User Interface

A core of "Tao of Programming" is the "Law of Least Astonishment", i.e. a program should always do that which surprises the user least - and this is a FLAGRANT violation of that very simple principle.

Of course, even once the user has overcome the surprise of a barely-useful shortcut showing up where there wasn't one before, to REMOVE the "helpful" checkbox you simply go select another letter and the checkbox goes away- but it comes back, so for the rest of the text entry if the next letter you wish to type happens to be to the left of the one you just entered, you have to wiggle the cursor around to shake off the dang uselessly premature checkbox.

Programmers. They need to learn the difference between "can" and "should"

(Mercifully, the searches on the various apps like Netflix and Amazon Prime implement their own keyboards, free of this half-bakerd crap.)

Monday, April 8, 2019

ecmascript 6 is fire. i mean, it should be burned. (safely destructure nested js objects)

ECMAscript 6 has a lot of features. One of them is Destructuring Assignment with Deep Matching which you can combine with Shorthand Notation... so you can do something like

var { foo, bar: { baz} } = someCall();
which is the same as 
var tmp = someCall();
var foo =;
var baz =;
One interesting note when you use that kind of destructuring is that the intermediate variables aren't defined - e.g. you don't get a "bar" in this case - "bar" is just a signpost to the structure
The problem is, things are very unhappy if "bar" is undefined.

I'm not sure if there's any cool syntax that might say "please destructure this, and just give me back an undefined for nodes I am implying should exists even if they having missing parent" (Because "is not defined" errors are so much harsher than mere "undefined" variables despite the superficial similarity.) 

So the boring way is to break the destructuring into steps and use object matching default values:
var {foo, bar = {}} = someCall();
var {baz} = bar;

As I ask about this at work, it's interesting how many devs I hear express some dislike for all the new synactic hotness. And I agree, things (especially curly braces) are weirdly context dependent and then there are tricks like destructuring with renaming
var { foo : bar } = someCall(); 
//same as var bar = someCall()['foo'];
that feel like a weird mix up of left operand and right operands - as if the meaning of the : has done a 180 relative to a "normal" object creation (e.g. var foo = { bar : 123 })

Saturday, April 6, 2019

eric was right - sometimes declarative rendering is better

I had a great tech manager Eric last year. He shared some of my inexperience with React and Redux and the concepts that underlie them, but he attacked the learning curve with gusto.

He told me how he made a learning/side project for a trello-like system, and for grins he implemented it with React (or maybe one of those Build Your Own Baby React systems) and then with more traditional methods. And he said, the declarative rendering system was miles ahead in speed and ease of use.

I didn't believe him.

Woe is me!

For my Porchfests side project, I needed to redo the Hourtron - as you can see with the (fairly simplistic but clean) 2015 prototype for it, the idea is you have a bunch of rows representing porches, and columns that represent performance times, and then you can drag and drop bands unto performance times / locations.

So for the first real implementation (2015-2018), I had it save all the performances on the page (aka "gigs") at once as a giant blob of JSON. I wanted to better support one band having multiple gigs, as well as be a bit more robust and be able to save each gig as it was set - I did a from-scratch rewrite (also figuring I was too pure of heart for JQuery, which was ok-ish for the drag and drop but was weirdly infeasible for the Ajax POST)

It was harder than it looked. In particular, these DOM blocks I had sometimes representing an unplaced band, sometimes showing a band at its gig - the IDs for gigs were server generated, and linking that gig id with the block in such a way that moving the gig time or place didn't generate a duplicate gig, was way tougher than I expected, and I realized the declarative method of saying "this bit of memory represents state, and the DOM can just reflect that as quickly as possible would have been great"... also the jQuery-free version of drag and drop reminded me that the "ghost" I use to show where a band will be dropped could still be handled as plain old javascript, so kind of a hybrid where the main block schedule was React-or-similar but the drag and drop was separate would have been fine.

Ah well, live and learn. I need to rethink my side project setup... I still like renting a cheap VPS and putting everything there, but I need to build up tools so that I can use tech that plays better with some kind of build system, rather than being spoiled by the "I save the raw file, reload, and run". Stuff with watchers and what not can get that feel pretty speedily, tbh, and then I have more options about the babel-ization and what not I use.

Friday, April 5, 2019

you may need jquery after all

Grrrr. Just blew like an hour on a pressing project, thinking I was too pure for jQuery--
You Might Not Need JQuery claims that
  type: 'POST',
  url: '/my/url',
  data: data

can be replaced with

var request = new XMLHttpRequest();'POST', '/my/url', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

On firefox and chrome, this does not seem to be the case

My test script was
$res = array();
$res['msg'] = $_REQUEST['bandid'];
print json_encode($res);
and looking at the network panel, the jQuery version does what I expect (using the print_r to mirror what I passed in (i.e. the 'data' parameter in both cases is a simple JS object) and the XMLHttpRequest version seems to send nothing. Probably missing something "obvious" but too tired and stressed to deal with it now.

Wednesday, April 3, 2019

unpopular opinion: 'developers do their own testing' doesn't scale

Almost two decades ago, I ran into Mr. Bad's Things to Say When You're Losing a Technical Argument. My favorite was the shortest, and first on the list:
1. That won't scale
So, keep that in your back pocket.

Sometime over the past decade, the concept of "We don't need QA as a separate discipline - we can trust our developers, fortified by automated testing".

Almost exactly five years ago I wrote a blog entry about joel on software and the quixotic nature of complete testing . I still stand by most of what I wrote there - especially about how hard it is to get coders to bruise their own ego, and think outside the box.

But the "No QA" policy is so hip and trendy in tech - and yet I know of at least two companies following that path that are really struggling with frequent emergencies. And of course, it's pretty smart and productive people espousing it.

My current theory is that the idea that developers know enough about the holistic system to do a good job of knowing what will break - not just coding to prevent it, but then taking the next step of meaningful tests well "outside the box" of where they've been codin - only works with a limited scale code base. As a team grows and codebase ages:
A. you probably have a smaller proportion of "rock stars" than you had early on
B.  the newer people haven't witnessed the growth from the simple core to whatever gnarly forest you now have, knowledge of which helps in intuition and sleuthing
C. just the number of connections is increasing, exponentially or at least geometrically. There's just more there there! Maybe- just maybe- "developers do their own testing" doesn't scale across time and space.

This is why my favorite work setups involved a small group of dedicated QA folk. They were engaged enough to ask good questions (different from that "oh we'll let offshore QA bang on it overnight" I've seen elsewhere), smart enough about the codebase - and at a high enough level - to have a gut feeling for where a new change might be problematic. It's a bit adversarial (but in a congenial style) in a way that a coder finding their own bugs isn't, even if the coder has a reputation to protect.

Tuesday, April 2, 2019

php notes: a directory full of json

Like I said in 2015,
Good lord, I know I'm not impressing anyone by digging on PHP, but man does it do a good job making easy things easy.
For a while now, I've liked doing my serverside plumbing in PHP and keeping my UI options open in javascript.

One of my favorite robust poor-man-db's paradigms is storing flat JSON files in directory - roughly, a directory is like a table, and each file is row. (GUID-ish filenames acts as a rowid). There are some downsides (it's not easy to rearrange columns, reading in a whole table is a large-ish amount of file reads, etc) but it's super-robust, hyper-portable, easy to implement and simple to operate on the data without simple text editors.

And sometimes, I just like to squirt a whole dang "table" like this into a page - here's some PHP that I'm sure I've recreated many times that does that:
    function dirOfJsonToFilesToJsonString($dir) {
        $files = array_diff(scandir($dir), array('.', '..'));
        $guts = array();
        foreach ($files as $i => $file) {
            $raw = file_get_contents("$dir/$file");
            $guts[$file] = json_decode($raw, true);
        return json_encode($guts);
That comedy gem wraps the full table contents as a JSON object/map string, and then I can let javascript do all the UI work.

Again, no one is impressed, but I'm one of those who believes in taking PHP seriously ;-)

Wednesday, March 27, 2019

nouns and verbs redux... or rather, react

For a long while I've been framing some of the difference between my mental modeling and that of another population of developers as the nouns vs verbs.

I thought of that today - my task was to put some analytics to monitor when our main "hamburger" menu was opened. I poked around the React inspector and at the source and couldn't see anything that looked like an "open menu" event. Investigating with the other inspector tools I shortly realized the trick employed was to have the clickable burger bit be a
<label for="anInvisibleCheckbox"> 
and then some CSS using the ~ sibling selector and the checked state put the sliding menu in the correct position, along with a easing/transition to let it slide gracefully into place.

It strikes me that the method they used was fundamentally "noun"-ish (i.e. the visible state depends on the checkbox) and that my thinking while hunting was fundamentally "verb"-ish - (the click causes an onpage action to occur) and so it took me a little longer than it might have to realize there was no onClick to be found.

I know I'm biased, but somehow the "invisible checkbox" feels like chicanery to me - not to mention, to do the analytics, I had to code to an imperative style, rather than the declarative pattern the invisible checkbox represents, anyway.

My thinking reflects my history as a web developer - from the bad old 90s when an entire HTML page would land as the result of some serverside CGI processing, and that's all you got, on to me  learning CSS and JQuery at the same time - a paradigm where the DOM is stable (more or less like the CGI days) but where Javascript with JQuery selectors could make changes to it at certain specific times, kind of an event-driven model.

This DOM stability is in sharp contrast to the Angular and React assumption that declarative nirvana is found by assuming JS memory is canonical, and that the DOM should be rejiggered as quickly and automatically as possible to reflect those structures. (And of course Redux swings back around to an event-driven way of thinking, but with formalizing manipulating the store/state of memory and not DOM.)

And making a smoothly transitioning UI (a critical bit of UX) uses those CSS transitions - still not my most fluent language, and still feeling a bit awkward. I guess it's because it's nouning a verb, so to speak-- or rather applying the adverb to the adjective....i.e. when you add an easing to a jQuery transition, you're clearly applying an adverb to a verb - change this state quickly, or bouncily, or whatever. Declaring it as a CSS transition - that when this adjective (e.g. the right: property) changes, it changes slowly, or mechanically, or whatnot.

I'm not saying my event-driven, DOM-centric, verb-ishness is superior - but knowing what my instincts are, and that they differ from those of some of my peers, helps me get in their heads a bit more and understand their presumptions and their code that much better.

Tuesday, March 26, 2019

the art of computer designing

The other week I went to a Boston Tech Poetics meetup (recommended if you're a coder or maker in the area!) One of the speakers was Zach Lieberman, who quoted this:
The work of past ages accumulates, and is remade again.
--Osamu Sato, "The Art of Computer Designing"
I don't think the book resonated as deeply for me as for him, but I could see it hitting the sweet spot if some creative person encountered it at the right age or in the right frame of mind. Used copies on amazon are like $600, but has a good copy online

Wednesday, March 20, 2019

crossbrowser regex danger (and the danger of chrome as your only test browser)

Today we found out the hard way that
return string.replace(/(?<!')'{2,2}(?!')/g,
(meant to replace double apostrophes with single, but leave 3 or more alone) will work on chrome but not Safari or Firefox.

Similarly, Firefox doesn't seem to support the //s operator for multiline matches.

So be careful. And don't just test in chrome!

Saturday, March 16, 2019

surf-tinged hardcore emo with a country twang and the problem of genres

The fundamental music genre list - my cousin Nathan posted this, I immediately thought of it in terms of a big problem for some of the porchfest websites I run - individual sites have to decide if "your band's genre" is a fill in the blank or a picklist. On the one hand I don't like to stifle bands (I mean, I guess in most of these taxonomies, the NOLA-influenced activist street bands I play in are... "Jazz", I guess?) but come on - "surf-tinged hardcore emo with a country twang" isn't really a genre people are likely to search on...

Wednesday, March 13, 2019

playful vr

This is a note I wrote to the group Boston Tech Poetics (formerly Boston Creative Coders)

Thanks to Adam and everyone who helped set up some great talks the other week!

I was so glad I shook off an urge to lose myself in my kindle until the "real" talks began - we have a nugget of this great little community doing really cool work here, and I'd love to see more - both what people are doing (like in the other thread) and also stuff, obscure or well-known, old or recent, that they think other Tech Poets should be aware of.

Zach Lieberman's work reminded me of two other artists I wish more people knew of: Some of his overhead projector / shadow stuff reminded me of Myron Krueger - he was working on amazing interactive stuff, most often w/ realtime silhouette / shadow data, and he started doing that when, like, "Pong" was the new hotness - but with a fervent dedication to keeping things real time. You can see a decent overview of some of his stuff here:
(Zach showing us Chris Sugrue's "Delicate Boundaries" was such a lovely extension of some of those ideas)

I like to see where ideas like these, either descendents or parallel thoughts, get commercialized. Way back in the PS2 era, "EyeToy" had some elements of that, of using simple webcam data to let you, say, fight off a big group of tiny ninjas leaping on you Maybe too this is all on my mind because I just got one of those PS4 VR setups, and some of the mini worlds play with some similar ideas...

At some point Zach was showing clips from software where people would draw something in a space, and that drawing would take on some kind of life - this reminded me of Takeo Igarashi's work.
He came up with this concept he called T.E.D.D.Y for making 2D sculptures by extrapolating from simple 2D doodles -
This got put into AMAZING commercial life with a game called "Magic Pengel". This was a PS2 joint project with Studio Ghibli (!!) and you didn't just draw static things, but fighting critters - as you drew, you indicated if this was a leg, or a wing, or a tail, or what, and then some super clever code animated what you drew and put it dancing and weaving in 3D space. Quite amazing! Unfortunately, the combat was just Pokemon-like Rock/Scissors/Papers turn-based battles. (A sequel, "Graffiti Kingdom", tried to make the creation system less loose and more engineer-y, I don't think it was an improvement.) Here is a Lets Play:

And while that video has loose, clay-lump drawings, apparently the sky was the limit in the hands of a skillful, determined artist:
I'm just blown away by this stuff. Going back to 2D, there was that "Crayon Physics" type games, and I see some more recent "2D physics from doodles" - but this 3D stuff was totally next level, and I'd love to see it in more applications - T.E.D.D.Y really bridged a gap from 2D inputs to 3D sculpture, and I don't even know what kind of black magic and animation genius about joints and physics Magic Pengel employed - I'd love to see a "Smash Bros" type physical combat with this idea (but I'm nowhere near smart enough to make it)

So what have you seen, either in the artists studio or gallery or on the store shelf (virtual or otherwise) that inspires you? What stuff based on Ollllld technology still inspires that "damn, how'd they do THAT?" And where would you like to try and put it in your own work?

Thursday, March 7, 2019

henry ford and the faster horse

UX Cliches and their honest explanations. My UX GF points out these are a bit free with denigrating users as "stupid" but other than that it's not bad.

Monday, March 4, 2019

css selectors cheatsheet

Decent little CSS selectors cheatsheet. Not sure I agree with the recommendations of not using ID selectors, and I think some of the example circles would have been better served by using class= and id= , but once you get to the more complex sibling-style partnerings it makes more sense.

Thursday, February 28, 2019

pac-man: get a grip!

Pac-Man: The Untold Story of How We Really Played the Game - intriguing description of how generations of right-hand Pac-Man players clutching the left side for leverage leaves its mark on the old upright cabinets.
Interesting how Pac-Man, which like Q*bert was button free, was ambidextrous. Nintendo famously put the crosspad under the left thumb, which may have heralded a switch in games away from being focused on rough movement and towards precision timing. (Continued with the WASD/mouselook arrangement favored by PC gamers- something I've never quite gotten into my skin.)

videogames and the modern ul techstack

On my "regular" (now almost two-decades-old) blog - Just Cause 3 as Psychological Self-Care. Interesting to think about how games' "you can do this and persistence is always repaid" might help counteract the frustration with UI tech stacks that don't do a great job scaling down into quick "throw these on your personal webserver" projects...

Monday, February 18, 2019

is dotAll you got? (frustrations with firefox multiline string matching)

There's growing discontent among developers with Chrome as a browser (and the risk of it becoming a kind of monoculture in the way IE was, albeit not quite as crappily and a bit more standards-compliant) and many are making the leap to Firefox. And recently I was delighted to see that the developer tools were pretty much at parity with Chrome's, and used many of the same UI patterns as well.

But I found Firefox was choking on some regular expressions I put into the backend tooling for my website.
SyntaxError: invalid regular expression flag s
That s flag, letting an expression like /(.*)/s match multiple lines (because it says to treat linebreaks as normal whitespace-ish stuff) was a critical tool going back to my Perl days...

So to quote T.J. Crowser in StackOverflow:
You are looking for the /.../s modifier, also known as the dotall modifier. It forces the dot . to also match newlines, which it does not do by default.
The bad news is that it does not exist in JavaScript (it does as of ES2018, see below). The good news is that you can work around it by using a character class (e.g. \s) and its negation (\S) together, like this:
His examples then show `[\s\S]` replacing good old `.`. I'm happy to have the workaround, but man is that an ugly one!

I wish I knew more about the history here - feels like Firefox was sticking to the spec more righteously than Chrome, which I guess is fair enough, but why was such a critical piece missing from JS/ECMAScript in the first place? It smells a little bit like some religious war fallout, some coders didn't like multiline conceptually, or something...

p5 and figure-ground reversal fun

I have a notebook from when I was 18, the summer before college.

I had designed T-shirts for my high school's jazz band the years previous, and I guess the band was still the focus of tooling around with some design stuff, and so I made this:

I've always enjoyed handcrafting blockletters, and I believe I made these by drawing the 3D extrusion behind the letters and then just filling in the extruded bits on the page in front.

Anyway, I realized I can now have the mojo to get a computer to do most of the work for me, and so I made fgrtext: figure-ground reversal (the fancy word I saw for it on wikipedia's entry for negative space.) It's a little virtual toy to mess around with the words, colors and other factors.

I made it so you can bookmark creations - here are some designs I made for 222 Street Jazz:


and JP Honk:

You can view source on the page to see everything in one file. The core idea is pretty simple - keep drawing the letters repeatedly in the "foreground" color on a diagonal slant, and then switch to the background color and keep drawing the letters a few more times. There were some challenges in the P5 code for it - they have a library for DOM elements and oddly (to me anyway) you set their .parent() after creation of them, otherwise they just end up attached directly to the body of the DOM, which is kind of weird. (Also since they didn't seem to support textareas, it was pretty easy to manually set up the HTML for that and use vanilla JS onkeyup events to call my functions directly, a bit of mix and match.) One drawback to the sliders was I had to only pay attention to mouse moves withing the boundaries of the main canvas - slider adjustments were showing up as background/foreground movements.

Also I made creations in this system bookmarkable by putting all the parameters in a state object and then encoding the JSON stringified version of that as the hash at every draw(), and then reading the hash at start.

Another courtesy I do is using noLoop() to only draw when the state has changed - p5 is great for many things but processor efficiency isn't one of them.

Saturday, February 16, 2019

ripping music the old-fashioned way

In the beginning (well, my beginning anyway) there were LPs and my parents old 33s. Then cameth cassette tapes and behold the radiant wonder of the CD. Upon this time was a golden age of mixtapes, whereupon one might assemble a cherrypicked selection of tunes (and come on - some may disagree but wouldn't you say most albums are a few good songs and a bunch of filler?) for thine only pleasure or to pitcheth a bit of woo... (gettest thou to the High Fidelity if you are ill-informed of this most wond'rous art.)

There was a brief interval when "mix-CDs" were also kind of a thing - an impressive feat to make one in the mid-90s, when blank CDs were like $25 a pop and a "buffer underrun error" would leave your CD as nothing more than a pretty coaster or frisbee...

But then things went digital even before portable MP3 players (most famously the iPod) really took off. And when laptops were still price luxuries... not sure how we listened to our music, maybe with computer desktop speakers? Anyway, "Napster" was the darling of the turn of millennium - a  co-operative venture that would let you nab pretty much any song you could think of. That was amazing! But, it failed to produce a good method of getting money back to artists...and so Napster was crushed, and for a while there was nothing that replaced it - if you read about a tune and wanted to hear a sample of it, you were probably out of luck.

Eventually, things got better. Online music stores emerged (and Apple dropped its DRM), Youtube coverage of esoteric tracks got about as complete as Napster was, and then came the rise of streaming - a trend I still don't really get. (I sort of see the appeal of customized robo-DJs, but man, I just don't want to encounter that much new so-so music all the time. I prefer buying MP3s, listening to my "recently added" playlist to get acclimated to songs, and keeping all my music even if I stop using a service.)

ANYWAY. There are still some songs or amateur-musicaly-things that aren't available for purchase or other legit download. For a a long while Convert2MP3 did a good job of ripping tracks, but with the rise of Youtube's own attempts at subscription music services, this no longer works for most music tracks (I think it still is an option for some other things that Youtube doesn't categorize as music.)

I figure that with my multiple laptops and tablets I would be able to do rips manually - that a stereo wire with a plug on both ends would let one device playback and the other to record. Turns out it wasn't quite that easy? There are some rumors that Macs' lone audio port used to be able to be used as an input device, but maybe later versions of the OS stopped supporting that. An old Windows 8 laptop didn't seem much better about it.

So not wanting to resort to "be in a really quiet room and use the built-in mic for recording", I bought a USB mic and speaker dongle for like $7, and was then able to use Audacity. I have one wire from the headphone jack on an iPad and it goes right into the microphone dongle, so there's no room noise. I wasn't quite sure how to set the levels, but fiddling with the iPad volume while recording some throwaway tracks 'til the visualization showed consistent filling of most but not all off the space seemed to work ok.

I do worry over time this path will be shut down somehow - already it was awkward. I would have needed a dongle to do it from my iPhone, of course, and if my main Macbook was newer I wouldn't have needed a USB-C dongle for that as well ... and that's beyond obscure technologies that will strive to prevent this kind of shenanigans (like if you try to record video from a secure playback source, or for that matter how photocopiers will recognize currency and decline to duplicate it...)

Thursday, February 14, 2019

drawing x1,y1,x2,y2 lines (any angle) with divs

When I was playing with different technologies for my timelines project Timelines project one advantage P5 had over straight DOM-stuff was being able to draw arbitrary lines (I was already using a lot of X/Y coordinate absolute positioning, rather than letting things flow)

Not surprisingly it's pretty easy to do similar in DOM and CSS, using transform rotations and just a bit of geometry.

The core CSS could be
.line {
    background-color: #000;
    position: absolute;
    transform-origin: top left;  
(the container div should be be styled position:relative or similar)

and then the JS something like

function addLine(id,x1,y1,x2,y2) {
  const canvas = document.getElementById(id);
  const newLine = document.createElement("div");

  const length = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
  const ang = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; = `${x1}px`; = `${y1}px`; = `${length}px`; = `rotate(${ang}deg)`;

I created a codepen proof of concept but didn't make it do anything interesting.

Of course, this doesn't hold a candle to stuff like Diana Adrianne's pure-CSS oilpaintings but it's a start :-D (For that matter, arguably I'm just reinventing svg, badly...)

Tuesday, February 12, 2019

design failure - when numbers confuse

I am one of the organizers for BABAM, a Boston-based alliance of activist musicians. We had some internal debate about whether it was appropriate for us as an activist group to get involved in electoral politics - for example, some of our partner bands are 501(c)(3) organizations who would be prohibited from that kind of activity. Or, there might be some members who might object to implicit endorsement for a particular politician.

I created an online survey, and then decided to have some design fun posting  the results. I came up with the following, where the size of each of the 28 votes was a dot, with the size of the dot reflecting how often the person said they attended events. A comment at the top explained that the numbers were references to numbered comments below the main display...

But I was surprised when the first response back from the mailing list was
I may be reading these results wrong, but it looks like :
6 fully
22 quietly
1 indirectly
17 none
1 dunno
Aargh! I'm not quite sure how they were working the math, but clearly the digits were throwing things off.

My fix was to replace the numbers with letters, and then visually repeat the circle motif at the start of the comment itself:

 Ah well. Maybe the thing was trying to be too clever. I may have been too anxious to cross reference what a person voted from how often they showed up (originally I was going to do a 2 axis graph of "frequency person attends" to "enthusiasm for allowing campaign activity)

Sunday, February 10, 2019

RIP WAP (or don't, we don't care)

Doing some cleanup of my blog, I ran into's rant about WAP - now available only on the Internet Wayback Machine. At the time I linked to the article I wrote
WAP is the underlying protocol that you use when you use "wireless internet" on your cellphone. Although the protocol itself isn't too too bad (except for an odd 1492 character limit in how much a server can send in one gulp), it's associated with WML, a terrible HTML-like language, and also having to use the cellphone keypad to laboriously tap in letters.
I'm impressed at the combination of technical depth and strong feeling of that article. WAP was horrible. And like the article mentions but my summary leaves out, the nickel-and-diming of the usage fees kept people away in droves. While some other phones were creating more-or-less-ok web experiences on phones (I will always love this horribly NSFW rant extolling the Nokia E70 over the iPhone) I am convinced that one absolutely critical factor in the success of the first iPhone was getting Cingular/AT&T to offer it only with "all you can eat" data, so people could just use the thing without hearing the tick tick tick of an invisible meter run.

Around that time I was working on a project making a WAP gateway to your ATM account balance information (which is why I was intimately familiar with the 1492 character limit) -- late stage dot com boom was a weird time

Thursday, February 7, 2019

VS Code jump back to last edit spot

One feature I'd gotten used to in IntelliJ is a "back" button that would take you back to the last place you were editing, even across files. According to stackoverflow on a mac the combo I want is ctrl-minus (or ctrl-shift-minus to go the other way.)

One feature of VS Code I didn't really grok til I did a big React/Redux fix is the "list of currently open files" on the sidebar. At first this seems a little redundant - isn't that what tabs are for? But there's a bit more room there to show the relevant path bits. Depending on your project structure, it can be very useful to be able to see path info (like "containers/"  or "components/" or "reducers/" or what not) to more quickly get back to the file you're thinking of.

Wednesday, February 6, 2019

visual studio code's logo is a disaster

Trying to be one of the hip kids at work, I'm migrating to Visual Studio Code.

I've complained about editor icons before but VS Code's is horrible:
This page talks about its origins - it claims
We iterated on the infinity logo for some time [...] Until we landed on the current "fish", which tested well with admittedly, a small number of developers.
A. That's... not the infinity logo, chief.
B. with current coloring it looks more like "XJ" then "Infinity Corner"... or like it's a sideways "ribbon for cancer awareness" (Esophagal Cancer according to this page )

For people who tend to think phonetically, it's a disaster, and I don't see many othe redeeming factors in terms of meaning.


Just note to future self:
Work buddy Noah used this immutable.js codepen to help me come up with "how can I modify values in particular Map which is the member of a Set":

const set = Immutable.Set([Immutable.Map({a:'1',b:'foo'}), Immutable.Map({a:'2',b:'bar'}), Immutable.Map({a:'3',b:'baz'})]);
const newSet = => 
    value.get('a') === '1' ? value.set('b', 'hello').set('c','woot') : value

confirming argument order with es6 property shorthand

A coworker was helping me with some Immutable.js (blarg) and wasn't sure of the exact order of arguments his callback would be receiving so he did this:
const funk = (foo,bar,baz) => console.log({foo,bar,baz});
and then
would put
{foo: 1, bar: 2, baz: 3}
in the console, and he could make sure foo and bar and baz were in the right places in the argument list. 

Thought that was pretty clever, an easy cut and paste way of adding human readable labels from "mere" variable names via the es6 sweetening.

Thursday, January 31, 2019

finding files on a mac

I find it ironic that the MacOS file management program is called "The Finder" because finding files (like, with a search) is not really one of its strengths.

Here I am trying to find files with "tuba" in the filename:

Besides the clunkiness of having to use an autocomplete-like function to do a filename search rather than also searching file contents, this view is inadequate if you think it would be useful to know WHERE the result was at a glance. (For a while I was thinking you couldn't get the information at all, but if you select the file the path shows up on the bottom.)

Anyway, I prefer the clunky layout of the free app EasyFind:
It's easy to sort by location, which I find useful in many cases.

If you don't mind paying $8 or so some people prefer Find Any File, which offers a hierarchical view.

Heh - one of my first big tech rants was in 2004 when Windows switched to a sidebar integrated search vs the previously perfectly serviceable standalone mini-program. For Mac too, I find the habit of having just the same kind of display for search results as for folder contents as being a bit of a misthink.

Some people (not me in particular, but I was stuck on Windows til 2013) long for the old old days of Mac, where there was only ever one window for a folder, and it would remember its location etc. It added a certain realness and physicality to the file system, I think.

But then again, from Windows "My Documents" to iOS's too little too late "files" app, OSes kind of don't want regular users thinking in terms of filesystems. And to be fair, it probably is simpler for many folks, but as soon as the folks want to level up and, say, back up their files on their own, or in general not be so beholden to a particular cloud service, it's annoying. (In the windows days C:\DATA was always "my stuff", and transferring to a new PC was pretty easy. These days I stuff everything into Dropbox, which is nicely multiplatform and straightforward in its folder->server mapping.)

Monday, January 28, 2019

timelines title image

I wanted to add my recent timelines project to my alienbill portfolio page - recently I redesigned that page to have fancy titles for the main attractions - I thought for timelines I would take a whole-document screenshot (with Fireshot) than copy and paste lines from that into the title "TIMELINE" (Guess I don't need the S, really, which means all the letters are composed of straight segments).

Here was the first result as seen on the page:

It had some legibility problems, so I went it and hand cut the whitespace around each letter:

Not quite perfect, but good enough.

Sunday, January 27, 2019

amazing playful interactive artsy stuff in browsers by david li

A friend linked to choir, an amazing software toy - a bit like my old favorite mobile app Bebot (a "robot synth") but with a choir and fascinating pseudo-photo-realistic visuals and physics.  (On my old Macbook Air, chrome struggled with it but firefox was fine, as was mobile.)

He has some other amazing works as well - "Character Soup" was a lot of fun with some probably relatively simple but well done fluid physics - the combination of that along with characters to make it less abstract is phenomenal.

Besides his git repository being there, he tweets a tiny bit about his methods - he's doing a lot of stuff in low level wasm and crosscompiling from C++.

Man! I wish I had the chops to code up fluids and 3D.

Also kudos to Adult Swim for sponsoring this kind of stuff.

Friday, January 25, 2019

slack strike out and strikethrough

Daringfireball really ripped into the design work for Slack's new logo:

Before and After image from this page that has some more thoughts. I admit I am not a fan of the "squirting rainbow cucumber swastika" aspect, but YMMV.

Anyway, today I learned you can use tilde to surround text in slack and get a cross out effect. This might make sense to remove a top level comment that then turned into a thread, since you can't properly delete it otherwise.

Thursday, January 24, 2019

slightly fancier console logging

Hmm. Dan Abramov's Idiomatic React Video Course mentioned a few tricks for console supported in chrome and some other browsers (but not all, so you might want to look for undefined functions)

You can do and console.groupEnd do give some nice formatting/indenting.

Also, console.log('%c smurf','color:blue','!!!'); gives you a blue smurf. (Heh, the color console logging thing is very similar to the example trojan horse used in I’m harvesting credit card numbers and passwords from your site. Here’s how.)

Sunday, January 20, 2019

#Software10YearChallenge meet #Website20YearChallenge

#Software10YearChallenge isn't really taking off, and I'm not sure website even count, and it's not like my sites have set the world on fire, but anyway, thanks to the Wayback Machine it's pretty easy to get old views of my two most important sites  and  (I'm sure the name changes didn't help my google juice none.... )

Alien Bill was my first domain, with "Alien Bill Productions" being my fake-y company since my teen years. In the late 90s it looked like this:

Oh, man. What's best about this? The animated GIF at top? The Robotech font? The "Imperfect Web Design for an Imperfect World" slogan? The subtle titled background rockets and UFOs? Or the photorealistic icons I was briefly enamored with? Probably that.

I like the running alien bill (the repeating squares behind him are meant to emphasize motion.) And the micro-screenshots are kind of fun too. I took the animation from the old header and broke it out by frames.
Current day. I've been using the oversized hero image for a while now, and kind of love it. Recently I did a redesign to really try to bring people's attention to the stuff that I'm most proud of or that they might find the most interesting, and used the title fonts from my various works when I could, which mixes things up in a kind of fun way.

Then, my blog, coming up on 20 years. This is shortly after I started blogging, vs just having a more personal homepage-
I moved the personal homepage stuff to a sidebar... and hey, remember guestbooks? Those were kind of great. (I remember my websites guestbook served as an emergency contact pad on a day of surprise layoffs at work, useful in those pre-Social Media times.)

Hmm. Went a little nuts. The hand-doodled icons at top are kind of a throwback to the mid-90s stuff, like an even earlier version of alienbill:
But for the sidebar I had these delightful tiny minimalist things. (Also I used to be so weirdly enamored of that shade of turquoise, which I think showed up in Windows 3.1 or 95 a lot)

Also that was when I was changing gears from slightly longer form blogging to stuff I could mirror on twitter, the "...of the Moment" section. Over the years the UI I built for that became my primary way of adding stuff to the site, and eventually I blurred the visual distinction as you can see in the present day:
A few Christmases ago I embraced a kind of minimalism, and had some fun building up a visual language for the icons and the title at top. Also I added a tag system which is sometimes useful to me.

Wednesday, January 16, 2019

operator overload

Watching this Redux Crash Course video, Brad uses
I could guess what that was doing, but had to ask what that syntax was called - "computed keys" or "computed property names"

In terms of JS, there's definitely a drive for conciseness. Which can pay some dividends in terms of letting experienced coders recognize a complex trope quickly, but also comes with potential ambiguity - sometimes i personally wish the language was a bit more verbose, even if function() { }s are ugly,  bar fat arrows or random floating {}s can be so hard to parse.

Anyhoo, a coworker recommended this guide to ES6 features - it's pretty cool in showing the old and busted after the new hotness.

Of all the new syntaxes, one sticks out as clunky, and the other sticks out as just plain bad and confusing.

Custom Interprolation:
new hotness:
get`${bar + baz}&quux=${quux}`
is the same as 
get([ "", "&quux=", "" ],bar + baz, quux);

Dividing a string that way seems very strange.
But Parameter Context Matching seems really ugly when it starts letting you declare a local variable from a totally different argument map entry....
I mean 
function f ([ name, val ]) {
    console.log(name, val)
function h ({ name, val }) {
    console.log(name, val)
make sense and are pretty easy to read, but the renaming that goes on with
function g ({ name: n, val: v }) {
    console.log(n, v)
is bizarre - it feels like it's messing with left / right operands, every else in js land the key / variable name you're changing is on the left...

(Random note: the video made use of which seems pretty hip.)

hungarian notation

I realized I was almost on the verge of forgetting the term "Hungarian Notation" - a now mostly rejected idea of prefixing variable names with the type of the object. It was probably rejected because it was misunderstood and misapplied - like you shouldn't call your incrementer iCounter just because it's an integer, but if you have, say, a screen dimension that might be in pixels or might be in em, it might make sense to have "pxWidth" or "emWidth".

For instance, I'm fooling around with a gimmicky 3D for my timeline data, and some of my dates are objects containing a y and m key for month and year, sometimes I'm using a "count of months" (i.e. y * 12 + m) and sometimes I've normalized it to a value between 0 and 1. Hungarian Notation kind of makes sense here.

(To google up the forgotten term I had to search "notation petzold" - ah, the old Petzold book "Programming Windows", what an artifact of my first programming job...)

UPDATE: My online pal Jeremy Penner of Glorious Trainwrecks and the Fringe Games podcast worked with Charles Simonyi (inventor of "hungarian notation") and told me about his experience with it:
Anyway, the whole system was written from the ground up using Hungarian notation, and it turns out that it's actually a very interesting mental hack with very unintuitive properties

So, for example, the thing everyone complains about, where coming to a new codebase is totally impenetrable? Like "what the fuck is an mpfuidsibst?" It turns out that's a huge tradeoff that absolutely makes sense when you're building something totally new, in that you don't assume anything about what an mpfuidsibst is. You KNOW you don't understand it instead of believing you have a fuzzy understanding that is actually incorrect.
(mpfuidsibst is a name I gave a thing and it is my go-to example of "this name makes complete sense in context but is utterly absurd to outsiders")
The other huge benefit is that it allows you to talk precisely about different things that are similar and would be given similar names
So instead of talking about an "event", and being unsure of whether you meant a win32 API event, or an internal UI event, or a "document modified" event, all of which are dispatched slightly differently and have different properties, you would have a unique short name for each, that you use consistently
The names are cryptic because they're short, and they're short so that you always say the full name out loud and don't abbreviate, so you are always precise in what you're talking about
It's as much a research collaboration tool as anything
And once you've bought in to the system, and you learn what things mean, it's incredibly effective at preventing misunderstandings
Heh, interesting. In some React/Redux tutorials, I've noticed some times when the naming gets a little fuzzy, like "todos" might mean the JSON object map in memory as state, or as the reducers that tell you how to apply a change to the old state to get a new state