UW Madison Computer Science

July 1, 2023

I like to plan things out, especially things of high importance. Since college happens to fall into that category, I’ve spent a significant amount of time planning out courses, and I’ve made a habit of studying for every math/cs course before the class begins. I was able to do both of these things with the help of online resources, many of which were student-created. I intend for this post to serve as an overview of the degree requirements and my experience with the classes for anybody who may be interested in what the degree entails or how to go about it. My main focus is the Computer Science major, but there is some overlap with general degree requirements.

General Resources

Requirement Clarifications

The university lays things out pretty well, but there are some small ambiguities due to the non-programatic definition of the requirements. It turns out that DARS is the soultion to this issue (you can find it more details in Course Search and Enroll and Noguera’s page (see above)), but here are a few clarifications that I was initially uncetain of.

The Plan

My goal is to graduate in as few semesters as possible. This is for three main reasons: (1) The standard lecture/discussion/homework/exam format of college rarely aligns well with my desired pace/focus. (2) I like pushing the limits: the rewards of my efforts seem to be proportional to the amount of work I put in, so I refuse to purposely hold back. (3) College is expensive. We could go into the details, but you probably get the point.

I think that this reasoning is relatively straightforward and probably relatable for a lot of people, but my advisor refused to even discuss a 2-year plan, repeatedly insisting that I rethink my plan, or else my mental health and networking opportunities were at stake. I bring this up to point out that my advisor was not entirely wrong: such a plan is not fit for everybody, and there are certainly some opportunities that will be missed by graduating early. At the same time, I think it’s closed-minded to assume that such a plan is not fit for any student, and that the opportunities gained by graduating later necessarily outweigh the cost (namely the financial vulnerability) incurred by extra semesters. I am not an extraordinary student, but I did put a considerable amount of work in to prepare for classes and study CS in general. I encourage anybody considering early graduation to consider the opportunity costs of all of the options, and to avoid underestimating their own abilities.

AP Credits

Fall 2022

Spring 2023

Summer 2023

Fall 2023

Spring 2024

CS Requirements

CS 200 — Programming I

An intro to programming fundamentals and Java syntax. I tested out of CS200 with the self-assessment, so I can’t speak about the class as a whole, but I did read through almost all of the slides online, which essentially covered a subset Java Tutorials (plus some more explanations of basic programming concepts and style guidelines), which I had read earlier in the summer. The self-assessment was consisted of a project (peg solitaire, which was slightly easier than the average CS300 assignment), a short (30 question) sample CS200 final exam (which mainly covered basic syntax), and a “reflection”.

CS 300 — Programming II

An overview of Object-Oriented Programming and fundamental Data Structures. Like 200, the course slides can be found online. The OOP portion is also almost completely overlapping with the Java Tutorials, but 300 also highlights a few more implementation details of how arrays and references work (i.e. heap vs stack), which are further iterated in 354. The Data Structures covered (linked lists, trees, heaps) are generally considered fundamental (they’re asked about in a lot of leetcode problems), but aren’t practically very useful, because they’re implemented in most languages’ standard libraries. The class itself consists of quizzes and exams (both in the same canvas-quiz format), programming assignments, as well as a mandatory online textbook through zybooks (a few other intro CS courses use zybooks as well; to earn the points, you must click through the readings and answer some basic “challenge” activities). The programming assignments involve fill-in-the-blank functionality (i.e. a method’s documentation is given, and you must write it) and writing testers. While the programs aren’t inherently complicated, there is a mandatory style guide, which requires the use of javadoc comments, which are (in my opinion) incredibly verbose (for the uses of this class); this, in combination with the verbose nature of Java itself, makes the programs much harder to work with.

CS 400 — Programming III

Sundries. This course attempts to cover lots of miscellaneous practical knowledge for programming (Bash, Git, Make, HTML/CSS/JS, Regex) along with a crossover between 300’s tougher concepts and 577’s easier concepts (Hash Maps, Balanced BSTs, Shortest Path, Minimum Spanning Trees), along with some more specialized Java tools and language features (JUnit, JavaFX, Lambda Expressions). Projects are done in groups of eight students (with two subgroups of four working on separate instances of the implementation), and serve as a way to practice all of the material (using the tools to work on projects related to the DSA concepts). There were also some weekly quizzes and activities sprinkled in to supplement the projects. The class was about as crazy as it sounds, but it worked surprisingly well. The projects were unsurprisingly messy, but considering the team aspect and the fact that the programs were completely designed by the teams (in comparison to the fill-in-the-blank methods of 200-300), I was impressed when our projects came together and worked as expected (almost).

CS/Math 240 — Intro to Discrete Math

