Omninox

A blog about education technology, teaching, learning, and startups

Pythonic AP Computer Science Principles (APCSP) Course Framework

Pythonic APCSP: Introduction

When College Board announced the launch of AP Computer Science Principles (APCSP) in 2016, you could feel the excitement among the Computer Science teachers at the AP Conference in Anaheim, CA. 10 months later, the numbers confirmed that it was the largest course launch in AP history with 45,000 end of course exams taken in May 2017.

In many ways, it was a necessary introduction because going from no programming experience straight into Java is like learning to swim in the deep end. All of the rules and intricacies of working with code come rushing all at once. Some students can swim but others need more help in getting adjusted to the strict rules of a language like Java. It can also be difficult to connect the dots on how Java is actually useful in programming interesting projects like games.

Since APCSP has now effectively become a prerequisite to AP Computer Science A, this will hopefully lead to stronger performance in both subjects. Plus, with the buzz around Computer Science education and technology’s increasing role as a necessity in all fields, teaching kids to become better with computers for one more year can only be a good thing.

Why Teach Programming in APCSP

Before going into which is the best programming language to teach in APCSP, let’s answer the question of why ANY programming language should be taught in APCSP. The College Board’s curriculum is abstract enough that just teaching the concepts without any real programming involved should be enough to pass the class and AP exam, but here's the rub:

If the goal of a prerequisite class is to prepare students for the higher level class, then any APCSP curriculum where students don’t work with actual code would do a poor job of preparing students for Java in AP Computer Science A.

Introducing students to a programming language in APCSP has two benefits: 1) It acts as a filter so that students who like programming can pursue AP CS A, and 2) The relatively abstract Big Ideas found in the College Board’s course description become much clearer when implemented with an actual programming language.

Also, among all of the programmers I’ve worked with, the best ones have multiple years of programming experience, often having started at the age of 12 or even younger. One extra year of programming will only help students become more proficient and marketable for almost any job.

Why Python? And only Python

Although I started with Visual Basic for Applications (VBA) when learning programming, looking back after 5 years of being in the educational software industry, I would recommend a beginner start with Python. Although it is a more “difficult” language compared to VBA or some of the other languages taught in APCSP like Snap! and Scratch, it is a very practical language for students who may consider a career in the field or even just for building web apps.

The nature of Python also allows students to go deep into it, so even if this is the only language they learn, they can really learn it and use it to understand many intricacies of computer science. This is great for the gifted students who love to explore and push the limits of their own knowledge. Combine this with its thriving developer community, a relative ease of getting it up and running on any computer (including Chromebooks), and its high level of readability, and you have the perfect combination of an ideal language used for teaching Computer Science to high schoolers. Now let’s go into what you need to teach Python.

Requirements and Materials

Although there are no academic requirements for doing well in APCSP, to understand Python well it is recommended that students have taken Algebra 1 + 2 and Geometry.

Classroom materials (required):

  • A teacher computer that can project Python code onto a screen or board
  • Students with access to a computer / tablet with a web browser at home or in the library

Classroom materials (recommended):

  • Each student has his or her own computer in class
  • Wifi access for all students
  • Ability for students to install their own software

Software requirements

Python Compiler and Text Editor

Pythonic APCSP Course Framework

Now that we have the requirements covered, let’s get into what a programming-oriented APCSP class could look like and how it would align to the College Board’s official Course Description for APCSP.

Unit 1: The Internet and its Global Impact

Recommended Time: 20 hours in class, 15 hours at home

This unit covers Big Idea 6 (The Internet) and Big Idea 7 (Global Impact) in the College Board Course Description for APCSP. The inspiration for starting at the end comes from the famous TED Talk by Simon Sinek on starting with the “Why”. New students coming into APCSP will wonder “Why learn computer science? Why is it important?”. Given that it is an introductory course to AP Computer Science A, answering this question well will engage students through the rest of the course and inspire them to persevere through AP CS A, which is much more challenging and rigorous.

