2021-05-14

Well aren't you just Mr. Subtle today?

I've been getting some unsolicited political texts recently. Here's a sampling:1

Trump won't ask again: Will you join him on his new social site. Friend? You have 1hr to stand w/ Trump until link closes for good [minified link redacted] stop=end
Have you abandoned Trump, Friend?! He launched his new site & you haven't told him you'll join. You have 1hr to stand w/ Trump [minified link redacted] stop=end
Trump won't ask again: Will you join him on his new social site, Susan? You have 1hr to stand w/ Trump until link closes for good [minified link redacted] stop=end
We've texted 9x & you still haven't answered Trump: WIll you join his new site, Susan? 20min or he'll know you've sided w/ Dems: [minified link redacted] stop=end
It's Steve Scalise & I'm wondering if we lost you, Susan. True Patriots will steps up. Socialists will ignore this. Which are you? [minified link redacted] stop=end

And so on. In case you're wondering, my name isn't Susan nor does that name belong to anyone I've shared a mobile plan or a mailing address with, so the contact database they are using is suspect.

The main thing that stands out to me here is the "subtle" menace in much of the phrasing here. Oh, it's ambiguous enough to provide cover against legal action—your basic plausible deniability—but it is also clear in the natural reading. The semantics here are those of bullies and crooks.


1 Before last year's election I was getting a bunch from pro-democratic sources. Those were run of the mill electioneering. The partisan selection and nature of this spam changed recently.

2021-05-10

Can't I just make a picture of this 3D model?

It sounds like a simple request: take this set of object models and make a set of pictures so we can vdiff them. No problem, right?

On one level that is right: there are a lot of tools out there than can draw you a picture of a 3D model.

