VW ID.4: First Impressions

I hate stopping for gas.

That’s not the only reason that I’ve long wanted an electric vehicle, but it’s certainly one of the bigger ones. Yeah, the fact that they’re a lot cheaper to run is nice. Avoiding polluting is nice. One pedal driving is fun. But mostly…I hate stopping for gas.

In 2016 I drove a Tesla Model S and I loved it. A few years later I drove the Model X (I didn’t love it as much). In 2022 I drove an Ioniq 5 and tried to buy one, but you just couldn’t get them anywhere.

Choosing a vehicle

When we needed a new vehicle this year, I was set on an EV. I test drove a Volkswagon ID.4, a Chevy Bolt EUV, and a Kia Niro, in addition to pricing the Hyundai Ioniq 5 and Toyota BZ4x.

People always mention the tight turning radius of the ID.4, and I liked that. I liked the handling on both it and the Niro. I spoke with another employee where I work who has the ID.4 and he said it was the best car he’s driven (although he hates the software). Due to a need to keep payments down and in the hopes that battery technology will improve over the next few years (I’d really like to have a 350 mile range to make road trips easier), I decided on a two-year lease of the base model.

Running the numbers

VW was advertising $299/month leases with nothing down, although once you add in taxes, fees, and the fact that the car will have some options, it ends up being closer to $400/month. With incentives, the purchase price would have been around $30k.

The ID.4 is almost identical in size and weight to what I was previously driving (a 2012 Toyota Highlander), but since those have gotten a foot larger in the last decade, I’ll instead compare it to a Toyota Rav4, which costs slightly more to lease than the ID.4, costs slightly less for the base model (around $29k), and has almost the same length and width (to within half an inch).

In the three weeks I’ve had the ID.4, I’ve driven about 900 miles. Depending on which (non-hybrid) version of the Rav4 you get, it gets 28-30 miles to the gallon, so we’ll call it 30, which means that would be 30 gallons of gas. Gas in my area goes for $3.39, so that’s just over a hundred dollars’ worth of gas.

I’ve averaged 3.9 miles to the kWh over that 900 miles, so that’s 231 kWh of electricity. Electricity here is just over 17 cents per kWh, so the charging would have cost $39.84 – 60% off the price of gas! I say would have, because the power company pays me less than 4.4 cents per kWh for the excess power generated by my solar panels, so my actual cost for that electricity was about $10 and I saved about $30/week compared to gas.

Charging and range

The base trim on the ID.4 has a range of about 200 miles, but normally I’m driving around 30 miles/day during the week. Plugging into a 120v outlet recharges the vehicle at a rate of about 4 miles per hour, so I can just plug in when I get home and the battery is recharged before I leave in the morning.

If we had a 240v outlet in the garage, I could charge a lot faster, but it hasn’t been enough of a priority to bother with yet. I did have one Sunday when I drove over a hundred miles in the car and didn’t want to wait a few days for the battery to be back to its usual level of charge, so I plugged in to a public level 2 charger while my kid and I were at the library and paid $1.27 to get 9.5 kWh (or 35+ miles of range).

Ideally, when I purchase an EV I would prefer 350 miles of range just because that would be convenient for road trips; you generally like to keep it at between 20% and 80% battery, which would mean driving about 210 miles between charges, or about three hours on the freeway. Right now most offerings are in the 200-300 mile range, but I’m expecting several 400-mile-plus options to become available in the next few years.

But since this is intended to be my daily driver, not our road trip car – we’ll still want to use the larger Sienna for that – the smaller range has been fine.

And plugging it in when I get home is so much less annoying than having to stop for gas.

Driving experience

When it comes to actually driving the car, I have few complaints. The ID.4 doesn’t have full one pedal driving and requires an extra step to even activate the regenerative breaking, so most of the time I end up not using that and just driving it the same way I would an ICE vehicle.

The voice controls have been hit or miss (mostly miss) for me, so I largely just control everything with the buttons. The extra large display is really nice for the backup camera. I have lane assist turned on, and it’ll nudge the steering wheel slightly if it thinks I’m too close to the edge of the lane.

I had one incident recently when I was pulling into a parking spot and the car just stopped. I knew I hadn’t hit anything, so I figured something must have triggered the automated brake; getting out, I realized the car had decided I was too close to a hitch that was sticking out from the truck in front of me. So that’s a nice safety feature.

You can use either the built in navigation or your phone with carplay/android auto. If you’re using the built in navigation, there’s a subtle LED light strip under the windshield that indicates when it’s time to turn. The software isn’t perfect – for example, I’d like the option to just save the location I’m currently at rather than searching the address first – but based on what I’ve heard about older versions of the car, it must have improved a lot for the 2024 models.

Overall – with the exception of when I’ve needed the extra space in the Sienna (sometimes you really do want a van) to haul things that wouldn’t fit in the ID.4, I haven’t chosen to drive our other vehicles since I got this one.

From a passenger perspective, when we drove the Ioniq 5 the front passenger seat felt a little cramped to me and I don’t notice that here. My daughter tells me that the backseat is roomier than the Highlander’s. It doesn’t have as many cupholders as I’d like, but you can get a third party attachment that fits into an open slot to add more.

Overall impressions

Overall, I’m pretty happy with the vehicle so far. Obviously, when the lease is up I’ll be looking at all the options for what’s available, but at this point I could very well see purchasing a 2026 ID.4 in two years.

Hopefully the Pro version with the massaging seats.

On Writing Books

This month I published the second volume of A Programmer’s Guide to Computer Science. One thing I’ve been asked is: why write books?

Four or five years ago, I was looking for a side project and I asked myself, what makes me unique? What can I do that doesn’t have a million other people trying to do the same thing? A number of items in my background pointed to writing a book as a likely option:

  • I used to write regularly for Scrye magazine, so I already know that I can write nonfiction.
  • My last full time job before becoming a programmer was as a math textbook editor.
  • I work as a senior software developer and have managed projects involving multiple programmers.
  • I have a PhD in computer science.
  • I enjoy teaching, but I was often unhappy with the available textbook options for the classes I taught.
  • I’ve previously published short ebooks (most notably, Healthcare in the 21st Century), so I have experience navigating Amazon’s system.
  • I’ve spoken at several conferences on computer science topics (sorting algorithms, graph theory) and seen that there are a number of programmers interested in learning these topics.

So writing a computer science textbook seemed like a good way to utilize my background and do some teaching (I do miss teaching), while also being completely separate from my day job (meaning there’s zero chance I run afoul of the non-compete clause in my contract).

I’ve advised a few people on the book writing and publishing process lately, so I thought I’d put some of that down in my blog. I want to call out that this post is not going to cover marketing your book, which is an entirely different subject altogether. You can write the best book in the world, but unless you can find a way to get it in front of people, nobody is going to purchase it.

Also, the steps below are for books that I self-published. I’ve considered traditional publishing, but chose to self-publish my books for three reasons:

  1. I keep more control over the process.
  2. I keep more of the earnings.
  3. Turnaround is faster; once the book is written and edited, it’s available for sale almost immediately.

That said, volume 1 has been translated into Russian by a traditional publisher and I may choose to work with one in the future if I have a book that I feel would be appropriate for them.

Write

I will assume that you already know how to write, and have a topic in mind that you want to write about. You can use any writing software you like, but be aware that you may need to convert it to an acceptable format.

I wrote the Programmer’s Guide books in LaTeX, for several reasons:

  • I can use tikzpicture to generate graphs.
  • I really hate trying to typeset formulas in Word.
  • I really like how the finished product looks.

That said, creating the ebooks afterwards was a major pain. I can compile directly to PDF for the print book, but getting the content into something that could be used for a reflowable ebook was difficult. (A reflowable ebook is one where the page can be resized and the content will be rearranged appropriately, so the same book will look fine on a paperback-sized ereader or a full-sized tablet. PDF is an image format and is very much not reflowable). There are plugins to compile .tex files to html or import into Word, but I found that they did not work well with the complex documents I was creating. For volume 1 I created the html file, then manually fixed everything that didn’t get set up correctly before using Amazon’s software to create the .mobi file. For volume 2, I used Adobe Acrobat to create a Word file from the PDF, then loaded that Word file into Vellum and used it to create the ebook. In both cases, a lot of cleanup was required. (The second method did result in a nicer book, and I’ll be redoing the volume 1 ebook when I get a chance).