If our goal as educators is to increase the number of students going into STEM fields, and especially Computer Science, we must be able to answer this question of “why” with clarity and precision, especially for girls and underrepresented minorities, and it’s the last two Big Ideas in the College Board’s outline that get to the heart of this question on “why” we should be learning computer science.

It starts with telling the story about how the Internet is actually a network of computers that communicate with each other. Although it started out as just a two-way communication channel between two computers, as more computers were added, it became a network and enjoyed many of the benefits of “Network Effects”. Similar to a telephone, as more users join this network, the more its reach, value, and development would accelerate. Built on the spirit of openness, it was analogous to the “wild wild west” in the early days, but eventually matured over time as the protocols underlying it and security standards became established for more widespread consumer use.

As the Internet matured, the applications built on top of it also matured. What started out as simple text-and-image websites ended up becoming full-fledged applications, leading to the rise of giant technology companies, social networks, and mobile applications like Google, Facebook, Twitter, and Snapchat, among others. Throughout the early 2000s, the standards and technologies that made up web browsers, like HTML and JavaScript, also matured and became more powerful. Hardware also continued to become more powerful and more portable during this time period, and consumers in emerging economies like India and China adopted smartphones in droves, leading to a perfect storm of increase in internet users and applications.

The reason some of these applications matured and became large technology companies was not only because of the Internet’s wide reach, but also because they solved critical social problems in communication (messaging apps), entertainment (games and on-demand sites like Netflix), and finding valuable information (Google). Like the Internet, many of these companies had the same “Network Effects” that increased the value of their services as each additional user joined their platform.

Covering the history of the Internet and its global impact from the beginning to the present day will provide students with a good framework to understand how, at the core of these companies, is a collaboration among several talented engineers, digital marketers, product managers, data scientists, and other professionals with a high level of technical expertise. The one skill that most of them share in common is a strong understanding of technology and programming.

Unit 2: An Introduction to Programming Concepts

Recommended Time: 30 hours in class, 20 hours at home

This is the Unit that covers the creative side (Big Idea 1) and also the technical side (Big Idea 2) of Computer Science Principles. We continue where we left off with the Internet’s global impact and first get into the creative problems that computer scientists have to solve to develop web and mobile applications. The representation of design elements on a screen, the layout, the user experience, and navigation all have to seamlessly work together in order to provide users with a memorable experience.

Whereas Unit 1 covered the history of the Internet, its function, structure, and impact, this Unit provides more specifics into how computers actually communicate with each other, represent data, how this data is structured with 0’s and 1’s at the hardware level and translates into readable applications and code after various layers of translation from the hardware into more readable source code programmed through various languages. This involves learning about how computers work at a hardware level, including the functions of key components in a computer like a CPU, memory, hard drive, motherboard, and graphics card.

Students will also engage in “computer math” and work with numbers in base 2, base 16, and then extrapolate this information to how this data can be stored to represent different aspects of an application. For example, all color and shades can be represented by combining 256 shades of Red, Blue, and Green. This produces 2563 colors, or almost 17 million different colors. Then use this information to calculate how many bytes this data takes up.

This is also a great unit to teach different software programs that various professionals use in their software development work, like:

  • Text editors - The minimalist way to write and edit code. Examples of text editors used by developers include Sublime Text, Notepad, Atom, or for more advanced users, terminal-based text editors like Emacs or Vim.

  • Integrated Development Environments (IDEs) - Whereas text editors provide a minimalist way to write and edit code, IDEs are on the other side of the spectrum. They often try to infer and auto-complete commonly written blocks of code through intelligent shortcuts and try to “integrate” both writing a program and running a program. The most sophisticated IDEs may also have seamless integrations with a bundle of commonly used libraries. Due to the rich feature set, IDEs are usually specifically tailored to a particular programming language, whereas text editors are an all-purpose way to edit code.

  • Software Development Kits (SDKs) - SDKs are exactly what they sound like: an entire toolkit of libraries, files, software programs (often including an IDE), programming languages and their interpreters / compilers, etc. packaged in one bundle. For example, the Android SDK can be downloaded freely from Google in order to develop apps for Android using Java. Similarly, developers can use the iOS SDK can be used to develop apps for the App Store on iOS.

  • Versioning Systems and Software Repositories - Since software development follows an iterative, collaborative approach with frequent updates, it often helps for developers to keep track of their software versions, previous source code and edits they’ve written, and a way to communicate and collaborate with other developers on software projects. The uncontested best resource to check out here is github.com.

The above tools show a very important and interesting trend in computer science, where advances in software make software development easier, more productive, and more accessible. Things that many developers take for granted today, like starting up a web server or collaborating on project-level source code using Github were much more difficult to accomplish just a decade ago. Computer scientists are especially good at building tools for each other because they intimately understand their users. This makes programming more productive and accessible for newer users over time, which is why many high school students can now take two programming classes through their AP program instead of just one.

Often, cross-disciplinary collaboration and creativity across various disciplines is required to build tools for different audiences. In order to run Physics simulations, for example, computer scientists must work together with physicists, or physicists have to learn computer science in order to model and measure real-world events. This is another reason why it’s important to learn computer science regardless of the field of study because Computer Science affects all fields in some way. Computers an store data about modeling and measuring the real world through simulations using a small or large amounts of data. The larger the size of this data, the more complex the simulation or measurement becomes (think Physics or Biology simulations). How this data is represented and shown on a computer is discussed in the next unit.

Unit 3: Working with Data and an Intro to Python

Recommended Time: 40 hours in class, 25 hours at home

This is the unit that will make the transition into writing actual programs and code. It primarily focuses on Big Idea 3, how programs represent data. First, it’s important to reiterate a concept from the previous unit to students—that data can be used for simulating and even recording real-world phenomenon. This data is often stored in a more structured collection of documents called a database, and computer scientists can work with databases by writing queries.

The larger the data, the longer it takes to analyze it, but with advances in hardware, the amount of data we can handle with current computing power has grown by leaps and bounds. Computers that used to take up entire rooms to process megabytes of data can now fit in our pockets. Industrial grade servers are now available to rent for small projects for free or as little as $20 per month with advances in cloud computing.

Data about data, metadata, is a common way of categorizing data for easier filtering and processing. All of these functions are supported by databases that can be hosted on web servers or on a personal computer. Advances in ways data can be structured has led to an explosion of different file types in the 21st century. What started with plan text files in the 20th century evolved into audio files, video files, and proprietary files that work with specific pieces of software. All of these files store data and specific programs know how to “play” this data in ways that allow us to hear sound, view images, or watch videos.

It’s also important to cover the implications of there being such an abundance of data in today’s world, especially the implications on user privacy. As more data is stored in the cloud through social networking apps, cloud storage services and applications that run in the cloud, we are making an implicit decision to trust these providers with our data. Although most of the time these applications are built on existing secure frameworks, the failure to implement cybersecurity properly can have far-reaching consequences ranging from email leaks to events as extreme as election manipulation.

Despite the complexity around the use of this data, at a fundamental level it is stored as bits and bytes. At a more human-understandable level, it is stored as “data structures”. These data structures are often conceptually familiar, like words, numbers, one-to-one relationships, collections of items, among others.

At this point in the class, it’s appropriate to start showing students code samples and go into working with various data types, like strings, floating point numbers, integers, lists, dictionaries, and tuples in Python. The Python documentation provides guidelines for this in more detail, but I’ve also attached some sample code file templates that you can start with and expand upon.

Unit 4: Designing Algorithms with Python

Recommended time: 40 hours in class, 30 hours at home

Up until now, we have looked at how data can be stored and structured by programming languages like Python and how these data structures help us access data in convenient ways, but we haven’t learned to make sense of this data yet. We also haven’t quite internalized some fundamental programming principles, like “Don’t Repeat Yourself (DRY)”, conditional selection, and loop-based iteration. Combined these three concepts form the building blocks of algorithms (Big Idea 4), a set of instructions that a computer executes to efficiently solve a problem.

These are fairly complex concepts and designing algorithms is often challenging. At this point it makes sense to introduce pseudocode as a way to structure an algorithm before implementing it in a particular language. Pseudocode is made up of the logical components of code without actually being implemented in the language and fully debugged. This is helpful for separating the logic from the syntax.

We will see examples of pseudocode soon, but even pseudocode should be DRY code and not repeat itself. Writing DRY code saves students time and also helps makes programs more readable and maintainable for other programmers. In addition to writing DRY code and pseudocode, now is also the time to get into conditional programming.

Conditional selection allows programmers to build very powerful algorithms and programs. For example, in order to write a program that automatically turns off the AC when you leave, the program must be able to detect whether you’re still in the house. Then it must make a decision whether to turn off the AC or not based on the “state” of there still being a person in the house or not. Assuming it’s easy to tell whether someone is in the house, we don’t want the AC to turn on or stay on when someone is not in the house. We also don’t want it to turn off automatically while someone is in the house. These scenarios are shown by the table below.

The goal of a good algorithm is not only to do something when a specific condition is met, but also to not do something or do something else if that condition is not met. This is the principle behind conditional selection. An algorithm executes a specific block of code depending on which conditions are met at the time of execution.

The pseudocode for something like this would look like:

if (person is in house):  
    use manual mode
else if person just left:  
    turn AC off
else assume no one is in the house:  
    make sure AC is off

Based on the above pseudocode we can see that we need three functions to effectively use if-then logical statements: 1) an “if”, which is the first conditional, 2) an “else if” which is a conditional operator that can be chained indefinitely to cover all possible conditions the programmer can think of, and 3) an “else”, which is the default case. This is how Python and many other languages implement if-then statements.

The ability for programming languages to do this is extremely powerful, especially when combined with a second fundamental concept of iteration. Iteration is where newbie programmers become dangerous, and it is especially helpful with large data sets. It allows us to loop through large data sets really quickly and extract valuable information from them.

For example, suppose we had a list of countries and we wanted to find all countries that had the letter ‘A’ in them, or started with a the letter ‘U’. Or we wanted to find all students who had missed more than 3 days of class in the last month and give them special attention. We can design an algorithm with the following pseudo-code. Let’s cover the three cases above with pseudocode first, starting with the list of countries that start with the letter ‘u’.

list_of_countries = [country_1, country_2, country_3, …]  
filtered list of countries = []  
iterate through each country  
    if a country starts with the letter ‘U’
        put the country in filtered list of countries
    else:
        continue iterating to the next country
print filtered list of countries  

Now let’s try the more complex algorithm for finding a particular letter in each country.

list_of_countries = [country_1, country_2, country_3, …]  
filtered list of countries = []  
iterate through each country  
    iterate through each letter in the country
        if any of the letters are ‘a’
            put the country in filtered list of countries
        else:
            continue iterating to the next country
print filtered list of countries  

Notice that in the above pseudocode we had to do two iterations, one iteration nested inside the other. This is the moment when dangerous programmers become power programmers, and at this point almost all data-driven algorithms become solvable. This time let’s write the pseudocode for the more complex algorithm in calculating student attendance and knowing when a student might need additional resources to catch up.

There is an important point to make here about algorithms and why they are so difficult to patent: in reality, very rarely will two algorithms look the same when implemented by two different programmers. Below is the pseudocode for writing the student intervention algorithm in two different ways to show how even writing pseudocode is quite a creative exercise and differs from programmer to programmer.

Method 1: iterate over dates first, then students

student dictionary = {  
    student_1: number of absences (0 by default),
    student_2: number of absences,
    student_3: number of absences
}

flagged students = []

