Teamwork is a big thing here at UAS. One of the first things everyone learns coming here is that you are very unlikely to survive on your own. In fact, it’s hardly even possible, purely technically, because basically every course requires some kind of teamwork. In the first term, our business administration course–of all things–became the initial spark for forming our long-term study group. As our exam admission prerequisite, we were required to present a business plan for a start-up firm of our own devising, and to do it in a group of eight students. Since I had the privilege of knowing a handful of good people from our math prep course, when we got that word I simply stood up and pointed–you, you, you, and you–and bingo, that became our study group not just for business administration but for everything. In math, we had to work in groups of four, so we simply re-defined ourselves as two groups for that course. CS people are big on rationalization and efficiency.
That study group–at least its remaining core–is still my most important environment for studying and social activities. Yet there is one relationship in any computer science student’s academic life that is more crucial than even a good study group: Programming partners. Right after your own intellectual capacities, intrinsic motivation, and work discipline, having a good programming partner is the second major ingredient for success in this course of studies.
I met mine in the math prep course. I think we sensed that we had each found a kindred soul when during the course of some afternoon homework session we both simultaneously hacked a quick routine for some math problem into our laptop computer–he in Java, I in Ruby. I believe at this point we were about the only ones in the semester group who programmed for fun.
When during the first week of the actual term we were informed that we should find partners for programming in teams of two, from a purely social perspective I could have imagined doing this with quite a few of people I knew from the prep course. But in terms of programming abilities they were all blank sheets to me. Anyway it’s a strange situation, somewhat akin to an arranged marriage. You have to pick somebody to be stuck with, for better or worse, for at least the best part of the term, to the extent that your admission to the exams will depend on his/her contribution, and vice versa, at a point when you know next to nothing about any of the other students.
So I reflected that knowing this guy loved to programm was a better reason to ask him than no reason at all. He seemed to think the same, and within ten minutes from the initial announcement we were, I think, the first programming partnership in the entire semester group. I do know for a fact that most people picked their partners more or less at random (the person accidentally sitting next to them, for instance), and many didn’t have one as late as the start of the first practical course in programming. As I related earlier, many of these random partnerships didn’t survive the first weeks of the first term. Ours has persisted through the first two terms and is likely, I believe, to do so for the foreseeable future.
Of course no such relationship is without its problems. I had to define ours in a few keywords, I should say it’s marked almost equally by competence, cooperation, and competition, with a fair bit of arrogance mixed in. Competence, in that we never have had any problems with any of the assignments for the practical courses and usually overdo our solutions, often to a ridiculous extent, doing GUI’s where none were required, generalizing our designs where a specific solution would be quite sufficient, and so on. Arrogance, in that we knew already in the first term that we knew a lot more about programming than could be reasonably expected of us, and particularly, that at least I knew more about programming in Ruby than our professor who had started acquiring this language just in time for our first term. (Needless to say, at the end of the term this headstart had long been lost, because anyone with 20 or 30 years of professional experience will learn a new programming language within a few weeks and then be way ahead of even the most eager student.) So we generally demonstrated our disdain for the more basic programming assignments by handing them in after a few hours (the actual deadline being a fortnight away), and for the programming lectures by doing a thousand other things on the side and still throwing in a casual to-the-point remark every once in a while.
Cooperation, in that both of us are reliable and meticulous in almost everything we do, so that none of us ever had to prod the other to do his part, as we saw it happen with so many other programming pairs. However, cooperation was often overshadowed by competition, and competition is what sometimes caused this partnership to turn sour at least temporarily.
I had an initial head start in the first term because I already knew how to program in Ruby while my partner didn’t. So for a few days I showed him the ropes of a programming style reasonably different from Java. Of course, after a couple of weeks he was at least as good as I. We had a chaotic beginning with an ill-conceived private project, a quadratic equation solver that turned into a nightmare of conflicting concepts and files sent to and fro by email, both of us working in parallel on the same source files. Unsurprisingly, the project foundered (the only thing ever that we didn’t complete at least in a reasonable, if certainly expandable, version), and the best I can say about it is that it taught us the virtues of version control which we have used ever since (Git).
The first official programming assignment was a simulated, optionally loaded, dice. It hadn’t been out for 30 minutes before we had both of us indepedendently completed it (it’s only a few lines of code in Ruby anyway). Then we spent about four hours arguing whose version was superior and another two synthesizing them into a single solution for handing in. Never have so few lines of code been honed to such a fine point with so much effort!
And we continued this way for most of the first term. Apart from some minor problems to be solved quickly we never did any actual pair programming, in the sense that we would both be sitting in front of the same screen working on the same piece of code. Not only did we consider it a waste of time, but also our different working styles and relative speed of coding rebelled against this practice. If I was the one typing, I would hear a constant stream of impatient interjections along the lines of “what are you doing?”, “why are you making this so complicated?”, “you don’t need that”, “you really don’t need that”, complete with attempts to wrest the keyboard and/or mouse from me, and besides, typing with someone looking over my shoulder makes me jittery at the best of times. Conversely, if my programming partner did the typing, he would be going so fast that while I was still trying to comprehend his first method he would be doing the third.
So with pair programming ruled out, we continued to work independently, which obviously meant we had to split the programming assignments between us (although for the second, very basic exercise sheet, we still announced a contest of “who can do this with the fewest lines of code”). Yet it took us a while to develop a set of rules that prevented us from simply each one starting to solve the entire problem, with the resulting mess in the style of the dice assignment on a much larger scale. And even then we competed and argued over who should do what. Whenever a new assignment came out, we fell on it like hungry cats and tried each of us to secure the best, most interesting, most challenging parts for ourselves. This race for the bigger, better chunk of the programming tasks often led to conflict. It was several month before we had established the principle of single responsibility for certain parts of the code, so that one of us would not just take the other one’s code from the Git repository and “improve” it, a practice that often caused bad blood. Sometimes we had to call a moratorium for a day or so to attend to the requirements of other courses, lest one of us would program away, adding usually completely unnecessary features to an already completed project, thus provoking the other to draw level.
In this enthusiastic way we overdid the solutions to nearly all the programming assignments in the first term (when there was still time to do that because, except for math, we had practically nothing else to do). For a converter from the fantasy Potrzebie system of measurements (introduced in the 1950s by the CS guru Donald E. Knuth) to metric, I read in the conversion table from a text file, so that the converter could be used for almost any unit conversion conceivable. For an implementation of John Conway’s “Game of Life” (1970), we not only digested the supremely inaccessible and practically undocumented (save for a short tutorial) graphics toolkit Tk for Ruby, but also did a complete model-view-controller setup with about three times as many classes as everybody else, just in case. For a marshalling yard problem based on a stack implementation, my programming partner wrote not just the solution, but an automatic problem solver for any such setup. Our implementation of the classic 1980s board game “Master Mind” was not only object-oriented and modular to the extent that every line of colored dots, and its evaluation, was a separate logic object paired with a graphic representation, but also fairly customizable: You could play with or without duplicates, and with any number of colours from 1 to 10. In fact, the console version, as opposed to the GUI one, could even accomodate a completely random alphabet of any length.
And we were still hungry for more. My programming partner became involved with the guys who build racing cars in the second sub-basement of the neighbouring building housing the automotive and aircraft engineering department. They wanted a graphical interactive live representation of their sensor readouts. So he decoded these readouts (there were hundreds of them), which required quite a bit of bit-shifting (that was before we actually learned about all that stuff in the second-term course on machine-oriented programming), and then displayed them in Java FX charts. Only he never managed to have the charts update continuously. Finally he turned to me and offered a piece of cake as a reward for my figuring it out. I rose to the challenge and spent a fortnight (!) getting these colored moving zig-zag lines to display properly–my first foray into both parallel programming and Java FX. I did this basically day and night, and during most lectures–those were the days! I think this was the last time I ever was ahead of my programming partner in anything programming-related.
For the second term turned the tables, for good. While I became increasingly overwhelmed by new stuff and time pressure and could no longer devote a lot of effort on programming, my programming partner throve on the chance to actually program in Java, his favorite language. Increasingly, a gap opened between us. Without investing nearly as much time as I did, he kept at least level with me in all other subjects, while at the same time outpacing me entirely in programming. In truth, from a merely interested novice, he became a full-blown semi-professional Java programmer within a few months, easily picking up even the most arcane language constructs and complex programming concepts, as needed, with just a cursory glance at the documentation or a reply on stackoverflow. On the rather limited standard exercise assignments I could still more or less keep abreast of him, because he no longer had much interest in them and tolerated my increasingly less than optimal solutions for the tasks I worked on.
But the major second-term project, the media player mentioned earlier, became my programming partner’s favorite playing field–and a primary source of time pressure and frustration for me. Probably our professor had nothing more in mind with this assignment than giving us some feeling for designing a non-trivial project and a little practice with Java FX GUI elements. Needless to say, it was almost inevitable that we overdid it. The first time we talked about this project, my programming partner already had a complete design with about 20 classes ready, including fully abstracted media entities for different formats, a media library with a database behind, and of course a GUI, plus a nearly endless feature list for the player. I was at a distinct disadvantage from the moment we started working on this project. First of all, I personally don’t use media players, so I had no idea what they should do, and cared less. Secondly, faced with the completely thought-out concept my partner brought to the table, I had nothing useful to say or add. And most of all, at this point he completely steamrollered me with his energy, time investment and Java skills. Simply put, when I (a reasonably efficient programmer myself) write a certain number of working code lines within a given time, he will have done twice the number of lines within half the time, they will work at least as well as mine, and probably be more generalized and generic, and he will have the other half of the time to learn something new–or pick at my code!
At least I managed to secure an area of the project where I could more or less do my own stuff, without much interaction with the other areas, namely the media library and database. That part was even interesting; I had never worked with databases before, let alone with JDBC (i.e., using a database from within a Java project). I was determined not to mess up the code with SQL literals and employed an external SQL query builder library. Rather sparsely documented (almost as bad as Tk), this took me a full weekend to figure out, but I learned a lot about both finding my way on badly mapped terrain and about SQL, getting confident about which may have helped me in the database exam as well. In the end, after a lot of trial and error, I had about 800 lines of code that actually worked–a successful integration of a database with our project.
Except my programming partner was not really pleased. He had very specific idea what our player should do, and particularly how well it should perform faced with veritable masses of audio titles–an avid music lover, he has over 6,000 titles on his work computer! And unlike with the smaller programming assignments, here he was determined to get his way. When I had uploaded my code to the repository, he sent me a two-page list of complaints–why had I done this that way, and that not the other way, method XY was way too slow, etc. etc.
In truth, that is what I have come to mind most about programming with him–that he can’t leave my code alone even when it works. While he nominally respects my responsibility for my parts of a project, he is quick to let me know what he thinks I should have done differently. I fairly dread pushing anything to our Git repository, because I know he will instantly subject every line to painful scrutiny. In fact, I never upload anything incomplete, even though that makes my work flow unnecessarily complicated when I move from laptop to desktop computer and vice versa, or he will certainly criticize it before it’s even done. And since he is a much more competent programmer, I usually have to admit he is right. This regularly puts me in a position where I no longer feel his equal, but rather like a pupil submitting a probably weak solution to a stern teacher.
Don’t get me wrong. My programming partner is in no way a difficult personality. On the contrary, he is perfectly uncomplicated, good-tempered, helpful, and well-liked by nearly everyone, not to mention one of the smartest persons I have ever met (and I am almost twice his age). Only when it comes to programming he becomes something akin to an overwhelming force of nature, and his enthusiasm and perfectionism then get the best of him. For me, this really became a problem this term. It’s not as if I had had any time to spare, with all the other courses, particularly the two math ones, already putting a lot of strain on me. Yet the media player project nearly ate me up.
You see, with the database integration and all that it was rather complex. Often a small improvement demanded by my programming partner would mean an additional day work for me. And he kept demanding them. My search mechanism was both too complicated and too slow for his liking (it seemed perfectly fine to me, but I have no great expectations there), so he had us introduce parallelism, which led straight into a hell of bugs and exceptions that needed more days of work to iron out. Mind you, I can stubborn like hell, myself. I clung to my advanced search mechanism that my partner pronounced superfluous and made it work, so in a way we got the best of both worlds–at a price!
In the end we had a project of about 4,000 lines of code to which I had contributed one large chunk (the library and database) and a small one (the overall GUI and some CSS styling), while he had done all the rest, from the original design to all the actual media stuff, plus let’s say the “quality control” (from my perspective that meant prodding me to do things his way).
And I was thoroughly humiliated and for a while seriously considered finding me a new partner. But then on sober reflection I realized that whoever I chose I was likely to lose out. There simply isn’t anyone else in our semester group from whom I could learn so much and from whose efficiency and reliability I could benefit so much. Worse, I might end up in a situation where I had to prod and carry somebody else. Not the least, as I said, my programming partner is an all-around nice guy when we aren’t programming, and a mainstay of our study group which I value above all things.
So I decided we had both of us to adjust our attitude somewhat, and plan our future projects better–particularly since they will only get larger. On my instigation, we had a long talk in the cafeteria where we agreed that henceforth we had to design our projects in a way that limited our involvement to a level that I (as decidedly the less productive part) could permanently support, then split them so that each one of us would nominally do a more or less an equal share (fully knowing that he would inevitably overdo his part so that he would come out with probably twice the number of code lines in any case). After all, these are study projects and should be manageable as such. More importantly, in the future we will initially define the complete interface for a project, and afterwards we will each of us have our own areas of responsibility, the other one limiting his comments to things that actually don’t work. Or at least that’s the agreement; the practice might turn out differently.
While this experience, in its intensity and general setup, is likely rather atypical for most programming partnerships, I think even so it shows a few things about the system of programming in pairs practiced at UAS:
- Two people are forced to work very closely together for a very long time, probably incomparable to anything you experienced at school or elsewhere.
- Inevitably, being this closely tied together under quite some external pressure will starkly expose the best and the worst in the motivation, work discipline, creativity, self-responsibility, reliability, performance under pressure, conflict behaviour, and any number of similar relevant character traits of both partners.
- Quite likely it will also result in a contest of wills and a clash of personalities.
Quite something we have signed up for with this study program!