For future books that don’t depend on creating graphs and formulas, I’ll probably just use Scrivener or Word and avoid the whole problem. (Added bonus: spellcheck! I don’t have spellcheck functionality in LaTeX). I may consider still typesetting the print book in LaTeX after it’s all done, since I really do like the output, but I’ll probably give the print functionality in Vellum a shot first.

In between writing and editing, I’ll also be getting graphics made. Many of them I can do myself in LaTeX, but the cover and some images I outsource to a professional graphic designer (fortunately for me, I happen to be married to one).

Edit

I’ve always been a pretty clean writer; my first drafts are pretty close to most people’s final drafts. It doesn’t matter; your work needs to be edited. Preferably, it needs to be edited by somebody who is not you. It’s entirely too easy to read what you meant instead of what you actually wrote. When that’s not possible, at least put the work aside for a while so you can forget what you wrote, then read it in a different medium. For the last book I wrote, my process was:

  1. Write the chapter.
  2. Put it aside for a bit
  3. Print it out and edit the printout.
  4. Repeat step 3 until I stop finding errors. (Remember I used to be an editor)
  5. Send it to my technical editor. Make changes based on his feedback.
  6. Send it to my copy editor. Make changes based on her feedback.
  7. Convert to an ebook. Fix anything that Word, Vellum, or Amazon’s processing software flags.
  8. Read on my Kindle. Fix anything that looks off there.
  9. Publish!

As you can see, the entire process is somewhat involved. I don’t always go to this much trouble – my science fiction, which I publish under a pen name, I don’t even have an outside editor for – but for technical material in particular I really want to make sure that everything is correct. Self-published books have had a bad reputation due to being rushed out without proper editing, and I aim to have mine be as good or better than anything that’s traditionally published.

Publish

Now it’s time to publish! This is actually the easiest part of the process.

If you already have an Amazon account, you can go to kdp.amazon.com and log in. Making your book available for sale is a simple matter of filling out a three-page form and then waiting a few days for it to be approved. Here you’ll need to know things like your price, whether you want your ebook to be enrolled in Kindle Unlimited, etc. If it’s your first time, you’ll probably spend a while figuring out the best options for your book.

Amazon is the big dog in book publishing, but not the only one. I want my paperbacks to be available from places that don’t want to purchase from Amazon, and I also want hardcovers, which aren’t available from Amazon. So my books are also printed at Ingram Spark. Unlike Amazon, which is free to publish with, Ingram charges a setup fee (and a change fee if you need to make updates later) but you can generally find coupons; I have not yet paid Ingram anything except printing and shipping fees. There are also other places to sell ebooks, including Apple and Kobo. Figuring out your publishing strategy is outside the scope of this article.

Objects, Inheritance, and X-Wings

Not too long ago, a friend who has only done procedural programming asked me to explain object-oriented programming. Today it occurred to me that it might be fun to explain objects in terms of the X-Wing Miniatures Game. [Obligatory disclaimer: this game is owned by Fantasy Flight. I have no rights to it and use it solely because I thought it would be a fun example. Rules may be simplified.]

In the X-Wing Miniatures game, players send fleets of ships against each other until one side is destroyed. Each ship is, naturally, a physical object that we can model with a logical object. How can we do that efficiently?

Base class: Ship

There are certain properties that are common across all ships, regardless of their physical aspects. Each ship has a name and a physical location in space. It has an attack value (how much damage it could potentially do), an agility value (how quickly it can maneuver), and a hull value (how many hits it can take before it is destroyed). It may or may not have shields. We can’t actually play a generic ship; this is just our common attributes. In our code, we can create the Ship class as an abstract class, which can be inherited from (we can have other classes that “are” Ships) but not instantiated (we can’t just create a Ship).

