Category Archives: Computer Science

Homemade Capture-the-Flag Competition, part 1

Happy New Year, everybody!

Just before school got out for the winter break, our school provided some time in the form of “block days” during which teachers could administer mid-year assessments.

I’m currently teaching two Computer Science classes—a single-semester Introduction to Computer Science taught using Python and a one-year AP Computer Science A course taught using Java—and in addition to a one-hour written assessment for each of those classes, I gave them a performance-based Capture the Flag-style assignment to complete as well.

A digital Capture the Flag competition is one which participants attempt to solve a variety of technology-based puzzles, challenges which are often based on hacking, or decrypting, or programming a solution to a problem.
With the exception of one or two students, nobody in these two classes had participated in something like this before, so I was sensitive to the idea of providing a few easy problems to get them started on things.

I also wanted to provide a variety of problems: some that would require programming a solution, some that would require converting from binary to decimal/hexadecimal/ASCII text, some that would require moving out onto the campus to find a hidden clue or “rogue wifi access point” (that I’d placed there with the permission of our IT team).

Having participated in a couple of CTF challenges myself, I also knew that one of the things that can be inspiring is seeing one’s score updated as challenges are solved, along with a leaderboard to let you know how you’re progressing compared with others.

I also wanted to try to ensure that teams had enough members that they could both support each other as needed, but also dole out responsibilities if they wanted to divide-and-conquer the problems they were working on. At the end of my verbal instructions, I ran a program that randomly assigned them to their groups.

There are two significant challenges for a teacher in implementing something like this: one is the creation of the problems themselves, and the other is programming the infrastructure that will manage the CTF: the delivery of problems, solution submission, scoring, and leaderboard updating.

Writing problems turns out to be mostly do-able, especially for anyone who has been teaching CS for awhile. A list of the challenges that were part of this most recent CTF:

  1. Hide and seek – Every page that you look at on the Internet is displayed according to code. Most web browsers have some means of allowing you to view the code that they use to display a page.

    Figure out how to see this code in your web browser, and then take a look at this page (which linked to a page with a lot of tildes, only one of which was an actual link to a page where the key was hidden).

  2. Content vs Style – Some people prefer to focus on creating content, and others like to emphasize their style. What sort of style do you like for your web pages? (The link led to a webpage with a link to an external CSS sheet, in which was hidden the key.)
  3. cd, ls, cat – I don’t know who came up with this idea, but these folders, randomly named, seem to go on forever. Log on to the server and see if you can find a flag in /home/rwhite/Public/directories. (Buried inside a series of randomly-named folders was a file with the key in it.)
  4. Chips Ahoy – I do love a good cookie now and then. Have you seen any on this website? (The competition website had placed a cookie in their browser, which they could identify (if using Chrome or Firefox).
  5. Indigo and Orange – What does that poster, hanging in Poly 110, mean? (A series of alternating colors represented 0s and 1s, which in turn were ASCII codes for the letters for the key.)
  6. Encapsulated data – A graphics file can contain all sorts of interesting information… (The linked-to file had appended to it a text value for the key, which could be identified with a hex analysis using hexdump or some similar tool.)
  7. Number Guessing Game – Well this is interesting. (The link led to a script running on the server that would take numerical input, and then produce a binary output that would guide the solver to closer and closer values until the correct number was entered, revealing the key.)
  8. Sowpods – The game of Scrabble has a collection of legal words that its players abide by. What is the highest scoring word that consists of only letters with odd-numbered point values?

    ‘cab’ has a value of 3 + 1 + 3 = 7, for example, but you can do better than that. Enter your flag in lower-case letters.

  9. Luhn and done – A list of stolen credit card numbers has been leaked on the Internet. You wouldn’t want to get caught using a false CC number (although you probably wouldn’t want to get caught using a correct stolen CC number either).

    Which number in the list is clearly a false CC number?

  10. Pirates Occupy Haaga – Somewhere on the Poly campus is a rogue wifi access point, operating without authority. Use your smartphone or computer to locate that access point, open a web browser, and retrieve the key you’re looking for.
  11. Taste the Rainbow – Just because I can’t brute force your password doesn’t mean it’s secure. If it’s a weak password, it’ll show up in a rainbow table somwhere.
    baddf925cae1a16b0641fd3da97600a1072b10991f66fed6387899cfa47ff726
    is the hash of my not-as-awesome-as-I-thought password.
    The flag for this problem is my password.
  12. Circular Primes – The number, 197, is called a circular prime because it and all rotations of its digits—197, 971, and 719—are themselves prime.

    There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.

    How many circular primes are there below one million?

There are always a few hiccups when writing problems. It’s nice to have other people double-check your solutions to make sure that you’ve gotten the answers correct. (I had an error in the first iteration of the rainbow table problem.)

Also, I’d intended the Circular Primes problem to be a programming exercise—I’d first heard of this problem from the awesome projecteuler.net website. But because of the fact that other people have discussed this very problem on the Internet, it’s pretty easy to Google an answer, so this problem turned from a programming challenge to a searching challenge. Not what I intended, but I’d already asked them to Google stuff on the Internet to assist them (the Luhn algorithm and the rainbow tables problem given previously) so I just had to go with it.

Once you have some problems, you have to find a way to administer those problems… and that is the far more significant challenge. :)

