Skip to content

Instantly share code, notes, and snippets.

@acbart
Created November 12, 2023 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acbart/627a4635e49ea7d5a25d53e97ef7eba8 to your computer and use it in GitHub Desktop.
Save acbart/627a4635e49ea7d5a25d53e97ef7eba8 to your computer and use it in GitHub Desktop.

image

  • Chapter 1 (Introduction): Covers the basics of Computer Science and programming. This appears to be one of the longest chapters, but is actually one of the easiest and shortest. There is a lot of ground to cover, but the pace is very gentle.
    • Part A: Explains what a program is and the basic input-processing-output model. Covers basics of values and types, simple math and logic, and interactive evaluation of expressions.
    • Part B: Explains variables and assignment statements. Introduces the idea of modules and organizing code with comments and imports. The last bit is about strings and string operations (e.g., slicing). Also covers the idea of errors/exceptions.
  • Chapter 2 (Functions): Introduces the idea of functions as "the smallest atomic unit of programming". This chapter is a little harder than the previous, but students usually don't struggle too much.
    • Part A: Starts off with how to call functions and methods, the ideas of parameters and arguments, and some common built-in Python functions. Then spends a long time explaining the syntax of functions, how return works, and type signatures. Testing functions is introduced almost immediately afterwards, and is used throughout the rest of the book a lot.
    • Part B: Covers more confusing aspects of functions, like the scope rules (do not write variables out of scope) and how bodies work. Also explains docstrings, although students tend to gloss over this more than they should. The most important part (and the part that students hit their first major struggle with) is about data flow: having functions call other functions and pass data between them. The Part ends with more about external functions available in Python, and how to read their documentation (by introducing the Designer game libraryLinks to an external site.).
  • Chapter 3 (If Statements): Covers the idea of if statements in Python, as a way of doing branching logic.
    • Part A: Covers the basic if and else structure, without any nesting. Spends a lot of time on syntax and tracing. Also explains the idea of truthiness in expressions (using non-Boolean expressions as conditionals).
    • Part B: Covers nesting if statements and elif statements, in terms of syntax, semantics, and behavior. Also covers the idea of unnecessary if statements (when a Boolean expression could be returned directly) and Unnecessary Tests (when students test if a Boolean value is ==True). A considerable amount of time is spent on "logical patterns", to give students more examples and mental schemas for using if statements. The Chapter ends with more information about Designer, this time covering events (introduced as a separate kind of execution model, not native to Python).
  • Chapter 4 (Structures): Introduces two different kinds of data structures: dataclasses and lists.
    • Part A: Dataclasses are introduced as a "struct" type to hold heterogenous record data and to create new types. Students are shown the class definition syntax and taught about the constructor. They access attributes, and define functions that consume and produce dataclasses. There is a brief diversion lesson about Worlds in Designer, which is when you use a dataclass to make a more interesting game with multiple components.
    • Part B: Lists are next introduced as the homogenous sequential data type. Remember, lists are not arrays! Students are taught list operations, including membership tests, slicing, and appending elements to lists. Mutability is introduced here (although students have a lot of trouble).
  • Chapter 5 (Project 1): At this point in time, we take a break to do a project (usually 3-card poker) and have the first exam. Everyone catches their breath.
  • Chapter 6 (For Loops): The first looping construct we teach is for loops, as a safe collection-based form of iteration. At this point, students are only going to iterate over lists of primitive values (strings, integers, floats, and Booleans).
    • Part A: The first lesson is about the syntax, semantics, and behavior of for loops. We don't have them do much here, mostly they're just trying to understand the code. However, we then introduce the first set of Loop Patterns, which dominate the rest of this chapter as a tool for writing loop code. The basic patterns are Summing, Counting, Accumulating (a generalization of Summing), Mapping (making a new list based off an old list), and Filtering (using an if statement to optionally remove some elements). In general, students are shown how to modify a list immutably by creating a new list based off the old list.
    • Part B: The next lesson is about the rest of the loop patterns. First is the Find pattern (returning an element in the list that matches a condition; either the first element or the last, depending on the pattern variant). Then is the Take pattern, where you return elements of a list as a new list, up until a certain condition is met (compare to slicing, which uses a specific index instead of a condition). Then there is the Minimum/Maximum pattern, which is one of the most complicated for students. However, the hardest part of the chapter is the last lesson, where students are asked to decompose complex problems into helper functions by composing the loop patterns we have taught them. Some of these questions are among the toughest in the course for students!
  • Chapter 7 (Sequences): This chapter is a bit of a grab-bag of things related to sequences.
    • Part A: First the idea of indexes are revisted, with time spent on accessing specific elements of lists both to read AND update. This is a chance to explain the difference between value iteration (the default behavior of for loops), index iteration (using the range and len functions), and combining the two with enumerate. Students get to mutate a list a little, though we discourage this. The other lesson covers the basics of iterating through a string and the use of the split method.
    • Part B: Exposes students to the idea of file systems and the basic of shell commands (though admittedly they do not do much with those). More time is spent on the other lesson, where they read data from files using the open function. Files are traversed either as a sequence of lines or as a single string via read method.
  • Chapter 8 (Nesting Data): One of the last major escalations, this takes students from list of primitive values to lists of dataclass instances. It's technically nothing they haven't seen before, but it still becomes MUCH harder.
    • Part A: This chapter introduces the idea of nesting dataclasses inside of lists and then inside of dataclasses. The former revists all the previous Loop Patterns, albeit with more complexity. The latter is actually not too difficult for students, and is relatively short.
    • Part B: This chapter first covers 2D lists (lists inside of lists). This requires coverage of nested iteration, which surprisingly isn't too bad for the students. The second half, though, is heavily nested data where there are multiple layers of lists and dataclasses. We use this opportunity to show UML diagrams in order to capture the relationships and scaffold their understanding.
  • Chapter 9 (Project 2): Another project (the Crypto Corgi, usually, although that only focuses on Chapter 7 material and not Chapter 8) and another exam.
  • Chapter 10 (While and Plotting): The chapters start being more grab-bag and variable here. We have mixed this content around a bit sometimes.
    • Part A: This is usually while loops, since those are a critical topic. We show the syntax, semantics, and behavior, and then teach some patterns. However, we generally steer students a bit more towards for loops since those are a safer form of iteration. This also introduces the idea of infinite loops.
    • Part B: A short lesson on Plotting is here, mostly built off the lists-of-dataclasses material. The only plots covered (using Matplotlib) are histograms, line plots, and scatter plots.
  • Chapter 11 (Time and Trees): This chapter might seem a little random, and it kind of is. It's "all the rest of the good CS stuff".
    • Part A: The first lesson is about Time Complexity. We do not talk about Big Oh, but focus instead of the RAM model and case analysis. To motiviate the discussion, the next lesson goes into binary search and sorting as concrete algorithms to study.
    • Part B: The last lesson is one of the most difficult and chonkiest, about recursion and trees. This actually even covers a bit of object-oriented programming (inheritance). The reason is that statically type checking recursive data in Python is still a huge pain. We teach students a form of Trees with an abstract base class that has a null EMPTY instance and then an implementing BinaryTree subclass for holding actual data. This works safely, and allows us to cover structural recursion (although we leave generative recursion aside).