Basic Logic, Proof Techniques, Graph Theory, Set Theory, and Combinatorics. I took this class with the Math Department (Prof. Sobieska); I’ve heard that there were previously big differences between the Math and CS version, but this one seemed to mirror Dieter’s Notes almost exactly, which are apparently the basis for the CS version. The class was laid out almost exactly like a typical math class, except that the textbook was through zybooks. Most of the material in this course is immediately relevant for 577 (the more popular of the two options for the Theory of CS requirement).

CS 252 — Intro to Computer Engineering

Computation at the binary, transistor, logic-gate, machine-language, and assembly-language levels. The class began with binary representations of integers, then rapidly jumped abstractions, finishing with a description of the LC3 (“Little Computer 3”) architecture. Having already read a book on x86 assembly and worked on a project (of sorts) with it, the assembly and binary logic portions of this course seemed trivial. The quizzes and exams were identical to the homework (with slight differences), but they were auto-graded through canvas, so a single mistake often meant a ~5% deduction. As one might imagine, this was pretty cruel when working with (binary) machine code and bitwise operations.

CS 354 — Machine Organization and Programming

Intro to C and various low-level topics. Topics include heap allocation, caching, x86 assembly (AT&T), stack frames, signals, and linking; all of these are discussed at a very high level. A handful of projects interlace learning C with small toy-examples of the aforementioned topics. Like in 252, “homeworks” are actually timed quizzes, whose questions are very similar to exam-questions. The class spends little time focusing on the fundamentals of C (it’s framed like a review); it’s pretty much assumed that the student learns C on their own. Reading K&R is the recommended way of doing that.

CS/Math Electives

Math 340 — Elementary Matrix & Linear Algebra

An introduction to the axioms of Linear Algebra. The first few weeks outlined relationships between linear systems and matrices, properties of matrices, matrix multiplication, and matrix inversion. The remainder of the course consisted mostly of memorizing a number of properties of matrices or vector-spaces that had implications on other properties of matrices (i.e. A is invertible <=> Ax = 0 has only the trivial solution <=> A is row (or column) equivalent to I[n] <=> the linear system Ax = b has a unique solution for every b in R^n <=> A is a product of elementary matrices <=> det(A) != 0 <=> the rank of A is n <=> the nullity of A is 0). I took this class at the same time as CS240, which was helpful because although there were no proofs in 340, there was some use of set theory and basic logic that wasn’t completely explained. 340, unlike 341 (which requires Calc 3 as a prerequisite) is not a proof-based class: the professor and TAs made this very clear, and often used it as an excuse not to explain certain properties (whose simplest explanation would likely require a proof). It was kind of amusing hearing “this is not a proof-based class” as a slogan, but it certainly didn’t make the material more intuitive, and as a result, the class consisted almost entirely of memorizing properties, which made the class easy, but not very interesting.

CS 368 — Learn a Programming Language: Python

Zybooks for credit. There were weekly lectures, but attendance was work 5%, while the class was pass/fail (with 80% or above being a pass), and the other 95% was zybooks. In addition to the usual zybooks, there were “zybooks labs” at the end of each chapter, which were similar to leetcode easy problems, often with a few more implementation difficulties. The coverage of Python was in general quite rudimentary (the zybook was an intro-programming-with-Python book), but there were some useful topics covered (list comprehensions, advanced uses of f-strings, variadic functions, etc.).

CS 577 — Intro to Algorithms

An overview of algorithmic paradigms. This class is commonly considered to be one of the most difficult “required” CS classes (520 is the only alternative to this class). It was significantly easier for me because of the large overlap with ICPC, but learning paradigms, problem-solving, proofs, and examples at the same time makes for a hard class. I was lucky enough to find loads of class resources from a previous semester on the 577 Discord (Thanks, Fahim!), so I came into the class having watched all of the lectures and done all of the homework, so I was able to spend time in class reinforcing rather than of discovering. The final was still tough, though.

CS 540 — Intro to Artificial Intelligence

Basic mathematical concepts involving AI. Depending on how you look at it, this class either opens up your eyes to the magical inner-workings of AI or takes all of the magic away because it turns out that it’s just math. The only prerequisite is CS 300; this is most likely because requiring CS 240, Math 340, Math 234, and Stat 324 would be a little cruel, considering that 540 doesn’t use more than a quarter of the material from any of them. Combining this with the inherent complexity behind many of the algorithms and formulas makes for a convoluted class with a lot of hand-waving and incomplete proofs. Luckily, the assessments usually stay out of the weeds. I took this class over an 8-week summer term with professor Young Wu, who set up the class in a way a little different from every other CS class I’ve taken (see the course website for details).

CS 435 — Intro to Cryptography

