On Wed, May 13, 2015 at 11:14 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > On Wed, 13 May 2015 02:05 am, Chris Angelico wrote: > >> So if you're writing a library function, it probably shouldn't use >> print()... but your application is most welcome to. You usually know >> which one you're writing at any given time. > > You might be, but beginners are not.
I meant the generic "you" there. A beginner may well not know whether to use / or //, whether it's better to use a list or a dict, etc etc etc. That's what instructors are for. Make the distinction that library functions shouldn't use print but application code can, and then examples like this... > I'm not sure I accept Rustom's fix for the problem (I think that his cure is > worse than the disease), but it is *hard* to get some beginners to use > return instead of print: > > def add_twice(x, y): > """Add twice y to x.""" > print x + 2*y > > > sort of thing. ... can be answered simply by explaining that "add_twice" ought to be written as a library function rather than an application. It's the exact same answer as this: def find_all_whatevers(base_dir): whatevers = [] os.chdir(base_dir) for fn in os.listdir(): if fn is a whatever: whatevers.append(fn) if fn is a directory: whatevers.extend(find_all_whatevers(fn)) return whatevers The working directory belongs to the application, not to a library function, so this shouldn't use os.chdir(), even though it does spare you the effort of string manipulation. (Of course, a real-world version of this should use os.walk(), but that's a complete rewrite.) The precise boundary between reusable functions and the actual application isn't always easy to draw, and there'll be times when you refactor something across that line. That's not a problem. There are still plenty of cases that are clear enough to use for explanation. > Personally, I think that banning print is only useful if you wish to > encourage cargo-cult programming: > > "Don't use print!" > "Why not?" > "My CS lecture said not to use it! I dunno, maybe it has a virus or > something." Agreed. There are VERY few features which should be utterly and totally banned, and they're usually kept only for backward compatibility with a time when people didn't know how dangerous they were. In Python, the only one I can think of is Py2's input(), which should be treated as XKCD 292 treats GOTO. (If you really *do* want to take a string from the user and immediately eval it, just write it as "eval(raw_input())" so everyone knows.) C has gets(), which is similarly dangerous and has a similarly straight-forward replacement. PHP has register_globals (or did until recently - it took a long time to go from "default is on, we recommend you turn it off" through "default is off, we recommend you don't turn it on" to finally "bad feature is removed"). Beyond those, there's not much that doesn't have at least _some_ reason for existing. > I'd rather give them exercises designed to show (rather than tell) the > differences between printing a result and returning a result, and how they > effect re-usability of software components and function chaining. Using a > procedural language is *perfect* for that, since you can highlight the > differences: > > function foo(n:int): int; > begin > foo := n+1; > end; > > procedure foo(n:int); > begin > writeln(n+1); > end; Yep. I'd also use clear function/procedure names to make it more visible, and probably tie this in with loops to show how you can print more than one thing but can only return one. (Generators are a more advanced topic.) A few examples go a long way. ChrisA -- https://mail.python.org/mailman/listinfo/python-list