Subclass: Small, Medium, or Large Ship

A given ship may be small, medium, or large. While a small ship and a medium ship each have all the attributes of the generic Ship class, they use different size bases (plastic bases, not to be confused with the base class) and follow slightly different rules.

Two plastic squares, one larger than the other, on top of a playmat.
Abstract classes cannot be instantiated; they only form the base for the concrete class to be used later.

These will also be abstract classes; we can’t actually fly a copy of SmallShip.

Object: The actual ship

When we instantiate an object, we create it in memory and provide values for its required attributes. For example, suppose we wish to instantiate a T-65 X-wing fighter. We create an XWing class which inherits from SmallShip (and thus indirectly inherits from Ship). The constructor sets the ship name (T-65 X-wing) and attributes (3 attack, 2 agility, 4 hull, 2 shields). We also need to assign a pilot to fly the ship, so we’ll instantiate an instance of Jek Porkins (a Pilot object) and associate it with the XWing object.

Jek needs some support, so we’ll instantiate a second XWing object and associate it with a Luke Skywalker Pilot object. The two X-wings were instantiated from the same class and have identical properties (although the pilots will use them in different ways) but they are different objects; what happens to one does not necessarily affect the other.

 

Four small ships (2 TIE fights, an X-wing, and a Y-wing) prepare to engage in battle over the Death Star.
Concrete classes can be instantiated, giving us objects we can manipulate. Here we have four ship objects, two of which are instantiations of the TIEFighter class.

Using the objects

Now that we’ve instantiated our fleet, we’re ready to send it out to battle some TIE fighters! The Ship class has Move as an abstract method; each of the concrete classes that inherits from Ship must implement this method. We’re in a hurry to blow up some TIEs, so we’ll call xwing1.Move(3) and xwing2.Move(4) to send our small fleet straight ahead into battle. If a pair of TIE fighters zero in on Jek and do four damage, his shields will be wiped out and his hull reduced to two. This doesn’t immediately affect Luke’s X-wing, but he’d better get over there and help…

tldr

With object-oriented programming, we model the system as a collection of objects, each of which has properties (hull, agility) and methods (move, attack). Each object is responsible for keeping track of its own state, freeing the programmer from keeping track of it in an external data structure. A class that inherits from another class “is a” thing of that class. In our X-wing example, an X-wing and a Lambda-class shuttle may have different implementations of the Move() method, but because they are both Ships, we can call any method defined on the Ship class and get the actual method implemented on the associated class. Thus, we can have a function which takes a Ship as a parameter and calls ship.MoveSlowly(), and we can pass that function any object which is instantiated from a class that derives from Ship; we don’t need a separate function for X-wings and TIE fighters (or even for SmallShips and MediumShips).

Now go blow up some TIEs.

Difficult for Us, Easy for Them

Suppose you’re working on a complex piece of software with a due date that’s coming up fast. At the last minute, someone realizes that several of the help text popups contain typos. Is it worth fixing?

One thing I’ve noticed – and this is true in general, not just in software – is that a lot of people (and businesses) just don’t really care about what they might see as “little things” like this. I’ve lost count of how many times I’ve seen misplaced apostrophes or quotation marks on business materials, even for large chain stores that presumably can afford graphic designers and proofreaders.

The argument for ignoring the “little things” is simple: most people probably won’t notice or care. I would argue, however, that taking the time to fix even a minor misspelling or grammatical error is worthwhile, for several reasons.

By flickr user volkspider. Used under creative commons license.

The obvious one is professionalism. All of the written content you put out is part of how you present yourself. When a business cuts corners on proofreading, I have to wonder what else they cut corners on. This seems particularly relevant in a field like software development where attention to detail can be extremely important.

Possibly more important, though, is the effect that sloppy writing can have on the ability of your customers to use your software. The amount of attention customers have is limited. Any little bit of that that’s being used up on understanding a poorly written prompt is attention that’s focused on your application instead of on the task the customer is attempting to complete.

