Making Code Reviews Practical

Let me preface this by saying I'm not a code review expert.  I just happen to have experienced everything from a very formal code review meeting to a very informal peer-review system.  And I like code reviews.  No, I love them.  They really do help produce better code overall, and also help developers familiarize themselves with the code.  Done properly, it will end up saving the company significant amounts of money and developer time by fixing errors before they make it into production.

So, here's what I've seen.  Formal reviews that are checklists and formal meetings are time consuming, but are also very thorough--something that's helpful when you have a detailed set of requirements.  Slightly less formal peer audits can be useful, but there are a few problems I've noticed.  First of all, depending on who reviews the code, different issues tend to be caught.  Theoretically, everyone should be working out of the same guidelines, but different reviewers pick up different things.  That's human nature.  Also, one book on developing code review standards made a very good point: don't sweat the small stuff. Depending on the circumstances, "small stuff" may have different meanings to different people.  For one person, spaces vs. tabs may not be relevant, for others, maybe it's eliminating the requirement for Hungarian notation.  In either case, you need to figure out what works well for you.

Now, here are some of the problems I've seen: the fact that reviews are completed by different people means some people will review a change and approve it with no comments, where others will pick the code to the point where there's nothing left.  Even more amusingly are getting comments that are completely unhelpful or wrong on working code, while other code is being checked in that won't even compile.  This all boils down to the absence of one particularly vital role: the moderator.  The moderator is an independent third party whose job it is to check the comments, ensure they are all applicable, and also ensure all concerns are properly addressed before the review passes.  By placing all the power in a single reviewer, you have destroyed the system of checks and balances that would exist otherwise.  If the reviewer doesn't like your code for some reason, sorry, but not today.

The most effective system I have seen so far was a rather informal system using Atlassian Crucible (yes, I really was pleased with their product), but where reviewers were randomly assigned to the review.  Then, a few of the reviewers (a minimum of two) would look over for defects and suggestions.  Only defects (such as security issues or gross violations of the standards) needed to be corrected, and suggestions for improvement were left up to the discretion of the programmer.  A moderator would observe the comments, decide on which ones were actually necessary to fix, and overall steer the discussion in productive ways.  After reaching the minimum number of reviews, the review would be closed with a simple pass/fail status, and re-review would be required for failed status.  The moderator would then ensure all comments were appropriately addressed in future reviews.

Basically, using this method, reviews were both fast and simple, and didn't waste a large amount of time.  At the same time, the comments out of a review were, on the whole, helpful, and provided a forum for a developer to make their point if they disagreed with some of the comments.  Take this for what you will, but I have found moderated informal pass-arounds to be the most effective reviews.

Two-Factor Auth with pam_google_authenticator

So, this is something pretty spiffy, and a lot of people have set it up already, provided nice walkthroughs, etc.  Since there are many good walkthroughs already (like here or here), I won't go into too much detail.  It's stunningly simple to set up, if you don't mind manually pulling the module's source out of version control and building it yourself.


But, one thing struck me as necessary.  I have users that don't use two-factor auth right now, and they may not want to.  So, how can I make this optional?  Well, PAM makes this pretty painless, although it's not built into the module itself:
auth    [default=ignore success=1]      pam_succeed_if.so quiet user notingroup secure
auth    required        pam_google_authenticator.so

That's it.  Basically, you have a group "secure," that if users are in, they will be required to use two-factor auth.  The way it works is by skipping the following rule if users are not in the "secure" group, but ignoring the result of pamsucceedif if they are.  Otherwise, they aren't.  Get it?  Now, this does mean that users need to be manually added to this group in order to be graced with two-factor authentication, but it's still better than nothing.  If you're curious about a related enhancement, this bug report details some additional thoughts on transitioning to two-factor auth.

Why People Suck at Driving

This shouldn't be a revelation.  But in some senses, it is.  I've noticed a few trends driving here in the winter.

  1. Oh shit, white stuff? (And no, not cocaine, kids.)  Really.  The moment this mysterious "white stuff" appears, people's brains immediately fly out the window, and traffic comes to a grinding halt.  The roads could be perfectly fine, but it doesn't matter.  Top speeds are 45MPH in a 70.
  2. We don't need no stinkin' brakes! Shortly after the snow has been on the ground, people immediately believe the roads will have magically improved.  It could be 1 minute or 1 day after the plows go through, but immediately speeds are back up to and BEYOND the speed limit.  All this occurs when there is still visible ice on the roads, so any attempt to stop at those speeds would be an exercise in futility.  Also, it follows that extreme tailgating becomes a popular passtime in this phase.
  3. Traction? What's that?  It really seems that the people committing offenses #1 and #2 are also the people least suited to be in a snowstorm.  That's right, giant SUVs and rear-wheel drive trucks.  Most trucks haven't even bothered to weight the bed with any type of snow, and it shows as they fishtail their way down the interstate.  Also, I see a surprising number of minivans and SUVs along the side of the road, in rather precarious positions from various spins.  I guess the pickups manage to find a way to pull themselves out.  Hurrah for that, at least.
Maybe it's just the county's elitist "I'm better than you, so get out of my way" attitude that is to blame, but really, I'm sick of it.  If you're going to drive like an idiot, please do it in the driveway of your mansion so you can kill yourself and not me.  Thanks.

Update: Another round of this stuff... and sure enough, wrecks immediately.  Always fun when you think, "hm, I think I'll turn here" and your car decides, "hm, no you won't."  But hey, I managed to control it and not cause any extra problems.  Also, remember kids, the (!) light is the "you're driving awesome" light.

Excess of the Electronics Industry?

So, it's fairly well known that boards that can be made for pennies on the dollar frequently go for ten times that amount, if not more.  To some extent, this is understandable, as a lot of engineering time and labor went into designing and producing the boards.  These costs are forgotten when you evaluate the parts cost per-board.  But, at what point is this excessive?

Just the other day, I was troubleshooting a relatively simple board.  A set of infrared LEDs and photodiodes, resistor network, some diodes and assorted resistors, a transistor, visible LED, and a single IC.  All in all, I would estimate the cost of the board at about $40, assuming you didn't want to mass-produce the PCBs and were silly enough to pay for them one-by-one.  The vendor, however (and they are quite reputable, too), wanted $120 for a replacement part.

The way the board had failed wasn't terribly uncommon--the output was essentially signaling that an IR beam was being broken at all times.  The manufacturer gives a relatively good troubleshooting guide for symptoms and their causes, and sure enough, this lined up with what the device was behaving like.  They also give a good set of schematics for the mainboard, but curiously enough, omit schematics for some of the subassemblies.  The troubleshooting guide stated something along the lines of, "If you see this condition, the sensor board is bad and should be replaced."  This was really fishy to me... no way would the entire board be bad.

I check all the photodiodes, and sure enough, they're all receiving the IR beam properly.  My next thought from tracing this very simplistic two-layer PCB was that either the IC or the transistor was dead.  The transistor seemed to be more related to driving the LED as a visual indicator, so I put my money on the IC.  Of course, without a parts list or schematic, determining what this IC was from the chip markings proved a little difficult.  After misreading one digit, I determined the part was an 8-channel Darlington sink array.  The logic diagram on the datasheet showed exactly what was going on: this was essentially being used as a giant NAND gate (really, more like a negative input logic OR, but who's counting?).  I place my order with an electronics supplier for a handful of this IC and the transistor and wait for them to show up.  Part cost for the IC?  $0.80/ea (for singles).  The transistor was even less.

Once the parts arrive, I go ahead and decide to swap the IC first.  After all, it's socketed, and sure beats desoldering the transistor on the board.  I go plug it into the unit for a quick test, and no LED lit.  Halfway there, so I break the beam, and the LED lights.  Yup.  Bad IC.  So, for $0.80 in parts, I fixed a board that the manufacturer wanted $120 for.  Yeah.  Totally makes sense why they wouldn't want to release schematics or parts list, huh?

In short, when electronics die, it's often not worth troubleshooting.  But if the device is simple and expensive enough, it's quite possible you may be able to beat the game and repair your device for far less than a replacement.  In this case, there was absolutely no actual hard work required: just diagramming the circuit used mentally and swapping a socketed IC.  Just look before you pitch something and start over.

Automated Lighting

So, as I mentioned earlier today, over the past few days, I had an idea to automate the lighting in my apartment.  After talking with some friends of mine, I finally decided on a rather simple implementation, wiring relays in parallel with the existing lightswitches (so all the lightswitches will continue to operate normally).  The relays aren't entirely necessary, since the MicroLogix PLC I'm using has relay outputs, but they do provide an extra layer of safety (not to mention all the signalling is low-voltage, 24vdc).  Relays themselves were squeezed into the electrical box where the switches are.  Also, all the contacts on the relay use crimp-on quick disconnects.

The ladder logic program I'm using is fairly simple: use timers to create a maximum length of time any light can be on, and also provide an automated mode where the lights cycle between on/off periods.  Inputs are wired like pushbuttons to toggle each light, as well as the manual/auto mode.  The whole thing works as expected, blinking lights and all.  Enjoy some pictures after the break.

Finally Done

