Re: [Tutor] Function works one time then subsequently fails
On 29/04/15 04:58, Jim Mooney Py3winXP wrote: numbers = [] Note that you chose to make this global. def parse_string(math_string): """Input: A math string with a verbal or mathematical operation and two valid numbers to operate on. Extra numbers and operations are ignored. Output: A tuple containing a function corresponding to the operation and the two numbers. Returns None on failure. """ General comment. returning a mixture of None and valid data is a recipe for confusion later. Its better to fail by raising an exception, say a ValueError for example, or even create a bespoke error. operation = None tokens = math_string.split() for token in tokens: if token in operations: operation = operations[token] elif test_number(token) != None: numbers.append(test_number(token)) if len(numbers) > 1: break if operation is None or len(numbers) < 2: return None else: return operation, numbers[0], numbers[1] REPL result = parse_string('1 minus 15') func, number1, number2 = result func(number1, number2) -14 result = parse_string('1 minus 15') print(result) None You never empty numbers so it already contains >1 numbers. Your loop breaks. And operation is None. So you return None. That's why raising an error with suitable text would be clearer. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Function works one time then subsequently fails
On 28Apr2015 22:27, Jim Mooney Py3winXP wrote: On 28 April 2015 at 21:27, Cameron Simpson wrote: At a first glance numbers is a global. It is reset to [] at program start, but never again. So you're appending to it forever. I have not investigated further as to how that affects your program's flow. Took you less time to find that than me. I, of course, realized I forgot to empty the number list on each time through the parse loop, After I posted ;') Seems to work okay otherwise, although criticism of Pythonicity is welcome. I just wanted to practice tossing functions around. I'll put it into a user input loop and work it. It won't catch everything. I have to study regexes for that. Basicly, you should almost never have a global variable. There is a host of special circumstances where globals solve some specific problems. But by and large, don't do it without a very concrete reason. If numbers had been local to the parse function you would never have been bitten by this. There's no need for it to be global; you can return the operator and the operands (numbers) easily from the parse function. At this point I'm starting to lose track and have to think of better ways to organize so I recall and understand what I'm doing. I know there are general tuts on that but that's just reading. Is there a python-specific tut on it where I could follow actual code along with the interpreter to reinforce things? Or, what is the official word for organize-so-you-don't-forget-or-get-confused so I can search google with it? "functional decomposition"? One rule of thumb is that functions should be short. That way you can generally keep their purpose and internal oparations in your head in one go, and the whole thing also fits on your screen. As with all things, sometimes that cannot be reasonably achieved, but it is usually so. We can pick over your code as well if you like. Should we? Cheers, Cameron Simpson If this experiment we're doing works, then I will follow up and push it as hard as possible. And if it doesn't work, I will write a science-fiction novel where it does work. It's a win-win situation. - John Cramer on his experiment for possible cuasality violation ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Function works one time then subsequently fails
On 28 April 2015 at 21:27, Cameron Simpson wrote: > At a first glance numbers is a global. It is reset to [] at program start, > but never again. So you're appending to it forever. I have not investigated > further as to how that affects your program's flow. > > Cheers, > Cameron Simpson > Took you less time to find that than me. I, of course, realized I forgot to empty the number list on each time through the parse loop, After I posted ;') Seems to work okay otherwise, although criticism of Pythonicity is welcome. I just wanted to practice tossing functions around. I'll put it into a user input loop and work it. It won't catch everything. I have to study regexes for that. At this point I'm starting to lose track and have to think of better ways to organize so I recall and understand what I'm doing. I know there are general tuts on that but that's just reading. Is there a python-specific tut on it where I could follow actual code along with the interpreter to reinforce things? Or, what is the official word for organize-so-you-don't-forget-or-get-confused so I can search google with it? -- Jim If you only had one hour left to live, would you spend it on Facebook, Twitter, or Google Plus? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Function works one time then subsequently fails
On 28Apr2015 20:58, Jim Mooney Py3winXP wrote: This is really puzzling me. I'm parsing a string to do some simple math operations and practice tossing functions around. My parser works on the first run, then it continually fails on the same input. [...] numbers = [] [...] def parse_string(math_string): """Input: A math string with a verbal or mathematical operation and two valid numbers to operate on. Extra numbers and operations are ignored. Output: A tuple containing a function corresponding to the operation and the two numbers. Returns None on failure. """ operation = None tokens = math_string.split() for token in tokens: if token in operations: operation = operations[token] elif test_number(token) != None: numbers.append(test_number(token)) if len(numbers) > 1: break [...] At a first glance numbers is a global. It is reset to [] at program start, but never again. So you're appending to it forever. I have not investigated further as to how that affects your program's flow. Cheers, Cameron Simpson There are two ways of dealing with this problem: one is complicated and messy, and the other is simple and very elegant. We don't have much time left, so I'll just show you the complicated and messy way. - Richard Feynman, 1981 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Function works one time then subsequently fails
This is really puzzling me. I'm parsing a string to do some simple math operations and practice tossing functions around. My parser works on the first run, then it continually fails on the same input. """ Takes the name of a binary math operation and two numbers from input, repeatedly, and displays the results until done """ def add(a, b): return a + b def subtract(a, b): return b - a def minus(a, b): return a - b def multiply(a, b): return a * b def divide(a, b): return a / b operations = {'add': add, '+': add, 'plus': add, 'subtract': subtract, '-': minus, 'minus': minus, 'multiply': multiply, '*': multiply, 'times': multiply, 'divide': divide, '/': divide, 'divided': divide} numbers = [] def test_number(astring): """ Input: A string that should represent a valid int or float. Output: An int or float on success. None on failure. """ for make_type in (int, float): try: return make_type(astring) except ValueError: pass return None def parse_string(math_string): """Input: A math string with a verbal or mathematical operation and two valid numbers to operate on. Extra numbers and operations are ignored. Output: A tuple containing a function corresponding to the operation and the two numbers. Returns None on failure. """ operation = None tokens = math_string.split() for token in tokens: if token in operations: operation = operations[token] elif test_number(token) != None: numbers.append(test_number(token)) if len(numbers) > 1: break if operation is None or len(numbers) < 2: return None else: return operation, numbers[0], numbers[1] REPL >>> result = parse_string('1 minus 15') >>> func, number1, number2 = result >>> func(number1, number2) -14 >>> result = parse_string('1 minus 15') >>> print(result) None >>> result = parse_string('1 minus 15') >>> print(result) None >>> -- Jim If you only had one hour left to live, would you spend it on Facebook, Twitter, or Google Plus? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor