The last test was trickier than the previous tests in my opinion, but that was to be expected because the material gets trickier and more nuanced as the class goes on and we have had less time to experiment and learn those concepts than we had for earlier concepts. I think the tests were fair. Although the daily quizzes could be a bit of a nuisance when the quizzes didn't cover the day's reading -- especially when a quiz covered a reading from several lectures ago and that reading is not fresh in your mind. Overall, the quizzes were another good tool to keep people on track with the material, encouraging students to study the tricky topics between every lecture, rather than waiting until the test is imminent.
Lectures
Overall I have a pretty positive opinion of the class. The lecture style was good for keeping everyone alert and learning, and was extremely clear. The papers were excellent reading. (The textbook on the other hand was dry and outdated.) The projects started off very simply and taught us the foundations of C++ and Object Oriented Programming (OOP), and then built upon those concepts. I wouldn't say the projects were particularly challenging on average, with the exception of the last project. Mostly they involved learning a simple concept and then building around that. I feel like I learned a lot about C++ and got some valuable experience and knowledge about C++ that benefitted me immediately because I was taking Computer Graphics this semester as well, wherein all the projects were in C++. Some knowledge of the trickiness surrounding certain concepts in C++ like copy constructors and copy assignment definitely bailed me out of some tricky problems that I saw other students [who had not worked with as much C++] struggle with. Immediate payoff is very validating.
One negative to the lecture style that poses a lot of questions to the students is that the learning is very instructor-driven, which can be a bit stifling to the types of learners that would prefer to digest an idea, interact with it (perhaps by experimenting with the code), and ask questions which explore tangential subjects. There were definitely topics that could have been explored in more detail and I wish I had been able to ask questions in the heat of the moment but we move pretty quickly through every detail that it's hard to really slow down and address some possibly interesting questions.
Programming Labs
The programming labs were generally a good learning experience, at least as far as the implementation of the project was concerned. I understand that testing is important, but the fact that I spent nearly half of my programming hours devising unit tests is, I think, a problem. For instance, sometimes you want to create a function which encapsulates some extremely simple functionality. Maybe it wraps another method. There are a lot of circumstances where being required to write 3 unit tests per method, no matter how simple, is extremely frustrating. There are also functions which don't lend themselves to unit testing at all. For instance, functions that generate text output. Instead of writing directly to the console or a file, I found myself constructing strings in the unit test code which have to exactly match the output of the function, down to the number of newlines. Isn't that what acceptance tests are for? Weren't we running acceptance tests anyway?
I would recommend slightly relaxing the requirement for unit testing. Default constructors shouldn't need testing. Constructors which do trivial assignments of arguments to variables in the class and no other code, really shouldn't need testing either. Functions that output text shouldn't need testing. Functions that simply return the value of an instance variable most likely don't need explicit unit testing. The threat of getting a serious reduction in the lab's score scares us into doing all of these things, rather than focusing on unit testing the functions that are likely to be incorrect, and especially the functions that are more likely to break as the functionality is extended.
I even became aware that some people were attempting to circumvent the requirement to test all their methods by making "simple methods" into complicated #define macros! They engineered around the problem of testing simple code, but ironically they made their "simple" code much more likely to break (and more difficult to debug)! I hope examples like this help to expose the flaw in the requirement, and that the requirement will be relaxed to be something like "write at least 3 unit tests for non-trivial methods" (and define trivial methods as you see fit).
For Computer Graphics, I spent about 40 hours on one project. This project had many parts, and a lot of opportunities for exploring and expanding the programs for extra credit. Every half hour or so you feel like you solved an interesting problem, added a small feature, or fixed a funny detail of the code. I don't view any of that time as wasted, and it was so rewarding that I actually plan to continue to work on several of the projects from that class. Unfortunately, I hardly remember my solutions to any of the projects in this class except the most recent one, which I will surely soon forget the details of.
Sadly, the projects for this class were simply not inspiring. I suppose that is to be expected for a class which is essentially an introduction to C++.
Skills Learned
Skills we learned in the class:
- C++
- CppUnit
- Git/Github. I like that there is a class which actually requires using source control in a sane way (i.e. not in a way that involves pushing to an repository that belongs to the instructor, for instance, where you don't have direct control over problems that arise). Using a VCS, especially a DVCS, is a good skill to have. My opinion is that Git should be required for programming labs beginning with a freshman- or sophomore-level required class.
- UML Diagramming. Nice to do, not too time consuming, good for designing solutions to OOP projects.
- Make (Makefiles). This doesn't even really need to be explicitly taught. Providing a Makefile with the project would probably be enough. Students will be smart enough to figure out how to update a simple makefile to add to the list of files that get compiled. My Graphics class did this and it worked very well. This allows students to turn in a project without worrying especially about how their files are named, because the grader will simply run "make" instead of a predefined build command, using the students' Makefiles.
- Multiple-file projects (when you have a lot of classes, we should make additional C++ files and update the Makefile as above -- also, executable code should be by-and-large in .cpp files, not in .h files. Even though the latter makes compiling much easier, it is bad style and confusing to teach this way in a class where most students are seeing C++ for the first time.)
Workload
There are some classes that are really hard, and that difficulty translates to the time you're likely going to spend on projects and studying. And then there are some classes that are just very time consuming. I've had some of both in my time at UT. I'm happy to say that there is less busy work as time goes on, and that as the classes get harder they also get more interesting. I very rarely find that the projects I do these days are a poor use of my time.
Unfortunately, this class toed the line between productive learning experience and busy work. The first labs were helpful to get oriented in C++ but they took way too many hours for what they were. For the first couple of labs, 75% or more of my time was spent writing unit tests, or updating the issue tracker in GitHub.
I think the class website is very accurate about the amount of time you'll spend on this class, in all categories. I was just a bit disappointed that the hours spent programming were mostly spent in mechanically devising unit tests, rather than in solving interesting problems. I wouldn't have minded 20-hour-a-week programming assignments if the assignments were legitimately interesting, as they were in computer graphics.
I expected more interesting and inspiring projects from a class which is numbered as Senior-level (371) and named "Object-Oriented Programming." Most of the OOP we covered in this class is covered in a standard Data Structures class taught in Java, and there is so much more to learn about OOP. I wish we had gone into more depth in that regard.
I know I sound like I'm complaining about the class more than I am praising it. Simply put: what was good about this class was good, and there's not much more to say about it. In fact, most of the class was good. I'm simply hoping that students who take this class in the future will benefit from the professor's consideration of these criticisms.