dtm: (lizard)
In my previous post, I said I was working on a version of my old killfile script as a chrome extension.

Well, that's now happened! And I have it as both a firefox and a chrome extension. (Same source, mostly.) I still need to go through and clean out the list of supported sites, but note that in addition to the sites it supports directly, it also supports any site that uses disqus through an iframe. (Like rawstory.com, wired.com, and many, many others; sadly, Shakesville uses disqus in a different manner that I can't handle yet)

  1. Killfile for chrome

  2. Killfile for firefox

The chrome extension can also be found by going to the chrome webstore and searching for it; the firefox addon can't be found by going to the main page and searching because firefox has a review process for addons that's really slow. It might be reviewed by Christmas.

On chrome, your killfile list is shared across all your devices if you sign into chrome and do the chrome sync thing. On firefox, it's strictly local.

The full source is on github.
dtm: (Default)
Hey, you, are you making a website that accepts credit card numbers? Or phone numbers, or any kind of long number or code that your annoying users want to enter with spaces and dashes? Are you about to add a message that says something like "no spaces or hyphens"? STOP. Just stop, right now. If you've already done that, go and fix it. NOW

There is no excuse for doing that. If you find yourself in the position of writing code to pull some data out of a web form and can't at the same time strip the spaces and hyphens your users put in there so that they'd type the stupid sixteen digits correctly, then you need to find another line of work. Or at least ask on stackoverflow.com if your framework makes massaging input like that stupidly difficult.

Are you a website owner who pays people to make forms that take credit card numbers or phone numbers, and have they given you a form with the text "no spaces or hyphens"? Send it back. Demand that they fix it, and if it's going to cost significantly more than any other change would, find someone else to do it.

Integrating with a third-party site to take the credit card information? Demand that they let your customers enter the numbers they need to with as many spaces and hyphens as they want. (And if they won't, find another site to integrate with)

Oh, and also: A pulldown menu for US states? That's just wrong too.

This message brought to you by an encounter with www.aa.com, who should be able to afford a better website.

Edited to add: If you're at a loss as to how to do this and are groaning about digging into your db code, at the very least implement step 1 on this page, which will ease the pain of the vast majority of your users. (That page describes some simple javascript you can add to such fields so that users can enter them however they want, but the form still has only numbers when it's submitted)
dtm: (Default)
So here's a bit of a geeky post, but not so terribly geeky that I'm hiding the bulk behind a cut link.

"true" and "false" are simple concepts, right? Different programming languages seem to have hugely different ideas of what they are:

In C, 0 is false, any other integer is true, and the coercion rules make a null pointer false, and any other pointer true. Anything else is a compile error.

C++ follows (inherits?) the C rule, and adds true and false as things that are true and false.

In shell, 0 is a true exit value; any other exit value is false. Inside [ ], empty strings are false and other strings (such as "0" or "1") are true.

In Python, 0, 0.0, -0.0, False, None, the empty string, empty tuples, lists, and dicts are all false. Anything else (such as the string '0') is true. (A note on 0.0 vs -0.0: they're both == according to python, and both false, but print differently. One can be turned into the other by multiplying by -1)

In Perl, 0, the empty string, and undef are false, and since evaluation as a boolean imposes scalar context, an empty array or hash variable is also false. Anything else (including arrayref or hashref values to empty structures) is true. Note that because perl helpfully autoconverts like a $SOME_NOUN_HERE, the string "0" and 0.0 are to perl identical to 0, and therefore false. (hence the Perl idiom "0 but true") A full discussion of the quirks of perl around various representations of zero could probably fill a small book, but I'll note that other consequences are that the expression -0 is true, but -0.0 is false.

In Ruby, false and nil are false, anything else (including 0, the empty string, and an empty Array or Hash) is true.

In Javascript, 0, null, undefined, the empty string, false and NaN are false. Anything else (such as an empty Array, or empty Object) is true.

In Java, (since the autoboxing introduced in Java 1.5) true and Boolean.TRUE are true, false and Boolean.FALSE are false, ((Boolean) null) is a runtime exception, and anything else is a compile error.

In Haskell, True is true, False is false, and anything else is a compile error.

Google Go behaves like Java 1.4 or Haskell - true is true, false is false and anything else is a compile error.

Scala appears to behave the same way - true is true and false is false. Anything else (including an instance of RichBoolean, or of java.lang.Boolean) is a compile error.

In Common Lisp, nil, aka the empty list, is false. Anything else - including 0, the empty string or empty vectors of other types - is true.
dtm: (Default)
Because I've recently read an article on how Microsoft has egg on its face because of this, and because searching on Google for "sort a list randomly in javascript" currently shows the wrong thing to do in the top several hits, here's how to take a list in javascript and shuffle it, or sort it in a truly random order.

Also, yeah, it's been over two months since I last posted, etc.

However, this is just going to be code, and anyone who still has me in the old friends list probably doesn't need their livejournal covered with code, so it goes behind a cut...
Read more... )
dtm: (Default)
Yeah, yeah, haven't posted in ages, etc.

As those few of you who still have me on your friends' lists probably know, I work for Google.

As the rest of you may know, Google's a fantastic employer and many, many more people than we can hire want to work here. In fact, many more people with good resumes want in than would be practical to interview in person. Hence the phone screen, wherein a Google engineer calls you up and assesses whether you should be brought in for an interview.

I do about one phone screen/week, on average.

Sometimes my interviewees manage to seriously annoy me. As a public service, here's how to avoid doing that. Note that many interviewees who did not annoy me still didn't end up with in-person interviews, but that no one who did annoy me did. This is basically a guide for how to avoid totally bombing - if you want a guide for how to actually succeed at a Google interview, look elsewhere.

This applies only to people being interviewed for a technical position (i.e., Software Engineer or Site Reliability Engineer). Not knowing everything on this list does not make you a bad person, nor will I be pissed off at meeting you if you don't know everything on this list. It does mean, though, that you are not ready to phone screen at google for an SWE position.
Cut for friends pages )
dtm: (Default)
Yeah, yeah. First post in a long time, first post of the new year, first post with a new US President, etc. Assume I've groveled sufficiently for not posting in ages.

So the other day I visited a website belonging to a friend and my web-browser completely freaked out, blocking the site and saying that it linked to all sorts of disreputable places. That is to say, it warned that my friend's site was including material from sites that attempted to install all sorts of malware.

Now, this was odd, but occasionally a bad ad can get into an ad network, and then everyone showing those ads accidentally is displaying malware, and I figured that was what happened since when I went back and then visited the site again, all was fine.

Only, after reloading her page I discovered that my friend doesn't run ads on her site.

A more detailed description of what was going on, probably of interest only to techies )
dtm: (Default)
From the quiz solution summary on http://rubyquiz.com/quiz122.html: (ellipses in the original)
You have shown me the light and it tells me... Daniel Martin is crazy. I'll leave it to him to explain his own solution, as punishment for the time it took me to puzzle it out. I had to print that Array inside of the inject() call during each iteration to see how it built up the answer.
Update: I did in fact accept my punishment and post an explanation of my twisted implementation of the Luhn algorithm.

Update: Sorry; anonymous comments aren't shown on this entry any more. Three spam deletions is my limit.
dtm: (Default)

So I've thought about several different journal entries I could write lately, but I somehow just don't feel I have the requisite will-to-type to write any of them. So here are some scattered thoughts I'm not journaling about:

dtm: (Default)
And now for something totally geeky. Of interest only to those programmers whose programming interests encompass both java generics and functional languages that tend to represent lists as singly linked lists most of the time. This is just kind of wandering about, with no coherent theme or conclusion to the post.
(Haskell-style lists in java, with generic type safeness) )

Update: figured out a better way to do append in the ? extends E model.
dtm: (Default)
So one thing I discovered as I went back over my old posts is that I used to do some serious computer geeking in my posts. I mean, seriously.

And I haven't done any computer geeking on livejournal in a while, so:
The insanity that is the jvm's shutdown sequence )
dtm: (Default)
I wrote this in Notepad on the train, but hadn't had a chance to post it until now - it's been a bit of a hectic day:

So last night, for reasons that may be apparent if you read [livejournal.com profile] jmartin2's journal, I had several hours during which I could just wander around Marlton, and perhaps not too surprisingly I found myself walking around the big Barnes and Noble that's at the corner of Rts. 70 and 73.

And, as often happens, wandering around that big bookstore made me sad. I've been trying to express why, but big bookstores like a Borders or a Barnes and Noble have that effect on me. The same thing does not happen in little stores like the several used-and-antique bookstores we sometimes visit in Bordentown, even on those occasions when I don't find anything to buy.
Looking at math books )
Then, having thoroughly depressed myself in the mathematics section, I wander a few shelves over to the computers section.
"Computers" )

Magic spot

Jun. 24th, 2004 10:41 am
dtm: (Default)
For years, whenever my father has been learning a new programming environment (being a programmer since the late 60's, he's gone through a few), especially a new GUI environment, one of the things he'd implement as a test is a game he invented in the early 80s called "magic spot". It's a stupid little game, but it works as something to implement and get ones feet wet in a new environment.

Anyway, he's somehow avoided learning any HTML or related technologies until now, when he suddenly has to rewrite a huge bunch of asp forms with embedded client-side scripting.

So he's been picking my brain on and off and the other day sent me an initial implementation of magic spot with client-side VBScript. Of course, I can't view that in Mozilla, so I responded with my own version which will take advantage of client-side javascript if available, but will work just fine if javascript is turned off. (and works in both mozilla and ie, but may not work too well in old netscape 4)

An easier (and faster-loading) version

The source code

If you look at it in a browser that supports the css attribute :hover on arbitrary elements (like mozilla), you get the added benefit of being able to easily see which spot you're clicking.

Edge cases

Mar. 2nd, 2004 01:02 pm
dtm: (Default)
Edge cases are hard. Off-by-one errors are painful. (see also page 25 of this pdf)

Why, then, do programmers seem to delight in creating edge cases for themselves?

I remember as an undergrad. helping out in the CS lab at Carleton. One of the first very painful assignments for people in the second CS course in our CS sequence involved making and using singly linked lists. Thorny edge cases all over the place, and with pointers too.

Now, there are some edge cases here, but not nearly as many as people think, if they simply use slightly different variables.

C singly-linked-list digression )

Maybe special cases are the kind of thing that creeps up on you - it's easy to do just one, but soon you end up with a dozen tricky edge cases because adding each one was easier than re-thinking your algorithm. However, I often find that special cases are added in preference to using a few extra variables, or allocating a little bit more memory.

I'm thinking about this because I recently dealt with someone at work being burried under special cases. The specific problem has been simplified; I'll include it in an lj-cut below. When he called me, he'd just gotten through trying to work out how to handle all his different test cases, which were ending up in at least four tricky edge cases, and several flag variables that he was having trouble keeping separate. In fact, I was able to simplify the main loop to have just three if statements (none nested), and two of those if statements were identical.
Fun with text manipulation in perl )
dtm: (Default)
So we have some code that loads data from one place to another place, and I'm trying to figure out why when this code flags an error, it appears that the bad data is still getting loaded, and I discover this:
> grep -n haveError read.cpp
211: int haveError = 0;
228: haveError = 1;

It's awfully hard for a variable that's never checked to affect program execution...
dtm: (Default)
This weekend, I went through and updated the software on my machine, including getting a new release of the modem driver for my computer from intel's website. You can see where this is going, right?

Well, the driver update caused ppp to stop working. After seeing the problem occur a few times a vague memory of finding and fixing this problem with the old modem driver software began to surface. Unfortunately, I'd already completely wiped out all copies of the old driver, so I had to figure out from scratch how to fix this.

This time, I'm documenting in LiveJournal how I got my stupid cheap no-brand modem (but based intel's 536ep chipset) to behave with ppp in linux. Next time I forget and accidentally wipe out the fixed version, I'll just look back at my livejournal and say "ah, that was how I did it."

source code diving )
| |
dtm: (undefined)

What I've been programming on like mad these past few days is SMML - St. Mary's Music Library. At least search now works, even if I don't have the log-in-so-you-can-comment bit working yet.

Jennifer's been cataloging the assorted sheet music that has accumulated in the chior room at our church on a scrounged computer (built mostly out of bits of machine I've cast off, plus a donated old vga monitor from work and a yard-sale dot matrix printer) using an old package called dbman and lynx.

Well, that has a few problems. First off, dbman isn't a very functional program to begin with; secondly, we need to advertize for them if we put it up somewhere so that other people are able to search with it.

So I'm a programmer, right? So it should be a simple matter to put something like this together. I mean, it's just throwing up a database based on DBD::CSV, and writing a few pages with Mason. These choices were made because dbman stores things in a file format that DBD::CSV can use, or at least I thought it did. It turns out that DBD::CSV is a bit picky about some things.  I chose Mason because I thought it would be easy to set it up in an environment where all I can set up is a cgi script; actually, that was true, modulo having to work around the fact that the webserver's chroot contained almost no perl modules.  Plus, if it becomes possible to move to a mod_perl setup, Mason will let me do that.

So two weekends and several long nights later, the searching that shouldn't take me "more than a few hours" is up and functional. (Lots of stupid stuff I ran into along the way - including an interesting bug that vanished when I looked at it with the debugger, because the condition I set on a breakpoint caused an integer comparison to happen. perl's string<->number equivalence can get whacky) Now I need to add everything necessary to let Jennifer make changes, and then I can work on allowing other people to add annotations (maybe; we're still not certain that there's any need for this feature).  The changes bit is interesting since I have to keep three copies of the database in sync - one on cush (my home machine), one on snowplow, and one on phoenix (the machine sitting in the chior room basement).  Fortunately only one person is going to be making any changes.

The search language parser is a neat hack, if I do say so myself. I should document it sometime as an example of leveraging perl's parser to do your work for you.

While taking a break I ran across some old pictures I had taken while in Baltimore, and my lj picture needed changing.

dtm: (Default)
So my coworker may have found a bug in one of our big jewels-of-the-company core libraries. We send off the bug report along with a short sample program that demonstrates the bug; to make a long bug short, it tries a certain sequence of operations in a specific order and fails (the library call returns a bizarre error status) half-way through.

We get back the message: "we couldn't reproduce the effects you mentioned; when we compiled the code here it coredumps at the first attempted operation".
Longer story about debugging someone else's changes )
And now a small rant about C and the equivalence of a null pointer and an uncasted-to-anything 0.C gripe )
Page generated Jul. 24th, 2017 12:50 pm
Powered by Dreamwidth Studios