This is one small element of a larger topic: keeping the software out of the way of the user. Ideally, when the user is attempting to accomplish a task with your software, the software should be intuitive and require minimal thought to use. If I’m creating a document in Word and I’m not using any special formatting, I don’t have to think about how to use the program; my attention is all on what I’m writing. Anytime I have to actually pay attention to the software – if, for example, I’m trying to typeset mathematics (in which case, yes, I really should be using LaTex) – it’s going to lower my productivity.

When designing and developing software, it’s worth asking: what are the pain points going to be for the user? Is it possible to smooth out those points, making the software simpler from an end user perspective even if that makes it more complicated behind the scenes?

We get paid to deal with complexity. Part of that complexity is figuring out how to make things as easy as possible for our users.

MVVM and MVC

Those of us who have been putting together websites for a long while will remember back when everything was included in the .html (or even .htm) file. Eventually this was replaced by a separation of concerns – content in the .html file, behavior in the .js file, appearance in the .css file.

We can see a similar separation for a web application, where we keep the data itself in one file and behaviors that interact with that data in another file (or several files). This makes the application easier to test and maintain.

For example, suppose that we are writing an application which deals with customers. Using the MVVM (Model-View-View Model) or MVC (Model-View-Controller) pattern, the model itself holds information about the customer – name, address, and so forth. It may optionally contain methods for manipulating and validating the properties it holds. This is the back end of the website; the structure of the data can be developed without needing to know anything about the user interface.

The view is the user interface – in a web application this is the .ascx page that the user interacts with. In MVVM, the view knows about the model and view model; it may have bindings to properties on the model and may call functionality on the view model to manipulate the model. Given information about what data will be available in the model, the UI can be designed independently.

The View Model (in MVVM) or Controller (in MVC) is what ties the view and the model together. When the user attempts to do something in the view, it will actually call functionality on the view model or controller rather than manipulating the model directly.

In MVC, the controller sends commands to the model to update the state of the data and also sends commands to the view to change the presentation. In MVVM, the view model is essentially an abstraction of the view through which the view is bound to the model. Rather than using a reference to the view to communicate with it, as a controller does, the view model updates properties which the view is bound to. A view will be paired with exactly one view model.

A single model may have multiple views that display and (through the view model or controller) manipulate the model in different ways. The model doesn’t know about any of the views; it simply exposes the appropriate properties (possibly setting limits on how they can be manipulated).

Understanding these patterns makes it easier to see where a given property or method should be located. Something which is always loaded from the database in the same way regardless of which view is in use will be found on the model, as will (usually) the validators for that information. Methods which are view-specific – for example, security checks to verify whether the user of the view has the right to manipulate a given piece of data – are found on the view model. The view itself doesn’t contain data, but displays the contents of the model (and possibly additional content from the view model) to the user.

No comment?

I was listening to a podcast recently and one of the hosts made a comment that I’ve heard before. “There are two types of comments – lying and useless.”

For the most part, it’s a fair point. When people comment for the sake of commenting, we end up with useless comments – those that simply repeat the obvious. In the following example, the comment doesn’t add to the user’s understanding and in fact makes the code harder to read:

DateTime admissionDate = new DateTime(year, month, day); // a date

In this case, because the variable is descriptively named, the code is self-documenting; the urge to comment here would suggest that the variable name needs to be updated.

Similarly, a comment that describes how a function works is in danger of becoming outdated the next time the function is updated, if the developer doesn’t notice and update the comment as well. This leads to confusion as the comment no longer accurately describes the functionality. In this case, it’s worth looking at whether we can refactor the code to be more clear so that it doesn’t need a comment.

What I take issue with is the suggestion that these are the only kinds of comments; I actually find comments to be useful in a variety of situations. Here are some times I use comments:

  • Explaining the why
    • For a while, I had an extra line of code that worked around an outstanding issue I needed another team to fix. A comment explained why the line was there and when it could be removed (with a link to the issue that needed to be fixed)
  • XML comments
    • I wrote a function recently where a particular option should be used only in certain situations, where it didn’t make sense to include the entire situation in the variable name. An XML comment on the function helped make sure it was used correctly; the next time I referred to it the intellisense helped me set the parameters correctly.
  • SVN comments
    • This one might be cheating a bit, since it’s not strictly a code comment…but when trying to find one particular change among many commits (when I don’t know exactly where the change is), having descriptive svn comments is a huge help.