So what do we actually do in the classroom? Each week is described below; the parenthetical next to the week describes what the textbook is covering.

  • Week 1 (Introduction):
    • Lecture: We spend a lot of time on the syllabus, and then do a fun little game where they are "computers" and "programmers". The "programmers" are given a word, and have to give instructions to the "computers" to draw and guess that word. The catch is that they can only use simple primitive shapes (e.g., "a blue square below a big red circle"). This tries to cover the fundamental ideas of Abstraction and Algorithms.
    • Practicum: We usually cancel practicum the first week because things are just too hectic and TA assignments usually aren't finished. We sometimes provide that time as a chance to help students get things set up.
  • Week 2 (Functions):
    • Lecture: This lecture is all about seeking help. We explain good strategies for how to ask for help and provide them structure for doing so correctly. The activity has them work in groups to respond to scenarios where people need help.
    • Practicum: This practicum is meant to reinforce the material about functions. Students are asked conceptual questions about functions and respond to them in groups. It's also a chance for TAs to introduce themselves.
  • Week 3 (If Statements):
    • Lecture: This lecture is about Code Coverage and the value of writing good tests. They do a game called Wheats and Chaffs, where we have a bunch of broken and working programs. Students have to write test cases that pass the good programs (wheats) and break/fail on the bad programs (chaffs). This imparts the idea of "Validity" and "Thoroughness" in tests. Students struggle a lot with this game, although that is very good for them because it's a great critical thinking activity. The delivery is a BlockPy coding assignment rather than a google doc, so students submit individually but still work together in pairs.
    • Practicum: This practicum is meant to reinforce the material about if statements. Students work together in groups to trace a big complicated set of function calls that involve if statements.
  • Week 4 (Structures):
    • Lecture: This lecture is about making "abstractions" out of real world data. Mostly, they are making up dataclasses to represent something with complex multiple parts. You have to watch them on this, they make SO MANY mistakes from not reading the instructions.
    • Practicum: This practicum is meant to reinforce the material about mutability. Students have to make predictions about whether different data types will be mutated during function calls. They struggle with this stuff.
  • Week 5 (Project 1/Midterm 1):
    • Lecture: A classwide discussion about Imposter Syndrome, and the effects of underepresentation in Computer Science on society. Students complete a worksheet together, but a lot of this is about sending them a message, I think.
    • Practicum: Students work on the project and get help from the TAs.
  • Week 6 (For Loops):
    • Lecture: This is all about how to interpret decomposed complex functions. Students are given a large program that iterates through lists of primitive data, and must trace out its values. Honestly, we need to revisit this activity because they just don't know how to follow instructions.
    • Practicum: This practicum is meant to reinforce the material about for loops. Students answer questions about lists of strings related to cards, figuring out what kind of loop patterns they would apply.
  • Week 7 (Sequences):
    • Lecture: The lecture material is about debugging complex functions, and the power of unit testing and decomposition. The activity is the "Flower Garden", where they given two different versions of a complex function, one where the logic is decomposed and one where it is not. The code of the functions is broken in five places each, but correct unit tests are provided. Students have to debug the logic in groups (submitted individually through BlockPy).
    • Practicum: This practicum is off the reservation by having students complete a Designer tutorial to make a little game where they click on a teleporting emoji. This is good if you want students to eventually make a Designer game, but probably not as relevant otherwise.
  • Week 8 (Nesting Data):
    • Practicum: Students work in pairs or individually on an autograded coding assignment called the Monster Mash. This is meant to reinforce the Nested Data material of this chapter. It's important that students complete the material this week before making too serious an attempt, which is probably an issue we should revisit.
    • Lecture: Students do a new version of the Week 3 assignment (wheats and chaffs) to write valid and thorough test cases, but this time for nested data.
  • Week 9 (Project 2/Midterm 2):
    • Lecture: The lecture material is about web requests via request and our own custom libraries (critical for setting up the final project). Students work on a long worksheet that has great material but might be a bit too long. But for 108 students, they actually do the Firefighter game tutorial to learn more about making games. Basically, this week is whatever we need to get them to do the final project.
    • Practicum: For CS majors, this lab is all about asking the TA questions about the Computer Science degree, signing up for classes, and stuff like that. But for all students, it's also a chance to ask for help reviewing for the exam this week and to get help on the project.
  • Week 10 (While Loops, Plotting):
    • Lecture: The final project is introduced and students are given time to work on it during lecture.
    • Practicum: Time to work on the project.
  • Week 11 (Recursion and Trees):
    • Lecture: Time complexity analysis, using the Runtime Case Builder tool. They aren't learning Big Oh, but they are tracing constant, linear, and quadratic time functions.
    • Practicum: Time to work on the project
  • Week 12:
    • Lecture: Should be a lecture on Variable Naming, where we give them an obfuscated program and they have to pick out better names. The actual slides are about "Technical Debt" to, but it's really just focused on the importance of picking variable names.
    • Practicum: Time to work on the project.
  • Week 13 (Thanksgiving Break)
    • Lecture and Practicum: Cancelled.
  • Week 14:
    • Lecture: Time to work on the project.
    • Practicum: Time to work on the project.
  • Week 15:
    • Lecture: Final lecture! We wrap up the course and leave them with parting words of advice.
    • Practicum: Tearful goodbyes, I assume. Also time to work on the project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment