MacBook, defective by design banner

Put the knife down and take a green herb, dude.

One feller's views on the state of everyday computer science & its application (and now, OTHER STUFF) who isn't rich enough to shell out for

FOR ENTERTAINMENT PURPOSES ONLY!!! Back-up your data and always wear white.
URLs I want to remember:
* Atari 2600 programming on your Mac
* joel on software (tip pt)
* Professional links: resume, github, paltry StackOverflow * Regular Expression Introduction (copy)
* The hex editor whose name I forget
* JSONLint to pretty-ify JSON
* Using CommonDialog in VB 6 * Free zip utils
* that hardware vendor review site I forget about is here * Javascript 1.5 ref
* Read the bits about the zone * Find column in sql server db by name
* Giant ASCII Textifier in Stick Figures (in Ivrit) * Quick intro to Javascript
* Don't [over-]sweat "micro-optimization" * Parsing str's in VB6
* .ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); (src) * Break on a Lenovo T430: Fn+Alt+B
email if ya gotta, RSS if ya wanna RSS, ยข if you're keypadless
Tuesday, November 24, 2015

You can find 'em here:

Or read 'em from that page here:

type char(2)
Object type:
AF = Aggregate function (CLR)
C = CHECK constraint
D = DEFAULT (constraint or stand-alone)
F = FOREIGN KEY constraint
FN = SQL scalar function
FS = Assembly (CLR) scalar-function
FT = Assembly (CLR) table-valued function
IF = SQL inline table-valued function
IT = Internal table
P = SQL Stored Procedure
PC = Assembly (CLR) stored-procedure
PG = Plan guide
PK = PRIMARY KEY constraint
R = Rule (old-style, stand-alone)
RF = Replication-filter-procedure
S = System base table
SN = Synonym
SO = Sequence object

Applies to: SQL Server 2012 through SQL Server 2016.
SQ = Service queue
TA = Assembly (CLR) DML trigger
TF = SQL table-valued-function
TR = SQL DML trigger
TT = Table type
U = Table (user-defined)
UQ = UNIQUE constraint
V = View
X = Extended stored procedure

So to check if a table exists (from here):


Voila. QED. Or something like that.

And just to complete what I was fiddling with today, here's how to create the two different types of ids, autoincrementing INT (or other INT type) and GUIDs:

TableId [uniqueidentifier] CONSTRAINT DF_SerialID DEFAULT newsequentialid(), -- GUID, natch
... or...
TableId INT IDENTITY(1,1), -- INTige

Labels: , , ,

posted by ruffin at 11/24/2015 09:03:00 AM
Monday, November 23, 2015

Why should you use DateTimeUTC and not DateTime in your SaaS systems? 4guysFromRolla actually has a pretty good answer from 2007:

The primary advantage of storing date/time values in UTC is that it makes the data transportable. To see what I mean, imagine that following scenario: you have an eCommerce website that is being hosted in a web server located in the Pacific time zone (UTC -8) and this application stores the date and time orders were placed in server time. Say a user, Bob, makes an order on August 1, 2007 at 9:00 AM UTC -8. After many months of phenomenal growth, you decide to switch to a larger web hosting company, one on the east coast where the time zone is UTC -5. Since the date/time is stored in server time, Bob's previous order still shows that it was made on August 1 2007 at 9:00 AM. But since we are now in UTC -5, it is as if Bob's order was made three hours earlier than it really was (since when it was 9:00 AM on August 1, 2007 in the west coast it was really 12:00 noon on the east coast).

One way around this, you might contend, is to execute a SQL query that adds three hours to the order date for all records in the table. Something like:


OrderDate = DATEADD(hh, 3, OrderDate)

And such an approach would suffice... for this situation. But imagine that you moved to a web hosting company situated in the US state of Arizona, where daylight savings is not observed. E[s]p. Now you would have to write a more complex UPDATE statement that adjusted the hours based on whether the order date fell within daylight savings. Ick.


Things like daylight savings further complicate working with dates and times, but UTC does not observe any time zone, simplifying things a tiny bit. [emph mine -mfn]

To make a long story short, you have two choices:

  • Use DataTimeUTC and use built-in converters to get "local" time, usually on the client
  • Pick another "native" time zone for your system, and prepare to maintain your own converters

Seems an easy enough choice to me.

Labels: , , ,

posted by ruffin at 11/23/2015 02:43:00 PM
Saturday, November 21, 2015

