From da@ski.org Sat Mar 6 04:57:48 1999 From: da@ski.org (David Ascher) Date: Fri, 5 Mar 1999 20:57:48 -0800 (Pacific Standard Time) Subject: [Tutor] test - ignore Message-ID: please ignore this test. From da@ski.org Mon Mar 8 04:36:39 1999 From: da@ski.org (David Ascher) Date: Sun, 7 Mar 1999 20:36:39 -0800 (Pacific Standard Time) Subject: [Tutor] Welcome Message-ID: Welcome all -- I'm pleased -- the list has been created about two days ago, and it has over two dozen subscribers. I know many of the email addresses of the subscribers, which means that there are at least a few 'old-timers' around, and there are also others which are new to me, which is great -- hopefully some of you are novices who will feel free to ask questions, for the others to answer. Let me start by introducing myself -- my name is David Ascher, and I've been programming in Python for about four or five years. While I've just co-authored a book called "Learning Python" with Mark Lutz, it's not a book which was designed to teach programming. I've been programming for more than half my life, and I haven't taught programming in ages, so I feel I'm a bit out of touch with what students new to programming need to know, and what parts are hard to learn or unintuitive. I'm hoping that with a little interaction between the students and the teachers on this list, two goals can be reached -- 1) the folks who are trying to learn programming with Python get the help they need, and 2) the folks who want to develop better documentation for learning programming with Python get a test audience to help them work out the pedagogics. Well, I'll clear the stage and let the questions roll in. Cheers, --david From siegel@eico.com Mon Mar 8 14:57:15 1999 From: siegel@eico.com (Arthur Siege;l) Date: Mon, 08 Mar 1999 09:57:15 -0500 Subject: [Tutor] Children of all ages Message-ID: <36D1D44300000A38@mail.eico.com> (added by mail.eico.com) >Welcome all -- David is about half my age and has been prgramming probably five times as long as I have. I have learned most of what I know about programming with Python, and DA's PyOpenGL over the past few years. Somehow I think graphics programming is a great place to start - particularly for kid's. The fact that objects appear as objects - on the screen - helps to make the process a bit less abstract. The beauty of Python, as a scripting language and in interactive mode, is that it allows one to futz around - great for learning. While I can now claim to grasp the basics of OOP and have a handle around Python as a tool for further exploration, there as still some basics I haven't gotten to. But what I want to explore is less Python or any specfic syntax, but broader areas of technological ignorance. Python is the tool that will allow me to explore. What I am not sure of is the appropriateness of this approach to the founding concept of this list. For example - sockets. I haven't a clue. Other than knowing that it is a basic technology of the web. If it is an appropriate question here, how might I use Python to get a grasp of the area?? From ajs@ix.netcom.com Mon Mar 8 14:47:06 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Mon, 8 Mar 1999 09:47:06 -0500 Subject: [Tutor] Children of all ages Message-ID: <002001be6974$803f2fa0$2e82f3d0@seigel.eico.com> >Welcome all -- David is about half my age and has been prgramming probably five times as long as I have. I have learned most of what I know about programming with Python, and DA's PyOpenGL over the past few years. Somehow I think graphics programming is a great place to start - particularly for kid's. The fact that objects appear as objects - on the screen - helps to make the process a bit less abstract. The beauty of Python, as a scripting language and in interactive mode, is that it allows one to futz around - great for learning. While I can now claim to grasp the basics of OOP and have a handle around Python as a tool for further exploration, there as still some basics I haven't gotten to. But what I want to explore is less Python specific syntax, but broader areas of technological ignorance. Python is the tool that will allow me to explore. What I am not sure of is the appropriateness of this approach to the founding concept of this list. For example - sockets. I haven't a clue. Other than knowing that it is a basic technology of the web. If it is an appropriate question here, how might I use Python to get a grasp of the subject?? From geek+@cmu.edu Mon Mar 8 16:47:00 1999 From: geek+@cmu.edu (geek+@cmu.edu) Date: 8 Mar 1999 11:47:00 -0500 Subject: [Tutor] Children of all ages In-Reply-To: <36D1D44300000A38@mail.eico.com> (added by mail.eico.com) Message-ID: --pgp-sign-Multipart_Mon_Mar__8_11:46:58_1999-1 Content-Type: text/plain; charset=US-ASCII Then spoke up and said: > still some basics I haven't gotten to. But what I want to explore is less > Python or any specfic syntax, but broader areas of technological ignorance. > Python is the tool that will allow me to explore. What I am not sure of is > the appropriateness of this approach to the founding concept of this list. > For example - sockets. I haven't a clue. Other than knowing that it is a > basic technology of the web. If it is an appropriate question here, how > might I use Python to get a grasp of the area?? This seems like as good a place as any. For what little socket work I've done, I've found the socket demos in the source distribution an excellent place to start. Unfortunately, this doesn't really teach the theory behind it all, or give you a good grasp of how it works. On the other hand, you do end up with tools that show you how to get a basic socket server up and running. The next big hurdle after that is terminal handling (if you need it). -- ===================================================================== | JAVA must have been developed in the wilds of West Virginia. | | After all, why else would it support only single inheritance?? | ===================================================================== | Finger geek@andrew.cmu.edu for my public key. | ===================================================================== --pgp-sign-Multipart_Mon_Mar__8_11:46:58_1999-1 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP MESSAGE----- Version: 2.6.2 Comment: Processed by Mailcrypt 3.3, an Emacs/PGP interface iQBVAwUBNuP/A4dzVnzma+gdAQE0AAIAmGRSjJs1jQydb+jRi8VxrZSKmQxvmvJf 0MW9D5OL1pekdmHvlMFj+1te1agv6T8//iegwrhJ6wfpTg13duk8Jg== =Q3/z -----END PGP MESSAGE----- --pgp-sign-Multipart_Mon_Mar__8_11:46:58_1999-1-- From alan.gauld@gssec.bt.co.uk Mon Mar 8 17:39:47 1999 From: alan.gauld@gssec.bt.co.uk (Alan Gauld) Date: Mon, 8 Mar 1999 17:39:47 -0000 Subject: [Tutor] RE: Tutor digest, Vol 1 #2 - 4 msgs In-Reply-To: <199903081704.MAA00472@python.org> Message-ID: <001e01be698a$a960a880$0acb9284@dumyat.gssec.bt.co.uk> Since folks seem to be introducing themselves... I am just starting with Python - looking for an alternative to Perl which I just hate for all sorts of reasons! Basically it offends my sense of programming purity. :-) But up to now it has been the only thing with that kind of sheer power... I've been programming for about 15 years in C, C++, awk, Smalltalk, Lisp and Delphi.(Oh and COBOL but I try to forget that...) Anyway, My point for a Python tutorial: Explain the colon!!! It gets a passing mention in Lutz's book, none at all in Watter's book. It took me (as an experienced programmer) at least half an hour to figure out how/when the colon should be used(mainly by browsing the demo code) a beginner to programming with no concept of a 'block of code' will be baffled IMHO. See ya'll around :-) Alan G. From M.Faassen@vet.uu.nl Mon Mar 8 20:07:25 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 08 Mar 1999 21:07:25 +0100 Subject: [Tutor] RE: Tutor digest, Vol 1 #2 - 4 msgs References: <001e01be698a$a960a880$0acb9284@dumyat.gssec.bt.co.uk> Message-ID: <36E42DFD.A3BC9443@pop.vet.uu.nl> Alan Gauld wrote: > > Since folks seem to be introducing themselves... > > I am just starting with Python - looking for an alternative > to Perl which I just hate for all sorts of reasons! Basically > it offends my sense of programming purity. :-) But up to now > it has been the only thing with that kind of sheer power... > > I've been programming for about 15 years in C, C++, awk, > Smalltalk, Lisp and Delphi.(Oh and COBOL but I try to forget > that...) > > Anyway, My point for a Python tutorial: > > Explain the colon!!! It gets a passing mention in Lutz's book, > none at all in Watter's book. It took me (as an experienced > programmer) at least half an hour to figure out how/when > the colon should be used(mainly by browsing the demo code) > a beginner to programming with no concept of a 'block of > code' will be baffled IMHO. This hangs together with 'indentation', though. Are you sure indentation isn't explained in these books (I haven't read either). I don't recall having had any problem grasping what the ':' was about (along with indentation marking block structure). Of course I was already experienced with other programming languages, so I don't count at as an absolute beginner. I agree a beginner tutorial should have a good explanation of 'block structure' in programming, though. In Python this is marked by the : and an indented block, but saying 'explain the colon' mystifies me. :) Regards, Martijn From da@ski.org Mon Mar 8 21:27:25 1999 From: da@ski.org (David Ascher) Date: Mon, 8 Mar 1999 13:27:25 -0800 (Pacific Standard Time) Subject: [Tutor] RE: Tutor digest, Vol 1 #2 - 4 msgs In-Reply-To: <36E42DFD.A3BC9443@pop.vet.uu.nl> Message-ID: On Mon, 8 Mar 1999, Martijn Faassen wrote: > Alan Gauld wrote: > > Explain the colon!!! > > I agree a beginner tutorial should have a good explanation of 'block > structure' in programming, though. In Python this is marked by the : and > an indented block, but saying 'explain the colon' mystifies me. :) Let me try to emphasize that I'd much rather see explanations than defensive reactions. If the questions are there, they indicate a need which isn't met. Here's a first pass: Python uses a combination of colons (:) and indented blocks to indicate to the compiler what lines of code are to be grouped together in flow-control statements like if, for, while, and other structural groupings like function definitions (def) and class definitions (class). In all of these cases, the syntax is very much like when presenting an outline: This is the first section of the outline -- it has two subsections: This is the first subsection. This is the second subsection of the first section. This is the second section. As you read this, the combination of consistent indentation and the : at the end of the preceding paragraph help you group things. Python uses the fact that you're used to this kind of grouping process from reading in its syntax -- that way your eye & brain read the same thing as the Python compiler. --david From doughellmann@mindspring.com Tue Mar 9 01:45:07 1999 From: doughellmann@mindspring.com (Doug Hellmann) Date: Mon, 08 Mar 1999 20:45:07 -0500 Subject: [Tutor] Children of all ages References: <002001be6974$803f2fa0$2e82f3d0@seigel.eico.com> Message-ID: <36E47D21.B2178565@mindspring.com> Hi, Art, I agree with your comments on learning OOP by writing graphics apps. I'm not familiar with OpenGL, but I know that learning with something like the Tk Canvas would be a good way to break into OOP and event based programming. As far as your project with sockets, I'd suggest starting out with a simple client/server setup. The first program I wrote with sockets had a server that would just print out whatever text the client sent. Once you can do that, you have the basics down for reading from the socket without hanging using select(). If you are sending plain text back and forth, you might send something that you have to parse (like a command with parameters). That means you have to accumulate enough data to make the parsing work. When you are comfortable with plain text, you can move on to something like reading a fixed amount of data from the socket. That lets you send records or data structures. Then you get into things like sending binary data, which brings up topics like byte order. If you want to play with select(), you could also start with the httplib that comes with Python. Using that, you can connect to any web server and grab web pages. The benefit of using HTTP is that you can check your results against what your web browser gets. Of course, httplib hides the really interesting part of openning the socket, etc., but it would be a good way to break into the client side. Doug From da@ski.org Tue Mar 9 04:28:15 1999 From: da@ski.org (David Ascher) Date: Mon, 8 Mar 1999 20:28:15 -0800 (Pacific Standard Time) Subject: [Tutor] Children of all ages In-Reply-To: <36E47D21.B2178565@mindspring.com> Message-ID: > I agree with your comments on learning OOP by writing graphics apps. > I'm not familiar with OpenGL, but I know that learning with something > like the Tk Canvas would be a good way to break into OOP and event based programming. This reminds me - I recommend trying out the turtle.py module which Guido put in Python 1.5.2b1 -- it's a great first step for logo-style graphics, especially when driven in IDLE (the Interactive Development Environment, also by Guido). --david From tim_one@email.msn.com Tue Mar 9 07:54:17 1999 From: tim_one@email.msn.com (Tim Peters) Date: Tue, 9 Mar 1999 02:54:17 -0500 Subject: [Tutor] RE: Tutor digest, Vol 1 #2 - 4 msgs In-Reply-To: <001e01be698a$a960a880$0acb9284@dumyat.gssec.bt.co.uk> Message-ID: <000f01be6a02$08131620$9b9e2299@tim> [Alan Gauld] > ... > I've been programming for about 15 years in C, C++, awk, > Smalltalk, Lisp and Delphi.(Oh and COBOL but I try to forget > that...) > > Anyway, My point for a Python tutorial: > > Explain the colon!!! It gets a passing mention in Lutz's book, > none at all in Watter's book. It took me (as an experienced > programmer) at least half an hour to figure out how/when > the colon should be used(mainly by browsing the demo code) > a beginner to programming with no concept of a 'block of > code' will be baffled IMHO. Alan, it's probably your very *experience* that gets in the way here. No kidding! The colons aren't syntactically necessary, and you're experienced enough to at least inuit that. Python's most direct predecessor was a language called ABC, designed at CWI in the Netherlands (Guido's former employer, and where Python began too). ABC was a research project aiming at computer first-timers, and all aspects of its design were subject to formal usability studies. After a few iterations, what they discovered is that "begin/end" blocking constructs confused complete newbies, but using indentation for blocking didn't -- provided that the block's opening line ended with a colon. We can speculate about *why* that might be (and David's analogy with outlines sounds good to me -- except that outlines don't usually have colons ), but the fact is that's what the studies discovered empirically. BTW, I can tell you from my own experience that you wouldn't like ABC. It catered to newcomers so relentlessly that many aspects of it plain got in the way for experienced programmers. The trailing colon isn't one of those, though; over time I predict you'll grow quite fond of it. historically y'rs - tim From M.Faassen@vet.uu.nl Tue Mar 9 09:59:06 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 09 Mar 1999 10:59:06 +0100 Subject: [Tutor] RE: Tutor digest, Vol 1 #2 - 4 msgs References: Message-ID: <36E4F0EA.6B3E1524@pop.vet.uu.nl> David Ascher wrote: > > On Mon, 8 Mar 1999, Martijn Faassen wrote: > > Alan Gauld wrote: > > > Explain the colon!!! > > > > I agree a beginner tutorial should have a good explanation of 'block > > structure' in programming, though. In Python this is marked by the : and > > an indented block, but saying 'explain the colon' mystifies me. :) > > Let me try to emphasize that I'd much rather see explanations than > defensive reactions. If the questions are there, they indicate a need > which isn't met. Whoops. I didn't mean to send out a 'defensive reaction'. I genuinely was puzzled by 'explain the colon' and it took me a second more careful reading to get what was being talked about. Also it seemed that Alan Gauld understood the concept just fine now, so I didn't venture an explanation in response (though I agreed there ought to be one). Independently (I haven't read David Ascher's response yet) here's my attempt at block structure, if not for Alan then for posterity. :) In an imperative computer language like Python and many others (don't bother about what 'imperative' means right now), the concept of 'block structure' is very important. A block of code is a sequence of statements in a programming language that 'belongs together'. Generally this means that whenever the first statement the block is executed, all the other statements in the block will be executed as well, one by one. There are exceptions to this rule in Python; I'll get to some of these later. A lot of programming language mark blocks by saying 'okay, here a block begins', and 'here a block ends' by using special characters such as '{' and '}'. In Python, the block structure is defined by: a) a colon announcing that here a new block starts. Compare this to the use of the colon in natural language, see for instance the colon in the previous paragraph. b) indentation (from the left side of the screen, using spaces (usually 4) or 'tab' characters). All statements in the block have the same indentation, except those of blocks that are contained, which have greater indentation. An example (not in Python) of a block containing 3 statements: my block: statement statement statement A block may also contain other blocks inside them. This would look like this: my block: statement my subblock: statement statement statement statement So, blocks can be used to structure a program. What would be the use of this structuring capability? In Python, we can define functions, with the statement 'def'. The statement 'def' announces a function definition follows. First after 'def' Python expects a function name, then a list of arguments marked by '(' and '), and finally a colon, announcing the block that follows. For instance: # function without arguments (so the space between '(' and ')' is empty, # to keep things simple def print_stuff(): print "Hello world." print "We are explaining block structure." print "We're done now." Once you have this function and Python has processed it, it can be used anywhere else in the program, just by calling it like this: print_stuff() This then makes Python execute the statements in the function 'print_stuff', and the result will be: Hello world. We are explaining block structure. We're done now. A program that runs on straight forever can't do much; it can't respond to changing circumstances in the outside world (the user or the data it may be reading from disk or from a network). A program needs to be able to behave differently in different circumstances. For this purpose we have the 'if' statement, another great example of the use of block structure. 'if' is always followed by a description of a condition (for instance, the value of 'a' is smaller than that of 'b'). If the condition happens to be the case (if the condition is 'true', in programmer speak), then the block that follows is executed. If the condition isn't the case or false, then the block that follows is skipped and not executed. An example: a = 3 b = 4 if a < b: print "'a' is smaller than 'b'." print "We put in another statement just to show we can." If we execute this program, of course a (3) will always be smaller than b (4), so we'll always get the output: 'a' is smaller than 'b'. We put in another statement just to show we can. (as you may have figured, a block can also just be just a single statement; we don't need the second 'print' statement here :) This is a trivial example. A more complicated example would not always behave the same, as the value of a and b would depend on other things (for instance they are the result of some calculation, involving data that may be different each time this program is executed). We can put blocks in blocks, as we saw before. An example (also of a function with two arguments, called 'a' and 'b'): def is_a_smaller_than_b(a, b): if a < b: print "Yes, a is smaller than b" print "We are done." If you call this function like this: is_a_smaller_than_b(3, 4) gets you the folllowing output: Yes, a is smaller than b We are done. If we call it like this: is_a_smaller_than_b(100000, 1) We get this output: We are done. As the 'if' block was not executed. Blocks are therefore a very useful and even essential way to structure your Python programs. It is easy to recognize a block in Python; they're always announced by a colon (:) and they are always indented. Of course, I'm trying to explain too many basic things at once, so I may have left posterity completely confused. If you happen to be completely confused, feel free to ask questions about anything I talked about (or things I didn't talk about :). Regards, Martijn From alan.gauld@gssec.bt.co.uk Tue Mar 9 17:37:01 1999 From: alan.gauld@gssec.bt.co.uk (Alan Gauld) Date: Tue, 9 Mar 1999 17:37:01 -0000 Subject: [Tutor] RE: Tutor digest, Vol 1 #3 - 7 msgs In-Reply-To: <199903091704.MAA24072@python.org> Message-ID: <004e01be6a53$71064a20$0acb9284@dumyat.gssec.bt.co.uk> > kidding! The colons aren't syntactically necessary, and > you're experienced > enough to at least inuit that. Yes, That's possibly why I was confused. There seemed to be an essential syntactic element which served no practical use, so I kept asking - "What's it for?!" Also I initially thought it was a line terminator (like ; in Perl). My point was that nobody even *mentions* the colon in the existing tutorial or in Guido and Aarons book. Lutz gives it a passing mention in one sentence! > iterations, what they discovered is that "begin/end" blocking > constructs > confused complete newbies, but using indentation for blocking > didn't -- > provided that the block's opening line ended with a colon. Bizarre, but OK I can believe it... :-) > though; over time I predict you'll grow quite fond of it. After about 3 months I still miss it out. :-( But at least I now recognise immediately what the problem is.... Thanks for all the responses, at least it got a thread going :-) Alan G. From alan.gauld@gssec.bt.co.uk Tue Mar 9 17:40:38 1999 From: alan.gauld@gssec.bt.co.uk (Alan Gauld) Date: Tue, 9 Mar 1999 17:40:38 -0000 Subject: [Tutor] RE: Tutor digest, Vol 1 #3 - 7 msgs In-Reply-To: <199903091704.MAA24072@python.org> Message-ID: <004f01be6a53$f248ce00$0acb9284@dumyat.gssec.bt.co.uk> > Whoops. I didn't mean to send out a 'defensive reaction'. I genuinely > was puzzled by 'explain the colon' and it took me a second No offense taken here - I've been on usenet too long for that :-) > Independently (I haven't read David Ascher's response yet) here's my > attempt at block structure, if not for Alan then for posterity. :) And a really fine attempt it is too (well, I understood it :) Now if we can collect snippets like that we can pretty quickly get a real newbie tutorial sorted. Alan G. From alex_c@MIT.EDU Tue Mar 9 18:16:10 1999 From: alex_c@MIT.EDU (Alexander S Coventry) Date: Tue, 9 Mar 1999 13:16:10 -0500 (EST) Subject: [Tutor] RE: Tutor digest, Vol 1 #3 - 7 msgs In-Reply-To: <004e01be6a53$71064a20$0acb9284@dumyat.gssec.bt.co.uk> (alan.gauld@gssec.bt.co.uk) References: <004e01be6a53$71064a20$0acb9284@dumyat.gssec.bt.co.uk> Message-ID: <199903091816.NAA00414@mass-toolpike.mit.edu> > After about 3 months I still miss it out. :-( So do I, actually. I find using emacs' python-mode a little helpful in this respect, because missing one, or forgetting to close a parenthesis screws up all the subsequent indentation. Alex. From joe@strout.net Tue Mar 9 18:37:12 1999 From: joe@strout.net (Joseph J. Strout) Date: Tue, 9 Mar 1999 10:37:12 -0800 Subject: [Tutor] RE: Tutor digest, Vol 1 #3 - 7 msgs In-Reply-To: <199903091816.NAA00414@mass-toolpike.mit.edu> References: <004e01be6a53$71064a20$0acb9284@dumyat.gssec.bt.co.uk> (alan.gauld@gssec.bt.co.uk) <004e01be6a53$71064a20$0acb9284@dumyat.gssec.bt.co.uk> Message-ID: At 10:16 AM -0800 03/09/99, Alexander S Coventry wrote: >> After about 3 months I still miss it out. :-( > >So do I, actually. I find using emacs' python-mode a little helpful >in this respect, because missing one, or forgetting to close a >parenthesis screws up all the subsequent indentation. FWIW, the same is true for the MacPython IDE. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From ajs@ix.netcom.com Tue Mar 9 18:45:54 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Tue, 9 Mar 1999 13:45:54 -0500 Subject: [Tutor] Malloc, bitwise operations and other nasties Message-ID: <000d01be6a5d$11515c00$2e82f3d0@seigel.eico.com> This is a multi-part message in MIME format. ------=_NextPart_000_000A_01BE6A33.273C6B60 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I am retransmitting the following. I apologize if duplicated. The following is a code snippet from OpenGL demo code I am trying to = port to Python.=20 /* Create a single component texture map */=20 GLfloat *=20 make_texture(int maxs, int maxt)=20 {=20 int s, t;=20 static GLfloat *texture;=20 texture =3D (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat));=20 for (t =3D 0; t < maxt; t++) {=20 for (s =3D 0; s < maxs; s++) {=20 texture[s + maxs * t] =3D ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1);=20 }=20 }=20 return texture;=20 } The code creates a checkerboard texture, which gets mapped to an object. Between the malloc call (something to do with memory, I know) and the = bitwise operators, I am lost. I certainly can't see how this becomes a texturemap. If I saw the code in Pythonese, I couldl probably begin to understand = it.=20 Any help is appreciated. ------=_NextPart_000_000A_01BE6A33.273C6B60 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
 
I am retransmitting the following. I = apologize=20 if duplicated.
 
 
The following is a code snippet from OpenGL demo code I am trying = to port=20 to Python.
/* Create a single component texture map */
GLfloat *
make_texture(int maxs, int maxt)
{
int s, t;
static GLfloat *texture;
texture =3D (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); =
for (t =3D 0; t < maxt; t++) {
for (s =3D 0; s < maxs; s++) {
texture[s + maxs * t] =3D ((s >> 4) & 0x1) ^ ((t >> = 4) &=20 0x1);
}
}
return texture;
}
The code creates a checkerboard texture, which gets mapped to an=20 object.
Between the malloc call (something to do with memory, I know) and = the=20 bitwise operators, I am lost.
I certainly can't see how this becomes a texturemap.
If I saw the code in Pythonese, I couldl probably begin to = understand it.=20
Any help is appreciated.
 
 
------=_NextPart_000_000A_01BE6A33.273C6B60-- From da@ski.org Tue Mar 9 19:14:26 1999 From: da@ski.org (David Ascher) Date: Tue, 9 Mar 1999 11:14:26 -0800 (Pacific Standard Time) Subject: [Tutor] Malloc, bitwise operations and other nasties In-Reply-To: <000d01be6a5d$11515c00$2e82f3d0@seigel.eico.com> Message-ID: On Tue, 9 Mar 1999, Art Siegel wrote: > The following is a code snippet from OpenGL demo code I am trying to > port to Python. > /* Create a single component texture map */ > GLfloat * > make_texture(int maxs, int maxt) > { > int s, t; > static GLfloat *texture; > texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); > for (t = 0; t < maxt; t++) { > for (s = 0; s < maxs; s++) { > texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); > } > } > return texture; > } > The code creates a checkerboard texture, which gets mapped to an object. > Between the malloc call (something to do with memory, I know) and the bitwise operators, I am lost. > I certainly can't see how this becomes a texturemap. > If I saw the code in Pythonese, I couldl probably begin to understand it. > Any help is appreciated. This is a great example of why C is ugly =) malloc creates an array of unitialized bytes. A close equivalent to the above code in Python would be texture = [0.0]*(maxs*maxt) for t in range (maxt): for s in range(maxs): texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); If you try it with maxs and maxt set to 20, you'll see the 'scan lines': >>> maxt = maxs = 20 >>> texture = [0.0]*(maxs*maxt) >>> for t in range (maxt): ... for s in range(maxs): ... texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); ... >>> print texture [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0] However, looking at it like that makes it a bit hard to see how it works. One could recode it as: >>> texture = [] >>> for t in range (maxt): ... line = [] # note we're using lists of lists ... texture.append(line) # to make the 'lines' ... for s in range(maxs): ... line.append(((s >> 4) & 0x1) ^ ((t >> 4) & 0x1)) ... >>> texture [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0] ] (this looks if you try like the corner of a checkerboard) How does it work? The key is clearly the ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); s >> 4 is the value of s, shifted to the right by four bits. When AND'ed with 1, that tests whether the bit four bits from the right in s is on or not. When OR'ed with the equivalent for t, that will be 1 if either the fourth bit in s or the fourth bit in t are on (or both). Which means that columns 16 through 31 and rows 16 through 31 will be "on", and columns 0 through 15 and rows 0 through 15 will be 'off' (with that pattern repeated ad infinitum). So the "4" in the right-shift operation determines the "coarseness" of the texture. The bit at the '4th position from the right' is the bit corresponding to 2 to the fourth, or 16. So in this case the checkerboard is 16-off, 16-on. If you make it 5, you'll get 32x32 checkerboards, etc. [I'm not happy about this discussion of bit-shifting -- anyone got better words to describe binary representations? -- say, Tim, where's that module of yours again?] [To use this lists of lists in PyOpenGL you'll have to flatten it first, as per our discussion on the PyOpenGL list, until the next release] Make sense? --david From ajs@ix.netcom.com Tue Mar 9 19:46:52 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Tue, 9 Mar 1999 14:46:52 -0500 Subject: [Tutor] Malloc, bitwise operations and other nasties Message-ID: <000401be6a65$959ba800$2e82f3d0@seigel.eico.com> >Make sense? > A bit. Or a byte. Probably more when I have a chance to play with it.. >_______________________________________________ >Tutor maillist - Tutor@python.org >http://www.python.org/mailman/listinfo/tutor > > From jlcos@accessone.com Tue Mar 9 20:50:34 1999 From: jlcos@accessone.com (Jon Cosby) Date: Tue, 9 Mar 1999 12:50:34 -0800 Subject: [Tutor] Tkinter Message-ID: <01be6a6e$7ac796c0$0100007f@localhost> This is a multi-part message in MIME format. ------=_NextPart_000_0004_01BE6A2B.6CA456C0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I need some help with Tkinter, and find the Pythonware tutorial to be = lacking. I'd like create a button to call an application and dialog = window for input, and present the results. Are there some good examples = to look at to get me started? Jon Cosby ------=_NextPart_000_0004_01BE6A2B.6CA456C0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
I need some help with Tkinter, and = find the=20 Pythonware tutorial to be lacking. I'd like create a button to call an=20 application and dialog window for input, and present the results. Are = there some=20 good examples to look at to get me started?
 
