You've probably heard (if you’re a programmer) about the cardboard programmer or rubber duck debugging.

These days, my rubber duck is the Ask a Question form at Stack Overflow (or another Stack Exchange Network site appropriate for the topic at hand). Writing a clear and considered question serves the same purpose as the hypothetical cardboard cutout or coworker — and if you don’t find your solution by the rubber duck method, then you have the question all ready to go, so no effort is wasted.

I haven’t gotten around to talking about it before, but I’m a big fan of Stack Exchange — it's a great place to get answers and give them, and focused on being a good resource in the long term and for all the web, not just another forum for discussions.

[profile for Kevin Reid on Stack Exchange]

Today I learned that there is a standard-DOM alternative to the convenient IEism element.innerText (a close relative of element.innerHTML): element.textContent.

It is slightly different, according to MDN: .innerText returns the visible text (omitting scripts and CSS-hidden text), whereas .textContent returns everything, more like walking the document tree.

(This information crossed my awareness while working on Caja, but I didn't recognize it as something I could actually make use of until now.)

(no subject)

Friday, August 5th, 2011 22:29

Never need to run a text editor as root: use sudo -e.

I've found a useful configuration option for if you're using Ubuntu on a Windows-layout keyboard and you're used to Apple's keyboards and ⌘ (Command)-shortcuts:

System → Preferences → Keyboard → Layouts → Options… → Alt/Win key behavior → Control is mapped to Alt keys, Alt is mapped to Win keys

With this option enabled, the Alt keys (in the Mac ⌘ position on the keyboard) function as Control keys, and the Windows keys (in the Mac Alt/Option position) function as Alt.

Having just discovered this, I find it quite handy for the years of muscle memory of ⌘W and other such shortcuts. (No, I haven't switched to Ubuntu; I just frequently find myself using it for software compatibility testing and so on.)

The problem of arranging a set of unbreakable text blocks in columns in an arbitrary order such that the columns are of approximately equal height is equivalent to the NP-complete “multiprocessor scheduling” problem, and the “LPT algorithm” described in the linked article performed excellently for my instance of the problem (4 columns, 6 blocks), which is actually my packing list for traveling to California tomorrow.

(I have a program which generates my packing list for me, based on type, duration, season, and transportation. It encodes all the accumulated knowledge about what to pack and where to pack it; after a trip I review my changes written on the printed list and incorporate them into the program.)

(no subject)

Wednesday, February 9th, 2011 09:49

Do not sort the category “Other” under “O”.

It is an often-used fact (in examples of elementary trigonometry and problems that involve it) that the sines of certain simple angles have simple expressions themselves. Specifically,

sin(0)=0
sin(π/6)=sin(30°)=1/2
sin(π/4)=sin(45°)=√(2)/2
sin(π/3)=sin(60°)=√(3)/2
sin(π/2)=sin(90°)=1

Furthermore, these statements about angles in the first quadrant can be reflected to handle similar common angles in the other three quadrants, and cosines. There is a common diagram illustrating this, considering sine and cosine as the coordinates of points on the unit circle.

When attempting to memorize these facts as one is expected to, I observed a pattern: each of the values may be expressed in the form √(x)/2.

sin(0)=√(0)/2
sin(π/6)=sin(30°)=√(1)/2
sin(π/4)=sin(45°)=√(2)/2
sin(π/3)=sin(60°)=√(3)/2
sin(π/2)=sin(90°)=√(4)/2

I found this pattern to be quite useful. It does not, however, explain why those particular angles (quarters, sixths, eighths, and twelfths — but not tenths! — of circles) form this pattern of sines.

(I'm posting this because I have the feeling it is not as well known as it should be.)

If you're compiling a C program with GCC, unless you have a reason to do otherwise (such as compatibility with other compilers), use -std=c99 instead of -ansi. -ansi specifically chooses the older C90 standard.

Why should you use C99? I'm not one to give you a complete list of changes (this article seems to be decent for that), but my favorite features are:

  • Boolean and complex number types
  • Variable declarations may be freely intermixed with statements, and used in the first expression of a for loop
  • // line comments
  • Variable-length arrays
  • Inline structure initializers: foo((struct bar){...});
  • Using field names or array indexes in structure initializers: struct bar g = { .x = 0, .y = 9.81 };

Note that many of these are common extensions to C (which would be rejected by -ansi -pedantic, I believe), but C99 makes them standard. C99 also removes some archaic features/looseness so as to make it harder to accidentally write incorrect programs.

Everything I’ve read says that the USB tethering facility of Android phones doesn’t work with Macs without installing additional software and possibly going through various moderately elaborate procedures. Imagine my surprise when I accidentally turned it on and it worked perfectly.

It appears that this is an unadvertised feature of Missing Sync for Android, which does use the phone’s tethering function as part of their recently added sync-over-USB feature. Specific evidence: (1) The phone does not appear as a network interface on another Mac with the same OS version. (2) When I unplug the phone or disable tethering, the network interface changes its name momentarily from "USB Ethernet (en3)" to "MissingSync" before disappearing.

I’m using Android 2.2.1 (FRG83D) on a Nexus One, Mac OS X 10.5.6, and Missing Sync 1.5.1 (phone)/1.5.0 (desktop).

I reiterate that this is not documented anywhere I have found, and especially not on Mark/Space, Inc.’s web site.

YRFOTD #2

Monday, December 6th, 2010 07:59

10,000 minutes ≈ 1 week

Unix tip

Monday, October 4th, 2010 17:47

The following command is not idempotent:

cat * > cat.txt

Got a nice fluid layout on your web site? Annoyed at how mobile browsers like to assume pages need nine hundred virtual horizontal pixels to display properly? Add this to your <head>, as I've just done across my site:

<meta name="viewport" content="width=device-width">

This tells iPhone and Android browsers, at least, to present the page with a virtual window width equal to the device's actual screen width. It was invented and specified by Apple.

(I am not taking up the question of whether these browsers are making the right default choice. I will say, however, that in my technical opinion this is the wrong choice of location for this parameter: whether a layout will work at narrow widths depends largely on the stylesheet, not on the HTML; this parameter therefore ought to be stored in the stylesheet (that is, be a CSS extension); insofar as it does depend on the HTML, you can then put it in a <style> element.)

If you're looking to use media types to provide different styles: These browsers also don't respect the “handheld” media type; but they do support draft CSS3 Media Queries, which allow you to condition on the actual screen width — if you want, even in ems! I've used this on the main switchb.org page to make the Big Text less likely to spill off the screen (could use some further testing; all I've used so far is my desktop and a Nexus One), and also in the Caja Corkboard demo (which I wrote this summer (among other things) and ought to blog about).

A data: URL directly contains its content; for example, data:text/plain,Hello%20World!. The main usefulness of this is that you can do things like including images inline in a document. But you can also use it to create 'anonymous' HTML documents, where any link to them or bookmark contains the entire document.

I originally did this in 2006 when I was in need of a URL-encoding tool and did not have one to hand; so I wrote out:

data:text/html,<form action="data:text/plain,"><input id=r>

Properly encoded, that's:

data:text/html,%3Cform%20action=%22data:text/plain,%22%3E%3Cinput%20name=r%3E

This produces a form with a single field which, when submitted, will generate a data URL for a plain text document containing “?r=” and then the text; the URL, then, will contain the entered text URL-encoded after the “?r=”.

Of course, that's a horrible kludge and JavaScript has an encodeURI function...

See my site for the rest of that thought and more examples. (I can't include any actual data URLs in this post because LiveJournal doesn't permit them, for necessary but unfortunate reasons — the origin, in the sense of same-origin policy, of a data URL is the origin of the page containing it.)

The Mac System Profiler app, in the “USB” section, will display a tree of all USB devices, including hubs, and what they claim to be. This can be useful when you're trying to find where the problem is when your system isn't seeing a device at all.

(You may also be surprised at the number of USB buses (a.k.a. root hubs, I think) and built-in USB devices your system has.)

Yesterday I tried the Android Bluetooth keyboard driver “BlueKeyboard JP” (Market link) again, and got it to work with my Palm Bluetooth Keyboard. The catch is/was that it will only connect to the keyboard if it's discoverable, not if the keyboard is just trying to connect. Once connected, though, it works fine for all ASCII input, though the Shift key acts sticky if not pressed in combination with another key.

Special functions: The arrow keys and Enter act like the phone trackball, throughout the phone (not just in text fields) (update: but not in the menu-button menu!). The keyboard's marked [Fn][`] = [Esc] works as Back and the [Cmd] key works as Menu; I haven't found any other hard-button shortcuts (home/search/camera/volume etc). (The driver's web page is all in Japanese, and I haven't found an English manual, though the settings screen on the phone has English.)

Update 2010-08-27:

Unsurprisingly from the name, this driver is also a Japanese input method; after several times accidentally shifting into Japanese mode I have determined that the toggle for this is [Shift][Space].

[Fn]<number> combinations (which are probably this keyboard's emulation of hard F-keys) have the following functions. No other [Fn] combination that I tried, including other numbers, produced noticeable results, but I may not have been in the right context to see an effect.

[Fn][7] Music: Previous track
[Fn][8] Music: Play/pause
[Fn][9] Music: Next track
[Fn][_-] Volume down
[Fn][=+] Volume up

Things that don't work: The Caps Lock key (but the Shift key acts as does the Android soft keyboard's shift (pressing twice locks)). The forward delete (Del) key. Unsurprisingly, the keyboard's onscreen battery level indicator shortcut — it types garbage — but the keyboard does have a hardware low-battery light.

(End update)

When in use, there is an AdMob ad bar at the bottom of the screen (where a soft keyboard would be). There is a paid version on the Market, but one reviewer said that it just displays the company's own ads instead — which seems odd.

I'm tempted to look into writing a keyboard driver myself, for the sake of having proper reconnection behavior and non-ASCII characters, but for now this seems good enough and there are other things to worry about (e.g. notepad software; Fliq Notes syncs with my existing desktop notes but lacks some features compared to the PalmOS app).

$ cat ~/bin/maken
#!/bin/sh
# Make files and view the results.
make "$@" && open "$@"

UPDATE: Turns out I posted this previously, with further thoughts: Avoiding repeating myself (on the command line).

I've several times seen the complaint that URL shortening services (tinyurl.com, bit.ly, etc etc) eliminate the ability to see where you're going by viewing the “real” URL and that this is dangerous.

In my opinion, if it is unsafe (except in the “seeing something you'd rather not” sense) to not know what the destination site is, then there's something wrong with the system. After all, you visit unknown sites all the time whenever you're learning about some new-to-you topic; it shouldn't be necessary to trust them.

The info visible from the URL is useful as a time-saving hint — “oh, that info is being presented as a video on YouTube — I don't have time to watch that now” or “I've seen that already” or “that site requires an account to do anything useful with”, but if it's neccessary to check it, then something needs fixing. I'm not saying you need fixing — it might be “the design/defaults of current web browsers” (e.g. that any web page is permitted to play sound by default) or “such-and-such protocol or plugin” — but something needs fixing.

That said, I don't actually approve of URL shorteners — because they do remove that helpful hint, and they create opportunities for links to break in the future.

One bit of advice sometimes given to the novice programmer is don't ever compare floating-point numbers for equality, the reason being that floating-point calculations are inexact, and one should use a small epsilon, allowable error, instead, e.g. if (abs(value - 1.0) < 0.0001).

This advice is actually wrong, or rather, overly strong. There is a situation in which it is 100% valid to compare floats, and that is an cache or anything else which is comparing a float with, not a specific constant (in which case the epsilon notion is appropriate), but rather a previous value from the same source; floating-point numbers may be approximations of exact arithmetic, but that doesn't mean you won't get the same result from the same inputs.

So, don't get any bright ideas about outlawing aFloat == anotherFloat.

Unfortunately, there's a case in which the common equality on floats isn't what you want for previous-value comparison anyway: for most definitions of ==, NaN ≠≠ NaN. This definition makes sense for numerics (and is conformant to IEEE floating point specifications), because NaN is “not a number”; it's an error marker, provided as an alternative to exceptions (or rather, floating point error signals/traps/whateveryoucallit) which propagates to the end of your calculation rather than aborting it and requiring immediate error handling, which can be advantageous in both code simplicity and efficiency. So if you think about calculating within the space of “numbers”, then NaN is outside of that. But if you're working in the space of “results of calculations”, then you probably want to see NaN == NaN, but that may not be what you get.

Mathematically, the floating-point comparison is not an equivalence relation, because it is not reflexive on NaN.

(It's also typically the case that 0 == -0, even though positive and negative zero are distinct values. Oh, and NaNs carry data, but I'm not talking about that.)

What to do about it, in a few languages:

JavaScript

Even the === operator does not compare identities rather than numeric values, so if you want to compare NaN you have to do it as a special case. Google Caja handles it this way:

/**
 * Are x and y not observably distinguishable?
 */
function identical(x, y) {
  if (x === y) {
    // 0 === -0, but they are not identical
    return x !== 0 || 1/x === 1/y;
  } else {
    // NaN !== NaN, but they are identical.
    // NaNs are the only non-reflexive value, i.e., if x !== x,
    // then x is a NaN.
    return x !== x && y !== y;
  }
}
Common Lisp

The = operator generally follows the IEEE comparison (if the implementation has NaN at all) and the eql operator does the identical-object comparison.

E

The == operator is guaranteed to be reflexive, and return false for distinguishable objects, so it is appropriate for the “cache-like” use cases, and the <=> operator does conventional !(NaN <=> NaN), 0.0 <=> -0.0 floating-point comparison.

(no subject)

Sunday, March 14th, 2010 14:28

Extended subset” makes perfect sense as long as you don’t think about it with set theory.

This, for example, is a link: Kevin Reid

This is not a link, but a URL: http://switchb.org/kpreid/