Self-documenting code (in particular, good naming) and version control (no need to leave large blocks of code commented out when you can simply retrieve them later if needed) greatly reduce the need for comments, but don’t remove it entirely. Your code should show intent – that is, what you want to do. Let your comments show motivation – why you’re doing it.

Analysis of a Difficult Project

In the eight years that I’ve been a software developer, I’ve had my share of difficult projects.

Early on, the difficulty might have been because I was new to development and new to the code base. I had to learn my team’s conventions and how to use our internal tools.

Recently, however, I had my most stressful project so far. The initial development seemed to go well enough, but getting the quality to where it needed to be took much, much longer than anticipated. I’m now taking the opportunity to reflect on what went wrong, so I can avoid making the same mistakes in the future.

Project Summary

In this project, I was taking some legacy code and rewriting it to be web-based. I’ve probably done this ten times before, but this was one of our most complicated activities. It was also one of my first projects since we switched to a quarterly release cycle, which meant more pressure from deadlines.

I won’t go into more detail than that, except to say that due to the nature of my job, the quality of released code has to be very, very high. The possibility of a data integrity error – either from a programming mistake or because the user is confused – is simply not acceptable.

Design

Part of our process is to have a design for each new piece of development, describing what we’re going to do and why. This is partially so that we can discover issues early on – much better for someone to realize that what we’re going to do won’t work before we start coding than after we’re finished – and partially so we have a record we can refer back to later if we’re not sure why we did something the way we did.

For this type of project – migrating legacy code to web – the assumption is that the functionality of the new activity will be the same as that of the old one, with the exception of changes that are explicitly called out. Usually, just listing out the changes is sufficient. In this case, however, because the activity is so complex, nobody on the team was familiar with all of it. This led to two issues:

  1. The quality assurance (QA) people reviewing the design weren’t fully familiar with the functionality, so they didn’t realize that there were changes they would like until they started testing the completed development. At that point, it was a lot more difficult to make the changes than it would have been if they had been brought up during the design. If the existing behavior had been fully spelled out in the design it would have been easier to catch changes we needed to make.
  2. Part of functional testing involved performing the same workflows in the old and new activities and ensuring that the functionality matched except where called out in the design. Since we didn’t have a complete list of functionality, testing was more difficult.

Development

The original project plan called for 300 hours of development.

However, this project was not the only thing on my plate, and I was assigned a lot of other work that kept pushing it back. At the same time, I was under pressure to get it done so we could keep making progress towards getting rid of our legacy code.

As a result, I pushed harder than I should have, finishing the initial development in just over 100 hours. That put me way ahead of schedule, development-time-wise (if not by the calendar) but with three big problems:

  • I barely had any unit tests. What I did have covered only a small fraction of the code.
  • I hadn’t done enough manual testing to ensure everything worked as anticipated.
  • I didn’t have a complete description of how the activity was supposed to work, so the new activity had less than 100% functionality.

Testing

As I mentioned above, we have very high quality standards, and as such every piece of new development has to undergo inspection by multiple people. This would normally mean that two other developers would review my code and two QAers would test it. Due to the complexity involved, we actually ended up with three QAers assigned to test and two unscripted testing sessions when additional QAers tried out the activity. We also had usability sessions when nontechnical people came in and tried out the new functionality.

The lack of unit tests hit me again at this stage. When doing a fix, it was difficult to ensure that I wasn’t causing any new issues – and we were still pushing hard to meet (new) deadlines. As a result, in the first round of code review and QA, we ended up with a fair number of new issues created by fixing the old ones.

Towards the end of the first round of testing, we were still finding differences between the old and new activities – an indicator that we really needed to have a detailed written description of exactly how everything worked.

Conclusion

This was a project in which it seemed that everything which could go wrong, did. Requirements kept changing – both technological and functional. We were constantly brushing up against (and shooting past) deadlines. Getting the quality up to expectations took much longer than anticipated.

