ICS 32A Fall 2023
Notes and Examples: Course Introduction


What is ICS 32A?

ICS 32A is a course that is targeted at students who have prior introductory programming experience, with the goal of leaving students with the same knowledge and skills at the end that they would obtain by taking both ICS 31 and 32. However, it is not simply the combination of both courses, taught at twice the speed. It is instead aimed particularly at students who have passed the AP Computer Science A exam, or who have studied introductory programming in some language other than Python, with that experience being recent enough that their skills remain largely intact.

It's not particularly important to consider what programming language you learned previously. While we will, from time to time, relate concepts in Python to concepts in other languages that you may have seen, such as Java, this is not a "Python for X Programmers" course for any particular programming language X. What's important is the set of skills you enter the course with, which should include the following:

Certainly, we would expect students passing the AP Computer Science A exam to have built those skills, as they form the core of that coursework, though there are other ways to obtain them besides an AP course, such as taking courses at a community college. What's important isn't so much what it says on a transcript or a score sheet; what's important is what you're capable of doing already when ICS 32A starts.

Is ICS 32A an "honors" course?

The title of ICS 32A in the course catalogue includes the word "Accelerated," and you might have taken a lot of courses in your academic past that were "honors" or "accelerated" courses, so you might infer from that previous experience that you should take ICS 32A, because you think of yourself as a more capable student than your peers, and that you would expect to get more out of such a course than taking the "normal" ones.

It's important to understand that ICS 32A is not an honors course; it's a different path to get you to the same place that ICS 31 and 32 would get you. The only difference is the assumptions that are made — ICS 32A assumes you've written programs before — and, because of those assumptions, the speed at which certain topics will be covered.


Course background and goals

Despite its alternative starting point, this course is part of our first-year introductory sequence, which focuses on introducing you to computer science and to programming using Python. It builds directly on your prerequisite work — AP Computer Science A, or at least one introductory programming course in some programming language — and emphasizes techniques used to write larger, more complex programs than you may have written previously. Each project we ask you to work on will inhabit a different, realistic problem domain. Additionally, this course introduces Python, under the assumption that you've written introductory-level programs in something other than Python previously.

At the end of the course, you should be able to write programs much larger than you could before, and you should feel like you're empowered to work on your own programs in whatever problem domains interest you, even if you haven't learned about them in class yet. While it's not as though programming will suddenly become easy for everyone, we do intend to demystify "real-world" programming to the point where, after this course, you're able to make positive progress on realistic problems of your own choosing.


Where we're going

Before we embark on our journey, it's not a bad idea for us to take a look at what lies ahead.

Python

Python is a programming language, which we've chosen in our first-year courses because it provides a good mix of simplicity early on — it requires understanding relatively few concepts to get started writing programs — while offering versatility and depth as we move further through our first-year sequence (and beyond) — as it includes a wide variety of built-in functionality and exposes (and allows customization of) many of its inner workings directly within the language.

Depending on what programming language(s) you've learned previously, you might find yourself right at home in Python, or you might find it quite different from what you're used to. Seeing things that are familiar may make you — subconsciously or purposefully — gravitate toward the parts that are familiar and away from the parts that are new. However, it's vital to catch yourself when you're doing that and think more carefully; when you learn any programming language, it's vital to understand the ideas, idioms, and tools provided by that language. Just as you can't effectively speak or write a natural language like French simply by translating individual words from another like English, you similarly can't translate a Java, C++, JavaScript, or Ruby program line-for-line into a well-written Python program. You might be able to barely communicate with someone by translating individual words, and you might be able to barely write a working Python program by translating it directly from something else, but you'll have written a much better Python program if you approach it the way a Python programmer would. You have to embrace what makes the language you're learning great and, in so doing, you might discover new techniques that you can bring back to the languages you already know.

We'll spend time throughout the quarter learning about Python, not specifically in terms of any one other language, but in terms of what gives Python its own character.

Software libraries

This course has kind of a peculiar-sounding title: Python Programming with Libraries. A software library is a collection of functions that are already implemented to solve a particular kind of problem. Ideally, libraries also include documentation that explains how to use them, e.g., what the names of the functions are, what inputs they accept, what outputs and effects they give as a result, and in what ways they might fail.