Overview and analysis of (mathematical) cryptographic algorithms. The course starts by outlining toy/historic/didactic ciphers involving shifts and permutations of the alphabet (Caesar, Affine, Vigenére, Playfair, General Substitution) and mathematical analysis of their security. This is followed by block and stream ciphers (with more formal mathematical definitions) and real-life algorithms involving them are discussed and analyzed (Fistel, DES, AES). The course ends with an outline of public-key cryptography (ElGaml, RSA, Rabin). I took the course over the summer with David Zikel; the beginning of the course was nearly identical to Eric Bach’s Cryptonotes (which may or may not still be available online), but the end of the course went farther into the gory (mathematical) details. The only prerequisite is linear algebra, but the course barely uses it at all (except for the Hill Cipher). Like 540, 435 brushes on a few areas (number theory, algorithms, probability, mathematical proofs, bitwise operations) of which knowledge would be useful, but it would be excessive to require any of them as a prerequisite.

CS 542 — Software Security

A laundry-list of common software vulnerabilities, and how to address them. The course materials are publicly available online. The majority of the topics in this course, once understood, are relatively elementary (they aren’t technically challenging to understand), and there aren’t many of them. As a result, the majority of the course is recitation of ideas already discussed. I’m usually not a fan of such repetition, but in the context of security, I agree with the approach, because of the gravity of the consequences of writing vulnerable code. The primary difficulty of the class lies in the ability to work with a wide range of tools (the command line, web technologies, an assortment of programming languages, and various other tools), and to pick them up on the fly. For that reason, for those preparing for this class, I’d recommend gaining a high-level understanding of C, Python, and Bash rather than reading through the course materials.

CS 559 — Computer Graphics

A mix of mathematical and practical topics regarding the efficient drawing of 2d and 3d scenes. Hierarchical modeling, parametric curves, transformations, projections, the GPU graphics pipeline, and mathematical models for lighting are the main focuses. I took this class with Eftychios Sifakis (Efty), who uses a particularly obscure grading scheme: total_grade = x * (sum_of_project_grades) + y * max(avg(midterm, final), final), where x and y aren’t disclosed. Projects are graded out of 4, and obtaining a 3 is usually quite easy, but obtaining a 4 is a matter of creativity and originality. This framework is a little controversial because of the arbitrariness of how 3s and 4s are distributed (I agree with this critique: distribution is not and cannot be fair), but it gives the student more flexibility over their learning. Michael Gleicher is the other graphics professor at UW: his version of the course seems to be much more structured. Michael and Efty have historically made a lot of course material available publicly online (Spring ‘23; List of Terms).

CS 502 — Theory and Practice in CS Education

An abstract guide to being a decent TA. Approximately 1 hour per week discussing personal opinions on high-level concepts with peers (discussion section), .25 hours reading/responding to various academic writings about tutoring, 1 hour on “the shelf” (the CS Learning Center), 1 hour in a “study group”, and maybe 1 hour observing a TA/Peer Mentor in office hours. I think that this course has good intention, but it’s not very effective. The theoretical portion of it was way too drawn out, repetitive, and obvious to maintain exigence (some of the insights are good, but the presentation didn’t do them service). The practical part of the course was also ineffective, because nobody ever showed up to the CSLC or the study groups. Apparently the course is being reworked, so it will probably be in a different format in coming semesters.

CS 536 — Intro to Programming Languages and Compilers

A (somewhat) practical intro to classic ideas in the space of compilers. As far as I know, this course has not changed an ounce since the 90s. The good part about this is that it contains all of the good ideas that were taught then; the downside is that it’s quite dry and the code for the projects is (in my humble opinion) awful. I’m currently working on a blog post where I refactor the code from this class. The topics are a mix of discrete-math-like ideas (FSMs, Lexing, Parsing) and low-level implementation details (Code Generation, Language Features, etc.). The course material is publicly available online. The central project is divided into 6 parts, dispensed across the semester; the grade is entirely composed of projects (40%) and exams (60%). The project is a reasonable amount of work considering how much of the grade it’s worth.

CS 538 — Intro to the Theory and Design of Programming Languages

Sundries under the large umbrella of PLs. Kaiser, the professor who taught and designed the course (at the time I took it) is young and enthusiastic; he doesn’t have the pretension of older and “more qualified” professors. That being said, the courage has a lot of rough edges. It gets very mathematical at times (with Lambda Calculus, Continuation-Passing-Style, Imperative Proofs, Haskell, etc.), yet also implementation-heavy (JavaScript, Closures, OOP). Many important ideas are covered, but the experience as a whole is a little fragmented. The 9 homeworks, 9 programming assignments, and 2 exams vary greatly in difficulty, and a handful are way harder then they ought to be, often because of needless ambiguity. Some course material may be on Kaiser’s website. Overall, it’s not a bad choice if you are interested in the subject.

CS 368 — Learn a Programming Language: C++

A high-independence C++ workshop. I took this with Tyler, who was on leave at the beginning of the semester, so the 1-credit course was compressed into the second half of the semester. The materials are publicly available on his website. It’s 6 short (25-50 LoC) projects, plus some optional lectures. Grading is pass-fail, and very forgiving. The range of C++ covered is pretty narrow, but that’s to be expected given the breadth of C++, and the most important ideas are mentioned.