Thursday, August 26, 2021

storybook - display the literal code in "show code" story block

 We were having a problem where the "show code" button for some of our components in storybook was being over-interpreted; like our formik config object was just showing as [Object object] and else where we were seeing children elements showing up as <MDXCreateElement> instead of the actual child.

One work around is to make sure you have docs.source.type = 'code';

Like in the meta of our .mdx that might be 

<Meta
  title='Components/Form'
  component={Form}
  docs: {
    source: {
      type: 'code'
    }
  }
  }}
/>

or we could do it globally in our preview.tsx, where we had a 

export const parameters = { docs: } 

All ready to go.

The downside is, this makes it so the "show code" content is no longer dynamic; we aren't applying it globally because we like the idea of having the source / properties for the current set of parameters shown. (like the code for a disabled button or whatever)

the music of the hemispheres

I slowly worked my way through Ian McGilchrist's The Master and His Emissary, his longest study into the division of focus of the left and right hemisphere of the brain and its possible implications for how societies construct themselves and evolve over time. 

Even if you are skeptical of the importance of the physical division in how our minds come together (though I think McGilchrist makes an excellent and well-researched case - I mean like 1/5 of the book is citations!) I think it's clear that there are several spectrums. In McGilchrist's view, the left hemisphere - the one that guides the right side of the body - tends to be very concerned with what it can control. It is reductionistic, it likes to categorize, it tends to isolate. In comparison, the right hemisphere is takes in the world as it is. It is holistic, everything is context-based.

Computer programming is intensely reductionistic. You solve a problem by breaking into tiny pieces. When explaining it to non-programmers, I tell it's like breaking a recipe into steps for an idiot chef. 

If you really push this idea, you get explanations for things like functional programming - the usefulness of completely isolating a bit of computation from context. Similar for unit tests: an extremely fine-grained way of studying every little pieces-part in isolation. 

McGilchrist worries that the left hemisphere (reductionism) tends to swamp the right hemisphere culturally, over time (with some counter-swings of the pendulum) but he doesn't think that the right hemisphere should predominate; the most fruitful times are when there's a balance. 

I see the for functional programming. On the one hand, it's easy to understand how code works best if you have clearly defined contracts and a clean room environment each time. On the other hand... it's often tough to get stuff done that way! I think of James Hague's essays on recreating retrogames as pure functional programs - if you think about all the state in even a humble game like Pac-Man: all the dots, the scores, the monster positions, etc - you REALLY have to jump through hoops to avoid terrible anti-patterns (whole state in, whole state out) and I begin to suspect it's would never have a good effort/reward ratio for forcing these games into the modality.

