Princeton’s Intro to CS Course Review

MARCH 12, 2023

The MOOC - Computer Science: Programming with a Purpose

The basis for education in the last millennium was “reading, writing, and arithmetic;” now it is reading, writing, and computing. Learning to program is an essential part of the education of every student, not just in the sciences and engineering, but in the arts, social sciences, and humanities, as well. Beyond direct applications, it is the first step in understanding the nature of computer science’s undeniable impact on the modern world.

This MOOC covers the first half of the book “Computer Science: An Interdisciplinary Approach” (the second half is covered in the course Computer Science: Algorithms, Theory, and Machines)

This is an introductory CS course, where you will learn about basic programming elements such as variables, conditionals, loops, arrays, and I/O. Next, we turn to functions, introducing key concepts such as recursion, modular programming, and code reuse. Finally, we get introduced to object-oriented programming.

Few weeks ago, we conducted a study group on this course:

📕 The Curriculum

• Basic Programming Concepts
Why program? This module addresses that basic question. Then it describes the anatomy of your first program and the process of developing a program in Java using either virtual terminals or a program development environment, with some historical context. Most of the module is devoted to a thorough coverage of Java's built-in data types, with example programs for each.

• Conditionals & Loops
The if, while, and for statements are Java's fundamental control structures. This lecture is built around short programs that use these constructs to address important computational tasks. Examples include sorting, computing the square root, factoring, and simulating a random process. The lecture concludes with a detailed example illustrating the process of debugging a program.

• Arrays
Computing with a large sequence of values of the same type is extremely common. This module describes Java's built-in array data structure that supports such applications, with several examples, including shuffling a deck of cards, the coupon collector test for randomness, and random walks in a grid.

• Input & Output
To interact with our programs, we need mechanisms for taking information from the outside world and for presenting information to the outside world. This module describes several such mechanisms: for text, drawings, and animation. Detailed examples covered include fractal drawings that model natural phenomena and an animation of a ball bouncing around in the display window.

• Functions & Libraries
Modular programming is the art and science of breaking a program into pieces that can be individually developed. This module introduces functions (Java methods), a fundamental mechanism that enables modular programming. Motivating examples include functions for the classic Gaussian distribution and an application that creates digital music.

• Recursion
A recursive function is one that calls itself. This module introduces the concept by treating in detail the ruler function and (related) classic examples, including the Towers of Hanoi puzzle, the H-tree, and simple models of the real world based on recursion. We show a common pitfall in the use of recursion, and a simple way to avoid it, which introduces a different (related) programming paradigm known as dynamic programming.

• Performance
When you develop a program, you need to be aware of its resource requirements. In this module, we learn about a scientific approach to understanding performance, where we develop mathematical models describing the running time our programs and then run empirical tests to validate them. Eventually we come to a simple and effective approach that you can use to predict the running time of your own programs that involve significant amounts of computation.

• Abstract Data Types
In Java, you can create your own data types and use them in your programs. In this and the next module, we learn about this ability which allows us to view our programs as abstract representations of real-world concepts. First we learn the mechanics of writing client programs that use data types. Our examples involve abstractions such as color, images, and genes. This style of programming is known as object-oriented programming because our programs manipulate objects, which hold data type values.

• Creating Data Types
Creating your own data types is the central activity in modern Java programming. This lecture covers the mechanics (instance variables, constructors, instance methods, and test clients) and then develops several examples, culminating in a program that uses a quintessential mathematical abstraction (complex numbers)
to create visual representations of the famous Mandelbrot set.

• Programming Languages
We conclude the course with an overview of important issues surrounding programming languages. To convince you that your knowledge of Java will enable you to learn other programming languages, we learn about the implementations of a typical program in C, C++, Python, and Matlab. We look at some of the important differences among these languages and address fundamental issues, such as garbage collection, type checking, object oriented programming, and functional programming with some brief historical context.

🚀 The Projects

Each week you will work on programming assignments which are auto graded. In each assignment, you will be solving 3-4 problems. The problems revolve around that week’s topics and lecture content.

For example, in week 1 (Basic Programming Concepts), you will implement the Haversine Formula, to calculate the great-circle distance - the length of the shortest path between two points (x1, y1) and (x2, y2) on surface of the sphere, where the path is constrained to be along the surface

In week 2, you implement the Band Matrices program that prints a n-by-n pattern like the ones below:

Next, you write the RandomWalker program that simulates the motion of a random walk until the random walker is at Manhattan distance r from the starting point.

In week 3, we implement a program to print Thue-Morse sequence: an infinite sequence of 0s and 1s that is constructed by starting with 0 and successively appending the bitwise negation (interchange 0s and 1s) of the existing sequence.

In addition, we solve the “Birthday Problem”

Birthday Problem: Suppose that people enter a room one at a time. How people must enter until two share a birthday? Counterintuitively, after 23 people enter the room, there is approximately a 50–50 chance that two share a birthday. This phenomenon is known as the birthday problem or birthday paradox

In week 4, we work the Input & Output libraries. We write the “Checkboard” program, that plots an n-by-n checkerboard pattern to standard drawing.

Following this, we write a program “World Maps” that reads boundary information of a country (or other geographic entity) from standard input and plots the results to standard drawing.

In week 6, we solve the “Reve’s Puzzle”. Reve’s puzzle is identical to the towers of Hanoi problem, except that there are 4 poles (instead of 3). The task is to move n discs of different sizes from the starting pole to the destination pole

In addition, we wrote a program that takes an integer command-line argument n and plots a recursive square pattern of order n.

In week 8, we implemented an image-processing library that applies various kernel filters to images, such as Gaussian blur, sharpen, Laplacian, emboss, and motion blur. A kernel filter modifies the pixels in an image by replacing each pixel with a linear combination of its neighboring pixels. The matrix that characterizes the linear combination is known as the kernel.

In week 10, we used animated bar charts in our java program

📔 Prior Requirements

• Most students in our group found the course challenging and intimidating. Even though it’s supposed to be an introductory course, most of us agreed that you need to have a strong background in mathematics before you enroll in this course.

• In addition, we also found that this course isn’t ideal for beginner Java learners. While the lectures cover several topics, we found that it does not teach the basics clearly. Most of the lectures revolve around abstract ideas and concepts.

• We recommend that you first study the following courses:

1. Algebra: Elementary to Advanced Specialization
2. Java Programming: Solving Problems with Software

📅 Duration

The course is around 80 hours long. Depending on your background and experience, we’d say that the course will take 5-7 weeks to complete.

Our study group took 7 weeks to complete the course, spending around +10 hours every week.

😃 Pros

1. Free & Accessible: The course is 100% free (no need to audit as well). However, you won’t receive a certificate on completion.

2. Suited for intermediate learners: As mentioned above, this course covers important concepts. This might not be suited for every beginner learner, however, this course is a good fit for someone who has 1-2 years of experience with Java. A student commented “Being a software developer for 10 years I really wanted to try something new and evaluate myself. You would be surprised to know this course made me realize the depth of actual Math behind all that I do and never cared how it actually happens.”

3. Abstract concepts covered really well: Adding on to the previous point, the instructors - Professor Sedgwick and Wayne - have presented clear and concise lectures on abstract programming concepts, such as Object Oriented Programming, Abstract Data Types, Recursion, and Performance. While some beginner learners will find the mathematics part of the course challenging, I believe this course does a brilliant job in teaching core CS concepts. You get to work with Input/Output functions, Audio Processing, Image Processing, and design abstract data types and classes.

4. Blend of Mathematics, Science, and Programming: “This course is without any doubt a perfect blend of Mathematics, science, and programming. Taking this course can help you improve your programming skills to a great extent. The instructor’s teaching style is very unique and the assignments were challenging but helped me think out of the box.” - a student reported.

☹️ Cons

1. Not for beginners: Several students of our group found the group really challenging. If you are completely new to CS and Java programming, I would not recommend signing up for this course. Not only will you find too difficult and time consuming, but it might discourage you to enroll in other course as well. I’d recommend that you enroll in the courses mentioned above, and then, revisit this course.

2. Time consuming assignments: Although we loved working on the weekly assignments, we found them taking really long hours. There were assignments that ended up taking 6-8 hours to finish. There is tremendous value in solving the assignments - that’s for sure. But, it’s important that you have clear expectations from this course. Be prepared to spend +10 hours per week to finish this course.

3. Perhaps too abstract: If you are looking for a course to learn Java programming, then I wouldn’t recommend this course. This course is meant as an introductory Computer Science course - as taught at undergraduate colleges. Thus, you will spend more time learning, understanding, and solving abstract problems, than actual Java programming.