Re: need some kind of "coherence index" for a group of strings
On 11/3/2016 1:49 PM, jlada...@itu.edu wrote: The Levenshtein distance is a very precise definition of dissimilarity between sequences. It specifies the minimum number of single-element edits you would need to change one sequence into another. You are right that it is fairly expensive to compute. But you asked for an algorithm that would determine whether groups of strings are "sort of similar". How imprecise can you be? An analysis of the frequency of each individual character in a string might be good enough for you. I also once used a Levenshtein distance algo in Python (code snippet D0DE4716-B6E6-4161-9219-2903BF8F547F) to compare names of students (it worked, but turned out to not be what I needed), but you may also be able to use some items "off the shelf" from Python's difflib. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Understanding help command description syntax - explanation needed
On 11/5/2014 7:41 AM, Chris Angelico wrote: On Wed, Nov 5, 2014 at 11:31 PM, Ivan Evstegneev webmailgro...@gmail.com wrote: That's what I'm talking about (asking actually), where do you know it from? I know it because I've been a programmer for 39 years. I didn't intend to offence anyone here. Just asked a questions ^_^ Don't worry about offending people. Even if you do annoy one or two, there'll be plenty of us who know to be patient :) And I don't think Larry was actually offended; it's just that some questions don't really have easy answers - imagine someone asking a great mathematician But how do you KNOW that 2 + 2 is 4? Where's it written down?... all he can say is It is. But it *can* be interesting to try and do otherwise. http://en.wikipedia.org/wiki/Principia_Mathematica -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: [OT] spelling colour / color was Re: Toggle
On 10/9/2014 3:53 PM, Tim Delaney wrote: That would be a theatre programme vs a computer program. I try to stick with the current spelling style when modifying existing code - esp. for APIs. It's very annoying to have some methods use z and others s in the same package. So since I'm currently working for a US company I have to consciously remind myself to use their abominations ;) Yes, we must not allow unmetred errour to paralyse communication. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Keepin constants, configuration values, etc. in Python - dedicated module or what?
On 9/30/2014 7:35 AM, c...@isbd.net wrote: Thus I'd have something like (apologies for any syntax errors):- cfg = { LeisureVolts: [AIN0, 0.061256, Leisure Battery Voltage], StarterVolts: [AIN1, 0.060943, Starter Battery Voltage], LeisureAmps1: [AIN2, 0.423122, Leisure Battery Current} (It might be better to makes those lists dictionaries, but it shows the idea) Using configparser.ConfigParser to read an ini-format seems like a good idea. I use it for my own numerous fixed format data file definitions, and it's been convenient and even extensible. [LeisureVolts] Description=Leisure Battery Voltage Code=AIN0 Value=0.061256 [StarterVolts] Description=Starter Battery Voltage Code=AIN1 Value=0.060943 [LeisureAmps1] Description=Leisure Battery Current Code=AIN2 Value=0.423122 I've set it up so I can understand abbreviations for the field names, for when I want to be lazy. Some of my values are dictionaries, which looks like this in my files (an alternate spelling of one of the above entries): LeisureVolts=desc:Leisure Battery Voltage code:AIN2 value:0.061256 It's simple to hook into ConfigParser to get whatever meaning you'd like, and whatever verification you'd find necessary. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python programming
On 8/27/2014 9:40 AM, Jake wrote: Jake I disagree! -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python vs C++
On 8/23/2014 9:00 AM, Chris Angelico wrote: On Sat, Aug 23, 2014 at 10:38 PM, Rustom Mody rustompm...@gmail.com wrote: Here is an example (not identical but analogous to) where markup+compile is distinctly weaker than wysiwyg: You can use lilypond to type music and the use a midi player to play it But lilypond does not allow playing and seeing-in-realtime WYSIWYG editors allow that -- can make a huge difference to beginners who find music hard to read. I don't buy that it's weaker. In fact, I'd say this proves that markup is distinctly better - just a little harder to do Hello, world in. At best, the simple GUI makes it easier to do something straight-forward, and then basically lets you drop to the more complicated form. At worst, it makes it easier to do the very simple, and nearly impossible to do the more complicated. The worst part of using a WYSIWIG program is the frustration of correcting a bewildering problem when some kind of autoformatting magic goes wrong. One odd example is when using Word to compose template documents meant for merging with external data. The markup+compile phase takes on a whole new, horrible meaning. My ears are turning red just imagining the next time I have to do it. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python vs C++
On 8/22/2014 5:29 AM, Marko Rauhamaa wrote: C is readily supported by all extension APIs. Its calling conventions are stable and well-understood. Its runtime requirements are trivial. Plus, you don't have to be a Medieval Scholar to program in it. C itself is very simple (albeit not simple to use). But I contend you do need to be a Medieval Scholar to compile and link it. My mind boggles watching a ./configure vomit ASCII all over my screen. I have to avert my eyes, make a wish, and make install. ;) -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Global indent
On 8/22/2014 2:19 PM, Seymore4Head wrote: Is there a way to indent everything again? Say I have a while statement with several lines of code and I want to add a while outside that. That means indenting everything. Is there a global way to do that? This sort of simple task is why fancy text editors were invented. I use and recommend gvim (press in select mode using the standard python plugin), but there are plenty of options out there. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Global indent
On 8/22/2014 3:54 PM, Rob Gaddi wrote: On Fri, 22 Aug 2014 15:46:33 -0400 Seymore4Head Seymore4Head@Hotmail.invalid wrote: On Fri, 22 Aug 2014 14:19:29 -0400, Seymore4Head Seymore4Head@Hotmail.invalid wrote: Is there a way to indent everything again? Say I have a while statement with several lines of code and I want to add a while outside that. That means indenting everything. Is there a global way to do that? Ok.so the answer is no using IDLE (Python GUI) The top two answers so far are Emacs and gvim. http://gvim.en.softonic.com/ Has a snazzy look, but I think it is not compatible with Windows so it looks like I might have to try Emacs. gvim runs just fine on Windows. http://www.vim.org/download.php Thanks everyone Emacs and vim both have huge learning curves that I've decided aren't worth climbing. Notepad++ is an excellent GUI text editor for Windows. Geany is nearly as good, and runs on anything. They do have a very long learning incline but it isn't actually as steep as it looks--it's just that it keeps going up as far as you can see. :) If simple things weren't simple to do, neither product would have ever succeeded. The GUI version of Vim (gvim), has beginner modes and Windows-like modes to help with the transitional phases. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python vs C++
On 8/21/2014 8:54 AM, David Palao wrote: Hello, I consider myself a python programmer, although C++ was one of the first languages I learned (not really deeply and long time ago). Hey, that sounds just like me. Now I decided to retake C++, to broaden my view of the business. However, as I progress in learning C++, I cannot take out of my head one question I have gone back and attempted to use C++ again a couple of times, but spoiler it turns out to not be worthwhile in my current position. Why to use C++ instead of python? It is not ranting against C++. I was/am looking for small-medium projects to exercise my C++ skills. But I'm interested in a genuine C++ project: some task where C++ is really THE language (and where python is actually a bad ab initio choice). The usual argument in favour of C++ (when comparing to python) is performance. But I'm convinced that, in general, the right approach is python-profiling-(extension/numpy/Cython/...). At least for a python programmer. I might be wrong, though. Python, for me, is the ultimate translator and aggregator of data. I use it constantly to get data from one place, combine it with some other data over there, fiddle with it, and spit it out in some usable manner. I could certainly use C++ for my projects. I think the standard containers, iterators, and algorithms provided in the STL are beautiful. Simple things can be relatively simple in C++, when I use the right parts of it. But in that case C++ doesn't provide me many benefits--virtually zero. Python's immutable strings and hash-based mapping type can even be faster than C++ in some cases. But I simply don't need efficiency. My longest running program takes less than 3 seconds to complete, and that's plenty fast for my purpose. The archaic separate compilation/linking model and the complication of static type declarations seem a pain in the ass that I don't benefit very much from. The one program I needed that was just horribly slow in Python involved trying to match up names in a fuzzy manner between two systems, to help me find students who couldn't be bothered to get their own social security number correct. This took nearly 20 minutes to run. But, ummm.., it turned out I was doing the wrong thing. Even students who can't remember their SSN mostly got their phone number or email address correct, it turns out. There's a tall stack of stuff *not* written in Python that I depend on, though: Python itself, sqlite3, gvim, Windows 7, etc. At this point I feel hopelessly unqualified to write any of that stuff, but if I had to, I'd need to resuscitate my C++, or at least my C, as a starting point. There's a growing number of projects hoping to bridge an apparent gap between Python and C. C++ can be regarded as an early effort--so early that there was no Python to measure against. Maybe it would've turned out better if there had been. ;) Python developers are filling part of the gap with libraries, e.g., numpy and scipy. I could take advantage of numpy by installing Pandas; I'll learn Pandas long before I resort to C++. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: how to get the ordinal number in list
On 8/10/2014 2:14 PM, Roy Smith wrote: In article 154cc342-7f85-4d16-b636-a1a953913...@googlegroups.com, Rustom Mody rustompm...@gmail.com wrote: l= [6,2,9,12,1,4] sorted(l,reverse=True)[:5] [12, 9, 6, 4, 2] No need to know how sorted works nor [:5] Now you (or Steven) can call it abstract. And yet its 1. Actual running code in the interpreter 2. Its as close as one can get to a literal translation of your Find the 5 largest numbers in a list [...] All the above are clearer than loops+assignments and can be taught before them I disagree. For a beginner, you want to be able to break things down into individual steps and examine the result at each point. If you do: l= [6,2,9,12,1,4] l2 = sorted(l,reverse=True) you have the advantage that you can stop after creating l2 and print it out. The student can see that it has indeed been sorted. With the chained operations, you have to build a mental image of an anonymous, temporary list, and then perform the slicing operation on that. Sure, it's the way you or I would write it in production code, but for a beginner, breaking it down into smaller pieces makes it easier to understand. l2[:5] Yes, and that teaching technique is supported by research. Beginners are particularly poor, in relation to experts, at noticing the applicability of idea, and at combining ideas together. Breaking things into component parts has multiple benefits: 1. The applicability of individual ideas becomes obvious. It's one thing to know about [].sort, and another thing to know when it's appropriate to sort something. 2. The expert specifically shows how and why the ideas are combined. This helps build the connection for the beginner, whose knowledge is not stored as an expert stores it; i.e, in broad categories with multiple connections; but as disorganized data with very few connections. http://www.amazon.com/How-Learning-Works-Research-Based-Principles/dp/0470484101 I bought the book based on a recommendation from SciPy talk, and it's really great. As an autodidact, it'll help me teach *myself* better, too. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: how to get the ordinal number in list
On 8/12/2014 2:20 PM, Rustom Mody wrote: On Tuesday, August 12, 2014 11:10:48 PM UTC+5:30, Neil D. Cerutti wrote: Beginners are particularly poor, in relation to experts, at noticing the applicability of idea, and at combining ideas together. Breaking things into component parts has multiple benefits: 1. The applicability of individual ideas becomes obvious. It's one thing to know about [].sort, and another thing to know when it's appropriate to sort something. 2. The expert specifically shows how and why the ideas are combined. This helps build the connection for the beginner, whose knowledge is not stored as an expert stores it; i.e, in broad categories with multiple connections; but as disorganized data with very few connections. Nice! And how do we lead the beginners towards expertise? In a way functional programming is to programming creativity what lego is to children's spatial creativity. Specifically there are a bunch of pieces that need to fit: 1. Functional Programming: Nothing more than composing functions [Maybe a bit simplistic but not unrealistic a defn] 2. Trying this out at the interpreter 3. Introspectable objects Functional programming could be particularly hard to teach since it is generally made up of numerous small units of work combined in a complex way. This is precisely the formula for something that beginners will find extremely challenging. When functional programming is dumbed down enough for a beginner to be able to grok it, the programming problems start to look really lame. It needn't be that way, of course, but it takes a good deal of creativity on the part of the instructor. If Factorial doesn't turn you on, you might be screwed. ;) Some things follow from this: For the lego-game of playing with functions at the REPL to work and be pleasant and rewarding: 1. functions should be non side-effecting; else same trials giving different answers adds more confusion than understanding 2. They should be non-printing else: def foo(x): return x+1 def bar(x): print x+1 look similar when trivially tried but compositionally are utterly different In effect a printing function breaks the lego bricks That may be so, but printing stuff to the screen is very natural to people. I've downloaded Haskell a few times, but the knowledge that getting input and writing output requires something mysterious called gonads just frightens me. [The P in the REPL is DRY enough that it does not usually need to be repeated all over] A good REPL does help a lot, though. 3. Abstractions (class instances) should be avoided in favor of concrete data (lists, dicts, scalars) because they add undue mess at little comprehension advantage. eg take the example of a regex match. It returns some object and then we have to scratch our heads wondering whats in the magic box. If instead of match, we use findall, the data is manifest and obvious. I'm with you on regex: match objects suck. That and escaping. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Specifying `blocking` and `timeout` when acquiring lock as a context manager
On 8/8/2014 9:25 AM, Ethan Furman wrote: On 08/08/2014 04:51 AM, cool-RR wrote: If I want to acquire a `threading.Lock` using the context manager protocol, is it possible to specify the `blocking` and `timeout` arguments that `acquire` would usually take? Not that I know of, but why would you want to? There's no built-in 'if' with a 'with' block -- how would your code know whether it ran or not? Perhaps defer release, a la a common Go pattern: with contextlib.ExitStack() as stack: acquired = lock.acquire(blocking=False) if acquired: stack.callback(lock.release) do_stuff -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Specifying `blocking` and `timeout` when acquiring lock as a context manager
On 8/8/2014 12:16 PM, Chris Angelico wrote: On Sat, Aug 9, 2014 at 2:05 AM, Neil D. Cerutti ne...@norwich.edu wrote: Perhaps defer release, a la a common Go pattern: with contextlib.ExitStack() as stack: acquired = lock.acquire(blocking=False) if acquired: stack.callback(lock.release) do_stuff There's a race condition in that - an unexpected exception could happen between those two. Are you able to set the callback to be a release if acquired atomic operation? Doesn't any natural looking use of blocking=False suffer from the same race condition? What's the correct way to use it? Here's another attempt at context managing: @contextlib.contextmanager def release_if_acquired(lock, blocking=True, timeout=-1): acquired = lock.acquire(blocking, timeout) if acquired: yield acquired lock.release() else: yield acquired with release_if_acquired(lock, blocking=False) as acquired: if acquired: do_stuff -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Specifying `blocking` and `timeout` when acquiring lock as a context manager
On 8/8/2014 2:35 PM, Neil D. Cerutti wrote: Here's another attempt at context managing: @contextlib.contextmanager def release_if_acquired(lock, blocking=True, timeout=-1): acquired = lock.acquire(blocking, timeout) if acquired: yield acquired lock.release() else: yield acquired I should not have used a temporary. @contextlib.contextmanager def release_if_acquired(lock, blocking=True, timeout=-1): if lock.acquire(blocking, timeout) yield True lock.release() else: yield False -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python Classes
On 8/4/2014 6:44 PM, John Gordon wrote: In mailman.12627.1407141661.18130.python-l...@python.org Shubham Tomar tomarshubha...@gmail.com writes: classes. I understand that you define classes to have re-usable methods and procedures, but, don't functions serve the same purpose. Can someone please explain the idea of classes If a function simply accepts some data, does some calculations on that data and then returns a value, then you don't need classes at all. An example of this might be the square-root function: pass it any number and it calculates and returns the square root with no other data needed. But classes do come in handy for other sorts of uses. One classic example is employees at a company. Each employee has a name, ID number, salary, date of hire, home address, etc. You can create an Employee class to store those data items along with methods to manipulate those data items in interesting ways. The data items are specific to each separate Employee object, and the methods are shared among the entire class. In simple cases like that, functions could do very well by including a little bundle of data (probably a dict) as one of the parameters for each related function. Classes help here by organizing the functions into namespaces, and allowing very convenient and explicit syntax for creating objects and using attributes. In addition, classes provide hooks into almost all of Python's syntax and operations, with special methods like __init__, __add__, etc. If you want your employees to be comparable using the , , == you need to use classes. Classes provide a means for objects to be related, substitutable, and interdependent, using inheritance. Properties work only with classes and provide a convenient way to customize attribute retrieval and setting without forcing a change in the syntax required for usage. Classes can be constructed dynamically using metaclasses. Some of these things can be emulated using just functions and mappings--it's what C programmers do--but most of classes in Python can do requires language support. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: one to many (passing variables)
On 7/25/2014 9:47 PM, C.D. Reimer wrote: Thank you for the link. I'm curious about one item mentioned in the article: Avoid return values that Demand Exceptional Processing: return zero-length array or empty collection, not null Isn't a zero-length array, empty collection and null all the same thing? Or does the Demand Exceptional Processing comes from testing to see if the object is empty versus being null? This seems like a specific application of a more general rule (I think I remember it from The C Programming Language by Kernighan and Ritchie): Whenever possible, manage special cases with data rather than with code. Doing so makes your data processing code simpler, and may help prevent errors. This should apply to any programming language. A mundane example is managing multi-line street addresses in a system storing addresses: most applications choose to store address lines as Street Address 1, through Street Address N, for some finite value of N, even though it results in special cases to handle. This is probably because it is more efficient: non-normalised data can be an efficiency win. Also, forgetting or refusing to handle the case of multi-line street addresses works well enough most of the time. You could instead store multi-line street addresses as a list of components in the street address: Forgetting to handle the special cases would then be impossible. In order to do a cheesy job you'd have to explicitly retrieve street_address[0] and ignore the rest. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: OT: usenet reader software
On 7/22/2014 11:14 AM, Anssi Saari wrote: I don't really know about about html and slrn since I don't see much of it but links in a terminal application is usually something for the terminal to handle. I run Gnus on a remote machine and use a local terminal for display, Konsole in Linux and mintty in Windows. In both of those terminals URLs are opened with a right click on the link and selecting open link from the menu that pops up. That is correct and the way slrn works. You set browser and/or guibrowser options in .slrnrc. With those set, SHIFT-G will troll an open message for web addresses, and you use up and down arrow to select the link you want from the generated list. Then it launches the browser you configured. Getting the escaping, path, and syntax of the browser setting correct was a pain, but after that it worked great. That said, I got tired of the inability to display most special characters correctly (slrn could only do as well the cmd.exe), and have switched to Thunderbird. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3 is killing Python
On 7/16/2014 10:27 AM, Frank Millman wrote: Would this have been so easy using Python2 - I don't think so. What follows is blatant speculation, but it is quite possible that there are many non-English speakers out there that have had their lives made much easier by the changes to Python3 - a 'silent majority'? I don't mean an absolute majority, as I believe there are still more Python2 users than Python3. But of those who have made the switch from 2 to 3, maybe most of them are quite happy. If so, then the python devs got that right as well. Python3 has helped me cope with unexpected non-ASCII characters in other systems on our university campus while using a program written back before I knew anything about unicode. When I first spotted mojibake appearing in a student's name and address, it was only a couple of emails and a little investigation to determine which encoding= bits to sprinkle into my program. And I was finished. I wrote these applications a decade ago in Python2, and never worried about unicode. I translated them to Python3 years ago, and still never worried about unicode. The database is supposed to be sanitized against non-ASCII by an address and name-scrubbing application, which we aspend large amounts of cash on (I don't understand why, but that's what we do). And thanks to Python3, even though illegal characters have crept in, and even though I had never worried about unicode before, I could fix my program(s) the instant I knew which encodings to use. It would have been much harder to get right using Python2. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: Standard library Help
On 7/11/2014 4:53 AM, Wolfgang Maier wrote: On 07/11/2014 10:32 AM, Nicholas Cannon wrote: Hey i would like to know alot more about the standard library and all of its functions and so on and i know it is huge and i would basically like to learn only the useful stuff that i could use and all of those features. i have been looking around and i cant really find anything so i wondering if you guys would know any places to learn it. Consult the documentation: https://docs.python.org/3/library/index.html It's probably the only place that has everything documented. Instead of reading everything from A-Z though, the more typical approach is to skim through it to know what is available, then read in-depth the parts that seem useful for a concrete problem you're trying to solve currently. In my experience, a thorough understanding of most chapters doesn't come with reading alone, but with practice. I recommend reading and becoming familiar with the first five sections first. You won't get far without the Built-in types and functions. list, dict, set, open, etc., are not in a library, per se, as other languages usually define it, but that's where they're described in Python's docs. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: open() and EOFError
On 7/7/2014 7:10 PM, Mark Lawrence wrote: On 07/07/2014 23:09, Gregory Ewing wrote: Marko Rauhamaa wrote: with open(path) as f: ... If the open() call is guarded against exceptions (as it usually should), one must revert to the classic syntax: Hmmm, maybe we could do with a with-except statement: with open(path) as f: ... except IOError: # Catches exceptions in the with-expression only ... Although that would be a bit confusing. I wrap the with inside a try/except, the other file handling parts within another try/except and use the finer grained exceptions from PEP 3151 to write (at least to my eye) cleaner looking code. Somehow I think we'll get agreement on the best way to do this when the cows come home. On Windows it's my experience that EOF from interactive sessions is ignored. Programs keep going as best they can, providing some other means of exit, e.g., an 'exit' command. But maybe that's just the shell. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: The “does Python have variables?” debate
On 5/8/2014 8:41 AM, Roy Smith wrote: In article mailman.9742.1399477705.18130.python-l...@python.org, Jerry Hill malaclyp...@gmail.com wrote: thinking of python variables as having two parts -- names and values -- really can help people who are struggling to learn the language. There's many levels of learning, and we see them all on this list. For people who are just learning programming, and are learning Python as their first language, we need to keep things simple. These are the people who are still struggling to understand basic concepts such as algorithms, loops, and the most fundamental data structures. For those people, talking about variables as a container to hold a value is the right level of abstraction. At some point, that model no longer fits reality well enough that it becomes a barrier to further learning. When I write: def mutate(x, y): x = 42 y[0] = 42 x = 4 y = [4] mutate(x, y) print x, y and run it, unless I really understand about name binding and argument passing, I'm going to be totally befuddled by the result. At that point, I need to unlearn something I thought I understood, and that's really hard (en.wikipedia.org/wiki/Principles_of_learning#Primacy). The surprising things can be demonstrated without using functions. Once assignment statements are mastered, the way argument passing works can be extrapolated. New programmers will have to further be taught about shadowing and scopes, while experienced programmers should already be up and running (until they try to get cute). Of course everybody has to eventually learn about the special syntax usable in function definitions and function calls. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: threading
On 4/8/2014 9:09 PM, Rick Johnson wrote: I warn you that not only will it impede the interpretation of your ideas, it will also degrade your ability to think clearly when expressing yourself and slow (or completely halt) your linguistic evolution. HAVE YOU NOTICED THAT YOUR INNER MONOLOGUE NEVER USES IT? Indeed! That's because it is a habitual viral infestation of the human communication interface. It strikes me that that's not superior to it. It's ironic that that would be used in place of it in your rant. Plus Rufus Xavier Sasparilla disagrees with it. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list