Python function has access to global variables, and doesn't need passed arguments

When teaching functions in Python I get a little annoyed that the code below actually prints out the greeting. I know the preferred way would be to pass in the name, but, for students, if it works then why do something more complex. I want to teach them how to pass in arguments but if they mess up and forget it will still work. Thoughts about how to approach situations like this without being convoluted or contrived?

def greeting():
print("Hello " + name)

name = input("Enter your name: ")
greeting()

• You are being annoyed at the language itself, not the students. It is perfectly valid Python. Variable name has a binding when greeting is called. Use the code above as a lesson about dynamic binding, not a complaint against the student. Write your preferred code and contrast the two. It is an opportunity not a bug here. I argue that the students have not "messed up". They just didn't read your mind. Sep 28 '18 at 11:26
• If you want the students to use parameters, give them an example where using a parameter is the obvious way to do it. Sep 28 '18 at 11:58
• @Buffy I didn't think anyone would imply that I'm annoyed by the students. I stated that it was the code, and I know it's not a bug. Sep 28 '18 at 13:26
• @MichelBillaud Could you write up an answer with such an example? It might help future visitors. (I would try, but I am not even a little bit of a Pythoner)
– Ben I.
Sep 28 '18 at 13:45
• BTW, if you are trying to teach Python, but don't yet understand it thoroughly, have a look at this question: cseducators.stackexchange.com/questions/4379/…. It is a common enough dilemma, but there are solutions to it. Sep 28 '18 at 20:05

Your example demonstrates how to declare and use a function with a parameter, but not why they should do so.

Actually, there are no reason (for them) why they should bother with a new concept (function) instead of writing

name = input("Enter your name: ")
print("Hello " + name)


which can be done with the programming elements they already know. And is both shorter and simpler,

So, how to sell functions with parameters to beginners?

• they avoid code duplication (the example should contain several calls)
• they are called with different values (so parameters is the simplet way to transmit information)
• they implement a decomposition of tasks into subtasks (the sooner they practice the procedural approach, the better)

Here is an example:

def draw_line(width, end, middle):
line = end + middle*(width-2) + end;
print(line)

def draw_rect(height, width):
draw_line(width, "+", "-")
for  line in range(height-2):
draw_line(width, "|", " ")
draw_line(width, "+", "-")

def draw_square(side):
draw_rect(side, side)

def main(args):
draw_square(3)
draw_square(5)
draw_square(7)


Actually, I use Processing with a group of students. Most of them total beginners. The first motivation for functions is decomposition.

After they draw a simple figure with a few predefined function calls, as fill() to select a fill color, rect() and ellipse(), they are taught to split the work into user-defined functions

void draw() {
draw_sky();
draw_beach();
draw_sunset();
}


and parameters are then used for similar parts occurring at different places

void draw_seabird(int x, int y) {
....
}

• Do you do Processing in high school? I was thinking about teach p5.js but ended up with Python. Any issues or things you like? Sep 30 '18 at 19:12
• The example was just something simple I could put up for a talking point. Reuse and readability are talking points for sure. Decomposition is a lot easier when it comes to drawing. Sep 30 '18 at 19:16
• @tazboy That's the reason why I chose drawings for the first examples. Sep 30 '18 at 19:40
• Yeah, that's a great way to start. Did you do this in high school? How far do you go with them? Sep 30 '18 at 19:46
• That a one year professional training program at the university. Processing is used to explain the basics of programming and algorithmic, and then we switch to Java and other languages C#, php, javascript etc. Sep 30 '18 at 19:52

I teach Python after teaching students C, so my context might be slightly different. That said, my students get used to program execution beginning at main() from day one. You could take this as an opportunity to introduce the same approach in Python with the following:

def greeting(name):
print("Hello, " + name)

def main():
greeting("tazboy")

if __name__ == "__main__":
main()


If a student doesn't have a main function defined, they will see NameError: name 'main' is not defined.

I will admit that the boilerplate at the bottom is about as opaque as you can get. Even so, boilerplate code is something they will encounter in many other programming languages. I correlate it for my students to the MLA heading they write at the top of any essay. It's something that just has to be there, and it has a clear and important purpose.

• This answer is valid even if you don't teach C first. Beginners don't actually need complete, bottom up, explanations of everything, especially a bit of boiler plate. It can be treated as a magic incantation. In the age of Harry Potter, especially. Sep 28 '18 at 11:45
• I like this idea but I also don't want to add complexity to an awesomely, simple language like Python. Another part of this is my ignorance to the whole __name__ == "__main__". I have no idea what that is, so I'm failing in that respect. Gotta go look that up now. Sep 28 '18 at 19:10
• Every language has its quirks @tazboy. Eventually you get used to that and just live with them. Alternatively, you can work to build better languages. But at some level a program has to connect to the system on which it runs. That results in a lot of those quirks. But for teaching, it is generally fine to ignore the details (while including them) until the student has a better overall grasp. The alternative is to tightly integrate a language and its OS as was done originally with Smalltalk and Oberon. You may think such necessary spells are "Riddikulus" and you'd be correct. Hard to avoid tho. Sep 28 '18 at 19:28
• Yeah. I just need to teach that concept in a different way now, which is fine. This is the first thing I encountered that I wasn't expecting and I'm really enjoying teaching Python. Thanks for info. Sep 28 '18 at 22:57

I would think that any use of the same function with another parameter, stored in another variable, would solve the problem. For example, if they are pair programming:

def greeter(name):
print("Hello, " + name)

def pair_greeter(name_one, name_two):
print(name_one + " and " + name_two + " are a great team!")

typist_name = input("Who's the typist?")
greeter(typist_name)
observer_name = input("Who's the observer?")
greeter(observer_name)
pair_greeter(typist_name, observer_name)

• For reasons that I hope are obvious to you, I would much prefer driver and navigator to typist and observer. Especially if you are speaking indirectly of pair programming. Your names give completely the wrong idea about pairing. You make one, the navigator, far too passive, for example. If you think that they are accurate names, I strongly suggest that you investigate further. amazon.com/Pair-Programming-Illuminated-Laurie-Williams/dp/… Sep 28 '18 at 14:56
• @Buffy You can call them whatever you want; it is irrelevant to the question at hand.
You could show the code and ask the students, whether name really is available in greeting() since greeting is defined at a point in time where the interpreter does no know anything abount name. Then show a step-by-step walkthrough in a visual debugger.