Many software libraries are provided free of charge, perhaps contingent on you following certain licensing rules (e.g., having to distribute the other party's copyright message with your program, or a prohibition on selling the program you built using the library). Others are available for purchase. But, in either case, they're about access to functionality that might otherwise be hard or costly for you to build on your own.

Even if they don't cost money, software libraries come at an intellectual price. If you want to use a library, you have to understand something about the problem domain — the kind of problem that it solves, the terminology that's used to describe aspects of that kind of problem, and the basic concepts involved in its solution. You have to be able to understand the contract between you and those libraries: what inputs you need to provide and what outputs and effects you can expect in return. Even if there's well-written documentation, you'll still have to spend time reading it, understanding it, and determining whether the library really is a good fit for solving some part of the problem you have.

Quite often, though, that price is vastly lower than the price of building the same code from scratch. You already know from your prior coursework that writing programs can be tricky. There are small-picture and big-picture details to get right. There are plenty of opportunities to make mistakes, to write code that doesn't work as you intended, to write individual pieces that work but that don't fit together the way you expected, and so on. There's a lot of value in code that's already written, especially if it's been heavily used by a wide audience, if it's been in use for a long period of time, and if it's well-documented.

So, libraries can be very useful indeed. There are tradeoffs, though, when you use libraries built by others. You don't get to do everything your way. You sometimes have to adjust your thinking and your design to match what's provided by the library. You may discover that the library doesn't behave the way it's been documented, that the documentation is inadequate and doesn't tell you what you need to know, or that the code is simply buggy in places. You may find that there are vital things you need that the library doesn't provide, even if it provides some of what you need.

Python's standard library

Most programming languages include some kind of standard library, which provide a range of features that are available to any program written in that language. Python is no exception to this; it has a very large standard library, containing all kinds of interesting and useful tools:

Python's standard library provides the tools to do all of those things (and many more). We'll spend a fair amount of time in this course learning about some parts of the Python standard library, each time with a particular problem domain in mind, with a desire to solve a particular kind of problem. We'll see how to recognize which parts of a problem have solutions in the standard library, as opposed to the parts we'll have to write ourselves. And you'll build confidence that you can figure out these kinds of details on your own when you have new needs that you've never had before.

By the end of the course, I want you to be empowered; I want "real" problems to seem accessible to you. I want you to feel that you can dream up new applications that you might like to have, find libraries that are appropriate and learn how to use them effectively, even if they're things we didn't learn about in this course. After the quarter is over, I want you to be able to write something cool that you think today is beyond your reach.

That's the goal. The sky's the limit.


A word of warning

Before we delve into the details, there are a couple of things I should warn you about.

First of all, the problems I'll be asking you to solve this quarter are quite a lot larger than the ones you solved in previous coursework. There are techniques for managing that complexity, and we'll talk about them early and often. But you'll need to be aware that there is a new set of skills, namely design skills, that you'll need to begin developing in order to succeed in this course. While we'll certainly guide you along the way, we'll gradually expect that you're able to decide on your own what components you need, how they should interact with one another, and what each one should do. As we'll see, taking the time to divide a solution into smaller parts, then to isolate those parts from one another as much as possible — so that changes to one don't require a cascading set of changes to others — is paramount.

As we delve into libraries, I should warn you that there is almost no one who has every detail of every library call memorized. In fact, I'd argue that you shouldn't even want that level of memorization, as it serves little purpose. With an Internet connection, you can look up the details you need as you need them. The important thing is to have a good understanding of what you're looking for, so you can formulate a search query that will help you find it, and so you can recognize when you have found it. You'll get stumped along the way, your TAs will get stumped, your tutors will get stumped, and I will, too. Getting started early, getting questions asked when you have them, and giving yourself time to put your work aside and let yourself turn it over in the back of your mind a few times are going to be paramount.


Course organization and logistics

This course web site describes the logistical details of how this course is going to be run. Particularly, be sure that you read through the Course Reference and the front page of the Project Guide, so you will know how this course operates, and how you'll be doing and submitting your work.