We did have some wins. From a usability perspective, the new activity is much better than the old one, and the users who participated in usability testing were excited to see the improvements. Accessibility – which presented its own challenges – is also much improved. The process worked – while it took a long time to make the code stable, it was never in danger of being released to end users before the quality was where it needed to be.

For future projects, my takeaways were:

  • Take the time to make the design as detailed as it needs to be – even if that means (as it would have in this case) spending an extra week on it. It’ll pay off in the long run.
  • Test, test, test. An extra two-four weeks up front writing unit tests and doing manual testing would have easily paid for itself in the long run. I’ve been pushing unit tests for a while and I’m now getting buy-in for spending the extra time required.
  • Given unrealistic deadlines, push back. I have a reputation for fixing problems quickly, especially when it’s a high-priority bug, but in this case I was simply being assigned too much work and I should have said so instead of trying to get everything done. Not pushing back enough left me stressed out as I struggled to finish everything, and quality suffered – which meant taking more time to ensure that the code was in the state it needed to be in.

I have many more projects like this to take care of over the next year (although this was the most complex). I’ll make things a lot less stressful on myself by insisting on following our best practices, even if it takes more time up front. And now I have an updated list of possible bugs to watch for in the future.

This was definitely a learning opportunity. Here’s to being better.

Instant Family

Last week I finally got around to seeing Instant Family.

If you’re not familiar with the movie, it follows a childless couple who decide to adopt out of foster care. As expected, crazy hijinks ensue.

I have to say that I enjoyed the movie quite a bit. It has a lot of humor, while still (pretty) accurately representing what it’s like to be a foster parent.

One thing to be aware of is that this movie is definitely from the foster parent perspective; it’s about how the foster parents fight through the process and (of course) come to learn that their kids are what was missing from their lives. If it was written from the foster child perspective it would be a very different (and probably much less funny) movie. From the perspective of the parents, their lives are being turned upside down because they now have three kids with behaviors that they aren’t prepared for and can’t control. From the perspective of the kids, their lives are turned upside down because they’ve been moved to a new home and don’t know what’s going to happen to them; almost everything in their lives is outside of their control.

I don’t know if I would show this movie to (especially younger) foster kids – as I said, it’s not aimed at them and could be upsetting – but for people considering adoption from the foster care system, or just enjoy a good movie, I highly recommend it.

On Writing

I’ve been working on a technical book for several years now.

Partially, this is because I have a million things to do (coincidentally, my son just turned two). Partially this is because I’m a slow writer. And partially…it’s because writing is hard! Here are a few things to improve the process:

  • Don’t write technical material in Word. Seriously, just don’t. Fortunately I learned this one many years ago – I used to type up my homework for my Algorithms class (due to my lousy handwriting) and it didn’t want long to determine that the effort to figure out LaTeX was less than the effort to get mathy things to work correctly in Word.
  • Once you’ve written something, leave it along for a while and then print it out to proofread it. It’s amazing how many typos you can find once you’re looking at something in a different format and state of mind and can read what you wrote rather than what you meant to write.
  • If at all possible, have somebody else read your work. Sentences that make complete sense to you might not work for someone else. If possible, get a reader who belongs to your target audience and can confirm that you’re not assuming background knowledge or ability that your readers won’t have.
  • Don’t assume you know what your readers want. In my case, I was expecting to write a 400-page book; I was told by multiple people that I should break it up into multiple shorter volumes. Bonus: the first one will be ready a lot sooner!
  • Don’t assume you have to make every change your beta reader suggests. Take their suggestions seriously, but remember, it’s your book – you’re in charge!

You don’t have to be the world’s top expert on something to write a book about it; you just need to have something to say or a way to say it that’s different from what’s been done before. In my case, I have a PhD in computer science and experience as a teacher, a textbook editor, a writer, and a software developer – so writing a book about computer science for software developers seemed like a good way to combine all of those elements. What does your background make you uniquely suited to do?

Doing big things

Fans of Marvel movies know to wait around until the end of the credits to see the extra scene. This adds a bit of time to the theater experience, as the credits go on for quite some time; it takes hundreds of people to make a movie on that scale.

At work, I’m one of a dozen developers on my team and one of several thousand developers in the company. While each team largely sets its own policies, there are some general standards for consistency across the company.

Even relatively small side projects tend to involve several people. I’m currently finishing a small computer science textbook that I’ve been working on for the last few years. Even though I have a PhD, work experience in both writing and editing, and a tendency to do everything myself, my book still has a technical editor, a copy editor, and a graphic designer. I could certainly finish the book without any of those people, but they’ll help me to make it as good as it can be.

In short, any project of significant complexity, even if it’s small enough to be done by one person, will benefit from having multiple sets of eyes. When multiple people are working on the same content, however, it’s important to have standards for consistency and for resolving disagreements. Sometimes this means there’s one person in charge – the director, the lead developer, the author – who makes decisions that the rest of the team will follow. Sometimes it’s a collaborative process. But consistency is key.

What are some things to do to help ensure that your projects are successful?

1. Save frequently and use version control.
Not too long ago, I needed to retrieve some code that had been deleted by another developer who had left the company over a year before. Although the code never made it to production, I was still able to retrieve it from svn, which saved me dozens of hours of work.

1a. Make small commits with good comments.
In the past, my habit was to save when I finished a chunk of development or at the end of the day, whichever came first. That meant that even if a disaster occurred I wouldn’t lose more than a day’s work, but it also meant that my svn commits while working on a project tended to be rather large and contain a number of fixes, making it more difficult to locate a specific change. Now, I generally commit (with a descriptive svn comment) every time I fix one bug or add one new feature. The primary reason for this is so that when I go on to the next change, if I screw it up it’s easy to roll back to the last stable state without losing any of my previous work, but it will also make it easier for any future developer (including future me) to find a specific fix if needed.

1b. Delete commented-out code.
I’m not opposed to comments – I’m in the school that believes that what the code is doing should generally be clear from reading it, but comments are useful to explain why the code is doing what it’s doing and document any assumptions. When working it’s easy to comment out sections of code for testing or because they’re not currently needed, but leaving those in afterwards clutters up the code and makes it more difficult to tell if something should have been turned back on. Version control means not needing to keep commented-out code. Just delete it – it can be restored if it’s needed again in the future.

2. Have consistent standards.
There are a lot of areas where there are multiple ways to do something and it doesn’t really matter which one you pick, but being consistent in your choice makes things easier. For example, my team consistently puts the list of properties for a class at the bottom of that class; while it’s easy enough to use F12 to jump to a given property definition, having all the properties together in the same place in each class makes it easier to look through them when needed, without having to think about it.

3. Use good names.
Few things result in as much unneeded mental effort as deciphering code with unclear or misleading variable names. I’ve certainly had instances where towards the beginning of a decent-sized project I’ve given two properties similar names and by the end I’m having trouble remembering which is which. If it’s not clear what information a variable or property is holding, then the name needs to be updated! Similarly, function names should accurately describe what the function does.

4. Test everything that needs to be tested.
What I’ve struggled with the most as a developer is making sure to test all the things that could possibly go wrong with my code. Unit tests can do a big chunk of the actual testing, but the developer still needs to come up with the test cases. This can be a challenge because as the developer you (hopefully) understand how the code is supposed to work, so you use it correctly. Take the time to figure out all the logic-impaired things your users might do and try those also.

5. Understand the desired outcome.
When I’ve had development that’s gone way over the expected timelines, it’s been because requirements have changed repeatedly over the course of writing the code. While that is sometimes unavoidable, do try to minimize it as much as possible for larger projects by writing a reasonably complete design document and getting buy-in from the relevant people before you start development. Sometimes you even get lucky; I’ve had projects end up becoming much less complex before I ever started coding, because my initial design was more complicated than it needed to be and my design reviewers were able to point out a better way to accomplish the same task. Aside from getting buy-in from key people, a good design helps you be sure that you understand the requirements, which makes it easier to implement them correctly.

It’s always worthwhile to make things easier for the next person who will look at your code. Very often, that person is you.