For the past two months, I have been helping my son’s grade 8 class to learn to program. All students wrote Python programs and got a feel for what programming is. This post has details on how we organized the course, code examples and lessons learned.
This year, all schools in Sweden are required to start teaching programming. Many schools already teach programming, but they depend on having teachers that know enough to teach. Writing code will be included in the subjects math and technology. Earlier this year, another grade 8 dad, Olle, volunteered to help teach programming this fall. He also recruited me (as a fellow enthusiastic programmer) to help.
We spoke to Caroline, the technology and math teacher, and she was grateful for any help. The class had done a bit of Scratch programming before, but Caroline wanted them to learn text-based programming (as opposed to block-based programming). She took a programming class at university several years ago, but she felt she needed a bit of help to teach it effectively. She also wasn’t sure of what environment and language to use, since there are so many choices.
Python. Olle and I got together a couple of times to plan it out. We discussed what language and environment to use. We picked Python for a couple of reasons. First of all, both Olle and I already know Python (I use it every day at work). Second, all students have a MacBook Air, so there is already a development environment for Python installed. On their computers they have Python 2.7.10 and the IDLE editor. Python is also a good choice because the syntax is relatively easy and compact, and is now the most popular language.
No magic. Caroline wanted the students to learn text-based programming. Block-based programming is good for showing concepts like if-statements and loops. However, professional programming is almost exclusively text-based. But, professional programming also involves using numerous frameworks and libraries, and we wanted to avoid that. We wanted to get to the essence of programming while avoiding “magic” behavior. So the programs should be as self-contained as possible. The behavior of the code should be evident from the instructions, without relying on functionality from external libraries.
Minimal subset. We also decided that we wanted to minimize the number of language constructs used, while still being able to write programs with a good chunk of logic in them. All programming comes down to using variables, statements in order, conditionals and loops. In Python terms, we decided that it would be enough to introduce strings and integers, if-elif-else and for-loops. We also need print-statements for output and raw_input() to make the programs interactive. And finally with decided to show how to use functions as well, to be able to show a way to structure programs. This is quite a small subset of Python, but it still allows for creating fairly advanced programs. In particular, there is no need to use classes.
For everybody. Finally, we wanted to show that anybody can learn how to program. It is like learning any other skill – there is no magic to it. And ideally we wanted to let the students feel the joy of programming – the sense of accomplishment that comes from having created a working program from scratch.
Hello world. The first program would be a simple “Hello, world!”-print-out, which only requires a print statement. Of course it also requires being able to start the IDLE editor, writing the code, and running a python program on the command line. Next, variables are introduced. We also talked about types (strings and integers) and that values of variables can be changed. Here we also show how to print the value of a variable (using %s notation) and how to read input.
Calculator. The next step is to make a calculator. This is a good way to introduce the concept of a function. We start by defining a function called add, that adds two numbers together. The program then prompts the user for two numbers, calls the add function and prints the result. Next we write a subtract function, and introduce if-statements to let the user pick between adding and subtracting.
Game – guess-the-number. The final example is to write the game of guess-the-number. A random number (between 1 and 100) is generated, and the user has to guess the number. Here we had to introduce one piece of magic, in the form of importing the function randint. We started by just generating the random number and letting the user guess and then comparing the guess to the number. This requires using an if-statement and converting the text input to an integer. The next step is to print whether the guess is correct, too high or too low. From there, it is natural to introduce loops to let the user guess more than once. So we introduced the for-loop here, and got a complete game of guess-the-number. We decided to use a for-loop instead of a while-loop, to reduce the number of python constructs needed.
The last two examples are both small, but they can be varied and expanded quite a bit. For the calculator, you can add multiplication and division. If division is introduced, it is good to also introduce floats, in order to avoid the unintuitive effects of integer division. You can also compose the functions, for example by adding and then multiplying. Or you can hard-code one of the inputs, or make a square function.
The guess-the-number game can be expanded even more. You can count the number of tries, write a scoring function, make the range selectable, check if a number has been guessed before (needs a list), allow for multiple plays etc.
In the Classroom
The first lesson was on Monday October 23th. Olle and I both took some time off work and came to school and gave the first presentation together. We started by talking a bit about what you do when you work as a programmer. For the programming part, we used our own laptops connected to the projector. We showed them how you start a terminal, how you start IDLE, how to type in print “Hello, world!” and how to run that program from the terminal.
It was good to be two, so one of us could walk around in the classroom and help whoever had a problem getting started. At the end of the one hour lesson, everybody had written a program in Python and got it to run on their own computer. We also emphasized that it is good to cooperate and help each other. Professional programming is a team effort, and pair programming is often used.
For the following two lessons, Olle and I split up and took one lesson each. We continued going through the concepts at a pretty brisk pace. Again we used our own computers hooked up to the projector and live-coded as we explained new concepts. The students followed along on their own computers. When I had shown how to write the add function, I was happy to hear how quickly the students came up with their own variations of what the functions could do.
One student asked if we could make the add function take a little while to come up with the answer (as if the computer was thinking). This was a good opportunity to show how to search for answers to programming questions. I googled “python delay one second” and the first hit was a Stack Overflow question showing how to use time.sleep(1).
After this initial push, Caroline took over and let the students work on their programs. Caroline mailed me a couple of questions, and I mailed her some more example programs. I came back to the school a few weeks later and helped with various questions. There were many excellent ideas from the students on how the guess-the-number program could be improved. So I showed how you can add playing a sound, how to measure the time taken to get to the correct answer, how to keep track of previous guesses, and how to keep track of high scores between runs of the program. To keep track of previous guesses, we used a list, and checked if the current guess was in there before adding it to the list. To keep track of high scores, we used a dict, and used pickle to store it to file and read it back. So these were natural points to introduce lists and dicts.
Some students chose to write a quiz game instead of guess-the-number. The program prints a question and four alternatives, and the user picks an answer. There were also some who made a battleship game, a hangman game and a dice rolling game. Caroline reported that many students were quite enthusiastic and worked on their programs at home as well. At the end of the course, the students were told to show their programs to their parents. That’s a nice opportunity to show off what you have built, and to explain how it works.
Here are some of the things we learned during the course.
- It worked well to start coding from lesson one. The pace was high, so it is important to make sure all students got help to get their programs running.
- As a teacher without a lot of programming experience, you have to accept that some students will soon know more than you do.
- It will be difficult to know how to grade the students’ work.
- Many students helped others with problem solving. This was good, but sometimes the “helpers” didn’t have much time for their own programs.
- Start IDLE as a background process (end the command with &) so you can run the python code from the same shell.
- Use arrow up to repeat the last command – usually you want to run the same python program over and over (after modifying it in IDLE).
- Use ctrl-c to stop a running program.
- Show how to comment out code using #
- Show how to indent and outdent blocks of code in IDLE, so they don’t have to do it manually line by line.
- If there are unicode characters (for example Swedish å, ä and ö) in the source code, the file encoding must be specified. IDLE suggests this at save, but you need to select it.
Common errors and tips for debugging.
- Make sure any changes in IDLE are saved before the program is run (the asterisk next to the file name indicates unsaved changes).
- Look out for missing colons, missing brackets, and wrong indentation.
- A common error when printing variables is missing %-signs, or using & instead of %.
- Look out for cases where a string (from raw_input() for example) is compared to an integer. This will not raise an error in Python 2, but will cause some comparisons to give the wrong result.
- When trouble-shooting the guess-the-number game, set the number to be guessed to a fixed value temporarily, for example 57. Then it is easier to see if the response to each guess is correct. When the program is debugged, set it back to a random number again.
Personally I would not write code for more than an hour before using some kind of source control system (like git). However, I think it is better to concentrate on the pure programming aspect when they are just learning to program, instead of adding the complexity of dealing with version control as well. It is good enough to just tell them to make back-ups of their program files once in a while.
All the code examples used are available at GitHub. Note that we were using Python 2.7, not Python 3. There are instructions on how to start IDLE and how to run a Python program in the file getting_started.txt. Then there are a number of files called e.g. example1_print_and_variables.py that contain the examples we started with.
There is one basic version of a guess-the-number program, and one advanced version with a few bells and whistles. In the end, there was some “magic” added, for example using sleep(), timer and playing sound clips and background music. This was all added on student requests, and did not confuse anybody as far as I can tell.
Neither Caroline, nor Olle and I, knew what to expect when we started this. However, it worked out better than any of us had hoped. The cooperation between us meant that all the students wrote complete Python programs. Many of the students were quite enthusiastic and want to continue programming.
For me, it was really nice to see how the students “got it” and quickly came up with all sorts of ways to improve the basic programs we presented. Hopefully the examples from this course can be useful for others as well. If so, please let me know in the comments.