But there are some unstated requirements:

  • These represent the same object at different points in the evolution of a physical effect, so we want to image them all from the same point using the same viewport and the same lighting. Maybe even generate a movie, but that's a bonus.
  • There are a lot of these objects because they are are generated by a scripted process, so we'd like to be able to initiate and control the rendering from the command line.
  • If our renderer uses a light model more sophisticated than pure ambient light (and it probably should, even if we don't need it to be particularly sophisticated), we want to control the lighting.
  • We'd actually like to add a simple legend to the scene, though this a "may" item that can be dispensed with.

And now the problem is actually pretty hard, and there are many fewer tools that offer the facilities we need.

Let's take a closer look at the requirements.

Scene description

The first thing to know is that a plain object model (in wavefront (.obj) or stl format) isn't enough to define a picture. What direction do you see it from? How much of the frame does it fill? Which way is "up" in the frame? How is it lit (and for that matter, how do we model lighting)? In what color? And so on ad nauseum.

So we need some kind of additional information. We call the combination of the object model(s) and all that ancillary information a "scene description", and it is written in a scene description language or format.

There are a lot of scene description languages out there (in many cases used by a single tool), though a small number are reasonable common. From today's web browing it looks like COLLADA, the RenderMan format (.rbi), and blender's proprietary and undocumented .blend files are the big players.

Command-line interface

This operation is part of a fairly complex workflow that I expect execute a few score to a few hundred times. It really should be scripted, but doesn't justify writing a custom tool unless I can just plumb together some existing bits. For that to be practical we need a renderer with a command-line interface (because this means that someone else has already done the bulk of the work).

In an ideal world I could write something like:

 renderer -i thingy_2.5s.obj \
        -c camera.txt -l lights.txt \
        --quality=3 --resolution=1920x1080

and get thingy_2.5s.png out. Then I could just loop over the available input files (re-using the scene description elements) and get my perfectly aligned set of images.

Where that leaves us

In a lot of ways the obvious choice is blender (not withstanding that this is a hugely heavy tool for the job), but it wants the scene description in an undocumented format which I can't generate outside of the program. Strike the obvious solution.

Now both COLLADA and RenderMan are documented, but as far as I've learned so far neither one is modular in the sense that I can define the camera and lights in a separate file from the 3D model and neither one lets me say "Use this wavefront file with rotation matrix M and translation T." in the singular file. In principle I could rework my code that is generating .obj files to produce .rbi instead but that would mean the producing code would need to know about my choice of camera and lights which is simply in the wrong domain for that code. Argh!

So, at least in my context, the answer to the title question seems to be "No, you can't.", which seems to be a bit of free real estate in the software utility market. Another task to add to my queue of projects that are not getting done due to the demands of my home life. Sigh.

Update 11-May: It turns out that RenderMan format does support separate inclusion in the form a "Entity files" and a ##Include directive. This represents a path forward, though it means supporting mesh output in a new format.

Update 14-May: The specification says:

Note that the Include keyword itself does not cause the inclusion of the specified file. Aswith all structural hints, theIncludekeyword serves only as a special hint for rendermanagement systems. As such, the Include keyword should only be used if render management facilities are known to exist.

Though it appears that I can provide the adequate level of "render management facilities" with a simple tool that identifies the keyword. Better still the renderer I'm looking at (aqsis) is willing to accept the standard input so it becomes possible to write something like includer lights_and_camers.rib | aqsis .

2021-05-02

Yep. Naming things is hard.

There are only two hard problems in computer science: cache invalidation and naming things.
Phil Karlton1

So I've been reaing Uncle Bob's Clean Architecture as part of my continuing education. I'm in the bit where he's talking about SOLID in gneral and trying to explain the Single Responsibility Principle in particular. Uncle Bob admits that it isn't well named. Nice mea culpa. Still, it's not too bad a job. Especially if you compare it to the naming of the principle widely know as RAII.

Anyway, moving on to defining this thing Uncle Bob gives the original statement of the principle as:

A module should have one, and only one, reason to change.

Which he immediately admits isn't particularly clear, so he then suggests the intermeidate form:

A module should be responsible to one, and only one, user or stackholder.

This is also less than perfect as there will often be a group of related users or stackholder who hold the module's specification collectively. To remedy that Uncle Bob tries:

A module should be responsible to one, and only one, actor.

Which is more pithy. Alas he needed a separate sentence to nail down the meaning of "actor" in this context.

It seems to me that "faction" might be a better word here. Admittedly there is a contation of conflict or at least competition that comes with that choice. But, honestly, the different groups of stackholders who rely on a medium to large scale software project are in competition for programmer hours if nothing else and they often have to hash out conflicting interests in specifications as well.


1 Yes, I'm a big fan of the variation that includes off-by-one errors in the list of two things. But the original is insightful enough that Phil deserves plenty of recognition and it is hard to find a authoritative origin for the expanded version.

2021-04-26

But what are the opinons?

I'm about to experiment with a piece of software (the meson build system). Now, I've read this and that and I've watched a couple of video presentation by the author who acknowledges that the software is opinonated and gives a reasonably convincing argument for why that is a good (or at least appropriate) thing for a build system.

Fine. I'll buy it for the interim. But .. what are the opinons? What rules does the tool enforce that I might not be used to from other tools in the same space? Is there a list? If so I can't find it. I'm not asking because I want to use them as a reason to reject this thing, I've commited myself in my own mind to trying it. But I'd like to get into the required mindset. Only there doesn't seem to be a single place to look.

2021-03-15

Bad webmonkey, no Mt. Dew!

Given the possibility that the title could be taken as a pejorative, I should get a few things out of the way:

  • Web programming can be "real" programming. It is a cross-disciplinary task and there are so many subtleties and complexities that web programmers ought to be taken seriously.
  • Web programmers don't have the luxury of having most of their mistakes take place off camera the way some of us do.
  • In addition to the complexities of the programming environment they get to deal with UI (or UE, if you prefer) all the time. Poor things.

But ... those same bullet points explain why they get bagged on: their mistakes are highly visible, annoying, and they generally turn out to be something that some segment of the users consider to be "obvious". As in "How could anyone with half-a-brain not know that?!?" kind of obvious to some part of their audience. And they don't generally hear from the cohort who shares their ignorance.

The answer to that exasperated query is that it takes time, effort, and experience to become good at cross-disciplinary stuff. You need to know a few things in great depth, a larger number of things to moderate depth, and a little bit about a huge number of things. That takes time.

Now, twenty years ago web programming had a reputation for low barrier to entry. Is that still true? I don't hang around the right places to know what people say about it these days. But combining low barriers to entry with pretty high requirements for preparation is a recipe for disaster.

So, "What brought this on?" I hear you saying.

Well, not really because you're on the other side of the internet from me, I haven't hacked your microphone, and it's not clear that anyone actually reads this thing with any regularity. But I have a good imagination, so I hear you saying it anyway.

Setting my security questions and responses for a web site. Unfortunately,

  • The street I lived on when I was ten years old had a two word name (not counting "Road": its name was a phrase), which the person who programmed the form apparently thinks is a thing that doesn't happen.
  • I got my first job in a city in the US southwest named after a saint. In Spanish. So it, too, is two words. Again, the programmer apparently doesn't believe in such nonsense.

Now, young programmers in my end of the business are pointed at a few documents early on to give them a starting familiarity with some of the more trap-laden parts of our work. Things like What Every Programmer Should Know About Floating-Point Arithmetic and What Every Programmer Should Know About Memory (PDF link) . I would have thought that Falsehoods Programmers Believe About Names and Falsehoods Programmers Believe About Addresses would be reasonably obvious candidates for the same role among web programmers. In fact these kinds of document make up a little genre of their own, and it's one worth taking a little time to explore. I promise you'll find one or two that you're guilty of.

Rather than hurling imprecations at web programmers in general, or even at the miscreant in this particular episode I'll just ask anyone going into web programming to find some resources for how to think about these things. Please.

2021-03-12

More on bureaucratic language

My wife and I got the Janssen (AKA Johnson&Johnson) vacinne today. No significant side effects at this point.

But I want to talk about the paperwork. The fact-sheet that I was required to acknowledge receipt of included language like

There is no U.S. Food and Drug Administration (FDA) approved vaccine to prevent COVID-19.
The Janssen COVID-19 Vaccine is an unapproved vaccine that may prevent COVID-19.

And several more variations on the same theme.

Now, on one hand the point is clear: the FDA has not completed its (lengthy) approval process and has just given permission to use these things because the pandemic represents an emergency situation.

But on the other hand the expectation is that hundreds of millions of Americans (not to mention billions of people in other parts of the world) will receive one or the other of these vaccines. So what is the difference between the current situation and approval? Nothing outside the structure of the bureaucracy's regulatory structure.

Not that I think there is anything malicious or even dishonest about this business. It's just that organizations create their own cognitive structure and then live in them even when they lose fidelity with the real world. In other cases that can be a problem.

2021-02-23

TDD practice project

Among the programming videos I've watched in the last few months there was a entire multi-day workshop given by Robert "Uncle Bob" Martin. He's an entertaining speaker. Of course, most of the presentation covered the topics he's been writing about for the last couple of decades, but the part that really caught my attention was his demonstration of the coding process for test-driven design.1 I'd like to take the idea for a test drive.

Now, I've been conscientiously adding testing to my personal process for years, and I've long included bug-report-as-test in my toolbox but I've never used the "write a failing test first" scheme that Uncle Bob demonstrated. I completely buy his claims that (a) you have to practice to learn how to do it and (b) you can't learn it on the job. I need an exercise.

Probably there are sample problems out there, but I've thought of one of my own: I'm going to write a bracket nesting validator. Moreover, I'm going to do it in stages as if I were refining an agile project. In all cases the program will accept a arbitrary number of files to process.2 The stages I intend are:3

  1. Work on a fixed set of bracket pairs ((), [], and {}) and reports the filename of each file that has an error. The program will be silent by default on correct files. A report-on-correct switch is optional.
  2. Expand the error report to include the line and column number at which the error was detected.
  3. Expand the error report to include the class of error (close doesn't match open, close with no open, reach end-of-file with one or more open brackets). Bad match reports should also include the line and column number of the non-matching open bracket; end-of-file reports should include the line and column numbers of the unmatched open bracket.
  4. Allow the user to specify arbitrary character pairs to be treated as open/close pairs (including canceling or overriding the default pairs). Attempting to specify a single character more than once represents a error and suitable diagnostic must be produced.
  5. Allow a single character (such as ' or ") to server as both open and close for a pair; note that these pairs can not nest without an intervening scope. That is 'a'b'c' has two single levels pairs not one pair inside another, but 'a"b'c'd"e' is three levels deep.

I haven't even set up a repository yet and I'm already struggling with the conflict between by habitual way of working and the Process-with-a-capital-P I'm suppose to be exploring. On the white-board in my home office is a sketched out scheme for five data structure that will collectively support at least version (4) of the spec which I started drawing automatically almost as soon as the idea occured to me. But I think I'm suppose to let most of that "just happen", aren't I?

Argh! This is going to be, uhm...fun?


1 I've also adopted his "Yeah! I'm a programer!" bit as pick-me-up for those days when even the little victories seem few and far between.

2 I'm intending to do a command-line tool, but there is nothing in here that requires it. Feel free to get that list of files from a file-picker widget and report in GUI list of some kind.

3 The professor in me feels obliged to note that there are even more basic versions of this exercise available. Notably:

  1. Perform the matching on exactly one kind of pair. This can be done without a stack.
  2. Just count that the number of open characters equals the number of close characters without caring about order.

However, I'm not going to bother with these variants unless the "do as little as you can" process happens to pass through one of them along the way.