Well, it's official.  I'm done with my undergraduate career--my official transcript and diploma arrived in the mail the other day.  Work starts Monday, so I'm looking forward to that.  Also got to spend some time working on a project around my apartment, so expect a post on that either later this evening or sometime over the weekend.  Pretty much been wrapping up as many loose ends as possible before work starts--still got more to do, but things are definitely moving along.

Triplog

So, a few weeks before I had to start work, I decided to take a week long road trip.  I wrote up some of my thoughts as I went, and others after the fact, and I will present them here.

day 0:
8 hours of driving, woot.  Aso, Indiana likes labeling phantom workzones.

day 1:
Holiday World -- where Christmas music can bug you year round!  Also, safety is a priority, and that's why we cross the tracks with the ride in operation (with auto-accept on, too)!
After I got bored of the three coasters, it was 8 hours of more driving. (Well, 7, plus losing an hour).
Arrived at Cedar Point with 10 minutes to spare.  Get to Top Thrill Dragster just in time.  Ride's out of order at that point, and from what I could gather, it had a failed launch.  So, I wait 15 minutes until they get it going again.  After getting off, the last train has empty seats, so I get a reride.  Sweet.  Hair blown back, and it's time for more sleep.

day 2:
Cedar Point -- one, owww, the sun is hot and causes a nasty case of sunburn.  I look something like a racoon, and I didn't even have sunglasses on.  First thing to do after walking back into my room was to strip down and take a cold shower.  All the rides were great--as it should be expected, Arrow Dynamics rides tend to cause the most headache, and all the Intamin rides provided the most fun to me--Dragster, Millenium Force, and as a real surprise, Maverick.  Okay, Maverick isn't smooth in the banked curves, and shakes you up pretty good, but it does it in a really fun way (and unlike Arrow, it's meant to).  Also, when I first arrived at the park and rode Raptor, I could've sworn I saw someone in the queue wearing a collar.  I thought that was funny, said to myself, "lol, furry," and brushed it off.  At the end of the night, just as I'm about to go to my last ride on Maverick, said guy stops and points at me, just saying "that shirt... FurAfinity?"  So, we get to talking, he's on his senior trip, and didn't expect to run into a furry at Cedar Point.  Quite frankly, I figured I might run into one or two (hence wearing the shirt), but didn't think I'd actually get to know any.  Really cool ending to the day, to say the least.  Up for tomorrow?  A long drive to Maryland ahead, then Six Flags Great Adventure and FA:U await.

day 3:
More endless driving.  This time, it comes with about $20 in tolls.  Wonderful, but I make it to Baltimore by dinnertime.  I figure I'm not terribly tired, so I see if I can move my hotel reservation forward a day in New Jersey, and decide to continue on with my friends in tow (RyuRabbit and Alukit).  We get there sometime around 10pm, with pretty chilly weather outside, and also happen to see some nice weather on the way.  Settled into the hotel room, it's time for sleep, as Six Flags is tomorrow.

day 4:
On to pick up another friend (Mex) and my sister (after getting lost in jughandle hell while trying to eat breakfast), we then make our way to Six Flags Great Adventure.  Overall impression of the day is, Great Adventure has the money for some pretty good rides, but has perhaps the worst management of any of the parks I've been to. For one, they prevent a friend from buying a $3 bottle of water because he can't show his driver's license (against Visa rules).  Also, getting squished while someone can't pass the metal detector which is IMMEDIATELY after the turnstyle was a bit uncomfortable.  That said, El Toro is a rather unusual (and fun) wooden roller coaster with pre-fabricated track--using the lift style of Millennium Force, too.  Also had some good B&M coasters (Batman, Bizarro, and Superman).  Of course, there's also Kingda Ka.  Rolling Thunder was perhaps the most painful of the day--despite being designed by the same people who built Screamin' Eagle (and a few years newer), it's in far worse shape.  Finish off the day with the wonderful Rai Rai Ramen #3 (on my sister's recommendation), and get back to the hotel late that evening.

day 5:
First day at FA:U.  I see a lot more of my friends--Nybble had already come down the previous night from NY for the day, also find BlakDrgn, Zero, and CrayWolf are all wandering around working.  I also find Bobskunk and say hello, and see CeriseWlf, but don't really say anything.  Also meet quite a few new people, including Voltage and V-Smok, and ultimately have a great time just hanging out.  I've been addicted to Wawa by this point, and figure I have to get my fix in before it's too late.  Concert and performance by Matthew Ebel and 2 Gryphon are both excellent (though something akin to what I had seen at FWA).  I also get a drink mixed from the wonderful bartender--he agrees to experiment and make a Baltimore Zoo, even though he's missing amaretto.  Doesn't turn out terribly bad, at least.

