I just finished progfun 002, a course offered by Coursera that teaches the fundamentals of functional programming in Scala. I was left with a favorable impression of the course and wanted to share some postmortem thoughts.
This was my first online course. It was also my first post-gradschool course. I spend plenty of free time writing code, but finding a sustainable way to make time for difficult (even tedious) assignments is a different beast. There were plenty of evenings when I didn’t have enough energy to solve hard problems, to say nothing of solving them in an alien language that I was just beginning to understand. The deadlines are a good partial solution to this. You can turn things in late—life happens—but it will cost you. The scaffolding that’s provided in the problem sets is the other half of the solution; I’ll get to that.
Each week, a half dozen short (10-20 minute) lectures are posted that cover the material for that week’s assignment. (That’s backwards, of course; you’re taking the course to learn the material, not just to solve the assignments. But when you’re five weeks in, you’re thinking about the assignments.) The lectures are nicely parceled into small topics that can be watched during a coffee break or over lunch.
The pace of the lectures is slow and steady. (I watched most of them at 1.25x. Beyond 1.5x, the audio becomes difficult to understand.) The videos are fairly easy to scan when you need to review a segment. I do wish that the course organizers would prepare a set of lecture notes that highlight the main points of each segment for later review. On more than one occasion, I found myself scanning through multiple videos in search of a specific slide.
PDF versions of the slides (even without the instructor’s annotations) would be another useful option. As Luc points out in the comments, a PDF version of the slides is available for each lecture. (Thanks!)
Periodically, the lecture will pause and present you with an exercise. These are probably worth your time. Most of them, anyway. The exercises might not be an option if you’re watching a lecture during your coffee break, but they provide a helpful check for your understanding and are a good way to cement new concepts in your mental model of Scala.
The lecture material can seem bogged down at times, especially when the instructor is discussing deep connections to mathematics, proofs, or topics from theoretical computation. If you’re a working professional whose aim is to develop a working level of fluency in Scala, such segments are probably safe to skip. For students of computer science or anyone with a bit of extra time, they are worthwhile. Martin Odersky, the course instructor, is a titan in the world of Scala, and he has a knack for distilling complex topics into useful morsels. Take advantage if you’re able.
Much like other well-known computer science courses (such as CS50X), this course unabashedly delivers some pain. The assignments are mostly excellent, though, and the time investment will leave you ready to build useful software.
As I mentioned earlier, the assignments provide a lot of scaffolding—code and documentation that is incomplete but provides a rough path for you to follow. The scaffolding serves two purposes in a course like this: it provides a skeleton for the solution that you’re developing, and it enables you to solve real, revelant problems without the cognitive load of simultaneously designing and implementing a solution.
The assignments also provide small fragments of finished code that can be used as-is. These are often fragments of code that are uninteresting, easy to screw up, or both. Mostly they’re irrelevant to the problem at hand, and it’s a better use of your time to focus on the stuff that matters. The course designers have clearly embraced this.
One of the great benefits of an online course is the discussion that happens around the lectures and the assignments. Even greater is being able to search those discussions after they’ve happened. Coursera has good infrastructure for supporting rich conversations, and this course in particular has a wonderful group of staff TAs who are available (seemingly at all hours) to answer questions. It’s often tempting to give and receive too much advice on the discussion boards, but with a bit of self-discipline you should be able to glean just enough information to see the solution.
The auto-grading machinery for this course is well done. Assignments can be submitted multiple times without penalty, and generally the grader will provide enough feedback that you can identify and resolve any problems with your code. On one occasion, though, I strongly wished that the test inputs (strings) were provided along with the grader’s output. The feedback can be cryptic. For most assignments, in my judgment, providing the test inputs would not give an undue advantage to anyone.
The course description predicts that you’ll need 5-7 hours per week. I think that this is slightly misleading. You can expect roughly one hour to be consumed by lectures. The time spent on assignments, however, will vary significantly—especially if this is your first experience with functional programming. I finished one assignment in less than 30 minutes, but another took me more than 10 hours. The genuine feeling of enlightenment is worth the effort, but it will take some time. The later assignments are fairly complex, and you will need to find additional time for debugging. Learner beware!
If you have any interest in functional programming, I hope that you take this course. It’s accessible to anyone with a good grasp of programming, and you’ll be hard pressed to find another course of equal calibre. For me, though, this is the real test: after working through the assignments, I feel prepared to learn the rest of its faculties and get my hands dirty with some real projects.
There are efforts underway to make a follow-up course that will cover concurrency and other advanced topics.
It’s well documented that the INSTEON I/O Linc can be used to control a garage door and monitor whether the door is open. It can even be accessed from a mobile device, making this a highly convenient home automation tool for less than $100. What was far less clear (to me, at least) was exactly how to connect the I/O Linc to the garage door opener. So, what follows is equal parts tutorial and lessons learned. The details will almost certainly vary, so be sure to consult the user manuals for your equipment.
- SmartLinc 2412n controller
- I/O Linc
- 20-28 gauge wire
- Garage door opener
- Magnetic sensor (optional)
- Soldering iron, wire nut, or some other means of joining wires (optional)
Wiring the Garage Door Opener
A garage door opener (GDO) typically has several terminals on its rear panel:
Some GDOs will have three terminals; others have four. For three-terminal openers, there are two “hot” terminals (one for devices that control the door, one for safety sensors) and a shared “common” terminal that’s normally in the center. A four-terminal GDO will normally have two terminals for controlling devices and two for sensors. The specific function of these terminals can vary from one GDO to the next, so be sure to track down the manual for your unit. (I hope you have better luck than I did.)
On my GDO—a Craftsman from circa 1997 with part number 41A5021-3B on the rear panel—there are three terminals:
To connect my GDO to the I/O Linc, I used a length of old (read: ugly) speaker wire that I had lying around. (I recommend using bell wire or one pair of wires from an RJ-45 cable as they will be a better fit for the I/O Linc terminals.) One wire connects to the Remote/Opener Terminal (#1). The second wire connects to the common terminal (#2) in the center. The button on the wall will also be wired to these terminals.
Next, we’ll connect the other end of the new wires to the I/O Linc. The instruction sheet that ships with the I/O Linc is helpful and full of dense information, but it left me scratching my head. There is one very important wrinkle that must be dealt with before we can wire the I/O Linc to the GDO. The I/O Linc ships with its relay in latch mode, which means that when you press the button on the wall, the I/O Linc will close the relay and keep it closed. Most GDOs assume that the relay will close for a brief period (say, two seconds) and then open again. We need to configure the I/O Linc to respect this assumption.
Configuring the relay mode
- Press and hold the “Set” button (on the side of the I/O Linc) until it beeps. Release the button. The I/O Linc is now in linking mode.
- Press and hold the “Set” button (on the side of the I/O Linc) until it beeps. Release the button. The I/O Linc is now in unlinking mode.
- Press and hold the “Set” button (on the side of the I/O Linc) until it beeps. Release the button. The I/O Linc is now in output relay programming mode. The unit automatically rotates to the next mode; if you were starting with a stock I/O Linc in “Latch” mode, it is now in “Momentary A” mode. This means that an “On” command will operate the door, and an “Off” command will be ignored. (If you prefer that “Off”—or even both commands—will trigger the door, then feel free to explore the “Momentary B” and “Momentary C” modes.)
I/O Linc Wiring
We’re ready to connect the GDO to the I/O Linc. The other ends of our wires need to be connected to the Normally Open (N/O) and Common (COM) terminals on the I/O Linc:
The other two wires in the photo are for a magnetic garage door sensor. More on that in a moment.
When the I/O Linc receives a signal from its controller (a SmartLinc 2412n in my case), its relay closes, and the normally open circuit is closed for a brief moment. This is the very same event that occurs when you press the button on the wall. The GDO responds by opening, closing, or halting the garage door.
Monitoring the door state
If you want to monitor whether the door is open or closed, then you’ll need a magnetic door sensor. These are inexpensive (< $5) and easy to install. Once the sensor is mounted, connect one wire to the I/O Linc’s “Sense” (S) terminal and the other to “Ground” (GND). When the door is closed, the green Sense light on the I/O Linc will be illuminated. When the door opens, the light will go out.
N.B.: If you plan to use the INSTEON mobile app, be advised that the “Status” for the I/O Linc is the status of the relay, not the door. When you open or close the door, the status will briefly change from Off to On and then back. If you want to monitor the open/closed state of the door, you will need a more sophisticated app. For Android devices, MobiLinc is a good option.
Controlling and monitoring your garage door opener with INSTEON devices is not complicated, but pulling together the relevant instructions can be frustrating. Makers of garage door openers generally don’t explain how to do one-off installations, and the dense instruction manuals for the other components can be offputting. Hopefully I’ve found a comfortable middle ground with this tutorial. If you follow these steps and find that the steps are incorrect or that your equipment differs from what I’ve described, please leave a comment below. Good luck, be safe, and have fun.
Anybody using git to manage text document revisions might benefit from this. I keep all of my research papers in git. I also collaborate on paper writing fairly often, and I may want to see the difference between two revisions.
My first solution looked like this:
git diff --word-diff commit1 commit2
This works, but long lines—which are very common in text documents—run off the edge of the terminal window. On Linux and Mac, the default pager for viewing diffs is less, and its stock viewing mode leaves something to be desired. I would like the long lines to be wrapped.
My next attempt was as follows:
git diff --word-diff commit1 commit2 | fmt
This version solved the line-wrapping problem, but the result was ugly and difficult to scan. git and fmt don’t play well together. If possible, I would like the changes to be color-coded rather than delineated by some ugly text scheme. Although git’s support for color highlighting works better for code than long-form text, it’s usually good enough that you can work out what changed.
git config core.pager 'less -+$LESS -FRX'
git diff --word-diff=color commit1 commit2
Bingo: lines wrap properly, changes are color-coded, and no junk text is introduced by incompatible tools. If you want to use the same pager settings across all of your git repositories, add the “–global” flag to the first command.