[Tutor] best practice

Remco Gerlich scarblac@pino.selwerd.nl
Wed, 31 May 2000 09:52:21 +0200


On Tue, May 30, 2000 at 11:13:49PM -0500, Timothy Wilson wrote:
> Hi everyone,
> 
> Thanks for all of the suggestions with my little prime number program. As
> several people pointed out, the problem was that raw_input gets a string
> which sqrt() chokes on. In the interpreter, all it well because the function
> gets called directly with an integer. OK, problem solved.
> 
> That brings up another very picky question though. Where should I handle
> these type difficulties? Here's another little program I was playing around
> with that takes an integer and returns a list of the integer's factors. The
> algorithm is crude, but effective.
> 
> wilson@beethoven modules]$ cat factor.py
> # This function factors an integer and returns a list
> 
> from math import *
> 
> def factor(number):
> 	factors = [1, int(number)]
> 	for i in range(2, sqrt(number) + 1):
> 		if number % i == 0:
> 			factors.append(i)
> 			if i != number/i:   # catch duplicates
> 				factors.append(int(number/i))
> 	factors.sort()
> 	return factors
> 
> if __name__ == '__main__':
> 	number = raw_input("Factor what? ")
> 	print factor(float(number))
> 
> As you can see, I convert the raw_input to a float before passing it to the
> function. Also, I have a couple of int() functions in my factor function to
> make sure that the list which is returned is a list of integers. **When run
> from the interpreter, those int()s aren't needed.**
> 
> So here's the question (it's about time :-). Is it better python practice to
> make those type conversion outside the function or inside as I've done?

The function only makes sense for integer arguments, really. So I usually
assume that the argument is an integer, *put that in the doc string*, and
use an assert statement.

def factor(number):
   """factor(number)
   
   Return a list with the factors of a number. Argument must be an integer."""
   assert type(number) == type(1)
   
   etc.

Now it throws an exception when the wrong type of argument is passed in.

> Should the functions be made as "pure" as possible? It seems to me that for
> maximum efficiency, a rule of thumb should be that functions should be made
> to work in the interpreter with a minimum of fuss.

Well... This 'works in the interpreter' because you give it an integer
argument there. And in your program you use float()... that's just odd,
nothing to do with the interpreter :).

Functions can either only accept the correct type of input and fail
otherwise, or try to convert input to the correct type. I think the first is
more Pythonish (consistent, programmer has to spell out exactly what he
wants) and the second is more Perlish (try to guess what the programmer
wanted).

Whatever you do, be consistent about it, and document it :-)

> The programmer who uses
> the function (or module) should be the one who concerns himself with the
> "types" of variables that are passed.

Yes. But what if he doesn't? In Python I say, throw an exception. In Perl,
try to figure out what he meant.

-- 
Remco Gerlich,  scarblac@pino.selwerd.nl