Similarly for unit tests. In my experience, programming bugs are an emergent property! In my experience, very few bugs are because of a blatant mistake inside of a unit... rather they show up as different units are drawn together, and these bugs reflect misunderstandings of contract or context. In other words, yes you want to keep an eye on your trees, but doing so obsessively isn't going to assure you have a valid forest. Higher levels of testing are critical, and to the extent resources put into testing one level might take from testing at another level, I would prefer the higher level views (that will, in turn, exercise the code at the lower levels.) But - it's a balance. (But my relative disinterest in unit tests is a rather unpopular view to people whose intuition believe it's THE key to keeping projects under control.) 



Monday, August 23, 2021

clickbait title images vs the skim

Netflix seems to be using more of a "clickbait" model. The article mentions one possible different path: analytics wise they ARE more closely tracking user engagement for like, entire series and 80% of full show, vs their previous "at least 2 minutes of watching".

I'll mention another factor that might ameliorate their clickbait trend: on most of their apps, their skim feature is really good. Empirically it looks as if they load a single giant image of thumbnails early-on, and once that is loaded you can skim the whole move -- effectively watching the whole thing on 10 or 20x fast forward, so if you ARE looking for something in particular: steamy scenes, battle scenes, whatever - you can ascertain that pretty quickly.

Sunday, August 22, 2021

homestar runner and the power of flash

Really good video praising both Homestar Runner and Flash as a medium in particular.

Flash's ignominious end is a tragedy! I never quite understood what happened. The reasons usually given for its demise are
1. "it's insecure". Like with Java applets, for some reason companies just couldn't get their acts together to batten down the hatches? Which is really weird, because it seems like stuff it would be very easy isolate in a virtual sandbox, especially relative to the trend to make javascript do everything.

2. "html5 is much better for video". I mean this is true, but as the video shows being "a wrapper for live action video" was a johnny-come-lately trick for flash

3. "it's hard on processor/battery life". I mean, I guess. But even in Steve Jobs' Thoughts on Flash letter, he's talking about video codecs, not the lightweight interactive animation that made Flash so powerful.

I think it's right to blame Apple for much of this. In that Jobs letter "Oh it's all mouse-centric, with rollovers, and our touch devices don't do 'hover'" is pathetically short-sighted - but it gets into the real reason, control of content. I think it's less "these Flash apps won't be good enough" and more they'd be too good.

Eventually, html5 technically picked up most of the capabilities that were lost when Flash went away, but there just isn't the community built up around it.

I feel bad that I didn't get into Flash... "Processing" was good enough for most of my stuff I wanted to build and then share via web, and now P5 plays that role. I took a one day class in Flash but it mostly dealt with animations that were easier to teach, not the type of interactive game stuff that I found most interesting.

I'm not sure where the action is, in terms of interactive content creation but especially community. P5/Processing has a little of that, "Scratch" probably has more - and Minecraft and Roblox, I think? And "Mario Maker". But much of the energy has been sapped off my either content creation community for non-interactive stuff, like Tik Tok.

In a related note I started playing around with Nintendo's "Game Builder Garage", pretty cool stuff as well... but it's always challenging to use a system where I feel a bit hobbled, especially at the beginning, relative to what I can make using traditional programming.

Tuesday, August 17, 2021

prokopetz on the tribulations of user-focused design

 While some people assume tumblr is a ghost-town, it actually is pretty vibrant, but is even more dependent on figuring out whom to follow than most social media. 

One of my favorite posters is prokopetz. He mostly talks about tabletop/roleplaying and games and general geek culture  (sometimes spinning off in hilarious ways with remarkable inversions) but I appreciated this take on user interface:

I guess a lot of my skepticism regarding user-focused design stems from working in tech support and witnessing first hand that user interfaces can only guide people to perform a task in a particular way if the method you have in mind is already very close to their prior assumptions about how the task ought to be performed.

If the way your UI thinks the task ought to be carried out and the way the user thinks the task ought to be carried out are very different, nine times out of ten what happens is that the user will Rube Goldberg together some bizarre workaround that’s ten times as complicated, takes ten times as long, and fights against the interface every step of the way, but preserves their prior assumptions, then become emotionally committed to their workaround and respond to any effort to demonstrate a more straightforward approach with extreme and disproportionate anger.

Critically, there doesn’t seem to be any way to avoid this scenario using pure design, because different people will have mutually exclusive prior assumptions about how the task ought to be performed, and you can’t possibly accommodate all of them. Conscientious design practices can supplement explaining shit in words, but they can’t replace it.

Figuring out the user’s possible mental model and explicitly hinting where it needs to be updated is so important! I’m a little more optimistic than the author, but still…

Monday, August 16, 2021

assembly

But as I read more about the physics of chips, I started to have a kind of acceptance of assembly language. I stopped seeing it as an annoying, unfinished abstraction--a bad programming language--and started seeing it for what it is: an interface to the physical world.
I am very bad at it now but I'm glad I dug into a little assembly language to make my Atari 2600 game JoustPong - and what I've learned about how damn physical and timer-based EVERYTHING is on that thing.

I remember having just a dash of assembly (of the Sparc or Solaris or whatever variety) in a computer languages class in college. It felt a bit dishonest, to be frank - like to run assembly that was talking about low level stuff like registers and what not, but then knowing it was on a system that was a bit virtualized, how it might be paged out by the OS at any time.

Saturday, August 14, 2021

believe it or not, i don't want the world to revolve around me

My sweetheart Melissa thinks it's bizarre that I switch my GPS app so that "north is always up", rather than the more common "forward is always up", with the display always shifting/rotation so it corresponds well with the view in front of the car hood.

There are three reasons I do this, in decreasing levels of silliness:

1. To up my manliness! I'm sure it's an outdated belief, but one nugget that stuck with my from like Cognitive Science 101 in college is allegedly men are better than women at performing mental spatial rotations. I don't want to get into the discourse here - I don't know if it's still a well-regarded finding, but it's a concept that stuck with me, and - ridiculously - I put GPS with "north is up" in order to get myself better at that kind of rotation. And thus, become "more manly" (snicker). 

2. To better reflect my philosophy of objective, shared reality over subjective truth. When I first got a GPS that rotated the view by default, I zoomed  way out, and realized how strange it was that, even though I'm on the east coast of the USA, the Atlantic was a big area on the LEFT of the screen, the opposite of what it is on a map. Regardless of what my friends think, I actually don't like the idea of the world rotating around me... the world - and by extension reality-  is what it is regardless of where I am at, and I kind of like my GPS to reflect that.

3. To better learn the lay of the land. I can't find the article, but a while back I read how there are two classes of tools - ones, such as training wheels or a temporary crutch, that build you up and let you perform better when you don't have them, vs ones you grow to depend on and so are made more helpless with their absence. An abacus is said to be in the first class - skilled users are greatly improved in visualizing mathematical operations even when without their preferred tool handy, while calculator users are more likely to be stuck. (I like that old gag, forget my Google search history, what would really be embarrassing is a usage history kept by a calculator app.) 

In fact that was a knock against the GPS, that would inhibit actually learning the geography. My response to that as an early adopter (In 2004 I got a Garmin StreetPilot 2610, $700 from walmart.com) was "I got news for you pal - I was bad at navigation even BEFORE I got the GPS, I was just more stressed about it"

But still I hope to reclaim some actual learning by keeping north as up, to continually work on building up my intrinsic feel for the way streets and neighborhoods are set out and are connected, to have to do a little mental work rather than being spoon fed with the map spun around me. 

(Melissa also hatest hates that I tend to mute the app so that the voice doesn't constantly interrupt my  music - especially when reciting long traffic sign-ish route identifiers for the second or third time. But that's a different story. I do wonder though, why Google Maps insists on breaking the silence when I cross a state border? Does it think I might be up to something nefarious and might need to know?)

javascript frameworks showdown

Pretty decent video building "TODO" in 10 different toolkits, starting with my favorite "vanilla" JS...

I thought he gave vanilla short shrift, really. For me it's a bit of a disservice to talk about the code alone, and ignore the fact you can just copy and work on code anywhere - and without pulling down 50Mb of random libraries "just in case". (I'm reminded of how BASIC was offered as an interpreted language on slow, slow early 8-bit computers - having absolutely minimal friction in the code/run loops is sometimes worth quite a bit) Also, using `` quotes to put HTML bits in works quite well as it does in some of the other frameworks.

