[Tutor] method conflict?
Okay, it appears the method in a class has its own ID, but all instantiations of that method have identical IDs. But what happens if we have a huge number of instantiations trying to access the identical method at the same time? class MyClass: def setdata(self, data): self.data = data def getdata(self): print(self.data) >>> MyClass.setdata >>> id(MyClass.setdata) 40676568 >>> f = MyClass() >>> g = MyClass() >>> id(f.setdata) 43576616 >>> id(g.setdata) 43576616 >>> d = MyClass() >>> id(d.setdata) 43576616 -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Are the methods in a class copied or just linked to?
When an instance uses a class method, does it actually use the method that is in the class object's memory space, or is the method copied to the instance? -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Is there a way to use "with" across suite boundaries?
'''I was using with open...:, but I'm printing a header in one function, calling a looping function to print detail lines, then returning to the calling function to print the footer. But that didn't work since the with statement only seems to work with the lexical suite and the file wasn't open in the detail print function. Is there a way around this, other than passing the file as I have here? Also, is it a good idea to pass a file handle like that or is there a better way? Using the below csv file co2-sample.csv to print a simple HTML table (header omitted) Since this is a file there are enclosing single quotes not visible: "ANTIGUA AND BARBUDA",0,0,0,0,0 "ARGENTINA",37,35,33,36,39 "BAHAMAS, THE",1,1,1,1,1 "BAHRAIN",5,6,6,6,6 "SPANISH INQUISITION, THE, SILLY",10,33,14,2,8 Program follows (py3.4, winxp):''' htbegin = ''' htest table, td {border:2px solid black; border-collapse:collapse;} td {padding:3px; background-color:pink; text-align:right;font-family:verdana;} td.l {text-align:left} ''' htend = ''' ''' def make_lines(): co2 = open('co2-sample.csv') ht = open('output.html', 'w') linelist = [] print(htbegin, file=ht) for line in co2: newlist = line.rsplit(',', 5) # ending is regular so split it out first for token in newlist: # since split char inside quotes for nation is problematic linelist.append(token.strip('"')) # get rid of extra quotes linelist[-1] = linelist[-1].strip() fprint(linelist, ht) linelist = [] co2.close() print(htend, file=ht) ht.close() def fprint(linelist, ht): # size formatting irrelevant for HTML formatted_string = "{}{}{}{}{}{}".format(*linelist) print(formatted_string, file=ht) print('', file=ht) if __name__ == "__main__": make_lines() -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting import to use a variable name
On 20 May 2015 at 01:02, Peter Otten <__pete...@web.de> wrote: > If you start with an object dir() gives you a list of attribute names. To > get the actual attributes use > > attribute = getattr(object, attribute_name) > > Then print the attributes' docstring with > > print(attribute_name, attribute.__doc__) > Thanks. That will save a lot of scrolling - and saving scrolling and typing is half the battle ;') -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting import to use a variable name
On 19 May 2015 at 17:25, Jim Mooney Py3.4.3winXP wrote: > > If I can get dir to accept x I can parse the output to get rid of the > __xxx stuff and print it out. > By that I mean dir will give me a list of strings I can then use __doc__ on to get all useful help items. -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting import to use a variable name
On 19 May 2015 at 17:18, Ben Finney wrote: > You will be pleased to know of the standard library ‘importlib’ > library:: > > >>> import importlib > Yes, I already got importlib to accept a string. But I can't figure how to get dir to accept it: >>> x = 'shutil' >>> import importlib >>> importlib.__import__(x) >>> If I can get dir to accept x I can parse the output to get rid of the __xxx stuff and print it out. -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Getting import to use a variable name
I use python help() a good deal but get tired of paging through the __object__ stuff to get to what I use at my level, so I wrote the following to omit it. The problem is, I want to import it then use it as shorthelp.py for different modules so I could just type shorthelp(modulename). Only the import mechanism won't let me rename. I can only use the hardcoded imported module name, shutil in this case. If I try x = anothermodule, then import x, it doesn't work. import sys.argv[1] also doesn't work. Is there any way to get around this? I'm mostly interested in doing this from the repl rather than running from the console. Py3.4 win32 import shutil #this works to print non __xxx helpstrings for a module, but I can't substitute it. useful_helps = [] helps = dir(shutil) for helper in helps: if helper[0] == '_': continue useful_helps.append(helper) for helper in useful_helps: print(helper.upper() + ':', helper.__doc__, '\n') -- Jim After not doing dishes for a week and washing spoon after spoon, fork after fork, knife after knife - I suddenly understand the mathematical concept of infinity, which is just one more damn thing after another. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Terminology question
On 15 May 2015 at 22:45, Steven D'Aprano wrote: > > What does "didn't work" mean? Did your computer crash? Catch fire? A > completely different error got printed? Something else? I can see I was marvelously unclear ;') Here is what I meant. def make_error(): raise ZeroDivisionError('Here I am') def call_error(): try: make_error() except: print("How do I get the 'Here I am' message to print in the calling routine?") >>> call_error() How do I get the 'Here I am' message to print in the calling routine? -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Terminology question
On 14 May 2015 at 16:47, Alan Gauld wrote: > Rather than printing the messages you could re-raise > the error but with the error message attached as a string. > I'm a little unclear how you catch the string you create in a raise, in the caller. I tried an example from the docs but it didn't work. Could you provide a simple example? Sometimes the docs are heavy slogging if you don't already know what's what ;') -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Terminology question
I noticed that if I call a function that throws an error, I can catch it from the caller, instead of catching it in the function. Is this is what is known as "errors bubbling up?" Also, is this how you're supposed to do it? *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** '''Print a table of random numbers, given min, max, rows, and columns''' from random import randint def make_table(minimum, maximum, rows, columns): for row in range(rows): print() for column in range(columns): print(randint(minimum, maximum), end = ' ') def get_input(): inp = input("Enter minimum, maximum, rows, and columns, separated by commas: ") inps = inp.split(',') try: minimum = int(inps[0]) maximum = int(inps[1]) rows = int(inps[2]) columns = int(inps[3]) return minimum, maximum, rows, columns except ValueError as err: print("non-integer entered", err) return None except IndexError as err: print("You didn't enter enough values.", err) return None vals = get_input() if vals: minimum, maximum, rows, columns = vals try: make_table(minimum, maximum, rows, columns) except ValueError as err: # CATCH FUNCTION ERROR HERE INSTEAD OF IN FUNCTION print("Enter min before max.") else: print('Nothing to do.') -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 7 May 2015 at 18:42, Dave Angel wrote: > Python doesn't have pointers So what is the difference between a python name and a pointer? I'm a bit fuzzy on that. -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 7 May 2015 at 13:03, Emile van Sebille wrote: > Compare to: > > def testid(K=100): > K += 10 > return 'the ID is', id(K), K > Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. It used lists so I tried ints. Although I realized persistence also works for dicts ;') def testid(newitem, K={}): K[newitem] = newitem + 'item' return 'the ID is', id(K), K >>> testid('bonk') ('the ID is', 18263656, {'bonk': 'bonkitem'}) >>> testid('clonk') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) >>> testid('spam') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': 'spamitem'}) -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] pointer puzzlement
I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? def testid(K=10): K += 10 return 'the ID is', id(K), K *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 6 May 2015 at 14:08, Dave Angel wrote: > I don't know why you would be expecting to get a utf-8 character for the > second byte of a function key code. It's an entirely arbitrary byte > sequence, and not equivalent to anything in Unicode, encoded or not I just didn't think of accounting for function keys until I hit one - experimental learning. The program I'm working on doesn't require F keys, but I tried one just to see what would happen ;') It's worth making the error to reinforce unicode in my head. One item - once I dropped decoding for special keys, some were printed as hex codes but some as letters. i.e. F11 was b'\x85', but F9 and F10 were b'C' and b'D', so I assume the second byte of some function keys just happens to map to utf-8 letters. Sure enough, when I put in decoding again, F9 and F10 second bytes printed as C and D, but the program bailed on F11. -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 6 May 2015 at 10:41, Jim Mooney Py3.4.3winXP wrote: > I went a further step from the recipes linked to above and got here >> https://pypi.python.org/pypi/readchar > > > I think that's the one that failed for me > Addendum. That only failed in python 3.4. It worked fine in python 2.7 - but I rarely use that. -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 5 May 2015 at 21:51, Mark Lawrence wrote: > On 06/05/2015 05:30, Jim Mooney Py3.4.3winXP wrote: > >> On 5 May 2015 at 18:32, Steven D'Aprano wrote: >> >> https://code.activestate.com/recipes/577977-get-single-keypress/ >>> >> >> >> That only has a stub for Linux, but I found one that does both. Although, >> alas, no IOS version: >> >> >> http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ >> >> Anyway, I set up msvcrt for now until I install linux - I'm not interested >> in the program I mentioned, per se, just the error message - mainly to >> know, generally, what sort of thing it's choking on. Errors are useful to >> know. >> >> > I went a further step from the recipes linked to above and got here > https://pypi.python.org/pypi/readchar I think that's the one that failed for me but I found out why. I just wrote the simple snippet below to try msvcrt out. I can add a Linux try block when I install Linux and actually find a wifi driver for it ;') I reproduced the error that puzzled me almost immediately. It was from hitting a function key. The snippet below worked fine for letters and such, but died when I hit a function key (although not all of them). I was decoding since msvcrt sends byte strings, but there was nothing in the utf-8 map for that key. The 2> redirect is sure handy for dos console error messages - something I'll have to remember ;') from msvcrt import * while True: if kbhit(): key = getch() if key == b'\xe0' or key == b'\000': print('special key follows') key = getch() print(str(key, encoding='utf-8')) #got rid of this decode after a function key error else: print('The key is: ', str(key, encoding='utf-8')) Traceback (most recent call last): File "keyget.py", line 9, in print(str(key, encoding='utf-8')) UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 0: invalid start byte -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 5 May 2015 at 18:32, Steven D'Aprano wrote: > https://code.activestate.com/recipes/577977-get-single-keypress/ That only has a stub for Linux, but I found one that does both. Although, alas, no IOS version: http://code.activestate.com/recipes/134892-getch-like-unbuffered-character-reading-from-stdin/ Anyway, I set up msvcrt for now until I install linux - I'm not interested in the program I mentioned, per se, just the error message - mainly to know, generally, what sort of thing it's choking on. Errors are useful to know. -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 5 May 2015 at 18:35, Steven D'Aprano wrote: > Is this under Linux or another Unix? If so, > only redirects stdout, not > stderr, so you need: > > python3 setup.py 2> errors.txt > > to capture the errors. > > I have no idea if Windows works the same way. > Damn, that actually worked in windows instead of using their awful screen copy. What a surprise: errors.txt Traceback (most recent call last): File "setup.py", line 39, in long_description=read_description(), File "setup.py", line 11, in read_description return fd.read() File "c:\python34\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 2468: character maps to -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 5 May 2015 at 16:47, Jim Mooney Py3.4.3winXP wrote: > But that didn't work. How can I get a printout of setup errors so I can > post them? I remembered how to copy the DOS console. Here is the error. Error wasn't in setup.py so that wouldn't have worked anyway. C:\Python34\Lib\site-packages\readchar-1.1.0>python3 setup.py Traceback (most recent call last): File "setup.py", line 39, in long_description=read_description(), File "setup.py", line 11, in read_description return fd.read() File "c:\python34\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 2468: cha racter maps to -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] key detection
On 5 May 2015 at 15:36, Alan Gauld wrote: > Can python detect a keypress? >> > > That sounds simple but is actually quite tricky > since it's terminal dependent. An ancillary question. I found a readchar that purports to install in py2 and 3 but fails in 3. The errors (something from the encodings module) won't copy from the console, so I thought I could redirect them like so: python3 setup.py > errors.txt But that didn't work. How can I get a printout of setup errors so I can post them? That's something of general use aside from the keyboard loop. Otherwise, I decided to just use msvcrt for now, which is quite simple, and put in a try block for win or linux, when I dual boot linux, which I'm working on. (solving the usual driver problems for a toshiba laptop) -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] key detection
Can python detect a keypress? I've looked all over and can't find it. I don't mean input('blah') and have to press Enter - just detect it directly like Javascript does. All I find are references using msvcrt, which is Msoft specific, or using tkinter - but I don't want a whacking big GUI, just keypress detection. Can I make a simple keyboard event loop without tkinter? -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] raise exception works as planned in program but not when imported into testing module
Oops, my mistake. Ignore dumb remark below. I was thinking of the try - except in the main loop, but since I only tested the parse function, I never used that. I need to look a bit harder and find this stuff Before I post ;') Jim On 29 April 2015 at 23:04, Jim Mooney Py3.4.3winXP wrote: > > I think I meant something like this. An exception in a function is caught > by the caller. I imported the program that did this into the test program, > expecting the exception to still be caught when the parse_string was > called, by the try except else block in the mainroutine of the imported > program.. > > def excepter(): > raise ValueError > > try: > excepter() > except ValueError: > print("Exception caught after function call") > > REPL > >>> > Exception caught after function call > -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Fwd: Function works one time then subsequently fails
Sure, but let me include the full working program after fixup On 29 April 2015 at 19:09, Cameron Simpson wrote: > > These could all do with docstrings. add() is pretty obvious, but the > distinction between minus() and subtract() could do with elaboration. etc, etc. Thanks. Very comprehensive. I'll print it out and ponder it ;') -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] raise exception works as planned in program but not when imported into testing module
On 29 April 2015 at 21:14, Dave Angel wrote: > But why are you surprised? There's no try/except protecting the latter > line, so the exception will be uncaught, and you'll see it reported in > parse_string(). > I think I meant something like this. An exception in a function is caught by the caller. I imported the program that did this into the test program, expecting the exception to still be caught when the parse_string was called, by the try except else block in the mainroutine of the imported program.. def excepter(): raise ValueError try: excepter() except ValueError: print("Exception caught after function call") REPL >>> Exception caught after function call >>> -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] raise exception works as planned in program but not when imported into testing module
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 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Fwd: Function works one time then subsequently fails
On 28 April 2015 at 22:40, Cameron Simpson wrote: > > 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 Sure, but let me include the full working program after fixup. Although I still have to write another program to feed it random problems to work it out. It's a bit spacey, but I ran it through the pep8 program and it suggested that. I think two spaces between such tiny functions is overkill, though. """ 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: 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() 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: return None else: return operation, numbers[0], numbers[1] 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 result = parse_string(user_input) if result == None: 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") -- 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