We’ll save that for the next post.

Parsons Problem Lesson: quad_functions

Learning Programming is Hard

Many challenges face the new Computer Science learner. One of the most interesting times for students learning to program is that period after they’ve learned a new feature or programming strategy, but before they’ve had a chance to really master it. The syntax may still be unfamiliar, or the strategy is “the same, but different” as something that they’ve seen before.

A Parsons Puzzle

I first stumbled upon the “Parsons Problem” type of question in a paper by researchers Denny, Luxton-Reilly, and Simon, Evaluating a New Exam Question: Parsons Problems, published in 2008, which led me to Parsons and Haden’s original paper Parsons’ programming puzzles: a fun and effective learning tool for first programming courses.

A “Parson’s Puzzle” is a programming problem delivered via computer, in which code fragments, manipulated via a drag-and-drop interface, may be assembled to form a correct, working program. Clicking a “Check” button would provide some sort of feedback. Parsons and Haden proposed that the nature of the puzzle would improve engagement with the topic, provide better structure for students still struggling to understand fundamental logic, strategies, or algorithms, and even intentionally allow for common errors so that a student could get immediate feedback on fundamental misunderstandings.

Parsons and Haden’s original idea of helping to teach students with an automated system was adapted to a paper-based means of assessing students by Denny, Luxton-Reilly, and Simon. Along the same lines, it’s certainly possible to use a paper-based strategy of helping students develop and clarify their thinking on any given computer programming topic.

A Paper-Based Parsons Problem in the Classroom

In an introductory computer science course taught using Python, students had recently learned about functions, and had had the chance to learn how to use functions in several different contexts. Students were paired randomly and given a paper copy of the activity here [PDF], and asked to a) arrange the lines of code into strips of paper that they would assemble into a working version of the program, and then b) enter their code into the computer to verify that it works as intended.

"""
quad_functions.py
This program solves quadratic equations using three functions:
* one function to get the coefficients a, b, and c
* one function to calculate the two roots, and
* one function to print out the results
@author You
@version 1.0
"""

def get_coeffs():

def get_coeffs(a, b, c):

def calculate_roots(a,b,c):

def main():

def calculate_roots():

def display_solutions(root1, root2):

def display_solutions():

main()

a, b, c = get_coeffs()

root1 = (-b + (b * b - 4 * a * c) ** (1/2)) / (2 * a)

root2 = (-b - (b * b - 4 * a * c) ** (1/2)) / (2 * a)

x, y, z = get_coeffs(a, b, c)

display_solutions(r1, r2)

return root1, root2

display_solutions()

display_solutions(a, b, c)

print(root1, root2)

return a, b, c

print("The solutions are: ")

a = eval(input("Enter coefficient a: "))

b = eval(input("Enter coefficient b: "))

c = eval(input("Enter coefficient c: "))

r1, r2 = calculate_roots()

a, b, c = get_coeffs()

r1, r2 = calculate_roots(a, b, c)

if __name__ == "__main__":

#!/usr/bin/env python3

Observations

Students took the assignment seriously, and seemed to appreciate the nature of the puzzle, and the fact that all of the information was available to them—they just had to (literally) put the pieces together. There were some lively discussions—”Do we need a function header with parameters or not? Do we need the function to return a value or not?”—as well as a desire to get done with the puzzle-solving as quickly as possible in order to move onto entering the code into the computer to test their program.

For a larger assignment or project with many variations, the Parsons approach is not well-suited: there are too many variations that need to be considered. For students just learning to master a new topic, however—functions, conditionals, while-loops, for-loops, etc—the Parsons Problem strategy is a great way to build students’ skills and confidence in programming.

References

Paul Denny, Andrew Luxton-Reilly, and Beth Simon. 2008. Evaluating a new exam question: Parsons problems. In Proceedings of the Fourth international Workshop on Computing Education Research (ICER ’08). ACM, New York, NY, USA, 113-124.

Dale Parsons and Patricia Haden. 2006. Parson’s programming puzzles: a fun and effective learning tool for first programming courses. In Proceedings of the 8th Australasian Conference on Computing Education – Volume 52 (ACE ’06), Denise Tolhurst and Samuel Mann (Eds.), Vol. 52. Australian Computer Society, Inc., Darlinghurst, Australia, Australia, 157-163.

Demo: Encapsulation

The idea of encapsulation is fundamental to computers in a number of ways. Generally speaking, “encapsulation” refers to the idea of building a container around something, as if that thing were contained in a capsule. When it comes to computers, there are a couple of slightly different ways the term might be used.

Hiding code in a class, function, or library

Commonly in computer programming, encapsulation refers to the idea of hiding away the details of code. For example, you may write a bit of Python code that takes three coefficients for a quadratic equation a, b, and c, and calculates the real roots (solutions) of that equation:

a = 2
b = 4
c = -5
root1 = (-b + ((b * b) - (4 * a * c)) ** (1 / 2)) / (2 * a)
root2 = (-b - ((b * b) - (4 * a * c)) ** (1 / 2)) / (2 * a)

If you were having to write lots of programs to calculate quadratic roots, or if you wanted to be able to use those lines of code other places, you might very well write them into a small function or method called something like quadratic_solver that you could use in lots of different places. You might call that function like this:

roots = quadratic_solver(2, 4, -5)

In this single line of code, the messy details of multiplying, dividing, and square-rooting have all been hidden away from the main program. The details of that calculation have been “encapsulated” in the function.

Any time you import a library into your program–import java.util.Scanner; in Java, for example, or import random in Python–you are bringing in complicated bits of code that will be available for you to use without having to worry about some of the arcane, or mundane, or complex details that are contained in that code. The concept of encapsulation is extraordinarily powerful.

Programming languages: Machine code, Assembly, High-level

A second way of considering encapsulation is less obvious, but one that we use all the time.

High-level languages

You have almost certainly seen computer programs written in some “high-level” language like Python or Java. These languages are called high-level because they, for the most part, consists of syntax that might be recognized and understood.

Here’s a program that’s written in C, which adds up the numbers from 0 to 255 and prints out the result:

# include 

int main(void)
{
    int x, sum;
    sum = 0;
    x = 1;
    while (x < 256)
    {
        printf("%d ",x);
        sum = sum + x;
        x = x + 1;
    }
    printf("\nSum = %d\n", sum);
}

You may not understand everything in this program, but it certainly has a few English words in it, and even a programmer who doesn’t know C might be able to work their way through this program to identify how it works.

We have a serious problem, however. You may have heard that computers don’t understand English: they only work in binary digits, or “bits,” the zeroes and ones that are represented by a billion switches being turned “off” or “on.”

So how does the computer run this program?

It doesn’t. But there is another program on the computer–a compiler–that is able to take this program and convert it to something called Assembly Language.

Assembly Language

In Apple’s macOS, if you have the Developer Tools installed, you can use the gcc compiler in the Terminal to output a compiled version of the program.

$ gcc -o sum sum.c

What does this new version of the program look like? We can see the Assembly Language version by using the otool program:

$ otool -tv sum
sum:
(__TEXT,__text) section
_main:
0000000100000f10 pushq %rbp
0000000100000f11 movq %rsp, %rbp
0000000100000f14 subq $0x20, %rsp
0000000100000f18 movl $0x0, -0x4(%rbp)
0000000100000f1f movl $0x0, -0xc(%rbp)
0000000100000f26 movl $0x1, -0x8(%rbp)
0000000100000f2d cmpl $0x100, -0x8(%rbp)
0000000100000f34 jge 0x100000f65
0000000100000f3a leaq 0x65(%rip), %rdi
0000000100000f41 movl -0x8(%rbp), %esi
0000000100000f44 movb $0x0, %al
0000000100000f46 callq 0x100000f84
0000000100000f4b movl -0xc(%rbp), %esi
0000000100000f4e addl -0x8(%rbp), %esi
0000000100000f51 movl %esi, -0xc(%rbp)
0000000100000f54 movl -0x8(%rbp), %esi
0000000100000f57 addl $0x1, %esi
0000000100000f5a movl %esi, -0x8(%rbp)
0000000100000f5d movl %eax, -0x10(%rbp)
0000000100000f60 jmp 0x100000f2d
0000000100000f65 leaq 0x3e(%rip), %rdi
0000000100000f6c movl -0xc(%rbp), %esi
0000000100000f6f movb $0x0, %al
0000000100000f71 callq 0x100000f84
0000000100000f76 movl -0x4(%rbp), %esi
0000000100000f79 movl %eax, -0x14(%rbp)
0000000100000f7c movl %esi, %eax
0000000100000f7e addq $0x20, %rsp
0000000100000f82 popq %rbp
0000000100000f83 retq

