Kushal Kumaran wrote: > On Tue, May 3, 2011 at 5:31 PM, Peter Otten <__pete...@web.de> wrote: >> <snip> >> >> Also you should make the try...except as narrow as possible >> >> try: >> centimeters = float(centimeters) >> except ValueError as e: >> print e >> >> is likely to catch the float conversion while with many statements in the >> try-suite you are more likely to hide a problem that is unrelated to that >> conversion. >> > > I would have expected it to be the other way. If you cannot > reasonable expect to continue after an exception, then the try block > should extend all the way across the block of code you want to skip. > In your snippet, what if some code later is relying on the > 'centimeters' variable having a useful float value? IMO, > encapsulating small bits of code in try ... except blocks really makes > code written using exceptions look ugly.
Instead of repeating what Alan said I'll give you a side-by-side example: import sys def make_raw_input(stdin, stdout): def raw_input(message): stdout.write(message) s = stdin.readline() stdout.write(s) return s.rstrip("\n") return raw_input if not sys.stdin.isatty(): raw_input = make_raw_input(sys.stdin, sys.stdout) _conversion_factors = {"in": (2.54, "cm"), "cm": (1/2.54, "in")} def thorough_convert(): default_unit = "in" while True: s = raw_input("Enter a length in inches or cm (like '7 in' or '1.3 cm') ") if not s: print "That's all, folks" break try: value, unit = s.split(None, 1) except ValueError as e: value = s unit = default_unit print "using default unit:", unit try: conversion_factor, target_unit = _conversion_factors[unit] except KeyError: print "unrecognized length unit: {!r}".format(unit) continue default_unit = unit try: value = float(value) except ValueError as e: print e else: target_value = value * conversion_factor print "{} {} --> {} {}".format(value, unit, target_value, target_unit) def simple_convert(): while True: try: s = raw_input("Enter a length in inches or cm (like '7 in' or '1.3 cm') ") if not s: break value, unit = s.split() factor, target_unit = _conversion_factors[unit] print s, "-->", float(value)*factor, target_unit except Exception as e: print e if __name__ == "__main__": if "--simple" in sys.argv: convert = simple_convert else: convert = thorough_convert if "--demo" in sys.argv: from StringIO import StringIO raw_input = make_raw_input(StringIO("""\ 1 cm 2 in 3 x 4 """), sys.stdout) convert() Let's run the demo: $ python2.7 inch.py --demo --simple Enter a length in inches or cm (like '7 in' or '1.3 cm') 1 cm 1 cm --> 0.393700787402 in Enter a length in inches or cm (like '7 in' or '1.3 cm') 2 in 2 in --> 5.08 cm Enter a length in inches or cm (like '7 in' or '1.3 cm') 3 x 'x' Enter a length in inches or cm (like '7 in' or '1.3 cm') 4 need more than 1 value to unpack Enter a length in inches or cm (like '7 in' or '1.3 cm') $ python2.7 inch.py --demo --thorough Enter a length in inches or cm (like '7 in' or '1.3 cm') 1 cm 1.0 cm --> 0.393700787402 in Enter a length in inches or cm (like '7 in' or '1.3 cm') 2 in 2.0 in --> 5.08 cm Enter a length in inches or cm (like '7 in' or '1.3 cm') 3 x unrecognized length unit: 'x' Enter a length in inches or cm (like '7 in' or '1.3 cm') 4 using default unit: in 4.0 in --> 10.16 cm Enter a length in inches or cm (like '7 in' or '1.3 cm') That's all, folks $ While thorough_convert() is three times as long as simple_convert() and both do almost the same I'd argue that the user experience is significantly improved by better error messages and smarter defaults. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor