Articles on this Page
- 11/01/10--01:10:_Sometimes I want a...
- 11/02/10--11:42:_That's going to take a...
- 11/26/10--01:34:_A foolish thought from...
- 12/09/10--05:56:_Intellectual weaknesses
- 12/11/10--00:50:_Trust
- 12/18/10--15:36:_Truly this is the age of...
- 01/09/11--01:57:_A foolish thought
- 02/01/11--01:14:_The Moment of Jinx
- 03/14/11--07:32:_Placing a foot into the...
- 03/16/11--04:36:_Layer-free shell syntax
- 03/17/11--03:23:_C abuse of the week
- 03/18/11--06:33:_Errata
- 03/22/11--04:26:_Gadgets I would like to...
- 04/05/11--16:24:_Exploding toothpaste
- 04/14/11--09:15:_Machine translation gets...
- 05/03/11--10:28:_Murphy strikes again
- 05/09/11--01:49:_Medical farce
- 05/11/11--10:15:_You couldn't make it up
- 06/16/11--16:01:_Pub poetry
- 06/30/11--12:32:_Bah
- 07/12/11--13:13:_Signs of life
- 09/26/11--05:47:_Unexpectedly handy
- 10/06/11--11:13:_Sometimes I have an idea...
- 12/07/11--07:45:_RepugNaNt
- 01/03/12--01:38:_Forgot my password!
More Channels
- Jan 29: LernVid.com | Webdesign,...
- Jan 29: Untitled, again.
- Jan 29: Last 25 matches for Imperial
- Jan 16: h p lovecraft | Keyword Feed
- Dec 14: hot sex stories | Keyword Feed
- Dec 19: hp f4486a battery | Keyword Feed
- Nov 26: homefront in focus | Keyword Feed
- Nov 25: Fotoblog robin1
- Nov 25: Root Hog Or Die
- Dec 9: home design | Keyword Feed
- Dec 9: hopedeans | Keyword Feed
- Dec 20: hotels most haunted | Keyword Feed
- Dec 14: howler monkeys | Keyword Feed
- Nov 26: how to stop bad habits | Keyword...
- Nov 25: Jenzy Fancy's site
- Nov 25: "I am who I am"
- Nov 25: rifa's Site
- Nov 25: Delighted
- Nov 25: yuyun's Site
- Nov 25: ...
- Nov 25: ROBERT ○ KRISTEN ○ TAYLOR...
- Jan 29: holy war on internet | Keyword Feed
- Dec 9: honest hosting | Keyword Feed
- Dec 9: hook up | Keyword Feed
- Dec 9: hopi legends | Keyword Feed
- Dec 29: hospital nurse rights |...
- Jan 25: house budget committee | Keyword...
- Dec 14: howie schwartz product launch...
- Jan 2: how to create a resume | Keyword...
- Nov 26: how to play piano | Keyword Feed
- Dec 31: 小丑——LEO
- Nov 25: ...
- Nov 25: WELCOME TO THE WORLD OF RESIDENT...
- Nov 25: Eyo's Site
- Nov 25: Richlite
- Nov 25: ayis' Site
- Nov 25: LoSt WorLD.......
- Nov 25: This ain't a fairy tale, it's...
- Nov 25: LanguagCourseReview.com»...
- Nov 25: TIME OF MY LIFE
- Nov 25: yumei's Site
- Dec 30: Good Morning Teacher.
- Nov 25: Rosendo's Site
- Nov 25: Firle Bonfire 2010: Roz South...
- Jan 3: Audioslave update feed
- Jan 27: holy relics | Keyword Feed
- Jan 14: home repairs | Keyword Feed
- Jan 8: homosexual spirit | Keyword Feed
- Jan 24: hoodia slimming supplements |...
- Dec 9: hoodstock | Keyword Feed
|
|
Are you the publisher? Claim this channel |
|
Channel Description:
Latest Articles in this Channel:
- 11/01/10--01:10: Sometimes I want a portable QI klaxon (chan 1676087)
- 11/02/10--11:42: That's going to take a little getting used to (chan 1676087)
- 11/26/10--01:34: A foolish thought from the pub (chan 1676087)
- 12/09/10--05:56: Intellectual weaknesses (chan 1676087)
- 12/18/10--15:36: Truly this is the age of the Internet (chan 1676087)
- 01/09/11--01:57: A foolish thought (chan 1676087)
- 02/01/11--01:14: The Moment of Jinx (chan 1676087)
- 03/14/11--07:32: Placing a foot into the other camp (chan 1676087)
- 03/16/11--04:36: Layer-free shell syntax (chan 1676087)
- searching for a string starting with a minus sign using a command along the lines of ‘
grep \-10 file.txt’. (‘The backslash causes other characters to be treated literally rather than specially, so why not this one?’) - expecting ‘
~’ and ‘~user’ to still be expanded after a colon (‘PATH=/here:~/there:$PATH’). - getting subtly wrong results when adding a prefix to an existing command line, if the latter had redirections. (E.g. prefixing ‘
sudo’ or ‘gdb --args’, and finding that in the former case the file is not opened with root privilege and in the latter case all of gdb's interactive output gets lost.) - almost anything involving multiple layers of escaping. (The typical example being regular expressions, where you have to first escape special characters to stop them being special to the shell, and then escape them a second time to stop them being special to the application. And don't forget to shell-
escape the extra characters you used for the second job, of course.) - when a one-
character option takes an argument either with or without a separating space, and you want to pass an empty string as argument, omitting the space before the quoted empty string. (‘If ‘ -s foo’ and ‘-sfoo’ and ‘-s ""’ all do what I expect, why on earth would ‘-s""’ not?’) - 03/17/11--03:23: C abuse of the week (chan 1676087)
- 03/22/11--04:26: Gadgets I would like to exist (chan 1676087)
- 04/05/11--16:24: Exploding toothpaste (chan 1676087)
- 04/14/11--09:15: Machine translation gets it spectacularly right (chan 1676087)
- 05/03/11--10:28: Murphy strikes again (chan 1676087)
- 05/09/11--01:49: Medical farce (chan 1676087)
- 05/11/11--10:15: You couldn't make it up (chan 1676087)
- 06/16/11--16:01: Pub poetry (chan 1676087)
- 07/12/11--13:13: Signs of life (chan 1676087)
- 09/26/11--05:47: Unexpectedly handy (chan 1676087)
- 10/06/11--11:13: Sometimes I have an idea and then just wish I hadn't (chan 1676087)
- 01/03/12--01:38: Forgot my password! (chan 1676087)
I'm in work an hour early today, as partial compensation for the fact that I have to leave two hours early to go home and wait for a boiler engineer.
Of course, it so happens that that's also the time I'd have shown up if I'd failed to notice that the clocks had changed. Naturally this occurred to me; naturally I suspected that somebody would make that assumption; and naturally, as I was sitting down at my desk, someone did indeed ask ‘You know the time changed, didn't you?’.
In such situations I can think of no better response than the QI alarm sound. (Though Stephen Fry pulling a foolish face is optional.)
As of yesterday, apparently, I am now Uncle Simon.
Everybody knows what wisdom teeth are. But under the influence of booze it occurred to me to take the concept in an unusual direction.
Strength teeth must surely be the molars; the sheer leverage available to them allows them to effortlessly crush things that the front teeth would have a hard time getting into.
Dexterity teeth are the canines: they grip on to things to allow them to be manipulated.
Charisma teeth, as
ptc24 pointed out, are the incisors right at the front, which are conveniently placed to (if properly cleaned and polished) catch the light photogenically when you smile.
What I'm not so sure about is where intelligence teeth and constitution teeth come in. Premolars are still to be assigned, but I can't make a good case for them being either of those…
For a while now I've been trying to think a bit about the way I think. When I get something wrong, fail to solve a problem, misunderstand something, or whatever, I try to look back on what went wrong, and I try to notice if it's the same thing that went wrong on other occasions. I now think I'm in a position to write down some of my most noticeable intellectual weaknesses. (At least, most noticeable to me. I expect other people probably notice different weaknesses about me from the ones I notice about myself.)
Neophobia. I often find that I'm extremely reluctant to get into a new piece of thought: picking up a new problem, or starting to learn about a new thing. Typically once I finally do get over that activation-
Too uninterested in the actual compared to the possible. To some extent this almost isn't a weakness –
Difficulty keeping track of many things. I much prefer to have a small number of problems to work on, each of which is complicated and fiddly, than a large number of problems each of which is in itself simple. I can handle complicated problems fine (or rather, I have at least as much of a fighting chance with them as anyone else), but keeping track of lots and lots of things without forgetting about one of them is much harder for me. Of course I can and do compensate by constant list-
Compartmentalisation. When I learn a fact in one context, I often find I've failed to apply it in another context, or failed to relate it to a fact I learned in another context which in combination with the first one would have told me something really useful. I seem to have a few mental compartments for thinking about different kinds of thing, and sometimes those compartments don't link up and talk to each other when they really ought to.
Insufficiently bold imagination. Quite a few times in the past couple of years I've tried to solve a problem by considering a lot of candidate solutions and then judging which of them are sensible or workable or likely. Often I've failed to solve the problem, and found out afterwards that this was because the real answer was completely outside the space of possibilities I'd considered –
I wonder what can be done about these. One feels that the neophobia ought to be dealable-
When I was a child, I remember that I used to have a peculiar problem whenever I replaced my watch. For days or weeks after strapping the new one on to my wrist, I'd wonder what the time was, look at my watch … and then feel unsatisfied, as if somehow I still didn't actually know what the time was in spite of having just read it off. I'd feel a strong urge to go and find another clock and look at that. It's as if I didn't trust the new watch.
I suppose it's possible that this was my subconscious reminding me of the practical consideration that I didn't yet have a feel for how accurate the new watch was, but that seems far-
I haven't replaced my watch in well over a decade, so until today I had no idea whether I would still have this odd feeling. But just now …
I've recently acquired an iPad, and also I've finally got round to setting up wireless networking at home to use it with. So today I thought I'd do my morning spod –
So I did that; but as soon as I got up, I felt a strong visceral urge to make for the nearest ‘real’ computer and reassure myself that there weren't any urgent emails waiting for me. But I just looked! Arrgh!
(This is even less rational than the one about the watch. A new watch might have turned out to be hopelessly inaccurate compared to the old one, but I check my email over SSH, which is really, really not going to present me with wrong answers depending on where I connect from. If it gives me any recognisable answer at all, it'll be the right one.)
Brushing the loose snow off the roof of my car, I found that the layer of more solid ice underneath had a message engraved in it. Some passing scamp had presumably written with their finger in the initial layer of snow, and when that solidified under the next layer the message was preserved.
The message just read ‘LOL’.
If somebody had been programming exclusively in FORTH and PostScript for years on end, they'd probably think a change would be inorder.
There's something about screwing the lid back on to a computer's case that seems to act as a magnet for bad luck. Especially if the same machine has been running just fine for weeks or months with the lid off; you finally decide that's cause to declare it working, so you put the lid back on and do up the screws … and the tightening of the final screw, symbolic of your overconfident belief that the job is at last done, is the cue for every intermittent fault, every surprising and hitherto unmanifested bug, every glitch and gremlin and gribbly to come out of the woodwork and make itself known.
Just occasionally there's a causally valid reason for this –
(Preliminary indications suggest that the one of these that happened to me last night was not even a fault in the computer in question, but I'm half expecting further nasty surprises…)
More migration seems to be occurring, so it's probably about time I got round to doing this: I'm now simont.dreamwidth.org as well as simont.livejournal.com. I have no plans to deactivate my LJ or stop reading stuff via it; I expect to cross-
There will doubtless be annoying teething problems as I sort out this dual presence and integrate it with the rest of my setup. In fact I've already made one cock-
Here's a question I've been pondering for a while, to which I don't have any good answer.
I often find myself answering questions from Unix users who are having a little trouble working out how to get some complicated piece of shell syntax to work. The impression I'm left with is that a major source of confusion is the fact that the POSIX shell syntax as a whole –
Examples of gotchas arising from this, many of which you need to develop quite a deep understanding to sort out, include:
Some of these even catch me out on occasion, and I know perfectly well why they don't work. Typically I realise my mistake as soon as I see the error message or odd behaviour –
And that's the point, really. The system is just too complicated to manage sensibly. So: if we were designing a shell syntax from scratch, would it be possible to arrange it in such a way that you don't ever have to reason about layers? The ground rule would be: the system is permitted to divide labour between multiple processes or pieces of code, as long as that division is its problem rather than the user's, and (barring the diagnosis of actual bugs) a user never has to keep in mind the divisions between those components just to figure out what a given command will do or what command they need to do a given task.
But the catch is that you aren't allowed to solve the problem by reducing the expressive power of the syntax. If you do, application authors will take up the slack by implementing all the things you didn't, and they'll all do it differently from each other, or not do it at all, and nobody will be better off. (See, for example, the haphazard state of wildcard support in Windows command-
Here's a simple example of the sort of thing I'm thinking of. In a summer job when I was a student, I had occasion to write a tool that presented an internal command line, and I got to make up the syntax used on that command line. Basically on a whim, I set it up as follows: spaces were special (they separated words), double quotes were special (they stopped spaces from separating words), and the only other special things were braces, which were used to enclose special tag names. Initially, when starting to scan a command line and looking for the actual command word, the only things you were allowed to do with braces was to use them to escape the existing special characters, so that {{} and {}} and {"} translated into the literal characters {, } and ". But the main command processor only parsed the input line as far as was necessary to find the command name –{-} which was not treated specially; so a user would not have had to draw the mental distinction between characters treated specially by the ‘shell’ and by one particular subcommand, and would have been able to work on the much simpler principle that all special characters were defusable by bracing them. (Or, perhaps better still, the subcommands could all have adopted the principle that everything not braced was treated literally, and invented braced tags to do everything special they might need.)
Of course it was easy for me to do something like that in a small language supporting only a few commands, particularly when there was no division into subprocesses (each of my commands was just a procedure within the same source file). And even so, my design wasn't perfect (e.g. it would still have suffered from the ‘-s""’ flaw in my above list). And it had very simple functionality by comparison to the full scope of real shell syntax. And, of course, I wouldn't even dare to imagine that any replacement shell syntax design would be realistically adoptable at this stage, what with a huge established source base.
But it illustrates the sort of idea I'm thinking of. So, just as an exercise for curiosity's sake … could the entire edifice of shell design be reworked, in principle, by means such as the above or by totally different means, so as to avoid the need to have users keep track of the multiple layers of code involved?
Also at Dreamwidth. (
A while back I wanted to write some C code that looped over every element in a collection. But I wanted the code to be parametrisable in the face of different implementations of that collection, because it might have to link against several other pieces of code which might all store the things in question in a different format.
LOOP_OVER_ALL_ELEPHANTS(elephant) {
/* loop body executed once for each elephant */
}
And then each implementation would define the macro LOOP_OVER_ALL_ELEPHANTS appropriately for how it happened to be storing its elephants. If it was an array, the macro would expand to
for (elephant = array; elephant < array + len; elephant++)
and if it was a linked list, it would expand to
for (elephant = head; elephant != NULL; elephant = elephant->next)
and I presumed that any more complicated thing like a C++ STL collection would have some kind of similar idiom available.
Unfortunately, the very first implementation I tried to test against turned out to be storing its elephants in a circularly linked list –
for (elephant = head; elephant != head; elephant = elephant->next)
then the loop terminates after zero iterations and you look foolish.
I solved the problem by rewriting my loop in the form
LOOP_OVER_ALL_ELEPHANTS(elephant) {
/* loop body executed once for each elephant */
} END_LOOP_OVER_ALL_ELEPHANTS(elephant)
which permitted the porting code to define a pair of macros containing the two ends of a do-
But this morning, I do believe I've solved it. You can iterate over a circularly linked list using a construction that can be encapsulated into my original macro, requiring no loop machinery after the single closing brace. It's strictly legal standard C as far as I can see, and it goes like this:
switch (elephant = head, 0)
while (elephant = elephant->next, elephant != head)
case 0:
Then you can follow that with a single braced block (or even an unbraced statement), and everything works –continue. So I could have put that lot into my macro, and it would have been fine!
More generally, this construction permits a sort of variant form of the for statement, which does its test after the loop body rather than before. You could almost define it as a macro in its own right:
#define for_after(init, condition, increment) \
switch(init, 0) while (increment, condition) case 0:
Of course that isn't quite syntactically right, because the three clauses of the for are separated by commas rather than semicolons, and can't contain initialisers in the way that a proper for can. Also there's the unusual constraint that the body of such a statement cannot contain case statements intended to bind to switches outside the loop (so you can't combine a loop of this form with Duff's Device).
But it's closer than I thought I'd be able to get!
eta: there's a bug in the switch-based solution above. See my follow-up post for details.
Also at Dreamwidth. ( comments | Leave a comment )
Ahem. In yesterday's post about iterating over a circularly linked list, I made a mistake. The construction I exhibited, because it completely skips any test at the start of the loop, will crash if the list is empty and hence its head pointer is NULL.
Fortunately, this is fixable by putting an additional test in the switch statement:
switch ((elephant = head) == NULL)
while (elephant = elephant->next, elephant != head)
case 0:
Then if the head pointer is NULL, the switch's input value will be 1, so it won't execute anything in its body at all.
However, I now also realise that there's a better answer in the first place. One commenter yesterday observed (and I had also thought myself) that the problem would be easy if only you could declare an extra flag variable and use it to suppress the first loop test. You can't, under the constraints of C90 syntax, because there's nowhere to put the declaration that doesn't cause further syntactic problems. But actually, I just realised, you don't need an extra variable at all –NULL. So you can just do this:
for (elephant = NULL;
elephant ? elephant != head : (elephant = head) != NULL;
elephant = elephant->next)
So if elephant is NULL on entry to the loop test clause, that's the signal that it's the very first iteration, and we reassign elephant to the loop head pointer (and terminate if even that is NULL). Otherwise, it's a non-head.
This is a cleaner solution than the switch-based one, because it doesn't interfere with case statements inside the user-
Also at Dreamwidth. ( comments | Leave a comment )
I've occasionally thought it would be nice to have a coffee mug with a built-
This morning it occurs to me that there's a much smaller, simpler and more realistic coffee-
I suppose you'd also want it to notice if you'd already finished the coffee, and not go beep just because an empty mug had cooled past the threshold. Hmm. Must be something clever you can do about that…
Also at Dreamwidth. ( comments | Leave a comment )
Warrgh, that was unexpected. I picked up my toothpaste tube, squeezed it gently until toothpaste began to emerge from the nozzle … and there was a sudden pop, a fingertip-
There must have been a big bubble of air in the tube due to a manufacturing defect of some sort, and the instant there was no longer enough toothpaste blocking the nozzle to impede its bid for freedom, off it went.
But for all that the cause is comprehensible after the fact … I've never had a tube of toothpaste explode in my face before!
Also at Dreamwidth. ( comments | Leave a comment )
In a debate at work about development workflow, I somewhat whimsically responded to a suggestion by writing ‘Jira issues non sunt multiplicanda praeter necessitatem’. (For those lucky enough not to have encountered it, ‘Jira’ is the name of a bug tracker.) I wondered briefly whether that would be too incomprehensible to post (but decided not, and posted it anyway).
Chris had the obvious idea that if someone didn't understand it, they might try pasting it into Google Translate, and tried it. Google Translate renders the sentence into English as ‘Jira issues must not be multiplied beyond necessity’. Very good; I'd have preferred should, but must is acceptable.
But what's impressive is that if you switch the target language to something else, it turns out that it's not (as I initially assumed) identifying the language as Latin, applying a Latin-
Also at Dreamwidth. ( comments | Leave a comment )
When wielding a Stanley knife, I concentrate extremely hard on not cutting myself with the Stanley knife.
So hard, in fact, that I manage to completely overlook the possibility of cutting a finger on the thumbnail of my other hand. Sigh.
Also at Dreamwidth. ( comments | Leave a comment )
Two weeks ago I tried to make an appointment with my GP. Since it was tedious administrative routine (renewing my prescription for gluten-
When I arrived for my appointment they said I didn't have one.
I was not best pleased, but the receptionist was utterly unwilling to do anything to compensate, so the best I could do was to walk away with an appointment card promising me an appointment in another week's time.
This morning I turned up for that one, and this time I got to see a doctor. However, I still didn't walk away with a prescription in my hand –
Also at Dreamwidth. ( comments | Leave a comment )
Oh, good grief.
My missing prescription from Monday turned up in the post yesterday, after the surgery got their printers working again.
I took it to a pharmacy just now –
Also at Dreamwidth. ( comments | Leave a comment )
Crashety-
bashety
Microsoft Windows is
badly in need of a
UI that's nice.Some feature filed under
‘Accessibility’
makes it superb –but you
can't find it twice.
(Brought to you by several pints of Kopparberg and
fanf praising the ‘mouse trails’ feature in Windows.)
Also at Dreamwidth. ( comments | Leave a comment )
A pleasant evening; a good book, a silly iPad game, a nice bowl of soup almost ready to eat, and then the prospect of the pub.
One ill-
That last point is probably just as well today, I suppose. If I can make this much mess in ten seconds while sober…
Also at Dreamwidth. ( comments | Leave a comment )
After over four years, a PuTTY release sees the light!
But good grief, I had forgotten how much hassle the release process was. I remember having a long and clearly worded checklist to help me through it –
(Or perhaps it's just my brain that's rotted.)
Suddenly I feel a surge of sympathy for the people at work who have to actually ship software to customers.
Also at Dreamwidth. ( comments | Leave a comment )
Over the last couple of weeks I've been trying to arrange to get a proper lock fitted on my back gate at home: one that you can conveniently open with a key from either side, instead of having to reach through the gate to a fiddly padlock and risk dropping your entire keyring on the wrong side of a gate you can't get through.
I found an online recommendation for a handyman, and since he had an email contact address listed, I thought I'd do the initial feasibility discussion by email in the hope that it would be less hassle than faffing about with telephones. This turned out to work very well: he was able to send me a URL showing the precise type of lock he suggested would be best, and in return I sent him a URL to a photo I'd just taken of my gate so he could judge whether it was suitable to take that lock without actually having to come and look at it, and then he sent me an official quote for the job as a PDF.
What I wasn't expecting was that an hour ago, when I was in the Tesco near work buying my lunch, a guy I'd never seen before stopped me in an aisle and asked ‘Are you Simon?’ –
Also at Dreamwidth. ( comments | Leave a comment )
Many Unix programmers will be familiar with the utility variously called strace, truss, ktrace, dtrace and probably other names too, which logs all communication between a process and the kernel across the system call interface.
A couple of years ago I wrote an analogous program called xtruss, which produces similar logging but operates at the interface between an X11 client program and the X server. (Of course, that wasn't a new idea; I just liked my version's design better than prior ones, mostly because it behaves more like strace.)
A related piece of software to strace is Subterfugue, which intercepts system calls using the same underlying technology that strace does, but instead of passively monitoring them, is able to modify the results as it sees fit. The result is a user-
Today I had the idea: why not fill in the blank in that table, and write the thing that is to xtruss what Subterfugue is to strace? Reuse xtruss's framework for conveniently setting up one-
But that wasn't the idea I started off with. I was actually wondering about a much more specific problem: remapping –
And since I already have the X proxy framework from xtruss, the thought occurred that I could enhance it just a little to let it rewrite or squash X events, and then I'd have a proxy that would do the thing I wanted; and although this would certainly be a disproportionate effort for the result if I were writing that X proxy from scratch, doing it by slightly modifying code I've already got seemed almost practical by comparison.
But of course once I'd thought of doing this job by proxying an X connection and rewriting pieces of it, I realised that that certainly wouldn't be the only use for such technology, which led immediately to the idea of a Subterfugue-
And on the one hand that does sound like quite a fun piece of software … and yet, we're now back to it being a huge amount of work to go to for the sake of the one specific application I actually wanted it for, and I'm pretty sure I can't be bothered. But on the other hand, now I've imagined the generic version, I also wouldn't feel right about writing just the one-
(There seems a good chance that at least one reader will point out some totally different way in which I could impose keystroke-
Also at Dreamwidth. ( comments | Leave a comment )
I had a disgusting thought just now. I needed to have some Python code check whether a dictionary contains a particular key/value pair. The obvious approach,
if dictionary[key] == value:
isn't sufficient, because I need to not throw an exception if the dictionary doesn't contain any mapping for that key at all.
An obvious way is to use a second clause to handle the latter case, so you end up writing
if key in dictionary and dictionary[key] == value:
But that's unpleasantly verbose, and also undesirable if dictionary or key is a complicated expression or one with side effects. So I wondered if we could do better.
Another possibility is to use the get() method of Python dictionaries, which lets you specify a default return value if the dictionary hasn't got the key in question. So you might say, for instance,
if dictionary.get(key, None) == value:
But in order to be able to do that, you have to be able to think of a default that will guarantee to compare unequal to value; for instance here, what if the value is None? If you know something about value (e.g. its type) then this is probably feasible one way or another, but one can imagine more general situations in which that wouldn't be the case.
I think the right answer, in fact, is to write
if (key, value) in dictionary.viewitems():
where viewitems() is a standard method which presents the dictionary as if it were a set of ordered pairs. (You could also use dictionary.items(), which would be semantically equivalent, but much slower due to constructing an explicit list and then iterating along it.)
But before I found the viewitems() method, I thought a bit harder about the get() approach. Perhaps, I thought, I could define a class with a comparison method that always returned false, so that an instance of that class would compare unequal to anything, including itself.
And then, as I thought the phrase ‘compare unequal to anything, including itself’, a stray neuron fired in my head. I think this would work pretty reliably:
if dictionary.get(key, float('nan')) == value:
and its only downside is that it is the most disgusting thing ever! :-)
Also at Dreamwidth. ( comments | Leave a comment )
I got into the office today after a relaxing holiday of three weeks (plus yesterday) and found, embarrassingly, that I couldn't remember my work password any more. I could remember a password, but I was pretty sure it was the one from before my most recent change, and it certainly didn't work when I tried it.
I can't believe that. First password I've forgotten in over a decade, surely. I had to go and queue outside the IT helpdesk room like a gormless student.
I had a brief moment of hope when I got back to my desk and found the new password didn't work either. ‘Aha!’ I thought, ‘perhaps the password I'd remembered was right after all, and it's just my desktop computer that's confused.’ But no; after some more faffing, it turned out that password changes are just propagating slowly this morning and I had forgotten my original password after all.
It's at moments like this I feel that companies ought to have a mechanism whereby you can turn round and go home and back to bed, on the basis that you're likely to do more harm than good if you continue trying to do work.
Also at Dreamwidth. ( comments | Leave a comment )