iterate through the list of dates in the past month  
    iterate through list of students for each date
        if a student is absent for a particular day
            store their name in a dictionary that counts their absences and increment their absence by 1
        otherwise
            continue iterating to the next student

iterate through students in the student dictionary  
    if any student is absence more than 3 times
        flag them for review and add them to a 

return the list of flagged students  

Method 2: iterate over students first, then the dates during which they were absent

absence counter = 0  
flagged students = []  
iterate through list of students  
    iterate through a list of dates
        if a student was absent for that date
            increment absence counter by 1
            if absence counter is greater than 3
                add student to flagged students
return the list of flagged students  

Note that the pseudocode for the second algorithm is shorter with logical progression that is somewhat easier to follow, but it is also much more nested. That doesn’t necessarily mean that this algorithm is better than the other one or that it will be more readable once it is actually implemented in Python, but it does give a good idea of which direction to prefer depending on how you like structuring your algorithms.

Unit 5: Combining Algorithms to make Programs

Recommended Time: 30 hours in class, 20 hours at home

This unit combines the programming knowledge learned from the previous two units and focuses exclusively on Programming (Big Idea 5). Specifically, students will learn to identify problems and how they can be partially or completely solved with programming. Additionally, students will learn about the differences in developing programs for end users versus personal use through actual programming, including testing, debugging, and getting user feedback. Finally, students will also learn about the key role that collaboration has to play in programming and dive deeper into libraries and APIs. Although this section is very exercise-driven, there are a few new concepts and a synthesis of previously learned concepts that are important to understand and communicate, discussed below.

Differences in hobby programs and “production-ready” applications

Multiple times throughout the course students are introduced to the concept of programming as a form of creative or artistic expression. Some of the best programmers often write programs to solve their own problems or inefficiencies, sometimes to an extreme, like this guy who hilariously automated personal and work-related aspects of his life through programming.

However, most programs created for personal use are not “production-ready” and are generally not a fit for a more consumer-oriented mass audience. For example, we have written quite a few programs already that could be useful for a small intended audience. An expanded version of the country-capital dictionary covered in Unit 3 could be quite helpful for playing a quizzing game, but the host would have to know Python to call the information stored in the dictionary. This is not an intuitive User Interface (UI) for the end user.

Production ready applications have to place a much greater emphasis on the User Interface (UI) and the User Experience (UX) throughout the development process, and even after the program is released. Before cloud storage and software updates became the norm, software often came installed on CDs or as a one-time application to install. It was difficult to collect user behavior data this way, and as a result, software usage rates were often very low.

As applications began moving to the “cloud” or web-based interfaces hosted on the Internet, service providers could collect sophisticated usage data and make their application UI and UX better over time depending on where users had the most difficulty in moving forward to the next step of the intended “user journey”. Production-ready applications also require a much higher level of debugging and testing to make sure they do not fail or give errors if a user enters an unexpected input that the application was not designed to handle.

Best Practices for Collaboration

When collaborating, make sure written code is readable and reusable. Writing readable code is fairly self-explanatory and has been shown in the exercises throughout the course. It involves using detailed variable names and helpful comments. Code reuse is easy to explain in theory, but difficult to implement in practice. It is the ability for your code to be flexible enough for someone else to use without requiring them to change any part of it that was not intended to be changed.

In practice, this means designing your functions in a way that accomplishes one thing really well. Before writing the function, it is important to understand the inputs that it will need (if any) and what that function will return as the output. Are all inputs required? Can some inputs be optional? If a function has too many required inputs (say more than 4), then it is probably not a good function because it tries to do too many things rather than doing one thing really well. Concepts around code reuse, maintainability, and readability are covered in more depth in AP Computer Science A, but it helps to introduce them now.

Having a centralized code repository is also essential for multiple students working on one project. repl.it handles cloud storage and link sharing, which provides the basics. For more advanced projects, teachers should consider introducing a more full-fledged collaborative environment like Github, which has a ticketing system with comments, milestones, and discussions that allow students to break up the project into smaller components.