day 6:
Last day of the con, I get my Wawa fix in, and hang out with everyone until the absolute last minute.  We originally planned on staying until closing ceremonies, but after the ceremonies, I decide to grab a bite to eat with BlakDrgn and RyuRabbit, making the trek up north for one last stop at Rai Rai Ramen.  Everyone loves it, and even though Alukit couldn't make it, we bring some ramen back for him.  We leave kinda later than I had expected, but make it back to Maryland safely, where I promptly pass out.

day 7:
I'm up bright and early, spending just a little bit of time playing IIDX before I have to get on the road again.  Goal is to make it about half-way, somewhere in Ohio.  I succeed, and find perhaps the dirtiest motel I've been in for the entire trip (but also the cheapest at $40/night).  I survive.

day 8:
One last day of driving, and it's a doozie.  11 hours of driving, one time zone change.  I make it back to Kansas City in time for dinner, and also manage to stop at Flatbranch again to pick up a pretzel to go.  It was totally worth it (any time I head east on I-70, I make it a point to stop there--the food's too good to pass up).  Overall, I'm worn out, but the trip was excellent.

MicroLogix 1000 and Linux (er, Win7)

So, because I'm a geeky guy, and I wanted something fun to play with (and since I've been taking a course on Factory Automation), I went over to America's junkyard and picked up an Allen-Bradley MicroLogix 1000 PLC on the cheap.  Good deal, and while not very featured (doesn't even have analog inputs), it's still something to tinker with.  Also had to buy a 24V power supply and a cable to program it with (which pretty much doubled my cost), but anyway, on to the fun stuff.

I'm a Linux user.  I prefer it, spend the majority of my day working with it, and don't even have a system that will natively boot to Windows anymore.  The one version of Windows I use on any regular basis is a VMware image of Windows 7.  Well, with this new PLC, I wanted a way to keep this trend going.  Maybe the title is misleading (or I cheated), but... it's the best I can do.

First hurdle was USB.  The drivers for the chipset (CP2102) weren't in Windows 7, and the provided drivers also wouldn't work... so it was off to the vendor to find something compatible with Win7.  That didn't take long, and after a quick reboot, that was up and running.

Next, I had to get RSLinx Classic running to allow communication.  Setting up a DF1 device is pretty simple in RSLinx, and autoconfiguring communications worked great with the PLC, but in Win7, I was getting an odd "Could not create registry" error.  Well, I remembered, it's not running privileged, so I shut it down and restarted it, this time running as an administrator. After I did this, it created the registry and started going, so all was happy there.  It also seems that on subsequent starts, it doesn't need to be run privileged anymore, since all the communication parameters are present.

Third, I just started up RSLogix Micro Starter Lite (I'm poor and it does what I need).  Since everything in RSLinx was good, I just tried going online and uploading the program from the processor to see what was on there, and saw there was a pretty simple program.  I mucked around with it a little, forced a few inputs, toggled a couple bits, and saw the state changing appropriately.  Satisfied all was well, I decided to write this and get some sleep.  But, before I go, I leave you with a pretty picture of my accomplishment.  Enjoy.

PLC Stuff - RSLogix

New Car and Ham Radio Install

| 1 Comment
Well, switched out cars today--dad took my old Dodge Neon, I get his old Camry.  Not a bad trade overall, and while I owe him some money for it, it's a nice deal.  Anyway, of course the first thing I want to do as soon as I have it is throw all my radio gear back in.  

My last car ('05 Neon) was a pain to install my radio--running the power back to the battery took much work with a coathanger and patience.  This time, the story was quite different.  Toyota got a couple things right with the Camry.  First, the grommet holding the wiring in place was actually very easy to move out of the way, letting me slide my power cable through, and they gave plenty of room to work in the engine compartment.  Then, routing the cables inside the car was very friendly, too--only needed a screwdriver to pop off one cover, and the rest of the paneling was toolless removal.  They gave plenty of space to route more cables, including clips to hold things in place.  Overall result was a very professional-looking install, with only a tiny bit of wire showing.

Anyway, enjoy a few pictures of the car, and some of my own handiwork after the break.

A Beginning

Well, after about five years of not touching a single page on my website, I decided it was time for a fresh start.  You can read a bit more about me in the "About" section... and a few things you might expect:
  • I ramble
  • I change the topic without any warning
  • I will probably go into more detail than you ever cared to know
Given this, over the next few weeks and months, hopefully I'll be able to give you a glimpse at some of the things I've accomplished.  Right now, as summer's winding down, I've been finishing my internship where I've learned anything from how frustrating certain software packages can be to very intriguing things like control systems security.  Along the way, I also had time to develop a simple application called "Acceleroid" to capture accelerometer/GPS data in near-realtime.  Blame that on my interest in roller coasters.  It's been an experience.

Where it goes from here?  Who knows, but the journey has to start from somewhere.