I have a group of students with a very shaky understanding of functions and their purpose (encapsulation, reuse, modularization). The assignments I give them require them to write simple functions that return boolean T/F, an integer or a simple Python object (str, list, etc.), then have the caller use the returned value in a print statement. Their programs are written in Python and run from the Windows command line.
The problem is that from the command line, the programs work but if you look inside it’s a mess. The functions ignore the parameters to reach into the main for global variables (misunderstand the idea of parameter passing), the input validity checking is done in the caller (defeating the idea of encapsulation, e.g is day of month valid for a given month), or the function prints the result without returning anything. The worst that I get is the function does all the work of the main and of the function, for example when asking for a simple function to add 1 to its argument, I get:
def add1(x): myval = int(input("Number?")) print(myval+1) add1(x)
…which of course is nonsense.
Here’s my question… Can I craft an exercise that calls a simple function like add1() that would give a dramatically wrong output, e.g. cause the screen to “blow” up if the function printed instead of returned, or stalled if it kept asking for input. I’m thinking of something that reads a large file of text or numbers.
The students are at the community college level and are not programmers — they are in electronics technology (and some are convinced that there is no software involved in electronics). I use Python but this is (mostly) language independent (I see the same shaky understanding with C++ functions in the Arduino world in another course).
Thanks in advance
Instead of an example, use a metaphor. Get yourself a frisbee - ultimate disk and two packs of sticky notes. You are the caller of a function. Another person is the function itself. Write a value on the sticky note and stick it to the frisbee. The pass it to the function (person). The person catches the disk, and replaces the stick note with a new one with a new computed function value. They then return the disk to you. You get the computed value and announce it.
Without the return value you get nothing. You can use any function you like but zero or one arguments is the easiest to manage.
A slightly more sophisticated version can be used to discuss pass by value and pass by reference.
Due to Mike Clancy of UCBerkeley. It is a classic from many years ago.
Correct answer by Buffy on December 27, 2020
You can call the function using the python unit test framework and run different tests against it. Simple print-statements and other things will most probably no longer work.
Answered by OBu on December 27, 2020
I saw the light at the end of the fiber optic cable as soon as you said that these are students of electronics. There is nothing more modular and encapsulated than that! Software is simply electronics without the hardware part.
If you said to them, "What are the building blocks of a simple AM radio receiver?" they would (hopefully) reply something like: antenna, tuning, rectification, filter, audio output... A crystal radio has all of those. They already know that it is pointless to build the antenna in to the filter, or duplicate the tuning parts more than once. They know that they can work in teams to produce parts that fit together to make a complete radio.
So speak to them in a language they already know: the functional relationship of parts and wholes. Using globals instead of parameters would be like having extra cables going outside the radio to connect different parts of it to the signal path or the power supply. Can you say "Rube Goldberg"? I knew you could.
Man, let me teach them. I have been studying electronics on my own since before anyone I knew even had seen a computer. Electronics students should be the easiest audience in the world to teach programming to. Use examples they already know.
Answered by Scott Rowe on December 27, 2020
If classes are guns, functions are sort of like bullets. Not a guns take the same rounds, not all classes have the same functions. But some classes can have the same base classes therefore have some similar functions; some guns have the same manufacturer and take the same bullets. Instances of a class can call functions, just as a gun can shoot bullets. Maybe thats why call of duty calls it "create a class"...
Answered by Mike on December 27, 2020
I think the example you showed on the original question is more about exception handling and unit testing rather than explaining the concept of function.
You may want to teach students on explaining the concept of function in a very simple way such as "Why is a lego so successful? Because it uses blocks! Function is like a lego block. It's about reusability, modular programming.", and give them enough time (maybe several weeks or so) to practice with different kind of examples to naturally get familiar with using functions.
The error-handling and unit-testing are more advanced concept and technique. It's probably best to teach these concepts once students are pretty good at writing code in general. I would suggest to actually teach this almost at the end of the course. It's important in the real-world software development, but for learning, I think these are less important compared to other topics.
Answered by Jason Huh on December 27, 2020
Sorry this is a half answer because I haven't concrete examples right now. Besides, the answer with the electronic analogies is already so great. But one point attracts me.
At the level where I imagine your students are, they do not need the modularity effectiveness that can be obtained with well structured functions. Indeed, you report from them mistakes of not following "your" way of doing things, but no concrete reason is dictating that your way is better than, for example, the cited way of implementing
add1, therefore they may be lost wondering what are you asking them.
The "problem", so to say, is that in their situation functions do not serve any purpose of encapsulation, reuse, modularization. More: these are most probably just empty words for them, they don't have any encapsulation need and are therefore unable to recognize this never encountered concept. So this is why the electronic analogy is great: it lets them connect with something they know.
But from the computing side of things there's more. It seems that you are letting your students somehow follow a path of prehistoric programmers discovering how to take advantage of that strange creature called processor armed only with a sharp stone.
We may think that all our reuse or modularization needs will be perfectly served by
goto. One sunny morning a programmer wakes up in his cave and observes that some problems are very very similar to one another and can be solved by repeating the same basic instructions with slight differences. He takes his stones and starts forging his
goto into something more elaborate: the point where you land after the jump doesn't start right away but inspects some mysterious values called parameters and only after that the work can begin, being different depending on the actual parameters seen.
If this is the learning path that the students are following then what is needed is a case where they must do some operations in differing incarnations: if they do not feel this need they won't understand what are you wanting from them. In your introducing examples nothing of this kind was needed: if I just need to add1 then read, +1, write, end of story.
One problem alone doesn't need functions. A class of similar problems does. Ultimately, a computing system is one calculating a function, i.e. solving a class of problems, represented as differing inputs.
Now, unfortunately I don't have such examples in mind right now, but I hope it may be easier to invent them by having a clearer picture of their nature.
Answered by user9137 on December 27, 2020
I like to think about pure function as a transmutation of inputs. Just like in Alchemy you connect Fire and Water to get Steam. Fire and Water are inputs, Steam is output. Or treat function as an assembly machine -- it takes resources, and converts those into another resource.
After that try posing a question: given two integer numbers as an input, what kinds of transmutation about these two numbers can you think about?
So first idea should be:
And usually that's it, I mean, student fantasy often stops here. Now your turn to make "how did I not think about it?" in student's brain:
Make sure students understood what every of these functions had done to two numbers. Ask them "anything else?" and if they produce more math examples (combinations), this is good, but at some step stop them and show this:
Now again, ask students "anything else?", make sure they understand how a function can take two arguments and do nothing, and return nothing, this is quite counterfactual for some. It is good if some list results are guessed, otherwise, show yourself:
Make sure students are able to visualize each example, of how two numbers transform to list. The biggest sign of this is when they get the pattern and try to produce own examples. After some time, you break their brain again:
Ask students "anything else?", and if they grok pattern they should start some random list generations with some random numbers. The more random examples, the better, creativity is not easy. But at some point you break their brain once more:
It is mind-shifting to think about function which returns a function, but if students can provide own examples (however fantastic), this is very good sign. Good if somebody can create function which returns a function which returns a function. But if not:
After students brain is completely devastated by trying to imagine this, you show a few more examples:
Ok, and after all this done, ask the original question again "what can a function do with two numbers" and check student recall, how many of these examples were really grokked. The simple
def plus(a, b): return a + b will now look different in student's head
P.S. After lesson is done, you tell "all the examples we talked about were about pure functions. But if we consider impure functions, then ..." :)
Answered by danbst on December 27, 2020
Can I craft an exercise ... that would give a dramatically wrong output, e.g. cause the screen to "blow" up if the function print-ed instead of return-ed...
Early in my Python classes I do (something like) this:
>>> def foo(x): ... print(2*x + 3) ... >>> def bar(x): ... return (2*x + 3) ... >>> foo(4) 11 >>> bar(4) 11
So they look quite the same, don't they?
Now use them:
>>> [bar(x) for x in range(5)] [3, 5, 7, 9, 11] >>> [foo(x) for x in range(5)] 3 5 7 9 11 [None, None, None, None, None]
Answered by Rusi on December 27, 2020
4 Asked on February 1, 2021 by user9137
3 Asked on January 29, 2021 by neal-zupancic
1 Asked on January 28, 2021
3 Asked on January 5, 2021 by user9790
5 Asked on December 30, 2020 by buffy
3 Asked on December 29, 2020 by neelesh-v
8 Asked on December 27, 2020 by louis-b
3 Asked on December 20, 2020 by pluke
21 Asked on December 11, 2020 by ben-i
0 Asked on December 8, 2020
5 Asked on December 7, 2020 by totera
3 Asked on December 4, 2020 by technosam
Get help from others!