Jon Cosby
------=_NextPart_000_0004_01BE6A2B.6CA456C0-- From geek+@cmu.edu Tue Mar 9 21:25:07 1999 From: geek+@cmu.edu (geek+@cmu.edu) Date: 9 Mar 1999 16:25:07 -0500 Subject: [Tutor] Tkinter In-Reply-To: <01be6a6e$7ac796c0$0100007f@localhost> Message-ID: --pgp-sign-Multipart_Tue_Mar__9_16:25:06_1999-1 Content-Type: text/plain; charset=US-ASCII Then spoke up and said: > I need some help with Tkinter, and find the Pythonware tutorial to be = > lacking. I'd like create a button to call an application and dialog = > window for input, and present the results. Are there some good examples = > to look at to get me started? Firstly, *please* disable sending mail as HTML. Next, I've always found that the best place to look for doing Tkinter things is in the DEMO directory of the source distribution. Unfortunately, there really are no "good" examples. One trick that sometimes works for me is to design something in Tcl/Tk, and then translate it into Tkinter. Of course, you end up working twice as hard, and if you use a tool like SpecTCL, the translation step can be painful. Speaking of SpecTCL, there is a plugin for it called SpecPYTHON that (theoretically) lets you design Tkinter apps and spits out Python code. Unfortunately, getting it all working is non-trivial. I almost forgot: don't forget to look at the source in /usr/local/lib/python1.5/lib-tk/*.py. While somewhat minimal, most of the source files there include test functions that show small, low-level uses of the various widgets. Beyond that, you have to get really specific. The most generic advice to give is this: Learn how to use and write factory functions. They are your friends. e.g import Tkinter def foo(): pass def button_factory(master, command=None): b = Tkinter.Button(t, background='red', command) b.pack(side=Tkinter.LEFT) return b t = Tkinter.Toplevel() t.b1 = button_factory(t, command=foo) While the above example is *really* trivial, if you have a more exciting set of attributes that need to be set for every button, the factory function will become very handy (and even more readable). Does this answer your question (at least in part)? -- ===================================================================== | JAVA must have been developed in the wilds of West Virginia. | | After all, why else would it support only single inheritance?? | ===================================================================== | Finger geek@andrew.cmu.edu for my public key. | ===================================================================== --pgp-sign-Multipart_Tue_Mar__9_16:25:06_1999-1 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP MESSAGE----- Version: 2.6.2 Comment: Processed by Mailcrypt 3.3, an Emacs/PGP interface iQBVAwUBNuWRs4dzVnzma+gdAQGB3QH+LnwMLgl2Sf/hCy4pGHdJH1kv0jxHrRpu HblyPTlVXLLmSHVhBOmOvw1OavoPCANdWP8S3dXBt+cButD3RnAuEA== =pMqB -----END PGP MESSAGE----- --pgp-sign-Multipart_Tue_Mar__9_16:25:06_1999-1-- From tim_one@email.msn.com Wed Mar 10 09:27:08 1999 From: tim_one@email.msn.com (Tim Peters) Date: Wed, 10 Mar 1999 04:27:08 -0500 Subject: [Tutor] Malloc, bitwise operations and other nasties In-Reply-To: Message-ID: <001301be6ad8$2b054b40$9b9e2299@tim> [David Ascher] > ... > [I'm not happy about this discussion of bit-shifting -- anyone got better > words to describe binary representations? The 1 bits are foxes, the 0 bits are chickens, shifting right is when the foxes chase the chickens to the east except some fall off the end of the Earth, and xor is the well-known rule that a fox and a chicken in the same coop at the same time leaves only the fox, will two foxes together devour each other and two chickens together bore each other out of existence. There! I hope you're a lot happier about *your* discussion now > -- say, Tim, where's that module of yours again?] tabnanny.py is in Tools/Scripts/, of course. playing-it-straight-ly y'rs - tim From GBCGOLF@aol.com Wed Mar 10 18:45:42 1999 From: GBCGOLF@aol.com (GBCGOLF@aol.com) Date: Wed, 10 Mar 1999 13:45:42 EST Subject: [Tutor] Python Picture Message-ID: I'm finishing a "beginners" paper on Python (i.e.: please have mercy, I'm a newbie.) I would like to put the "Python" symbol (prefer full snake icon over snake head icon) on the first page of a MS Word (Office 97) document. Is that possible? If so, how. I need to turn in the paper this evening so I may have posted this question too late for a response. Thanks much for any info. Beth From joe@strout.net Wed Mar 10 18:56:45 1999 From: joe@strout.net (Joseph J. Strout) Date: Wed, 10 Mar 1999 10:56:45 -0800 Subject: [Tutor] Python Picture In-Reply-To: Message-ID: At 10:45 AM -0800 03/10/99, GBCGOLF@aol.com wrote: >I'm finishing a "beginners" paper on Python (i.e.: please have mercy, I'm a >newbie.) I would like to put the "Python" symbol (prefer full snake icon over >snake head icon) on the first page of a MS Word (Office 97) document. Hi Beth, Python's proper symbol is not a snake, but a 16-ton falling weight. From the documentation (section 1.4): "By the way, the language is named after the BBC show ``Monty Python's Flying Circus'' and has nothing to do with nasty reptiles..." Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From da@ski.org Wed Mar 10 19:18:24 1999 From: da@ski.org (David Ascher) Date: Wed, 10 Mar 1999 11:18:24 -0800 (Pacific Standard Time) Subject: [Tutor] Python Picture In-Reply-To: Message-ID: On Wed, 10 Mar 1999, Joseph J. Strout wrote: > > >I'm finishing a "beginners" paper on Python (i.e.: please have mercy, I'm a > >newbie.) I would like to put the "Python" symbol (prefer full snake icon over > >snake head icon) on the first page of a MS Word (Office 97) document. > > Hi Beth, > > Python's proper symbol is not a snake, but a 16-ton falling weight. From > the documentation (section 1.4): "By the way, the language is named after > the BBC show ``Monty Python's Flying Circus'' and has nothing to do with > nasty reptiles..." That said, I think she can use a snake if all the book publishers do. =) As to how that should be done, what I'd do if I were you Beth is to take a snapshot of the screen (with the Control-PrintScreen key combination), go to a bitmap editor (you should have one called "Paint" under your Accessories menu under Program under the Start menu), and paste the new picture into it -- then use the rectangle selection tool to isolate the part of the screen you want to use, copy that, and paste that into word. Should work. permissively-yrs, --david From tismer@appliedbiometrics.com Wed Mar 10 19:29:54 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Wed, 10 Mar 1999 20:29:54 +0100 Subject: [Tutor] Python Picture References: Message-ID: <36E6C832.89667F02@appliedbiometrics.com> This is a multi-part message in MIME format. --------------F4D90759C6B207B0323C932E Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit GBCGOLF@aol.com wrote: > > I'm finishing a "beginners" paper on Python (i.e.: please have mercy, I'm a > newbie.) I would like to put the "Python" symbol (prefer full snake icon over > snake head icon) on the first page of a MS Word (Office 97) document. Is that > possible? If so, how. I need to turn in the paper this evening so I may have > posted this question too late for a response. Thanks much for any info. > Beth You mean the icons from PythonWin, and these are .ico files. You can of course turn it into a graphics format which Word will accept. There are several ways to do that. Assuming you have the Office 97 full tool set, there is the Microsoft Photo editor as well. Here is a brute force attack :-) Open an Explorer Window in a directory with a couple of .py files. Change the display (view menu) to "big symbols" and scroll until you have some nice Pythons in sight. Hold alt-shift down and press the print key. This gives you a snapshot of the current window in the clipboard. Now open the Photo editor, and select "edit - insert as picture" (maybe slightly different, my German version reads "bearbeiten - als neues Bild einfügen". Having done that, you have the screenshot in the Photo Editor. Now zoom to 800%, use the selection tool and capture a Python. 32x32 pixels should be the exact result, or something is wrong. Now use edit - copy to copy this selection into the clipbord. Create another picture which is your Python cutout, again with the "insert as picture" operation. Now save the file in a format as you like. BMP will work, GIF is ok as well. You can also leave it in Photo Editor format since Word can display it. Just open Word and insert the graphic object from the clipboard. Note that a JPeg version with 90% quality looks better for me than the original. Note also that the same procedure is possible with a number of other graphic editors like Paintshop Pro or Adobe Photoshop. In Photoshop, you would simply select the 32x32 range and use image/crop to adjust the size. Alternatively, you can grab such a Python from the internet. See http://starship.python.net/crew/skippy/ where you will find an animated Python gif from Mark Hammond. But I doubt that it will stay animated in the Word document, at least not after printing :-) have fun - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home --------------F4D90759C6B207B0323C932E Content-Type: image/jpeg; name="python.jpg" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="python.jpg" /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoM DAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsN FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAAR CAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl 5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk 5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD6p/4KF+M7PSPht4a8K3fi+PwxB4o1K6t7 23XVrPTZtRtINNvLj7N510jxxwyXMdlDIzKVKziN8rKVb8/fhX48b4HfEnwF4u07V7kR22n6 PN4q16PULPUZ7a23aet/YS2lpCJraCCGS7iW2uRIVFlEYQhtgR1WhaJ4p8Sg+KfEl7aXHi3V ik+v3F7F5d81wkLrLbzZYeXJDOkibNoWFU8lUQJlcm0+JHg7UbrUztg1zwZpcM39t+ILlilg jK2wW8Ssh+1s29Cyr8uGXa0hkVD+QYziaVTHTlh8PzqnZbzTTUr30lGPM7OCjJSUlJ6OXI4f PYriPLsNRk6UnVmr+7BXd+zbso+V2m2rJN3T/XjwV8QvCvxK0qXU/CHibR/FWmxTG2kvNEv4 ryFJQqsYy8bMAwV0O3OcMD3FdBX48eGfE2tfAS7t/iHZbodZ0VZb3alyrzXekpO8p0y4mG8O GhXymZvNCygTKXdEc/sPX6Dk+b0s4pSqU1Zxdnrf5p9Uz3KNWGIowr03eMldf5PfVbPzPzO/ aP8A2VdY8ZfEz4tfF3xPoPh7RPD16bKC5HiLxFeWc4jSztEWOP7JZTecZD5cRSF23TGSJfNw jHi7fSvD2geH7jTdKaO70W+0y4slkl0aPTlMc0rxTmwsld2slntAY5Jrl5bki6mEYs2EiP8A dX7ZngnxJ4y+GWkSeH4LvUbfRdai1fVdK08eZcX1rHBOAscOCJ3jne3uBGfmJtwYw0qxq3wV 9p0/4r6xLpng+/8A+Ey1e7hVP7L8OzfarxQcRB2e3JWBNxQGeR444zIm50yDXwvEjxWGxkKW Dpycp68/vSad7WgtYwdrXaSdnbQ8PO8Ysdm9CjWi6dPkXK4uclFqy5acWpRpuWsp1F7z5nqp zUzuf2cfAmjftNfFa40vUPEWkS6T4cljudV0f7ZDNeagIZI2+yC2YsxtdzRpcSyKUYSGEbne RoPtzxv+1b8LPBPwn1f4ijxjpfiLw3p0j23meG7yLUJLm6WLzfssIjchptnzlSQFTLuVRWcf nuPgp4v1C6Tw1YfDbxW+oW/mWsemjRLixgRRG8csIvZAll5ZiMsbYuDFKjNGrSrIFf3Xwz/w Tn1PVPFdjJ481LQL7QrixC6tJo0csV7KhOX0pXZcmAnlrsPG7LuVbeF2WZPV4fliMJhlhsPg pRs/ecny66a2aTa8ltZJNts9ujKgqUY4eLUI6JcrjZekraelz//Z --------------F4D90759C6B207B0323C932E Content-Type: image/gif; name="python.gif" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="python.gif" R0lGODdhIAAgAPcAAAAAAAAAVQAAqgAA/wAkAAAkVQAkqgAk/wBJAABJVQBJqgBJ/wBtAABt VQBtqgBt/wCSAACSVQCSqgCS/wC2AAC2VQC2qgC2/wDbAADbVQDbqgDb/wD/AAD/VQD/qgD/ /yQAACQAVSQAqiQA/yQkACQkVSQkqiQk/yRJACRJVSRJqiRJ/yRtACRtVSRtqiRt/ySSACSS VSSSqiSS/yS2ACS2VSS2qiS2/yTbACTbVSTbqiTb/yT/ACT/VST/qiT//0kAAEkAVUkAqkkA /0kkAEkkVUkkqkkk/0lJAElJVUlJqklJ/0ltAEltVUltqklt/0mSAEmSVUmSqkmS/0m2AEm2 VUm2qkm2/0nbAEnbVUnbqknb/0n/AEn/VUn/qkn//20AAG0AVW0Aqm0A/20kAG0kVW0kqm0k /21JAG1JVW1Jqm1J/21tAG1tVW1tqm1t/22SAG2SVW2Sqm2S/222AG22VW22qm22/23bAG3b VW3bqm3b/23/AG3/VW3/qm3//5IAAJIAVZIAqpIA/5IkAJIkVZIkqpIk/5JJAJJJVZJJqpJJ /5JtAJJtVZJtqpJt/5KSAJKSVZKSqpKS/5K2AJK2VZK2qpK2/5LbAJLbVZLbqpLb/5L/AJL/ VZL/qpL//7YAALYAVbYAqrYA/7YkALYkVbYkqrYk/7ZJALZJVbZJqrZJ/7ZtALZtVbZtqrZt /7aSALaSVbaSqraS/7a2ALa2Vba2qra2/7bbALbbVbbbqrbb/7b/ALb/Vbb/qrb//9sAANsA VdsAqtsA/9skANskVdskqtsk/9tJANtJVdtJqttJ/9ttANttVdttqttt/9uSANuSVduSqtuS /9u2ANu2Vdu2qtu2/9vbANvbVdvbqtvb/9v/ANv/Vdv/qtv///8AAP8AVf8Aqv8A//8kAP8k Vf8kqv8k//9JAP9JVf9Jqv9J//9tAP9tVf9tqv9t//+SAP+SVf+Sqv+S//+2AP+2Vf+2qv+2 ///bAP/bVf/bqv/b////AP//Vf//qv///yH5BAAAAAAALAAAAAAgACAAQAj/AP8JHPgPAICC BgkqXLjQICQ2DyNChAhgYkKGCg0CAAdOIyQOHA4CAMlB4kGMGUmymfgQgMmCEQ1SzMhvAICa NtmcRNmQJRs4jDjAAWmQZMWXGDlqvFiQpERIO3kOHEmSAyOJJX1CFcg041KDcHRKlXqTX1mz UKOOPeqTEdChQYmyVEuQalWiBuPafbiSbl2OHNgYPUnVrdutPMHVtfsTYli/izNGDAzpKiM2 V59OdIsZst2hF7+OrUvxMuLRGMuerQgZ9U2bOAHAab1Wo868LTW61grp7c+gshvTdulS52/B H6sCsHy6IUjkVgeXDBk47GOUIz8Knl1UsMyPlSsPS9/YcblRrkMnzpYKeDDXh1aRJv2nOCPQ 5/JT94Qf1qRurqGJVVdVzOkESURuLRcWZy2lRBIc1j30lmZFhZQaRHFJpxxtDS2FmkIBAQA7 --------------F4D90759C6B207B0323C932E-- From da@ski.org Wed Mar 10 22:56:21 1999 From: da@ski.org (David Ascher) Date: Wed, 10 Mar 1999 14:56:21 -0800 (Pacific Standard Time) Subject: [Tutor] "Instant Hacking" - programming intro (fwd) Message-ID: FYI: ---------- Forwarded message ---------- Date: Wed, 10 Mar 99 22:00:55 GMT From: Magnus L. Hetland To: python-announce-list@cwi.nl Newsgroups: comp.lang.python, comp.lang.python.announce Subject: "Instant Hacking" - programming intro I have made (or am making...) a small programming tutorial with Python as the example language. It is available from my Python page http://www.idi.ntnu.no/~mlh/python/ as "Instant Hacking". It is a work in progress - comments and suggestions are highly appreciated. == Magnus Lie Hetland http://arcadia.laiv.org From cyberjet@cheerful.com Thu Mar 11 00:18:43 1999 From: cyberjet@cheerful.com (John E. Tobler) Date: Wed, 10 Mar 1999 18:18:43 -0600 Subject: [Tutor] Python Picture References: Message-ID: <36E70BE3.E5C1118A@omaha.crosswinds.net> Joseph J. Strout remarked: > Python's proper symbol is not a snake, > but a 16-ton falling weight. Just for the record, where can we find an official image of that 16-ton falling weight? John Tobler cyberjet@cheerful.com From joe@strout.net Thu Mar 11 00:35:54 1999 From: joe@strout.net (Joseph J. Strout) Date: Wed, 10 Mar 1999 16:35:54 -0800 Subject: [Tutor] Python Picture In-Reply-To: <36E70BE3.E5C1118A@omaha.crosswinds.net> References: Message-ID: At 4:18 PM -0800 03/10/99, John E. Tobler wrote: >Just for the record, where can we find an official image of that 16-ton >falling >weight? It's nothing official, but here's the one used with MacPython: http://www.strout.net/python/ Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From doughellmann@mindspring.com Thu Mar 11 02:37:41 1999 From: doughellmann@mindspring.com (Doug Hellmann) Date: Wed, 10 Mar 1999 21:37:41 -0500 Subject: [Tutor] Tkinter References: <01be6a6e$7ac796c0$0100007f@localhost> Message-ID: <36E72C72.AF697EB@mindspring.com> Hi, Jon, I have been going through the Tk/Tkinter learning curve over the past 6 months. It took a little while to get up to speed, but now I'm writing my own Python Mega Widgets (Pmw - http://www.dscpl.com.au/pmw/) -- check out my widgets at http://www.mindspring.com/~doughellmann/Projects/PmwContribD. Of course, that doesn't help with your question. It isn't clear whether you are having trouble with Tkinter, or Tk, or both. What sort of GUI/Tk/Python background do you have? I was learning both Tk and Tkinter at the same time (though at least I was already fairly fluent with Python). I found _Practical Programming in Tcl and Tk_ useful as a good Tcl/Tk book. It helped to translate some of the examples in to Python, as exercises. For creating a dialog, I would start by looking at the SimpleDialog.py source file in your Python distribution. The __init__ method shows how to create a dialog which will respond to different button presses. You probably don't need to worry about all of the geometry management stuff at first. If you want the user to be able to enter a value, take a look at the Entry widget -- the basic text field widget for getting simple values from the user. Pmw has some canned classes to do these sorts of things, and you can look at that code too. Since there is a lot of Pmw-specific overhead though, that might be more confusing. Doug > Jon Cosby wrote: > > I need some help with Tkinter, and find the Pythonware tutorial to be > lacking. I'd like create a button to call an application and dialog > window for input, and present the results. Are there some good > examples to look at to get me started? > > Jon Cosby From phil@media-1.ml.uwcm.ac.uk Thu Mar 11 09:42:42 1999 From: phil@media-1.ml.uwcm.ac.uk (Phil Harris) Date: Thu, 11 Mar 1999 09:42:42 -0000 Subject: [Tutor] Python Picture Message-ID: <003f01be6ba3$82b035a0$5c773fc1@media1> And now, the easy way to convert ico files to bitmaps. Open windows explorer, hilite the file to be converted, and rename it, the file is automaticaly converted by Windows. Easy when you know how eh! ----- Original Message ----- From: Christian Tismer To: Cc: Sent: Wednesday, March 10, 1999 7:29 PM Subject: Re: [Tutor] Python Picture GBCGOLF@aol.com wrote: > > I'm finishing a "beginners" paper on Python (i.e.: please have mercy, I'm a > newbie.) I would like to put the "Python" symbol (prefer full snake icon over > snake head icon) on the first page of a MS Word (Office 97) document. Is that > possible? If so, how. I need to turn in the paper this evening so I may have > posted this question too late for a response. Thanks much for any info. > Beth You mean the icons from PythonWin, and these are .ico files. You can of course turn it into a graphics format which Word will accept. There are several ways to do that. Assuming you have the Office 97 full tool set, there is the Microsoft Photo editor as well. Here is a brute force attack :-) Open an Explorer Window in a directory with a couple of .py files. Change the display (view menu) to "big symbols" and scroll until you have some nice Pythons in sight. Hold alt-shift down and press the print key. This gives you a snapshot of the current window in the clipboard. Now open the Photo editor, and select "edit - insert as picture" (maybe slightly different, my German version reads "bearbeiten - als neues Bild einfügen". Having done that, you have the screenshot in the Photo Editor. Now zoom to 800%, use the selection tool and capture a Python. 32x32 pixels should be the exact result, or something is wrong. Now use edit - copy to copy this selection into the clipbord. Create another picture which is your Python cutout, again with the "insert as picture" operation. Now save the file in a format as you like. BMP will work, GIF is ok as well. You can also leave it in Photo Editor format since Word can display it. Just open Word and insert the graphic object from the clipboard. Note that a JPeg version with 90% quality looks better for me than the original. Note also that the same procedure is possible with a number of other graphic editors like Paintshop Pro or Adobe Photoshop. In Photoshop, you would simply select the 32x32 range and use image/crop to adjust the size. Alternatively, you can grab such a Python from the internet. See http://starship.python.net/crew/skippy/ where you will find an animated Python gif from Mark Hammond. But I doubt that it will stay animated in the Word document, at least not after printing :-) have fun - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home ---------------------------------------------------------------------------- ---- ---------------------------------------------------------------------------- ---- From tismer@appliedbiometrics.com Thu Mar 11 10:12:51 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Thu, 11 Mar 1999 11:12:51 +0100 Subject: [Tutor] Python Picture References: <003f01be6ba3$82b035a0$5c773fc1@media1> Message-ID: <36E79723.879FA05D@appliedbiometrics.com> Phil Harris wrote: > > And now, the easy way to convert ico files to bitmaps. > > Open windows explorer, hilite the file to be converted, and rename it, the > file is automaticaly converted by Windows. > > Easy when you know how eh! Did you ever test it? 3-[ I did, and it doesn't work, at least not with my Win98 standard setup. I think you should stand in the corner, or I'm dumb. <|:) Way out of the corner: Tell us what you installed to get the autoconversion, and please send me a converted py.ico file which is recognized by word :-) Well, I know there are some auto conversions available. Versions of WinZip know to convert a .zip file into a self extractor after you simply rename the file. But this is dependent of the availability of a converter, and I doubt this is installed by default for .ico files. renaming_.py_to_.exe_is_easier_than_freeze - ly y'rs chris.ico -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From phil@media-1.ml.uwcm.ac.uk Thu Mar 11 10:22:08 1999 From: phil@media-1.ml.uwcm.ac.uk (Phil Harris) Date: Thu, 11 Mar 1999 10:22:08 -0000 Subject: [Tutor] Python Picture Message-ID: <005901be6ba9$04c643e0$5c773fc1@media1> I stand converted 8^( I'm sure this used to work, hmm, I hate it when I'm wrong. Apologies all round 8^) Phil ----- Original Message ----- From: Christian Tismer To: Phil Harris Cc: ; Sent: Thursday, March 11, 1999 10:12 AM Subject: Re: [Tutor] Python Picture > > >Phil Harris wrote: >> >> And now, the easy way to convert ico files to bitmaps. >> >> Open windows explorer, hilite the file to be converted, and rename it, the >> file is automaticaly converted by Windows. >> >> Easy when you know how eh! > >Did you ever test it? 3-[ > >I did, and it doesn't work, at least not with my Win98 standard setup. > >I think you should stand in the corner, or I'm dumb. <|:) > >Way out of the corner: >Tell us what you installed to get the autoconversion, >and please send me a converted py.ico file which >is recognized by word :-) > >Well, I know there are some auto conversions available. >Versions of WinZip know to convert a .zip file into >a self extractor after you simply rename the file. >But this is dependent of the availability of a converter, >and I doubt this is installed by default for .ico files. > >renaming_.py_to_.exe_is_easier_than_freeze - ly y'rs chris.ico > >-- >Christian Tismer :^) >Applied Biometrics GmbH : Have a break! Take a ride on Python's >Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net >10553 Berlin : PGP key -> http://wwwkeys.pgp.net >PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF > we're tired of banana software - shipped green, ripens at home > >_______________________________________________ >Tutor maillist - Tutor@python.org >http://www.python.org/mailman/listinfo/tutor > From aa8vb@vislab.epa.gov Thu Mar 11 15:48:58 1999 From: aa8vb@vislab.epa.gov (Randall Hopper) Date: Thu, 11 Mar 1999 10:48:58 -0500 Subject: [Tutor] Tkinter In-Reply-To: <01be6a6e$7ac796c0$0100007f@localhost>; from Jon Cosby on Tue, Mar 09, 1999 at 12:50:34PM -0800 References: <01be6a6e$7ac796c0$0100007f@localhost> Message-ID: <19990311104858.A132573@vislab.epa.gov> Jon Cosby: | I need some help with Tkinter, and find the Pythonware tutorial to be | lacking. I'd like create a button to call an application and dialog | window for input, and present the results. Are there some good | examples to look at to get me started? I've been learning it lately too. Here are some Tkinter links I've saved off that might be useful: http://hem1.passagen.se/eff/tkintro/Widgets.htm http://starship.python.net/crew/hinsen/part6.html http://www.python.org/topics/tkinter/doc.html http://www.python.org/doc/life-preserver/index.html http://www.pythonware.com/library.htm (Prob. the one you read) Links on Tcl/Tk are useful too. Once you know what you want to do in Tcl/Tk, but aren't sure how that translates into Tkinter, consult the Life Preserver reference manual (link #4). There are a number of examples in the Python distribution pkg under Python-1.5.1/Demo/tkinter (see http://www.python.org/download/). You might run them and look for GUIs with pieces that look like they might be useful, and then browse the source and extract the widget or two that you want. Randall From tim_one@email.msn.com Thu Mar 11 17:04:51 1999 From: tim_one@email.msn.com (Tim Peters) Date: Thu, 11 Mar 1999 12:04:51 -0500 Subject: [Tutor] Python Picture In-Reply-To: <36E79723.879FA05D@appliedbiometrics.com> Message-ID: <000001be6be1$46c546a0$669e2299@tim> [Phil Harris] > And now, the easy way to convert ico files to bitmaps. > > Open windows explorer, hilite the file to be converted, and > rename it, the file is automaticaly converted by Windows. > > Easy when you know how eh! [Christian Tismer] > Did you ever test it? 3-[ > > I did, and it doesn't work, at least not with my Win98 standard setup. > > I think you should stand in the corner, or I'm dumb. <|:) Now, now, Phil may be an unwitting victim of Microsoft docs. There's actually a Knowledge Base article that makes a similar claim, in response to a question like "how can I use a .bmp file as an icon?". The answer says you can rename .bmp -> .ico, and Windows "converts it". In fact it does no such thing, and indeed you can use a .bmp file as an icon without even bothering to rename it. It's trying to say that Windows converts it on the fly when & if a .bmp is used as an icon; the disk file remains untouched. even-easier-when-you-don't-have-to-ly y'rs - tim From priest@sfu.ca Fri Mar 12 06:16:09 1999 From: priest@sfu.ca (David Priest) Date: Thu, 11 Mar 1999 22:16:09 -0800 Subject: [Tutor] Singletons In-Reply-To: <199903111706.MAA08701@python.org> Message-ID: <4.1.19990311220422.00964360@mailserver.sfu.ca> On the wxPython list, this tidbit was posted. It has potential for really simplifying complex GUI design (where one GUI element would influence the appearance of another)... but I have a problem with it. First, the pattern: Singleton.py: --snip--- def Singleton(parent): if __Singleton.instance: return __Singleton.instance __Singleton.instance = __Singleton(parent) return __Singleton.instance class __Singleton: instance = None def __init__(self,parent): { place rest of class here } --snip--- Now, the problem: GUI stuff tend to have a bunch of methods associated with them. How does one access them through the singleton? If the class were defining a window, for instance, then that class would have a "Close()" method. Thus, the dropdown File menu entry for "Exit" might need to jump to code that would do pre-exitting processing (saving files, etc), and then request the application to shut down by calling the Close() method... Main.py --snip--- def Window(): # as above def __Window(window): def __init__: # set up window def Close(self): # shut down app --snip--- Menu.py --snip--- class FileMenu(menu): def __init__(self, etc): # set up the dropdown entries def Exit(self): # process the shutdown activities import Main Main.Window.Close() --snip--- But the singleton pattern for Window() doesn't have a Close() method, of course. Error city. Of course, *this* works, but is dead ugly.... --snip--- def Exit(self): # process the shutdown activities import Main target = Main.Window() target.Close() --snip--- So... here's this potentially *fantastic* resource -- something newbies like me probably would take a year to think of trying -- that is rather limited. Of course, I've been discovering more and more that "If something seems to be difficult to accomplish... ...you're doing it wrong. Find the easy way." Thanks for any hints, peeples! From joe@strout.net Fri Mar 12 17:10:44 1999 From: joe@strout.net (Joseph J. Strout) Date: Fri, 12 Mar 1999 09:10:44 -0800 Subject: [Tutor] Singletons In-Reply-To: <4.1.19990311220422.00964360@mailserver.sfu.ca> References: <199903111706.MAA08701@python.org> Message-ID: At 10:16 PM -0800 03/11/99, David Priest wrote: >def Window(): > # as above >def __Window(window): > def __init__: > # set up window > > def Close(self): > # shut down app >But the singleton pattern for Window() doesn't have a Close() method, of >course. Wait... if you've done something like myWindow = Window() then myWindow is an object of class __Window (which is what the Window() factory function returns, right?). It has a Close() method. What's the problem? Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From guido@CNRI.Reston.VA.US Fri Mar 12 18:50:04 1999 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Fri, 12 Mar 1999 13:50:04 -0500 Subject: [Tutor] Re: Tutor digest, Vol 1 #5 - 12 msgs In-Reply-To: Your message of "Thu, 11 Mar 1999 12:06:28 EST." <199903111706.MAA08700@python.org> References: <199903111706.MAA08700@python.org> Message-ID: <199903121850.NAA01649@eric.cnri.reston.va.us> > From: Magnus L. Hetland > Subject: "Instant Hacking" - programming intro > > I have made (or am making...) a small programming tutorial with Python > as the example language. It is available from my Python page > > http://www.idi.ntnu.no/~mlh/python/ > > as "Instant Hacking". It is a work in progress - comments and > suggestions are highly appreciated. I've added a new category for this intro to the webpage listing various Python introductions (http://www.python.org/doc/Intros.html). If anybody else knows of any such intros, I would be delighted to add them (if they use Python). --Guido van Rossum (home page: http://www.python.org/~guido/) From priest@sfu.ca Sat Mar 13 17:32:12 1999 From: priest@sfu.ca (David Priest) Date: Sat, 13 Mar 1999 09:32:12 -0800 Subject: [Tutor] Singletons In-Reply-To: <199903131703.MAA18069@python.org> Message-ID: <4.1.19990313093102.0095f100@mailserver.sfu.ca> >>def Window(): >> # as above >>def __Window(window): >> def __init__: >> # set up window >> >> def Close(self): >> # shut down app Er, nevermind, everyone. I just got generally clueless there for a bit. Confused by previous sneaky code I'd been using that fooled me into thinking I was doing something I wasn't... -- David Priest w: 542-5208 e: priest@sfu.ca Business Development Solutions: "The Steps to Success" From jlcos@accessone.com Thu Mar 18 16:21:41 1999 From: jlcos@accessone.com (Jon Cosby) Date: Thu, 18 Mar 1999 08:21:41 -0800 Subject: [Tutor] Question on lists Message-ID: <01be715b$6806eec0$0100007f@localhost> Hi - I'm trying to write a function that will return a list of prime factors of a given number. For example, factor(36) would return [2,2,3,3]. What I have so far is given below. Trouble is, each time it factors the quotient, a is given as an empty list again. At this point, it's returning just the first prime factor of the number. Is there any way to work around this? Thanks in advance, Jon Cosby # Factor by trial division: def factor(n): a = [] # Is there a better way to define a? k = floor(sqrt(n)) for i in range(2, k+1): if n%i == 0: a.insert(len(a), i) factor(n/i) # Factor quotient break return a From joe@strout.net Thu Mar 18 16:41:48 1999 From: joe@strout.net (Joseph J. Strout) Date: Thu, 18 Mar 1999 08:41:48 -0800 Subject: [Tutor] Question on lists In-Reply-To: <01be715b$6806eec0$0100007f@localhost> Message-ID: The basic problem is that you're saying: > a.insert(len(a), i) > factor(n/i) # Factor quotient i.e., you're saying "now factor the quotient", but you're not doing anything with the result of this factorization! You're imagining that it will get appended to a, but how would Python know to do that unless you tell it? Also, I'd recommend using a.append to append an element to a, rather than the insert construction used above. Finally, there's a minor bug where you're factor() does not return a prime number as its own factor, as it should. The corrected function looks like this: # Factor by trial division: def factor(n): a = [] # Is there a better way to define a? k = floor(sqrt(n)) for i in range(2, k+1): if n%i == 0: a.append(i) ### (append rather than insert) a.extend(factor(n/i)) ### add the factors of the quotient return a ### don't break; just return # if not divisible by any of the above, then it must be prime return [n] Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From pels@bio.uva.nl Thu Mar 18 16:50:28 1999 From: pels@bio.uva.nl (bas pels) Date: Thu, 18 Mar 1999 17:50:28 +0100 Subject: [Tutor] search path Message-ID: <36F12ED4.A0EFAB0@bio.uva.nl> a small question about search paths. i have downloaded two so-called site-packages that both contain x.pth files in their directories (so-called path configuration files). from the reference manual (p.57) i learnt that the site module uses these files to modify the sys.path list. it seems to me that the path configuration files need to be in a specific directory (given by sys.prefix or sys.exec_prefix) to be read. however, to put them there i need to be root. is there a way to test the packages (and to make use of their path configuration files) without travelling around as root? thanks! bas From M.Faassen@vet.uu.nl Thu Mar 18 16:47:59 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Thu, 18 Mar 1999 17:47:59 +0100 Subject: [Tutor] Question on lists References: <01be715b$6806eec0$0100007f@localhost> Message-ID: <36F12E3F.FD04AC0F@pop.vet.uu.nl> Jon Cosby wrote: [snip question] > # Factor by trial division: > def factor(n): > a = [] # Is there a better way to define a? > k = floor(sqrt(n)) > for i in range(2, k+1): > if n%i == 0: > a.insert(len(a), i) > factor(n/i) # Factor quotient > break > return a Hullo, This is a common phenomenon with recursive functions. In your function you initialize a to a new empty list each time factor() gets called. Instead, you need to pass the list that you are building along each time you call the function. The usual Python trick for this is to use default arguments to functions. This way you can pass the list on to each recursive function, and the function still works as expected if you use it with a single argument. Here's the improved function: from math import floor, sqrt def factor(n, a = []): # if no second argument is passed, use the empty list for a k = floor(sqrt(n)) for i in range(2, k+1): if n%i == 0: a.append(i) # more efficient and readable than a.insert(len(a), i) factor(n/i, a) # Factor quotient break return a print factor(36) # test things Note that there is still an algorithmic problem with your function; the last quotient doesn't appear to be added to the list (k becomes smaller than 2, namely 1, so the range command generates an empty list (effectively nothing). The condition that ends the recursion appears to be wrong (in your program it occurs whenever k <= 2). If this one of your first experiences with recursion, welcome to recursion, that mystical powerful way to program (though it isn't too fast in Python - go to functional programming languages such as lisp for that). Do amazing things by just letting functions call themselves; it's almost something for nothing! At least so it seemed to me at my first brush with recursion. Regards and good luck, Martijn From da@ski.org Thu Mar 18 21:23:56 1999 From: da@ski.org (David Ascher) Date: Thu, 18 Mar 1999 13:23:56 -0800 (Pacific Standard Time) Subject: [Tutor] Question on lists In-Reply-To: <36F12E3F.FD04AC0F@pop.vet.uu.nl> Message-ID: On Thu, 18 Mar 1999, Martijn Faassen wrote: > Here's the improved function: > > from math import floor, sqrt > > def factor(n, a = []): # if no second argument is passed, use the > k = floor(sqrt(n)) > for i in range(2, k+1): > if n%i == 0: > a.append(i) # more efficient and readable than a.insert(len(a), i) > factor(n/i, a) # Factor quotient > break > return a > > print factor(36) # test things Martijn should know better than to use an empty list as a default argument -- he was probably not awake when he wrote that. Try calling factor(36) a few times and look at the results: >>> factor(36) [2, 2, 3] >>> factor(36) [2, 2, 3, 2, 2, 3] >>> factor(36) [2, 2, 3, 2, 2, 3, 2, 2, 3] >>> factor(36) [2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3] That's because of the famous 'mutable default argument problem', discussed in the FAQ Question 6.25 http://www.python.org/doc/FAQ.html#6.25. The solution is to use None and do a test in the body of the function: def factor(n, a = None): if a is None: a = [] k = floor(sqrt(n)) for i in range(2, k+1): if n%i == 0: a.append(i) factor(n/i, a) break return a >>> factor(36) [2, 2, 3] >>> factor(36) [2, 2, 3] >>> factor(36) [2, 2, 3] >>> factor(36) [2, 2, 3] Note that the code *still* doesn't work (it's missing a 3), but I'll leave that one to others. =) --david From joe@strout.net Thu Mar 18 21:42:35 1999 From: joe@strout.net (Joseph J. Strout) Date: Thu, 18 Mar 1999 13:42:35 -0800 Subject: [Tutor] Question on lists In-Reply-To: References: <36F12E3F.FD04AC0F@pop.vet.uu.nl> Message-ID: At 1:23 PM -0800 03/18/99, David Ascher wrote: >That's because of the famous 'mutable default argument problem', discussed >in the FAQ Question 6.25 http://www.python.org/doc/FAQ.html#6.25. > >The solution is to use None and do a test in the body of the function A better solution still (IMHO) is to not pass the working content back to the function at all, but instead to return it and append it locally, as in the code I posted this morning. ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From TomJenkins@zentuit.com Thu Mar 18 22:04:04 1999 From: TomJenkins@zentuit.com (Tom Jenkins) Date: Thu, 18 Mar 1999 17:04:04 -0500 Subject: [Tutor] Question on lists In-Reply-To: References: <01be715b$6806eec0$0100007f@localhost> Message-ID: <199903182207.RAA14256@mail.digiweb.com> > # Factor by trial division: > def factor(n): > a = [] # Is there a better way to define a? > k = floor(sqrt(n)) > for i in range(2, k+1): > if n%i == 0: > a.append(i) ### (append rather than insert) > a.extend(factor(n/i)) ### add the factors of the quotient > return a ### don't break; just return > # if not divisible by any of the above, then it must be prime > return [n] > Hi Joe, I get an AttributeError on extend. Is this a 1.5.2 enhancement? Or is there a compile time option (I grabbed the binaries for both Win & Linux). Thanks, -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Tom Jenkins DevIS (http://www.devis.com) Y2K problem? The Mayans didn't have a millennium-2K problem! Eric S. Raymond at IPC7, on learning that the Mayan calendar takes 28 octillion years to wrap around From joe@strout.net Thu Mar 18 22:17:31 1999 From: joe@strout.net (Joseph J. Strout) Date: Thu, 18 Mar 1999 14:17:31 -0800 Subject: [Tutor] Question on lists In-Reply-To: <199903182207.RAA14256@mail.digiweb.com> References: <01be715b$6806eec0$0100007f@localhost> Message-ID: At 2:04 PM -0800 03/18/99, Tom Jenkins wrote: >> a.extend(factor(n/i)) ### add the factors of the quotient >I get an AttributeError on extend. Is this a 1.5.2 enhancement? Or is >there a compile time option (I grabbed the binaries for both Win & Linux). Whoops, must be a 1.5.2 thing. No wonder I hadn't heard of it before last week! =) Barring that, then just do: a = a + factor(n/i) which is pretty much equivalent (unless somebody else has a reference to a...). Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From tim_one@email.msn.com Fri Mar 19 09:30:50 1999 From: tim_one@email.msn.com (Tim Peters) Date: Fri, 19 Mar 1999 04:30:50 -0500 Subject: [Tutor] Question on lists In-Reply-To: <01be715b$6806eec0$0100007f@localhost> Message-ID: <000501be71eb$2d75ca20$409e2299@tim> The questions about recursion and ways to fiddle lists were covered well already, so I'd just like to encourage you to think about other ways to solve the problem. Attached is a very similar algorithm that doesn't use recursion. Which is faster? Which is clearer? Which gives the right answer ? not-rhetorical-questions-ly y'rs - tim def factor(n): a = [] d = 2 while d*d <= n: while n % d == 0: a.append(d) n = n / d d = d + 1 if n > 1 or not a: a.append(n) return a From M.Faassen@vet.uu.nl Mon Mar 22 09:23:39 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 22 Mar 1999 10:23:39 +0100 Subject: [Tutor] Question on lists References: Message-ID: <36F60C1B.2F90E1C8@pop.vet.uu.nl> David Ascher wrote: > Martijn should know better than to use an empty list as a default argument > -- he was probably not awake when he wrote that. I should know better; my excuse is that the bug just hasn't bitten me before; I was well aware of problems, but I keep mixing up *what* problems. I actually *did* think about doing the None thing but left it out for 'clarity'. Silly me. Thanks for the 'not awake' excuse, by the way. ;) > Try calling factor(36) a > few times and look at the results: Okay, now that I've actually been bitten by this bug I'll better my life. :) Regards, Martijn From alan.gauld@bt.com Thu Mar 25 14:34:56 1999 From: alan.gauld@bt.com (alan.gauld@bt.com) Date: Thu, 25 Mar 1999 14:34:56 -0000 Subject: [Tutor] __init__ problem Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB24E08E0@mbtlipnt02.btlabs.bt.co.uk> Given: class Transaction: def __init__(self): self.total = self.paid = self.change = 0 self.GST = 0.07 self.items = [] class RentalTransaction(Transaction): def __init__(self): Transaction.__init__(self) pass why do I get: >>> r = RentalTransaction() Traceback (innermost last): File "", line 1, in ? File "C:\Program Files\Python\Projects\transact.py", line 38, in __init__ Transaction.__init__(self) TypeError: unbound method must be called with class instance 1st argument >>> Alan G. From M.Faassen@vet.uu.nl Thu Mar 25 15:13:32 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Thu, 25 Mar 1999 16:13:32 +0100 Subject: [Tutor] __init__ problem References: <5104D4DBC598D211B5FE0000F8FE7EB24E08E0@mbtlipnt02.btlabs.bt.co.uk> Message-ID: <36FA529C.D334A0F6@pop.vet.uu.nl> alan.gauld@bt.com wrote: > > Given: > > class Transaction: > def __init__(self): > self.total = self.paid = self.change = 0 > self.GST = 0.07 > self.items = [] > > class RentalTransaction(Transaction): > def __init__(self): > Transaction.__init__(self) > pass > > why do I get: > > >>> r = RentalTransaction() > Traceback (innermost last): > File "", line 1, in ? > File "C:\Program Files\Python\Projects\transact.py", line 38, in __init__ > Transaction.__init__(self) > TypeError: unbound method must be called with class instance 1st argument > >>> Hm, this works for me. Are you sure you are re-importing the module into Python? Perhaps you're having some old module in memory that's disrupting stuff. Try quitting interactive mode and starting again. I myself don't use interactive mode a lot. To test I just added r = RentalTransaction() to the .py file with the source, and hit C-c C-c in Emacs to execute the buffer. :) Regards, Martijn From joe@strout.net Thu Mar 25 16:12:32 1999 From: joe@strout.net (Joseph J. Strout) Date: Thu, 25 Mar 1999 08:12:32 -0800 Subject: [Tutor] __init__ problem In-Reply-To: <5104D4DBC598D211B5FE0000F8FE7EB24E08E0@mbtlipnt02.btlabs.bt.co.uk> Message-ID: At 6:34 AM -0800 03/25/99, alan.gauld@bt.com wrote: >class RentalTransaction(Transaction): > def __init__(self): > Transaction.__init__(self) > pass > >why do I get: > >>>> r = RentalTransaction() >Traceback (innermost last): > File "", line 1, in ? > File "C:\Program Files\Python\Projects\transact.py", line 38, in __init__ > Transaction.__init__(self) >TypeError: unbound method must be called with class instance 1st argument >>>> Beats me. I copied and pasted your code, and it works just fine for me. The code is correct (though the "pass" on the second line of RentalTransaction. __init__ is superfluous). Looks like a bug in your Python, perhaps? Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From cwebster@math.tamu.edu Thu Mar 25 16:38:02 1999 From: cwebster@math.tamu.edu (Corran Webster) Date: Thu, 25 Mar 1999 10:38:02 -0600 (CST) Subject: [Tutor] __init__ problem In-Reply-To: <5104D4DBC598D211B5FE0000F8FE7EB24E08E0@mbtlipnt02.btlabs.bt.co.uk> Message-ID: <199903251638.KAA13573@radon.math.tamu.edu> On 25 Mar, alan.gauld@bt.com wrote: > Given: > > class Transaction: > def __init__(self): > self.total = self.paid = self.change = 0 > self.GST = 0.07 > self.items = [] > > class RentalTransaction(Transaction): > def __init__(self): > Transaction.__init__(self) > pass > > why do I get: > >>>> r = RentalTransaction() > Traceback (innermost last): > File "", line 1, in ? > File "C:\Program Files\Python\Projects\transact.py", line 38, in __init__ > Transaction.__init__(self) > TypeError: unbound method must be called with class instance 1st argument >>>> I copied and pasted the example and it works fine for me (Python 1.5.1 on Solaris), but I notice that you are indenting using both tabs and spaces. While the combination of tabs and spaces that appreared in you message appears to be consistent (each singly indented line has 4 spaces, each doubly indented line has 4 spaces followed by one tab), it might be worthwhile checking that the original version doesn't have an additional tab somewhere which is causing a conflict. In general it is a very bad idea to indent using spaces and tabs, use one or the other, but not both together. Unfortunately some editors can be bad about automatically inserting them. I'd recommend going through and replacing all your tabs by spaces to ensure correct indentation, and then seeing if it works. Regards, Corran From jlcos@accessone.com Thu Mar 25 20:35:14 1999 From: jlcos@accessone.com (Jon Cosby) Date: Thu, 25 Mar 1999 12:35:14 -0800 Subject: [Tutor] Writing to output file Message-ID: <01be76fe$fca9a6a0$0100007f@localhost> This should be an easy one, but I'm not finding it: How do you print to an output file? I'm trying to get the results of search.py below on a text file. Nothing I've tried seems to work. Maybe somebody can tell me why it's so slow, too; it took it 15 minutes to search a 115 MB archive. Jon Cosby -----------------------------------Start search.py-------------------------------------- # Search.py # Counts (case-insensitive) instances of string in a given directory and it's sub-directories # To-do: Include file names in the search; search multiple strings import re, sys, os def searchtext(filename, text): line = "initialized" infile = open(filename, 'r') outfile = open('c:\\data\\results.txt', 'w') a = [] while line != "": line = infile.readline() b = re.compile(text, re.I).findall(line) if len(b) > 0: a.extend(b) if len(a) > 0: print filename, text, ':', len(a) # I want to write this to 'results.txt' else: # Seems like a simple problem, but the return 0 # documents only give instructions infile.close() # for writing a string. outfile.close() def getFile(dir, text): dl = os.listdir(dir) for i in range(len(dl)): dl[i] = dir + '\\' + dl[i] if os.path.isfile(dl[i]): searchtext(dl[i], text) else: getFile(dl[i], text) if __name__ == '__main__': getFile(sys.argv[1], sys.argv[2]) ------------------------------------------------------End search.py----------------------------------------------------- From M.Faassen@vet.uu.nl Thu Mar 25 20:56:22 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Thu, 25 Mar 1999 21:56:22 +0100 Subject: [Tutor] Writing to output file References: <01be76fe$fca9a6a0$0100007f@localhost> Message-ID: <36FAA2F6.1EA2801@pop.vet.uu.nl> Hiya, You can write strings to a textfile, of course, and first translate other types to strings, using str() or using the % operator. "%s" % a_value, for instance. Another way is to redirect sys.stdout to a file object. That makes all your print statements print to the file instead of to the console: # import sys to get at stdout (standard output) import sys # open a file for writing f = open("myfile.txt", "w") # okay, our standard output is now that file sys.stdout = f # this prints to the file print "Foo", 6, "bar" I hope this helps, Regards, Martijn From joe@strout.net Thu Mar 25 21:00:47 1999 From: joe@strout.net (Joseph J. Strout) Date: Thu, 25 Mar 1999 13:00:47 -0800 Subject: [Tutor] Writing to output file In-Reply-To: <01be76fe$fca9a6a0$0100007f@localhost> Message-ID: You just set sys.stdout to your file... import sys ... oldstdout = sys.stdout sys.stdout = open("results.txt", 'w') print "here's some data...." ... sys.stdout = oldstdout Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From cwebster@math.tamu.edu Thu Mar 25 22:55:04 1999 From: cwebster@math.tamu.edu (Corran Webster) Date: Thu, 25 Mar 1999 16:55:04 -0600 (CST) Subject: [Tutor] Writing to output file In-Reply-To: <01be76fe$fca9a6a0$0100007f@localhost> Message-ID: <199903252255.QAA23618@radon.math.tamu.edu> On 25 Mar, Jon Cosby wrote: > This should be an easy one, but I'm not finding it: How do you print to an > output file? I'm trying to get the results of search.py below on a text > file. Nothing I've tried seems to work. To write to a file, you want to use the write method of the file object. Looking at your code, you want something like: outfile.write("%s:%d" % (text, len(a))) or outfile.write(text + ":" + `len(a)`) or even outfile.write(text + ":" + str(len(a))) or, as has been mentioned by others, you can redirect standard output to your file. > Maybe somebody can tell me why it's so slow, too; it took it 15 minutes to > search a 115 MB archive. I suspect a lot of the slowness comes from the fact that you are compiling your regular expression every time you go through the loop. Also I am a little unclear about why you need to keep a copy of the matches when all you seem to be interested in is the number of matches. Both these could be factors, as could be the simple fact that 115 MB is a lot of data, and Python is slower than C. For other issues, I think you want to open your results file in the getfile if you are going to be processing many different files - if you open and close the file within the searchtext function, you will overwrite the results file each time you search. If you don't need the full power of regular expressions you may be able to get away with using string.count(). Finally, the os.path.walk function will improve your getFile function - it does much the same thing, but is more robust and will work on any platform without modification. (Warning! The following code is untested - I only have 1.5.1 here, findall requires 1.5.2.) import os, re, sys def searchfile(text, filename): n = 0 pat = re.compile(text, re.I) try: infile = open(filename, "r") except IOError: # can't open the file or something similar print filename, ": Cannot open" else: line = infile.readline() while line: n = n + len(pat.findall(line)) line = infile.readline() print filename, ":", n infile.close() def searchdir(text, dir, names): for name in names: fullname = os.path.join(dir, name) if os.path.isfile(fullname): searchfile(text, fullname) def searchtree(text, dir): os.path.walk(dir, searchdir, text) if __name__ == "__main__": outfile = open('c:\\data\\results.txt', 'w') oldstdout = sys.stdout sys.stdout = outfile searchtree(sys.argv[1], sys.argv[2]) sys.stdout = oldstdout outfile.close() From jlcos@accessone.com Fri Mar 26 20:36:21 1999 From: jlcos@accessone.com (Jon Cosby) Date: Fri, 26 Mar 1999 12:36:21 -0800 Subject: [Tutor] Listing web contents Message-ID: <01be77c8$4f2d83a0$0100007f@localhost> Hi - Is there any way of listing the directory contents of a URL address? Something like dir = urllib.urlopen(url) os.listdir(dir) Thanks, Jon Cosby From joe@strout.net Fri Mar 26 20:50:12 1999 From: joe@strout.net (Joseph J. Strout) Date: Fri, 26 Mar 1999 12:50:12 -0800 Subject: [Tutor] Listing web contents In-Reply-To: <01be77c8$4f2d83a0$0100007f@localhost> Message-ID: At 12:36 PM -0800 03/26/99, Jon Cosby wrote: >Hi - Is there any way of listing the directory contents of a URL address? >Something like > >dir = urllib.urlopen(url) >os.listdir(dir) No. A URL address does not refer to a file. It refers to a document, which may (if the server so chooses) represent a listing of files, but it's still a document. Asking "how to list the directory contents of a URL address" doesn't make sense. Your example would be equivalent to: f = open("somefile.txt") os.listdir(f) Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From joe@strout.net Fri Mar 26 21:06:29 1999 From: joe@strout.net (Joseph J. Strout) Date: Fri, 26 Mar 1999 13:06:29 -0800 Subject: [Tutor] Listing web contents Message-ID: ...I should add that URL refer to documents when the protocol is http. If the protocol is something else, like ftp for example, then a URL could refer to a directory. I didn't think of that earlier. But I'm still pretty sure you can't use urllib to list the contents of such a directory; you'd have to use the ftp module instead. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From guido@CNRI.Reston.VA.US Sat Mar 27 13:11:42 1999 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Sat, 27 Mar 1999 08:11:42 -0500 Subject: [Tutor] Re: Listing web contents In-Reply-To: Your message of "Sat, 27 Mar 1999 01:06:31 EST." <199903270606.BAA23528@python.org> References: <199903270606.BAA23528@python.org> Message-ID: <199903271311.IAA28831@eric.cnri.reston.va.us> > Hi - Is there any way of listing the directory contents of a URL address? > Something like > > dir = urllib.urlopen(url) > os.listdir(dir) I'm assuming the URL points to an HTML document, and what you really want is a listing of URLs that the given URL refers to. In this case, you can cook something up using Python's HTML parsing library module (htmllib). I'm guessing that what you area really looking for is writing an automated tool that browses a tree of related pages on the web. In this case, please have a look at webchecker in the Python source distribution, Tools/webchecker/. PS. To the tutors. I see no significant difference between the tutor list and the help list. Perhaps tutor should be merged back into help? --Guido van Rossum (home page: http://www.python.org/~guido/) From Treed@CAM.ORG Sat Mar 27 13:19:27 1999 From: Treed@CAM.ORG (Tony Reed) Date: Sat, 27 Mar 1999 08:19:27 -0500 Subject: [Tutor] Listing web contents In-Reply-To: Message-ID: On 26/3/99, Joseph J. Strout wrote: :...I should add that URL refer to documents when the protocol is http. If :the protocol is something else, like ftp for example, then a URL could :refer to a directory. I didn't think of that earlier. But I'm still :pretty sure you can't use urllib to list the contents of such a directory; :you'd have to use the ftp module instead. What a URL returns is dependant on the protocol used and to a certain extent the server. So would tell the Apache server to look in the directory somedir for an document called index.html, and to display it. If no index.html is found, then Apace will return a listing of the directory. Of course, savvy web designers put an index.html in _every_ directory, to foil the nosy. . . -- Tony Reed From rbb@nebiometrics.com Sat Mar 27 13:21:53 1999 From: rbb@nebiometrics.com (Robert Burrows) Date: Sat, 27 Mar 1999 08:21:53 -0500 (EST) Subject: [Tutor] using command line arguments Message-ID: Hello, How can I use a command line argument in range()? I think I need something like C's atoi(). TIA, Robert Burrows rbb@nebiometrics.com From tismer@appliedbiometrics.com Sat Mar 27 15:06:52 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 27 Mar 1999 16:06:52 +0100 Subject: [Tutor] using command line arguments References: Message-ID: <36FCF40C.7EEBCCF8@appliedbiometrics.com> Robert Burrows wrote: > > Hello, > > How can I use a command line argument in range()? I think I need something > like C's atoi(). Right, a command line argument always comes as a string. The sys.argv list is a list of string which you need to parse. The string module has exactly that function which you mention: >>> import string >>> s="123" >>> string.atoi(s) 123 >>> Friends are string.atof for floats and string.atol for longs. string.atoi provides you with an extra parameter 'base' which defaults to 10, but here you can use 16 for instance if you want atoi to parse hexadecimal numbers. If you don't need an extra base parameter, it is easier to just use the standard functions int and float, which don't need to be imported. >>> int("123") 123 >>> There is another issue if you are handling command line parameters: Your program should recover gracefully if the user did not specify a parameter at all, or if it was no string. The easiest way to do this is to catch an exception. Here the quick example: >>> try: ... int("123c") ... except ValueError: ... print "this was not a number" ... raise SystemExit, 1 ... this was not a number Traceback (innermost last): File "", line 5, in ? SystemExit: 1 >>> Now, after we have figured out the details, we can write a minimum comand line handler for your case. The following sample program prints a number range to your console, or dies with an error message. #from here def int_tuple_from_cmdline(): """return exactly two integers form sys.argv or die with an error message """ import sys args = sys.argv[1:] # drop first entry (progpath) if len(args) != 2: raise SystemExit("expected two integer parameters") for i in range(len(args)): try: args[i] = int(args[i]) except ValueError: raise SystemExit("Parameter %d is no integer:%s" %(i+1, args[i])) return tuple(args) start, stop = int_tuple_from_cmdline() print range(start, stop) #to here Now, here is my session log: D:\tmp>python log.py 2 11 [2, 3, 4, 5, 6, 7, 8, 9, 10] D:\tmp>python log.py 2 expected two integer parameters D:\tmp>python log.py 2 notanumber Parameter 2 is no integer:notanumber hope this helps - ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tismer@appliedbiometrics.com Sat Mar 27 15:17:14 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 27 Mar 1999 16:17:14 +0100 Subject: [Tutor] Purpose of this list (was: Listing web contents) References: <199903270606.BAA23528@python.org> <199903271311.IAA28831@eric.cnri.reston.va.us> Message-ID: <36FCF67A.91B1ADBE@appliedbiometrics.com> [contents dropped] Guido: > PS. To the tutors. I see no significant difference between the tutor > list and the help list. Perhaps tutor should be merged back into > help? I don't think so. Python-help is anonymous. Its purpose is to help people with advice anonymously. After a helper has taken his hand, the rest of the conversation will usually disappear. Tutor has a slightly different purpose. Besides helping people, we also try to leave the conversations as a useful archive, which could serve as a basis for more. This could finally be material for some cookbook. (Python a'la carte). I don't just see it as help, but as a collection. For me this makes very much sense. The tutors are all suffering from being too experienced to imagine beginners problems. Offering a list where everybody is invited to ask any question brings things to mind which have vanished for a long time. Example: I would never think of writing about how to parse two integers from the command line if the question was not here. It encourages us to write some pieces of prose, instead of these short "ack - use int()" answers. I really do think about a book. cheers - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tismer@appliedbiometrics.com Sat Mar 27 15:37:08 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 27 Mar 1999 16:37:08 +0100 Subject: [Tutor] search path References: <36F12ED4.A0EFAB0@bio.uva.nl> Message-ID: <36FCFB24.39442E4B@appliedbiometrics.com> bas pels wrote: > > a small question about search paths. > > i have downloaded two so-called site-packages that both contain > x.pth files in their directories (so-called path configuration files). > from the reference manual (p.57) i learnt that the site module uses > these files to modify the sys.path list. > > it seems to me that the path configuration files need to be in > a specific directory (given by sys.prefix or sys.exec_prefix) to be > read. however, to put them there i need to be root. > > is there a way to test the packages (and to make use of their path > configuration files) without travelling around as root? Yes. I believe the easiest way is to manually adjust the startup a little and test the packages. If you have a look into site.py, you will see that function addsitedir(path) does what you want. I would start my testing script this way: #from here from site import addsitedir addsitedir('/home/pels/python/newstuff') del addsitedir # assuming a package "superpackage" in newstuff from superpackage import tester tester() #to here Makes sense? ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From ajs@ix.netcom.com Fri Mar 26 23:17:02 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Fri, 26 Mar 1999 18:17:02 -0500 Subject: [Tutor] Re: super classes Message-ID: <000201be7867$a6071840$2e82f3d0@seigel.eico.com> I have come across considerable discussion about "super" classing on the Python newsgroup. I need more of a what is than a how to. What is the definition, basic function, and significance of a super class. Help - as always - is appreciated From joe@strout.net Sat Mar 27 16:02:16 1999 From: joe@strout.net (Joseph J. Strout) Date: Sat, 27 Mar 1999 08:02:16 -0800 Subject: [Tutor] Re: super classes In-Reply-To: <000201be7867$a6071840$2e82f3d0@seigel.eico.com> Message-ID: A superclass is the parent of some other class, i.e., the class from which it is derived. When you write: class Shape: (...stuff all Shapes can do goes here...) class Circle(Shape): (...stuff specific to Circle shapes goes here...) then "Shape" is the superclass of Circle, and Circle is the subclass of Shape. Subclass/superclass is just a relationship, like child/parent. Another terminology which is often used is base class (Shape) and derived class (Circle). Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From ajs@ix.netcom.com Sat Mar 27 17:52:19 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Sat, 27 Mar 1999 12:52:19 -0500 Subject: [Tutor] Re: super classes Message-ID: <000801be787a$90647b00$2e82f3d0@seigel.eico.com> -----Original Message----- From: Joseph J. Strout To: Art Siegel ; Python Tutor Date: Saturday, March 27, 1999 11:03 AM Subject: Re: [Tutor] Re: super classes >A superclass is the parent of some other class, i.e., the class from which >it is derived. Now that I understand the terminology, a few more questions: Java has a "super" function, I believe, which I assume allows one to directly access methods of the parent class from inside the child class. Under what circumstances is it useful? Aren't, by definition, the parent's method already at the disposal of the child? What is the Python equivalent to the java super call? This is all coming up as I try to understand some java code and port it to Python. From tismer@appliedbiometrics.com Sat Mar 27 18:45:02 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 27 Mar 1999 19:45:02 +0100 Subject: [Tutor] Re: super classes References: <000801be787a$90647b00$2e82f3d0@seigel.eico.com> Message-ID: <36FD272E.599E400@appliedbiometrics.com> Art Siegel wrote: ... > Now that I understand the terminology, a few more questions: > > Java has a "super" function, I believe, which I assume allows one to > directly access methods of the parent class from inside the child class. > > Under what circumstances is it useful? Aren't, by definition, the parent's > method already at the disposal of the child? Usually yes. But sometimes your subclass or your instance defines its own version of an attribute, and the parent's is hidden. In Java, super allows you to access overridden methods. I think, this is also used if one wants to use the inherited function in the implementation of the new function. Something for "do the old thing, but this also". > What is the Python equivalent to the java super call? There is no direct equivalent, but something alike. If you have a derived class which redefines a method of its superclass and you need to call that, you have several choices: If you know the name of the superclass, you can simply refer to the class and use its method. Here an example which might clarify this. #from here class classa: def say(self, text): print "classa says '%s'" % text class classb(classa): def say(self, text): print "but classb says '%s'" % text inst = classb() #to here Now, inst can say hello: >>> inst.say("hello") but classb says 'hello' >>> What happens here is that the method "say" is looked up in inst's __dict__, where it is not found, so it is looked up in its class's __dict__ where it is found. The unbound method "say" of classb is then bound to inst (this means providing inst as parameter self) and called with the additional arguments. You can get the same result by calling th unbound method by yourself: >>> classb.say(inst, "hello") but classb says 'hello' >>> The same way, we can call the superclass's method >>> classa.say(inst, "hello") classa says 'hello' >>> This is allowed if inst is an instance of that class or any of its subclasses. Now, what if you want to access a superclass method without spelling its name? >>> inst.__class__.__bases__[0].say(inst, "hello") classa says 'hello' >>> inst always has an attribute __class__ which is its class. The class has an attribute __bases__ which is a tuple with all the classes which appeared in the class statement. In this case, there is just one entry, classa. In general, you must expect that a class is a subclass of more than one since Python has multiple inheritance. Then you need to know the class' index in the __bases__ tuple to call the right method. A more common problem is to access a class variable instead of the instance's. You know, every instance can redefine any attribute, wether the class provides it or not. I don't think it should be a recommended practice, but a situation might appear where a user is allowed to put arbitrary attributes into an instance, and you must be sure to use always the class attribute Assume the following situation: >>> class circle: ... defaultperimeter = 100 ... maximumperimeter = 100 ... def draw(self, x, y, perimeter): ... if perimeter > circle.maximumperimeter: ... perimeter = circle.defaultperimeter ... print "drawing at (%d,%d) p=%d" % (x, y, perimeter) ... >>> c=circle() >>> c.draw(10,10,200) drawing at (10,10) p=100 >>> c.defaultperimeter=1000 # ha, no chance! >>> c.draw(10,10,200) drawing at (10,10) p=100 >>> The instance cannot change the defaultperimeter. >>> c.defaultperimeter 1000 >>> Observe, that I used the class name "circle" explicitly. If I had referred to self.__class__, then a user could overwrite the defaultperimeter again, like this: >>> class circle: ... defaultperimeter = 100 ... maximumperimeter = 100 ... def draw(self, x, y, perimeter): ... if perimeter > self.__class__.maximumperimeter: ... perimeter = self.__class__.defaultperimeter ... print "drawing at (%d,%d) p=%d" % (x, y, perimeter) ... >>> class othercircle(circle): ... defaultperimeter = 1000 ... >>> c=othercircle() >>> c.draw(10, 20, 1000) drawing at (10,20) p=1000 >>> c.defaultperimeter = 200 >>> c.draw(10, 20, 1000) drawing at (10,20) p=1000 >>> As you can see, self.__class__ always referres to the actual class of the object, no matter that draw was defined in a different class. Here we overwrote a class attribute by subclassing, where the extra attribute of the instance was ignored. > This is all coming up as I try to understand some java code and port it to > Python. What are you porting, btw? ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From ajs@ix.netcom.com Sat Mar 27 19:49:25 1999 From: ajs@ix.netcom.com (Art Siegel) Date: Sat, 27 Mar 1999 14:49:25 -0500 Subject: [Tutor] Re: super classes Message-ID: <000601be788a$ee0e7f20$2e82f3d0@seigel.eico.com> >What are you porting, btw? > Thanks for response. I haven't absorbed it yet but I will. Your sample code is on point because I am doing graphic stuff - mostly with David's PyOpenGL. I have also taken a few shots at using OpenGL through Java using JPython. The one Java OpenGL implementation that I got at (with David's help) was Magician. Magician was commercial, its recent versions available for download were crippled - and, even if I wanted to license it, it in fact has been abandoned by its developers. So, what I am trying to port to JPython now are demos of GL4Java - a GNU license product and what looks like a good implementation of OpenGl for Java From ivnowa@hvision.nl Sat Mar 27 22:27:43 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sat, 27 Mar 1999 23:27:43 +0100 Subject: [Tutor] Python Snippets Site Message-ID: <199903272221.XAA10583@axil.hvision.nl> Howdy y'all, This tutor forum looks like a good place to announce my Python Snippets site. (In fact, it's been there for a while, but I've been reluctant to show it to the world.) In this case, "snippets" are small, *working* pieces of Python code. "Working" means here that you can take a snippet, feed it to Python, and it works right out of the box, without any implicit assumptions ("it's obvious that this module should have been imported" etc). People who have a certain Python question, can go to this site and see if the solution is there. Of course, anybody who wants learn something new can browse it. Anyway, that's the goal. So far not too much snippets are in the repository yet, and those who are, might need a double check. A lot of new ones are waiting on my hard disk, but before I spend much energy to working on this site, I want to know if it will be useful to a lot of people. Here's what I offer: ;^) http://www.hvision.nl/~ivnowa/snippets/ (It's still under construction, and as I said, there aren't many snippets yet, but before I continue to work on it, I need to know if it's worth working on.) Here's what I need: 1) Feedback. It's cool making such a site, but if I don't get any reactions, I won't know if things are good or bad, useful or crockish, etc. 2) More snippets. Lots more! The more, the merrier. A site with lots of snippets is of course more likely to have the solution to one's problem. I feel that picking snippets is not something one person should do. If your question is satisfactorily answered by a Python guru, and s/he has provided you with some nice code, I'd like to hear from it. Similarly, if you've just developed and posted some great code, I'd appreciate it if you could cc me the file. Sure enough, I can find it in the newsgroup myself -- but if anyone will be so friendly to forward his code, this would speed up things a lot. Because to be honest, I don't have much time to wade through myriads of files looking for that one gem of Python code. The email address is hey_psst@usa.net. (PSST stands for Python Snippet Support Team. ;^) Please do not use my other email addresses for this purpose. Depending on your reactions and support, this site will live... or die. Veel liefs, + Hans Nowak (Zephyr Falcon) + Homepage (under construction): http://www.cuci.nl/~hnowak/ + You call me a masterless man. You are wrong. I am my own master. + May Grandma Moses bake your heavy burden! From skip@mojam.com (Skip Montanaro) Sun Mar 28 14:04:14 1999 From: skip@mojam.com (Skip Montanaro) (skip@mojam.com (Skip Montanaro)) Date: Sun, 28 Mar 1999 09:04:14 -0500 (EST) Subject: [Tutor] Re: Listing web contents In-Reply-To: <199903271311.IAA28831@eric.cnri.reston.va.us> References: <199903270606.BAA23528@python.org> <199903271311.IAA28831@eric.cnri.reston.va.us> Message-ID: <14078.13833.155285.406265@toshiba-54-180.nycap.rr.com> Guido> PS. To the tutors. I see no significant difference between the Guido> tutor list and the help list. Perhaps tutor should be merged Guido> back into help? Well, recently the python-help list has turned into more-or-less a single question list, which boils down to someone asking, "how can I use Python to break into other computers?" to which someone replies, "Get a life! Read Eric Raymond's 'How to Become a Hacker'". Thus far I haven't seen any of that on the tutor list. ;-) Skip Montanaro | Mojam: "Uniting the World of Music" http://www.mojam.com/ skip@mojam.com | Musi-Cal: http://www.musi-cal.com/ 518-372-5583 From da@ski.org Mon Mar 29 06:03:11 1999 From: da@ski.org (David Ascher) Date: Sun, 28 Mar 1999 22:03:11 -0800 (Pacific Standard Time) Subject: [Tutor] Re: Listing web contents In-Reply-To: <199903271311.IAA28831@eric.cnri.reston.va.us> Message-ID: On Sat, 27 Mar 1999, Guido van Rossum wrote: > PS. To the tutors. I see no significant difference between the tutor > list and the help list. Perhaps tutor should be merged back into > help? Well, I think there's a difference, but perhaps it's too soon to tell. The biggest difference IMHO is that the tutor list is public and subscribed to by both tutors and novices -- and my hope is that some of the novices listening on the exchanges can learn from them, which doesn't happen w/ the help-list because of its relatively private nature (which I think is useful for some). Is that happening? I can't tell -- maybe some of the novices on the list can let us know. --david ascher From wilson@chemsun.chem.umn.edu Mon Mar 29 06:23:35 1999 From: wilson@chemsun.chem.umn.edu (Tim Wilson) Date: Mon, 29 Mar 1999 00:23:35 -0600 (CST) Subject: [Tutor] parsing chemical formula Message-ID: Greetings all: I'd like to write a small Python app to act as a command line molecular weight calculator. I'm a Python beginner, and I'm still in the planning stage on this one. Specifically, I'd like to get some expert opinions on the best way to parse the chemical formula to extract the type and number of atoms. An example (and chemistry refresher): H2SO4 contains 2 H, 1 S, 4 O atoms Mg(NO3)2 contains 1 Mg, 2 N, 6 O atoms (watch those parentheses!) Ideally, the user would run the program like this: $ molwt H2O The molecular weight of H2O is 18.02 g/mol. $ I've constructed a dictionary containing all of the element symbols and molecular weights. What type of data structure would be most appropriate for temporarily holding the number and type of atoms in the formula before the total mol. weights is calculated? Any other suggestions? I think this might be a nice little app that could be very useful. -Tim (At least that's what some people call me.) -- Timothy D. Wilson "A little song, a little dance, University of MN, chem. dept. a little seltzer down your wilson@chem.umn.edu pants." -Chuckles the Clown Phone: (612) 625-9828 as eulogized by Ted Baxter From DOUGS@oceanic.com Mon Mar 29 08:56:55 1999 From: DOUGS@oceanic.com (Doug Stanfield) Date: Sun, 28 Mar 1999 22:56:55 -1000 Subject: [Tutor] Re: Listing web contents Message-ID: <5650A1190E4FD111BC7E0000F8034D264A9EAB@HUINA> Guido, I believe there is a need for the public tutor list. I still consider myself a novice, and probably will be for the rest of my programming days. I'm on record in c.l.py advocating a different forum for those of us without the concentration of effort or otherwise the wherewithal required to progress to guru-dom. My lack of progress is because my work keeps me from being a programmer. Yet I have problems that need to be solved programmatically. Python has taken me further with less effort than any other 'way'. I'm one of those that will be filling in the third or fourth level down on the pyramid as Python spreads further through the computing community. There is a difference between documenting something and explaining it. Also between clarifying using the jargon of programming theory or language comparisons, and teaching the fundamental or elementary use of Python. There's definately a difference between a reference 'bot and an educator. I see this as the difference between c.l.py and the tutor list. And because the tutor list is public instead of hidden it is generating that atmosphere of trusting collegial discussion that leads to the 'ah ha' reaction. Someone once told me that an educator was someone who could correctly answer a question at least three uniquely different ways. The other necessary ingredient is the empathy to know which answer most resonates with the students current understanding. Personally I feel the empathy on the tutor list, but lacking that, it's most helpful to hear all the answers and all the perspectives. For me that most often leads to a higher level of comprehension. The nature of your question implied merging the tutor-list into the anonymous private answer help system. Perhaps you meant the opposite. If there could only be one I'd choose the tutor-list, but this email should be plenty of evidence that I don't feel the need for anonymity. Others must so I'd say both forums have their place. -Doug- > -----Original Message----- > From: David Ascher [mailto:da@ski.org] > Sent: Sunday, March 28, 1999 8:03 PM > To: Guido van Rossum > Cc: tutor@python.org > Subject: Re: [Tutor] Re: Listing web contents > > > On Sat, 27 Mar 1999, Guido van Rossum wrote: > > > PS. To the tutors. I see no significant difference > between the tutor > > list and the help list. Perhaps tutor should be merged back into > > help? > > Well, I think there's a difference, but perhaps it's too soon > to tell. The > biggest difference IMHO is that the tutor list is public and > subscribed to > by both tutors and novices -- and my hope is that some of the novices > listening on the exchanges can learn from them, which doesn't > happen w/ > the help-list because of its relatively private nature (which > I think is > useful for some). > > Is that happening? I can't tell -- maybe some of the novices > on the list > can let us know. > > --david ascher > > > > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://www.python.org/mailman/listinfo/tutor > From steve@estel.uindy.edu Mon Mar 29 11:07:54 1999 From: steve@estel.uindy.edu (Steve Spicklemire) Date: Mon, 29 Mar 1999 06:07:54 -0500 (EST) Subject: [Tutor] parsing chemical formula In-Reply-To: (message from Tim Wilson on Mon, 29 Mar 1999 00:23:35 -0600 (CST)) Message-ID: <199903291107.GAA04009@estel.uindy.edu> I guess we're neglecting the mass defect due to the chemical binding energy. ;-) How about something like: ---------------------------------------------------------------------- # I'm making these up.... I really don't know the correct masses off the top... # ElementDict = {'H':1.0, 'He':4.0, 'Li':6.0, 'O':16.0 } # and on and on ..... class ElementContainer: def __init__(self, name, count): self.name = name self.count = count class Molecule: elementList = None massDefect = None # just in case we want to get fancy... def addElement(self, name, count): if self.elementList is None: self.elementList = [] # a list allows multiple instances of ElementContainers # with the same element... self.elementList.append(ElementContainer(name, count)) def calcWeight(self): weight = 0.0 for element in self.elementList: weight = weight + element.count*ElementDict[element.name] if self.massDefect is not None: weight = weight - massDefect return weight if __name__=='__main__': m = Molecule() m.addElement('H',2) m.addElement('O',1) print "This damp example has a result of: ", m.calcWeight() ---------------------------------------------------------------------- -steve From jlcos@accessone.com Mon Mar 29 14:04:45 1999 From: jlcos@accessone.com (Jon Cosby) Date: Mon, 29 Mar 1999 06:04:45 -0800 Subject: [Tutor] Re: Listing web contents Message-ID: <01be79ed$195eb600$5b802bd1@jlcos> >I'm assuming the URL points to an HTML document, and what you really >want is a listing of URLs that the given URL refers to. > >In this case, you can cook something up using Python's HTML parsing >library module (htmllib). > >I'm guessing that what you area really looking for is writing an >automated tool that browses a tree of related pages on the web. >In this case, please have a look at webchecker in the Python source >distribution, Tools/webchecker/. > Websucker may be what I'm looking for. I'm trying to write a simple search engine; can you give me a hint as to how to edit websucker to return a list of web contents, rather than downloading the whole site? Thanks, Jon Cosby From guido@CNRI.Reston.VA.US Mon Mar 29 15:14:30 1999 From: guido@CNRI.Reston.VA.US (Guido van Rossum) Date: Mon, 29 Mar 1999 10:14:30 -0500 Subject: [Tutor] Re: Listing web contents In-Reply-To: Your message of "Mon, 29 Mar 1999 06:04:45 PST." <01be79ed$195eb600$5b802bd1@jlcos> References: <01be79ed$195eb600$5b802bd1@jlcos> Message-ID: <199903291514.KAA00524@eric.cnri.reston.va.us> > Websucker may be what I'm looking for. I'm trying to write a simple search > engine; can you give me a hint as to how to edit websucker to return a list > of web contents, rather than downloading the whole site? Sorry, I'm not very good at answering questions of this kind -- I'm simply too busy to sit down and figure it out. Basically, reading the source it should be easy enough to figure out which method saves the data and replace it (in a subclass) with one that indexes it. Other tutors may have more constructive help! (PS I take it back that the tutor list should be merged with the help list -- maybe vice versa...) --Guido van Rossum (home page: http://www.python.org/~guido/) From wilson@chemsun.chem.umn.edu Mon Mar 29 15:51:44 1999 From: wilson@chemsun.chem.umn.edu (Tim Wilson) Date: Mon, 29 Mar 1999 09:51:44 -0600 (CST) Subject: [Tutor] parsing chemical formula In-Reply-To: <199903291107.GAA04009@estel.uindy.edu> Message-ID: On Mon, 29 Mar 1999, Steve Spicklemire wrote: Steve, thanks for the example. I'm still a little intimidated by the OOP features that Python offers. I should probably just bit the bullet and dig in and learn it. I think I understand how a list would be useful to store the atoms until the total mass can be calculated. I don't see where you parse the user input here. I'll be more specific: How will the program be able to figure out how many atoms of each type are in a molecule like (NH4)3PO4? How will it know the difference between CO (carbon monoxide) and Co (a cobalt atom)? It seems to be that figuring out the difference between Co and CO and interpreting the parentheses correctly is fairly tricky (at least for me). Any other suggestions would be appreciated. -Tim Steve's sample code follows: > # I'm making these up.... I really don't know the correct masses off the top... > # > > ElementDict = {'H':1.0, 'He':4.0, 'Li':6.0, 'O':16.0 } # and on and on ..... > > class ElementContainer: > > def __init__(self, name, count): > self.name = name > self.count = count > > > class Molecule: > > elementList = None > massDefect = None # just in case we want to get fancy... > > def addElement(self, name, count): > > if self.elementList is None: > self.elementList = [] # a list allows multiple instances of ElementContainers > # with the same element... > > self.elementList.append(ElementContainer(name, count)) > > def calcWeight(self): > weight = 0.0 > > for element in self.elementList: > weight = weight + element.count*ElementDict[element.name] > > if self.massDefect is not None: > weight = weight - massDefect > > return weight > > > if __name__=='__main__': > m = Molecule() > > m.addElement('H',2) > m.addElement('O',1) > > print "This damp example has a result of: ", m.calcWeight() > > > ---------------------------------------------------------------------- > -steve > > > > -- Timothy D. Wilson "A little song, a little dance, University of MN, chem. dept. a little seltzer down your wilson@chem.umn.edu pants." -Chuckles the Clown Phone: (612) 625-9828 as eulogized by Ted Baxter From M.Faassen@vet.uu.nl Mon Mar 29 16:34:41 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 29 Mar 1999 18:34:41 +0200 Subject: [Tutor] parsing chemical formula References: Message-ID: <36FFABA1.983ED48F@pop.vet.uu.nl> Tim Wilson wrote: > > I'm still a little intimidated by the OOP > features that Python offers. I should probably just bit the bullet and dig > in and learn it. For starts, you might try thinking of a class instance as a Python dictionary. For instance the dictionary: # make a dictionary aFoo = {} # fill dictionary with data aFoo['one'] = 1 aFoo['two'] = 2 aFoo['three'] = 3 is quite similar to the class: # make a class (and also say somehow how the data inside is structured) class Foo: def __init__(self, one, two, three): self.one = one self.two = two self.three = three # fill an instance of Foo (aFoo) with data aFoo = Foo(1, 2, 3) Of course, initialization in __init__ isn't necessary, you could do: class Foo: pass # empty class aFoo = Foo() aFoo.one = 1 aFoo.two = 2 aFoo.three = 3 But the nice thing about a class (as compared to a dictionary) is that it's easy to add functions to a class that actually do something with the data stored inside (for instance, do some calculation). By initializing (lots of) the data in an __init__ function, you're sure these data members are there during the class's lifetime, as __init__ is always executed when the class is created: class Foo: def __init__(self, one, two, three): self.one = one self.two = two self.three = three def add_all(self): return self.one + self.two + self.three aFoo = Foo(1, 2, 3) print aFoo.add_all() # prints 6 aBar = Foo(3, 3, 3) print aBar.add_all() # prints 9 Of course, it's possible to write functions that do this with dictionaries, but classes add some nice extra structure that is helpful. They can be useful to bundle data and the functions that operate on that data together, without the outside world needing to know what's going on exactly inside the data and the functions (data hiding). Classes of course also offer inheritance, but that's for later. > I think I understand how a list would be useful to store > the atoms until the total mass can be calculated. I don't see where you > parse the user input here. > I'll be more specific: > How will it know the difference between CO (carbon monoxide) > and Co (a cobalt atom)? Hmm. You have this dictionary with as the keys the various element names (and as value their mass), let's call it 'elements', and a string describing a molecule called 'molecule'. An approach may be: # untested code! Doesn't do boundary checking! is probably slow! def getWeightForNextElement(molecule, elements): # assumption: all elements are a maximum of two characters, where the first # is a capital, and the second is lowercase # if 'molecule' doesn't start with an atom identifier at all we return 'None' if molecule[0] not in string.uppercase: return None if molecule[1] not in string.lowercase: # okay, we're dealing with a single char element, look it up: if elements.has_key(molecule[0]): return (elements[molecule[0]), 1) # return weight and length of what we read else: return None # not a known element else: # okay, we're dealing with a two char element: if elements.has_key(molecule[0:1]): return (elements[molecule[0:1]), 2) # return weight and length of str we read else: return None # not a known element This function, if it works at all :), could be fed with a molecule string. If the function doesn't return None and thus recognizes the weight, it'll return the weight value, and the length (1 or 2) of the characters it read. You can then strip those characters from the front of the string, feed in the string again, and get the weight of the next character, until you read the string. Of course it doesn't work with '()' or numbers yet. > How will the program be > able to figure out how many atoms of each type are in a molecule like > (NH4)3PO4? Numbers first. You can adapt the previous function (better rewrite it anyway, it was just a bad first attempt :) so that it recognizes if digits are involved (string.digits). What it should do is that as soon as it encounters a digit, it scans if any digits follow. It'll compose a string of all digits read. It then should convert (with int(), let's say) this string to an actual amount. It should then somehow notify the calling function that it read a number, and the value of this number. Since the function doesn't support this I suggested rewriting. Better perhaps to do any weight calculations later anyway, and just return the elements read (not their weights), too. Parenthesis. You could do something like this: * If you read a '(' parenthesis, add create a new empty list of elements, and add this to the list of elements read. * Do this whenever you see another '(' (a nested '('). So you might get a list nested in a list nested in a list, if you have a lot of ((())) stuff. * Until you read a ')' parenthesis, add any read elements to the current list (or their mass). If you read numbers, of course do the right multiplications, or simply add as many elements to the current list as the number indicates. When you've read the string (and the string makes sense syntactically; doesn't contain unknown elements or weird parenthesis such as '(()'), you'll end up with a big master list of elements (or mass) that may contain sublists of a similar structure. Now you want to add the weight of it all: # untested! def add_everything(master_list, elements): sum = 0.0 for el in master_list: if el is types.ListType: # recursion; add everything in the sublist and add it to the master sum sum = sum + add_everything(el, elements) else: sum = sum + elements[el] return sum A whole long post. I hope I'm making sense somewhat and that it helps. :) Please let us all know! Regards, Martijn From bwinton@tor.dhs.org Tue Mar 30 01:41:07 1999 From: bwinton@tor.dhs.org (Blake Winton) Date: Mon, 29 Mar 1999 20:41:07 -0500 (EST) Subject: [Tutor] parsing chemical formula In-Reply-To: from "Tim Wilson" at Mar 29, 99 09:51:44 am Message-ID: <199903300141.UAA25612@tor.dhs.org> > On Mon, 29 Mar 1999, Steve Spicklemire wrote: > don't see where you parse the user input here. I'll be more specific: > How will the program be able to figure out how many atoms of each type > are in a molecule like (NH4)3PO4? How will it know the difference > between CO (carbon monoxide) and Co (a cobalt atom)? It seems to be > that figuring out the difference between Co and CO and interpreting > the parentheses correctly is fairly tricky (at least for me). Any > other suggestions would be appreciated. I've been playing around with John Aycock's "Little Language Framework" (at http://www.csc.uvic.ca/~aycock/), and it looks pretty much perfect for what you're trying to do, so I whipped a quick little something up. WARNING!!! : It's not really suitable for the tutor list, since it relies on a non-standard Python module, and compiler technology isn't really beginner material. But it works, so far. I can try to explain what I did, if anyone thinks it'll be useful, but I think the explanation would be better kept to email. Later, Blake. From bwinton@tor.dhs.org Tue Mar 30 01:47:26 1999 From: bwinton@tor.dhs.org (Blake Winton) Date: Mon, 29 Mar 1999 20:47:26 -0500 (EST) Subject: [Tutor] parsing chemical formula In-Reply-To: from "Tim Wilson" at Mar 29, 99 09:51:44 am Message-ID: <199903300147.UAA25673@tor.dhs.org> > On Mon, 29 Mar 1999, Steve Spicklemire wrote: > Any other suggestions would be appreciated. And of course, I forget to tell you all where the solution is... :P Written by me: http://tor.dhs.org/%7Ebwinton/python/chemweight.py # My program Writtne by John: http://tor.dhs.org/%7Ebwinton/python/generic.py # The framework http://tor.dhs.org/%7Ebwinton/python/framework-0.3/doc/faq.html # A FAQ Sorry about that... Blake. P.S. John, if you're reading this, I couldn't find a "Token" class in generic.py. Is it in an example file, or should there be a stub in generic.py? The docs seem to suggest the latter. From tim_one@email.msn.com Tue Mar 30 06:50:10 1999 From: tim_one@email.msn.com (Tim Peters) Date: Tue, 30 Mar 1999 01:50:10 -0500 Subject: [Tutor] parsing chemical formula In-Reply-To: Message-ID: <000201be7a79$8eb969e0$ee9e2299@tim> [Tim Wilson] > I'd like to write a small Python app to act as a command line molecular > weight calculator. I'm a Python beginner, and I'm still in the planning > stage on this one. Specifically, I'd like to get some expert opinions on > the best way to parse the chemical formula to extract the type and number > of atoms. ... Well, the syntax of a formula is recursively defined: each chunk of the expression is either an element name, or is itself an expression enclosed in parentheses (that's the recursion ), and in either case followed by an optional "repeat count". Parsing isn't easy, but can be learned. I'm going to attach a complete solution to this one, allowing you to type e.g. D:\Python>python misc/molw.py ? H2O input must have two fields ? molw H2O molecular weight 18.0152 ? syms H2O H (Hydrogen): 2 O (Oxygen): 1 ? molw NaCl molecular weight 58.44277 ? syms (H2O4)12 H (Hydrogen): 24 O (Oxygen): 48 ? PbUr input must have two fields ? molw PbU molecular weight 445.229 ? syms PbU Pb (Lead): 1 U (Uranium): 1 ? molw Mg(NO3)2 molecular weight 148.3148 ? syms Mg(NO3)2 Mg (Magnesium): 1 N (Nitrogen): 2 O (Oxygen): 6 ? molw ClAp 'Ap' is not an element symbol: ClAp ^ ? The parsing technique here is called "recursive descent with one token lookahead". That may all sound like gibberish now, but once you understand the (simple) code, each word in that will be seen to have a definite meaning. The structure of the parsing code matches the informal English recursive definition above very closely. That's the great advantage of recursive descent: it's inuitive. You'll find that it won't accept any illegal formulas, but that sometimes the error msgs it produces are odd. This should give you a lot of sympathy for Guido's job <0.9 wink>. Apart from the parser, there's a Tokenizer class here that's a bit of overkill in this particular context. The tokenizer simply looks at "the next" piece of the formula, and classifies the first chunk of it as to whether it looks like a parenthesis, element name, repeat count, or end of input. The *kind* of token is stored in global ttype, and the *value* of the token is stored in global tvalue. The parsing code makes its decisions based on ttype, and uses tvalue as needed to extract specific information. This is a classic structure for parsers, and works very well in practice -- provided you get used to it first, and don't get too terribly ambitious. Before the advent of machine-generated table-driven parsers, entire compilers (e.g. Pascal's) were written "by hand" this way. It's easy enough to pick up that everyone ought to learn how to do it -- which is why I'm posting the whole thing to the tutor list . The rest of it is simpler, and should remind you of the series/parallel circuit example Gordon posted to c.l.py a while back. A formula is a sequence of elements and subformulas, and an ElementSequence class models that as a list (a list of what? of Elements and other ElementSequences! again this matches the English description very closely). It's trivial for an Element to report its own weight, and an ElementSequence just has to ask its contained guys for their weights and sum them up. recursion-is-your-friend-because-nature-is-recursive-ly y'rs - tim # symbol, name, atomic number, molecular weight _data = r"""'Ac', 'Actinium', 89, 227 'Ag', 'Silver', 47, 107.868 'Al', 'Aluminum', 13, 26.98154 'Am', 'Americium', 95, 243 'Ar', 'Argon', 18, 39.948 'As', 'Arsenic', 33, 74.9216 'At', 'Astatine', 85, 210 'Au', 'Gold', 79, 196.9665 'B', 'Boron', 5, 10.81 'Ba', 'Barium', 56, 137.33 'Be', 'Beryllium', 4, 9.01218 'Bi', 'Bismuth', 83, 208.9804 'Bk', 'Berkelium', 97, 247 'Br', 'Bromine', 35, 79.904 'C', 'Carbon', 6, 12.011 'Ca', 'Calcium', 20, 40.08 'Cd', 'Cadmium', 48, 112.41 'Ce', 'Cerium', 58, 140.12 'Cf', 'Californium', 98, 251 'Cl', 'Chlorine', 17, 35.453 'Cm', 'Curium', 96, 247 'Co', 'Cobalt', 27, 58.9332 'Cr', 'Chromium', 24, 51.996 'Cs', 'Cesium', 55, 132.9054 'Cu', 'Copper', 29, 63.546 'Dy', 'Dysprosium', 66, 162.50 'Er', 'Erbium', 68, 167.26 'Es', 'Einsteinium', 99, 254 'Eu', 'Europium', 63, 151.96 'F', 'Fluorine', 9, 18.998403 'Fe', 'Iron', 26, 55.847 'Fm', 'Fermium', 100, 257 'Fr', 'Francium', 87, 223 'Ga', 'Gallium', 31, 69.735 'Gd', 'Gadolinium', 64, 157.25 'Ge', 'Germanium', 32, 72.59 'H', 'Hydrogen', 1, 1.0079 'He', 'Helium', 2, 4.0026 'Hf', 'Hafnium', 72, 178.49 'Hg', 'Mercury', 80, 200.59 'Ho', 'Holmium', 67, 164.9304 'I', 'Iodine', 53, 126.9045 'In', 'Indium', 49, 114.82 'Ir', 'Iridium', 77, 192.22 'K', 'Potassium', 19, 39.0983 'Kr', 'Krypton', 36, 83.80 'La', 'Lanthanum', 57, 138.9055 'Li', 'Lithium', 3, 6.94 'Lr', 'Lawrencium', 103, 260 'Lu', 'Lutetium', 71, 174.96 'Md', 'Mendelevium', 101, 258 'Mg', 'Magnesium', 12, 24.305 'Mn', 'Manganese', 25, 54.9380 'Mo', 'Molybdenum', 42, 95.94 'N', 'Nitrogen', 7, 14.0067 'Na', 'Sodium', 11, 22.98977 'Nb', 'Niobium', 41, 92.9064 'Nd', 'Neodymium', 60, 144.24 'Ne', 'Neon', 10, 20.17 'Ni', 'Nickel', 28, 58.71 'No', 'Nobelium', 102, 259 'Np', 'Neptunium', 93, 237.0482 'O', 'Oxygen', 8, 15.9994 'Os', 'Osmium', 76, 190.2 'P', 'Phosphorous', 15, 30.97376 'Pa', 'Proactinium', 91, 231.0359 'Pb', 'Lead', 82, 207.2 'Pd', 'Palladium', 46, 106.4 'Pm', 'Promethium', 61, 145 'Po', 'Polonium', 84, 209 'Pr', 'Praseodymium', 59, 140.9077 'Pt', 'Platinum', 78, 195.09 'Pu', 'Plutonium', 94, 244 'Ra', 'Radium', 88, 226.0254 'Rb', 'Rubidium', 37, 85.467 'Re', 'Rhenium', 75, 186.207 'Rh', 'Rhodium', 45, 102.9055 'Rn', 'Radon', 86, 222 'Ru', 'Ruthenium', 44, 101.07 'S', 'Sulfur', 16, 32.06 'Sb', 'Antimony', 51, 121.75 'Sc', 'Scandium', 21, 44.9559 'Se', 'Selenium', 34, 78.96 'Si', 'Silicon', 14, 28.0855 'Sm', 'Samarium', 62, 150.4 'Sn', 'Tin', 50, 118.69 'Sr', 'Strontium', 38, 87.62 'Ta', 'Tantalum', 73, 180.947 'Tb', 'Terbium', 65, 158.9254 'Tc', 'Technetium', 43, 98.9062 'Te', 'Tellurium', 52, 127.60 'Th', 'Thorium', 90, 232.0381 'Ti', 'Titanium', 22, 47.90 'Tl', 'Thallium', 81, 204.37 'Tm', 'Thulium', 69, 168.9342 'U', 'Uranium', 92, 238.029 'Unh', 'Unnilhexium', 106, 263 'Unp', 'Unnilpentium', 105, 260 'Unq', 'Unnilquadium', 104, 260 'Uns', 'Unnilseptium', 107, 262 'V', 'Vanadium', 23, 50.9415 'W', 'Tungsten', 74, 183.85 'Xe', 'Xenon', 54, 131.30 'Y', 'Yttrium', 39, 88.9059 'Yb', 'Ytterbium', 70, 173.04 'Zn', 'Zinc', 30, 65.38 'Zr', 'Zirconium', 40, 91.22""" class Element: def __init__(self, symbol, name, atomicnumber, molweight): self.sym = symbol self.name = name self.ano = atomicnumber self.mw = molweight def getweight(self): return self.mw def addsyms(self, weight, result): result[self.sym] = result.get(self.sym, 0) + weight def build_dict(s): import string answer = {} for line in string.split(s, "\n"): symbol, name, num, weight = eval(line) answer[symbol] = Element(symbol, name, num, weight) return answer sym2elt = build_dict(_data) del _data class ElementSequence: def __init__(self, *seq): self.seq = list(seq) self.count = 1 def append(self, thing): self.seq.append(thing) def getweight(self): sum = 0.0 for thing in self.seq: sum = sum + thing.getweight() return sum * self.count def set_count(self, n): self.count = n def __len__(self): return len(self.seq) def addsyms(self, weight, result): totalweight = weight * self.count for thing in self.seq: thing.addsyms(totalweight, result) def displaysyms(self): result = {} self.addsyms(1, result) items = result.items() items.sort() for sym, count in items: print sym, "(" + sym2elt[sym].name + "):", count NAME, NUM, LPAREN, RPAREN, EOS = range(5) import re _lexer = re.compile(r"[A-Z][a-z]*|\d+|[()]|").match del re class Tokenizer: def __init__(self, input): self.input = input + "" self.i = 0 def gettoken(self): global ttype, tvalue self.lasti = self.i m = _lexer(self.input, self.i) if m is None: self.error("unexpected character") self.i = m.end() tvalue = m.group() if tvalue == "(": ttype = LPAREN elif tvalue == ")": ttype = RPAREN elif tvalue == "": ttype = EOS elif "0" <= tvalue[0] <= "9": ttype = NUM tvalue = int(tvalue) else: ttype = NAME def error(self, msg): emsg = msg + ":\n" emsg = emsg + self.input[:-5] + "\n" # strip emsg = emsg + " " * self.lasti + "^\n" raise ValueError(emsg) def parse(s): global t, ttype, tvalue t = Tokenizer(s) t.gettoken() seq = parse_sequence() if ttype != EOS: t.error("expected end of input") return seq def parse_sequence(): global t, ttype, tvalue seq = ElementSequence() while ttype in (LPAREN, NAME): # parenthesized expression or straight name if ttype == LPAREN: t.gettoken() thisguy = parse_sequence() if ttype != RPAREN: t.error("expected right paren") t.gettoken() else: assert ttype == NAME if sym2elt.has_key(tvalue): thisguy = ElementSequence(sym2elt[tvalue]) else: t.error("'" + tvalue + "' is not an element symbol") t.gettoken() # followed by optional count if ttype == NUM: thisguy.set_count(tvalue) t.gettoken() seq.append(thisguy) if len(seq) == 0: t.error("empty sequence") return seq import string while 1: x = raw_input("? ") fields = string.split(x) if len(fields) != 2: print "input must have two fields" continue action, formula = fields ok = 0 try: seq = parse(formula) ok = 1 except ValueError, detail: print str(detail) if not ok: continue if action == "molw": print "molecular weight", seq.getweight() elif action == "syms": seq.displaysyms() else: print "unknown action:", action From tismer@appliedbiometrics.com Tue Mar 30 11:53:48 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Tue, 30 Mar 1999 13:53:48 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> Message-ID: <3700BB4C.2C430E63@appliedbiometrics.com> Tim Peters wrote: ... > NAME, NUM, LPAREN, RPAREN, EOS = range(5) As I see this idiom of creating ENUM-alike constants appear again (see doctest), this deserves an entry in some howto. Tim, when did you start using it? Very elegant. ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From M.Faassen@vet.uu.nl Tue Mar 30 12:02:54 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 30 Mar 1999 14:02:54 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> Message-ID: <3700BD6E.84DA979@pop.vet.uu.nl> Christian Tismer wrote: > > Tim Peters wrote: > ... > > > NAME, NUM, LPAREN, RPAREN, EOS = range(5) > > As I see this idiom of creating ENUM-alike constants > appear again (see doctest), this deserves an entry in > some howto. Tim, when did you start using it? > Very elegant. It's a neat idiom. I'm not sure where I got it from (I've used it too), but I recall a while back I was pondering the problem. You see, I hate counting, and one needs to *count* to do this trick with range. C's 'enum' doesn't have this problem. So I tried to figure out an elegant way to do something like: enum(NAME, NUM, LPAREN, RPAREN, EOS) but couldn't come up with anything that worked well. The main problem is of course that NAME etc simply aren't defined, so you get an exception. You can catch that exception of course, and then define, but so far that's still a kludge. Perhaps: enum('NAME', 'NUM', 'LPAREN', 'RPAREN', 'EOS') could work..still, that is too much typing. :) Of course this doesn't belong on tutor but in the newsgroup, really, but I felt so much mental exertion on my part deserved some mention somewhere, and this was a good opportunity. :) Regards, Martijn From tismer@appliedbiometrics.com Tue Mar 30 13:17:40 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Tue, 30 Mar 1999 15:17:40 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> Message-ID: <3700CEF4.D82CF0C4@appliedbiometrics.com> Martijn Faassen wrote: > > Christian Tismer wrote: > > > > Tim Peters wrote: > > ... > > > > > NAME, NUM, LPAREN, RPAREN, EOS = range(5) > > > > As I see this idiom of creating ENUM-alike constants > > appear again (see doctest), this deserves an entry in > > some howto. Tim, when did you start using it? > > Very elegant. > > It's a neat idiom. I'm not sure where I got it from (I've used it too), > but I recall a while back I was pondering the problem. You see, I hate > counting, and one needs to *count* to do this trick with range. C's > 'enum' doesn't have this problem. So I tried to figure out an elegant > way to do something like: > > enum(NAME, NUM, LPAREN, RPAREN, EOS) > > but couldn't come up with anything that worked well. The main problem is > of course that NAME etc simply aren't defined, so you get an exception. > You can catch that exception of course, and then define, but so far > that's still a kludge. > > Perhaps: enum('NAME', 'NUM', 'LPAREN', 'RPAREN', 'EOS') could > work..still, that is too much typing. :) > > Of course this doesn't belong on tutor but in the newsgroup, really, but > I felt so much mental exertion on my part deserved some mention > somewhere, and this was a good opportunity. :) :-)) Well, how 'bout this? You can even save to type those ugly commas: >>> def enum(tokens, base=0): ... import string ... lis = string.split(tokens) ... g = globals() ... for i in range(len(lis)): ... g[lis[i]] = i+base ... >>> enum("ONE TWO THREE", 1) >>> ONE, TWO, THREE (1, 2, 3) >>> ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From M.Faassen@vet.uu.nl Tue Mar 30 15:23:11 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 30 Mar 1999 17:23:11 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> Message-ID: <3700EC5F.6B8E0490@pop.vet.uu.nl> Christian Tismer wrote: > > Martijn Faassen wrote: [enum thoughts] > :-)) > > Well, how 'bout this? > You can even save to type those ugly commas: > > >>> def enum(tokens, base=0): > ... import string > ... lis = string.split(tokens) > ... g = globals() > ... for i in range(len(lis)): > ... g[lis[i]] = i+base > ... > >>> enum("ONE TWO THREE", 1) > >>> ONE, TWO, THREE > (1, 2, 3) > >>> Cool, I hadn't thought of using string.split to reduce the amount of quotes (and commas!). Still not exactly of the elegance of: ONE, TWO, THREE = range(3) # this *looks* like Python code (as it is :) but almost there, and no counting! Fun! Regards, Martijn From tismer@appliedbiometrics.com Tue Mar 30 16:03:48 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Tue, 30 Mar 1999 18:03:48 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> <3700EC5F.6B8E0490@pop.vet.uu.nl> Message-ID: <3700F5E4.E6231638@appliedbiometrics.com> Martijn Faassen wrote: > > Christian Tismer wrote: > > > > Martijn Faassen wrote: > [enum thoughts] > > :-)) [me, with an enum impl by strings] > Cool, I hadn't thought of using string.split to reduce the amount of > quotes (and commas!). Still not exactly of the elegance of: > > ONE, TWO, THREE = range(3) # this *looks* like Python code (as it is > :) > > but almost there, and no counting! Now, if you must, how 'bout this: >>> def make_enum(func, base): ... g = globals() ... for i in range(func.func_code.co_argcount): ... g[func.func_code.co_varnames[i]] = i+base ... del g[func.__name__] ... >>> # after this, you can fake an enum like this >>> def enum(ONE, TWO, THREE) : pass >>> # and you activate it so: >>> make_enum(enum, 1) >>> # here we are: >>> ONE, TWO, THREE (1, 2, 3) >>> I think I have to duck and cover if Timbot watches me :-) ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From M.Faassen@vet.uu.nl Tue Mar 30 17:08:36 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 30 Mar 1999 19:08:36 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> <3700EC5F.6B8E0490@pop.vet.uu.nl> <3700F5E4.E6231638@appliedbiometrics.com> Message-ID: <37010514.177A92E5@pop.vet.uu.nl> Christian Tismer wrote: > Now, if you must, how 'bout this: > > >>> def make_enum(func, base): > ... g = globals() > ... for i in range(func.func_code.co_argcount): > ... g[func.func_code.co_varnames[i]] = i+base > ... del g[func.__name__] > ... > >>> # after this, you can fake an enum like this > >>> def enum(ONE, TWO, THREE) : pass > >>> # and you activate it so: > >>> make_enum(enum, 1) > >>> # here we are: > >>> ONE, TWO, THREE > (1, 2, 3) > >>> Hm, this is too many lines [whine, nag, never-pleased-ly yours]. As kludge trickery though, it's way cool! > I think I have to duck and cover if Timbot watches me :-) Indeed, Timbot is sure to catch us at this soon! Martijn From tismer@appliedbiometrics.com Tue Mar 30 17:43:21 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Tue, 30 Mar 1999 19:43:21 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> <3700EC5F.6B8E0490@pop.vet.uu.nl> <3700F5E4.E6231638@appliedbiometrics.com> <37010514.177A92E5@pop.vet.uu.nl> Message-ID: <37010D39.971056D8@appliedbiometrics.com> Sorry, tutor list, but I could not resist. I will stop this now. (Ahem) Martijn Faassen wrote: > > Christian Tismer wrote: > > > Now, if you must, how 'bout this: [second try. But watch out...] > Hm, this is too many lines [whine, nag, never-pleased-ly yours]. As > kludge trickery though, it's way cool! > > > I think I have to duck and cover if Timbot watches me :-) > > Indeed, Timbot is sure to catch us at this soon! Now I will him give a final reason to pursue me. def enum(func): g = globals() ; code = func.func_code base = apply(func, (0,)*code.co_argcount) or 0 for i in range(code.co_argcount): g[code.co_varnames[i]] = i+base Yeees, this is hefty. But now watch out what I got for the application: from spinners.pirx import enum # har har enum(lambda ONE, TWO, THREE, FOUR, FIVE:1) # this gives us an enumeration, based from 1. Believe me. >>> ONE, TWO, THREE, FOUR, FIVE (1, 2, 3, 4, 5) Naaah? Oh yeah, now we really have a "useful" lambda example :-))) ciao - chris.ducked.and.covered.for.the.rest.of.... -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From tismer@appliedbiometrics.com Tue Mar 30 18:04:35 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Tue, 30 Mar 1999 20:04:35 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> <3700EC5F.6B8E0490@pop.vet.uu.nl> <3700F5E4.E6231638@appliedbiometrics.com> <37010514.177A92E5@pop.vet.uu.nl> <37010D39.971056D8@appliedbiometrics.com> Message-ID: <37011233.C024631A@appliedbiometrics.com> Christian Tismer wrote: > > Sorry, tutor list, > but I could not resist. > I will stop this now. (Ahem) Last refinement: To make an import of enum possible, I have to obtain the globals from the lambda: # in somewhere.py def enum(func): g = func.func_globals ; code = func.func_code base = apply(func, (0,)*code.co_argcount) or 0 for i in range(code.co_argcount): g[code.co_varnames[i]] = i+base # Now I can do from somewhere import enum enum(lambda ONE, TWO, THREE, FOUR, FIVE:1) ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net 10553 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF we're tired of banana software - shipped green, ripens at home From M.Faassen@vet.uu.nl Tue Mar 30 18:25:28 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 30 Mar 1999 20:25:28 +0200 Subject: [Tutor] parsing chemical formula References: <000201be7a79$8eb969e0$ee9e2299@tim> <3700BB4C.2C430E63@appliedbiometrics.com> <3700BD6E.84DA979@pop.vet.uu.nl> <3700CEF4.D82CF0C4@appliedbiometrics.com> <3700EC5F.6B8E0490@pop.vet.uu.nl> <3700F5E4.E6231638@appliedbiometrics.com> <37010514.177A92E5@pop.vet.uu.nl> <37010D39.971056D8@appliedbiometrics.com> Message-ID: <37011718.36F37EEA@pop.vet.uu.nl> Christian Tismer wrote: > def enum(func): > g = globals() ; code = func.func_code > base = apply(func, (0,)*code.co_argcount) or 0 > for i in range(code.co_argcount): > g[code.co_varnames[i]] = i+base > > Yeees, this is hefty. > But now watch out what I got for the application: > > from spinners.pirx import enum # har har > > enum(lambda ONE, TWO, THREE, FOUR, FIVE:1) > > # this gives us an enumeration, based from 1. Believe me. > > >>> ONE, TWO, THREE, FOUR, FIVE > (1, 2, 3, 4, 5) > > Naaah? Oh yeah, now we really have a "useful" lambda example :-))) This literally made me laugh out loud. :) Such ingenuity spent on my childish demands! Thanks, it was fun! Martijn From wilson@chemsun.chem.umn.edu Tue Mar 30 22:19:06 1999 From: wilson@chemsun.chem.umn.edu (Tim Wilson) Date: Tue, 30 Mar 1999 16:19:06 -0600 (CST) Subject: [Tutor] chemical formula Message-ID: Thanks to everyone who offered suggestions for my little molecular weight app. You've given me more than enough to chew on for awhile. I plan to study the OOP techniques that were used in creating them and see if I can understand it. I have yet to read a good tutorial on OOP for the novice. I find _Programming Python_ to be a little too advanced for me in that area. I'm working my way through Guido's excellent tutorial as well, but even there it's easy to get lost in the vocabulary. If anyone knows of some reading I could do to get the "big picture" of OOP, please post it. Hanging loose as usual, Tim -- Timothy D. Wilson "A little song, a little dance, University of MN, chem. dept. a little seltzer down your wilson@chem.umn.edu pants." -Chuckles the Clown Phone: (612) 625-9828 as eulogized by Ted Baxter From tim_one@email.msn.com Wed Mar 31 06:43:38 1999 From: tim_one@email.msn.com (Tim Peters) Date: Wed, 31 Mar 1999 01:43:38 -0500 Subject: [Tutor] parsing chemical formula In-Reply-To: <3700BB4C.2C430E63@appliedbiometrics.com> Message-ID: <000a01be7b41$cee41f60$f19e2299@tim> >> NAME, NUM, LPAREN, RPAREN, EOS = range(5) [Christian Tismer] > As I see this idiom of creating ENUM-alike constants > appear again (see doctest), this deserves an entry in > some howto. Tim, when did you start using it? > Very elegant. I do believe I was the first to do this, sometime in the first year of Python's life. Hard to remember whether Guido was tickled or appalled . Back then you couldn't mix sequence types across an unpacked assignment, though, so it had to be written with a list on both sides: [NAME, NUM, LPAREN, RPAREN, EOS] = range(5) It's nicer now. While I normally charge hefty royalties for use of this device, I hereby grant lifetime royalty-free licenses to all readers of the Tutor list . You and Martijn went on to have a lot of fun making count-free variations, but you neglected to tell the tutorees that anything beyond this is *sick* fun. Sick, sick, sick! This is the way to do it: import enum enum.start(100) import A, B, C, reset500, D, E enum.stop() import math print A, B, C, D, E, math.sqrt(169) # prints 100 101 102 500 501 13.0 Seriously (and, yes, I'll attach enum.py anyway ), while I generally oppose by-hand counting too, you have to weigh it against the alternatives, and anything else here is deadly obscure or deadly clumsy. Not worth it. I usually don't bother to count correctly! In this idiom, if you get the count wrong Python will tell you by raising a "unpack of wrong size" error. Most of the time you guess right; it's not worth any hassle to avoid the few times you don't. simple-code-for-our-simple-minds-ly y'rs - tim Here's enum.py. Tutorees, reminder: this is sick! Sick, sick, sick. Do yourself a favor and don't look at it . import __builtin__ _saved_import = __builtin__.__import__ _magic = "reset" _nmagic = len(_magic) def _hohoho(name, *args): global _base if name[:_nmagic] == _magic: _base = int(name[_nmagic:]) return this = _base _base = _base + 1 return this def start(base=1): global _base _base = base __builtin__.__import__ = _hohoho def stop(): __builtin__.__import__ = _saved_import From M.Faassen@vet.uu.nl Wed Mar 31 08:18:25 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Wed, 31 Mar 1999 10:18:25 +0200 Subject: [Tutor] parsing chemical formula References: <000a01be7b41$cee41f60$f19e2299@tim> Message-ID: <3701DA50.6FC08574@pop.vet.uu.nl> Tim Peters wrote: > While I normally charge hefty royalties for use of this device, I hereby > grant lifetime royalty-free licenses to all readers of the Tutor list > . Darn, I never paid royalties, where do I hide! > You and Martijn went on to have a lot of fun making count-free variations, > but you neglected to tell the tutorees that anything beyond this is *sick* > fun. Sick, sick, sick! This is the way to do it: Oh no, Christian, Timbot caught us! [snip sick sick example costing way too many lines anyway] > Seriously (and, yes, I'll attach enum.py anyway ), while I generally > oppose by-hand counting too, you have to weigh it against the alternatives, > and anything else here is deadly obscure or deadly clumsy. Not worth it. Agreed, still, this is of course an interesting challenge. > I usually don't bother to count correctly! In this idiom, if you get the > count wrong Python will tell you by raising a "unpack of wrong size" error. > Most of the time you guess right; it's not worth any hassle to avoid the few > times you don't. > simple-code-for-our-simple-minds-ly y'rs - tim > > Here's enum.py. Tutorees, reminder: this is sick! Sick, sick, sick. Do > yourself a favor and don't look at it . > [sick sick sick sick SICK code I don't pretend understanding deleted] Regards, Martijn From M.Faassen@vet.uu.nl Wed Mar 31 08:22:06 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Wed, 31 Mar 1999 10:22:06 +0200 Subject: [Tutor] chemical formula References: Message-ID: <3701DB2E.A95F2DBC@pop.vet.uu.nl> Tim Wilson wrote: > If anyone knows of some > reading I could do to get the "big picture" of OOP, please post it. You might want to try this book; it doesn't mention Python but talks about various OOP languages (the first edition which I read had C++, Smalltalk, Object Pascal, Objective C, I believe, the newer apparantly also includes Java and Delphi). An Introduction to Object Oriented Programming (2nd Edition), Addison Wesley, Reading, Massachusetts, 1997. 452pp. ISBN 0-201-82419-1 by Timothy Budd Regards, Martijn From alan.gauld@bt.com Wed Mar 31 10:10:21 1999 From: alan.gauld@bt.com (alan.gauld@bt.com) Date: Wed, 31 Mar 1999 11:10:21 +0100 Subject: [Tutor] chemical formula Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB24E08F0@mbtlipnt02.btlabs.bt.co.uk> > understand it. I have yet to read a good tutorial on OOP for > the novice. Marginally off topic but I found Timothy Budd's OOP book excellent. he uses several OOP languages to illustrate(Smalltalk, C++, Java, Delphi(OP) - I think they are) so you don't get hung up on a single languages view of OOP. It explains the concepts well IMHO. Alan G. From StnCold180@aol.com Wed Mar 31 18:31:11 1999 From: StnCold180@aol.com (StnCold180@aol.com) Date: Wed, 31 Mar 1999 13:31:11 EST Subject: [Tutor] programming Message-ID: <61407840.370269ef@aol.com> Hi. I am real interested in learning Python, but how do I go about starting? What do I need? can you help? Thanx, John Akles (stncold180@aol.com) From joe@strout.net Wed Mar 31 18:45:26 1999 From: joe@strout.net (Joseph J. Strout) Date: Wed, 31 Mar 1999 10:45:26 -0800 Subject: [Tutor] programming In-Reply-To: <61407840.370269ef@aol.com> Message-ID: >Hi. I am real interested in learning Python, but how do I go about starting? Start with the Tutorial at: http://www.python.org/doc/ It's marked "Start Here." ;) Then you might want to look at some simple scripts... here are a few: http://www.strout.net/python/tidbits.html >What do I need? You need a working installation of Python. How exactly you get that depends on what sort of computer you're using. >can you help? Yes, we can. Ask us when you get stuck. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From M.Faassen@vet.uu.nl Wed Mar 31 18:59:18 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Wed, 31 Mar 1999 20:59:18 +0200 Subject: [Tutor] programming References: Message-ID: <37027086.E0EB5089@pop.vet.uu.nl> "Joseph J. Strout" wrote: > > >Hi. I am real interested in learning Python, but how do I go about starting? > > Start with the Tutorial at: http://www.python.org/doc/ > It's marked "Start Here." ;) If you are new to programming and the tutorial confuses you, don't worry; it's aimed at programmers coming from other languages primarily (it is excellent for that). As Joe Strout said, just ask us here whenever you get stuck or confused. Regards, Martijn