[Tutor] raise exception works as planned in program but not when imported into testing module
Jim Mooney Py3.4.3winXP
cybervigilante at gmail.com
Thu Apr 30 03:05:29 CEST 2015
I raised an exception in the parse_string function in my math parser
program, function_tosser.py, and caught it in the calling routine, and that
worked fine. But when I imported function_tosser.py into a test program,
tester.py, it threw the exception in the parse_string function instead of
handling it in the try block in the calling routine. Why did it work in one
and not the other? The testing program works fine if I return None as I did
before, instead of raising the exception.
# function_tosser.py
"""
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,
'subtracted': subtract,
'-': minus, 'minus': minus, 'multiply': multiply, '*':
multiply, 'multiplied': multiply,
'times': multiply, 'divide': divide, '/': divide, 'divided':
divide}
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: # Previously returned None, which worked. This
works fine here but when imported into the test program
pass # it doesn't wait for the try block in the
calling routine.
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()
numbers = []
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:
raise ValueError
else:
return operation, numbers[0], numbers[1]
if __name__ == "__main__":
instructions = '''Enter two numbers and one of the four basid math
operations,
either mathematical or verbal. i.e. 3 + 2, 12 divided by 14, 10 minus
4, etc.
Enter done to quit.
'''
try:
user_input = input(instructions)
while True:
if user_input == 'done':
break
try:
result = parse_string(user_input)
except ValueError:
print("Not a valid math operation.")
else:
func, num1, num2 = result
print(func(num1, num2))
user_input = input()
except KeyboardInterrupt:
print("Program terminated by user")
# tester.py
'''Test function_tosser.py mainlogic against random operators, operands,
and bad input'''
import random
import function_tosser as ft
valid_terms = list(ft.operations.keys())
def eval_test():
pass
trash = ['1 +', 'blah', '3-4', 'gargle', 'Newt Gingrich',
",,,,,", '{+=-33.44 minus12 3 times blarg 1445641654644555455']
for ctr in range(50):
term = ' ' + random.choice(valid_terms) + ' '
num1 = str(random.randint(1,1000))
num2 = str(random.randint(1,1000))
if term == ' subtract ' or term == ' subtracted ': term = ' subtracted
from '
if ctr % 10 == 0: # stress testing for a None failure
monkey_wrench = random.choice(trash)
print(ft.parse_string(monkey_wrench), '\n')
else:
func, num1, num2 = ft.parse_string(num1 + term + num2)
print(func, num1, term, num2)
print('result:',func(num1, num2), '\n')
--
Jim
"What a rotten, failed experiment. I'll start over. Maybe dogs instead of
monkeys this time." --God
More information about the Tutor
mailing list