Side benefits

I’m reading Donald Gauss and Jerry Weinberg’s Exploring Requirements, and in the chapter called Measuring Satisfaction where they’re discussing the use of user satisfaction tests, they say this:

Even if the results are never summarized, the test is useful to those who fill it out.  In fact, even if nobody fills it out, the process of creating the test itself will provide useful information to the designer. (p. 239)

Huh!  Side benefits of creating a user satisfaction test.

Maybe this stuck out to me because I experienced something similar when I worked on the security enhancement project.  On that project, to get a more accurate project time estimate, I attempted to map chunks of work to days on the calendar.  Doing that did help significantly toward a better time estimate; but I think it also made me think about what the project involved in ways I hadn’t up to that point.  It made me really focus on the big picture for a day or two, and I think the improvements from that may have benefited the project as much as the more accurate time estimate did.

$H clock

Background

InterSystems Caché’s native datetime format is  days-since-12/31/1840 + comma + seconds-since-midnight. I call this $H format because it’s the format the the $H (short for $horolog) Caché system variable returns.

As an example,

03/27/2009 16:22:27

would translate to

61447,58947

in $H format.

What I Want

I want a $H clock.

  1. The clock should display the $H time in big LCD numbers, updated once per second.
  2. I’m thinking the clock would be about 3″ high by 8″ wide.
  3. I don’t want it to be attached to the computer or powered by the computer.  I can already display the $H time on the computer.  If the $H clock gets its time or power any way from a PC, the whole coolness factor for this is gone.
  4. Battery powered probably, but could be electric plug-in or solar powered, I don’t care so much as long as it’s not powered by a PC (see #3).
  5. If I build this myself, I’m willing to spend up to about $50 on materials because it will be so fun to attempt, but if someone else beats me to it I’m only willing to spend about $15 to buy their version.
  6. I have to be able to set the time somehow, preferably not by typing in a raw $H number (which I would have to look up on the computer -> detrimental to coolness factor -> see #3).
  7. I don’t care if it supports a 6-digit year value (that would be needed starting on 10/16/2114).  In fact, I’d probably rather it didn’t leave room for more than a 1 in the sixth column, as the extra space could make the display proportions look odd, detracting from the coolness factor.  (The coolness factor is very important to me. : )

Code

I expect there might need to be an IC chip to compute the $H datetime display from the current date and time.  Here’s some Python code that does the job, as an example:


# $horolog-style date/time.
from datetime import date,datetime

dateh = date.today() - date(1840,12,31)
now = datetime.now().time()
timeh = (now.hour * 60 + now.minute) * 60 + now.second
print str(dateh.days)+','+str(timeh)

def FromHorologFormat(horolog):
  parts = horolog.split(',')
  dateh = date(1840,12,13) + parts[0]
  timeh = parts[1]

  timeDec = timeh
  hours = timeDec / 60

def ToHorologFormat(dateParam, timeParam):
  dateh = dateParam - date(1840,12,31)
  timeh = (timeParam.hour * 60 + timeParam.minute) * 60 + timeParam.second
  print str(dateh.days)+','+str(timeh)

def currentHorolog():
  dateh = date.today() - date(1840,12,31)
  now = datetime.now().time()
  timeh = (now.hour * 60 + now.minute) * 60 + now.second
  print str(dateh.days)+','+str(timeh)

For an IC chip it might need to be done in C, but the Python could serve as pseudocode…

Book review: JavaScript: The Good Parts

This review covers JavaScript: The Good Parts, by Douglas Crockford.  Sebastopol, California: O’Reilly Media, Inc., 2008.

javascript-the-good-parts-cover-scan

Summary

This book undertakes to introduce the most important  things you need to know to use the good parts of JavaScript well, in 100 pages.  The author’s premise is that within the JavaScript language is a much cleaner subset, and that if you restrict yourself to that subset you’ll be able to write better programs.

There is also an appendix of Bad Parts, and another appendix of Awful Parts (Bad Parts that cannot be avoided).

The Good

  1. Terse!  Succinct! The book says so much in so few pages.  I’ve bought 800 or 1000 page books before that had almost nothing to say, but this book’s every word is there for a purpose.  Even the code snippets, while supporting some statement in the text, sometimes provide additional value by illustrating a language detail not mentioned in the text.  For example, a code example on page 22 shows var a = {}, b = {}, c = {} and a = b = c = {}, demonstrating a couple of ways JavaScript supports multiple assignments in one statement.
  2. Dry, non-sugarcoated  style. This helps keep the tone light when dealing with a programming language that admittedly has a lot of warts.  Examples:

    undefined and NaN are not constants.  They are global variables, and you can change their values.  That should not be possible, and yet it is.  Don’t do it. (p. 107)

    And:

    Unfortunately, for in makes no guarantee about the order of the properties, and most array applications expect the elements to be produced in numerical order. Also, there is still the problem with unexpected properties being dredged up from the prototype chain. (p. 60)

  3. Points out surprises in the language. This is one of the strongest points of the book.  Two quick examples:
    • The typeof operator returns object sometimes when you wouldn’t expect it (p.16);
    • Dealing with array objects:

      Because an array is really an object, we can add methods directly to an individual array…Since the string ‘total’ is not an integer, adding a total property to an array does not change its length.  Arrays are most useful when the property names are integers, but they are still objects, and objects can accept any string as a property name.  (p.62)

  4. Introduces you to the benefits of a loosely-typed language. Crockford says:

    JavaScript is a loosely typed language, so JavaScript compilers are unable to detect type errors.  This can be alarming to people who are coming to JavaScript from strongly typed languages.  But it turns out that strong typing does not eliminate the need for careful testing.  And I have found in my work that the sorts of errors that strong type checking finds are not the errors I worry about.  On the other hand, I find loose typing to be liberating.  I don’t need to form complex class hierarchies.  And I never have to cast or wrestle with the type system to get the behavior that I want.  (p. 3)

    It was really interesting to read this book soon after finishing Effective Java, since that book  had such a focus on using strong type checking to prevent errors.

  5. Helpful railroad diagrams (p. 6).  I found these really helpful in making a grammer intuitively understandable.  You can take your finger and trace around to see what’s allowed and what’s not (for examples, see the JSON site).
  6. Explains closures. (pp. 37-39)

The Bad

  1. Organization. The author says at the beginning of the book:

    There is a lot of material packed into it.  Don’t be discouraged if it takes multiple readings to get it.  Your efforts will be rewarded.  (p. xi.)

    I understand the desire for terseness and succinctness — these are strengths of the book.  But there are organizational elements that make the material more difficult to absorb than it needs to be.  A couple stand out:

    • Forward references. There are points in the book where a term or concept is stated in the text without explanation and you haven’t been given the tools to understand what you’re seeing yet — by later in the book you have what you would need to go back and understand, but at the moment, you about have to shrug and go on.  Examples:
      • The term “truthy” is introduced on page 10, but not explained until page 12
      • The term “refinement” is introduced on p. 14, but not explained until page 17
      • “The / operator can produce a noninteger result” (p.16)…  Huh?  (I now think this may be referring to NaN)
      • The Object.create function described at the bottom of p.22 was a mystery to me the first time through
    • Grammar front and center. Chapter 2 is full of railroad diagrams of the language grammar, with accompanying explanation.  The diagrams are helpful in understanding the syntax — but as I proceeded through the chapter I wished I had had more concepts first.  Then I would be able to dig into the grammar with some understanding.
  2. Lack of cross-references within the text. Even though it’s only 100 pages, it would still be quite helpful to have a page reference instead of just “There will be more about X in the next chapter” (three examples of this on page 17) or “in Chapter 6” or “at the end of this chapter” (p 31).
  3. Index is mediocre. The index is a Bad Part of this book.  It is missing several entries that would have been helpful to me.  Examples:
    • Forward references such as truthy, falsy and refinement are missing from the index
    • The topic of “global abatement” is not specifically in the index so you have to sift through three entries about global X looking for the page that deals with global abatement.  Similar for “semicolon insertion” — the index entry is for “semicolons” and you have to check out the two pages listed to find the part about automatic semicolon insertion.

    The index falls short of what I expect for an O’Reilly book.

  4. Doesn’t understand what positive and negative regex lookahead are for (p. 75).  A minor issue that I’m tuned into since reading Mastering Regular Expressions, 3rd ed. Crockford says lookahead is not a good part of the language… but would he maintain his opinion if he had seen my wonderful examples of how they can help?

Not Sure If Good or Bad

  1. Defines a new language? The author suggests augmenting the language in several ways to neutralize deficiencies in the language as it exists:
    Suggestion Strength Suggestion Page
    we can… Add method method to Function.prototype 32-33
    we can fix it Add integer method to Number.prototype 33
    That is an easy oversight to fix Add trim method to String.prototype 33
    we can fix that Add curry method to Function.prototype 43-44
    we can work around that Add is_array function 61
    can easily correct Add dim method to Array.prototype 63
    we can correct that too Add matrix method to Array.prototype 63
    You may want to Add isNumber method 105

    Maybe this is a good idea.  And it’s so little code — about 45 lines total!

  2. Explains how to create tamper-proof objects (pp. 52-55).  After getting a glimpse of some of the flexibility and benefits of a loosely-typed language, I’m not sure what to make of tamper-proof objects — they seem to work against all that flexibility, and Crockford does not offer any analysis of how this fits in with a philosophy of normally not locking down things.  Is this something that you’d normally reserve for special situations?  Use all the time?

Overall Impressions

Reading the book was like tagging along with an expert.  Sometimes he’s teaching you, but other times you don’t understand what he’s doing.  Sometimes you just have to be patient, and watch and learn.

I give the book an A in Content and a C in Organization/Indexing/Cross-Referencing.

The faults I have mentioned are not showstoppers.  The main part of the book is only 100 pages, and you can work around the forward reference problem by skimming through it a second time.  Crockford’s book helped me quickly get up to speed on the language and avoid many issues I would likely have stumbled against as a JavaScript beginner, and that was my hope for the book.  I would recommend the book to anyone hoping to do the same.

Enabling monitor power save mode on Mandriva 2009.0

I couldn’t find how to enable monitor power save mode in Mandriva 2009.0 KDE — the screen saver just kept going and going without ever turning the monitor off.

It’s really quite easy — it’s just that the setting has moved from screensaver options to monitor options:

Just go to “Configure Your Desktop” -> Display -> Power Control

(Thanks to a forum post on 0x61.com for leading me toward the right idea!)

Positive examples of positive and negative lookahead

Many tools that support regular expressions (regexes) support positive and negative lookahead.  What good is lookahead?  Why would you ever use it?

A Positive Example

Say I want to retrieve from a text document all the words that are immediately followed by a comma. We’ll use this example string:

What then, said I, shall I do?  You shan't, he replied, do anything.

As a first attempt, I could use this regular expression to get one or more word parts followed by a comma:

[A-Za-z']+,

This yields four results over the string:

  1. then,
  2. I,
  3. shan't,
  4. replied,

Notice that this gets me the comma too, though, which I would then have to remove.  Wouldn’t it be better if we could express that we want to match a word that is followed by a comma without also matching the comma?

We can do that by modifying our regex as follows:

[A-Za-z']+(?=,)

This matches groups of word characters that are followed by a comma, but because of the use of lookahead the comma is not part of the matched text (just as we want it not to be).  The modified regex results in these matches:

  1. then
  2. I
  3. shan't
  4. replied

A Positive Negative Example

What if I wanted to match all the words not followed by a comma?  I would use negative lookahead:

(?>[A-Za-z']+)(?!,)

(Okay, negative lookahead and atomic grouping)

…to get these matches:

  1. What
  2. said
  3. shall
  4. I
  5. do
  6. You
  7. he
  8. do
  9. anything

Huh? Atomic Grouping?

Yep.  Otherwise you’ll get the following (unintended matches highlighted):

  1. What
  2. the
  3. said
  4. shall
  5. I
  6. do
  7. You
  8. shan’
  9. he
  10. replie
  11. do
  12. anything

Without atomic grouping (the (?>) in the regex), when the regex engine sees that a match-in-progress comes up against a disqualifying comma, it simply backs off one letter to complete the match: the + in the regex gives the engine that flexibility.  Applying atomic grouping disallows this and says, don’t give up characters you’ve matched.

When Lookahead Does You No Good

Lookahead doesn’t really help if you only care whether or not there was a match (that is, you don’t care what text was matched).  If  all I care about is whether or not the string contains any words followed by a comma, I would dump lookahead and use the simpler regex:

[A-Za-z']+,

Acknowledgments

Thanks to Jeffrey Friedl for writing Mastering Regular Expressions, 3rd ed., before reading which I had not even heard of regex lookahead.

Also, thanks to Sergey Evdokimov for his online Regular Expression Editor.  Handy!

online-regex-editor

K3B: Restorin’ them data files

I had burned a backup of all our word processor files onto a CD-R, and armed with how to get the CD drive to show up in the Windows 95 virtualbox I popped that backup CD in to restore the data files onto the virtual hard disk.

I could pull up a directory listing for the backup CD, but only the first (oldest) backup folder appeared.  Oops, maybe Windows 95 didn’t support multisession CDs out of the box?  Mandriva can see the word processor data file backup directory on the CD, but Windows 95 can’t.

I had the idea, what if I could “burn” just the data files I wanted to their own .iso image file and then mount that in virtualbox to present to Windows 95 as the CD-ROM to copy from?

In the Mandriva application launcher menu search box I typed burn and found a program called k3b.  Here’s how I used the options to get the result I was looking for:

  1. I copied the files to the hard drive (in retrospect I don’t think this was necessary)
  2. I dragged the folder of backup data onto the what-to-burn area on k3b’s main window.
  3. I clicked the Burn button.
  4. On the Writing tab, I chose Only create image:
    k3b-writing-mode-image-file-only
  5. On the Image tab I chose where the .iso image file should be created (or rather, took note of the default):
    k3b-image-filename
  6. After clicking Start and creating the .iso image, I was able to set that up as a CD-ROM image in virtualbox, mount that image, and copy the files into my virtual Windows 95 box.  Woohoo!

Why virtualbox couldn’t see my CD-ROM

I was trying to install a program onto my Windows 95 virtual machine in VirtualBox, but the CD-ROM drive kept not being able to be read.  What was up???

Apparently the CD-ROM drive isn’t auto-mounting in Mandriva when I put a CD in.  If I go to the new device notifier, though, I can see the title of the CD there.  If I double-click it there to get a directory listing, then the CD mounts and the Windows 95 virtual machine can see it.

Locked out of virtualbox

I was trying to set up my wife’s Windows 95 installation as a virtual machine in VirtualBox on my Linux box, but when the VBoxManage clonevdi command didn’t work (which I am now pretty sure was just because I didn’t give the full path to the virtual hard drive .vdi file I was trying to clone) I did a bunch of things without writing down what I did, trying to get things to work.

When the dust settled, when I tried to run VirtualBox from my user account, I got this error:

dreaded-virtualbox-error1

Running VirtualBox worked fine from my wife’s account though.  I was baffled.

After another sleep or two though, I thought I’d try starting VirtualBox from the command line, since sometimes you get debug output to the console that way.  Sure enough, when the error box popped up I also saw these two lines on the console:

Wrong owner (0) of '/tmp/.vbox-dmeyer-ipc'.
Wrong owner (0) of '/tmp/.vbox-dmeyer-ipc'.

Ah!  I probably ran VirtualBox as root a time or two.  Looks like there’s some kind of a stale file owned by root out there.

Yep, all I had to do was

chown --recursive dmeyer  /tmp/.vbox-dmeyer-ipc
chgrp --recursive dmeyer  /tmp/.vbox-dmeyer-ipc

so my dmeyer user owns that directory and its contents, and now I can get back into VirtualBox!

Book review: Effective Java

This review covers Effective Java 2nd ed., by Joshua Bloch.  Stoughton, Massachusetts: Addison-Wesley (an imprint of Pearson Education, Inc.), 2008.

effective-java-cover-scan

Summary

From the Foreword:

If you have ever studied a second language yourself outside the classroom, you know that there are three things you must master: how the language is structured (grammar), how to name things you want to talk about (vocabulary), and the customary and effective ways to say everyday things (usage)… This book addresses your third need: customary and effective usage.

And as Bloch says in the Introduction:

This book consists of seventy-eight items, each of which conveys one rule.  The rules capture practices generally held to be beneficial by the best and most experienced programmers.

The items are organized into ten categories:

  • Creating and Destroying Objects
  • Methods Common to All Objects
  • Classes and Interfaces
  • Generics
  • Enums and Annotations
  • Methods
  • General Programming
  • Exceptions
  • Concurrency
  • Serialization

The format of the book is based on Scott Meyers’ Effective C++.

The book is designed as a next-level book for those who already have some experience with the Java programming language rather than as an introduction to the language.

The Good

The book:

  1. Helps the Java non-expert toward usability, robustness, and flexibility.  There are a lot of things to know about Java to use it well.
  2. Gives reasons for his statements. In cases where you may decide to deviate from Bloch’s advice, this gives you the opportunity to examine his reasoning and understand the implications of your decision, so you’re not flying blind.
  3. Makes recommendations concrete by giving examples. For example, in Item 20, the exhortation to prefer class hierarchies to tagged classes is illustrated with a tagged class and its alternative representation as a class hierarchy.  There are helpful code examples like this sprinkled throughout the book.
  4. Includes a succinct summary of the advice at the end of many Items.
  5. Provides expert help in doing common but tricky tasks. For instance, the naive developer may not know the contract that they’re responsible to uphold when overriding the equals() method (Item 8), or may not realize the maintainability implications of marking an object Serializable (Item 74).  Much time and distress can be saved by reading about common pitfalls ahead of time.
  6. Points out how to avoid many surprises. For example, several important details that should be dealt with when making a class Clonable (and the consequences of ignoring them – Item 11); and details about the relationship between arrays and generics (Item 25).
  7. Provides help in doing some advanced tasks well. For example, the chapter on concurrency points out the benefits and details of using the Executor Framework in java.util.concurrent rather than the Thread class (Item 68); the Serialization chapter presents the Serialization Proxy pattern (Item 78);  and Item 17 discusses issues that should be addressed when designing a class for inheritance.
  8. Includes some just plain old great ideas. The book includes several ideas that made me think, “Huh!  Why aren’t we doing this?”  An example is his advice to put methods on your checked exception that help your callers extract the information they want out of it without having to resort to parsing the description string (p. 245) and to give your custom exception types constructors that receive that information (p. 254).
  9. Is honest about Java design mistakes. Bloch believes in the Java platform, but he is not shy about pointing out its warts.  For example, p.86: Stack should not extend Vector and Properties should not extend HashTable.  I appreciate that honesty.
  10. Helps you design for robustness. Don’t leave room for error where you can prevent it — Bloch gives many techniques for making correct use happen naturally.
  11. Is scientifically up-to-date: Doesn’t call Pluto a planet (p.149) : )

The Bad

  1. Often doesn’t take testability into account. This is my number one gripe with the book.  Examples:
    • Item 13, “Minimize the accessibility of classes and members”, doesn’t address how its advice interacts with making a class unit testable.  In practice, there tends to be some tension between minimized accessibility and full testability.
    • Item 17, “Design and document for inheritance or else prohibit it”, similarly recommends marking classes final when they’re not designed for inheritance.  If you follow this advice naively, though, you could be setting up your code to be untestable (see the section in Michael Feathers’ Working Effectively with Legacy Code chapter 10, titled “The Case of the ‘Helpful’ Language Feature”).  Bloch does mention in passing an alternative that “provides the flexibility to use subclasses internally” (p.91), so if you have your testability goggles on that could point you in a helpful direction.
    • Item 60, “Favor the use of standard exceptions” – but it can be quite helpful to extend the standard exceptions so that test code can be certain that when an exception occurs, it was thrown by the place the test is testing.
  2. Sometimes bogs down in the details. Examples are Item 11 on cloning and Item 30 on enums, both of these being several pages longer than their sibling Items.  There were maybe five such extra long Items.
  3. Lacks numbered subheadings under Items. The book makes do with bold text, but it would be more navigable if there were numbered subsections.  This is especially the case for the longer Items.
  4. Could benefit from flowchart diagrams. Several times near the end of a chapter there is a series of questions leading to a decision tree.  For example, on p. 180:

    If you answered no to the first question, ask yourself one more: Do I want to limit the use of this marker to elements of a particular interface, forever? If so, it makes sense to define the marker as a subinterface of that interface.  If you answered no to both questions, you should probably use a marker annotation.

    It takes effort to process this prose, and I would find it helpful if such conditional logic were presented in the form of some kind of flowchart-like diagram.

  5. Directing attitude. This is the flip side of “helps you design for robustness” — not uncommonly, in the quest to close the gaps where a class could be used improperly with poor results, Bloch’s advice is to prevent, guarantee, or force.  (An example of this type of advice is Item 58, where the recommendation is to use checked exceptions to force clients to deal with an exception.   I’m not sure this is A Good Thing.)

Overall

I’ve used the word “details” a lot in my descriptions.  Bloch gives you the details you need to use Java effectively.

By reading this book I became aware that there’s more to understand about Java than I realized.  There were several things I didn’t know I didn’t know — the caveats of serialization and cloning, for instance — and some things I knew I didn’t know (concurrency comes to mind)

My biggest concern is the lack of attention given to testability.  The reader who cares about testability is on their own to work through which advice can be taken at face value and which must be modified by testability concerns.

Still, I highly recommend this book.  Its imperfections are surmountable, and every professional Java developer should understand the issues it addresses.  Even in the cases where you  may not follow Bloch’s rules,  you will gain valuable understanding of the trade-offs you’re making; and you’ll avoid many costly mistakes.