[Tutor] please return flys in ointment
Alan Gauld
alan.gauld at btinternet.com
Sun Jul 7 01:06:29 CEST 2013
On 06/07/13 22:38, Jim Mooney wrote:
> naturally, lest I look dumb, I'd appreciate criticism,
OK, here are a few comments, take em or leave em...
> import sys
>
> # Data
<snip...>
> # Functions
> def make_triplets_from_input():
Why not pass in the prompt string as an argument?
> '''Enter a positive integer. A list of triplets in the same order
> will be returned.
> Raise ValueError to loop on non-integer input, or return 'zero'
> trigger-value of
> 'xxx' if all zeroes are entered. If input is okay, strip leading
> zeroes, then
> zero-pad leftmost triplet to three characters, so all slices are
> triplets. Adjust
> input for different Python versions.'''
Not strictly accurate - see comments below.
> while True:
> try:
> if sys.version[0:3] == '2.7':
> numbers_str = original = raw_input('Enter a positive
> integer, space \
> separated if desired.')
I'd probably just use
input = raw_input
to keep the code simple.
> elif sys.version[0:3] == '3.3':
> numbers_str = original = input('Enter a positive
> integer, space \
> separated if desired.')
Then you don't really need this bit unless you really want to
exclude other v3.X Python's which seems a tad harsh!
> else:
> print('Python versions 2.7 and 3.3 only supported')
> sys.exit()
Probably better to take a chance and say Python versions above 2.7.
Backward compatibility is pretty good in Python land.
> numbers_str = ''.join(numbers_str.split())
> if numbers_str == '' or numbers_str == ' ': raise ValueError
> numbers_int = int(numbers_str)
Why not just allow the built in Exception to raise itself?
>>> int('')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''
>>>
> if numbers_int == 0:
> print('Zero')
> sys.exit()
> numbers_str = str(numbers_int)
Not sure why this is needed, you already got the int from
the str so why not use the original string?
> if len(numbers_str) > 36: raise ArithmeticError
> break
Its not really Arithmetic? I'd have said a ValueError...
> except KeyboardInterrupt:
> print('Program cancelled by user')
> sys.exit()
Again, what's wrong with the standard error message?
> except ValueError as err:
> print(original, "is not an integer.")
> continue
> except ArithmeticError as err:
> print(original, "is too big.\n999...decillion is max:
> 10**37-1 or 36 chars \
> or 12 groups of 3 chars")
OK, Now i see why the ArithmeticError. But you cpuild just have printed
the message before raising ValueError? Or even passed the message into
ValueError?
>>> raise ValueError('Value too big, try again')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Value too big, try again
>>>
It feels like you are trying to do much of Python's job yourself.
Let the force be with you...
> leftpad = len(numbers_str) % 3 # zero-pad left, so we get all
> 3-character triplets
> if leftpad == 0: leftpad = ''
> elif leftpad == 2: leftpad = '0'
> else: leftpad = '00'
Feels like a job for a dictionary and get() - or even a
simple tuple index:
leftpad = ('','0','00')[leftpad]
Personally I prefer not to change types in a single
variable like that (probably my C/Pascal background
coming out!) so I'd probably do it like this:
leftpad = ('','0','00')[ len(numbers_str) % 3 ]
Or introduce an extra vareiable - padlen or somesuch...
> numbers_str = leftpad + numbers_str
> triplets = [numbers_str[x:x+3] for x in range(0,len(numbers_str),3)]
> return (triplets, len(triplets))
Not sure I'd bother returning the len, the user can get it as needed
very easily and your function name and docstring give no hint to expect
a len result as well as the triplets.
No further comments - its getting late! :-)
HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
More information about the Tutor
mailing list