I'm going to be teaching a group of high school students about programming, and I have a general curriculum designed already, but I can't quite figure out how to introduce methods. I'll be teaching ruby specifically, but language agnostic answers are good as well. A general theme of my teaching will be allowing students to do things the "hard way" first, then showing them an easier way. For example, I plan on teaching them how to print to the console, then I'll ask them to print a word to the console 20 times. I'll use that to introduce looping. Is there a similar way to introduce methods? I'd like concrete examples/activities, along with general advice about how to use those examples.
Subroutines/methods are a way to reuse code. As is iteration (loops). They are also a way to document what code does.
Therefore show how they can be used to reduce the amount of code: to make the program simpler, and to make it more readable. Note that there is often resistance as a new concept: as, temporarily, it does not make sense, so is not simpler.
In my first year of teaching, for my python class, I did turtle graphics, as having a visual output can help with understanding. We added procedures for drawing basic shapes. And functions for calculating angles. And eventually complex shapes such as a house, with windows, a door, and a roof.
At first we did it simply:
tracy.moveForward(100) tracy.turnLeft(90) tracy.moveForward(100) tracy.turnLeft(90) …
We then introduced loops. Then we studied the code to find patterns. The code for Square is used a lot, can we reuse it. Put it into a subroutine. Then we did pattern matching to see that drawSquare, drawTriangle etc are similar. Introduced parameters, and create drawPolygon.
I also experimented with giving them code that I write, and asking them to modify it. (this was done on last lesson of term with a set of classes. We got to python very late.) Next time I will spend more time on getting them to read the code, and making a prediction of what it does. I will provide two sets of code, one using subroutine, with nice names, the other without. I will ask then to predict that they do, and to also evaluate which one is easier to read (to make this prediction). This should show one of the advantages of subroutines/methods (readability). Readability is the most important property of subroutines/methods. Code reuse in secondary, memory is cheap. However reuse is important, as it makes code consistent, and easier to fix (only in one place). Therefore after they have had time to discover the reuse property, do an evaluation that focuses on consistency and bug fixing.
Order of teaching
I have been considering order of teaching. Here is some of what I have come up with. I am using partial sequences: that is describing some things that should be taught before some other thing. From these we come up with a sequence, to teach (some parts of this order may be arbitrary, as long as we obey the partial sequences). [notation:
→ represents “is taught before”].
- subroutines without parameters → subroutines with parameters → variable mutation.
- iteration → selection.
I think that selection needs to come after parametrised subroutines, as I don't know how to do it with out variables. However it can come before mutation (almost everything can come before mutation).
I almost always teach programming by connecting each component of programming with something in real life. For instance, when explaining variables, I ask the students to imagine them as boxes in which you put things, like food items or gifts or something similar.
For methods, I ask them to think of their friends. For instance, there will be a 'rich' friend, and then there are 'stingy' friends, 'useful' friends and so on. So, bring up a scenario. For instance, lets say the challenge, you are in trouble and you want to ask for help.
You have 3 friends - rich, stingy and useful. Instead of friends, think of them as methods, and you (as in the individual) is the program or the main method. Now, you need help, which friend aka method are you going to call...you will obviously call the 'useful' friend/method.
So, essentially, whenever you want something to be done, you design/code a method for that, just like how in life, you want something done, you call upon a friend. So, methods are like friends who help out get things done.
Of course, in an actual classroom, I pick students, make them do role-play (pretend that they are functions) and make it all very active (and hopefully fun) and it seems to work for me.
and of course, once they get the concept, I jump into code right away, building small methods that do simple print statements, then upping it to display simple variables and then complex stuff including sending and getting values
Perhaps I'm wrong, but your question (and your example) seems to imply that your intention is too "teach them Ruby". For beginners that seems backwards to me. My intention would be to teach them to "solve interesting problems".
Once someone already knows "how to program" in some language it seems fine to teach them a (different) language. But focusing on the language is the wrong way about. Find an interesting, if simple, problem and examine how to break that problem down. In an object-oriented language you break it down into objects first. The objects have behavior. The methods implement that behavior. So methods are natural, not something that you need to come up with examples to teach. Your examples should be example problems.
Instead of giving them a hammer and a bunch of nails, give them a problem that a hammer would solve. Hammering isn't, in itself, a useful skill. Think about the problem first.
This is one reason that a system like Greenfoot is useful in teaching beginners. It offers the possibility of a framework for posing problems (simulation) and a visual framework for solution (a flexible grid like world).
Giving a person a full complement of carpenter tools doesn't make them a carpenter.
In teaching programming to beginners, make the language and its features a secondary concern. I would introduce new language features only when a problem requires it. Of course you can choose the problem set so that you introduce "interesting" language features along the way, but make the problems "interesting" first.
Also, if you really want to teach them object-oriented programming, don't teach them static methods first. Teach ordinary (dynamic) methods of objects until they are familiar with "behavior of objects." Wait a bit (maybe a long bit) before introducing statics.
Have them write up a straight class and document it. Here are some ideas.
- Complex Numbers: Create a class that spawns complex numbers and does their arithmetics. Throw exceptions where needed.
- Big Fraction: Create a class for extended-precision rational arithmetic. You will need +, -, * and /.
- Quaternions: These are used extensively in computer graphics. Implement them.
When I do OO programming a project of this ilk is my first big assignment.
Because you mentioned Console, I will chime in. Many of the answers here, and other questions also, mention doing something visual with graphics, etc. When I was teaching myself (almost 40 years ago), I printed shapes on a terminal using asterisks. This obviously requires nested FOR loops, or clever recursive functions.
Show a two-level loop solution, then show how it is much clearer to extract the Row printing to its own method. Now you have a loop calling a method, with a loop inside that. Once you have a Row method, you can create all kinds of variations that use it, to make different shapes without altering the Row method at all. It would be best if the Row method had two parameters: number of spaces to indent, then number of asterisks to print.
The Row method could return a string, or just print the output directly. If it returns a string, you could easily migrate the application to a Windows form instead. Now you have demonstrated reuse and the importance of separating the platform from the algorithm.
You could even have another method that encapsulated the character to print, so it could be an input value. Then methods to accept numeric input and keep it within bounds, etc. It can easily grow in an Object Oriented way.
Well, if you were to use Excel, you could show some of the built-in functions that come with it... They will not know how these work internally, but SUM, MIN, MAX etc. are pretty handy- you could demonstrate what they do and discuss HOW they are doing it internally.
After getting different versions pseudocode for the functions, you could discuss using a function many times in one program- in loops...
A simple "intro" function may be to print a "#" n times. You might get some ideas here- I know I did.
This example may be a bit verbose, but what if you wanted to check a sentence and see how many words in the sentence have two consecutive letters the same...
Well, there is probably a builtin method such as split(). Isn't that handy? How does it work? Who cares, but it may be interesting to look at how it might work.
Here's some Python Code for checking if there are two consecutive letters the same in a word. There are two versions. Each work differently but do the same thing.
As mentioned already, the main purpose is to allow code-re-use. It may be worth mentioning concepts such as modularisation, and the analogy that many complex systems are broken down into simpler, smaller subsystems... and simpler problems are easier to solve.
I have never taught the same computer course twice the same way, so all we can do is to try out different things, methods, exercises etc.
Hope you find some of this helpful!