I'd like to pretend that online gambling sites aren't a big deal, but I'm having a more difficult time believing that now. The way FanDuel and DraftKings took over every advertising spot on ESPN and NFL games really woke me up a little. There has to be insane amounts of cash going in. What did they recently brag they were paying out each week? Seventy-five million? Wonder what percent they don't pay out?

But gambling is gambling. Or playing games of *cough* skill (Are carnival games games of skill? Aren't they? The basketball hoop is just smaller right? If you're winning thrice the time if you're Mark Price, then it's skill, even if that's just 2%, right?) for money is playing for money. Either way, it's not something I'm interested in or really care much about. If you're not risk adverse enough to skip these games, well, you get what's coming, I guess. I mean, you can get in worse trouble selling stocks short, right? Isn't that just as much skill and luck? If you can do one, why not the other?

But then you see a story like this one from CBS News, and I, at least, started doing more thinking. PayPal handles those payments, and gets a taste. Yahoo apparently is invested in similar services. And then, the real kicker is the disclosure at the bottom of the page:

Editor's Note: CBS has an investment in FanDuel of less than 1 percent of that company's value.

Add to that Robert Kraft, and NFL Team Owner, and Fox Sports, an NFL broadcaster, both own parts of these companies, and you've got a real conflict.

Ouch. Big Business is still Big Business, no matter how little you want to pretend it affects you. Look at the people who not only have dogs in this fight, but who do get juice from its winnings:
  • The owners of the teams who are being bet (or whose players performances determine who wins a game, whichever way you look at it)
  • The teams' broadcasters (Fox) 
    • I'd add ESPN to this. So many ads, even native reads on Mike & Mike, who wouldn't stop saying that these things were games of skill, and how much they enjoyed playing. If I have to hear one more stupid comparison to state lotteries or poker games... I'd like to hear how often the hosts played & what they won/lost.
  • The news outlets that both broadcast and report on them (Yahoo and CBS)
  • The banks that provide payment to them (PayPal)
Two of these -- banks and journalists -- I don't want getting anywhere near these "games of chancy skill". And don't discount Fox Sports and ESPN as journalists. They provide entertainment first, sure, but you don't have to be Bill Simmons to wonder when their advertisers become their true customers, to the detriment of their producing hard-hitting pieces for their viewers, and anyone counting on their role as press to perform the last check and balance on corruption in sports.

Not that gambling could corrupt sports, could it?

If we keep mixing dollars between banks, journalism, and sports, sports betting could make Glass-Stegall's repeal look like a walk in the park.

Labels: ,

posted by ruffin at 11/21/2015 10:53:00 PM
Friday, November 20, 2015

I'll try not to get too verklempt, but I finally hit my informal goal for StackOverflow: I received the [second] JSLint badge [SO's awarded].

It used to be difficult to program without googling answers to what were sometimes painfully easy questions -- it was just more efficient that coding "from scratch". Now, it's even more difficult to code without leaning heavily on StackOverflow.

It's also hard to get that much value without giving something back. Admittedly, I'm nowhere near as "giving" as one of my old coworkers, who is creeping up on 80,000 StackOverflow points as I blog. But you can't use it without finding some means of giving back.

For me, it was sitting on the JSLint tag. We started using JSLint at a company I worked with a while back, and I think I was one of our better JavaScript guys (Whitaker, above, was pretty busy), so I got stuck with implementing JSLint as a company-wide blocking check-in test. I first got a Visual Studio JSLint extension working and configured like we wanted it, then I copied what it was doing and wrote a TFS rule using Noesis, the same engine that plugin used, to test files folks were checking in, slowly forcing us to JSLint our legacy code (though with exceptions for third-party libraries) as we edited files.

Looking back, I should've used Node, which would have been much easier, but Noesis didn't require any serious installation.

Anyhow, when you're the contact person for something like this, of course you also end up being the person who actually does much of the linting, as almost every time someone edited a file over a hundred or so lines, I'd get an email about how difficult and unfair the new policy [that, I might add, I'd been tasked in implementing, though I do believe it was a very good idea] was. It was easier to spend the time linting than arguing, though I feel badly I gave fish rather than taught folks how to get 'em themselves. Admittedly, some of those files were a mess.

So like Jim Morris pitching, I got decent at understanding JSLint. More importantly, that was a manageable tag on StackOverflow. I'd learned it was easy to get reputation just by sitting on topics and being the first to answer, but that wasn't always the best way to learn, and seemed to be more gamification than "scholarship". It's the difference between sitting on jQuery and wishing you could sit on child jQuery selectors or DOM concatenation. But JSLint had that specificity. A small pond, but active enough that you could actually contribute.

Overly long story a little shorter, here we are. I'm the second person in StackOverflow history!!!1!1!!2 to bag the JSLint badge. And boy, I did it the hard way (which is not a complement to me). The first guy to get it, James Allardice (who also has the JSHint badge) currently has 202 points answering 32 questions. I've got 101 for answering 57. I'd like to think James plowed up the ground pretty well with the obvious answers (I've gotten 24 of my points for being the first to document `ignore`, for instance), but still.

There are at least 20 people with more JSLint points than me, but since only one has 20 or more answers in there, I still get to be second. (TJ Crowder will be there soon, I think, but other than Quentin at 13, nobody else has 10 answers.) I also like that with th eexception of the last two guys on the list, who essentially have the same rep as me, everyone else has 3k or more than me, many with tens of thousands more. It's good company.

Looks like my first JSLint answer was on 5 Feb 2013 (with my first question on 1 May 2012), when nobody had earned this tag yet. Just a little over two years since Allardice bagged the tag, and just over 33 months since I started, I get the second.

Nobody remembers the second schmoe on the moon, but that doesn't mean it wasn't enjoyable.

Guess I'll keep watching JSLint, but (and I'd already kinda started relaxing) I'll be a little less likely to want to be FIRST! and more likely to just chime in when I have something good to add. Which is how StackOverflow should work.

Labels: , , , ,

posted by ruffin at 11/20/2015 01:44:00 PM
Friday, November 13, 2015

Sorry, this one cracked me up. Apparently, somewhere, some way, I've told iTunes not to go online to get CD track names, perhaps. When I tell it, "No, really, go get some track names," instead of a useful, but already insanely stodgy, "Allow iTunes a single-use exception to transmit information about the tracks from your CD to the Internet," I get ye old "No Error" error.

Again, Apple's not impressing with its test case creativity. QA fail.

So, of course, I attached my external DVD drive to my iMac and imported there, no problems. What a mess iTunes has become.

Labels: , , , ,

posted by ruffin at 11/13/2015 09:35:00 PM
Wednesday, November 04, 2015

From here:

SOLUTION: in Windows 7 [and 8, as it turns out -mfn], press and hold Shift and right click on the grouped icon that you want to open all of it's grouped windows in a cascade arrangement, then click on Cascade . All the windows of this particular program will open in cascade exactly as in XP.

Wow. Yes please. I used to use the right-click shortcut to cascade all the windows, but didn't realize you could do it one application at a time, I don't think. I often leave open too many browser windows, and it's nice to bring them all to the front where they're easily eyeballed before shutting them out.

Labels: ,

posted by ruffin at 11/04/2015 10:46:00 AM
Tuesday, November 03, 2015

    document.createElement("test1"), document.body.childNodes[0]

That could've been easier. I think. Bottom line is that you're taking the parent node, and inserting a new node (first parameter) before the existing (second param). Here, of course, I'm doing it to the body. Sub document.body with the node o' your choice.

EDIT: So here's a slightly nicer way of inserting html, since the above won't actually parse HTML in the string...

function insertAsFirstChild(strHtml, nodeWithChildren)    {
    // If strHtml isn't wrapped in tags, we probably want to put into
    // a span so that we can accept html. CreateTextElement would push
    // out the text as is, showing markup in the page.
    var newSpan, strTag, strEndTag;

    newSpan = document.createElement("span");
    if (!nodeWithChildren)  {
        nodeWithChildren = document.body;

    if (
        0 === strHtml.indexOf("<")
        && strHtml.length - 1 === strHtml.lastIndexOf(">")
        && strHtml.indexOf("</" > -1)
    ) {
        strTag = strHtml.substring(1, strHtml.indexOf(">"));
        strEndTag = strHtml.slice(strHtml.lastIndexOf("</")+2, -1);

        if (strTag && strTag === strEndTag)   {
            newSpan = document.createElement(strTag);
            strHtml = strHtml.substring(strHtml.indexOf(">")+1, strHtml.lastIndexOf("</"));

    newSpan.innerHTML = strHtml;
    nodeWithChildren.insertBefore(newSpan, nodeWithChildren.childNodes[0]);

Labels: ,

posted by ruffin at 11/03/2015 10:46:00 AM

Support freedom
All posts can be accessed here:

Just the last year o' posts:

Powered by Blogger Curmudgeon Gamer badge