![]() |
condensing try except - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: condensing try except (/thread-7622.html) |
condensing try except - mepyyeti - Jan-18-2018 There must be a way to achieve this type of code. As it is its violating everything about DRY... also is there any way to condense try except statements within 1 while True looks? example while True: try: foo = str(input('enter a string: ')) bar = int(input('enter a bar num > ')) moo = int(input('enter moo num > ')) break except ValueError: if foo != str(foo): print('must be a word...') else: print('number please') continuethere must be a way to tighten this up... RE: condensing try except - metulburr - Jan-18-2018 your code can be simplified to just this foo = input('enter a string: ') #input already returns a string while True: try: bar = int(input('enter a bar num > ')) moo = int(input('enter moo num > ')) except ValueError: print('you must input a number only') continue breakinput() returns a string, so its obviously a string. assume bar and moo will be input correctly as ints, and catch it in try/except if not RE: condensing try except - Gribouillis - Jan-18-2018 If you fear to violate the DRY principle, write a function from functools import partial def typed_input(prompt, type, errmsg): while True: v = input(prompt) try: v = type(v) except ValueError: print(errmsg) else: return v int_input = partial(typed_input, type=int, errmsg='An integer is required, try again...') float_input = partial(typed_input, type=float, errmsg='A real number is required, try again...') if __name__ == '__main__': foo = input('enter a string: ') bar = int_input('enter a bar num > ') moo = int_input('enter a moo num > ') RE: condensing try except - mepyyeti - Jan-18-2018 @Gribouillis I think this is very elegant. Can you give me a quick run down of the what the function is doing. I don't quite understand it. I'm not very familiar with the functools module. My first impression is that this is similar to a wrapper (aka hard coded decorator...which I've only recently gotten to...) I'm stuck on the concept of the definition name used as a leading argument when the int and float objects are instantiated... I understand the if clause at the bottom. That is crystal clear. I'm lost on the interplay between function and object here....would u pls run through it (even if only briefly)...thx RE: condensing try except - Gribouillis - Jan-18-2018 (Jan-18-2018, 05:20 PM)mepyyeti Wrote: Can you give me a quick run down of the what the function is doing The function typed_input() takes three arguments, it can be used this wayn = typed_input('enter integer: ', int, 'An integer is required, try again...')It then asks repeatedly a string by printing enter integer: , then it tries to convert the string to a python integer by calling int() and if it fails, it prints the error message and asks again.The idea of using int and errmsg in the parameters is that the function can be used to input other datatypes by using for example float or complex in the arguments.The fuctools.partial() callable is the python implementation of partial function application. It takes a function and some arguments and it creates a new callable with fewer arguments, so partial(type_input, type=int, errmsg='No, try again...') creates a new callable which takes a single prompt argument, the same interface as input() This looks a little like meta-programming, because we use a type as a parameter, which is not very frequent. If you look carefully, you'll notice that the only hypothesis on the 'type' parameter is that is is a callable taking one argument and throwing ValueError . This can be used to input more general data. For exemple suppose I want the user to enter a probability, which is a real number between 0 and 1, I can writedef probability(arg): p = float(arg) if not (0.0 <= p <= 1.0): raise ValueError(('Invalid value for probability():', arg)) return p proba_input = partial(typed_input, type=probability, errmsg='A probability is required, try again...') qux = proba_input("Give me a probability > ")This will prompt the user until she enters a number between 0 and 1 ! RE: condensing try except - mepyyeti - Jan-26-2018 (Jan-18-2018, 06:20 PM)Gribouillis Wrote:(Jan-18-2018, 05:20 PM)mepyyeti Wrote: Can you give me a quick run down of the what the function is doing Working on partials, I'm noticing that the variable qux isn't really necessary. Suppose: the user is ask to input probability 3 times. why wouldn't I just use proba_input = partial(typed_input, type=probability, errmsg='prob reqd')? I mean at its extreme end I could just reuse the same variable and just overwrite the value. I'm not quite clear on the benefit of foo = bar(original_func_as_place_holder,para1='a',para2='b')when I have already set up bar = partial(original_func_as_place_holder,para1='a',para2='b'). I mean since foo is a variable I can't just use it as a function every time I ask for probability input. I have to rewrite the partial anyway. RE: condensing try except - Gribouillis - Jan-26-2018 I don't understand your objection. One can ask the user to input 3 different probabilities by calling proba_input() 3 timesfor i in range(3): qux = proba_input('Give me the {}-th probability: '.format(i))The line with partial is only a way to define a new callable ( proba_input ) by specifying two arguments for typed_input .Consider the following example >>> def is_multiple_of(a, b): ... return b % a == 0 ... >>> is_multiple_of(5, 15) True >>> is_multiple_of(5, 14) False >>> from functools import partial >>> is_even = partial(is_multiple_of, 2) >>> is_even(14) True >>> is_even(13) False >>> is_even(12) True >>> is_even(9) False |