This version of the program contains a series of commands–push, move, jump, add, call, pop, return–that manage the data in the program, addresses in memory (listed along the left side), and registers (like %esi). Some people program in assembly language, but you can see that it’s a much more complicated affair. The process of storing the value 1 in the variable x is, in assembly language

movl $0x1, -0x8(%rbp)

We can say that the assembly language instructions are “encapsulated,” or hidden away, so that we don’t have to worry about those implementation details. We can write our high-level code, and rest assured that the compilation process will take care of the dirty work for us.

Of course, we still haven’t gotten down to the 0s and 1s that the computer needs to run a program. Let’s go one step farther down.

Machine Language

In the process of compiling, we actually created a binary version of the program, with nothing but 0s and 1s. We can use the xxd program in the terminal to view that code:

$ xxd -b sum | cut -c 11-64
11001111 11111010 11101101 11111110 00000111 00000000
00000000 00000001 00000011 00000000 00000000 10000000
00000010 00000000 00000000 00000000 00001111 00000000
00000000 00000000 10110000 00000100 00000000 00000000
10000101 00000000 00100000 00000000 00000000 00000000
00000000 00000000 00011001 00000000 00000000 00000000
01001000 00000000 00000000 00000000 01011111 01011111
01010000 01000001 01000111 01000101 01011010 01000101
01010010 01001111 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000001 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00011001 00000000 00000000 00000000
11011000 00000001 00000000 00000000 01011111 01011111
01010100 01000101 01011000 01010100 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000001 00000000 00000000 00000000 00000000 00010000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00010000 00000000 00000000
00000000 00000000 00000000 00000000 00000111 00000000
00000000 00000000 00000101 00000000 00000000 00000000
00000101 00000000 00000000 00000000 00000000 00000000
00000000 00000000 01011111 01011111 01110100 01100101
01111000 01110100 00000000 00000000 00000000 00000000
.
.
.

It is this code–these 1s and 0s–encapsulated several layers below our original version, that the computer uses to run the program.

These 0s and 1s are used to operate the digital hardware, the memory locations and the logic gates, that produce a given output. In fact, before we had keyboards, mice, and monitors, the personal computer was simply a set of switches with lights above them. Computer code was entered using the individual switches–a long, painful, error-prone process–and output was read from the computer as a series of flashing lights.

Here’s a programmer entering a program by hand onto such a machine. The resulting program displays (in binary, of course!) the prime numbers between 2 and 255.

Fortunately, we don’t have to enter binary logic instructions by hand. Those codes are encapsulated well beneath our high-level languages.

Demo: Binary Numbers

If you teach Computer Science, chances are that learning about the binary numbering system is part of the curriculum at some point.

Why teach binary?

Some people question whether or not binary numbers should be part of a high-level curriculum, given the multiple layers of abstraction between, say, a webpage and the binary code that brings that page to life. I’d suggest that:

  1. Those multiple layers of abstraction / encapsulation are very much a part of computer science, and a perfect jumping off point for a conversation about binary numbers.
  2. Students should understand that binary numbers are at the heart of every computer. A great video for demonstrating how people used to have to program computers is this one, demonstrating the programming of an old 8080 microcomputer. Follow that up with a demo of high-level / assembly / binary version of a program, described here.
  3. Learning how to decipher a binary number is not that difficult, and provides students with a manageable gateway activity to the field of computer science.

Demonstration strategies

Binary numbers can certainly be displayed on a computer monitor or projected in front of the class. An interactive Python session works just fine:

>>> bin(13)
'0b1101'
>>> print(bin(13))
0b1101

A more visible and physical demonstration of binary numbers can easily be constructed using an outlet power strip, socket adapters, and low-wattage aquarium light bulbs (see parts list below).

This device can be easily manipulated at the front of the room, with individual bulbs easily turned on or off simply by screwing them in tightly (on), or unscrewing them slightly (off). Students can be asked to identify the decimal equivalent of a binary number, or asked to manipulate the bulbs themselves to produce the binary equivalent of a decimal number.

Conclusion

This inexpensive and physical, practical demonstration device can be used in the classroom, with parents, during open house events, etc. It has become a mainstay of every CS course I teach.

