From urnerk at qwest.net Fri Sep 2 04:28:29 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 1 Sep 2005 19:28:29 -0700 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <6.2.3.4.0.20050830235909.03e9f758@127.0.0.1> Message-ID: <20050902022839.C04611E4003@bag.python.org> Hi Peter -- I do question the choice of Word, given its platform specificity (not talking about operating system: you need a heavy duty word processor to open it -- even OpenOffice is a chore). To me, a course manual for programmers should be in a medium they'll appreciate in future. Probably HTML, although the XML you mention (DocBook) is good. I use sometimes. From one XML master document, you may output HTML, PDF or several other un/friendly formats. I do think the day is passed when the teacher could win popularity points for doing man pages -- and anyway, they're not really meant as a vehicle for course materials. There's a cgi utility that I use, some of it by Guido's brother, which colorizes Python using HTML tags. You can run it locally to automatically colorize your code. Then, if you're using HTML or XML as your base (you could use Word to get the HTML, but I don't find its WYSIWYG solution attractive -- too busy on the HTML side) you can just paste in the cgi scripts output. To see the script in action, and to get a link to its home (bottom of the rendered output), check some page of mine with a link to colorized source code, e.g. http://www.4dsolutions.net/ocn/hypertoons.html Kirby PS: speaking of hypertoons, there's some silliness in rbf.py (one of the dependencies) that I've needed to fix, but nothing that affects functionality -- just some kinda dumb code. > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Peter Bowyer > Sent: Wednesday, August 31, 2005 2:53 AM > To: edu-sig at python.org > Subject: [Edu-sig] Writing books/manuals containing code > > Hi, > > I have just started writing a course manual to introduce students to > programming. There are going to be lots of code examples, and I was > wondering: is there a way to insert the code into the document from > external files, so I can test all the files and make sure the code > works, even if I edit it? In Microsoft Word I can embed a file as an > object, but the file's contents does not show in the document. > > My example programs are then broken down and I go through it > line-by-line. Again, is there any way to insert these single lines > of code without copying and pasting from the main block? > > I'm using Microsoft Word 2000, which is also making referencing code > hard. I am open to suggestions of other programs, alhtough I'd > prefer not to have to learn and write Docbook/LaTeX by hand. > > Finally, is there a way to syntax highlight python code before > putting it into MS Word? > > Thanks, > Peter > > -- > Maple Design - quality web design and programming > http://www.mapledesign.co.uk > > _______________________________________________ > Edu-sig mailing list > Edu-sig at python.org > http://mail.python.org/mailman/listinfo/edu-sig From delza at livingcode.org Fri Sep 2 05:38:30 2005 From: delza at livingcode.org (Dethe Elza) Date: Thu, 1 Sep 2005 20:38:30 -0700 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <20050902022839.C04611E4003@bag.python.org> References: <20050902022839.C04611E4003@bag.python.org> Message-ID: <8ED5BBA5-8B16-4F8B-AB4A-7028B2106767@livingcode.org> On 1-Sep-05, at 7:28 PM, Kirby Urner wrote: > Hi Peter -- > > I do question the choice of Word, given its platform specificity (not > talking about operating system: you need a heavy duty word > processor to > open it -- even OpenOffice is a chore). To me, a course manual for > programmers should be in a medium they'll appreciate in future. > Probably > HTML, although the XML you mention (DocBook) is good. I use > sometimes. From one XML master document, you may output HTML, PDF or > several other un/friendly formats. I do think the day is passed > when the > teacher could win popularity points for doing man pages -- and anyway, > they're not really meant as a vehicle for course materials. And sometimes even XML is too heavy--in which case you can use reStructured Text[1] (or reST, part of the Python Docutils project). Using reST is kind of like wiki markup, but it can be transformed into DocBook, reST XML, XHTML, PDF, etc. Much more readable and editor-friendly than XML. If you are on OS X there is even a reST- specific editor[2] which transforms to XHTML as you go, for WYSIWYG- ish goodness. [1] http://docutils.sourceforge.net/docs/index.html [2] http://python.net/~gherman/ReSTedit.html --Dethe "Well I've wrestled with reality for thirty-five years now, doctor, and I'm happy to state I've finally won out over it." -- Elwood P. Dowd, Harvey From ajsiegel at optonline.net Fri Sep 2 14:20:33 2005 From: ajsiegel at optonline.net (Arthur) Date: Fri, 02 Sep 2005 08:20:33 -0400 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <8ED5BBA5-8B16-4F8B-AB4A-7028B2106767@livingcode.org> Message-ID: <0IM6003VOVMLXSZ2@mta1.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Dethe Elza > And sometimes even XML is too heavy--in which case you can use > reStructured Text[1] (or reST, part of the Python Docutils project). > Using reST is kind of like wiki markup, but it can be transformed > into DocBook, reST XML, XHTML, PDF, etc. Much more readable and > editor-friendly than XML. Again, just offering my own experience - I found learning to work with reST well worth the investment. It's a strange beast in a way - you write pretty naturally, but as if you were using a very primitive text editor with few "modern" capabilities - and by so doing you are connected, as mentioned above, with the state of the art capabilities of XHTML ,XML, PDF, etc. >If you are on OS X there is even a reST- > specific editor[2] which transforms to XHTML as you go, for WYSIWYG- > ish goodness. Frustrating that it's OS X specific, as I don't have easy access to it. Would be anguish to give it a whirl. Art From villate at gnu.org Fri Sep 2 18:04:34 2005 From: villate at gnu.org (Jaime E. Villate) Date: Fri, 2 Sep 2005 17:04:34 +0100 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: References: <6.2.3.4.0.20050830235909.03e9f758@127.0.0.1> Message-ID: <20050902160434.GA29060@fe.up.pt> On Wed, Aug 31, 2005 at 12:43:03PM +0200, Nicola Larosa wrote: > > You want Docutils ( http://docutils.sourceforge.net/ ), with ReStructured > Text markup, much simpler than those alternative. You might also want to try my python script: http://villate.org/wikiup/ Look at the example: http://villate.org/wikiup/examples/example.html and the result: http://villate.org/wikiup/examples/example1.html In the near future it will produce Latex and Docbook output, which is something that I have already implemented in its predecessor, before I switched into Python: http://villate.org/parsewiki/ (debian> apt-get install parsewiki) Cheers, Jaime From missive at hotmail.com Sat Sep 3 16:17:30 2005 From: missive at hotmail.com (Lee Harr) Date: Sat, 03 Sep 2005 18:47:30 +0430 Subject: [Edu-sig] Writing books/manuals containing code Message-ID: >I have just started writing a course manual to introduce students to >programming. There are going to be lots of code examples, and I was >wondering: is there a way to insert the code into the document from >external files, so I can test all the files and make sure the code >works, even if I edit it? You might want to look at Bruce Eckel's Thinking in Python. http://www.mindview.net/Books/TIPython I remember that being able to test all of the code examples was an important consideration in the system he set up for the book. _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ From peter at mapledesign.co.uk Sat Sep 3 20:32:50 2005 From: peter at mapledesign.co.uk (Peter Bowyer) Date: Sat, 03 Sep 2005 19:32:50 +0100 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <8ED5BBA5-8B16-4F8B-AB4A-7028B2106767@livingcode.org> References: <20050902022839.C04611E4003@bag.python.org> <8ED5BBA5-8B16-4F8B-AB4A-7028B2106767@livingcode.org> Message-ID: <6.2.3.4.0.20050902231502.0255f1a8@127.0.0.1> At 04:38 02/09/2005, Dethe Elza wrote: >If you are on OS X there is even a reST- specific editor[2] which >transforms to XHTML as you go, for WYSIWYG- ish goodness. A bit of searching found one for all platforms available: DocFactory - http://docutils.sourceforge.net/sandbox/gschwant/docfactory/doc/ I'm not convinced about reST from the examples I've seen, but I will certainly play with it. I think it's one of those things you have to *get* before it makes sense (and Leo even more so). It seems counter-intuitive to drop back to plain text with syntax. One question I do have about it, is can you extend the syntax with your own modifiers etc? Does anyone know how publishers such as O'Reilly have their books written? When I read the Pragmatic Programmer's guide to Ruby I noted at the front they say the code results in their book are actual output - the code is executed every time the book was generated. Is anyone familiar with the systems for doing this? For the number of books and manuals being written I've found very little in the way of guides on different set-ups people use. Peter -- Maple Design - quality web design and programming http://www.mapledesign.co.uk From jmillr at umich.edu Mon Sep 5 00:13:38 2005 From: jmillr at umich.edu (John Miller) Date: Sun, 4 Sep 2005 18:13:38 -0400 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: References: Message-ID: <99AB100E-F573-43E3-8B99-94885EA47865@umich.edu> Just recently the editor of About This Particular Mac, Michael Tsai, wrote about this topic (although for a magazine rather than a book) from an historical perspective. The gist is that now he is using ReST: http://www.atpm.com/11.07/publishersletter.shtml """ The core of our new publishing system is Docutils, a text processing system designed for use with the Python programming language. I now format ATPM articles in reStructuredText format, a plaintext markup language that?s similar to Setext and Markdown. Docutils includes a parser, which reads reStructuredText files into an internal representation. Then, a writer translates the internal representation into an output format such as HTML. The beauty of the Docutils system is that both sides of this process are extensible. reStructuredText doesn?t have support for the blue ATPM article headers, but I was able to teach it about them by extending the parser. Similarly, Docutils doesn?t have writers that generate ATPM- style HTML or PDFs, but it lets you plug in writers of your own. As a programmer, it was simple for me to make these and other extensions, and Docutils? good design meant that I didn?t have to re-invent the wheel to do so. """ John Miller Peter Bowyer wrote: > I'm not convinced about reST from the examples I've seen, but I will > certainly play with it. I think it's one of those things you have to > *get* before it makes sense (and Leo even more so). It seems > counter-intuitive to drop back to plain text with syntax. One > question I do have about it, is can you extend the syntax with your > own modifiers etc? From schliep at molgen.mpg.de Mon Sep 5 13:10:06 2005 From: schliep at molgen.mpg.de (Alexander Schliep) Date: Mon, 5 Sep 2005 13:10:06 +0200 (MET DST) Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: References: Message-ID: Hi everyone, LaTeX is (rightfully so, IMHO) the standard for scientific publishing, in particular for books if there is any math context. To automate the production of PDFs with up-to-date code examples, sample outputs and figures (that is sometimes more difficult) you can use make. Appropriate rules create output such that myscript.py produces myscript.out whenever myscript.py is changed. Both code and output can be incorporated and pretty-printed using the listings package; the only bummer is that you have to reference line numbers. It would be nice if you could reference particular pieces more easily; Knuth's original programming tools seemed not that much more helpful for the lots of theory and small sample programs and their output type publications. I use pyexpect to capture the output of an interactive session given some commands a user would type in a file. I just stumbled over http://starship.python.net/crew/bhoel/PyLaTeX-0.2/README.html which is another way to have Python code in LaTeX. Best, Alexander -- Alexander Schliep schliep at molgen.mpg.de From H.FANGOHR at soton.ac.uk Tue Sep 6 04:18:31 2005 From: H.FANGOHR at soton.ac.uk (Hans Fangohr) Date: Tue, 6 Sep 2005 03:18:31 +0100 (BST) Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <6.2.3.4.0.20050830235909.03e9f758@127.0.0.1> References: <6.2.3.4.0.20050830235909.03e9f758@127.0.0.1> Message-ID: Hi Peter, > I have just started writing a course manual to introduce students to > programming. There are going to be lots of code examples, and I was > wondering: is there a way to insert the code into the document from > external files, so I can test all the files and make sure the code > works, even if I edit it? In Microsoft Word I can embed a file as an > object, but the file's contents does not show in the document. > > My example programs are then broken down and I go through it > line-by-line. Again, is there any way to insert these single lines > of code without copying and pasting from the main block? > > I'm using Microsoft Word 2000, which is also making referencing code > hard. I am open to suggestions of other programs, although I'd > prefer not to have to learn and write Docbook/LaTeX by hand. > > Finally, is there a way to syntax highlight python code before > putting it into MS Word? I'll have to agree with some of the previous emails that Word (whatever version) is a questionable choice. I also think you should look into LaTeX: it is just another programming language where the source code is 'compiled' into graphical output (usually so called dvi-files) which is easily converted into postscript or pdf. You can also create html from latex using latex2html (although this sometimes needs manual fine tuning). Note also that latex is very similar to html in that you have tags defining how things should look like (I write this in case you know html). Finally, even if you use Word in the end, knowing latex will show you how to typeset well. To answer some of your questions: I often use LaTeX for lecture notes etc and use the 'listings' extension to include source code (http://www.ctan.org/tex-archive/macros/latex/contrib/listings/). It supports syntax highlighting of more than 20 languages, including Python (although I don't think it does different colours such as IDLE but just highlights keywords in a style of your choice). It allows you to read a piece of source code from a file into your document; this is great to make sure you don't get your main document out-of-date when you change the code. You can also ask it number the lines for you (so you can discuss the code more easily). You can also ask it to only print lines 10 to 20 or so which might help you in what you are asking for above. In particular, if you need equations, it is unlikely you can get around LaTeX. Most people (certainly on this list, I think) will agree that equations written in LaTeX look best. I hope this is useful, Hans From delza at livingcode.org Tue Sep 6 07:15:55 2005 From: delza at livingcode.org (Dethe Elza) Date: Mon, 5 Sep 2005 22:15:55 -0700 Subject: [Edu-sig] Writing books/manuals containing code Message-ID: (sorry, forgot to reply to list with this earlier) On 3-Sep-05, at 11:32 AM, Peter Bowyer wrote: > I'm not convinced about reST from the examples I've seen, but I > will certainly play with it. I think it's one of those things you > have to *get* before it makes sense (and Leo even more so). It > seems counter-intuitive to drop back to plain text with syntax. > One question I do have about it, is can you extend the syntax with > your own modifiers etc? > There are a couple of other "lightweight markup" formats around. Two are more data focussed: JSON (Javascript object notation, which also works fine in Python, Perl, Java, etc.) and YAML (YAML Ain't Markup Language, which is kind of JSON++). Others are simpler markups than reST used mainly for weblog posting: Markdown [3] and Textpattern [4] are two that I know of. There are also lightweight text markups for more specialized purposes, such as RelaxNG's compact syntax[5] for defining XML dialects, and ABC[6] for music notation (and there is a project in the docutils sandbox for adding ABC to reST). Finally, to answer your question, you can extend reST in several ways. One of the simplest may be to use interpreted roles[7]. It is not terribly difficult to add new directives to reST[8], and I wrote a tutorial[9] for doing it. You can easily customize the stylesheet (s) used by reST if you are converting reST to (X)HTML. If you need to convert reST to a format that it doesn't already have a writer for, you can create a new writer, and there are examples to work from for writing PDF, XHTML, XHTML snippets, slides, LaTeX, and other formats. What kind of customizations do you need? > Does anyone know how publishers such as O'Reilly have their books > written? When I read the Pragmatic Programmer's guide to Ruby I > noted at the front they say the code results in their book are > actual output - the code is executed every time the book was > generated. Is anyone familiar with the systems for doing this? > Judging by the colophons of O'Reilly books over the years, they use a lot of different sytems for writing their books, depending on what the author is comfortable with, as far as I can tell. You can see their "Writing for O'Reilly"[10] section for more details. IBM's developerWorks has their own XML format[11] they require. David Mertz has written his own simple text markup (Smart ASCII) and a python tool[12] for converting it to developerWorks markup. Some publishers prefer plain (unmarked-up) text, many request (or require) Word documents. It depends a lot on the market, the publisher, etc. [1] http://www.crockford.com/JSON/index.html [2] http://www.yaml.org/ [3] http://daringfireball.net/projects/markdown/ [4] http://textpattern.com/weblog/11/textpattern-4-stable-released [5] http://www.xml.com/pub/a/2002/06/19/rng-compact.html [6] http://staffweb.cms.gre.ac.uk/~c.walshaw/abc/ [7] http://docutils.sourceforge.net/docs/ref/rst/roles.html [8] http://docutils.sourceforge.net/docs/ref/rst/directives.html [9] http://docutils.sourceforge.net/docs/howto/rst-directives.html [10] http://www.oreilly.com/oreilly/author/intro.html [11] http://www-128.ibm.com/developerworks/library-combined/i-dwauthors/ [12] http://www-128.ibm.com/developerworks/xml/library/x-tipt2dw.html HTH --Dethe "And you think you're so clever and classless and free" ? John Lennon on prototype-based programming From delza at livingcode.org Tue Sep 6 18:59:31 2005 From: delza at livingcode.org (Dethe Elza) Date: Tue, 6 Sep 2005 09:59:31 -0700 Subject: [Edu-sig] Writing books/manuals containing code In-Reply-To: <6.2.3.4.0.20050906085010.03ad9910@127.0.0.1> References: <20050902022839.C04611E4003@bag.python.org> <8ED5BBA5-8B16-4F8B-AB4A-7028B2106767@livingcode.org> <6.2.3.4.0.20050902231502.0255f1a8@127.0.0.1> <6.2.3.4.0.20050906085010.03ad9910@127.0.0.1> Message-ID: <949DB8A0-562E-48D1-89B6-B4955B17A94D@livingcode.org> (Sending this to the list because it might be useful to others as well) On 6-Sep-05, at 7:37 AM, Peter Bowyer wrote: > Hello Dethe, > > Thanks for your excellent information (which I see you've now sent > to the list as well). I'm nearly convinced by reST now, it's a > really nice way to write and I know I can 'bail out' into Docbook/ > LaTeX at any stage using the converters. There's some bits of reST > that feel odd (*italics* and **bold**, vs _italics_ and *bold*) but > that's because I've been using Textile before. The more I use reST > the smarter it feels. You're welcome. I think the *italics* and **bold** come from old email conventions (of which there were many %-) and from the fact that HTML phasis then maps to one asterisk, while emphasis maps to two. And that leaves the underline for other purposes--it has many roles in reST. > At 05:10 04/09/2005, you wrote: > >> Finally, to answer your question, you can extend reST in several >> ways. >> [...] >> What kind of customizations do you need? >> > > Well I was thinking along the lines of suppose I want a section to > be collapsing/expanding in the HTML output (using Javascript), but > as a fixed box in the PDF. Some sections I want to tag as advanced > material (which will be shown online with a blue background in > collapsing boxes, and may be missed out of the printed version), > others as important or asides (red and green backgrounds > respectively). I am guessing this will have to go into the > structure of the document. > > Another may be a converter to the tbook format, but probably not - > I'll go direct to LaTeX and HTML. For making a section in HTML collapse and expand, you can do that pretty easily with CSS classes, simply by switching the class name (one class for expanded, one for collapsed). Bob Ippolito's MochaKit [1] gives some nice Javascript tools for manipulating class names (since a given element may have more than one class) as well as many other useful Javascript methods (making JS mare like Python in some important ways). Depending on what elements you want to expand/ collapse, you may be able to walk the DOM in the onload event and add the appropriate classes, or you may want to tweak the output of the HTML writer in docutils itself. In any case, attaching the javascript should be fairly trivial. Docutils already has a variety of Admonitions (Attention, Caution, Danger, Error, Hint, Important, Note, Tip, Warning) and you can make up your own Admonitions, so that might be the way to create the boxes you want. Admonitions can be styled differently in different outputs (blue, collapsing in HTML, discarded in PDF, for instance). The implementation (for HTML) puts the admonition of your choice as the class name. >> Judging by the colophons of O'Reilly books over the years, they use a >> lot of different sytems for writing their books, depending on what >> the author is comfortable with, as far as I can tell. > > The Pragmatic Programmers summarise their original system at http:// > blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Random/DocPrep.rdoc, > which seems pretty similar. I like their way of tagging blocks of > code with surrounding comments and inserting those chunks into the > document - something which shouldn't be hard to implement with a > preprocessor. Docutils is intended to be able to extract documentation from the docstrings of Python code, but I'm not sure if that Reader is fully implemented yet. Alternatively, you can include external code into a reST document using directives. > Whichever route I take is going to have to end up with LaTeX for > the final output to render the equations. Have you used reST's > equation handling? Not really. And I found it's table, while nice to read in text format, painful to create. I ended up writing a simple script to massage an even simpler format into reST tables in that case. > Thinking ahead to when I write the final report: what is > bibliography handling like in reST? I've come across http:// > www.pricklysoft.org/software/bibstuff.html which can link reST to > bibtex, is this as good as it gets? Not sure, this is something you should probably ask on the docutils mailing list[2]. They're quite friendly. > The other thing I'm looking for as I write a sample document in > reST: is there some way to mark up text so that HTML's or > tags are used? I'm thinking maybe in conjunction with a > glossary (definition list) but from the documentation I cannot see > how this could be linked in. I don't see anything like this in a cursory look of the site and a quick google, but it's something so useful that it has almost certainly been discussed on the mailing list at some point. I did discover while looking that automatic numbering of lists has finally been implemented (in the svn version, not yet in the released version) and that they have a table format which may be like what I implemented with an external script awhile back (I haven't really been keeping up with docutils for the past year or so). Again, a quick question on the mailing list may get you what you need. Development appears to still be quite active, so if there is not a way to specify there could be one soon. > I think the one question I do have about reST is how sophisticated > are its converters? As far as I can tell, the Docbook one is under > development while the LaTeX converter is pretty much complete? They vary widely. Once they are reasonably complete they migrate to the docutils core. While still rough works in progress they tend to live in the sandbox. > Thanks so much for your help, > Peter My pleasure. Best wishes with the writing. --Dethe [1] http://www.mochikit.com/doc/html/MochiKit/index.html [2] http://sourceforge.net/mailarchive/forum.php?forum_id=11444 A good engineer is a person who makes a design that works with as few original ideas as possible. --Freeman Dyson From urnerk at qwest.net Wed Sep 7 00:31:36 2005 From: urnerk at qwest.net (Kirby Urner) Date: Tue, 6 Sep 2005 15:31:36 -0700 Subject: [Edu-sig] Python Quiz Message-ID: <20050906223138.DE3861E4002@bag.python.org> class Shell: def __init__(ghost): pass def __repr__(ghost): return 'What famous Japanese cartoon?' OK that was easy. So how about: class Shell (object): def __init__(ghost): pass def __repr__(ghost): return 'What famous Japanimation?' Hint: think "new-style class." Kirby From urnerk at qwest.net Wed Sep 7 17:17:49 2005 From: urnerk at qwest.net (Kirby Urner) Date: Wed, 7 Sep 2005 08:17:49 -0700 Subject: [Edu-sig] Link to RUR-PLE added Message-ID: <20050907151752.980241E4002@bag.python.org> Finally got a couple updates to: http://www.python.org/sigs/edu-sig/ i.e. Andr?'s RUR-PLE and Ipython. Not an easy process, as pydotorg is undergoing changes and some of the web based instructions on how to update pages is obsolete. Under the current (changing) setup, A.M. Kuchling had to do the final push to the old server, as I the old ssh-based update method is no longer accessible to me. Soon, making changes will be easy again. I believe I've got the svn process down. Kirby From cpif at handysoftware.com Wed Sep 7 20:35:50 2005 From: cpif at handysoftware.com (David Handy) Date: Wed, 7 Sep 2005 14:35:50 -0400 Subject: [Edu-sig] Python Quiz In-Reply-To: <20050906223138.DE3861E4002@bag.python.org> References: <20050906223138.DE3861E4002@bag.python.org> Message-ID: <20050907183550.GC1107@arno2> On Tue, Sep 06, 2005 at 03:31:36PM -0700, Kirby Urner wrote: > > class Shell: > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanese cartoon?' > > OK that was easy. So how about: > > class Shell (object): > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanimation?' > > Hint: think "new-style class." > > Kirby I don't get it. You have two classes, both with a repr implementation, and the second one happens to be a new-style class as indicated by its being derived from "object". Was there more to it than that? Just in case, I copied and pasted your new-style class definition into kirby-ghost.py and tried it out with Python 2.3 on my machine, just to see if there was some gotcha that I had overlooked. It works just fine for me: [david at ujae stuff]$ python -i kirby-ghost.py >>> dir() ['Shell', '__builtins__', '__doc__', '__file__', '__name__'] >>> s = Shell() >>> s What famous Japanimation? Loving-Python-Quizzes-but-being-puzzled-by-this-one'ly-yours, David H From delza at livingcode.org Wed Sep 7 20:50:44 2005 From: delza at livingcode.org (Dethe Elza) Date: Wed, 7 Sep 2005 11:50:44 -0700 Subject: [Edu-sig] Python Quiz In-Reply-To: <20050907183550.GC1107@arno2> References: <20050906223138.DE3861E4002@bag.python.org> <20050907183550.GC1107@arno2> Message-ID: <3DEA6D74-F5EB-4B16-B410-F5F407EAB4AB@livingcode.org> I thought this was an obscure joke on "Ghost in the Machine," but I didn't get it either. --Dethe On 7-Sep-05, at 11:35 AM, David Handy wrote: > On Tue, Sep 06, 2005 at 03:31:36PM -0700, Kirby Urner wrote: > >> >> class Shell: >> >> def __init__(ghost): >> pass >> >> def __repr__(ghost): >> return 'What famous Japanese cartoon?' >> >> OK that was easy. So how about: >> >> class Shell (object): >> >> def __init__(ghost): >> pass >> >> def __repr__(ghost): >> return 'What famous Japanimation?' >> >> Hint: think "new-style class." >> >> Kirby >> > > I don't get it. You have two classes, both with a repr > implementation, and > the second one happens to be a new-style class as indicated by its > being > derived from "object". Was there more to it than that? > > Just in case, I copied and pasted your new-style class definition into > kirby-ghost.py and tried it out with Python 2.3 on my machine, just > to see > if there was some gotcha that I had overlooked. It works just fine > for me: > > [david at ujae stuff]$ python -i kirby-ghost.py > >>>> dir() >>>> > ['Shell', '__builtins__', '__doc__', '__file__', '__name__'] > >>>> s = Shell() >>>> s >>>> > What famous Japanimation? > > Loving-Python-Quizzes-but-being-puzzled-by-this-one'ly-yours, > David H > _______________________________________________ > Edu-sig mailing list > Edu-sig at python.org > http://mail.python.org/mailman/listinfo/edu-sig > What dark passions and ancient evils have been held in check by the grim totalitarianism of the profit motive? --Bruce Sterling From dooms at info.ucl.ac.be Wed Sep 7 21:13:16 2005 From: dooms at info.ucl.ac.be (=?ISO-8859-1?Q?Gr=E9goire_Dooms?=) Date: Wed, 07 Sep 2005 21:13:16 +0200 Subject: [Edu-sig] Python Quiz In-Reply-To: <20050906223138.DE3861E4002@bag.python.org> References: <20050906223138.DE3861E4002@bag.python.org> Message-ID: <431F3BCC.70206@info.ucl.ac.be> Kirby Urner wrote: >class Shell: > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanese cartoon?' > >OK that was easy. So how about: > >class Shell (object): > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanimation?' > >Hint: think "new-style class." > > > Is it that new-style classes are to old-style classes what animation is to old-style cartoons ? -- Gr?goire PS: this mailing list is really deviating from "Python in/for education". From urnerk at qwest.net Thu Sep 8 01:35:24 2005 From: urnerk at qwest.net (Kirby Urner) Date: Wed, 7 Sep 2005 16:35:24 -0700 Subject: [Edu-sig] Python Quiz In-Reply-To: <20050906223138.DE3861E4002@bag.python.org> Message-ID: <20050907233527.2DD5D1E4002@bag.python.org> Answers: Ghost in the Shell: http://www.imdb.com/title/tt0113568/ Ghost in the Shell 2: Innocence http://www.imdb.com/title/tt0347246/ (new-style as in sequel, next generation, or freshmeat) Kirby > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Kirby Urner > Sent: Tuesday, September 06, 2005 3:32 PM > To: edu-sig at python.org > Subject: [Edu-sig] Python Quiz > > > class Shell: > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanese cartoon?' > > OK that was easy. So how about: > > class Shell (object): > > def __init__(ghost): > pass > > def __repr__(ghost): > return 'What famous Japanimation?' > > Hint: think "new-style class." > > Kirby > > > > _______________________________________________ > Edu-sig mailing list > Edu-sig at python.org > http://mail.python.org/mailman/listinfo/edu-sig From urnerk at qwest.net Thu Sep 8 19:42:34 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 8 Sep 2005 10:42:34 -0700 Subject: [Edu-sig] Gutless classes Message-ID: <20050908174338.DE7211E4004@bag.python.org> I'm thinking about how, in Ruby, class definitions are never closed, meaning you can add methods to a script in various locations. You don't supersede the old class def when you reopen it for more stuff. There's also this idea of defining a module full of methods and then binding those to a class -- I haven't really learned this fully yet. In Python, we have the ability to define methods externally to classes, as ordinary functions, except we need the implicit 'self' variable as a first argument. For example: >>> def __init__(self, a,b): self.a = a self.b = b >>> def __repr__(self): return 'Duh object (%s, %s)' % (self.a, self.b) >>> class Duh(object): pass >>> Duh.__init__ = __init__ >>> Duh.__repr__ = __repr__ >>> o = Duh(1,2) >>> o Duh object (1, 2) Or we could do it this way: >>> class Duh2(object): __init__ = __init__ __repr__ = __repr__ >>> o = Duh2(3,4) >>> o Duh object (3, 4) Why do it this way? I suppose you might have several classes that all use some method. Define the method once, then shove it into more than one gutless class. In the above case, I guess there's no reason to use underunder syntax in the external function name, given the rebinding to a local attribute at runtime. I.e. we might as well go: >>> def representer(self): return 'Duh object (%s, %s)' % (self.a, self.b) >>> class Duh(object): pass >>> Duh.__init__ = constructor >>> Duh.__repr__ = representer >>> o = Duh(9,10) Duh object (9, 10) Kirby From delza at livingcode.org Thu Sep 8 23:03:08 2005 From: delza at livingcode.org (Dethe Elza) Date: Thu, 8 Sep 2005 14:03:08 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050908174338.DE7211E4004@bag.python.org> References: <20050908174338.DE7211E4004@bag.python.org> Message-ID: <84417792-A448-4543-A93E-D4C53ED9DEB6@livingcode.org> You can do the Ruby-style class extension, but it takes a little more setup-up in Python. See this Python Cookbook article for one approach. This works on existing classes, not just "gutless" or stub classes. Extending Classes http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412717 --Dethe Art is either plagiarism or revolution. --Paul Gauguin From urnerk at qwest.net Fri Sep 9 00:57:47 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 8 Sep 2005 15:57:47 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <84417792-A448-4543-A93E-D4C53ED9DEB6@livingcode.org> Message-ID: <20050908225748.EFBC91E4004@bag.python.org> > Extending Classes > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412717 > > --Dethe > Thanks for showing me that. I guess I'm just fascinated by the mutability of classes at runtime even without __metaclass__ magic, e.g.: >>> class Alter(object): "stub class" Pass >>> def meth1(self): return "Meth 1" # mindless method 1 >>> def meth2(self): return "Meth 2" # I'm mindless too >>> class Alter(object): pass >>> Alter.m1 = meth1 >>> oa = Alter() # create objects, go wild >>> oa.m1() 'Meth 1' >>> ob = Alter() Sometime later, rebind the method m1 in the class itself: >>> Alter.m1 = meth2 >>> oa.m1() 'Meth 2' >>> ob.m1() 'Meth 2' Honey, the kids seem a little different this morning, don'tcha think? Pretty lightweight stuff, but "not every language can do it" (tm). Kirby From david at handysoftware.com Fri Sep 9 19:04:31 2005 From: david at handysoftware.com (David Handy) Date: Fri, 9 Sep 2005 13:04:31 -0400 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050908225748.EFBC91E4004@bag.python.org> References: <84417792-A448-4543-A93E-D4C53ED9DEB6@livingcode.org> <20050908225748.EFBC91E4004@bag.python.org> Message-ID: <20050909170431.GA9280@arno2> On Thu, Sep 08, 2005 at 03:57:47PM -0700, Kirby Urner wrote: > > Extending Classes > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412717 > > > > --Dethe > > > > Thanks for showing me that. > > I guess I'm just fascinated by the mutability of classes at runtime even > without __metaclass__ magic, e.g.: > > > >>> class Alter(object): > "stub class" > Pass > > >>> def meth1(self): return "Meth 1" # mindless method 1 > > >>> def meth2(self): return "Meth 2" # I'm mindless too > > >>> class Alter(object): > pass > > >>> Alter.m1 = meth1 > >>> oa = Alter() # create objects, go wild > >>> oa.m1() > 'Meth 1' > >>> ob = Alter() > > Sometime later, rebind the method m1 in the class itself: > > >>> Alter.m1 = meth2 > >>> oa.m1() > 'Meth 2' > >>> ob.m1() > 'Meth 2' I haven't yet found any need to change the method on a class, but I have often written code that changes a method on an instance. Here's a class that "runs" something, but it is an error to run it more than once: class RunOnce: def run(self): self.run = _noMoreRunning # do other stuff that you only want to happen once def _noMoreRunning(self): raise Exception("Can only call run() once.") I prefer the pattern above to the alternative: class RunOnce: def __init__(self): self.__has_been_run_before = False def run(self): if self.__has_been_run_before: raise Exception("Can only call run() once.") self.__has_been_run_before = True # do other stuff that you only want to happen once David H From delza at livingcode.org Fri Sep 9 19:50:20 2005 From: delza at livingcode.org (Dethe Elza) Date: Fri, 9 Sep 2005 10:50:20 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050909170431.GA9280@arno2> References: <84417792-A448-4543-A93E-D4C53ED9DEB6@livingcode.org> <20050908225748.EFBC91E4004@bag.python.org> <20050909170431.GA9280@arno2> Message-ID: <1B23F824-957B-4631-B409-919B6E997E66@livingcode.org> On 9-Sep-05, at 10:04 AM, David Handy wrote: > I haven't yet found any need to change the method on a class, but I > have > often written code that changes a method on an instance. Here's a > class that > "runs" something, but it is an error to run it more than once: > > class RunOnce: > > def run(self): > self.run = _noMoreRunning > # do other stuff that you only want to happen once > > def _noMoreRunning(self): > raise Exception("Can only call run() once.") > > I prefer the pattern above to the alternative: > > class RunOnce: > > def __init__(self): > self.__has_been_run_before = False > > def run(self): > if self.__has_been_run_before: > raise Exception("Can only call run() once.") > self.__has_been_run_before = True > # do other stuff that you only want to happen once > > David H Yes, this is called "trampoline style." It can make code hard to read if it's over-used, but it's quite nice once in a while. I tend to use this style more in Javascript than in Python, but not for any obvious reason. I think the idea of changing a class after it has been defined is more for extending the class with additional methods, rather than changing the methods it has. In Objective-C this type of extension is called a Category and it is explicitly supported by the language. The idea is that sometimes instead of subclassing, all you really want to do is add a couple of methods to an existing class. In Objective-C you can only add methods, not properties, but in Python you can do both. --Dethe "No lesson seems to be so deeply inculcated by experience of life as that you should never trust experts. If you believe doctors, nothing is wholesome; if you believe theologians, nothing is innocent; if you believe soldiers, nothing is safe." --Lord Salisbury, 19th century British prime minister -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2488 bytes Desc: not available Url : http://mail.python.org/pipermail/edu-sig/attachments/20050909/e1f0c5b7/smime.bin From urnerk at qwest.net Fri Sep 9 19:54:01 2005 From: urnerk at qwest.net (Kirby Urner) Date: Fri, 9 Sep 2005 10:54:01 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050909170431.GA9280@arno2> Message-ID: <20050909175405.855311E4004@bag.python.org> > class RunOnce: > > def run(self): > self.run = _noMoreRunning > # do other stuff that you only want to happen once > > def _noMoreRunning(self): > raise Exception("Can only call run() once.") > Yeah, this is clever, I like it. You slam the door from the inside, interpose a "door closed" next time run() is called -- likely in error. A mutable runtime strategy might be to force oneself to create and run all the instances needed, then shut 'em all down at the class level: class Runner (object): def run(self): print "Yo!" >>> obja = Runner() >>> objb = Runner() >>> obja.run() Yo! >>> def newrun(self): raise Exception("Sorry, too late") >>> Runner.run = newrun >>> objb.run() Traceback (most recent call last): File "", line 1, in -toplevel- objb.run() File "", line 1, in newrun def newrun(self): raise Exception("Sorry, too late") Exception: Sorry, too late Kirby From urnerk at qwest.net Fri Sep 9 21:14:32 2005 From: urnerk at qwest.net (Kirby Urner) Date: Fri, 9 Sep 2005 12:14:32 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050908174338.DE7211E4004@bag.python.org> Message-ID: <20050909191435.C9AF51E4004@bag.python.org> Here's another example of defining a class by stuffing an empty shell with externally defined methods. It's really just another way of organizing code, perhaps to bring out some aspect of the knowledge domain. Here, we're in geometry, talking about how a given polyhedron (tetrahedron, cube, you name it), when scaled, changes its edge, surface area, and volume. The scale factor is here applied directly to the edge, i.e. a scale factor of 3 trebles every edge in size (like zooming in by 3x). This has 2nd and 3rd powering side effects on area and volume, as these functions make clear: IDLE 1.1 >>> class Shape (object): pass >>> def build(self, edge = 1, area = 1, volume = 1): self.edge = edge self.surface = area self.volume = volume >>> def scale(self, factor): self.edge *= factor self.surface *= factor**2 self.volume *= factor**3 >>> def reporter(self): return "Shape <%s, %s, %s>" % (self.edge, self.surface, self.volume) >>> Shape.__init__ = build >>> Shape.__mul__ = scale >>> Shape.__repr__ = reporter >>> myshape = Shape() >>> myshape Shape <1, 1, 1> >>> myshape * 3 >>> myshape Shape <3, 9, 27> >>> myshape * 0.125 >>> myshape Shape <0.375, 0.140625, 0.052734375> Kirby From delza at livingcode.org Fri Sep 9 23:02:56 2005 From: delza at livingcode.org (Dethe Elza) Date: Fri, 9 Sep 2005 14:02:56 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050909175405.855311E4004@bag.python.org> References: <20050909175405.855311E4004@bag.python.org> Message-ID: <8044FB93-33E6-4C87-A2D0-DFB254CAEAAF@livingcode.org> On 9-Sep-05, at 10:54 AM, Kirby Urner wrote: > Yeah, this is clever, I like it. You slam the door from the inside, > interpose a "door closed" next time run() is called -- likely in > error. It's usful for things where a decision needs to be made *once* rather than testing a condition every time the code is run, so instead of: class MyUsualThing(object): def doYourThing(self, x,y,z): if isThisAMac(): # mac code here elif isThisWindows(): # windows code here elif isThisLinux(): # linux code here you can do: class MyTrampolinedThing(object): def _doMacThing(self, x,y,z): # mac code here def _doWindowThing(self, x,y,z): # windows code here def _doLinuxThing(self, x,y,z): # linux code here def doYourThing(self, x,y,z): klas = self.__class__ if isThisAMac(): klas.doYourThing = klas._doMacThing elif isThisWindows(): klas.doYourThing = klas._doWindowsThing elif isThisLinux(): klas.doYourThing = klas._doLinuxThing del klas._doMacThing del klas._doWindowsThing del klas._doLinuxThing return self.doYourThing(x,y,z) You could of course define your specific handlers inline in the doYourThing method before it is replaced, but I think it's clearer to define them seperately and then delete them to clean up the object namespace. As you can see, this could be confusing if you get a stacktrace which lists doYourThing, because this method will only ever be called once, and after that the doYourThing will be one of the other methods. Still, it avoids a test on subsequent calls and possibly a function call or two. Just remember that premature optimization is the root of all evil. If trampolining make the code flow *more* readable, use it. Or, if your code is too slow, and you've profiled it and found that the tests are the culprit, then use it. Otherwise, it can make your objects into a jumbled, untraceable mess. --Dethe "All spiritual paths have four steps: show up, pay attention, tell the truth, and don't be attached to the results." Angeles Arien -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2488 bytes Desc: not available Url : http://mail.python.org/pipermail/edu-sig/attachments/20050909/9abd948e/smime.bin From Scott.Daniels at Acm.Org Sat Sep 10 16:44:00 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Sat, 10 Sep 2005 07:44:00 -0700 Subject: [Edu-sig] Gutless classes In-Reply-To: <8044FB93-33E6-4C87-A2D0-DFB254CAEAAF@livingcode.org> References: <20050909175405.855311E4004@bag.python.org> <8044FB93-33E6-4C87-A2D0-DFB254CAEAAF@livingcode.org> Message-ID: Dethe Elza wrote: > > class MyTrampolinedThing(object): > ... > > def doYourThing(self, x,y,z): > klas = self.__class__ > if isThisAMac(): > klas.doYourThing = klas._doMacThing > elif isThisWindows(): > klas.doYourThing = klas._doWindowsThing > elif isThisLinux(): > klas.doYourThing = klas._doLinuxThing _but_, I have a problem with the next three lines: > del klas._doMacThing > del klas._doWindowsThing > del klas._doLinuxThing There is no reason to destroy the source of the method, nor even the other (presumably unused) methods. The Pythonic way is to leave them alone with the underscores in front, and expect programmers not to use them. > return self.doYourThing(x,y,z) --Scott David Daniels Scott.Daniels at Acm.Org From ajsiegel at optonline.net Sat Sep 10 21:36:47 2005 From: ajsiegel at optonline.net (Arthur) Date: Sat, 10 Sep 2005 15:36:47 -0400 Subject: [Edu-sig] quantum instance? Message-ID: <432335CF.40309@optonline.com> Trying to handle the sudden change of state of an instance of an object - a "quantum instance" c starts as a Circle instance. Say, in the course of the manipulation of c its radius approaches towards infinity, and upon the radius becoming > than some Max, I want c to suddenly think of itself as a Line instance rather than as a Circle instance. doable? hints? Art From Scott.Daniels at Acm.Org Sun Sep 11 00:30:17 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Sat, 10 Sep 2005 15:30:17 -0700 Subject: [Edu-sig] quantum instance? In-Reply-To: <432335CF.40309@optonline.com> References: <432335CF.40309@optonline.com> Message-ID: Arthur wrote: > Trying to handle the sudden change of state of an instance of an object > - a "quantum instance" > > c starts as a Circle instance. > > Say, in the course of the manipulation of c its radius approaches > towards infinity, and upon the radius becoming > than some Max, I want c > to suddenly think of itself as a Line instance rather than as a Circle > instance. > > doable? > > hints? > > Art As a sketch: class Blended(object): MaxRadius = 123456 def __init__(self, radius): self._active = Circle(radius=radius) self._other = Line() self.radius = radius # Switch to Line if necessary def __getattr__(self, name): return getattr(self._active, name) def __setattr__(self, name, value): if name[0] == '_': object.__setattr__(self, name, value) elif name[0] != 'radius': return setattr(self, value) if value < self.MaxRadius: if isinstance(self._active, Line): self._active, self._other = self._other, self._active else: if isinstance(self._active, Circle): self._active, self._other = self._other, self._active self._active.radius = value You could read up on __getattr__, __getattribute__, and friends in the Language References section 3.3.2: Customizing attribute access --Scott David Daniels Scott.Daniels at Acm.Org From urnerk at qwest.net Sun Sep 11 20:08:08 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 11 Sep 2005 11:08:08 -0700 Subject: [Edu-sig] quantum instance? In-Reply-To: <432335CF.40309@optonline.com> Message-ID: <20050911180811.AB4C91E4005@bag.python.org> > Say, in the course of the manipulation of c its radius approaches > towards infinity, and upon the radius becoming > than some Max, I want c > to suddenly think of itself as a Line instance rather than as a Circle > instance. > Footnote: In Fuller's synergetic geometry, circles don't become infinite lines, but just bigger and bigger circles. Lines that appear locally straight are just that: local. Clearly we're starting with different assumptions than those of Euclidean greek metaphysics. More from Democritus. Lines aren't perfectly straight either -- zoom in and they become zig-zaggy/wavilinear. Zoom out, and all you get are curves and great circles. Kirby From ajsiegel at optonline.net Sun Sep 11 21:34:57 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 11 Sep 2005 15:34:57 -0400 Subject: [Edu-sig] quantum instance? In-Reply-To: <0IMN00HD2ZPMBKA7@mta22.srv.hcvlny.cv.net> References: <0IMN00HD2ZPMBKA7@mta22.srv.hcvlny.cv.net> Message-ID: <432486E1.2020501@optonline.com> Kirby Urner wrote: >In Fuller's synergetic geometry, circles don't become infinite lines, but >just bigger and bigger circles. Lines that appear locally straight are just >that: local. Clearly we're starting with different assumptions than those >of Euclidean greek metaphysics. More from Democritus. Lines aren't >perfectly straight either -- zoom in and they become zig-zaggy/wavilinear. >Zoom out, and all you get are curves and great circles. > FWIW, I am working with (as in studying and implementing some tools in PyGeo to enliven that study of) the geometry of complex numbers. And doing so in such a way that all fundamental elements are defined by its 2X2 hermitian matrix. So I am getting fairly abstract - a "line" has hermitian[0][0] == 0, else I am looking at a "point" or a "circle". Drawing the damn things is a lot less abstract - and as hermitian[0][0] approaches 0, a line makes a better represetantion - is all. And since things are dynamic, I need my iinstances to think on their feet as to what makes a better representation. If/else is really all I need - but I was playing in my head with trying something more "dramatic". Fredrk Lundh - the fbot and author of PIL - posted a blog entry a few months ago about working with complex numbers to do basic image manipulation. With Numeric in play, I can imagine a lot of efficiency gains by working with it and the Python built_in complex numbers- via Hermitian matrixes and 2X2 mobius transformation matrixes - to accomplish a lot of the kind of image transformation effects that I imagine are normally done otherwise. I expect that experimentation along these lines is going to eventually get me more into playing with bitmap graphics, whereas until now I have been a vector graphics kind of guy. Art From ajsiegel at optonline.net Mon Sep 12 00:33:22 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 11 Sep 2005 18:33:22 -0400 Subject: [Edu-sig] quantum instance? In-Reply-To: <0IMN00HD2ZPMBKA7@mta22.srv.hcvlny.cv.net> References: <0IMN00HD2ZPMBKA7@mta22.srv.hcvlny.cv.net> Message-ID: <4324B0B2.8040409@optonline.com> Kirby Urner wrote: >Lines aren't >perfectly straight either -- zoom in and they become zig-zaggy/wavilinear. >Zoom out, and all you get are curves and great circles. > > Yes. From a bitmap perspective, anyway. And certainly circles, even from a vector computer graphics point of view are actually polygons, not circles. Which is really my problem.. And is directly related to dynamic zooming. I am in fact attempting to make my algorithm for converting a representation from a circle (i.e. polygon) to a line and back again sensitive to the actual zoom level. At some definition of local, the circle becomes a line. Summer must be over . I have time for this kind of fun again. Art From ajsiegel at optonline.net Mon Sep 12 22:33:40 2005 From: ajsiegel at optonline.net (ajsiegel@optonline.net) Date: Mon, 12 Sep 2005 16:33:40 -0400 Subject: [Edu-sig] quantum instance Message-ID: >You could read up on __getattr__, __getattribute__, and > >friends in the Language References section 3.3.2: > Customizing attribute access "and friends" include descriptors, so that the discussion about properties here had actually led me into some better understanding of this realm of Python. It ties together a bit, in that in reviewing my own code and my own use of properties I see I did use it mostly in comformity with the example outlined in Guido's article on new style classes, and to solve a problem not unrelated to the one I am trying to solve by a "blended class". Specifically, vpython will try to draw anything you send to it, but if you send it a vector outside of some range relative to the current zoom level, the display fritzes. So in retrieving a vector (which I consider an attribute) for purposes of rendering, I was setting a constraint that would be sufficient to avoid the fritz, while keeping the actual values of the vector pure, for the purposes of further calculation. IOW I am managing the retrievel of data from an attribute. Another friend of __getattr__ is __slots__. I was confused by slots as well early on, as I think were many others. I satsified myself - if no one else - that my confusion was in part generated by a general confusion, including some confusion in the What's New in Python2.X (when __slots__ first appeared). It is not too surprising that there can be some degree of misinprepation of Guido's intention in adding a feature to the language. The problem is exasperated when an example of the mechanical use of something like properties is presented - and confused (by folks at my level ,at least) as an actual use case of the feature. I do think this happened with getters and setters and properties, and think there may be some pedagogical lesson in this somewhere. Extending the point - one reason that I think Java cannot work well (or as well) as an introductory language is that it forces one to mechanically understand attribute access modification (and such like) well before one can be expected to understand in any authentic manner the use cases. The result is seditious and wide ranging, because we then settle on an approach where expectations as to authenticity are generally lowered. Much preferable to understand the feature, its mechanics, and its use case as one process. I get there my not concerning myself about features I don't need, until I think I need them. And then determine whether it actually solves my problem. If I manage the mechanics, and it solves my problem - I have my use case. But of course I have a context - my interests. I think teaching programming outside a context - as an abstract discipline - is unavoidably problematic in this regard. Web and network programming, scientific programming, algorithomics, business programming, graphics and entertainment programming ... all provide a context and a context implies use cases. I am not convinced "programming" as a stand-alone subject cannot be optimum as an approach. But I guess that postion runs counter to enough established realities as to be essentially meaningless. My specialty. I do think Python lends itself well to a pedagogoical approach that gives context - whatever it might be - due weight. Which is what brings me here , at least indirectly. And why I am committed to annoy everyone until everyone sees everything my way. ;) Art From Scott.Daniels at Acm.Org Tue Sep 13 01:57:41 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Mon, 12 Sep 2005 16:57:41 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: References: Message-ID: ajsiegel at optonline.net wrote: >... > I think teaching programming outside a context - as an abstract > discipline - is unavoidably problematic in this regard. I would have more sympathy if you would subscribe to the same philosophy for "geometry" and "mathematics." As someone who has concentrated on computer science and "The Art of Computer Programming" for a huge number of years, I am offended at the denigration of my field of study (or at least what I perceive to be a denigration). > I am not convinced "programming" as a stand-alone subject cannot be optimum as an approach. Why is this different from saying, "I am not convinced 'mathematics' as a stand-alone subject cannot be optimum as an approach?" "Only in the context of physics or engineering or ...." Please distinguish from the teaching of the computer science and/or programming that _you_ want to learn from that that _anyone_ might want to learn. > And why I am committed to annoy everyone until > everyone sees everything my way. Well, you certainly accomplished the "annoy" part today. Perhaps I am just in a cranky mood. --Scott David Daniels Scott.Daniels at Acm.Org From ajsiegel at optonline.net Tue Sep 13 04:48:58 2005 From: ajsiegel at optonline.net (Arthur) Date: Mon, 12 Sep 2005 22:48:58 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: References: Message-ID: <43263E1A.5070804@optonline.com> Scott David Daniels wrote: >ajsiegel at optonline.net wrote: > > >>... >>I think teaching programming outside a context - as an abstract >>discipline - is unavoidably problematic in this regard. >> >> >I would have more sympathy if you would subscribe to the same philosophy >for "geometry" and "mathematics." As someone who has concentrated on >computer science and "The Art of Computer Programming" for a huge number >of years, I am offended at the denigration of my field of study (or at >least what I perceive to be a denigration). > > And I would have more sympathy if you were willing to deal separattely and distinctly with computer science, as science and the "Art of Computer Programming" as an art. I personally have very little interest in (but great respect for) the former, and a good deal of personal interest in the latter. Maybe its harder for those who started by writing machine code to make the distinction than it is for those of us who only came to the party when and becuase high level languages were developed. It is indeed stimulating and challenging to attempt to communicate with a complex machine, and do so with elegance. But I don't find it difficult at all to maintain that the pursuit is different in nature from the study of mathematics and geometry. Some wold argue that mathematics and geometry are there whether we as a race are or are not. Certainly though they are there whether my machine powers up or does not. >>I am not convinced "programming" as a stand-alone subject cannot be optimum as an approach. >> >> >Why is this different from saying, "I am not convinced 'mathematics' as >a stand-alone subject cannot be optimum as an approach?" "Only in the >context of physics or engineering or ...." > > I believe computer science is a stand alone subject, and that programming is natural in the context of a computer science curriculum.. But I do that think someone like yourself is in fact actually studying programming in a particular context. Maybe its most general context . But a quite specific context nonetheless. >Please distinguish from the teaching of the computer science and/or >programming that _you_ want to learn from that that _anyone_ might >want to learn. > > > >>And why I am committed to annoy everyone until >>everyone sees everything my way. >> >> >Well, you certainly accomplished the "annoy" part today. Perhaps I >am just in a cranky mood. > > Perhaps an attempt to liberate programming from the control of computer scientists is bound to annoy a computer scientist, a bit. ;) Art From urnerk at qwest.net Tue Sep 13 04:54:16 2005 From: urnerk at qwest.net (Kirby Urner) Date: Mon, 12 Sep 2005 19:54:16 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <20050913025418.709A91E4006@bag.python.org> I pretty much agree with Arthur that CS needs grist for its mill, and geometry and mathematics are good suppliers. I would also turn that around and go with Scott's point that CS is not alone in needing grist: geometry and mathematics benefit by having CS supply context and applications. For example, a purist mathematician might scorn an approach to the concept of vectors that uses Python code as a means to communicate just what a vector *is* i.e. uses a computer language to help anchor a mathematical generality. However, not being a purist, I think such cross-breeding begets many positive synergies. We get to use string substitution to generate scene description language, directly from our Python vector class, as food for POV-ray.[1] Python and POV-ray are wonderful and powerful tools. It hardly makes sense to teach mathematics/geometry without these tools, or tools like them, if the requisite tech is available. They're free, after all. In sum, it makes plenty of sense to teach CS while importing from other fields (I'd argue that Knuth makes extensive use of pre-CS mathematics), and it makes just as much sense teach math and geometry while importing from CS. The advantages of a cultivating a math/CS hybrid for use in present and future curricula are just too great to ignore. Why rip ourselves off unnecessarily? We should continue this lineage, which is already a tradition, stretching back to before Python was born. Kirby Related thread @ Math Forum (math-teach list): http://mathforum.org/kb/message.jspa?messageID=3934957&tstart=0 [1] >>> reload(satacad) >>> from satacad import Vector, Edge >>> v0 = Vector((1,1,1)) >>> v1 = Vector((1,2,-3)) >>> v2 = v0 + v1 >>> e = Edge(v2,v0) >>> e Edge <2, 3, -2>, <1, 1, 1> >>> e.write() 'cylinder <2, 3, -2>, <1, 1, 1>, 0.1 pigment { color Red }' >>> v0 Vector <1, 1, 1> >>> v2*3 Vector <6, 9, -6> class Vector(object): color = 'Red' def __init__(self, xyz): self.xyz = xyz def write(self): basic = "cylinder <0,0,0>, <%s,%s,%s>, 0.1" % self.xyz return "%s %s" % (basic, "pigment { color %s }" % self.color) def __repr__(self): return "Vector <%s, %s, %s>" % self.xyz def __mul__(self, scalar): xyz = tuple([scalar * i for i in self.xyz]) return Vector(xyz) def __add__(self, other): xyz = tuple([ i+j for i,j in zip(self.xyz, other.xyz)]) return Vector(xyz) def _get_xyz(self): return '<%s, %s, %s>' % self.xyz coords = property(_get_xyz) class Edge(object): color = 'Red' def __init__(self, v0, v1): self.v0 = v0 self.v1 = v1 def __repr__(self): return "Edge %s, %s" % (self.v0.coords, self.v1.coords) def write(self): basic = "cylinder %s, %s, 0.1" % (self.v0.coords, self.v1.coords) return "%s %s" % (basic, "pigment { color %s }" % self.color) From letondal at pasteur.fr Tue Sep 13 07:44:55 2005 From: letondal at pasteur.fr (Catherine Letondal) Date: Tue, 13 Sep 2005 07:44:55 +0200 Subject: [Edu-sig] Gutless classes In-Reply-To: <20050908174338.DE7211E4004@bag.python.org> References: <20050908174338.DE7211E4004@bag.python.org> Message-ID: <8eb2c87af35daae38408c2f15cdce049@pasteur.fr> Hi, On Sep 8, 2005, at 7:42 PM, Kirby Urner wrote: > > I'm thinking about how, in Ruby, class definitions are never closed, > meaning > you can add methods to a script in various locations. You don't > supersede > the old class def when you reopen it for more stuff. There's also > this idea > of defining a module full of methods and then binding those to a class > -- I > haven't really learned this fully yet. > > A good reason to extend a class at run-time, either by adding a new method or by redefining an existing one, is for customization by a knowledgeable end-user of an application (people like you and me are sometimes end-users of others'programs, aren't they?). This is for example the case for scientists (I work with biologists): they are not programmers, but they have sometimes enough programming experience for such adaptation. When methods are defined as small and modular, it's very convenient to be able edit them -- for instance to add a conditional, or to add a method that you are able to call from a GUI that opens access to the Python interpreter. [Another language that can extends a class at run-tim is XOtcl (www.xotcl.org), developped as an extension of MIT Otcl] Best, -- Catherine Letondal -- Institut Pasteur www.pasteur.fr/~letondal From Scott.Daniels at Acm.Org Tue Sep 13 21:14:45 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Tue, 13 Sep 2005 12:14:45 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <43263E1A.5070804@optonline.com> References: <43263E1A.5070804@optonline.com> Message-ID: Arthur wrote: > Scott David Daniels wrote: > >>ajsiegel at optonline.net wrote: >>>I think teaching programming outside a context - as an abstract >>>discipline - is unavoidably problematic in this regard. >> >>I would have more sympathy if you would subscribe to the same philosophy >>for "geometry" and "mathematics." As someone who has concentrated on >>computer science and "The Art of Computer Programming" for a huge number >>of years, I am offended at the denigration of my field of study (or at >>least what I perceive to be a denigration). OK, here I may have been unclear. TAoCP is a set of books I love, but I was, in fact, referring to the art of computer programming, and engaging in a bit of a pun. It seems to have helped confuse the issue. I also understand most of the best programmers I know are not computer scientists, though many of them read in it from time to time. > And I would have more sympathy if you were willing to deal separattely > and distinctly with computer science, as science and the "Art of > Computer Programming" as an art. OK, we are getting to a nub here, but we are also moving to my personal biases rather than that of the field itself. I went to the Univ. of Penn., where Mathematics was definitely classified an Art; even Applied Math. I view computer programming as an Art, not engineering nor a science. The art is in the clear expression of a solution to a problem. Much of what you need to know to develop that art involves things like brushwork -- technical skills at which you must become proficient in order to work (the _craft_ part of computer programming), but the art lies not only in a perfected craft, but an ability to see a problem and find a solution that seems obvious once found. But, to confuse the issue a bit, I also find Mathematics and Computer Science equally arts. > I personally have very little interest in (but great respect for) > the former [Computer Science], and a good deal of personal > interest in the latter [Computer Programming]. Maybe its harder for > those who started by writing machine code to make the distinction > than it is for those of us who only came to the party when and because > high level languages were developed. > It is indeed stimulating and challenging to attempt to communicate with > a complex machine, and do so with elegance. Ah -- is that what computer science is to you, or is it programming? In my view the communication is with the reader of the program (who may be reading for the joy, but more likely is reading in order to alter). > But I don't find it difficult at all to maintain that the pursuit is > different in nature from the study of mathematics and geometry. Some > would argue that mathematics and geometry are there whether we as a > race are or are not. Certainly though they are there whether my machine > powers up or does not. > >>>I am not convinced "programming" as a stand-alone subject cannot be optimum as an approach. Could you restate this? I presume (but am unsure) this means: I believe teaching "programming" without computer science is optimal. > I believe computer science is a stand alone subject, and that > programming is natural in the context of a computer science > curriculum. > But I do that think someone like yourself is in fact actually > studying programming in a particular context. Maybe its most > general context. But a quite specific context nonetheless. Hmmm. I think you know me less than you think you do. I think a core computer science question is how efficiently some values can _ever_ be calculated, based on as few assumptions as we can get away with making about the nature of the machines (and languages) doing the computation. These kinds of results should inform how you (or even whether you attempt to) build programs to solve these problems. > Perhaps an attempt to liberate programming from the control of computer > scientists is bound to annoy a computer scientist, a bit. ;) I suppose you might call me a computer scientist, but if so I am an amateur computer scientist; my CS is from the love of the ideas, not from a compensated position. My pay has come, almost exclusively, from being a programmer. I would say that writing computer programs without an understanding of computer science is certainly possible (and I've worked with lots of people who do so), but to write well, and to write are not the same skill at all. --Scott David Daniels Scott.Daniels at Acm.Org From ajsiegel at optonline.net Tue Sep 13 22:23:11 2005 From: ajsiegel at optonline.net (Arthur) Date: Tue, 13 Sep 2005 16:23:11 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: References: <43263E1A.5070804@optonline.com> Message-ID: <4327352F.8080906@optonline.com> Scott David Daniels wrote: >Arthur wrote: > >> >> >>>>I am not convinced "programming" as a stand-alone subject cannot be optimum as an approach. >>>> >>>> >Could you restate this? > > """" The art is in the clear expression of a solution to a problem.. """ and """ but the art lies not only in a perfected craft, but an ability to see a problem and find a solution that seems obvious once found. """" What problem? What context for problems? How to we avoid "learning to program" as a game of make beleive, attacking self- referential problems that have already been solved. How do we break the cycle of the best programmers solving the problem of making the best IDE that can be used by the best programmers - to make better IDEs? Art From ajsiegel at optonline.net Wed Sep 14 01:16:48 2005 From: ajsiegel at optonline.net (Arthur) Date: Tue, 13 Sep 2005 19:16:48 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: References: <43263E1A.5070804@optonline.com> Message-ID: <43275DE0.6050609@optonline.com> Scott David Daniels wrote: >I would say that writing computer programs without an understanding of >computer science is certainly possible (and I've worked with lots of >people who do so), but to write well, and to write are not the same >skill at all. > Let me sign on to your point of view. I am writing for other human beings. But which other human beings? A little ditty I had written here was judged harshly (and incorrectly, I believe), because it spoke in a vocabulary of finance - to programmers. Can someone whose first identity is as a programmer judge the writing of someone whose is not. Back to where I started to get testy: properties and decorators I honestly believe that if I had seen them in my first Python Triangle class I would have judged myself to be looking at a language that might be swell - for somebody else. But a little too magical, self-referential and self-involved - for my own taste. And would have moved on. Which might have saved the Python community from the annoyances of one annoying guy. But I can imagine someone with my sensibilities - just a lot less annoying - having moved on, and think that would have been a shame. Is that really how we do a Triangle in Python today? Can we accept the less sophisticated appraoches on equal footing? Art From urnerk at qwest.net Wed Sep 14 01:49:23 2005 From: urnerk at qwest.net (Kirby Urner) Date: Tue, 13 Sep 2005 16:49:23 -0700 Subject: [Edu-sig] Draft math/CS stuff (satacad 6938) Message-ID: <20050913234927.8CE971E4002@bag.python.org> I'd be happy if anyone wants to comment on and/or mess with the code below. It's what I'm working on for my upcoming Saturday Academy class, which uses a combination of Python and POV-Ray to teach geometry. http://www.saturdayacademy.org/classes/ClassDetail.aspx?id=6938 Some of my background info is on file here (another list) i.e. I talk about what's unfinished: http://mail.geneseo.edu/pipermail/math-thinking-l/2005-September/000840.html plus I'm still looking at properties, and continuing some recent threads re pedagogy here on our edu-sig list. Also, math-think-l unindented/trashed the source, perhaps because I submitted in rich text through gmail, whereas a plain text submission might've gotten through unscathed (??). Kirby ===== class Vector(object): color = 'Red' def __init__(self, xyz): self.xyz = xyz def write(self): basic = "cylinder <0,0,0>, <%s,%s,%s>, 0.1" % self.xyz return "%s %s" % (basic, "pigment { color %s }" % self.color) def __repr__(self): return "Vector <%s, %s, %s>" % self.xyz def __mul__(self, scalar): xyz = tuple([scalar * i for i in self.xyz]) return Vector(xyz) def __add__(self, other): xyz = tuple([ i+j for i,j in zip(self.xyz, other.xyz)]) return Vector(xyz) def _get_xyz(self): return '<%s, %s, %s>' % self.xyz def _get_length(self): return pow(sum([i**2 for i in xyz]), 0.5) coords = property(_get_xyz) length = property(_get_length) class Edge(object): color = 'Red' def __init__(self, v0, v1): self.v0 = v0 self.v1 = v1 def __repr__(self): return "Edge %s, %s" % (self.v0.coords, self.v1.coords) def write(self): basic = "cylinder %s, %s, 0.1" % (self.v0.coords, self.v1.coords) return "%s %s" % (basic, "pigment { color %s }" % self.color) class Polyhedron(object): color = 'Red' def __init__(self, vertsdict, faces): self.verts = vertsdict self.faces = faces self.edges = self._get_edges() def __repr__(self): return "Polyhedron: %s edges, %s faces" \ % (len(self.edges), len(self.faces)) def _get_edges(self): # stub procedure: take a list of face-tuples and distill # all the unique edges, e.g. ((1,2,3)) => ((1,2),(2,3),(3,1)) # e.g. icosahedron has 20 faces and 30 unique edges # ( = cubocta 24 + tetra's 6 edges to squares per jitterbug) pass def write(self): # stub procedure -- needs to be completed return 'write out edges' def __mul__(self, scalar): newvectors = {} for v in self.verts: newvectors[v] = self.verts[v] * scalar return Polyhedron(newvectors, self.faces) class Header (object): # defaults bgcolor = "color Gray50" lightloc = "<300, 300, -1000>" lightcolor = "White" @staticmethod def write(): return """ #include "colors.inc" background { %(bgcolor)s } light_source{ %(lightloc)s %(lightcolor)s } """ % Header.__dict__ class Camera (object): # defaults look_at = 0 location = '<0, .1, -25>' @staticmethod def write(): return """ camera { location %(location)s look_at %(look_at)s angle 30 } """ % Camera.__dict__ def buildicosa(): phi = (1 + pow(5,0.5))/2.0 verts = {# 2*phi x 2 rectangle in XZ 1:Vector((-phi, 0, -1)), 2:Vector((-phi, 0, 1)), 3:Vector(( phi, 0, 1)), 4:Vector(( phi, 0, -1)), # 2*phi x 2 rectange in XY 5:Vector(( -1, phi, 0)), 6:Vector(( 1, phi, 0)), 7:Vector(( 1, -phi, 0)), 8:Vector(( -1, -phi, 0)), # 2*phi x 2 rectange in YZ 9:Vector(( 0, 1, phi)), 10:Vector(( 0, -1, phi)), 11:Vector(( 0, -1, -phi)), 12:Vector(( 0, 1, -phi))} faces = ((5,6,9),(5,6,2),(5,12,1),(5,6,1),(5,1,2), (11,1,12),(11,12,4),(11,1,8),(11,4,7),(11,7,8), (4,12,6),(4,6,3),(4,3,7), (3,9,6),(3,6,4), (10,7,8)) #unfinished return verts, faces def main(): icosa = Polyhedron(*buildicosa()) f = file('icosa.pov','w') Camera.location = '<0, 2, -20>' print >> f, Header.write() print >> f, Camera.write() print >> f, icosa.write() f.close() if __name__ == '__main__': main() From Scott.Daniels at Acm.Org Wed Sep 14 02:15:11 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Tue, 13 Sep 2005 17:15:11 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <43275DE0.6050609@optonline.com> References: <43263E1A.5070804@optonline.com> <43275DE0.6050609@optonline.com> Message-ID: Arthur wrote: > Back to where I started to get testy: > > properties and decorators > > I honestly believe that if I had seen them in my first Python Triangle > class I would have judged myself to be looking at a language that might > be swell - for somebody else. But a little too magical, > self-referential and self-involved - for my own taste. And would have > moved on. I understand that properties and decorators look like obscure magic. I ask you to suspend judgment on those (an act of faith), until you understand why such features seriously assist the readability of code and designs. This act of faith can be based on a respect for the obvious effort somebody has gone to in other ways to make Python such a clear and simple language. I don't object to your not wanting to use such constructs, but rather to your desire to remove them from the language (or veto adding them) in order to make it "simpler." I'm sure others have said as much about the ridiculous idea of making a value for the square root of minus one, or for the incomprehensibly strained "line at infinity." When you ask what these features provide, I try to explain how they make it possible to write some very clear simple code. I think Kirby will attest to the fact that decorators seriously improved the readability of his "hypertoons" code. Decorators should be used sparingly, if at all. That is not to say they shouldn't exist. The key to understanding when decorators are useful can be summarized as "whenever you feel you are writing boilerplate your skin should itch." This doesn't mean that you should not write boilerplate on occasion, but rather that you should be searching for a way around it. I tried to explain to you why I found properties such a useful addition. Their existence allows me to write code without the "protective generality" of always writing accessors and mutators in case, some two years hence, I need to change more than the single attribute on a mutation, or decide some value that I have been storing is much better left calculated. This was unconvincing to you, but you responded more in the vein of "nobody should be allowed to use this, so the code I read is simpler." I am surprised you accept exceptions (a relatively recent development in the design of computer languages). The rule I use in commenting code is that you should not comment use of features of a language in code written in that language. Programmers who read code written in Python are responsible for learning Python, and there is no excuse for code like: a = range(12) # Make a list of integers between 0 and 11 inclusive The comment slows down your reading of the code and distracts you from reading the application itself. The language is the given. When you choose a language, you buy its tradeoffs. If you cannot stand descriptors, insist on python 2.3. When you ask what something is good for, and get given an explanation that turns out to not make your life simpler, don't presume that the examples given are therefore useless. You have not spent a career writing code that must be rewritten constantly (to accommodate changing requirements); properties help in that task, in part because you can avoid using them until necessary, with their existence in your back pocket. > Can we accept the less sophisticated approaches on equal footing? We can accept the less sophisticated approach to designing programs as workable. Do you seriously think that when designing a language equal weight should be given to those that understand the implications of a decision and those who "go with their gut?" It is one thing to make ivory tower decisions, and another to know the impact a decision might have. --Scott David Daniels Scott.Daniels at Acm.Org From ajsiegel at optonline.net Wed Sep 14 04:22:20 2005 From: ajsiegel at optonline.net (Arthur) Date: Tue, 13 Sep 2005 22:22:20 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: References: <43263E1A.5070804@optonline.com> <43275DE0.6050609@optonline.com> Message-ID: <4327895C.1060405@optonline.com> Scott David Daniels wrote: >I understand that properties and decorators look like obscure magic. >I ask you to suspend judgment on those (an act of faith), until you >understand why such features seriously assist the readability of code >and designs. This act of faith can be based on a respect for the >obvious effort somebody has gone to in other ways to make Python such >a clear and simple language. > > No faith. If that were me I'd be writing "protected" before my methods knowing there was a damn good reason for it. That I was practicing good objected oriented design. And that I was solving a problem I just didn't happen to know I had, but most assuredly did. If language design decisions were not all about trade-offs, language design would be easy. It would be as silly for me to suggest that properties and decorators do not bring advantages as it would be for you to suggest that those advantages come for free. My argument though is with you, not Guido. It is about use cases for existing features, not about the features themselves. And in the particular case of properties, it was only in going back to Guido's own use case illustration that I begin to develop some comfort with why properties are there - why they are a neat solution to a limited set of problems. I understand them now more in terms of something akin to a GUI event, or a SQL trigger. You have a need to know when something attempts to set or get a particular attribute. The relation to the actual attribute might be tenous. It's an event. It might begin a process that sends an e-mail to Mary. Who knows what. Its all quite practical and tangible stuff, though. It has nothing yet, in my mind, to do with decoupling anything from anything else as a matter of good OOP design. And to the extent you feel properties are well used in that regard, than you are developing your own use cases which may or may not be similar to Guido's ideas and implicit in the design of the language. And I guess I am suggesting you are suggesting too much by suggesting otherwise. Art Am I making any sense whatever? Art But I still don't see the connection to XP programming, API design >I don't object to your not wanting to use such constructs, but rather >to your desire to remove them from the language (or veto adding them) >in order to make it "simpler." I'm sure others have said as much about >the ridiculous idea of making a value for the square root of minus one, >or for the incomprehensibly strained "line at infinity." > >When you ask what these features provide, I try to explain how they make >it possible to write some very clear simple code. I think Kirby will >attest to the fact that decorators seriously improved the readability >of his "hypertoons" code. Decorators should be used sparingly, if at >all. That is not to say they shouldn't exist. The key to understanding >when decorators are useful can be summarized as "whenever you feel >you are writing boilerplate your skin should itch." This doesn't mean >that you should not write boilerplate on occasion, but rather that you >should be searching for a way around it. > >I tried to explain to you why I found properties such a useful addition. >Their existence allows me to write code without the "protective >generality" of always writing accessors and mutators in case, some two >years hence, I need to change more than the single attribute on a >mutation, or decide some value that I have been storing is much better >left calculated. This was unconvincing to you, but you responded >more in the vein of "nobody should be allowed to use this, so the code >I read is simpler." I am surprised you accept exceptions (a relatively >recent development in the design of computer languages). > >The rule I use in commenting code is that you should not comment use of >features of a language in code written in that language. Programmers >who read code written in Python are responsible for learning Python, and >there is no excuse for code like: > a = range(12) # Make a list of integers between 0 and 11 inclusive >The comment slows down your reading of the code and distracts you from >reading the application itself. The language is the given. When you >choose a language, you buy its tradeoffs. If you cannot stand >descriptors, insist on python 2.3. When you ask what something is good >for, and get given an explanation that turns out to not make your life >simpler, don't presume that the examples given are therefore useless. >You have not spent a career writing code that must be rewritten >constantly (to accommodate changing requirements); properties help in >that task, in part because you can avoid using them until necessary, >with their existence in your back pocket. > > > Can we accept the less sophisticated approaches on equal footing? > >We can accept the less sophisticated approach to designing programs >as workable. Do you seriously think that when designing a language >equal weight should be given to those that understand the implications >of a decision and those who "go with their gut?" It is one thing to >make ivory tower decisions, and another to know the impact a decision >might have. > > >--Scott David Daniels >Scott.Daniels at Acm.Org > >_______________________________________________ >Edu-sig mailing list >Edu-sig at python.org >http://mail.python.org/mailman/listinfo/edu-sig > > > From delza at livingcode.org Wed Sep 14 06:19:22 2005 From: delza at livingcode.org (Dethe Elza) Date: Tue, 13 Sep 2005 21:19:22 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: References: <43263E1A.5070804@optonline.com> <43275DE0.6050609@optonline.com> Message-ID: Arthur, You may be happy to know that hard-core computer scientists cannot agree on the benefits of abstractions such as decorators. Paul Graham attributes power and elegance to the tersest languages[1] [2], claiming that fewer lines of code means fewer bug, less time writing the code, and less time maintaining the code. Meanwhile Richard Gabriel notes[2] that code can share with poetry the aspect of Compression, in which a few words can hold a great deal of meaning, but he is careful to note that this can easily be taken too far, resulting in incomprehensible gibberish (in poetry or in code). Perhaps this comes down to the fact that both men are old hands at Lisp, but while Graham literally wrote the book on Common Lisp[3], Gabriel wrote "A Critique of Common Lisp." Graham used a simplistic program to demonstrate succinctness, a straw man I could argue against, but it demonstrates what I'm talking about, using Python's standard foil: Perl. The goal is to create a function which generates accumulators: Given a number n, it will return a new function which takes another number i, and returns n incremented by i, storing the accumulating result. Graham's canonical example is in Common Lisp, and is indeed quite succinct. (defun foo (n) (lambda (i) (incf n i))) And in Perl you have sub foo { my ($n) = @_; sub {$n += shift} } Which is succinct and perhaps readable to someone thoroughly familiar with Perl, but does look like line noise to me. Perhaps the most succinct you can get this in Python is the following: def foo(n): def bar(i, l=[n]): l[0] += i return l[0] return bar Although this is quite a bit longer than the Lisp version, it is nearly as unreadable as the Perl code. In part this is because Python distinguishes between expressions and statements, so we cannot "return l[0] += i". Also, Python does not allow us to assign to local integers, so we hack around this by putting the integer "n" in a mutable container "l = [n]". And lambdas don't allow statements (or is it expressions?) so that keeps it from getting succinct as well. But of course, this is not the canonical Python. Canonical Python would create a class: class foo: def __init__(self, n): self.n = n def __call__(self, i): self.n += i return self.n As you can see, this is not much longer, and (in my eyes at least), vastly more readable. No hacks with lists, it clearly shows that we're accumulating the value. If I were to use this in any real system, I would change "self.n" to "self.accumulator" or some such, and make it even longer, because readability counts more than succinctness, despite what Graham claims[5]. If you're still reading this far you may have noted that I haven't actually talked about decorators at all. In my code, I have come to places where there are aspects which cut across classes and methods in a way that's not always intuitive or easy to capture in standard object-oriented code. In Java and some other languages they are implementing Aspect-Oriented Programming (AOP), where you create "cutpoints" where code will be injected for different "aspects" which are defined elsewhere. Generating this code is called "code weaving" or "aspect weaving" and the result is not intended to be read or modified by humans. Debugging this type of code must take the patience of a saint, since all your line numbers and references would have disappeared in the warp and weft. With decorators I get an 80/20 solution to aspects which cover all of the most common (and dare I say, important) uses of AOP, without compile-time weaving, or losing line numbering or stack tracing or any of my standard editing, reading, or debugging toolkit. For me, this is a big win, and I'm happy to have decorators in my toolbox. I'm also quite happy to have generators, list comprehensions, properties, and descriptors, because these all fill needs for times I have bumped up against a wall of complexity and my code has grown too big, too multi-branched to fit comfortably in my head. Since I do a lot of "hobby coding" in my limited spare time, on a lot of different project, being able to fit the code in my head is essential. I need to be able to come to a project I left off with months ago and quickly grok what it does and why. That said, I don't make daily use of decorators, descriptors, properties, or even generators. Just as a carpenter's toolbox may contain hammers and screwdrivers he uses everyday, and also more specialized planes or chisels he uses more rarely (but still values having the right tool for the job when he needs it), these are my more specialized tools. I do use list comprehensions daily, they have become one of my favored hammers, but I do try to take care to use them in a way which enlightens the code rather than obfuscates it, which they can certainly do. And while Lisp hackers like Graham cannot understand why anyone wouldn't want to use his all-powerful language, the Smalltalk community is equally amused when the concepts they cut their teeth on in the seventies are finally adopted by more mainstream languages [6]. Power quote: "Reinventing Smalltalk, one decade at a time." --Dethe [1] http://www.paulgraham.com/icad.html (especially see "Appendix: Power" at the end). [2] http://www.dreamsongs.com/NewFiles/PatternsOfSoftware.pdf (Reuse vs. Piecemeal Growth chapter) [4] http://www.paulgraham.com/acl.html (ANSI Common Lisp) [3] http://dreamsongs.com/NewFiles/clcrit.pdf (A Critique of Common Lisp) [5] http://www.paulgraham.com/power.html (Succinctness is Power, a direct attack on Python) [6] http://www.intertwingly.net/blog/2005/09/09/The-Case-for-Dynamic- Languages (slides link) "And you think you're so clever and classless and free" ? John Lennon on prototype-based programming -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2488 bytes Desc: not available Url : http://mail.python.org/pipermail/edu-sig/attachments/20050913/a4d8e99a/smime.bin From delza at livingcode.org Wed Sep 14 06:27:49 2005 From: delza at livingcode.org (Dethe Elza) Date: Tue, 13 Sep 2005 21:27:49 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <4327895C.1060405@optonline.com> References: <43263E1A.5070804@optonline.com> <43275DE0.6050609@optonline.com> <4327895C.1060405@optonline.com> Message-ID: <26CC842E-FFC8-4F87-932D-1ABA3256F2D5@livingcode.org> On 13-Sep-05, at 7:22 PM, Arthur wrote: > My argument though is with you, not Guido. It is about use cases for > existing features, not about the features themselves. And in the > particular case of properties, it was only in going back to Guido's > own > use case illustration that I begin to develop some comfort with why > properties are there - why they are a neat solution to a limited > set of > problems. I understand them now more in terms of something akin to > a GUI event, or a SQL trigger. You have a need to know when > something attempts to set or get a particular attribute. The > relation > to the actual attribute might be tenous. It's an event. It might > begin > a process that sends an e-mail to Mary. Who knows what. Its all quite > practical and tangible stuff, though. As Guido has said, properties don't do anything that couldn't be done before with __getattr__ and __setattr__, they just give a cleaner syntax for it. Since VPython makes extensive use of __getattr__ and __setattr__, do you think you would like the package more or less if they used properties instead? Or perhaps if instead of (I don't actually remember if VPython allows named colours, but bear with me for this example): ball = sphere(color=blue) # a blue sphere appears on the screen ball.color = 'red' # the ball changes instantly to red would this be better if we wrote: ball = sphere(color='blue') ball.setColor('red') does that make it more readable, or less? --Dethe "Trusting a scientist on questions of metaphysics is like paying someone else to worship God for you." -- Bill Welton From ajsiegel at optonline.net Wed Sep 14 15:34:35 2005 From: ajsiegel at optonline.net (Arthur) Date: Wed, 14 Sep 2005 09:34:35 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <26CC842E-FFC8-4F87-932D-1ABA3256F2D5@livingcode.org> Message-ID: <0IMT00EJ271SO100@mta8.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Dethe Elza > As Guido has said, properties don't do anything that couldn't be done > before with __getattr__ and __setattr__, they just give a cleaner > syntax for it. Since VPython makes extensive use of __getattr__ and > __setattr__, do you think you would like the package more or less if > they used properties instead? Or perhaps if instead of (I don't > actually remember if VPython allows named colours, but bear with me > for this example): > > ball = sphere(color=blue) > # a blue sphere appears on the screen > ball.color = 'red' > # the ball changes instantly to red > > would this be better if we wrote: > > ball = sphere(color='blue') > ball.setColor('red') > > does that make it more readable, or less? What are you saying here? ball.color='red' is what is readable. Why is the color attribute of the sphere anything other than a normal Python attribute initialized by a keyword argument, with some default? It is set and retrieved. No magic. Are you suggesting that since normal attribute mechanics use __getattr__ and __setattr__ under the hood, my issue with the use cases of properties are somehow an issue with Python's entire attribute mechanism. If so you have indeed joined the debate, as such ;) If vpython has some implementation specific reason to need to send an e-mail to Mary when I change the color attribute, I may in fact have a preference for the use of __setattr__ directly, as more expressive of the fact that we are under the hood a bit - but that admittedly can get ugly and the truth is I would probably myself opt for the convenience of property, maybe going the whole nine yards and using the further convenience of its decorator form. If I were sending an e-mail to Mary. Art "I didn't get a harrumph out of that guy" Mayor, Blazing Saddles From john.zelle at wartburg.edu Wed Sep 14 16:57:01 2005 From: john.zelle at wartburg.edu (John Zelle) Date: Wed, 14 Sep 2005 09:57:01 -0500 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMT00EJ271SO100@mta8.srv.hcvlny.cv.net> References: <0IMT00EJ271SO100@mta8.srv.hcvlny.cv.net> Message-ID: <43283A3D.4060107@wartburg.edu> Hi All, This has been an interesting and enlightening discussion. I have a bit of knowledge of VPython internals, so I thought I'd jump in here. Arthur wrote: > >>-----Original Message----- >>From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On >>Behalf Of Dethe Elza >>As Guido has said, properties don't do anything that couldn't be done >>before with __getattr__ and __setattr__, they just give a cleaner >>syntax for it. Since VPython makes extensive use of __getattr__ and >>__setattr__, do you think you would like the package more or less if >>they used properties instead? Or perhaps if instead of (I don't >>actually remember if VPython allows named colours, but bear with me >>for this example): >> >>ball = sphere(color=blue) >># a blue sphere appears on the screen >>ball.color = 'red' >># the ball changes instantly to red >> >>would this be better if we wrote: >> >>ball = sphere(color='blue') >>ball.setColor('red') >> >>does that make it more readable, or less? > > > What are you saying here? > > ball.color='red' is what is readable. > > Why is the color attribute of the sphere anything other than a normal Python > attribute initialized by a keyword argument, with some default? It is set > and retrieved. No magic. Actually, there is some magic going on here. Even at the surface level, setting this attribute has the side effect of changing the appearance of the object on screen. The efficient way to make sure that happens is for the setting of the attribute to actually produce the update. In other words, it actually performs a method call. Beneath the surface, VPython is using a compiled C++ module where these attribute accesses are mapped into C++ getter and setter type methods. > > Are you suggesting that since normal attribute mechanics use __getattr__ and > __setattr__ under the hood, my issue with the use cases of properties are > somehow an issue with Python's entire attribute mechanism. > > If so you have indeed joined the debate, as such ;) > > If vpython has some implementation specific reason to need to send an e-mail > to Mary when I change the color attribute, I may in fact have a preference > for the use of __setattr__ directly, as more expressive of the fact that we > are under the hood a bit - but that admittedly can get ugly and the truth is > I would probably myself opt for the convenience of property, maybe going the > whole nine yards and using the further convenience of its decorator form. > I think the point here is that VPython chooses to use the more Pythonic interface allowing the user to "think" about colors (and virtually all other aspects of an visible object) as simple attributes, whereas underneath it is performing method calls. An alternative API would be to simply expose the methods [e.g. mysphere.setColor(color.red)]. In fact, I was first taken aback by VPython's use of what appears to be direct attribute reference. With experience, I have come to appreciate it. The beauty of properties is that it provides an easy and elegant way to provide an attribute-based interface for the client, while allowing the implementer the flexibility to intercept attribute requests through methods. Of course, VPython did this using pre-property techniques. But it's a generally useful thing to do, so making it easy and elegant for the implementer seems to be a rather unambiguous win. Just my $.02 --John -- John M. Zelle, Ph.D. Wartburg College Professor of Computer Science Waverly, IA john.zelle at wartburg.edu (319) 352-8360 From ajsiegel at optonline.net Wed Sep 14 17:21:23 2005 From: ajsiegel at optonline.net (Arthur) Date: Wed, 14 Sep 2005 11:21:23 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMT00EJ271SO100@mta8.srv.hcvlny.cv.net> Message-ID: <0IMT0032PBZS0B10@mta9.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces+ajsiegel=optonline.net at python.org [mailto:edu-sig- > bounces+ajsiegel=optonline.net at python.org] On Behalf Of Arthur > the > whole nine yards and using the further convenience of its decorator form. Oops. Forgot. Can't use @property for a set. Because of course @property is itself in some sense an accident of history. Dying to share all this in Python 101. Art From Scott.Daniels at Acm.Org Wed Sep 14 17:35:57 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Wed, 14 Sep 2005 08:35:57 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <4327895C.1060405@optonline.com> References: <43263E1A.5070804@optonline.com> <43275DE0.6050609@optonline.com> <4327895C.1060405@optonline.com> Message-ID: Arthur wrote: >... But I still don't see the connection to XP programming, API design Do you truly not understand my position, or merely disagree with it? --Scott David Daniels Scott.Daniels at Acm.Org From delza at livingcode.org Wed Sep 14 17:50:43 2005 From: delza at livingcode.org (Dethe Elza) Date: Wed, 14 Sep 2005 08:50:43 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMT0032PBZS0B10@mta9.srv.hcvlny.cv.net> References: <0IMT0032PBZS0B10@mta9.srv.hcvlny.cv.net> Message-ID: Thanks John, you set what I meant. On 14-Sep-05, at 8:21 AM, Arthur wrote: > Oops. Forgot. Can't use @property for a set. Because of course > @property > is itself in some sense an accident of history. Not so much an accident of history: property was never intended as a decorator and probably shouldn't be used as one. If you really want to create a read-only decorator, make a new one called "readonly" or some such. You can still *implement* it with property, of course. > Dying to share all this in Python 101. Not every part of the language needs to fit into an introduction. There are obscure parts of English that not everyone uses day to day, but that doesn't mean I argue with poets who use them. --Dethe "I started with nothing, and I still have most of it." -- Steven Wright From ajsiegel at optonline.net Wed Sep 14 18:58:08 2005 From: ajsiegel at optonline.net (Arthur) Date: Wed, 14 Sep 2005 12:58:08 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <0IMT0030RGHM9Y40@mta9.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Dethe Elza > > Not every part of the language needs to fit into an introduction. > There are obscure parts of English that not everyone uses day to day, > but that doesn't mean I argue with poets who use them. This started with a Triangle class. It has 3 sides, And an area. And I have made the most excellent point about confusing students by not being clear about whether one is explaining mechanics and or illustrating a use case. If you want to see me as a confused student - you're welcome. Art From ajsiegel at optonline.net Wed Sep 14 19:02:42 2005 From: ajsiegel at optonline.net (Arthur) Date: Wed, 14 Sep 2005 13:02:42 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <0IMT00EURGOMT740@mta8.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Scott David Daniels > Arthur wrote: > >... But I still don't see the connection to XP programming, API design > Do you truly not understand my position, or merely disagree with it? > Let's say I don't understand. And as much as people want to believe I relish being off topic, I don't believe I am. I am a confused student - let's say - trying to explain the nature of my confusion. Am I communicating the nature of my confusion in an incomprehensible way. Am I simply not paying attention. Do I not want to learn? Or is there some failure in the communication process for which we need to take joint responsibility? Art From urnerk at qwest.net Thu Sep 15 05:23:07 2005 From: urnerk at qwest.net (Kirby Urner) Date: Wed, 14 Sep 2005 20:23:07 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMT00EJ271SO100@mta8.srv.hcvlny.cv.net> Message-ID: <20050915032313.BD1621E4003@bag.python.org> Art: > I would probably myself opt for the convenience of property, maybe going > the whole nine yards and using the further convenience of its decorator > form. Footnote: Although I think Scott did an admirable job of showing how the property function could be served with the new decorator syntax, I don't think the trade off in convenience is necessarily worth the convoluted helper functions that make this short-cut doable. That being said, I'm quite pleased that Scott spelled it out, and I have in fact used his invention (in subsequent code). In yet more recent code (satacad.py with Vector, Edge and Polyhedron classes), I'm back to straight attr = property(args) syntax, and quite satisfied with it. I feel no strong temptation to use decorators in this context. In sum, I wouldn't necessarily go "the whole nine yards" as you've put it. Kirby From urnerk at qwest.net Thu Sep 15 05:36:55 2005 From: urnerk at qwest.net (Kirby Urner) Date: Wed, 14 Sep 2005 20:36:55 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMT0030RGHM9Y40@mta9.srv.hcvlny.cv.net> Message-ID: <20050915033658.AA80F1E4009@bag.python.org> > This started with a Triangle class. > > It has 3 sides, > It had 3 sides that I made open to rebinding, such that mytri.a = 6 could be used to change the shape of the triangle at run time, ergo its area -- which is why I wanted to see area as both an attribute (makes sense) and a read-only one at that (because rebinding area could mean any number of side combinations -- too impractical for my current needs). > And an area. > The area gets to come off as an attribute, as in mytri.area, but it's triggering a method, cuz my user may have changed one of the sides in the meantime. I don't recompute area until I have to (or my Triangle doesn't, whatever). > And I have made the most excellent point about confusing students by not > being clear about whether one is explaining mechanics and or illustrating > a use case. > I think I was clear: the use case of implementing a Triangle class with modifiable edges drives home the point of syntax like property. And as I mentioned at the time, Alex Martelli gives a similar use case regarding the Rectangle ('Python in a Nutshell'). In both cases, I think the use case gives a good example of why we might want to use such syntax (I'm not saying anything about decorators -- a whole different discussion). If by mechanics you mean syntax (and underlying implementation) then I think here we have geometry providing grist for the CS mill (as you said we should do, and as I agreed we should). Math feeds CS with examples, and CS provides math with machine-executable notations -- a two way street of great pedagogical value. > If you want to see me as a confused student - you're welcome. > > Art I don't see you as confused. But I don't see me as confused either. The examples were clear, the mechanics are clear. All that remains are differences in judgment as to whether this or that other use case merits using the property feature. Sometimes, using properties is as bad an idea as it is a good one, in other contexts, especially in Python, which doesn't penalize so heavily if you decide to change your design later (so don't clutter your code just because "you'll wish you had someday"). Kirby From ajsiegel at optonline.net Thu Sep 15 12:57:40 2005 From: ajsiegel at optonline.net (Arthur) Date: Thu, 15 Sep 2005 06:57:40 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMU00MWTA224035@mta22.srv.hcvlny.cv.net> Message-ID: <0IMU00KCKUGQ4J00@mta8.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > > If you want to see me as a confused student - you're welcome. > > > > Art > > I don't see you as confused. Can't we agree about anything? I'm confused I tell you ;) Scott David's Triangle did *not* use a property for area. I think that was quite purposeful. OTOH, his general explanation for the use case of properties in respect to API design seemed to me to be a perfect defense of the extensive use of a pattern of: @property def getx(self): return self._x @porperty def sety(self,x) self._x =x because while now x is a normal attribute you never know what tomorrow may bring. OTOH, as you point out Alex did use exactly your case of the area of a Triangle to illustrate properties in Nutshell. Was he simply illustrating mechanics or, in so doing, advocating a use case as well? Would we have flatted the area method before properties, through the __getattr__ mechanism. Were properties put into the language to make it more convenient for us to do this kind of thing - *as a way of encouraging this kind of pattern*. I think you - implicated or explicitly - think yes. I think I explicitly think no. John and Dethe point out that when a color attribute in vpython is changed the proverbial e-mail to Mary needs to be sent - rerender. Before properties it was done under the covers, now we have the convenience of properties as an alternative. The unambiguous use case, IMO. John feels the appearance of properties in the language to be an unambiguous win. I would probably agree if I didn't believe it had the side effect of having some of us second-guessing the way they did business pre-properties. I guess I am pleading for constraint in the presentation of properties to novices, with clear *and narrow* use cases. Its part of my campaign for this year's Willison award. I'm think my chances are 50/50, best case ;) Art From ajsiegel at optonline.net Thu Sep 15 14:51:32 2005 From: ajsiegel at optonline.net (Arthur) Date: Thu, 15 Sep 2005 08:51:32 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMU00KCKUGQ4J00@mta8.srv.hcvlny.cv.net> Message-ID: <0IMU0013HZQ1FE00@mta9.srv.hcvlny.cv.net> > -----Original Message----- > From: Arthur [mailto:ajsiegel at optonline.net] > > I'm confused I tell you ;) I think what I am trying to communicate is the fact that folks like me are not really interested in being: "taught how to program" Though we are anxious to be taught how to "program" What could be clearer? Art From john.zelle at wartburg.edu Thu Sep 15 16:20:27 2005 From: john.zelle at wartburg.edu (John Zelle) Date: Thu, 15 Sep 2005 09:20:27 -0500 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMU00KCKUGQ4J00@mta8.srv.hcvlny.cv.net> References: <0IMU00KCKUGQ4J00@mta8.srv.hcvlny.cv.net> Message-ID: <4329832B.4050101@wartburg.edu> Arthur, It often seems to me that I agree with you, but you think that you don't agree with me. This may be one of those cases. Arthur wrote: > >>-----Original Message----- > I'm confused I tell you ;) > > Scott David's Triangle did *not* use a property for area. I think that was > quite purposeful. > > OTOH, his general explanation for the use case of properties in respect to > API design seemed to me to be a perfect defense of the extensive use of a > pattern of: > > @property > def getx(self): > return self._x > > @porperty > def sety(self,x) > self._x =x > > because while now x is a normal attribute you never know what tomorrow may > bring. First up, I don't particularly like the decorator syntax here. However main concern is (in your words) the use cases for properties. No one is arguing that you should use use properties anywhere where normal attribute access suffices. The point is that you can just use the simple attribute access mechanism if that is what you need now. Later on, if your design changes, you can use properties so that the API remains unchanged even though you are now using a method call. Not having to change the API is good in two ways. First, it means that existing clients don't break, and second at preserves the simpler user model of assigning and reading attributes. This second advantage is one that a desginer might choose to use up-front. That is, even when an initial design uses a method call, it might be convenient for users to have an attribute-based API (ala VPython). > > OTOH, as you point out Alex did use exactly your case of the area of a > Triangle to illustrate properties in Nutshell. Was he simply illustrating > mechanics or, in so doing, advocating a use case as well? > > Would we have flatted the area method before properties, through the > __getattr__ mechanism. Were properties put into the language to make it > more convenient for us to do this kind of thing - *as a way of encouraging > this kind of pattern*. I think you - implicated or explicitly - think yes. > I think I explicitly think no. I don't understand how you can say "no" to this. Properties exist precisely to make it simpler to call methods through attribute access syntax, period. My instinct is that, pre-properties, most programmers would not have resorted to the __getattr__ magic for these simple cases; they would just provide a method-call API (as I did for my graphics library). With properties, I would probably now take the other route. > > John and Dethe point out that when a color attribute in vpython is changed > the proverbial e-mail to Mary needs to be sent - rerender. Before > properties it was done under the covers, now we have the convenience of > properties as an alternative. The unambiguous use case, IMO. > > John feels the appearance of properties in the language to be an unambiguous > win. I would probably agree if I didn't believe it had the side effect of > having some of us second-guessing the way they did business pre-properties. > Hmmmm. Are you saying adding something to the language that provides a more elegant way of doing what you were doing before (__getattr__) is a bad thing? Or are you talking about using properties everywhere you used to just do attribute reference? The former I don't understand. The latter I already addressed; don't use a property unless that is what you need. > I guess I am pleading for constraint in the presentation of properties to > novices, with clear *and narrow* use cases. > I can't disagree with this. Beginners don't need properties. Start with attribute reference. It's important to realize that this would be anathema in many OO languages (Smalltalk, Java, C++), but it's OK in Python because it still maintains implementation independence. I used to be able to guarantee this through __getattr__ and friends. Now it's much simpler with properties. > Its part of my campaign for this year's Willison award. I'm think my chances > are 50/50, best case ;) Best of luck to you. -- John M. Zelle, Ph.D. Wartburg College Professor of Computer Science Waverly, IA john.zelle at wartburg.edu (319) 352-8360 From urnerk at qwest.net Thu Sep 15 16:23:34 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 15 Sep 2005 07:23:34 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMU00KCKUGQ4J00@mta8.srv.hcvlny.cv.net> Message-ID: <20050915142336.F3A221E4003@bag.python.org> > > I don't see you as confused. > > Can't we agree about anything? > > I'm confused I tell you ;) > > Scott David's Triangle did *not* use a property for area. I think that was > quite purposeful. > I was referring to my Triangle class in http://mail.python.org/pipermail/edu-sig/2005-August/005063.html (admittedly not my first version). I use properties (for the triangle's angles too), and area is a property (behind which is getArea). I don't use any decorators, though Scott has shown how we might do this by then. I wrote: "It's easy to think of angles and area as attributes, even if we don't allow them to be set except through changes to edges. Why should we force a user to remember what's a method and what's not, given edges, angles and area (could add perimeter too)." > OTOH, his general explanation for the use case of properties in respect to > API design seemed to me to be a perfect defense of the extensive use of a > pattern of: > > @property > def getx(self): > return self._x > > @porperty > def sety(self,x) > self._x =x > > because while now x is a normal attribute you never know what tomorrow may > bring. And I say such defensive programming is unnecessary in Python. You can turn 'x' into a property later, and define new private variable '_x' behind it, if that's what you need to do. Plus there's no setter here, only a getter, so if you wanna go "the whole nine yards" you'll need to go a little further than above. > OTOH, as you point out Alex did use exactly your case of the area of a > Triangle to illustrate properties in Nutshell. Was he simply illustrating > mechanics or, in so doing, advocating a use case as well? > I don't know about "advocating" a use case. He's *presenting* a primitive use case in which making use of the property feature makes sense, is motivated by the circumstances. It's like showing how using the cork screw feature on a Swiss Army knife when you have this bottle of wine and nothing else handy to open it with. Does that mean I advocate drinking a lot of wine? Maybe, but that's not important here. > Would we have flatted the area method before properties, through the > __getattr__ mechanism. Were properties put into the language to make it > more convenient for us to do this kind of thing - *as a way of encouraging > this kind of pattern*. I think you - implicated or explicitly - think > yes. > I think I explicitly think no. > I think using __getattr__ is comparatively more trouble and maybe more trouble than it's worth. The property feature makes such code less cluttery, requires less hackery and I agree with you that this is in line with our definition of 'syntactic sugar': "I think it's fine to call it "syntactic sugar" when we make object attributes call their associated accessors and mutators behind the scenes." (same post as linked above). And although I admire Scott's ability to use decorators in this context (a better idea than my using them to support differentiation ala calculus), I'm not myself motivated to use decorators in this way at this time. > John and Dethe point out that when a color attribute in vpython is changed > the proverbial e-mail to Mary needs to be sent - rerender. Before > properties it was done under the covers, now we have the convenience of > properties as an alternative. The unambiguous use case, IMO. I don't think the Triangle or Rectangle examples are any less ambiguous. Better to not have to install the whole VPython library just to find your first use case, which is implemented in C++ after all (even the color change part). But I do agree this is an unambiguous use case (one of many) -- John was being very apropos in bringing it up. > John feels the appearance of properties in the language to be an > unambiguous > win. I would probably agree if I didn't believe it had the side effect of > having some of us second-guessing the way they did business pre- > properties. > > I guess I am pleading for constraint in the presentation of properties to > novices, with clear *and narrow* use cases. I think that's fine. I generally agree with you that Java throws too much at the novice and gets her into habits of mind *without much justification* and this is unsatisfying to questioning minds. Python starts with *far* less clutter, but the real world rationale for properties (or wine and Swiss Army knives) hasn't gone away. They still turn out to be useful, as do other design patterns the Java books go on about. > Its part of my campaign for this year's Willison award. I'm think my > chances are 50/50, best case ;) > > Art Things we agree on: too much up front clutter is bad, Java has too much up front clutter, CS would do well to import math and geometry as grist for its mill, to illustrate new mechanics based on use cases. Plus I think kids learning math need more Swiss Army knives like Python. Kirby From urnerk at qwest.net Thu Sep 15 16:31:45 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 15 Sep 2005 07:31:45 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMU0013HZQ1FE00@mta9.srv.hcvlny.cv.net> Message-ID: <20050915143148.51DD21E4008@bag.python.org> > I think what I am trying to communicate is the fact that folks like me are > not really interested in being: > > "taught how to program" > > Though we are anxious to be taught how to > > "program" > > What could be clearer? > > Art I think you've made it clear that you don't like to have a lot of unmotivated mechanics thrown at you because "CS says you need them". Unless you've seen the use cases, and are directly motivated by them, you're not one to sit at the feet of CSers and just take their word for it. I like and support your "question authority" attitude. I think it's right for you to *not* take anything on faith alone. And CS shouldn't require you to. It's not that kind of discipline. You: """ That being said, I think in this particular thread about properties, the use cases were there from the beginning. What you came to after that was that it comes down to judgments and possible differences therein: We end up, as Laura says (I think), only able to make judgment calls as to what is and what is not appropriate as to what to expose and what not to expose, depending on what we are trying to accomplish. Judgment calls are to me a-theoretical. I think I understand the basic theory - and reserve to the right to do little more than take it under advisement. """ http://mail.python.org/pipermail/edu-sig/2005-August/005110.html I have no problem with any of the above. Kirby From urnerk at qwest.net Fri Sep 16 00:20:40 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 15 Sep 2005 15:20:40 -0700 Subject: [Edu-sig] Draft math/CS stuff (satacad 6938) In-Reply-To: <20050913234927.8CE971E4002@bag.python.org> Message-ID: <20050915222043.2B78D1E40C8@bag.python.org> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Kirby Urner > Sent: Tuesday, September 13, 2005 4:49 PM > To: edu-sig at python.org > Subject: [Edu-sig] Draft math/CS stuff (satacad 6938) > > > I'd be happy if anyone wants to comment on and/or mess with the code > below. This curriculum segment has now been turned into a web page linked from my CP4E page: http://www.4dsolutions.net/ocn/polys.html Kirby From edusig.20.schellenberg at spamgourmet.com Fri Sep 16 05:28:28 2005 From: edusig.20.schellenberg at spamgourmet.com (edusig.20.schellenberg@spamgourmet.com) Date: Thu, 15 Sep 2005 21:28:28 -0600 Subject: [Edu-sig] pyGame tutor for high school students wanted Message-ID: <42CC168A-0D6A-4731-9F78-018B44859007@gmail.com> Hi there, I am teaching an introduction to computer science at a high school level, and have given my students freedom to choose to create pretty much whatever they would like for a final project in the course. A group of 3 of my obviously keen and talented programmers came up to me wondering whether they could create a simple RPG type game using Python, and I suggested they take a look into pyGame. Now, I don't have any experience with pyGame myself, and so I am looking for someone who would be willing to tutor them via email as they undertake this project from now until the beginning of January. Anyone willing to help along some aspiring computer programmers? Thanks, Dan -- Dan Schellenberg High school computer science/math teacher From ajsiegel at optonline.net Fri Sep 16 06:03:34 2005 From: ajsiegel at optonline.net (Arthur) Date: Fri, 16 Sep 2005 00:03:34 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMV0098ZSZCKKJ0@mta16.srv.hcvlny.cv.net> Message-ID: <0IMW00LD55YAJZ00@mta7.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > > OTOH, his general explanation for the use case of properties in respect > to > > API design seemed to me to be a perfect defense of the extensive use of > a > > pattern of: > > > > @property > > def getx(self): > > return self._x > > > > @porperty > > def sety(self,x) > > self._x =x > > > > because while now x is a normal attribute you never know what tomorrow > may > > bring. > > And I say such defensive programming is unnecessary in Python. You can > turn > 'x' into a property later Yes. John explains this as well. I told you I was confused. But I remain confused to the extent that this - from where I sit - rather obscure and remote situation comes up prominently as a reason properties are so welcome as a builtin function. As I don't think I sit anywhere *that* far off the mainstream of things. As an emergency fix - __getattr_ and __setattr__ would serve as well. "As well" as in also. As well as in "as well as" I guess is open to debate, but I keep thinking we are in obscure corner of things in any case - and having to get there as a use case for properties implies a stretch, and for me, is therefore a source of suspicion. Art From lac at strakt.com Fri Sep 16 10:47:38 2005 From: lac at strakt.com (Laura Creighton) Date: Fri, 16 Sep 2005 10:47:38 +0200 Subject: [Edu-sig] pyGame tutor for high school students wanted Message-ID: <200509160847.j8G8lcqS023972@theraft.strakt.com> I'd try that question on the pygame mailing list, or its gatewayed newsgroup. http://www.pygame.org/info.shtml Laura Creighton From urnerk at qwest.net Fri Sep 16 22:56:10 2005 From: urnerk at qwest.net (Kirby Urner) Date: Fri, 16 Sep 2005 13:56:10 -0700 Subject: [Edu-sig] pyGame tutor for high school students wanted In-Reply-To: <42CC168A-0D6A-4731-9F78-018B44859007@gmail.com> Message-ID: <20050916205612.75DDA1E4004@bag.python.org> Hi Dan -- I doubt it's practical to request any intensive hand-holding regarding a for-school project, or rather, they'd be lucky to get that, especially for free. However, Pygamers tend to be friendly and the documentation is itself something of a tutorial. I managed to code up some presentation management software simply by having the docs open, the API spelled out. After that, it's a lot trial and error and building on past experience. Pygame is good for 2D games, especially puzzling strategy games, less so for rapidly scrolling anything, and if you want to go 3D, I think you're talking about just using Pygame as a front end for PyOpenGL. That's something I'd like to learn myself. I'm envious of the very simple and effective OpenGL examples Ruby ships with, and given how X is moving to that platform, in at least one distro, I feel increasing pressure to figure a Python angle (from a curriculum writer viewpoint), or to jump ship when it comes to OpenGL, maybe just buckle down and learn the Ruby way. In the meantime, we have VPython, which in a lot of ways is better than OpenGL, just because it's so simple. I don't think the full potential of VPython as a gaming engine, at least for small teams of coders, has been tested. It made my hypertoon dream come true, why not these others? My recommendation: have your students work through the Pygame tutorial on their own, and see if it seems like the kind of thing they want to get into more deeply (the tutorial I'm thinking of involves a monkey as I recall, or maybe it's a rocket ship). I'd also recommend you work through it yourself at some point, just so you'll have an approximate understanding of what they're encountering. Pygame is pretty low level. Alternatives exist. Have they looked at GameMaker yet? http://www.gamemaker.nl/ You're the teacher -- doesn't mean you have to know everything (nobody does), just that you demonstrate a strong willingness to learn (the key to being an effective teacher in any field, I should think). CS (including its application in game making) is one of those "always a student" disciplines. Kirby > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of edusig.20.schellenberg at spamgourmet.com > Sent: Thursday, September 15, 2005 8:28 PM > To: edu-sig at python.org > Subject: [Edu-sig] pyGame tutor for high school students wanted > > Hi there, > > I am teaching an introduction to computer science at a high school > level, and have given my students freedom to choose to create pretty > much whatever they would like for a final project in the course. A > group of 3 of my obviously keen and talented programmers came up to > me wondering whether they could create a simple RPG type game using > Python, and I suggested they take a look into pyGame. Now, I don't > have any experience with pyGame myself, and so I am looking for > someone who would be willing to tutor them via email as they > undertake this project from now until the beginning of January. > Anyone willing to help along some aspiring computer programmers? > > Thanks, > Dan > > -- > Dan Schellenberg > High school computer science/math teacher > _______________________________________________ > Edu-sig mailing list > Edu-sig at python.org > http://mail.python.org/mailman/listinfo/edu-sig From ajsiegel at optonline.net Sat Sep 17 23:57:40 2005 From: ajsiegel at optonline.net (Arthur) Date: Sat, 17 Sep 2005 17:57:40 -0400 Subject: [Edu-sig] quantum instance Message-ID: <0IMZ008E1ECBAW00@mta7.srv.hcvlny.cv.net> Me > >> Would we have flatted the area method before properties, through the >> __getattr__ mechanism. Were properties put into the language to make it >> more convenient for us to do this kind of thing - *as a way of >> encouraging this kind of pattern*. I think you - implicated or >> explicitly - think yes. I think I explicitly think no. John > >I don't understand how you can say "no" to this. Properties exist >precisely to make it simpler to call methods through attribute access >syntax, period. My instinct is that, pre-properties, most programmers >would not have resorted to the __getattr__ magic for these simple cases; >they would just provide a method-call API (as I did for my graphics >library). With properties, I would probably now take the other route. And I don't understand how you can't understand that. Sometimes we just disagree, it seems. The version of Python I run - Python 2.4 (#60, Nov 30 2004, 11:49:19) - discourages me from writing extra code for the purpose of revealing less. It comes with no "properties" exception of which I am aware. I guess we all have our own sense of elegance, and the properties discussion leads me to believe that there is more than one version of Python 2.4 (#60, Nov 30 2004, 11:49:19) floating around. Which is as it should be. And as it should be taught it should be, it seems to me. And don't expect that you disagree with *that*. Art From urnerk at qwest.net Sun Sep 18 01:41:14 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sat, 17 Sep 2005 16:41:14 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMZ008E1ECBAW00@mta7.srv.hcvlny.cv.net> Message-ID: <20050917234117.028051E4004@bag.python.org> > The version of Python I run - Python 2.4 (#60, Nov 30 2004, 11:49:19) - > discourages me from writing extra code for the purpose of revealing less. > It comes with no "properties" exception of which I am aware. <<...>> > > Art Hey Art, this is making very little sense to me. All versions of 2.4 should give you 'property' syntax. Just write: >>> class Foo: def __get_duh(self): return "Well, yeah, Duh!" duh = property(__get_duh) >>> obj = Foo() >>> obj.duh 'Well, yeah, Duh!' That's all in my Python 2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)] on win32. Let's not continue until we figure out why this isn't working for you. Kirby From ajsiegel at optonline.net Sun Sep 18 02:25:49 2005 From: ajsiegel at optonline.net (Arthur) Date: Sat, 17 Sep 2005 20:25:49 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMZ003UXJ39WI10@mta11.srv.hcvlny.cv.net> Message-ID: <0IMZ00BE5L75T800@mta7.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Saturday, September 17, 2005 7:41 PM > To: 'Arthur'; edu-sig at python.org > Subject: RE: [Edu-sig] quantum instance > > > Let's not continue until we figure out why this isn't working for you. My version works something like this (though this is admittedly a slightly simplified version): >>If type(attribute)=='set by assignment' _ and (needs(setting) or needs (getting)) =='something unusual': see if property function might help else: forget property function exists Your Python version - from what I can see - works different. Art From urnerk at qwest.net Sun Sep 18 03:06:46 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sat, 17 Sep 2005 18:06:46 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMZ00BE5L75T800@mta7.srv.hcvlny.cv.net> Message-ID: <20050918010648.1C8BC1E4004@bag.python.org> > Your Python version - from what I can see - works different. > > Art OK, fun. My Python version goes more like this: Consider if client Z, inhabitant of knowledge domain X, would tend to think of this object-related foo as a noun or a verb, e.g. without knowing anything about Python or programming, but knowing a lot about heart surgery and its objects, is this something I'd like to send arguments to, or will I just set it or consult it, with no sense that I need to tweak parameters? If verb, define a method, and capture the key arguments in a clear API. If noun, then aim to implement as an attribute from the point of view of the user, but if necessary use methods under the hood, as the knowledge domain's concept of noun versus verb may not precisely match your class designs in Python (cite our Triangle example). Bottom line re properties: Python aims to be accommodating and supply a noun where the object's user is already thinking noun (because of the native knowledge domain). With only a few changes, we could make the client *another programmer* i.e. someone fluent in coding idioms. I want other programmers to appreciate my noun-sense and verb-sense, and so I use properties (or not) to communicate these subtle nuances. No one said Python couldn't be subtle. On the contrary, we call it expressive. Kirby From urnerk at qwest.net Sun Sep 18 05:44:27 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sat, 17 Sep 2005 20:44:27 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <20050918010648.1C8BC1E4004@bag.python.org> Message-ID: <20050918034428.D110D1E4005@bag.python.org> > If verb, define a method, and capture the key arguments in a clear API. > Note: Sometimes a verb might not imply arguments. E.g. myheart.beat() makes sense as a verb if it's supposed to simulate a beat. A rule of thumb might be: if it's a verb, it makes sense to do it over and over, e.g. myheart.beat(10) also makes sense. Verbs are doings. On the other hand, myheart.weight would seem more noun-like, even if it changes over time. I suppose I could just as well think of attributes as adjectives (nouns go with 'state'). Anyway, the more general point is: it's the knowledge domain that should determine the API, and this often means mimicking real world objects -- e.g. trying to be "like" a heart. I don't believe in a philosophy that insists on making it all uniform (e.g. either all attributes or all methods), irrespective of how things are in reality. In my Triangle class, it made sense for sides a,b,c to be come across as attributes, and likewise angles A,B,C. Likewise area and perimeter. But if I rotate it by 45 degrees, that seems like a verb, likewise if I translate or scale it. It's my common sense notion of a triangle, its properties, its capabilities, that drives my API, i.e. it's the knowledge domain, not so much Python. And yes, there's room for judgment and different APIs, depending on who does the programming and who represents the knowledge domain. Kirby From ajsiegel at optonline.net Sun Sep 18 06:25:57 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 18 Sep 2005 00:25:57 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMZ0029CN3A80D0@mta15.srv.hcvlny.cv.net> Message-ID: <0IMZ00I8ZWBET410@mta7.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Saturday, September 17, 2005 9:07 PM > To: 'Arthur'; edu-sig at python.org > Subject: RE: [Edu-sig] quantum instance > > > > Your Python version - from what I can see - works different. > > > > Art > > OK, fun. My Python version goes more like this: > > Consider if client Z, inhabitant of knowledge domain X, would tend to > think > of this object-related foo as a noun or a verb My clients use a version of Python compatible to my own. But have no interest in what I might tend to think they might tend to think. They like information - hard information. Art From urnerk at qwest.net Sun Sep 18 17:41:29 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 18 Sep 2005 08:41:29 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IMZ00I8ZWBET410@mta7.srv.hcvlny.cv.net> Message-ID: <20050918154131.7FFF41E4005@bag.python.org> > My clients use a version of Python compatible to my own. > > But have no interest in what I might tend to think they might tend to > think. > > They like information - hard information. > > Art Yes, well, we all have limited experience, depending to some degree on which clients we work for. I really do work with cardiologists and heart surgeons some. Fortunately for you and me, Python is emerging from the collective experiences of a lot of people, a lot of walks of life, not just from Art's or Kirby's. I'm glad I'm not confined to using your version of Python. Kirby From ajsiegel at optonline.net Sun Sep 18 19:16:35 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 18 Sep 2005 13:16:35 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN0008MHRL5A2R1@mta18.srv.hcvlny.cv.net> Message-ID: <0IN00082HVZSI700@mta9.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Sunday, September 18, 2005 11:41 AM > To: 'Arthur'; edu-sig at python.org > > I'm glad I'm not confined to using your version of Python. As I said, so am my. I have my confidence scale. But as I've said previously -it's *never* 10 out of 10. But I do I think we have no choice but to teach in a way that let's our students know there are competing versions in play. I think *that* with a very high level of confidence. Art From ajsiegel at optonline.net Sun Sep 18 19:37:53 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 18 Sep 2005 13:37:53 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN0008MHRL5A2R1@mta18.srv.hcvlny.cv.net> Message-ID: <0IN000JRBWZ9BF00@mta7.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > > I'm glad I'm not confined to using your version of Python. My other problem is this: Did somebody forgot to mention to me, pre-Python2.2, that the language was missing a fundamental construct for the proper configuration of the proper API framework? And allowed me go about my business of constructing improper API frameworks - because that is what the language supported. Is it the same somebodies who jump at me when I question the new Python who would have jumped at me if I had questioned the old? It often seems so. Is information hiding also part of community building? If so, what is being hidden now? Art I don't believe the above, BTW - as long as I stick to my guns that properties are a minor piece of syntax sugar with a lot being read into their appearance in the lnaguage. And that if Guido was all-seeing he might have anticipated a lot more than intended being read into them. Or else I don't want to believe the above - so I stick to my guns. Art From urnerk at qwest.net Sun Sep 18 22:44:26 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 18 Sep 2005 13:44:26 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN000JRBWZ9BF00@mta7.srv.hcvlny.cv.net> Message-ID: <20050918204429.10A9D1E4005@bag.python.org> > My other problem is this: > > Did somebody forgot to mention to me, pre-Python2.2, that the language was > missing a fundamental construct for the proper configuration of the proper > API framework? Apparently many programmers felt this lack, including Guido, and added the missing capability. To answer your question: yes, no one thought to tell you -- not clear what that'd have accomplished. It's your responsibility to read the PEPs. > And allowed me go about my business of constructing improper API > frameworks - because that is what the language supported. > > Is it the same somebodies who jump at me when I question the new Python > who would have jumped at me if I had questioned the old? It often seems > so. You're free to raise objections at any point along the way, no? Others do, and often in tones less dark and paranoid, which is probably why they sometimes get more attention. I think you effectively self-marginalize by casting yourself as this always-marginalized kibitzer. You're too interested in the soap opera (real or imagined), seem less attentive to real engineering considerations. You seem reluctant to believe that real engineering could be a basis for changes to Python, prefer to invoke images of secret cabals and behind-the-scenes machinations. I chalk this up to personality and temperament. > Is information hiding also part of community building? > > If so, what is being hidden now? > You'd have to be on py-dev or be reading the PEPs to get a sense of what's in the pipeline (maybe you are -- I'm not at the moment, but from time to time dive into the PEPs). I mentioned after Europython about how yield, and hence generators, are getting more features. I think the process whereby Python Enhancement Proposals get submitted and hashed through *is* a vital part of Python-the-community and even Python-the-language, and should be taught, including right from the start, when introducing it to newbies. By design, I don't think edu-sig is the place to hash through the merits of this or that PEP. Other mechanisms have been established. So if you confine your kibitzing to edu-sig, then it's perfectly fine that your objections don't get a lot of attention. This is not the place for them, if their purpose is to influence Python's evolution and direction. On the other hand, I think edu-sig *is* the place to voice pedagogical concerns, i.e. to talk about how we might best teach the language to others. I think you've given us a lot of valuable input along these lines over the years and I'm glad you've been generous with your time. Plus there's Pygeo itself, which showcases the capabilities of Python/VPython pretty effectively -- a great advertisement for why Python is such a valuable asset (including the part about you learning it on your own, having come from another walk of life besides professional programming -- a good story, all the better because true). Kirby From urnerk at qwest.net Sun Sep 18 22:55:13 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 18 Sep 2005 13:55:13 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN00082HVZSI700@mta9.srv.hcvlny.cv.net> Message-ID: <20050918205514.944E31E4037@bag.python.org> > But I do I think we have no choice but to teach in a way that let's our > students know there are competing versions in play. I think *that* with a > very high level of confidence. > > Art Different teachers will inevitably bring their own "spin" to their teaching. I can well imagine a class in which Python is brought up primarily to talk about its deficiencies and inferior qualities e.g. a presentation by some Scheme guy, pissed that the Python community is making inroads in K-12 and anxious to head that off. The background of the teacher matters. John Zelle has taught Java a lot, and brings that experience to bear. At OSCON, I attended a talk on Ruby geared especially to Java programmers, e.g. "this is how you're used to doing it in Java, here's how you might do the same thing in Ruby" (followed by a much shorter piece of code). I don't think it's the obligation of a teacher to accommodate the spins and slants of every other teacher, e.g. I'm happy to teach about the property feature without a hint of your dark warnings about "information hiding" and the like. Let Arthur handle Arthur's spin. Let students drift from one teacher to another, building up their own biases and spins. I think we've already agreed it comes down to judgment. And when it comes to judgments, we may differ. That in itself gives neither of us the right to complain that the other is "discounting" or "ignoring" the other. The right to go with one's own sense of right and wrong is a feature, not a bug. I see no reason to complain if you teach a different version of Python from mine. Kirby From ajsiegel at optonline.net Sun Sep 18 23:33:43 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 18 Sep 2005 17:33:43 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN100FOF5M3PV24@mta23.srv.hcvlny.cv.net> Message-ID: <0IN100EYQ7WCK820@mta6.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Sunday, September 18, 2005 4:44 PM > To: 'Arthur'; edu-sig at python.org > Subject: RE: [Edu-sig] quantum instance > > > My other problem is this: > > > > Did somebody forgot to mention to me, pre-Python2.2, that the language > was > > missing a fundamental construct for the proper configuration of the > proper > > API framework? > > Apparently many programmers felt this lack, including Guido, and added the > missing capability. Can you please support your statement! Guido added properties to the language. No doubt. He says they are about "managed attributes". His example in the original presentation of the use of properties was quite narrow. In fact it was only in referring back to it that I feel I began to get my head on straight about what properties were really intended to be about (IMO). I believe I am interpreting his purpose much more carefully then are you. You feel otherwise. We are in Lit class arguing interpretation, the author's intent. Some authors successfully use ambiguity to their advantage. Perhaps there is a good deal here. But in this milieu I can't believe a straight forward reading of the author's stated intent - which is where I feel I am - is without merit. Maybe the cigar is just a cigar. > To answer your question: yes, no one thought to tell you -- not clear > what > that'd have accomplished. It's your responsibility to read the PEPs. > > > And allowed me go about my business of constructing improper API > > frameworks - because that is what the language supported. > > > > Is it the same somebodies who jump at me when I question the new Python > > who would have jumped at me if I had questioned the old? It often seems > > so. > > You're free to raise objections at any point along the way, no? Others > do, > and often in tones less dark and paranoid, which is probably why they > sometimes get more attention. I am dark and paranoid when I confront what I (rightly or wrongly) interpret as some form of group think. There are reasons for it. Apologies. Art From urnerk at qwest.net Mon Sep 19 01:45:21 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 18 Sep 2005 16:45:21 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN100EYQ7WCK820@mta6.srv.hcvlny.cv.net> Message-ID: <20050918234524.652D11E4005@bag.python.org> > > Apparently many programmers felt this lack, including Guido, and added > > the missing capability. > > Can you please support your statement! > The fact that it was added isn't evidence programmers wanted it added? > Guido added properties to the language. No doubt. He says they are about > "managed attributes". His example in the original presentation of the use > of properties was quite narrow. In fact it was only in referring back to > it that I feel I began to get my head on straight about what properties > were really intended to be about (IMO). > > I believe I am interpreting his purpose much more carefully then are you. > > You feel otherwise. The whole idea of attributes managed through setters and getters (mutators) is a known design pattern. SmallTalk wouldn't even allow direct assignment to attributes, right? *All* access to variables is "managed." Setters and getters are built into C# as well, at the syntax level. Not because of Python though. We're talking about a feature of the OO model that's been around for awhile. Python acquired this feature later in its development, but not out of the blue. Like many features in Python, you can point to their precedents in other languages. List comprehensions from Haskell, generators from Icon... (correct me if I'm wrong). Many programmers wouldn't need to closely study Guido's examples to show what properties are good for; it'd was already a tool in their tool chest, in other languages (or in Python using __setattr__ and __getattr__ -- less convenient). You come to OO through Python and all of a sudden it acquires one of these new (to you) features. To you, it seems like something alien is creeping in, perhaps against some deep-seated philosophy that you've come to respect. You worry something valuable is being undermined. These developments seem sinister, all about "information hiding" or whatever. But to someone else, a long-time OO coder (who maybe started in SmallTalk) the reaction is more like "about time, what took you so long?" > We are in Lit class arguing interpretation, the author's intent. Some > authors successfully use ambiguity to their advantage. Perhaps there is a > good deal here. But in this milieu I can't believe a straight forward > reading of the author's stated intent - which is where I feel I am - is > without merit. > > Maybe the cigar is just a cigar. > Kinda cryptic. I think people are being quite up front about what properties are good for, why other programming languages besides Python manage access to attributes (e.g. to protect private variables from direct exposure through the API). Python could get along nicely without 'em at first, sure, but adding a property method was a small price to pay for a valuable feature programmers have come to expect within the OO paradigm. What's so hard to understand here? > I am dark and paranoid when I confront what I (rightly or wrongly) > interpret as some form of group think. There are reasons for it. > Apologies. > > Art What's wrong with "group think"? I know we're supposed to reflexively dislike the sound of that, but when a community reaches a consensus, based on professional history and prior experience, must it always be wrong? I feel the explanations put forward for why the property feature was added have made plenty of sense. You seem to reject them on the basis of: well if *I* Arthur didn't need them, how come anyone else should? I felt the same way about Guido's change to the division operator. In the new design, a/b will always be a float, a//b always an integer -- much better, and not a politically motivated cave-in to newbies learning VPython (the dark motive you always persisted in reading in). Perhaps my version of Python is evolving at a faster rate, and in different directions, than you necessarily need in your version, for what you're trying to do. What's the harm in that, as long as your code still runs? Kirby From ajsiegel at optonline.net Mon Sep 19 02:47:20 2005 From: ajsiegel at optonline.net (Arthur) Date: Sun, 18 Sep 2005 20:47:20 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN100GSYDZNG7B0@mta21.srv.hcvlny.cv.net> Message-ID: <0IN100M9GGV3W900@mta6.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Sunday, September 18, 2005 7:45 PM > To: 'Arthur'; edu-sig at python.org > Subject: RE: [Edu-sig] quantum instance > > > > Apparently many programmers felt this lack, including Guido, and added > > > the missing capability. > > > > Can you please support your statement! > > > > The fact that it was added isn't evidence programmers wanted it added? Though not necessarily for the purposes you seem to suppose. > > > Guido added properties to the language. No doubt. He says they are about > > "managed attributes". His example in the original presentation of the > use > > of properties was quite narrow. In fact it was only in referring back to > > it that I feel I began to get my head on straight about what properties > > were really intended to be about (IMO). > > > > I believe I am interpreting his purpose much more carefully then are > you. > > > > You feel otherwise. > > The whole idea of attributes managed through setters and getters > (mutators) > is a known design pattern. SmallTalk wouldn't even allow direct > assignment > to attributes, right? *All* access to variables is "managed." > Setters and getters are built into C# as well, at the syntax level. Not > because of Python though. We're talking about a feature of the OO model > that's been around for awhile. Python acquired this feature later in its > development, but not out of the blue. Python is not Java or C# or Smalltalk. I know - because if it were I wouldn't be programming in it. > What's wrong with "group think"? I know we're supposed to reflexively > dislike the sound of that, but when a community reaches a consensus, based > on professional history and prior experience, must it always be wrong? > > I feel the explanations put forward for why the property feature was added > have made plenty of sense. I have heard 3 or 4 explanations. And don't see much logical connection between them. It sometimes appears that community ethos is to work backward form the fact that it is there, to the knowing explanation for why its good its there. My only objection to it being there - in fact - is the lack of consensus as to the compelling reason it is necessary. There seems to be agreement, in fact, on only this one aspect of the reason for its presence as a built_in function. The fact that the reason is compelling. Whatever the hell it is. Art From urnerk at qwest.net Mon Sep 19 03:43:24 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sun, 18 Sep 2005 18:43:24 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN100M9GGV3W900@mta6.srv.hcvlny.cv.net> Message-ID: <20050919014327.D6C8F1E4005@bag.python.org> > Whatever the hell it is. > > Art > As you wish. However I'm going to resist the temptation (won't be suckered into?) restating the rationale(s). Sometimes "persuading Arthur" is just too much work -- and to what end? Besides, your version of Python doesn't have these features, so what's the problem? Kirby From john.zelle at wartburg.edu Mon Sep 19 05:02:39 2005 From: john.zelle at wartburg.edu (John Zelle) Date: Sun, 18 Sep 2005 22:02:39 -0500 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN100M9GGV3W900@mta6.srv.hcvlny.cv.net> References: <0IN100M9GGV3W900@mta6.srv.hcvlny.cv.net> Message-ID: <432E2A4F.6030401@wartburg.edu> Arthur wrote: > > My only objection to it being there - in fact - is the lack of consensus as > to the compelling reason it is necessary. There seems to be agreement, in > fact, on only this one aspect of the reason for its presence as a built_in > function. The fact that the reason is compelling. > I thought we already agreed that properties are a _convenience_. We could already do everything that properties give us using __getattr__ and friends. The _convenience_ was added because many people find it useful. You seem to be saying that having multiple good reasons for a feature is an argument against its inclusion! Most of us consider multiple justifications evidence of a compelling feature. To extend the argument in your direction: I _can_ do everything I _need_ to do in C++, Java, or even assembler. I choose to use Python exactly because it makes the things I need to do _more convenient_ to accomplish. Mind you, I have managed quite well in Python without properties. Now that I have them, I will use them. Furthermore, because it allows me to do something I feel is useful in a simpler way, I will probably use them more often than I used __getattr__ magic before. That is, the benefit I derive (attribute access syntax with implementation independence) is now offset by an even smaller overhead cost (code complexity). Plus my code is more transparent, a double win. And it in no way affects how you have to write your code, so that argument that you don't want to do things the "Java way" (or any other way) is a complete strawman. I still have not read an argument that the property feature itself is in _any_ way a bad thing. Only your claim that some people may like them for reasons that differ from Guido's (and even that is open to interpretation--I happen to view Guido's use-case and the implementation-independence use-case as one and the same). Hence I stand by my previous conclusion that properties are an unambiguously Good Thing (tm). > Whatever the hell it is. "It" is convenience. Convenience is the compelling argument. I guess I'll have to accept your offering the we simply disagree here. My only misgiving is that I still don't know exactly what we're disagreeing about. But we've probably already spent more time and effort than this particular disagreement was worth. -- John M. Zelle, Ph.D. Wartburg College Professor of Computer Science Waverly, IA john.zelle at wartburg.edu (319) 352-8360 From ajsiegel at optonline.net Mon Sep 19 07:04:18 2005 From: ajsiegel at optonline.net (Arthur) Date: Mon, 19 Sep 2005 01:04:18 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <432E2A4F.6030401@wartburg.edu> Message-ID: <0IN1007H0SRBU400@mta6.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of John Zelle > Sent: Sunday, September 18, 2005 11:03 PM > To: edu-sig at python.org > Subject: Re: [Edu-sig] quantum instance > > > > Arthur wrote: > > > > > My only objection to it being there - in fact - is the lack of consensus > as > > to the compelling reason it is necessary. There seems to be agreement, > in > > fact, on only this one aspect of the reason for its presence as a > built_in > > function. The fact that the reason is compelling. > > > > I thought we already agreed that properties are a _convenience_. John had written - """ Properties exist precisely to make it simpler to call methods through attribute access syntax, period. My instinct is that, pre-properties, most programmers would not have resorted to the __getattr__ magic for these simple cases; they would just provide a method-call API (as I did for my graphics library). With properties, I would probably now take the other route. """ Properties - which were meant as a *mere convenience* - seem here to be influencing an outcome. To me, a not insignificant outcome. Not what one thinks of when one thinks of mere convenience. Kirby believes - is "adamantly" too strong - that properties were added to the language just so as to influence this kind of outcome. To bring Python more in line with generally accepted OOP thinking and practice. That is not an unreasonable thing to believe when one considers the name of the function, the general milieu of the influence of the leading languages such as Java and C#. I happen not, however, to believe it. Perhaps because I don't want to. My thought is that it is highly preferable - except in highly unusual circumstances - to call methods through method call syntax and to access attributes through attribute access syntax. For reasons that are only obvious - we know better whether we are accessing something akin to a stored value or, in contrast, calling for something akin to a calculation of a value. Which is information. Information is good. Knowing that there is authority in OOP theory that appears to be directly contrary to my preference here. And not caring a whole lot. The question is: Is the inclusion of properties into Python in fact to any extent as Kirby (and you, I think) seem to interpret it - an implicit vote on this matter? That is the essential question I have been trying to pursue - not whether it is more or less convenient. It is more. But its cost is the extent to which it influences outcomes in unintended directions. If it was intended to influence toward greater use of the technique of calling methods through attribute access syntax, it is an unambiguous win. Because it - witness your statement above - undoubtedly does. If one believes - as do I - that there was no such intention, then the addition of properties has suffered from the fate of having unintended consequences. And in that sense cannot be viewed as an unambiguous win. Art From lac at strakt.com Mon Sep 19 12:21:28 2005 From: lac at strakt.com (Laura Creighton) Date: Mon, 19 Sep 2005 12:21:28 +0200 Subject: [Edu-sig] quantum instance In-Reply-To: Message from "Kirby Urner" of "Sun, 18 Sep 2005 16:45:21 PDT." <20050918234524.652D11E4005@bag.python.org> References: <20050918234524.652D11E4005@bag.python.org> Message-ID: <200509191021.j8JALS1D006856@theraft.strakt.com> In a message of Sun, 18 Sep 2005 16:45:21 PDT, "Kirby Urner" writes: >Perhaps my version of Python is evolving at a faster rate, and in differe >nt >directions, than you necessarily need in your version, for what you're >trying to do. What's the harm in that, as long as your code still runs? > >Kirby There is enormous potential harm in this. The problem is that programming is not an individual activity. When new features make code harder to read, or harder to understand, then readers are penalised at the expense of writers. When bugs are easier to make, or harder to detect when reading code, then everybody suffers. This is terrible for the productivity of a company. Once your company is beyond a certain size -- the exact number is subject to debate, and it varies depending on what language you use -- and once your codebase is beyond a certain size, you will find that you spend far, far, far more time _reading_ code than _writing_ it. The more senior you are, the worse this is, and managers often end up writing little or no code at all. This means that any productivity gains you get when you add {feature} which makes it easier to write code X has to be weighed against the productivity losses when you have to read {feature}. Since readers outnumber writers, there comes a point where no feature should be added that produces less-readable code, on the grounds of productivity gains to the code-writers alone. Remember, the productivity of a company is not driven by the speed at which your coders can write new code. Instead it is the speed at which they can understand the codebase, and the ease in which they can make modifications to it, and how bug-free those modifications are that matter. So if your new feature makes the code harder to read, it had better make certain bugs harder to make, or certain modifications easier to make in a bug free way, or have some other benefit. Some languages have developed the way they have precisely because they have persued some other benefit to the exclusion of all else. C++ sacrifices readability for speed. This was a fine trade for those people who absolutely must have the speed. But as CPUs got faster, people found their companies were more productive using something else. If you have worked commercially, then you will already be familiar with this situation. 'I don't have time to understand this code, I will just rewrite it instead'. This happens all the time. Writing is easy. Understanding is hard. But every time this happens, there is an indication that something is seriously wrong in your company. The fact that it is wrong in everybody else's company too is no excuse, just a sad commentary on the state of the art. Was the original code too poorly written? poorly documented? Is the new programmer too lazy to read the code? Too unskilled at reading code? Is the old code obscure but really damn excellent at something important, and the new version inferior? Will it cause subtle bugs? What about the reabability of the new version? Next week will somebody come along, not understand _it_ either, and reinvent the wheel a third time? Sometimes the problem is with the language itself. Take Perl. I never bother, any more, trying to deeply understand what any Perl script I find is doing. I just rewrite it in Python. I will never have any confidence in my ability to 'understand' what an arbitrary Perl script does. I've been wrong too often. One of the sad things about life as a commercial programmer is that often only the most junior programmers get to write code all day. This is because somebody else has come and given them the specs and told them what to write. Everybody else has to figure out what to write and where to write it, which requires being familiar with the code base, which requires reading it regularly, which takes time. This means that the coolest in new features, those meant to be used _sparingly_ fall directly into the hands of those who do not have the maturity and experience to know when not to use them. With predictable results. :-) This means come code review time, you have to waste a whole bunch of time explaining to your junior people why they need to rewrite their code to not use this feature. This makes code review a lot more painful and acrimonious than it was. And it is difficult on the reviewer. What do you say when you are only 65% convinced that this is a poor use of {feature}? Especially when what you want to say amounts to 'my XX years of experience in the field say that this is too cutesy?' Your junior programmers may only conclude from this that you are an senile old fart. You may conclude that they lack the wisdom that God gave green apples. Age-based splits in your company are among the hardest things to combat and sap morale and team building. Pair programming will not work unless there is mutual respect. In general, the greater the difference between 'your best people' and 'your worst people' the harder productivity suffers. If the language is hard to use, you may find out that only your top people provide positive value to the company. Your worst people subtract value. Not only do the things they write have to be rewritten, but everybody wastes time on bugs they caused, and talking to them with their problems and so on and so forth. I once managed a project that was late, and the only way we found to fix it was to take the 6 worst people on the team and send them to the other side of the country to take 3 weeks of training in some damn thing that wasn't even relevant to what our company did -- I forget what. Then everybody else got the job done. But those 6 people didn't learn much about how to be productive. What they really needed was training in UI design and how to use C++ without screwing up so much. But Andrew Koenig hadn't written _C++ Traps and Pitfalls_ yet, http://www.accu.org/bookreviews/public/reviews/c/c002114.htm so we couldn't give them a course based on it. And so it goes. Some languages have grown so much that only experts can be productive with it. What's more, even after you have your own company in shape, with nobody abusing the new features any more, you still have to interface with code written by people who do not work for your company. And they may not have as strict a set of standards as you do. If the innappropriate use of a new feature makes for buggy code, then you may be forced to not use some package that over-uses the feature despite its attractiveness in other ways. And you have absolutely no control over these people. Even deciding whether to use somebody else's code requires reading it. If the code is hard to read, you may find that you do not have the time. Obscure language features can make 'spot the poorly written code' game a lot harder. What you need is a way to quickly tell if the code you are reading is good or not. For my own peace of mind, I have decided that 'anybody who over-uses language feature X as much as those guys do is statistically unlikely to be up to anything good' - but I know as well as anybody that 'statistically unlikely' is not the same thing as 'never'. What opportunities are being missed? It is the tragedy of the commons all over again. Code-writers have the interest and motivation to add every feature they dream up into the languages they create, in the same way that sheep-owners have the interest and motivation to overgraze the commons. Laura From lac at strakt.com Mon Sep 19 15:44:05 2005 From: lac at strakt.com (Laura Creighton) Date: Mon, 19 Sep 2005 15:44:05 +0200 Subject: [Edu-sig] quantum instance In-Reply-To: Message from Laura Creighton of "Mon, 19 Sep 2005 12:21:28 +0200." <200509191021.j8JALS1D006856@theraft.strakt.com> References: <20050918234524.652D11E4005@bag.python.org> <200509191021.j8JALS1D006856@theraft.strakt.com> Message-ID: <200509191344.j8JDi5UK016671@theraft.strakt.com> In a message of Mon, 19 Sep 2005 12:21:28 +0200, Laura Creighton wrote: I just want to mention that I like properties. I think they make the code easier to read. I've read too much code where people who wanted the behaviour of properties got out __getattr__ and did it wrong. Or decided that some hideous thing using metaclasses was the way to go. Or that using __slots__ to restrict access was a fine idea. So I think that code readability has improved. My problem with properties is some of the people who use them. There is a class of people who go around compulsively adding restrictions, wherever they go, whenver they cannot think of a reason not to. It makes them feel 'safer' or 'more professional' or something. Unfortunately, this desire to over-control everything frequently shows up in people who have no more imagination than a turnip. This is a bad combination. Laura From urnerk at qwest.net Mon Sep 19 18:18:44 2005 From: urnerk at qwest.net (Kirby Urner) Date: Mon, 19 Sep 2005 09:18:44 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN1007H0SRBU400@mta6.srv.hcvlny.cv.net> Message-ID: <20050919161847.B17B61E4002@bag.python.org> Arthur: > My thought is that it is highly preferable - except in highly unusual > circumstances - to call methods through method call syntax and to access > attributes through attribute access syntax. For reasons that are only > obvious - we know better whether we are accessing something akin to a > stored value or, in contrast, calling for something akin to a calculation > of a value. Which is information. Information is good. And this is what I *don't* believe. I think it's preferable to make mytri.A (angle A) come across as an attribute, not a method call, even if I use a method call to compute it on the fly. I want to be able to express user intuitions about what's a method and what's an attribute drawing from a knowledge domain. I don't want to instruct a user in how Python must necessarily force a different view. If the user wants to know whether a method is being invoked, the user should just look at my source code (I think open source is highly preferable). > Is the inclusion of properties into Python in fact to any extent as Kirby > (and you, I think) seem to interpret it - an implicit vote on this matter? > Sure. A lot of us think properties are a good idea. *Every* feature added to Python may be seen as an implicit "vote" although the precise process whereby features get added is a little different from simple polling. > But its cost is the extent to which it influences outcomes in unintended > directions. If it was intended to influence toward greater use of the > technique of calling methods through attribute access syntax, it is an > unambiguous win. Because it - witness your statement above - undoubtedly > does. > Yes, an unambiguous win. Using attribute syntax to invoke methods is a good thing in some circumstances (they don't even have to be "unusual" circumstances). I think you're misplacing your distrust. If the source code is not available at all, that's one issue. There're lots of ways to hide information in that case, including back doors, trap doors, whatever. But properties are not about hiding the source. Properties are about making the control panel more rational and stable from a user's point of view (where the user may be oneself or another programmer). > If one believes - as do I - that there was no such intention, then the > addition of properties has suffered from the fate of having unintended > consequences. And in that sense cannot be viewed as an unambiguous win. > > Art I believe encouraging the use of attribute syntax to invoke methods behind the scenes is synonymous with managed access to class internals. It's what OO is encouraging and what Python is encouraging. I don't subscribe to your philosophy that we should avoid doing this. I do it, and will continue to do it, without apology. Kirby From urnerk at qwest.net Mon Sep 19 18:26:28 2005 From: urnerk at qwest.net (Kirby Urner) Date: Mon, 19 Sep 2005 09:26:28 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <200509191021.j8JALS1D006856@theraft.strakt.com> Message-ID: <20050919162630.26B1F1E4002@bag.python.org> > >Perhaps my version of Python is evolving at a faster rate, and in > >different directions, than you necessarily need in your version, > >for what you're trying to do. What's the harm in that, as long > >as your code still runs? > > > >Kirby > Laura: > There is enormous potential harm in this. The problem is that > programming is not an individual activity. When new features make > code harder to read, or harder to understand, then readers are > penalised at the expense of writers. When bugs are easier to make, > or harder to detect when reading code, then everybody suffers. Yes, that's true of course. You make a lot of good points. In the case of property syntax, I think as you do, that it adds clarity to the code. It also encourages a practice Arthur doesn't like, and I have no problem with that, as I don't think Arthur's distrust is well founded in this case. But it *is* possible for a language to make wrong turns, and even though old code still runs, the new features encourage a lot of bad habits and in general contribute to the unreadability of the code. Python *could* take these turns for the worse. Feature creep/bloat might eat away from its integrity from within. I was being too glib. And again, I have no problem encouraging the use of attribute syntax to invoke methods if that's what makes an API easier to use and maintain. We saw how that works in VPython (C++/color), how it works in a triangle, how it might work in any number of not-that-unusual circumstances. Arthur thinks maybe this practice lacks integrity but I think he's just projecting from some other knowledge domain he's been exposed to. I refuse to be swayed by his sense of aesthetics in this case. Kirby From ajsiegel at optonline.net Mon Sep 19 20:04:02 2005 From: ajsiegel at optonline.net (ajsiegel@optonline.net) Date: Mon, 19 Sep 2005 14:04:02 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN20058MNZJP451@mta28.srv.hcvlny.cv.net> References: <0IN1007H0SRBU400@mta6.srv.hcvlny.cv.net> <0IN20058MNZJP451@mta28.srv.hcvlny.cv.net> Message-ID: ----- Original Message ----- From: Kirby Urner Date: Monday, September 19, 2005 12:18 pm Subject: RE: [Edu-sig] quantum instance > I want to be able to express user intuitions about what's a method and > what's an attribute drawing from a knowledge domain. I don't want to > instruct a user in how Python must necessarily force a different view. Working with, rather than against, others' misaligned intuitions is the anti-thesis of the scientific spirit. You don't propose that there is no meaningful distinction between methods and attributes. You might be able to con me into believeing *that*, at least. ;) Instead you acknowledge the distinction but are consciously using the power to shuffle appearances to appease and re-enforce intuitions that happen to be wrong. I have to suppose that a intepretation of computer science that seems to support that approach is a misreading of the science. I am a great believer in the proposition that in the end, Reality wins. Put properties away in your use case, and you have no choice but to transcend the users' misaligned intuitions, and align with reality. I don't for a moment believe that can be harmful to your scientists/users. All of which is besides the point. Please stop implying that you have some insight that Python is encouraging you toward this approach. It's slander - as far as I am concerned. Art From urnerk at qwest.net Mon Sep 19 20:58:27 2005 From: urnerk at qwest.net (Kirby Urner) Date: Mon, 19 Sep 2005 11:58:27 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <20050919185827.F03891E4002@bag.python.org> > Working with, rather than against, others' misaligned intuitions is > the anti-thesis of the scientific spirit. > Which is maybe why I'm working against your misaligned intuitions. ;-D > You don't propose that there is no meaningful distinction between > methods and attributes. > > You might be able to con me into believeing *that*, at least. ;) > > Instead you acknowledge the distinction but are consciously > using the power to shuffle appearances to appease and re-enforce > intuitions that happen to be wrong. > No, the knowledge domain isn't "wrong" when it thinks of angles A,B,C as *attributes* of a triangle, or myaccount.balance as an *attribute* of my bank account -- even if there're SQL lookups or cosine calculations going on behind the scenes. How a particular programming language needs to work to satisfy a use case needn't trump the basic intuitions of the user. You want to "educate" your user about what you had to do in Python. I say the user shouldn't have to care about that. Python is a servant, a tool, not a dictator. I don't give a rats ass what hoops you needed to jump through to make 'weight' an attribute of my heart object, not a method. As the client cardiologist, I'm telling you what I want the API to look like -- or I'll get a more competent programmer. You don't want to acknowledge that verb-sense and noun-sense are prior to any programming language (part of ordinary thinking). The whole idea of OO is we're modeling object-worlds [1], trying to make our code meet the expectations of users who may *already have* a refined understanding of their own discipline (gasp!). We're here to learn from clients, and do our best to mirror their expectations, not second-guess them at every turn. You seem temperamentally incapable of adopting this attitude. > I have to suppose that a intepretation of computer science that > seems to support that approach is a misreading of the science. > > I am a great believer in the proposition that in the end, Reality wins. Python isn't "reality". It's a modeling tool. Programmers and programming languages are about helping scientists and others get work done, not educating them about what a Python callable is, vs. an attribute. How your objection sounds to me: "how can you in good faith make humans look *that big* on a movie screen? -- humans really aren't that huge, nor are they flat." You seem to deny that it's OK to model, to represent, to use any special effects. Artists use perspective to give the illusion of depth on a flat surface -- is that somehow anti-scientific in your book? Properties are an "illusion" in the same sense. They're about mirroring expectations -- *legitimate* expectations. Likewise with the whole OO apparatus of classes and objects -- the cues come from reality, but the implementation (in the form of a computer language) is merely a representation (we hope a nuanced and expressive one). > Put properties away in your use case, and you have no choice but to > transcend the users' misaligned intuitions, and align with reality. > I don't for a moment believe that can be harmful to your > scientists/users. > I do. You're arrogantly putting Python front and center, thinking it defines "reality" in some sense, over and above what your client learned in medical school, banking school or whatever. *Ask* them what's a verb and what's a noun, don't *tell* them. Python shouldn't get in their way. > All of which is besides the point. > > Please stop implying that you have some insight that Python is > encouraging you toward this approach. > > It's slander - as far as I am concerned. > > Art You were the one suggesting Python was (inadvertently?) encouraging the use of attribute syntax to trigger methods. I'm agreeing with you, it does, and it should -- and it's not inadvertent. Bottom line: We're trying to paint it as *they* see it. This is not pandering. It's working with professionals who know their own jobs -- yet may know nothing much about programming. Kirby [1] for more re 'object worlds', see 'Designing Engineers (Inside Technology) by Louis L. Bucciarelli (MIT Press, 1996). http://www.amazon.com/exec/obidos/tg/detail/-/0262522128/ From ajsiegel at optonline.net Mon Sep 19 21:46:45 2005 From: ajsiegel at optonline.net (ajsiegel@optonline.net) Date: Mon, 19 Sep 2005 15:46:45 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN200JH6VDEEE72@mta30.srv.hcvlny.cv.net> References: <0IN200JH6VDEEE72@mta30.srv.hcvlny.cv.net> Message-ID: ----- Original Message ----- From: Kirby Urner Subject: RE: [Edu-sig] quantum instance > How a particular programming language needs to work to satisfy a > use case > needn't trump the basic intuitions of the user. You want to have your intuition as to someone else's intuition control - in a scientific setting. We are at unscience**2 - before we get started. The closest thing to reality we might have to grasp unto is the grammar of the language in which we are choosing to converse. I would urge you to go with that. I will, in any case. In part at the urging of *my* version of Python. 2.4 Art From urnerk at qwest.net Mon Sep 19 22:08:57 2005 From: urnerk at qwest.net (Kirby Urner) Date: Mon, 19 Sep 2005 13:08:57 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <20050919200859.1C35A1E400E@bag.python.org> > You want to have your intuition as to someone else's intuition control - > in a scientific setting. We are at unscience**2 - before we get started. > No, we're having a meeting of the minds, me and the client. I go through iterations of the API, and the client lets me know if I'm on the right track. You make it sound like it's all guess work. It ain't. In financial planning, isn't it a good idea to ask the client what his or her goals might be, his or her sense of what's an ethical investment, other questions? This is what I'd want in a financial planner. Client-centric consulting, we might call it. Basic good sense, and already a popular business model. Contract programmers aren't *totally* clueless. > The closest thing to reality we might have to grasp unto > is the grammar of the language in which we are choosing to converse. > Which *isn't* Python. I've been in hours and hours of meetings with clients and haven't had to force them into learning how to use my tools (Visual FoxPro, Python, whatever). My job is to learn as much of the knowledge domain as needed to meet my clients' legitimate expectations as already competent professionals. If my client wants to learn more programming in the process, fine, but that's somewhat optional. And if/when I need a heart operation (god forbid), I don't need to know about all the surgeon's tricks of the trade, when it comes to keeping me alive. > I would urge you to go with that. > > I will, in any case. > > In part at the urging of *my* version of Python. > > 2.4 > > Art I'll pass on taking your advice. I've been a contract programmer for several decades, much longer than you have. I think that counts for something. Kirby From delza at livingcode.org Mon Sep 19 23:17:52 2005 From: delza at livingcode.org (Dethe Elza) Date: Mon, 19 Sep 2005 14:17:52 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <20050918204429.10A9D1E4005@bag.python.org> References: <20050918204429.10A9D1E4005@bag.python.org> Message-ID: <2E0154D6-07A0-482E-A949-535B42890A2E@livingcode.org> On 18-Sep-05, at 1:44 PM, Kirby Urner wrote: > You'd have to be on py-dev or be reading the PEPs to get a sense of > what's > in the pipeline (maybe you are -- I'm not at the moment, but from > time to > time dive into the PEPs). I mentioned after Europython about how > yield, and > hence generators, are getting more features. Or read "What's New in Python 2.X" that Andrew Kuchling writes for every release. Here is the 2.4 version: http://docs.python.org/whatsnew/whatsnew24.html And here is the "in-development" 2.5 version: http://python.org/dev/doc/devel/whatsnew/whatsnew25.html --Dethe "No lesson seems to be so deeply inculcated by experience of life as that you should never trust experts. If you believe doctors, nothing is wholesome; if you believe theologians, nothing is innocent; if you believe soldiers, nothing is safe." --Lord Salisbury, 19th century British prime minister From delza at livingcode.org Mon Sep 19 23:26:12 2005 From: delza at livingcode.org (Dethe Elza) Date: Mon, 19 Sep 2005 14:26:12 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <20050919162630.26B1F1E4002@bag.python.org> References: <20050919162630.26B1F1E4002@bag.python.org> Message-ID: <3F57915A-BD1C-48BB-839A-EE2FC6FCDEE6@livingcode.org> On 19-Sep-05, at 9:26 AM, Kirby Urner wrote: > We saw how that works in VPython (C++/color), how it works in a > triangle, > how it might work in any number of not-that-unusual circumstances. I thought I had written an example using PyGame, but I don't see it now. Perhaps it was when I was having trouble with my mail last month. In any case, one more usecase for properties, related to Kirby's triangle example, is PyGame's Rect. A Rect has the following properties, all modifiable, and setting any of them will update any related properties: * top * bottom * left * right * topleft * topright * bottomleft * bottomright * midleft * midright * midtop * midbottom * center * centerx * centery * size * width * height Certainly these are merely conveniences which could be replaced with just left,top,width,height (or various other combinations). However, in a game you are likely to need a substantial subset of these in the course of the game, and having easy accessors like this makes the code vastly more readable than strewing if (sprite.left + sprite.width) > some_offset: when what you mean is if sprite.right > some_offset: For what it's worth --Dethe A good engineer is a person who makes a design that works with as few original ideas as possible. --Freeman Dyson From ajsiegel at optonline.net Tue Sep 20 11:38:12 2005 From: ajsiegel at optonline.net (Arthur) Date: Tue, 20 Sep 2005 05:38:12 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN200CXEYMXIWY0@mta13.srv.hcvlny.cv.net> Message-ID: <0IN400N2Q0410H00@mta8.srv.hcvlny.cv.net> > -----Original Message----- > From: Kirby Urner [mailto:urnerk at qwest.net] > Sent: Monday, September 19, 2005 4:09 PM > To: ajsiegel at optonline.net > Cc: edu-sig at python.org; 'John Zelle' > Subject: RE: [Edu-sig] quantum instance > > > You want to have your intuition as to someone else's intuition control - > > in a scientific setting. We are at unscience**2 - before we get > started. > > > > No, we're having a meeting of the minds, me and the client. I go through > iterations of the API, and the client lets me know if I'm on the right > track. You make it sound like it's all guess work. It ain't. Of course you are not representing that you are talking about an actual Python Application Programmers Interface that you have written for actual surgeons who intend to use it - in reality - as an Application Programmers Interface. You are talking about something else, applying a few decorators to a few property functions, which then entitle you to talk about it as if you were - in reality. Speculating along those lines of course makes me an obnoxious bastard - but we already knew that. Art From urnerk at qwest.net Tue Sep 20 18:34:38 2005 From: urnerk at qwest.net (Kirby Urner) Date: Tue, 20 Sep 2005 09:34:38 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN400N2Q0410H00@mta8.srv.hcvlny.cv.net> Message-ID: <20050920163443.835DE1E4095@bag.python.org> > Speculating along those lines of course makes me an obnoxious bastard - > but we already knew that. > > Art > No you're right of course. I was conflating a lot of experience into a story about me and the heart surgeons, but at some expense in realism. More realistically, the point of contact between my "world of code" and the knowledge domain of cardiology is the event-driven GUI -- that's what we focus on and iteratively rework. I've had my GUIs running in operating rooms (e.g. CORIS), but these days they mostly run on back office desks at Regional Heart Data Services (less stressful for me, plus I don't have to change clothing just to get access to the site). The low level methods vs. attributes thing is more within the object world of programmers coding for other programmers. As a FoxPro programmer, I get to interact with library objects through APIs. FontBold is an attribute of a text field and is either true or false. In code: thisform.text1.FontBold = .T. (not a method call). DateFormat is another attribute (not a method call) and accepts values 1-14 (e.g. 7 is described as 'Japan' and formats a date as yy/mm/dd). When I change an attribute at design time, I'll often see immediate changes in the form I'm designing. My change to a property triggers methods in the underlying GUI that is the FoxPro IDE itself -- a very typical use case, replicated throughout the programming world (e.g. in VPython). Given I'm trying to help math teachers integrate programming into their new math/CS hybrid course materials, the use of Python properties is more explicit when I'm doing my flavor of Pythonic mathematics. That's where you'll find myvector.length triggering _get_length() behind the scenes.[1] Your idea that an API should carry information about the underlying mechanisms, at the expense of mirroring expectations inherent in the user's knowledge domain, is wrongheaded. OO is all about modeling object worlds, meeting user expectations (where users may be other programmers), and Python's property feature is one standard tool for achieving this. Meeting user expectations is neither anti-scientific nor pandering -- it's the job of a competent programmer, including when coding for other programmers. Your objections against having attribute syntax trigger setters and getters, couched in some sanctimonious rhetoric about "reality" and the badness of "information hiding" comes across on my end as bogus, poorly thought out, reflective of your inexperience and apparently weak grasp of what OO programming is all about. From my point of view, you simply don't know what you're talking about. I'm in no way persuaded that you have some special insight into what the property feature is "really" intended to provide, based on some supposedly close reading of Guido's examples. It's there for the same reason it's in other OO languages, to help coders build and maintain APIs that make sense to their users. Kirby [1] e.g. http://www.4dsolutions.net/ocn/polys.html From ajsiegel at optonline.net Tue Sep 20 19:48:11 2005 From: ajsiegel at optonline.net (ajsiegel@optonline.net) Date: Tue, 20 Sep 2005 13:48:11 -0400 Subject: [Edu-sig] quantum instance In-Reply-To: <0IN400JLNJDU9590@mta13.srv.hcvlny.cv.net> References: <0IN400N2Q0410H00@mta8.srv.hcvlny.cv.net> <0IN400JLNJDU9590@mta13.srv.hcvlny.cv.net> Message-ID: ----- Original Message ----- From: Kirby Urner Date: Tuesday, September 20, 2005 12:34 pm Subject: RE: [Edu-sig] quantum instance > > I'm in no way persuaded that you have some special insight into > what the > property feature is "really" intended to provide, based on some > supposedlyclose reading of Guido's examples. It's there for the > same reason it's in > other OO languages, to help coders build and maintain APIs that > make sense > to their users. You win. But only in the sense that you get the last word. Even *I'm* tired of the thread. Let's move on. Art From urnerk at qwest.net Wed Sep 21 01:21:11 2005 From: urnerk at qwest.net (Kirby Urner) Date: Tue, 20 Sep 2005 16:21:11 -0700 Subject: [Edu-sig] quantum instance In-Reply-To: Message-ID: <20050920232113.0E9571E4002@bag.python.org> > You win. > > But only in the sense that you get the last word. > Got it. I'll keep in mind you've not changed your position. Kirby From urnerk at qwest.net Wed Sep 21 01:58:32 2005 From: urnerk at qwest.net (Kirby Urner) Date: Tue, 20 Sep 2005 16:58:32 -0700 Subject: [Edu-sig] Brute force solutions Message-ID: <20050920235835.6CF331E4002@bag.python.org> Per my 'Pentagon math' thread, I think the golden ratio (phi) is an important one to explore in K-12.[1] It's one of those key nodes in our curriculum network. Given a regular pentagon, the ratio of a diagonal to an edge is phi. In other words, that famous pentacle pattern is phi-edged, vis-?-vis a containing pentagon of edges 1.[2] Although we have many closed form algebraic methods for deriving phi, computers give us this power to solve through brute force. Some may frown on using such "mindless methods" but I'm thinking to go ahead and introduce them -- not exclusively, but as an exhibit along the way. In the Python function below, we're looking for a way to break a line of unit length into two segments, the shorter 'a' and the longer 'b', such that the ratio b:a is as close as feasible to the ratio of the whole to b (1:b). We move 'a' to the right by tiny increments, and keep track of which value minimizes the difference between these two ratios: >>> def findphi(step = 0.01): """ step -> -----|---------- (a+b)=1 a b Lengthen a stepwise, while testing how closely b/a approaches 1/b, and return b/a for the least difference. """ diff = b = 1.0 a = phi = 0 while a < b: a += step b = 1 - a e = abs(b/a - 1/b) if e < diff: phi = b/a diff = e return phi >>> findphi(0.000001) 1.6180340658818939 Some lessons that might be learned from this approach: (1) when working with floats, you want to compare differences, not check for equalities, e.g. looking for when b/a == 1/b would be a bad idea. (2) you get greater accuracy in exchange for more cycles (3) visualization helps The last point is especially important. The code itself says nothing about lines. The diagram is what explains the logic behind the algorithm -- which is why it's included right in the comments, as primitive ASCII art (bad form, or a good idea?). Kirby [1] http://mathforum.org/kb/message.jspa?messageID=3867841&tstart=0 [2] http://altreligion.about.com/library/glossary/symbols/bldefswiccasymbols.htm PS: happy birthday Dawn Wicca (9/20/2005) From david at handysoftware.com Wed Sep 21 15:33:29 2005 From: david at handysoftware.com (David Handy) Date: Wed, 21 Sep 2005 09:33:29 -0400 Subject: [Edu-sig] Brute force solutions Message-ID: <20050921133329.GA11320@arno2> I'm sorry, but I couldn't help taking Kirby's findphi() function as a personal challenge. At the cost of roughly doubling the complexity of the code (19 lines instead of ten lines in the function body), I was able to improve the performance by a factor of more than 6500, while basically still using the same "brute-force" approach of guessing a number, adjusting the guess by a delta, and noticing which number gets the lowest error. Why bother optimizing, when phi is a constant? Because using my approach, you can add two digits more precision to the answer with less than 30% more time, whereas the original approach would cost 100x (10000% as much) time for 2 more digits of precision. This refines Kirby's statement that "you get greater accuracy for more cycles" - it doesn't have to be a linear trade-off. (Yes, I know the original version wasn't claimed to be optimized, but it was crying to be optimized...) # phi.py def findphi(step = 0.01): """ step -> -----|---------- (a+b)=1 a b Lengthen a stepwise, while testing how closely b/a approaches 1/b, and return b/a for the least difference. """ diff = b = 1.0 a = phi = 0 while a < b: a += step b = 1 - a e = abs(b/a - 1/b) if e < diff: phi = b/a diff = e return phi def findphi2(tolerance=0.01): a = tolerance N = 8.0 step = (0.5 - a) / N last_e = INFINITY = 1e+30 while True: b = 1.0 - a e = abs(b/a - 1/b) if e < tolerance: break if e > last_e: a -= 2.0 * step # tricky! must go back 2 steps if a < tolerance: a = tolerance step /= N last_e = INFINITY else: a = a + step last_e = e return b / a def test(): import timeit print "Slow method -- result:", findphi(0.000001), n = 10 timer1 = timeit.Timer(stmt='findphi(0.000001)', setup='from phi import findphi') t1 = timer1.timeit(number=n) print "time:", t1/n, "seconds" print "Faster method -- result:", findphi2(0.000001), timer2 = timeit.Timer(stmt='findphi2(0.000001)', setup='from phi import findphi2') n = 1000 t2 = timer2.timeit(number=n) print "time:", t2/n, "seconds" print "2 digits more precision -- result:", findphi2(0.00000001), timer2 = timeit.Timer(stmt='findphi2(0.00000001)', setup='from phi import findphi2') n = 1000 t2 = timer2.timeit(number=n) print "time:", t2/n, "seconds" if __name__ == '__main__': test() # end-of-file david at arno2:~$ python phi.py Slow method -- result: 1.61803406588 time: 0.755390405655 seconds Faster method -- result: 1.6180333003 time: 0.000112377882004 seconds 2 digits more precision -- result: 1.61803398295 time: 0.000145354032516 seconds david at arno2:~$ python -c "print 0.755390405655/0.000112377882004" 6721.87793705 On Tue, Sep 20, 2005 at 04:58:32PM -0700, Kirby Urner wrote: > > Per my 'Pentagon math' thread, I think the golden ratio (phi) is an > important one to explore in K-12.[1] It's one of those key nodes in our > curriculum network. > > Given a regular pentagon, the ratio of a diagonal to an edge is phi. In > other words, that famous pentacle pattern is phi-edged, vis-?-vis a > containing pentagon of edges 1.[2] > > Although we have many closed form algebraic methods for deriving phi, > computers give us this power to solve through brute force. Some may frown > on using such "mindless methods" but I'm thinking to go ahead and introduce > them -- not exclusively, but as an exhibit along the way. > > In the Python function below, we're looking for a way to break a line of > unit length into two segments, the shorter 'a' and the longer 'b', such that > the ratio b:a is as close as feasible to the ratio of the whole to b (1:b). > > > We move 'a' to the right by tiny increments, and keep track of which value > minimizes the difference between these two ratios: > > >>> def findphi(step = 0.01): > """ > step > -> > -----|---------- (a+b)=1 > a b > > Lengthen a stepwise, while testing how closely > b/a approaches 1/b, and return b/a for the least > difference. > """ > diff = b = 1.0 > a = phi = 0 > while a < b: > a += step > b = 1 - a > e = abs(b/a - 1/b) > if e < diff: > phi = b/a > diff = e > return phi > > >>> findphi(0.000001) > 1.6180340658818939 > > Some lessons that might be learned from this approach: > > (1) when working with floats, you want to compare differences, not check for > equalities, e.g. looking for when b/a == 1/b would be a bad idea. > > (2) you get greater accuracy in exchange for more cycles > > (3) visualization helps > > The last point is especially important. The code itself says nothing about > lines. The diagram is what explains the logic behind the algorithm -- which > is why it's included right in the comments, as primitive ASCII art (bad > form, or a good idea?). > > Kirby > > [1] > http://mathforum.org/kb/message.jspa?messageID=3867841&tstart=0 > > [2] > http://altreligion.about.com/library/glossary/symbols/bldefswiccasymbols.htm > > PS: happy birthday Dawn Wicca (9/20/2005) > > > _______________________________________________ > Edu-sig mailing list > Edu-sig at python.org > http://mail.python.org/mailman/listinfo/edu-sig > -- David Handy Computer Programming is Fun! Beginning Computer Programming with Python http://www.handysoftware.com/cpif/ ----- End forwarded message ----- -- David Handy Computer Programming is Fun! Beginning Computer Programming with Python http://www.handysoftware.com/cpif/ From urnerk at qwest.net Wed Sep 21 18:31:41 2005 From: urnerk at qwest.net (Kirby Urner) Date: Wed, 21 Sep 2005 09:31:41 -0700 Subject: [Edu-sig] Brute force solutions In-Reply-To: <20050921133329.GA11320@arno2> Message-ID: <20050921163144.C11AA1E4003@bag.python.org> > (Yes, I know the original version wasn't claimed to be optimized, but it > was crying to be optimized...) > Yes. This is a valuable addition to the thread. Thanks for taking the time. Reminds me of when Tim Peters used to swing by in the early days of edu-sig and optimize the hell out of my algorithms. I just agreed to teach Python to 8th graders for 9 weeks (one session per week) in my daughter's school, starting in November. There's a good chance I'll be using this phi stuff. Mine original draft makes sense to set the stage, cuz the reasoning is so dang primitive. Yours adds a layer of sophistication more reflective of how real world programmers learn to squeeze the most out of their cycles. Of course all of this requires temporarily ignoring the fact that algebraic methods give us a way to compute phi as simply (1 + math.sqrt(5))/2.0. Kirby From peter at mapledesign.co.uk Wed Sep 21 19:44:01 2005 From: peter at mapledesign.co.uk (Peter Bowyer) Date: Wed, 21 Sep 2005 18:44:01 +0100 Subject: [Edu-sig] Brute force solutions In-Reply-To: <20050921133329.GA11320@arno2> References: <20050921133329.GA11320@arno2> Message-ID: <6.2.3.4.0.20050921184304.038cb6f8@127.0.0.1> At 14:33 21/09/2005, you wrote: >At the cost of roughly doubling the complexity of the code (19 lines instead >of ten lines in the function body), I was able to improve the performance by >a factor of more than 6500, while basically still using the same >"brute-force" approach of guessing a number, adjusting the guess by a delta, >and noticing which number gets the lowest error. Psyco also makes a very noticeable difference: Without: Slow method -- result: 1.61803406588 time: 1.40232660855 seconds Faster method -- result: 1.6180333003 time: 0.000200135212716 seconds 2 digits more precision -- result: 1.61803398295 time: 0.000242882824493 seconds With psyco.full() Slow method -- result: 1.61803406588 time: 0.256314531595 seconds Faster method -- result: 1.6180333003 time: 3.65800681372e-005 seconds 2 digits more precision -- result: 1.61803398295 time: 4.53755994128e-005 second -- Maple Design - quality web design and programming http://www.mapledesign.co.uk From david at handysoftware.com Wed Sep 21 20:39:05 2005 From: david at handysoftware.com (David Handy) Date: Wed, 21 Sep 2005 14:39:05 -0400 Subject: [Edu-sig] Brute force solutions In-Reply-To: <6.2.3.4.0.20050921184304.038cb6f8@127.0.0.1> References: <20050921133329.GA11320@arno2> <6.2.3.4.0.20050921184304.038cb6f8@127.0.0.1> Message-ID: <20050921183905.GD11740@arno2> On Wed, Sep 21, 2005 at 06:44:01PM +0100, Peter Bowyer wrote: > At 14:33 21/09/2005, you wrote: > >At the cost of roughly doubling the complexity of the code (19 lines instead > >of ten lines in the function body), I was able to improve the performance by > >a factor of more than 6500, while basically still using the same > >"brute-force" approach of guessing a number, adjusting the guess by a delta, > >and noticing which number gets the lowest error. > > Psyco also makes a very noticeable difference: > > Without: > Slow method -- result: 1.61803406588 time: 1.40232660855 seconds > Faster method -- result: 1.6180333003 time: 0.000200135212716 seconds > 2 digits more precision -- result: 1.61803398295 time: > 0.000242882824493 seconds > > With psyco.full() > Slow method -- result: 1.61803406588 time: 0.256314531595 seconds > Faster method -- result: 1.6180333003 time: 3.65800681372e-005 seconds > 2 digits more precision -- result: 1.61803398295 time: > 4.53755994128e-005 second Thanks for bringing up Psyco. This is an example of something Psyco can speed up, with about a 5.5x improvement for both my algorithm and Kirby's. However, it doesn't change the fact that original agorithm doesn't scale well. Try 12 digits of precision instead of 6: Slow method -- result: 1.61803406588 time: 0.753984212875 seconds Faster method -- result: 1.6180333003 time: 0.000110749006271 seconds 2 digits more precision -- result: 1.61803398295 time: 0.000144357919693 seconds 6 digits more precision -- result: 1.61803398875 time: 0.000229076862335 seconds 6 more digits of precision takes the optimized algorithm only 2x more time. With the original algorithm, 6 digits more precision takes 1000000x more time. Even with Psyco, it would take about three days to calculate phi to 12 decimal places on your machine. -- David Handy Computer Programming is Fun! Beginning Computer Programming with Python http://www.handysoftware.com/cpif/ From david at handysoftware.com Wed Sep 21 20:47:55 2005 From: david at handysoftware.com (David Handy) Date: Wed, 21 Sep 2005 14:47:55 -0400 Subject: [Edu-sig] Brute force solutions In-Reply-To: <200509211631.j8LGVhdh008876@handysoftware.com> References: <20050921133329.GA11320@arno2> <200509211631.j8LGVhdh008876@handysoftware.com> Message-ID: <20050921184755.GF11740@arno2> On Wed, Sep 21, 2005 at 09:31:41AM -0700, Kirby Urner wrote: > Mine original draft makes sense to set the stage, cuz the reasoning is so > dang primitive. Yours adds a layer of sophistication more reflective of how > real world programmers learn to squeeze the most out of their cycles. Your original draft was a great baseline. That's one good reason not to prematurely optimize: it makes you look like a hero when you optimize later. :) > > Of course all of this requires temporarily ignoring the fact that algebraic > methods give us a way to compute phi as simply (1 + math.sqrt(5))/2.0. The technique is generally useful to solve any equation of one variable, given: 1. You have an interval in which the solution lies 2. You have an error function that is monotonically increasing over the interval the further you get from the solution (and goes to zero at the solution) I think exposing students to numerical equation solving using Python can give them an understanding that will help them later when they are trying to, i.e. figure out how to solve a problem with their fancy caculator, spreadsheet functions, etc. > > Kirby > > -- David Handy Computer Programming is Fun! Beginning Computer Programming with Python http://www.handysoftware.com/cpif/ From john.zelle at wartburg.edu Wed Sep 21 23:52:23 2005 From: john.zelle at wartburg.edu (John Zelle) Date: Wed, 21 Sep 2005 16:52:23 -0500 Subject: [Edu-sig] Brute force solutions In-Reply-To: <20050921184755.GF11740@arno2> References: <20050921133329.GA11320@arno2> <200509211631.j8LGVhdh008876@handysoftware.com> <20050921184755.GF11740@arno2> Message-ID: <4331D617.1090503@wartburg.edu> David Handy wrote: > On Wed, Sep 21, 2005 at 09:31:41AM -0700, Kirby Urner wrote: > >>Mine original draft makes sense to set the stage, cuz the reasoning is so >>dang primitive. Yours adds a layer of sophistication more reflective of how >>real world programmers learn to squeeze the most out of their cycles. > > > Your original draft was a great baseline. That's one good reason not to > prematurely optimize: it makes you look like a hero when you optimize > later. :) > > >>Of course all of this requires temporarily ignoring the fact that algebraic >>methods give us a way to compute phi as simply (1 + math.sqrt(5))/2.0. > > > The technique is generally useful to solve any equation of one variable, > given: > > 1. You have an interval in which the solution lies > 2. You have an error function that is monotonically increasing over the > interval the further you get from the solution (and goes to zero at the > solution) > If you have the sign of the error, you can also make use of simple bisection (aka binary search). Here's a version: def findphi3(tolerance=0.01): low = 0.0 high = 1.0 while True: a = (low + high)/2.0 b = 1.0-a e = b/a - 1/b if abs(e) < tolerance: break if e > 0: low = a else: high = a return b/a Which turns out to be a bit more efficient than the adaptive stepsize version in this case: Slow method -- result: 1.61803406588 time: 0.756837797165 seconds Faster method -- result: 1.6180333003 time: 0.000106906890869 seconds Bisection -- result: 1.61803328419 time: 3.86953353882e-05 seconds > I think exposing students to numerical equation solving using Python can > give them an understanding that will help them later when they are trying > to, i.e. figure out how to solve a problem with their fancy caculator, > spreadsheet functions, etc. > > >>Kirby >> >> > > -- John M. Zelle, Ph.D. Wartburg College Professor of Computer Science Waverly, IA john.zelle at wartburg.edu (319) 352-8360 From john.zelle at wartburg.edu Thu Sep 22 15:31:48 2005 From: john.zelle at wartburg.edu (John Zelle) Date: Thu, 22 Sep 2005 08:31:48 -0500 Subject: [Edu-sig] Brute force solutions In-Reply-To: <20050921184755.GF11740@arno2> References: <20050921133329.GA11320@arno2> <200509211631.j8LGVhdh008876@handysoftware.com> <20050921184755.GF11740@arno2> Message-ID: <4332B244.8030203@wartburg.edu> > On Wed, Sep 21, 2005 at 09:31:41AM -0700, Kirby Urner wrote: > >Of course all of this requires temporarily ignoring the fact that algebraic >methods give us a way to compute phi as simply (1 + math.sqrt(5))/2.0. I've been considering this a bit. The closed form here begs the question, what is math.sqrt(5)? Sure, we have a built-in function that computes this, but someone had to write the algorithm that computes sqrt. That calculation makes use of numerical techniques similar to what we are discussing w.r.t. phi (much more efficient ones, of course). In a sense, you could view your discussion as a look under the hood at possible implementations. In fact, I would think a good problem to tackle in a math class is to develop some algorithms for approximating square roots. Various "guess and check" techniques can be successful. Newton's method is vary good, and can easily be "derived"/motivated without actually looking at any of the calculus. --John -- John M. Zelle, Ph.D. Wartburg College Professor of Computer Science Waverly, IA john.zelle at wartburg.edu (319) 352-8360 From dajoy at openworldlearning.org Thu Sep 22 16:06:48 2005 From: dajoy at openworldlearning.org (Daniel Ajoy) Date: Thu, 22 Sep 2005 09:06:48 -0500 Subject: [Edu-sig] Brute force solutions In-Reply-To: Message-ID: <43327428.3642.D84AC21@localhost> On 22 Sep 2005 at 12:00, (Kirby Urner) wrote: > > Some lessons that might be learned from this approach: > > > > (1) when working with floats, you want to compare differences, not check for > > equalities, e.g. looking for when b/a == 1/b would be a bad idea. > > > > (2) you get greater accuracy in exchange for more cycles > > > > (3) visualization helps My approach to teaching about phi is by asking kids to draw construction #78 http://mondragon.angeltowns.net/paradiso/Construcciones.html Daniel ***************************** OpenWorld Learning http://www.openworldlearning.org From ajsiegel at optonline.net Thu Sep 22 17:00:44 2005 From: ajsiegel at optonline.net (Arthur) Date: Thu, 22 Sep 2005 11:00:44 -0400 Subject: [Edu-sig] Brute force solutions In-Reply-To: <43327428.3642.D84AC21@localhost> Message-ID: <0IN800F4A4DIPN00@mta6.srv.hcvlny.cv.net> > -----Original Message----- > From: edu-sig-bounces at python.org [mailto:edu-sig-bounces at python.org] On > Behalf Of Daniel Ajoy > Sent: Thursday, September 22, 2005 10:07 AM > To: edu-sig at python.org > Subject: Re: [Edu-sig] Brute force solutions > > My approach to teaching about phi is by asking kids to draw > construction #78 > > http://mondragon.angeltowns.net/paradiso/Construcciones.html That would be more my approach as well. My learning theory - yes I am repeating myself - is that it is absolutely disorienting and ineffective to loose all sense of history when approaching these things. It is great to get to the algorithmics, but we can't get there effectively by skipping over 30 centuries of history. Start by drawing pictures in the sand. But certainly don't stop there. And there comes appoint when there are no pictures in the sand to be drawn. The necessary pictures became too complex. Mathematicians - 17th century, say - began drawing the pictures in their head. But they were in fact still drawing pictures. With computers we can begin to draw those pictures, and better pick their brains. That's essentially what PyGeo is about. Art From urnerk at qwest.net Thu Sep 22 17:15:37 2005 From: urnerk at qwest.net (Kirby Urner) Date: Thu, 22 Sep 2005 08:15:37 -0700 Subject: [Edu-sig] Brute force solutions In-Reply-To: <4332B244.8030203@wartburg.edu> Message-ID: <20050922151540.4240F1E4003@bag.python.org> > I've been considering this a bit. The closed form here begs the > question, what is math.sqrt(5)? Sure, we have a built-in function that > computes this, but someone had to write the algorithm that computes > sqrt. That calculation makes use of numerical techniques similar to what > we are discussing w.r.t. phi (much more efficient ones, of course). > Good point. A mathematician gets around this with a certain philosophy of language that says "if I just write sqrt(5) -- using a surd -- that's already infinitely precise." Then he gets to look down his nose at those imprecise computer people who traffic in floating point evaluations. Those floating point people don't have the benefit of "real numbers." > In a sense, you could view your discussion as a look under the hood at > possible implementations. In fact, I would think a good problem to > tackle in a math class is to develop some algorithms for approximating > square roots. Various "guess and check" techniques can be successful. > Newton's method is vary good, and can easily be "derived"/motivated > without actually looking at any of the calculus. > > --John I've a couple times implemented the old manual algorithm for finding square roots. I might be able to dig those up for discussion. The longer it runs, the more digits you get. Kirby From urnerk at qwest.net Sat Sep 24 09:28:31 2005 From: urnerk at qwest.net (Kirby Urner) Date: Sat, 24 Sep 2005 00:28:31 -0700 Subject: [Edu-sig] Brute force solutions Message-ID: <20050924072834.786961E4004@bag.python.org> > I've a couple times implemented the old manual algorithm for finding > square roots. I might be able to dig those up for discussion. The longer > it runs, the more digits you get. > > Kirby But instead, this steaming unoptimized octopus of a code specimen spits back the repeating digits for any positive integer, as needed to generate the ongoing continued fraction, for said integer's square root. def sqrtcf(n): orig = n denom = 1 addterm = 0 cflist = [] while True: m = int(pow(n,0.5)) # <-- replace with function call cflist.append(m) if len(cflist)>1 and denom == 1: break addterm = -(addterm - m*denom) denom = (orig - addterm**2)/denom n = ((pow(orig,0.5) + addterm)/denom)**2 return cflist IDLE 1.1 >>> from gonzo import sqrtcf >>> sqrtcf(19) [4, 2, 1, 3, 1, 2, 8] >>> sqrtcf(13) [3, 1, 1, 1, 1, 6] >>> sqrtcf(2) [1, 2] What's especially inelegant is that it uses pow, whereas with some Zelle-style numeric method, we could compute successive m's with more primitive primitives (e.g. Newton's method). Then we'd have a bona fide square root generator that didn't use any built-in square root generator. The only remaining piece is to feed the repeating lists, e.g. [4, 2, 1, 3, 1, 2, 8] in the case of sqrt(19), to a continued fraction evaluator. I've recently shared a recursive one, based on building a rational number class and using its objects. However, a non-recursive cf algorithm exists, as Tim Peters mentioned way early in the archives of edu-sig (we played with it then, if memory serves). So.... (a) To get the square root of integer N, write a Zelle-style optimized approximater to get the biggest m = integer sqrt of N (i.e. m**2 < N < (m+1)**2). (b) call this in an implementation of the algorithm at this web page (with lots of check data): http://www.mcs.surrey.ac.uk/Personal/R.Knott/Fibonacci/cfINTRO.html (the algebraic algorithm). (c) use the returned list to feed a continued fractions evaluator. The fun part here is we can use numerator/denominator syntax with open-ended precision integers, to like express sqrt of 19 as some humongous fraction (as many digits as memory will allow). This lets us far surpass the floating point barrier. This is *not* a super-efficient way of getting 2nd roots, just a way that meanders through a lot of interesting math (continued fractions have a lot of cool features). Math through programming, we call it. Kirby From urnerk at qwest.net Sun Sep 25 00:03:27 2005 From: urnerk at qwest.net (urnerk@qwest.net) Date: Sat, 24 Sep 2005 18:03:27 -0400 Subject: [Edu-sig] Brute force solutions Message-ID: <380-22005962422327743@M2W043.mail2web.com> >The fun part here is we can use numerator/denominator syntax with open-ended >precision integers, to like express sqrt of 19 as some humongous fraction >(as many digits as memory will allow). This lets us far surpass the >floating point barrier. For example, the sqrt of 19 is rougly: 745969084203762918506900171 6630770611758990188906918072 4013315460866431392624885605 5112125808098871177881508095 4010864598095 ---------------------------- 1711370448973571545640915466 3001505416992487326376156603 4301985589644920244770721090 4993017822174818974832607428 966608330904 (that's a numerator over a denominator). Here's the code behind it (still need to replace int(pow(x,0.5)) with a numerical method that doesn't do all the work to find an actual floating point sqrt -- overkill): """ gonzo.py """ from mathteach import cf2 # http://www.4dsolutions.net/ocn/python/mathteach.py def sqrtcf(n): orig = n denom = 1 addterm = 0 cflist = [] while True: m = int(pow(n,0.5)) # <-- replace with function call cflist.append(m) if len(cflist)>1 and denom == 1: break addterm = -(addterm - m*denom) denom = (orig - addterm**2)/denom n = ((pow(orig,0.5) + addterm)/denom)**2 return cflist def getsqrt(n,default=30): thelist = sqrtcf(n) while len(thelist)>> from gonzo import getsqrt >>> getsqrt(19) ... Kirby _______________________ Edu-sig mailing list Edu-sig at python.org http://mail.python.org/mailman/listinfo/edu-sig -------------------------------------------------------------------- mail2web - Check your email from the web at http://mail2web.com/ . From urnerk at qwest.net Sun Sep 25 00:24:58 2005 From: urnerk at qwest.net (urnerk@qwest.net) Date: Sat, 24 Sep 2005 18:24:58 -0400 Subject: [Edu-sig] Brute force solutions Message-ID: <380-220059624222458915@M2W033.mail2web.com> > n = ((pow(orig,0.5) + addterm)/denom)**2 Hmmmm, this may be the Achilles heal of my project, to not use any sqrt finder in the process of finding a sqrt using continued fractions. Back to the drawing board? Kirby -------------------------------------------------------------------- mail2web - Check your email from the web at http://mail2web.com/ . From Scott.Daniels at Acm.Org Sun Sep 25 02:54:58 2005 From: Scott.Daniels at Acm.Org (Scott David Daniels) Date: Sat, 24 Sep 2005 17:54:58 -0700 Subject: [Edu-sig] Brute force solutions In-Reply-To: <380-22005962422327743@M2W043.mail2web.com> References: <380-22005962422327743@M2W043.mail2web.com> Message-ID: urnerk at qwest.net wrote: >>The fun part here is we can use numerator/denominator syntax with > > open-ended > >>precision integers, to like express sqrt of 19 as some humongous fraction >>(as many digits as memory will allow). This lets us far surpass the >>floating point barrier. OK, here we go: def test_sqrt(numerator, denominator, trial): '''True iff trial (a num,den pair) over-estimates the sqrt(n/d)''' root_n, root_d = trial # return numerator / denominator >= root_n ** 2 / root_d ** 2 return root_d ** 2 * numerator >= root_n ** 2 * denominator # since we don't have 2.5 yet, here's a version of partial: def partial(function, *args): '''Simple no-kwargs version of partial''' def andthen(*final_args): return function(*(args + final_args)) return andthen def farey_trials(tester): '''Binary search for fraction. value must be between 0 and +Inf tester((num, den)) returns True if fract is high, False if Low ''' low_n, low_d = low = 0, 1 # 0/1 = 0 .. high_n, high_d = high = 1, 0 # 1/0 = Infinity while True: mediant_n = low_n + high_n mediant_d = low_d + high_d mediant = mediant_n, mediant_d yield mediant if tester(mediant): low_n, low_d = low = mediant else: high_n, high_d = high = mediant # Now here is a cute reporter that relies on another trick: # n & -n == n only if n is either 0 or a power of 2. for n, fraction in enumerate(farey_trials(partial(test_sqrt, 19, 1))): if n & -n == n: # report increasingly rarely print n, fraction if n > 4096: break -- Scott David Daniels Scott.Daniels at Acm.Org