Maybe I need to look into Svelte. I also liked Vue which I learned a bit to apply for some jobs last year. But mostly I need to give Preact a try.

Thursday, August 12, 2021

old dogs, new tricks: css grid for block schedules (vs absolute positioning and/or flexbox)

Usual disclaimer: In some ways I'm not a great tech blogger because my writing voice is more "well this is what worked for me" and sometimes even "except for this bit which I couldn't quite get where I wanted it." So definitely a bit of seeing how the sausages are made today.

Anyway. 2021's delayed Porchfest season (after 2020's year of cancellations) is approaching - albeit with a little more caution thanks to the Delta variant of COVID.

JP Porchfest, the site that got me starting all my endeavours on porchfest websites, is being run by a new group. One innovation they had (partially as a form of crowd control) is to have the event across both days of the weekend.

You never quite realize how assumptions baked into a system - e.g. "this event is just a one day stretch of time" - until they are challenged and you have to fiddle with code all over the place.

So I've had to scramble and update a lot of stuff. In some cases I've been able to fix some things that were bothering me. (I started doing these websites in 2014, with several generations of code, but sometimes 2014-era technique slips through and calls out to be replaced.) 

The block schedule has always been a challenging thing to make - in many ways having blocks hold positions on a page controlled by times and not their own natural flow goes against the way HTML does layout. Historically I  would do with a big heap of position: absolute divs. My first pass at updating the page to be two-day aware looked like this:


You can see the problem this approach always had, which is that with fixed height rows, performers with long names just didn't fit! Also my approach meant that porches were displayed even if there weren't any performances on that day. To fix both, I would have to go back and adjust the heights and positions of things manually (Earlier I worked up some nested DOM structures so I could read the computed heights) but since changes of heights in earlier rows effects positions of all lower rows... that is ugly capital Ugh!

(I think in previous years I also messed with techniques to experimentally shrink the font-size of any given entry so the name would fit in whatever box it was given... again, super hack-y even by my standards)

I had an idea to try to use flexbox but while that neatly solved the problem of having rows take up their natural height based on the content, I couldn't get the arbitrary positioning needed to represent a performances placement in time without manually setting each row item's height to the tallest object, thus somewhat defeating the purpose!

So my attention turned to css-grid, which is - kind of - a natural candidate for this sort of thing. I renewed my knowledge via CSS Grid Garden. It took a lot of work to rebuild the page, but my first pass at a usable result came out very promisingly:


Since different Porchfests have different run times I have to set up the grid dynamically, something like 

holder.style.gridTemplateColumns = `30px 200px repeat(${MINUTECOUNT}, 1fr)`;

Which holds space for the porchnumber, the porchname, and the breaks the rest up by however many minutes we have.

You can see it's a much more efficient use of space - especially since it's a lot easier to leave out porches that aren't hosting that day. I still don't have a perfect answer for performers like "DonYoyo" doing a 15 minute set. Also things got a little hacky as I put in the dotted line time bars showing each hour... but I can't let perfectionism stop me from getting the rest of the site done. I may swing back to figure out if I was doing something wrong or if there are just some quirks I have to live with (the "1/-1" for the rows of the separators just wasn't quite making them reach all the way to the bottom)

CSS Grid syntax feels very weird to me, like it's drawing from a print tradition or something... like how everything counts from 1 not 0, and you specify what column a thing stops short of at rather than the width or even which is the last column it occupies (so to take up the first 3 columns of 5 column layout it would be the shortcut "grid-column: 1/4", which is also weird because it looks like a fraction!)

Oh also, it's amazing how much more eloquent javascript is now that is ` ${variables} in template strings` and various map/filter/reduce functions, and fat-arrow functions. 

Thursday, August 5, 2021

p5 drawing clipping masks

I have an idea for an art project, roughly speaking using photos as wedges in a pie chart.

I knew you could make "masks" in p5 but wasn't sure if they had to be images... nope, stackoverflow says they can also be offscreen graphics. You make an offscreen image, draw the shape of the photo you want to see in black, and then apply it to your image object.

A slight gotcha - besides the slight oddness that the mask is applied to the image itself - is that the mask stretches to cover the whole image.

So this code:

let circleMask;
let myImage;

function setup() {
  createCanvas(526  ,688);
  circleMask = createGraphics(1000, 1000);
  myImage = loadImage('flamingo.jpg');
}

function draw() {
  background(100,0,0);
  circleMask.fill('rgba(0, 0, 0, 1)');
  circleMask.circle(500, 500, 500);
  myImage.mask(circleMask);
  image(myImage,0,0);
}

leads to 

i.e. even though the mask was made as a circle, when I applied it to the tall image, it got stretched into an oval.


Monday, August 2, 2021

ui gripe blog / hall of shame: Mass General Brigham Patient Surveys Online

 So my health care provider asked me to do a patient information survey, and offered this URL if I preferred to take it online:

https://massgeneralbrighampatientsurvey.intelliscaninc-surveys.com/english

That's quite a lot to type! Plus, if you eschew the https:// and make a typo in the first part of the URL - you get taken to a 404 page. But then correcting the typo in that ~30 character URL section doesn't fix anything, because you're stuck in "http" land, not https...

So

A. that is a horrible URL to expect a human to type

B. 404 pages should be smart enough to try to bounce people to https.