Parts List

Update your Creative Process

In early 2001, in press releases and ads, Apple encouraged its customers to Rip. Mix. Burn. their music on an iMac.

It was an audacious advertising campaign given that the recording industry was in the midst of grappling with the rampaging growth of digitally copied media via Napster, LimeWire, and others. The Mac would soon leverage its position as a media hub with the release of the iPod later that same year. The process of assembling a “mix tape” of songs for a friend would never be the same again… although that process has since disappeared completely. Because everybody just streams now.

This post isn’t about that, though.

If taking prerecorded media and putting it together into a custom mix was the “old creativity,” it didn’t take much in the way of actual… you know, creativity. Assembling and ordering someone else’s music is fine, but… it’s a stretch to call it creative.

Welcome to the new creative. “Rip. Mix. Burn.” has evolved.

Fork. Commit. Push.

That’s right, I’m talking about using GitHub to fork a project, make changes that you commit to your fork, and then push those changes back to the master. If you know about GitHub, this all makes perfect sense, and is absolutely reflective of a creative process happening.

And if you don’t know about GitHub? Well… you need to get on it!

More to come…

Pair Programming

As a Science teacher I am well-acquainted with the idea of students working as partners in a lab setting. It’s a time-honored practice based on a variety of rationales, depending on the setting. Lab partners, or indeed partners in any academic setting, might be placed together for logistical reasons: there may be multiple responsibilities that need to be shared, there may be limited equipment, limited lab supplies, limited computers, or limited space. There may be pedagogical reasons as well: students can assist each other in learning material, or learning to work together may even be the goal of the lesson.

In computer programming classes, “pair programming” may be used, with one student typically “driving” (entering code on the computer), and another “navigating” (dictating code, catching typos, etc.) There are variations on the specific responsibilities of each role, but the general idea is that two heads are better than one, and that an ongoing conversation as the code is developed will produce a stronger product. Pair Programming isn’t just for classes–it’s actually used in the software industry by some organizations.

Regardless of the context, there are bound to be challenges when two people are asked to work together in a demanding situation. One common challenge is when two students have varying abilities or levels of success. Sometimes teachers will even pair students with this in mind, either placing students of similar level with each other, or pairing a successful student with a challenged student with the hope of fostering some impromptu peer tutoring. (I’d suggest that there are issues with both of these strategies, but we’ll leave that for another time.)

In my courses I’ve developed a Pairing Strategy that seems to be working well for my students based on the success I’ve seen in their assignments and their behaviors in the classroom. It works like this:

1. Introduce the idea of Paired Work.
Discuss the benefits and talk about the challenges. Mention the fact that there may be different roles to be played, and that those roles will likely change over the course of the experience.

2. Discuss behavior.
Point out that people need to be on their best behavior when working as a pair. Respect is an important part of this process, and that includes during that first moment when you learn who you’re going to be working with. A loud cry of “Oh, man, I got stuck with Christine??!” doesn’t get you off to a great start, and celebrating that you got paired with the person with the highest test average isn’t appropriate either.

Code.org’s video on Pair Programming, while a bit cheesy and clearly intended for a more Middle School audience, pretty much nails it.

3. Explain the Pairing process.
Very often I’ll use this computer program to pair students randomly. They’ve come to appreciate the excitement of finding out who they’re going to be working with.

In the case of Pair Programming, I’ll be very specific. Just before running the program so that students can see the results on the overhead projector, I’ll say that the partner listed on the left side of list will be the first “driver,” and that students will be using that person’s computer for the project. The person listed on the right side of the list will be the navigator, and will get up and move over to where the driver is sitting to get started.

#!/usr/bin/env python3

"""
random_partners.py
This program takes a list of students in the class and assigns them randomly
to a series of groups of a specified size.
@author Richard White
@version 2018-10-10
"""

import random,os

def main():
    all_students = ["Kareem","Lucas","Marcela","Dylan","Gwen","Ella","Adam","Carrie","Patty","Annie","Audrey","Aidin","Sinjin","Henry","Robby","Sean","Ms. Dunham"]
    students_present = ["Kareem","Lucas","Marcela","Dylan","Gwen","Ella","Adam","Carrie","Patty","Annie","Audrey","Aidin","Sinjin","Henry","Robby","Sean","Ms. Dunham"]
    os.system("clear")
    groupsize = eval(input("Enter # of people in a group: "))
    os.system("clear")
    i = 0
    print("PARTNERS:")
    while len(students_present) > 0:
        if i > 0 and i % groupsize != 0:        # Print commas after first one in group, 
            print(", ", end='')                 # but not if done with group
        random_student = random.choice(students_present)    # Pick random student
        print(random_student,end='')
        students_present.remove(random_student)             # Remove name from list
        i += 1
        if i % groupsize == 0:
            print()             # Space down at end of members
    print()

if __name__ == "__main__":
    main()

4. Run the program
Here’s a sample run from running this program in my Introductory Computer Science course:

PARTNERS:
Robby, Adam
Kareem, Aidin
Ella, Annie
Henry, Patty
Gwen, Ms. Dunham
Lucas, Carrie
Dylan, Audrey
Sean, Sinjin
Marcela

5. At an opportune time, have students exchange roles.
During every assignment, assuming I’ve done a good job of building in an unexpected challenge or new idea, I’ll ask for attention: “Hands off the keyboard!” or something similar. I’ll pose a question regarding the work that they’ve done, or share some observations I’ve made, or ask if anyone has come across the difficulty that I’ll expect they’re going to have. After this brief interruption, I’ll ask them to change roles and continue their work.

Sometimes the process doesn’t work quite right the first time, or there may be mid-course corrections required if students get a little sloppy in their treatment of each other. That can happen in any classroom environment. The fact that students are truly randomly assigned, however, seems to keep them on their best behavior. They know that I don’t have any intentions in assigning them to a given partner–this is just who they’re going to be working with today.

Here’s a video clip of my students working on a programming assignment in a Paired environment.

Overall, I’ve been very pleased with how this process has worked with my students over time. Give it a try in your classroom and see what you think!

That Teacher with the Butcher Paper and Sharpies

I try to encourage my students to keep a paper-based notebook for their work in my computer science courses. I think there’s a benefit to taking notes by hand (when appropriate), and there are handouts, worksheets, paper copies of problems that I have them do by hand, and printouts of project specifications. Most of this is available on the website I keep for the students as well, but there’s something different about paper. You interact with it in a way that you can’t with a keyboard.

I’ve never really been into the idea of doing a lot of “crafting” in my classes, however. Paper, glue, tape, pencil sharpeners, colored markers, scissors, string… It all sounds very middle school (no offense to my colleagues there), and don’t even get my started on all those teacher meetings where we have to wander around the room, putting up stupid colored Post-Its everywhere.

I really hate that stuff.

Last year, though, a roll of butcher paper found its way into my possession, and I stuck a ring stand through it and set it off to the side in my computer science class. Recently I’d started to feel like there was a sizable number of students in my CS courses who were watching what I was doing on the board/screen, but they weren’t getting to write, to draw, to interact with the material the same way even that students in my AP Physics class work with ideas. I decided I’d find a good opportunity to see if I could change that.

Zookeeper

“Zookeeper” is a project in my AP Computer Science class that is designed to give students the opportunity to explore inheritance, creating an Animal superclass and a few subclasses that inherit from it. Object-oriented design asks one to consider data objects in terms of instance variables, and accessor and mutator methods. Every year I ask students to get together in small groups to consider their classes in some detail before jumping on to the keyboard. This year I asked them to draw diagrams of their classes on the butcher paper. It took a bit longer–I was surprised how much time it takes for someone to figure out how to tear off a piece of paper from a roll–and the result diagrams weren’t necessarily *artistic*, but that was beside the point. Being able to wrestle with the concept with paper and Sharpies resulted in projects that clearly demonstrated a greater facility with the concept of inheritance.

Binary Heaps

In the post-AP Advanced Topics class, we’ve just learned about binary heaps, a strategy for prioritizing items in what would otherwise be a standard First In-First Out queue. Here, optimized strategies for adding an item to the heap consist of placing it at the bottom and having it “percolate” up, while deleting an item from the top of the heap involves percolating down… and writing code to implement these strategies is hopeless without a solid qualitative understanding of the process.

Bring out the office supplies. Small groups of students each create their own heap structure on large pieces of butcher paper, then go through the process of inserting a value and percolating, or deleting a value and percolating. Cries of “Wait, what are we doing here?” intermixed with “Ohhhhhh! Now I get it…!” A few minutes later, armed with a clearer understanding of the mechanics, they’re ready to turn to their keyboards.

So, yeah, I’m that teacher now, the one with the butcher paper and the sharpies.

And I’ve got some post-its in the cupboard, too, but I’ve got to draw the line somewhere.

I Had a Pretty Good Day

Some days are better than others… and April 5 was a pretty good day for me at work.

The night before, it wasn’t looking like it. I’ve been behind in grading, in part because I’ve been working on developing some new assignments, and the one I’d been working on for my Advanced Topics class—The Elevator Project—hadn’t been coming together as quickly or as neatly as I’d hoped it would. After an hour or two wrestling with it, I crawled into bed with the idea that I’d have to rearrange the course calendar a bit…

Today was a Day 2, which means I get to see all of my students: AP Physics, and later on in the day AP Computer Science, followed by Advanced Topics.

AP Physics

It was already going to be a good day—a bit of lecture, followed by a fun lab activity—and just as I was getting going, I received a FaceTime call on my phone. I apologized to the students for the interruption, looked down to see who was calling, and didn’t recognize the 626 number. “Is one of you all pranking me?” I asked the class. I’d given my number out to all of them earlier in the week as an emergency contact for our field trip to Six Flags Magic Mountain.

I answered the call, and the face of Turner, a student in that class who was out sick for the day, appeared on the screen.

“Hi, Mr. White! Sorry to interrupt class. Did you get my email?”

“Uh… no. When did you send it?”

“Oh, about three minutes ago!”

“Yeah, I’m afraid I haven’t had a chance to read that yet. What’s up?”

“Would it be okay if I FaceTimed our class today so I don’t get behind on anything? If you could just prop your phone up there, I can see what’s going on…”

It was a good idea, and I applauded her initiative. “My phone is going to die if I FaceTime with you for the next hour,” I pointed out, “…but I’ll be happy to set up a GoToMeeting session with you. Look for an email from me with a link in it in two seconds.”

“Okay, thanks! Bye…”

I launched the app, got the screen pointed toward the board I was developing on, and a few minutes later Turner was following along from home, just as if this was something that we do every day.

Pretty cool.

Then it was time for our lab. Students were arranging magnets in various configurations, placing a clear piece of plastic over them, and sprinkling iron filings on the plastic in order to discover what the magnetic fields around those magnets looked like. One of the students in class, Nick, kindly volunteered to work with Turner, and for the next 30 minutes or so, there they were, looking at the magnetic field effects, making drawings, and discussing whether or not what they’d observed made sense, just as if she was in class.

When people talk about distance-learning, they’re often talking about a model in which a student watches a video lecture, and then maybe “interacts” with other students by leaving a few messages on an online discussion board. It doesn’t sound like a very robust way to teach/learn, and I think most people I know have a natural (and perhaps well-founded) distrust of the experience offered by taking an online class.

What I loved about my experience with Turner this morning was the natural way that the distance-experience occurred within the context of our regular class. And the fact that she was interacting with her teacher and peers in real-time was cool, too.

This isn’t something that can scale. This isn’t an experience that anybody is going to be able to monetize in any real way (I don’t think).

But it was awesome, and a great way to start my teaching day!

AP Computer Science

The AP Computer Science this year is overfilled, and the difference in the ability level of students varies pretty widely. The “Goldilocks” experience in there that’s just right for most students will be too easy for the more capable students, and require significant support for the students who are still coming along.

Today, as students were still struggling to recover from ten days off for Spring Break, I was trying to bring to a close our conversations around Sorting algorithms, recursion, Big-O notation. The Merge Sort was the topic for the day… and I wasn’t looking forward to it.

In the past I’d given them a template for this algorithm and had them try to fill in the missing pieces, or in tough years I’d forego this particular algorithm altogether. Today, I was having none of that. Today, I’d decided, I was going to develop it with them in class, step-by-painful step.

As I considered the lesson and how I wanted to run it, I realized that the timing was actually just about right for developing this moderately-challenging sort. One part of it consisted of keeping track of three separate pointers, one for each of three separate lists, and if I could do a good job of managing our development, it might be a solid introduction to some of the challenges they would face on the typical AP problem… and the test is coming up in just four weeks or so. I made some brief notes on what I wanted to do, and headed down to the classroom…

It worked fantastically. After a few moments settling into class—one student wanted to show me the new Tiger Woods video and update me on the current scores in the Masters—I grabbed a marker and took them through a quick review of the Merge Sort process itself. And then I was writing a bit of code for the first part of the sorting process. I targeted specific students with specific questions, and everybody was keeping up, more or less. I left the room at one point to let them work on their own for a bit, typing what we’d developed by hand into the computer. I came back to develop the tail end of that sort process… and then we were in to the business: the merge method that would pull each pair of recursive arrays back together.

And that, too, worked. They were on it, with insightful questions, and understanding nods when I explained how the thing they’d been thinking about was a good idea but wouldn’t work in this case because…

They were on it!

For just a moment there, I felt like a real teacher.

Advanced Topics in Computer Science

And following directly on the heels of that was the class for which I’d attempted to flesh out the Elevator Project, and more or less failed. I’d decided earlier in the day to re-frame it as an open-ended project. A few days before I’d had students fill out a Course Evaluation form and the results of that, while generally positive, also suggested that there was room to push the students a bit more. An open-ended project that gave students a bit more latitude to explore, fall down, and ultimately (one hopes) succeed might be just the thing.

I had typed up a brief two-page handout with a general description of the project: they needed to write a class-based simulation of a Hotel with a single Elevator that would move up and down between floors, picking up each Passenger from their current floor and delivering them to a requested floor. I passed out the blue photocopy of the assignment while explaining the general idea, and pointed out that this was a classic introductory Computer Science assignment and that I’d be working on my own version of the project at the same time they were.

“And… I don’t know about you, but whenever I’m about to write a simulation, I like to spend a little time with the actual thing so I can better understand some of the details of what I’m going to have to code. So…”—I started edging toward the classroom exit—”I’m going to ride the elevator for a little while.”

“Ummm… what?”

“Wait! I’m coming, too!”

“Come on you guys, let’s go…!”

And next thing you know, there is me along with thirteen Advanced Topics students crammed into the three-story elevator of the Poly building, traveling up and down.

Teacher: “So, are we going to write a Button class for the elevator buttons, or can we leave those out?”

Student 1 (with worried look on face): “What about the ‘Open Door’ and ‘Close Door’ buttons? Do we need to model those?”

Teacher: “You can if you want. I think I’m leaving those out of mine.”

Student 1 (relieved): “Oh. Okay. Me, too.”

Student 2: “Wait, let me off at floor 1. I’m going to run upstairs and hit the buttons for ‘Up’ and ‘Down’ at the same time. Don’t go yet! Wait for me to get there!”

Student 3 (in the corner, fists clenched in excitement): “This is so much fun!

Ah, my little Computer Geeks.

We got off the elevator a few minutes later and returned to the classroom, armed with ideas on how we might put together a solution to this problem. For the rest of the period, there wasn’t much beyond the sound of typing as people began working their way into the challenge.

Yup. It was a Pretty Good Day.

The Growth of CS Education at My School

by Richard White

2018-04-22

I’ve worked at four different high schools in my career as an educator, and taught computer science courses at two of them. I was the lone CS teacher at those schools, as are many of us. It gives us a lot of freedom in some ways, but it also makes teaching CS a bit lonely sometimes: as a science teacher, I enjoy lunchtime conversations with colleagues in that department, and benefit from having a colleague who teaches the same course I do (AP Physics C).

Computer Science is different. It’s not what many teachers consider a “core competency,” I don’t have a department chair to advocate for me, and having a single teacher of that subject implies that the classes offered by the school are limited to subjects with which I have some familiarity: I am comfortable offering an Intro to Computer Science course in Python, an AP Computer Science A course, and an Advanced Topics in CS (data structures) class, but I don’t offer classes in mobile application development, networking, or game development.

After several years of encouraging the school to increase the number of sections of CS offered, I am so excited that we made the decision to hire someone for a Math/CS position, and that I’ll soon have a colleague with whom I’ll be sharing CS teaching duties.

It’s a time of transition for the school, and for me as well. I’ve never had a CS colleague before! The courses currently offered at the school have all been designed by me, and taught by me for so long that I suppose I might be forgiven for being a little possessive of them. And yet (at this point, anyway) I don’t feel too worried about that.

It may help that I’ve seen our new hire teaching a CS class and I appreciated the way he worked with the students. Or maybe I’m just looking forward to having conversations with a colleague with whom I can discuss curriculum ideas, teaching strategies, projects, etc.

This new hire is relatively young, and although he has a decent amount of experience programming in a variety of languages, this will be his first experience formally teaching CS.

At this point, the challenge facing me is this: how do I share what I’ve done with these classes with the new teacher?

  • Course description? (of course)
  • Course syllabus?
  • Course calendar from last year?
  • Lesson plans?
  • Activities and projects?
  • Assessments (tests, quizzes)?
  • Teaching strategies?

I’m happy to share some/all of these things, but it’s also important for a teacher to be able to develop their own materials, and find their own way of teaching a class. I’ve worked with student teachers in the past, and giving them the freedom to find their own pedagogical identity is one of my favorite parts of that experience.

We’ll see how it all works out! In the meantime, I’m just so pleased that my school–a relatively small, independent institution–recognizes that providing CS experiences for as many students as possible is increasingly important.