From deirdre@deirdre.net Thu Apr 1 00:49:20 1999 From: deirdre@deirdre.net (Deirdre Saoirse) Date: Wed, 31 Mar 1999 16:49:20 -0800 (PST) Subject: [Tutor] File upload (via html) In-Reply-To: Message-ID: I was looking at the info about determining if something passed in is a file if fileinfo.file: but how does one retrieve the *name* of the uploaded file? I wanted to preserve the file's suffix though I wanted to select my own name for the beginning of the file. _Deirdre * http://www.linuxcabal.org * http://www.deirdre.net "During my service in the United States Congress, I took the initiative in creating the Internet." -- Al Gore "If Al Gore invented the internet, I invented spell check." -- Dan Quayle From alan.gauld@bt.com Thu Apr 1 14:16:05 1999 From: alan.gauld@bt.com (alan.gauld@bt.com) Date: Thu, 1 Apr 1999 15:16:05 +0100 Subject: [Tutor] New Python book Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB24E08FE@mbtlipnt02.btlabs.bt.co.uk> I just noticed theres a new Python book due out: The Quick Python Book By one K McDonald Priced at 34 pounds sterling (so probably ~$40?) Due out April. Anyone know anything about this one? Alan G. From tim_one@email.msn.com Sat Apr 3 07:54:51 1999 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 3 Apr 1999 02:54:51 -0500 Subject: [Tutor] New Python book In-Reply-To: <5104D4DBC598D211B5FE0000F8FE7EB24E08FE@mbtlipnt02.btlabs.bt.co.uk> Message-ID: <000201be7da7$414b0ac0$879e2299@tim> [alan.gauld@bt.com] > I just noticed theres a new Python book due out: > > The Quick Python Book > > By one K McDonald > > Priced at 34 pounds sterling (so probably ~$40?) > Due out April. > > Anyone know anything about this one? I reviewed an early draft late last year. Looks very good! I'm not at liberty to say more than the publisher (Manning) does, although it's not aimed at computer newbies (Python newbies, yes -- and, in the 2nd half, even Python old-timers looking for concentrated intros to advanced app areas). discreetly y'rs - tim From johnk@meta3.net Sat Apr 3 13:07:29 1999 From: johnk@meta3.net (John Kleinjans) Date: Sat, 03 Apr 1999 07:07:29 -0600 Subject: [Tutor] Learning programming Message-ID: <37061291.15DD@meta3.net> I generally start teaching programming with Qbasic. Then, when the kids know something about (list of topics here) I like to move on to ANSI C. I've stayed away from C++ so far. Python looks like a good OO language. I'd like to learn Python and OO thinking/programming, too. ----- I got Python running, read a pile of docs, started working through the tutorial Python in interactive mode), and wondered how to actually write and run a program. I think that beginning programmers would like to know how to do this (and would _not_ be able to figure it out). figured this out: 1) get a windowing environment running 2) get Python running in one window 3) get a text editor running in another window 4) with the text editor, write your program (call me "prog") 5) save your program to disk a) in the Python directory b) with a ".py" extension 6) switch to the Python window and >>> import prog 7) at his point, a) your program might actually run b) you'll probably get some error messages 8) switch back to the editor window 9) edit the program. Try to fix it. 10) SAVE IT TO DISK AGAIN 11) switch back to Python and type >>> reload(prog) ----- At this point, 7 through 11 keep repeating. Beginning programmers would take a very long time to figure this out. They'd probably quit first. Please tell me; am I doing this the hard way? Or is this the way? We should probably provide more detailed instructions for users of DOS, Macs, even Windows. Realistically, that's what's running on most boxes out there... there's a lot of kids with W95 (or even W311, or DOS) boxes who would like to learn how to program. ----- So now, of course, the newbie has to write a program like ... print "Hello world\n" ... and get that running. And that is the big hurdle for someone who is learning how to program for the very first time. Even in Python. ----- I teach high school--that'll probably (assuredly) affect what I see and say. That's not so bad. And I teach programming (and some other things). Well, I'd like to see if this effort gets from here to there (and back again) before I put more into it. John K From tismer@appliedbiometrics.com Sat Apr 3 13:58:18 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 03 Apr 1999 15:58:18 +0200 Subject: [Tutor] Learning programming References: <37061291.15DD@meta3.net> Message-ID: <37061E7A.7DEF752B@appliedbiometrics.com> John Kleinjans wrote: > > I generally start teaching programming with Qbasic. Then, when the kids > know something about (list of topics here) I like to move on to ANSI C. > I've stayed away from C++ so far. Python looks like a good OO language. > I'd like to learn Python and OO thinking/programming, too. Very good. > I got Python running, read a pile of docs, started working through the > tutorial Python in interactive mode), and wondered how to actually write > and run a program. I think that beginning programmers would like to know > how to do this (and would _not_ be able to figure it out). > > figured this out: > > 1) get a windowing environment running > 2) get Python running in one window > 3) get a text editor running in another window > 4) with the text editor, write your program (call me "prog") > 5) save your program to disk > a) in the Python directory > b) with a ".py" extension > 6) switch to the Python window and > >>> import prog > 7) at his point, > a) your program might actually run > b) you'll probably get some error messages > 8) switch back to the editor window > 9) edit the program. Try to fix it. > 10) SAVE IT TO DISK AGAIN > 11) switch back to Python and type > >>> reload(prog) This is fine so far. Although under PythonWin, things are easier: You have an MDI window with an interpreter shell and any number of source files. I used to type some single lines. After figuring out the basics, I open an editor window and move the lines over, starting to write functions. Instead of importing that, I almost write a main program which defines a couple of functions, and simply run it. This gives a very small turn-around time since PythonWin does an automatic save for me. I also quite often use my pylog.py logger, to get a transcript of my session and edit it as a Python file. You can find it at http://starship.python.net/crew/pirx/pylog.py It will keep a record of "the goods" (the non-failing commands) and also allows you to replay sessions to your students. > Beginning programmers would take a very long time to figure this out. > They'd probably quit first. Depending on your courses environment, you should provide them with a three page handout which simply shows these basic steps. Fire up some shell Run some commands and inspect the resulting objects Save some functions as a Python file and so on. I think it makes sense to let the instructor do this, instead of having these recipes ready-made for every platform. But that's just my opinion, since I have been an autodidact for ages. > Please tell me; am I doing this the hard way? Or is this the way? One of the right ways, of course. You could also decide to use Idle, Guido's Tk based delevopment GUI, which is already quite usable. I personally still prefer PythonWin, and I even use it to edit Python files on one of our Linux boxes. PythonWin is the editor, and the test bed for non-Unix-specific functions. For the rest, I have a telnet screen where I always fire the same python command line off for testing. > We should probably provide more detailed instructions for users of DOS, > Macs, even Windows. Realistically, that's what's running on most boxes > out there... there's a lot of kids with W95 (or even W311, or DOS) boxes > who would like to learn how to program. So here is the point. What Python still lacks (together with most other languages) is support for the absolute beginner. It is simply not there. Python is in good neighborship here, but anyway it should of course take the chance to become a beginner's language. > So now, of course, the newbie has to write a program like ... > > print "Hello world\n" > > ... and get that running. And that is the big hurdle for someone who is > learning how to program for the very first time. Even in Python. Not quite. The absolute beginner does not need a Python script in the first place. What you should teach him on any platform is something like: (DOS example) Run Python: start a DOS shell and then type c:\python>python then see how to use it as a calculator: >>> 1+1 2 >>> Form there on, continue. The best experience for newbies is that they can use Python immediately. Of course this enthusiasm will diminish when they recognize that under DOS, the command line cannot be retrieved again. SO they will quickly want to use file, or PythonWin. Different on Linux, there you have the full history of your session available, and you can recall lines and edit them. Again a word on documentation: The tutorial which comes with the standard distribution as a bunch of HTML files already contains sample sessions for the very beginning. Have a look at file:///D|/Python/Doc/tut/interactive.html in the tutorials HTML. Then, using Python as a calculator is also there: file:///D|/Python/Doc/tut/numbers.html And so on. Maybe the standard docs are not too easy to become familiar with, but if you know where to look, almost everything is there. I hope you stay with Python - chris (teaching companies:) -- 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 joe@strout.net Sat Apr 3 14:18:41 1999 From: joe@strout.net (Joseph J. Strout) Date: Sat, 3 Apr 1999 06:18:41 -0800 Subject: [Tutor] Learning programming In-Reply-To: <37061291.15DD@meta3.net> Message-ID: The loop is much easier if you're using the MacPython IDE. It looks like this: 1) launch the IDE 2) create a new window 3) type some Python code 4) click the "Run" button 5) at this point, a) your program might actually run b) you'll get some error messages, which gives you an option to drop into the GUI debugger to inspect variables, etc. 6) dismiss the debugger, and edit code in the window Repeat steps 4-6 as desired. And somewhere, you'd probably want to add a "save to disk" step. For newbies, I think this is definately the way to go, though of course it only works for those with Macs available. ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From ivnowa@hvision.nl Sat Apr 3 17:54:01 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sat, 3 Apr 1999 18:54:01 +0100 Subject: [Tutor] Learning programming In-Reply-To: <37061291.15DD@meta3.net> Message-ID: <199904031652.SAA11830@axil.hvision.nl> On 3 Apr 99, Ce'Nedra took her magical amulet and heard John Kleinjans say: >figured this out: > >1) get a windowing environment running Why? That's not necessary... Python for Windows is pretty good, but there are other versions around working in "console-mode". >2) get Python running in one window >3) get a text editor running in another window >4) with the text editor, write your program (call me "prog") >5) save your program to disk > a) in the Python directory > b) with a ".py" extension >6) switch to the Python window and >>>> import prog In my opinion, the best way to start a Python program is still from the command line, possibly specifying options and arguments for your program. So python myprog.py should do, too. It seems that you are used to a DOS environment. If this is the case, then I would suggest installing 4DOS which makes starting a program easier. I start my program by just typing the program name, like myprog like it was an executable. Also, an editor with some macro capabilities is also useful. I use vim 5.x myself, but there are lots of editors around (I don't recommend vi for newbies :^). With 4DOS and the editor combined, I edit my program, save it by pressing F2, and run it by pressing F9 (or Shift-F9 if I want to specify arguments first). Instant IDE for DOS or Win95 console mode. And this is just one way to do it. Python 1.5.2 comes with a development environment called IDLE, to name something. There's PythonWin... >7) at his point, > a) your program might actually run > b) you'll probably get some error messages >8) switch back to the editor window >9) edit the program. Try to fix it. >10) SAVE IT TO DISK AGAIN >11) switch back to Python and type >>>> reload(prog) > >----- > >At this point, 7 through 11 keep repeating. > >Beginning programmers would take a very long time to figure this out. >They'd probably quit first. I see your point. Although some of the points you mention (like the saving and editing thing) is considered common knowledge unless you're an absolute beginner, also when it comes to computers. Even my mom who just started with Word knows that she should save regularly. :^) >Please tell me; am I doing this the hard way? Or is this the way? There are easier ways... >We should probably provide more detailed instructions for users of DOS, >Macs, even Windows. Realistically, that's what's running on most boxes out >there... there's a lot of kids with W95 (or even W311, or DOS) boxes who >would like to learn how to program. I don't disagree, although this is a mix of 'how to start programming' and 'how to start with computers'. If someone doesn't know about editing and saving yet and about the operating system in general, I don't know if it's such a good idea to start programming already. ;^) >I teach high school--that'll probably (assuredly) affect what I see and >say. That's not so bad. And I teach programming (and some other things). > >Well, I'd like to see if this effort gets from here to there (and back >again) before I put more into it. I can understand that. Python is not something that comes in a box with disks/CDs and a coupla manuals to get you started. Still, working with it isn't too hard, it's just a bit different from commercial environments like Delphi, VB or (some years ago) Turbo Pascal. (I must admit that when I started with Python, this bit me too. Heck, I even hacked the Turbo Pascal editor so it accepted .py files and started them upon pressing F9...) Regardz, + 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 Duke Nukem pull the plug out of your nail polish! From ivnowa@hvision.nl Sat Apr 3 17:54:01 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sat, 3 Apr 1999 18:54:01 +0100 Subject: [Tutor] Learning programming In-Reply-To: <37061E7A.7DEF752B@appliedbiometrics.com> Message-ID: <199904031652.SAA11833@axil.hvision.nl> On 3 Apr 99, Ce'Nedra took her magical amulet and heard Christian Tismer say: >Form there on, continue. The best experience for newbies is that >they can use Python immediately. Of course this enthusiasm >will diminish when they recognize that under DOS, the command >line cannot be retrieved again. Ahum. Not quite true. Which Python version have you been using? :^/ + 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 a wicked smurf shamelessly use your panties! From tismer@appliedbiometrics.com Sat Apr 3 17:39:20 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 03 Apr 1999 19:39:20 +0200 Subject: [Tutor] Learning programming References: <199904031652.SAA11833@axil.hvision.nl> Message-ID: <37065248.E79F5293@appliedbiometrics.com> Hans Nowak wrote: > > On 3 Apr 99, Ce'Nedra took her magical amulet and heard Christian Tismer say: > > >Form there on, continue. The best experience for newbies is that > >they can use Python immediately. Of course this enthusiasm > >will diminish when they recognize that under DOS, the command > >line cannot be retrieved again. > > Ahum. Not quite true. Which Python version have you been using? :^/ Well, I could indeed have mentioned your DX Python for DOS. And I have to admit that I still owe you an answer to your mail from Tue, 1 Dec 1998 09:12:27 concerning python-dx and publishing the source files. It is still on my to-do list. Anyway, I'm used to allways forget to mention any Python related stuff which I cannot compile by myself :-)) The average Python user on Windoze will usually come up with the standard dist, putting either PythonWin on top, or have a disgusting DOS window with no history. What I think would be very useful: Can you isolate the necessary stuff to make the standard Python have a termcap like interface as yours? happy easter - 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 tim_one@email.msn.com Sat Apr 3 18:17:04 1999 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 3 Apr 1999 13:17:04 -0500 Subject: [Tutor] Learning programming In-Reply-To: <37061291.15DD@meta3.net> Message-ID: <000a01be7dfe$2d1d1b40$3a9e2299@tim> [John Kleinjans, seeking a way to teach programming] John, like everyone else so far, I recommend you use one of the Python IDEs (Integrated Development Enviornments). Any will do! PythonWin and Mac IDE were covered in some detail, so I'll run thru it for IDLE on Win95/98/NT: > 1) get a windowing environment running Starting with 1.5.2, the Python Windows installer also (but optionally) installs Tcl/Tk. That's a very popular cross-platform windowing system, and IDLE builds on top of it. > 2) get Python running in one window IDLE comes with 1.5.2 too, so it's a matter of starting IDLE. Note that the Windows installer creates a "python" entry under Start -> Python. That's enough to bring up a DOS box Python. I change its properties by hand to bring up IDLE instead. Or create a desktop shortcut, etc -- each platform has a bunch of shortcuts specific to it. > 3) get a text editor running in another window IDLE is also a (simple but reasonably powerful) editor, and any number of files can be opened and/or created from its File menu, each in its own independent window. > 4) with the text editor, write your program (call me "prog") Piece o' cake. Any of the IDEs will have special editor support for Python too, from automatic indentation to syntax coloring. > 5) save your program to disk > a) in the Python directory > b) with a ".py" extension File -> Save (or hit Ctrl+S). The standard Windows "Save As" dialog box appears; unless it's the first time they've turned on their computer, they've seen this dialog a thousand times before . > 6) switch to the Python window and > >>> import prog Easier in IDLE to do Edit -> Run module, from the editor window. Unfortunately, if you *haven't* saved the file before doing this, it doesn't save the file for you, but instead pops up an error box saying "Please save first!". At least it's self-explanatory . > 7) at this point, > a) your program might actually run > b) you'll probably get some error messages > 8) switch back to the editor window When you get an error msg from Python, you also get a traceback. The traceback includes the appropriate file names and line numbers. IDLE knows how to parse these lines, so you just need to point at the error, right-click, and select "Go to file/line" from the pop-up context menu. IDLE opens the file (or switches to its window if it's already open), positions the cursor on the offending line, and gives that window the focus. Very handy! Again, all the IDEs have something like this built in. > 9) edit the program. Try to fix it. > 10) SAVE IT TO DISK AGAIN > 11) switch back to Python and type > >>> reload(prog) This is reduced to steps 5 & 6 again. IDLE's "Run module" knows whether or not it's the first time the module has been run, and magically does a "reload" if it's not the first time. > ... > Beginning programmers would take a very long time to figure this out. > They'd probably quit first. Self-selection at work: then they don't have what it takes to become "real programmers" <0.5 wink>. No way around it, computers are still a pain in the ass to use, and it requires a certain pig-headedness to succeed. An IDE will take away much of the needless tedium. In return, each has its own quirks to stumble into and worm around. Very much a net win, though. > ... > So now, of course, the newbie has to write a program like ... > > print "Hello world\n" > > ... and get that running. And that is the big hurdle for someone who is > learning how to program for the very first time. Even in Python. D:\Python>python Python 1.5.2b2 (#0, Feb 16 1999, 17:09:09) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> print "Hello world" Hello world >>> That is, 1) Start with interactive mode. 2) Anything hard to learn in that sequence is due to the OS, and can't possibly be made simpler without replacing the OS -- the clumsiness of a DOS box under Windows isn't Python's fault, nor is it something Python (or any other program) can do anything about. 3) Your program was far too elaborate: Python supplies the newline for you . > Python looks like a good OO language. I expect it's *much* better for teaching OO than is C++; the latter is a "efficiency at any cost" language that's most appropriate for demanding professional use (as a professional C++ programmer, I'm allowed to say that ). I don't know of any language (& I know of a lot) in which OO is easier to "get going" than in Python, although there are several languages in which OO plays a more central role. Eiffel in particular is a sparkling jewel in the OO world, but supports a theory of programming that's probably too heavy for high-school level. I'm not an educator, but Python is what I'd pick if I were you. Java is another good choice for teaching OO, in some ways better, in others worse. > I'd like to learn Python and OO thinking/programming, too. If you have the source distribution, I'd recommend studying Demo/classes/Dates.py. I wrote that in 1993 to try out Python's then-new operator overloading features, and many people have written to say they've found it especially helpful for "getting into" OO. I'm not sure why, except that it's mostly a procedural module with a simple OO interface; and calendar trivia is inherently fascinating to many ("what day of the week will my birthday fall on in the year 1 billion?"). The math is subtler than it looks, but you're not going to find any simpler calendar algorithms (this is *much* simpler than most), and 95% of it is junior-high level integer arithmetc. for-a-real-education-try-rewriting-dates.py-in-c++-ly y'rs - tim From ivnowa@hvision.nl Sat Apr 3 22:56:31 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sat, 3 Apr 1999 23:56:31 +0100 Subject: [Tutor] Learning programming In-Reply-To: <37065248.E79F5293@appliedbiometrics.com> Message-ID: <199904032155.XAA19111@axil.hvision.nl> On 3 Apr 99, Ce'Nedra took her magical amulet and heard Christian Tismer say: >Well, I could indeed have mentioned your DX Python for DOS. I don't want to mention "my" Python every time, but many people seem to think that Python DOS versions are somehow inferior... truth is, there are DOS Pytha around (not only mine) which are actually superior to the Windows version, or at least to the clunky console version for Windows. No bad words about Python for Windows, especially not in Windows mode, but Python-DX is much closer to Unix and has a stupid fat collection of Unix(-esque) modules built in... crypt, pwd, gdbm, termios, readline, etc. Python for Windows with GUI is quite nice, but the console version looks like it's unfinished, possibly "because Win95 users don't work in the obsolete DOS mode anyway". I like console mode because it's much more flexible, and a lot is possible too, especially with backup from Win95 (long filenames, sockets etc). OK, I'll get off my soapbox now... :^) >And I have to admit that I still owe you an answer to your >mail from Tue, 1 Dec 1998 09:12:27 concerning python-dx >and publishing the source files. It is still on my to-do list. Publishing the source files is still on *my* to-do list... :^) >Anyway, I'm used to allways forget to mention any >Python related stuff which I cannot compile by myself :-)) Why not? If I can do it, anyone can... >The average Python user on Windoze will usually come up with >the standard dist, putting either PythonWin on top, or have >a disgusting DOS window with no history. Yes, I agree. Well, now they know what to do... :^) >What I think would be very useful: Can you isolate the necessary >stuff to make the standard Python have a termcap like interface >as yours? Hmm... at the moment I have only the .a files lying around somewhere... not the source. I must have it at least *somewhere*... but I don't have it handy. I could try to find it, though. >happy easter - chris Likewise! Egg-eating Hansa + 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 a hobgoblin shrink your hamburger! From tismer@appliedbiometrics.com Sat Apr 3 22:20:46 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sun, 04 Apr 1999 00:20:46 +0200 Subject: [Tutor] Learning programming References: <199904032155.XAA19111@axil.hvision.nl> Message-ID: <3706943E.D3790E0C@appliedbiometrics.com> Hans Nowak wrote: ... > >The average Python user on Windoze will usually come up with > >the standard dist, putting either PythonWin on top, or have > >a disgusting DOS window with no history. > > Yes, I agree. Well, now they know what to do... :^) > > >What I think would be very useful: Can you isolate the necessary > >stuff to make the standard Python have a termcap like interface > >as yours? > > Hmm... at the moment I have only the .a files lying around somewhere... not > the source. I must have it at least *somewhere*... but I don't have it handy. > I could try to find it, though. I just played a little with Winnows consoles. Used Sam's calldll and windll functions and fiddled around with a DOS console. It is even a cakewalk to create one for PythonWin :-) I was able to read and write this console with my data. Also I have access to all color and cursor attributes. That means, with a little work, calldll, and the new code module of Python, I can run a Python shell which has a faked stdin and stdout which goes through my module. Which means that I can add readline functionality with ease, using no C code. This can then be extended to a little ANSI terminal, and a subset of ncurses can be set on top of it, again all in Python. Wheee, looks like fun (if I have time). 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 ivnowa@hvision.nl Sun Apr 4 16:54:44 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sun, 4 Apr 1999 16:54:44 +0100 Subject: [Tutor] File upload (via html) In-Reply-To: References: Message-ID: <199904041453.QAA11610@axil.hvision.nl> On 31 Mar 99, Ce'Nedra took her magical amulet and heard Deirdre Saoirse say: >I was looking at the info about determining if something passed in is a >file > >if fileinfo.file: > >but how does one retrieve the *name* of the uploaded file? I wanted to >preserve the file's suffix though I wanted to select my own name for the >beginning of the file. I don't really understand what you are trying to do here... Could you please be more specific? And what kind of beast is fileinfo? :^) (I could not find it in the standard library... only in the binhex module, but I doubt that that's what you want.) 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 Chelsea cut your chicken feathers out with your legs! From johnk@meta3.net Sun Apr 4 15:16:25 1999 From: johnk@meta3.net (John Kleinjans) Date: Sun, 04 Apr 1999 09:16:25 -0500 Subject: [Tutor] Learning programming In-Reply-To: <37061E7A.7DEF752B@appliedbiometrics.com> References: <37061291.15DD@meta3.net> Message-ID: <3.0.3.32.19990404091625.006b8840@mail.meta3.net> At 03:58 PM 4/3/99 +0200, you wrote: > > >John Kleinjans wrote: >This is fine so far. Although under PythonWin, things >are easier: Looks like PythonWin is the easy answer. >You have an MDI window with an interpreter shell >and any number of source files. > >I used to type some single lines. After figuring out >the basics, I open an editor window ... sounds similar to what I found. >and move the lines >over, starting to write functions. Instead of importing >that, I almost write a main program which defines >a couple of functions, and simply run it. How does one "write a mian program ... and simply run it" without importing it? >This gives >a very small turn-around time since PythonWin does >an automatic save for me. > >I also quite often use my pylog.py logger, to get >a transcript of my session and edit it as a Python >file. You can find it at >http://starship.python.net/crew/pirx/pylog.py > >It will keep a record of "the goods" (the non-failing >commands) and also allows you to replay sessions to >your students. > >> Beginning programmers would take a very long time to figure this out. >> They'd probably quit first. > >Depending on your courses environment, you should provide >them with a three page handout which simply shows these >basic steps. >Fire up some shell >Run some commands and inspect the resulting objects >Save some functions as a Python file Gotcha. >and so on. I think it makes sense to let the instructor >do this, instead of having these recipes ready-made >for every platform. But that's just my opinion, since >I have been an autodidact for ages. I teach myself, too. It's a real push, and I get tired, and I could probably teach myself faster with a bit of help. > >> Please tell me; am I doing this the hard way? Or is this the way? > >One of the right ways, of course. >You could also decide to use Idle, Guido's Tk based >delevopment GUI, which is already quite usable. >I personally still prefer PythonWin, and I even use it >to edit Python files on one of our Linux boxes. >PythonWin is the editor, and the test bed for non-Unix-specific >functions. For the rest, I have a telnet screen where I always >fire the same python command line off for testing. > >> We should probably provide more detailed instructions for users of DOS, >> Macs, even Windows. Realistically, that's what's running on most boxes >> out there... there's a lot of kids with W95 (or even W311, or DOS) boxes >> who would like to learn how to program. > >So here is the point. What Python still lacks (together with >most other languages) is support for the absolute beginner. >It is simply not there. Python is in good neighborship here, >but anyway it should of course take the chance to become >a beginner's language. > That's the outcome that I'm risking my time on. >> So now, of course, the newbie has to write a program like ... >> >> print "Hello world\n" >> >> ... and get that running. And that is the big hurdle for someone who is >> learning how to program for the very first time. Even in Python. > >Not quite. >The absolute beginner does not need a Python script in the >first place. What you should teach him on any platform >is something like: >(DOS example) > >Run Python: >start a DOS shell and then type >c:\python>python > >then see how to use it as a calculator: >>>> 1+1 >2 >>>> > >Form there on, continue. Right. Did that. >The best experience for newbies is that >they can use Python immediately. Of course this enthusiasm >will diminish when they recognize that under DOS, the command >line cannot be retrieved again. SO they will quickly want to use >file, or PythonWin. Did that, too. >Different on Linux, there you have the full history of your >session available, and you can recall lines and edit them. > >Again a word on documentation: The tutorial which comes >with the standard distribution as a bunch of HTML files >already contains sample sessions for the very beginning. >Have a look at file:///D|/Python/Doc/tut/interactive.html >in the tutorials HTML. >Then, using Python as a calculator is also there: >file:///D|/Python/Doc/tut/numbers.html > Did. Done. >And so on. Maybe the standard docs are not too easy to >become familiar with, but if you know where to look, >almost everything is there. > >I hope you stay with Python - chris (teaching companies:) > >-- >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 johnk@meta3.net Sun Apr 4 16:20:49 1999 From: johnk@meta3.net (John Kleinjans) Date: Sun, 04 Apr 1999 10:20:49 -0500 Subject: [Tutor] Learning programming In-Reply-To: <199904031652.SAA11830@axil.hvision.nl> References: <37061291.15DD@meta3.net> Message-ID: <3.0.3.32.19990404102049.006bbf04@mail.meta3.net> At 06:54 PM 4/3/99 +0100, you wrote: >On 3 Apr 99, Ce'Nedra took her magical amulet and heard John Kleinjans say: > >>figured this out: >> >>1) get a windowing environment running > >Why? That's not necessary... Python for Windows is pretty good, but there are >other versions around working in "console-mode". > I'd like to know what other versions and where I can get them, with the constraint that they have to run on my DOS/W311/W95 machines (yes, I actually have a 386 in my teaching lab, and a bunch of 486s with 4 Mb RAM; and 3 Pentiums with W95). >>2) get Python running in one window >>3) get a text editor running in another window >>4) with the text editor, write your program (call me "prog") >>5) save your program to disk >> a) in the Python directory >> b) with a ".py" extension >>6) switch to the Python window and >>>>> import prog > >In my opinion, the best way to start a Python program is still from the >command line, possibly specifying options and arguments for your program. So > >python myprog.py > >should do, too. > On my machines, Python takes 20 or 30 seconds to load, so I'm looking for an alternative protocol. The elapsed time from Python -> editor -> Python leads to major attention- and memory-lapses. There has to be something faster for DOS. I'm thinking about running a TSR editor... >It seems that you are used to a DOS environment. Actually, I'm used to DOS and Windows (and Mac, but that was long ago and far away). In my teaching, I have to take account of what's available (sounds like real life again); hardware, software, OSs. licenses, curriculum guides, state DOE regulations, etc--and then make good things happen. DOS is OK--a lot of people did a lot of good work with DOS for several years. And until it's dead, it's still alive. And it doesn't hurt for kids to learn some command-line stuff... ...but I'm getting off-track. Sorry. >If this is the case, then I >would suggest installing 4DOS which makes starting a program easier. I start >my program by just typing the program name, like > >myprog > >like it was an executable. Also, an editor with some macro capabilities is >also useful. I use vim 5.x myself, but there are lots of editors around (I >don't recommend vi for newbies :^). With 4DOS and the editor combined, I edit >my program, save it by pressing F2, and run it by pressing F9 (or Shift-F9 if >I want to specify arguments first). Instant IDE for DOS or Win95 console >mode. I might try that. Thanks. >And this is just one way to do it. Python 1.5.2 comes with a development >environment called IDLE, to name something. There's PythonWin... > >>7) at his point, >> a) your program might actually run >> b) you'll probably get some error messages >>8) switch back to the editor window >>9) edit the program. Try to fix it. >>10) SAVE IT TO DISK AGAIN >>11) switch back to Python and type >>>>> reload(prog) >> >>----- >> >>At this point, 7 through 11 keep repeating. >> >>Beginning programmers would take a very long time to figure this out. >>They'd probably quit first. > >I see your point. Although some of the points you mention (like the saving >and editing thing) is considered common knowledge unless you're an absolute >beginner, also when it comes to computers. Even my mom who just started with >Word knows that she should save regularly. :^) > My point here is that beginners frequently think "it's in the computer" and are often fuzzy on exactly _where_ in the computer 'it' is. In the above-mentioned mode, _we_ know that Python can't just "get" the code from the editor--but newbies don't. As we teach, we help them build a correct model of the parts and processes. Your mother (and mine, too) save frequently for a different reason, and the difference matters. >>Please tell me; am I doing this the hard way? Or is this the way? > >There are easier ways... > >>We should probably provide more detailed instructions for users of DOS, >>Macs, even Windows. Realistically, that's what's running on most boxes out >>there... there's a lot of kids with W95 (or even W311, or DOS) boxes who >>would like to learn how to program. > >I don't disagree, although this is a mix of 'how to start programming' and >'how to start with computers'. If someone doesn't know about editing and >saving yet and about the operating system in general, I don't know if it's >such a good idea to start programming already. ;^) > Not necessarily "how to start with computers". With C, there's a sequence (cycle) of - write source code - compile - link - run & test - repeat that is above and beyond 'start with computers' level. And (I'm sure) Python has its processes and procedures also. That is... a programmer interacts with a programming environment in a different manner than a student writing a term paper interacts with a word processor. And we can help that student, who might be capable in the one area, become capable in another, different area. >>I teach high school--that'll probably (assuredly) affect what I see and >>say. That's not so bad. And I teach programming (and some other things). >> >>Well, I'd like to see if this effort gets from here to there (and back >>again) before I put more into it. > >I can understand that. Python is not something that comes in a box with >disks/CDs and a coupla manuals to get you started. Still, working with it >isn't too hard, it's just a bit different from commercial environments like >Delphi, VB or (some years ago) Turbo Pascal. (I must admit that when I >started with Python, this bit me too. Heck, I even hacked the Turbo Pascal >editor so it accepted .py files and started them upon pressing F9...) > >Regardz, > >+ Hans Nowak (Zephyr Falcon) Thanks. John. From johnk@meta3.net Sun Apr 4 16:36:37 1999 From: johnk@meta3.net (John Kleinjans) Date: Sun, 04 Apr 1999 10:36:37 -0500 Subject: [Tutor] Learning programming In-Reply-To: <000a01be7dfe$2d1d1b40$3a9e2299@tim> References: <37061291.15DD@meta3.net> Message-ID: <3.0.3.32.19990404103637.006bbf04@mail.meta3.net> At 01:17 PM 4/3/99 -0500, you wrote: >[John Kleinjans, seeking a way to teach programming] > >John, like everyone else so far, I recommend you use one of the Python IDEs >(Integrated Development Enviornments). Any will do! PythonWin and Mac IDE >were covered in some detail, so I'll run thru it for IDLE on Win95/98/NT: Thanks very much. Looks good--I'll try it. >I expect it's *much* better for teaching OO than is C++; the latter is a >"efficiency at any cost" language that's most appropriate for demanding >professional use (as a professional C++ programmer, I'm allowed to say that >). I don't know of any language (& I know of a lot) in which OO is >easier to "get going" than in Python, although there are several languages >in which OO plays a more central role. Eiffel in particular is a sparkling >jewel in the OO world, but supports a theory of programming that's probably >too heavy for high-school level. I'm not an educator, but Python is what >I'd pick if I were you. Java is another good choice for teaching OO, in >some ways better, in others worse. > What I'm thinking here about teaching (and learning) programming is that: 1. QBasic is a procedural language, and introduces sequence, branches, and loops; variables, constants, and data types; input, processing, and output; arrays and structures (and arrays of structures)... but if you got this far, don't put too much more energy into it but instead switch to ... 2. C, which is more... everything (except easy). Now you begin to learn (some) how the computer actually works. But still a procedural language. 3. OhOh. Now we have to think in a whole new way. At least, I've been told by a reputable source that the key to programming objects is to understand objects--and then learn how to write code that does that. And I'm not so sure that C++ is the best way to _learn_ how to think like that. So (as usual) I'm going from the known to the unknown--and in such a case (aka lack of knowledge) I have to go on informed intuition. BTW--as I re-read this before sending it (what a concept!) I notice that I followed up on a loose end that I left dangling from my previous post. That is where I said (and I manually cut and paste) ... --> I generally start teaching programming with Qbasic. Then, when the kids --> know something about (list of topics here) ... that "list of topics here" was (partially) enumerated above in #1. Do we need to teach all these things _before_ we get into objects? How much procedural programming do we need to learn OO? How and where does knowledge of procedural programming methods interfere with learning OO? Is there an OO way of thinking that doesn't depend on ... Anyway. I can't answer these questions because I don't know OO. As I said earlier, I've intentionally kept away from C++ in an effort to clearly learn C. Can you remember when you weren't quite sure what a variable was? Or a structure? When you couldn't remember whether it's long or double that's the big int (or float)? When you worked out how to dereference a member of an array of structures? Everybody has to figure out everything for a first time. We can help. Thanks much for a most helpful and informative response. Col-ly yr's John From johnk@meta3.net Sun Apr 4 20:35:20 1999 From: johnk@meta3.net (John Kleinjans) Date: Sun, 04 Apr 1999 14:35:20 -0500 Subject: [Tutor] Teaching computer programming Message-ID: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> We must remember that teaching _programming_ differs from teaching a programming _language_. So if we want to develop some materials for "teaching programming with Python", we need to focus on teaching *programming* first. ----- A personal note: I like to teach programming for (at least) two reasons. One is because teaching people how computers work, and how to make computers do what they want them to do, gives them power. The other reason is that it teaches people how to think in a logical, connected, sequential, directed way. That gives them even more power; power over their own minds, power to control their thinking and the sequences of ideas in their own heads. I think that teaching computer programming is a very powerful tool for teaching people how to think clearly. The program runs, or it doesn't. It does what you want, or not. The cause is (usually) in plain sight, in the source code; the error is in one's understanding or precision. This is not to say that logic is the only, or even the best, way to think--but it's a powerful and necessary tool for one's mental toolbox, and one that too few people have or can use. Intuition is good, too... and an aesthetic sense... just use the right tool for the job at hand. I think that it's good for one's personal development to learn to program, somewhat as participation in athletics is (supposed to be) good, whether you ever program/play for money or not. Learn how to use your mind _and_ body. Left _and_ right brain. Yada yada yada ... ----- Back on subject. So, once they get the compiler/interpreter environment operating, and learn a process for typing instructions and getting the computer to execute said instructions (or choke on them and cough out error messages); what is it that people need to learn, in what sequence, to learn _How_to_Program_in_Python_? In QBasic, I start with ... PRINT "Hello world" ... and then go to ... INPUT "What's your name"; name$ PRINT "Hello "; name$ ... and already we're talking about variables, variable names (name$), data types, input and output--there's a bundle of concepts that (it seems) have to be handled as a group. In Python, we can (I think) ignore the whole 'variable types and names' mess, which simplifies this step to teaching input, output, and variables. So someone new to programming will want to know what a variable is, and why we need variables (we're teaching _programming_, remember). And we want to tell them something that is _true_, yet not necessarily exact; something they can understand, use, and build on later without having to un-learn . Most newbies don't want or need to hear about allocating a block of RAM and creating a symbol table with addresses... save that for later, when they need to know. Maybe say "a variable is a place to put a piece of data that can change (that's why we call it a "VARIable") and that we want to use later. Maybe call it 'box1' (and 'box2', etc.) to allow us to use that metaphor, and help the learners learn to think clearly and correctly about these things. Now we have input, output, and variables. How much can we do with that much? Can we now give learners a few programming assignments? It's tough, with no 'if' or 'while', but such is life. --Write a program to take in two numbers and return the sum/difference/product/quotient. Or maybe all of the above. box1 = input("First number: ") # User types a number; it goes into box1 box2 = input("Second number: ") # User types another; it goes into box2 box3 = box1 + box2 # Add what's in box1 and box2; put it into box3 print box3 # Show what's in box3 So when 'box' is on the _left_ of the equals sign, we *put something into it*. And when it's on the _right_ of the equals sign, we *see what's in it*. (I'd say that we 'get' what's in the box on the right, except that what's there _stays_ there--it's like, when I tell you something that doesn't make me forget it!). Aha! We should explain 'commands' and 'functions'. But maybe not just yet! At least, we do need to point out that 'input' has parentheses after it, and 'print' doesn't. ----- It occurs to me that teaching programming must be (I've come to hate the word) proactive. That is, you can't just wait for learners to ask questions, because they don't know enough to ask the right questions in the right sequence. You need to initiate and introduce sequences of ideas. I don't expect my students to invent pointers, much less linked lists. Shoot, most of them are hazy about differences between integers and floats ("something we saw in math"). Of course, there also comes a time to shut up and allow the learner time to digest stuff. It helps to give them projects of the right size. ----- I think that there's a lot you can teach people who only know 'print' and 'input()'. 'if' is a good next candidate. Right after that, 'while' is useful, so the user doesn't have to re-start the program for each run. Later -- John From tismer@appliedbiometrics.com Mon Apr 5 12:51:42 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Mon, 05 Apr 1999 13:51:42 +0200 Subject: [Tutor] Learning programming References: <37061291.15DD@meta3.net> <3.0.3.32.19990404102049.006bbf04@mail.meta3.net> Message-ID: <3708A3CE.7582B39F@appliedbiometrics.com> John Kleinjans wrote: ... > I'd like to know what other versions and where I can get them, with the > constraint > that they have to run on my DOS/W311/W95 machines (yes, I actually have a 386 > in my teaching lab, and a bunch of 486s with 4 Mb RAM; and 3 Pentiums with > W95). Arghh! So they gave you all the crap which they could not use for anything anymore, now take this and teach! If I were in your company/institution, there would now be a lot of rumor for a couple of weeks, until I have at least 16 MB in every machine, and the 386's are gone. Seriously, with 4 MB of RAM, you cannot teach Windows applications. What you could do is to install Linux and use Python under Linux. Or use Hans' DOS Python here. My fear is just that this all will not be too attractive to the students, since you don't have an environment which gives them "real problems" from the environment which they would use at work or at home. For me, it also doesn't make sense to teach on Win311 machines any longer since that is a dead OS which puts an unnecessary learning load on the beginner. If they go out and buy one of the cheapest machines, it will be for sure a 200MHz Pentium or up with probably Win98, at least 16MB of Ram since you can't buy less. You say, your machines take 20-30 seconds to load Python. Even on my old 16MB 486 machine which acts as a Linux server, Python is up and running after less than a second. Maybe you should tell your employers that it is cheaper to upgrade a couple of machines than to waste a lot of your precious time and of your tutees as well. Hardware is very cheap. If I would put a single 2-hour session into my tutorials to teach them an out-dated OS which they don't use after all, this would come at the same cost as buying a new machine. good luck - 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 Mon Apr 5 14:13:14 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Mon, 05 Apr 1999 15:13:14 +0200 Subject: [Tutor] Teaching computer programming References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> Message-ID: <3708B6EA.519CA988@appliedbiometrics.com> John Kleinjans wrote: > > We must remember that teaching _programming_ differs from teaching a > programming _language_. So if we want to develop some materials for > "teaching programming with Python", we need to focus on teaching > *programming* first. First, I usually try whetting their appetite. I show something to them that looks quite "spectacular" which they think they are far away to reach it. Then I show them the ridiculously short Python script which did it. I let them repeat it step by step, and they feel the power. Then it is time to try to explain what's going on. This might fill the whole course. I had most success by showing them Office automation. But well, they were no absolute beginners, no kids. What you would need would be some challenging graphics application which makes them eager to learn scripting. > A personal note: > > I like to teach programming for (at least) two reasons. One is because > teaching > people how computers work, and how to make computers do what they > want them to do, gives them power. The other reason is that it teaches > people how to think in a logical, connected, sequential, directed way. > That gives them even more power; power over their own minds, power to > control their thinking and the sequences of ideas in their own heads. You seem to be in the happy situation to teach kids. They are in highschool (and cannot run off if it's boring), and they are in fact able to learn a different kind of thinking in that age. Much less with my grown-ups, there is not much chance to install something completely different, since the brains are very much settled already. And I have to fight the "what is it good for" question all the time, since I'm wasting paid working time. > I think that teaching computer programming is a very powerful tool for > teaching people how to think clearly. The program runs, or it doesn't. It > does what you want, or not. The cause is (usually) in plain sight, in the > source code; the error is in one's understanding or precision. Hmm, this is true, for sufficiently trivial pro(gram|blem)s :-) In "real world" (which is quite often some Windows platform), this is quite different since your program isn't alone. My most beloved problem is if I get something running in the debugger, but it crashes when run alone. This sharpenes thinking even more, since you are trying to figure out what could be wrong, who is causing this, is there a bug in the documentation or in some dll which you have to use, and so on. This is no longer deterministic, but defensive programming. > Maybe say "a variable is a place to put a piece of data that can change > (that's why we > call it a "VARIable") and that we want to use later. Maybe call it 'box1' > (and 'box2', > etc.) to allow us to use that metaphor, and help the learners learn to > think clearly and > correctly about these things. > > Now we have input, output, and variables. How much can we do with that much? > Can we now give learners a few programming assignments? It's tough, with no > 'if' > or 'while', but such is life. > > --Write a program to take in two numbers and return the > sum/difference/product/quotient. Or maybe all of the above. > > box1 = input("First number: ") # User types a number; it goes into box1 > box2 = input("Second number: ") # User types another; it goes into box2 > box3 = box1 + box2 # Add what's in box1 and box2; put it into box3 > print box3 # Show what's in box3 > > So when 'box' is on the _left_ of the equals sign, we *put something into > it*. And > when it's on the _right_ of the equals sign, we *see what's in it*. (I'd > say that we > 'get' what's in the box on the right, except that what's there _stays_ > there--it's like, > when I tell you something that doesn't make me forget it!). Well, let me dig in here. It is correct to give this simple view to beginners in the first place. But yu need to be aware that this is not very true in a language like Python. Some day later, you must try to get the full truth to them. Variables in Python have almost nothing in common with variables in QBasic or any other compiled language. Boxes are ok so far. Boxes take the values. But variables are better seen as lables, sticked to the boxes. They just hold a reference, not the value. This is hard to recognise with simle number or string variables, but as soon as you are dealing with structures like lists an tuples, the difference will be very visible. I can only recommend to read the documentation about Python's object model very carefully and learn about that whatever you can, since you will run into the following situation more or less early: Your kids find out that they can do a = range(3) b = range(3) or also a = b Now, they modify the "box" a by a.append("howdy") and look at b, which has changed as well. They will ask you what happened, and you must be prepared to give a good answer which they understand. The list is an object, with a and b being labels sticked at it. This is also true for many of the simple types like string and numbers. They are often shared objects, although in this case it makes no difference since they cannot be changed. If they get that right, they will avoid a lot of mystic errors in their future programs. > Aha! We should explain 'commands' and 'functions'. But maybe not just yet! > At least, we do need to point out that 'input' has parentheses after it, > and 'print' doesn't. Maybe you could use this opportunity to introduce functions as first class objects in he first place? You don't need to use difficult wording, but give them just an "input" or some other function like "max" and let them play with it. Tell them there is a thing like "max" which can be assigned to any variable as well. It just happens to be callable. They can invoke it by putting arguments in parentheses behind it. But they also can inspect it, look at its __doc__, take a dir() from it, and so on. This is the basic interactive playing with mud which so many other languages are lacking. This can become real fun when they begin to find out things alone. > It occurs to me that teaching programming must be > (I've come to hate the word) proactive. That is, you > can't just wait for learners to ask questions, because they > don't know enough to ask the right questions in the > right sequence. You need to initiate and introduce > sequences of ideas. I don't expect my students to > invent pointers, much less linked lists. Shoot, most > of them are hazy about differences between integers and > floats ("something we saw in math"). Give them a small problem, solve it with them, and let them explain what they saw. Of course they don't need to invent pointers. Throw a list at them, and they will ask you good questions. Python is such a smart tool which gives you data structures at your finger tips, without having to teach all the mess about pointers, memory, element size and whatsoever. When I remember the 2 semester programming course which I attended in 1979 (in Algol 68 which already was high level and very modern stuff), I have to say this would have been even more effective using Python. > I think that there's a lot you can teach people who > only know 'print' and 'input()'. > 'if' is a good next candidate. Right after that, 'while' > is useful, so the user doesn't > have to re-start the program for each run. I'm in doubt wether it is good to start with "input" at all. It does an evaluation of the user's input already, and how do you want to explain that? I would use raw_input, or better nothing at all. Let them just assign values to variables. Then, I would try to get them writing their own little function as early as possible. Let them feel that they can build their own tiny callables which are similar to the builtin functions and imported stuff. I would even do this before coming to control structures, since writing useful functions is one of the biggest hurdles for most beginners which I've seen. They end up with large "main" programs and lots of global variables. Writing tiny functions from the beginning is something which you can achieve easily with Python. Where are they in math, BTW? Writing a couple of functions which solve their math homework can give a lot of motivation :-) 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 -- Python changes both our learning and our teaching -- From tismer@appliedbiometrics.com Mon Apr 5 14:24:31 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Mon, 05 Apr 1999 15:24:31 +0200 Subject: [Tutor] Learning programming References: <37061291.15DD@meta3.net> <3.0.3.32.19990404102049.006bbf04@mail.meta3.net> <3708A3CE.7582B39F@appliedbiometrics.com> Message-ID: <3708B98F.6484E5AD@appliedbiometrics.com> Christian Tismer wrote: [dropping my gibberish] > Maybe you should tell your employers that it is cheaper > to upgrade a couple of machines than to waste a lot of > your precious time and of your tutees as well. Hardware > is very cheap. If I would put a single 2-hour session > into my tutorials to teach them an out-dated OS which > they don't use after all, this would come at the same > cost as buying a new machine. When I wrote this I forgot that you are in high school. If it is a similar situation as here in Germany, then there can't be much done about this. Nobody realizes the waste of human resources in school, and who finally pays the bill. Sometimes it makes sense to talk to the parents to collect some money or donate a older machine. Sorry for being not carefully reading - 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 Apr 6 09:40:10 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 06 Apr 1999 10:40:10 +0200 Subject: [Tutor] Learning programming References: <37061291.15DD@meta3.net> <3.0.3.32.19990404091625.006b8840@mail.meta3.net> Message-ID: <3709C86A.5B08B97A@pop.vet.uu.nl> John Kleinjans wrote: > How does one "write a mian program ... and simply > run it" without importing it? Hm, coupled with 'put files in python directory' in your earlier list, this points out a possible misconception which nobody seems to have pointed out yet. The Python interactive mode is nice to do simple things, but for bigger programs you usually don't use it. It seems as if you've been using it as follows: * Put your program module in the python directory, so that the module is found by python for importing * start the command line * import yourprogram * call the start function of yourprogram to start your program This is not necessary. Instead, you can do: * Put your program in any directory at all. * go to the DOS command line (or load the file into PythonWin or IDLE or some other IDE, or even Emacs (great, wonderful, but probably not recommended for newbies)). * At the DOS command line (in the same directory as your program), you type: python yourprogram.py This starts your program. In your favorite IDE, use the 'run' command to do the same. In Emacs in Python mode this is control-C control-C. If you're not going to use Emacs (in win95, NTEmacs or XEmacs for win32 works) for your students, at least try it out for yourself. Hmm, auto indenting in Python mode..execute current buffer..output in a separate window.. And ugh, obscure space jockey commands to do simple stuff! :) If I had a misconception about your possible misconception, consider this post as not posted. :) Regards, Martijn From M.Faassen@vet.uu.nl Tue Apr 6 10:05:20 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Tue, 06 Apr 1999 11:05:20 +0200 Subject: [Tutor] Learning programming References: <37061291.15DD@meta3.net> <3.0.3.32.19990404103637.006bbf04@mail.meta3.net> Message-ID: <3709CE50.37A84AC1@pop.vet.uu.nl> John Kleinjans wrote: > What I'm thinking here about teaching (and learning) programming is that: > > 1. QBasic is a procedural language, and introduces sequence, branches, and > loops; variables, constants, and data types; input, processing, and output; > arrays > and structures (and arrays of structures)... but if you got this far, don't > put too > much more energy into it but instead switch to ... Why not skip QBasic and do Python instead? Python is in my opinion a much cleaner language than QBasic, and can do anything QBasic can (with less effort :). You can do procedural programming in Python just fine. > 2. C, which is more... everything (except easy). Now you begin to learn (some) > how the computer actually works. But still a procedural language. While C is a good language to know as a programmer, I'm not sure if it's necessary to teach it in an introductory programming course. It's low level and makes some fairly basic stuff like string manipulation far more difficult than it is in Python (or QBasic). *if* you want to teach C, then Python is a better start than QBasic in my opinion: * Python exposes some Pythonized C libraries as modules. This way people can become familiar with aspects of C (such as stdin and stdout) without actually programming in C yet. * You can teach C as a way of extending Python. That way you can make C useful much sooner. > 3. OhOh. Now we have to think in a whole new way. At least, I've been told > by a reputable source that the key to programming objects is to understand > objects--and then learn how to write code that does that. And I'm not so sure > that C++ is the best way to _learn_ how to think like that. I agree, I would definitely not recommend C++ for teaching object oriented concepts. Python is a good language to teach most basic object oriented concepts as used in C++ and other OO languages. The main exception is perhaps data hiding, for which Python has only limited facilities. Of course one can and should still practice data hiding without facilities for it in the language anyway. > So (as usual) I'm going from the known to the unknown--and in such a case > (aka lack of knowledge) I have to go on informed intuition. > > BTW--as I re-read this before sending it (what a concept!) I notice that I > followed up on a loose end that I left dangling from my previous post. That > is where I said (and I manually cut and paste) ... > > --> I generally start teaching programming with Qbasic. Then, when the kids > --> know something about (list of topics here) > > ... that "list of topics here" was (partially) enumerated above in #1. > > Do we need to teach all these things _before_ we get into objects? How much > procedural programming do we need to learn OO? How and where does > knowledge of procedural programming methods interfere with learning OO? > Is there an OO way of thinking that doesn't depend on ... Actually, good procedural and object based (which is basically object-oriented without inheritance) is not that far apart at all. procedural (in Python): # define the structure of the data # could be a dictionary, a list, an empty class, or a data-only class or whatever data = {} # define procedures which work on that data def print_data(data): for key in data.keys(): print key, data[key] def add_keyvalue(data, key, value): data[key] = value ... # to use: mydata = { "foo" : "bar" } print_data(mydata) add_keyvalue(mydata, "hm", "um") object based (in Python): class Data: def __init__(self, some_data): self.data = some_data # initialize object self with some starting data def print(self): for key in self.data.keys(): print key, self.data[key] def add_keyvalue(self, key, value): self.data[key] = value ... # to use an object of this class: mydata = Data({"foo" : "bar"}) mydata.print() mydata.add_keyvalue("hm", "um") In Python, object based is introduced rapidly as many built in modules and even more importantly, the sequence data types make use of object based techniques: mylist.append(7) # object based way to add 7 to a list > Anyway. I can't answer these questions because I don't know OO. As I said > earlier, I've intentionally kept away from C++ in an effort to clearly > learn C. That is a good idea; it's good to learn C (and all the lore and programming techniques associated with it -- C itself isn't much without all the lore on how to use it): * C can be compiled to very efficient code * Many programming libraries (such as those in Windows and Linux) are most easily used/interfaced to from C (as the libraries themselves are in C). * it opens up a lot of sources to your perusal (the majority of open source/free software projects, including Python, are written in C) Good luck, and regards, Martijn From johnk@meta3.net Wed Apr 7 12:23:18 1999 From: johnk@meta3.net (John Kleinjans) Date: Wed, 07 Apr 1999 06:23:18 -0500 Subject: [Tutor] Teaching computer programming In-Reply-To: <3708B6EA.519CA988@appliedbiometrics.com> References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> Message-ID: <3.0.3.32.19990407062318.006864f4@mail.meta3.net> At 03:13 PM 4/5/99 +0200, you wrote: >John Kleinjans wrote: >> >> We must remember that teaching _programming_ >First, I usually try whetting their appetite. I show something >to them that looks quite "spectacular" which they think they >are far away to reach it. Then I show them the ridiculously >short Python script which did it. I let them repeat it step >by step, and they feel the power. Then it is time to try >to explain what's going on. This might fill the whole course. You call it a "script". Is this the same as a "program"? Or is there a functional/conceptual difference? I know Python is sometimes called a "scripting language"--maybe you can tell me what that is? >I had most success by showing them Office automation. But >well, they were no absolute beginners, no kids. >What you would need would be some challenging graphics >application which makes them eager to learn scripting. Anybody know of a/some good one/s? >You seem to be in the happy situation to teach kids. >They are in highschool (and cannot run off if it's boring), >and they are in fact able to learn a different kind of thinking >in that age. Yes, I do teach kids. I teach in a poor school district, and most of the kids are two years (or more) below grade level. My biggest problem is to get them to _try_, to get the kids to make an effort, to attempt to actually think--because they got along until now, and maybe never saw much thinking before. They think that thinking is hard work, not fun! And that living on government aid is a career... and that fighting and being in a gang is cool... So I can have a big impact on someone's whole life, if they want it. I keep telling them "a teacher can only bring knowledge to your eyeballs and eardrums--YOU have to move it the last 3 inches" (about 8 cm). And if they can start doing _that_, then we can go somewhere. And if they make an effort, they will have some success--and if they have some success, they might make an effort again... But back to teaching programming with Python. >Much less with my grown-ups, there is not much >chance to install something completely different, since >the brains are very much settled already. >And I have to fight the "what is it good for" question >all the time, since I'm wasting paid working time. So what is a baby good for? ;-) >> I think that teaching computer programming is a very powerful tool for >> teaching people how to think clearly. The program runs, or it doesn't. It >> does what you want, or not. The cause is (usually) in plain sight, in the >> source code; the error is in one's understanding or precision. > >Hmm, this is true, for sufficiently trivial pro(gram|blem)s :-) > >In "real world" (which is quite often some Windows platform), >this is quite different since your program isn't alone. >My most beloved problem is if I get something running >in the debugger, but it crashes when run alone. This >sharpenes thinking even more, since you are trying to >figure out what could be wrong, who is causing this, >is there a bug in the documentation or in some dll >which you have to use, and so on. This is no longer >deterministic, but defensive programming. And we'll get there, too, one step at a time. Then we're getting to a place where we need to understand how programs 'think', and how they share information with each other--how the system works. But for a person first learning programming, that is far away. First crawl, then walk, then run, and fly... then maybe "beam me up, Scotty". So we start with "trivial" programs--the first step looks small when you look back down at it, but it can seem very big to those who are looking *up* at it. > >> So when 'box' is on the _left_ of the equals sign, we *put something into >> it*. And >> when it's on the _right_ of the equals sign, we *see what's in it*. (I'd >> say that we >> 'get' what's in the box on the right, except that what's there _stays_ >> there--it's like, >> when I tell you something that doesn't make me forget it!). > >Well, let me dig in here. It is correct to give this simple >view to beginners in the first place. But yu need to be aware >that this is not very true in a language like Python. Some >day later, you must try to get the full truth to them. This is why I (John) put this here. I don't know objects--this is one reason why I feel that Python is a good next step for me. And I want to test ideas with you. When teaching procedural languages, we need to teach variables quite soon, because programs with no variables don't let us do interesting things. I have this feeling that objects are different ('feeling' because my ideas aren't clear, because I don't know, and I know that I don't know). So, what should you teach to a person learning programming for the very first time? Is there a more productive first look to show them? >Variables in Python have almost nothing in common with variables >in QBasic or any other compiled language. > >Boxes are ok so far. Boxes take the values. >But variables are better seen as lables, sticked to the >boxes. They just hold a reference, not the value. >This is hard to recognise with simle number or string >variables, but as soon as you are dealing with structures >like lists an tuples, the difference will be very visible. So maybe we tell learners that 'box1' and 'box2' (or 'x' and 'y' and 'total') are _labels_ on the boxes. That is, when I type in "John", that has to go somewhere (into a "box"); and maybe we label the box 'fname', say. Similar idea, but a different emphasis. Is this a more productive way to present it? Or am I still stuck in the old thinking? >I can only recommend to read the documentation about >Python's object model very carefully and learn about that >whatever you can, since you will run into the following >situation more or less early: > >Your kids find out that they can do >a = range(3) >b = range(3) >or also >a = b > >Now, they modify the "box" a by >a.append("howdy") >and look at b, which has changed as well. > >They will ask you what happened, and you must be prepared >to give a good answer which they understand. The list is an >object, with a and b being labels sticked at it. >This is also true for many of the simple types like string >and numbers. They are often shared objects, although in this >case it makes no difference since they cannot be changed. >If they get that right, they will avoid a lot of mystic >errors in their future programs. Because we gave to one thing more than one name? We have one box, but we put two (or more) labels on it? >> Aha! We should explain 'commands' and 'functions'. >Maybe you could use this opportunity to introduce functions >as first class objects in he first place? You don't need to >use difficult wording, but give them just an "input" or >some other function like "max" and let them play with it. >Tell them there is a thing like "max" which can be assigned >to any variable as well. It just happens to be callable. >They can invoke it by putting arguments in parentheses >behind it. But they also can inspect it, look at its __doc__, >take a dir() from it, and so on. >This is the basic interactive playing with mud which so many >other languages are lacking. This can become real fun when >they begin to find out things alone. There's some language here that I don't understand. "first class objects", "assigned", "callable", "invoke", "arguments", "inspect", "look at its __doc__", "take a dir()" ... well, I know some of them--but students think that "callable" is someone with a telephone, and an "argument" is when you don't agree, "assigned" is where you sit, and so on. There's a lot of ideas inside each of those words. We have to help students build each idea, and then help put them together. Of course, it's better if they can experience it first. Then when you name it, they already know it--then it's easy. (The best teaching is like the best writing--the learners (readers) think it's real easy, and that the teacher (author) is doing nothing at all. When they go "Oh, that's obvious", then you know you set them up well.) If you name it first, before they see it, most kids get scared and can't think; or they define it (incorrectly) in terms of thingas they already know--and may have to un-learn that before they can understand. So maybe you have a small example program, then some "words" (commands or functions) to mess around with? >Give them a small problem, solve it with them, and let them >explain what they saw. Of course they don't need to invent >pointers. Throw a list at them, and they will ask you >good questions. Python is such a smart tool which gives >you data structures at your finger tips, without having >to teach all the mess about pointers, memory, element size >and whatsoever. >When I remember the 2 semester programming course which I >attended in 1979 (in Algol 68 which already was high level >and very modern stuff), I have to say this would have been >even more effective using Python. > >> I think that there's a lot you can teach people who >> only know 'print' and 'input()'. >> 'if' is a good next candidate. Right after that, 'while' >> is useful, so the user doesn't >> have to re-start the program for each run. > >I'm in doubt wether it is good to start with "input" >at all. It does an evaluation of the user's input >already, and how do you want to explain that? >I would use raw_input, or better nothing at all. >Let them just assign values to variables. >Then, I would try to get them writing their own >little function as early as possible. Let them feel >that they can build their own tiny callables which >are similar to the builtin functions and imported stuff. > >I would even do this before coming to control structures, >since writing useful functions is one of the biggest >hurdles for most beginners which I've seen. They end up >with large "main" programs and lots of global variables. >Writing tiny functions from the beginning is something >which you can achieve easily with Python. I agree--modular programming styles should be encouraged early. In-line code is a thought pattern that can be learned easily and un-learned with difficulty. >Where are they in math, BTW? Writing a couple of functions >which solve their math homework can give a lot of >motivation :-) > >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 > -- Python changes both our learning and our teaching -- > From tismer@appliedbiometrics.com Wed Apr 7 14:01:48 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Wed, 07 Apr 1999 15:01:48 +0200 Subject: [Tutor] Teaching computer programming References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> <3.0.3.32.19990407062318.006864f4@mail.meta3.net> Message-ID: <370B573C.E3F77B5A@appliedbiometrics.com> John Kleinjans wrote: > You call it a "script". Is this the same as a "program"? Or is there > a functional/conceptual difference? I know Python is sometimes > called a "scripting language"--maybe you can tell me what that is? There is no princial difference between scripts and programs. It seems to depend from the application. Usually, a program which does a specific task for a web server is called a script. Sometimes, scripts have the flavor of being a short time solution, where a program is a more general solution, but this is a matter of taste. Scripts tend to be small, and to perform a specific task. I often generate a script which contains a lot of simple calls to some functions, where the script is itself generated by another script. Such scripts can make sense if you want to perform a specific task, like special renaming or copying of file trees, generating a number of new Unix accounts and other stuff, where the OS shell script is sometimes less handy. I would name a Python program which transferres my starship account to a different machine a script. A python program which does no special action but just defines a bulk of useful functions and objects for, say, polynomial calculations, is a module. It will usually be not run alone, but be imported. A bunch of related modules which sit in a directory can be called a package. If the directory contains an __init__.py file, it is a true package, and one can import from it: import directory.pyfile Hmm. What is a program? Guido's idle package, when used as your shell, is for sure a program. Don't ask me why. ... > But back to teaching programming with Python. > > >Much less with my grown-ups, there is not much > >chance to install something completely different, since > >the brains are very much settled already. > >And I have to fight the "what is it good for" question > >all the time, since I'm wasting paid working time. > > So what is a baby good for? ;-) Good for teachers who need some success. ... > But for a person first learning programming, that is far away. > First crawl, then walk, then run, and fly... then maybe "beam me up, > Scotty". Well, let me try to scott you up, Beamie. [objects] > >Well, let me dig in here. It is correct to give this simple > >view to beginners in the first place. But yu need to be aware > >that this is not very true in a language like Python. Some > >day later, you must try to get the full truth to them. > > This is why I (John) put this here. I don't know objects--this is one > reason why I feel that Python is a good next step for me. And I want to > test ideas with you. Then let's look at an object. here comes a commented session: >>> range(7) [0, 1, 2, 3, 4, 5, 6] >>> What do we have here? I called the function "range" with an argument of "7". But range is more than a function, since everything is an object. Functions are first class objects, which means that I can refer to the function itself, not only by calling it but by spelling its name: >>> range >>> The range object is an object. Instead of calling it, I can use it itself as an argument for another function. In this case I use the dir() function to inspect range: >>> dir(range) ['__doc__', '__name__', '__self__'] >>> You can see that range has three attributes which are itself objects. The "__doc__" attribute is very useful if you want to know what range does: >>> print range.__doc__ range([start,] stop[, step]) -> list of integers Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements. >>> Now, let's go back to the beginning of this session where we called range() to get a list. This time, we do this again, but assign the result to a variable. >>> x=range(7) >>> x [0, 1, 2, 3, 4, 5, 6] >>> After the assignment, no output is printed. Python prints the output of expressions, but "x=range(7)" is an assignment statement. To see the result, I added the expression "x" which then was printed. More interesting, we now have the label x tied to the resulting object of our range(7) call. We nw can plax with this one as well. Let's have a look: >>> dir(x) ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> Whow, what a lot of attributes! Actually, these are all callables. That means, we see here the list of available methods which a list understands. Let's call one: >>> x.reverse() >>> x [6, 5, 4, 3, 2, 1, 0] >>> The reverse method changed the list object by reversing the positions of its elements. This happenes "in-place", and x.reverse() returned nothing (the None object) which gets not printed, for brevity. To relate this to what I said before, let's inspect this reverse method: >>> dir(x.reverse) ['__doc__', '__name__', '__self__'] >>> x.reverse.__doc__ 'L.reverse() -- reverse *IN PLACE*' >>> You see, I used this method (think "function of an object") again as a first class object, by not calling it. Instead, I used the method itself and printed its doc. > When teaching procedural languages, we need to teach variables > quite soon, because programs with no variables don't let us do > interesting things. > > I have this feeling that objects are different ('feeling' because my ideas > aren't clear, because I don't know, and I know that I don't know). So, > what should you teach to a person learning programming for the very first > time? Is there a more productive first look to show them? I never did. But I would think like this: Programming means to teach something to a machine in some way. Now that we have this nice machine with Python, let's teach it do do something simple: Add one to any number we give it. >>> def addone(num): ... return num+1 ... >>> addone(5) 6 >>> Great, isn't it? From here on, you can continue endlessly and keep it fun to the audience. And after a while, you can also show how similar this little function is to other callable objects: >>> dir(addone) ['__doc__', '__name__', 'func_code', 'func_defaults', 'func_doc', 'func_globals', 'func_name'] >>> It is just an object with a number of attributes. You can use it like any other object. For example, I'll create a list with quite a mixture of objects and do something with it: >>> x = [2,3,5, "hello", max, addone] >>> x[2]+5 10 >>> x[4](3,5) 5 >>> x[-1](3.14) 4.14 >>> len(x[3]) 5 >>> Step by step: I created a 6 element list. It is indexed from 0 to 5, as always in Python. You can also number from the back, by using negative indexes. I took the element with index 2 (which is the 5) and added 5. Then I took elemend with index 4 which is the function "max", and called it with two arguments. Then I used the last element (index -1 in this case) which happened to be out addone function, and called it. Then I used the len function to get the length of the string "hello" which was sitting at index 3. Got an idea? [boxes and lables] > >They will ask you what happened, and you must be prepared > >to give a good answer which they understand. The list is an > >object, with a and b being labels sticked at it. > >This is also true for many of the simple types like string > >and numbers. They are often shared objects, although in this > >case it makes no difference since they cannot be changed. > >If they get that right, they will avoid a lot of mystic > >errors in their future programs. > > Because we gave to one thing more than one name? We have one > box, but we put two (or more) labels on it? Right. And in the example above, we have some functions, accessible through a list, without the need of any labels. I could also rename any function simply by assignment: >>> f2 = addone >>> f2 >>> f2(7) 8 >>> f2.__doc__ = "there should be some doc" >>> addone.__doc__ 'there should be some doc' >>> As you can see, the function retains its original name, but that needn't be the name under which I access it. "f2" and "addone" are both labels which hld exactly the same object. I changed the __doc__ attribute of f2 and afterwards inspected addone's __doc__ attribute which had changed as well, since it is only one object. > There's some language here that I don't understand. "first class > objects", "assigned", "callable", "invoke", "arguments", "inspect", > "look at its __doc__", "take a dir()" ... > well, I know some of them--but students think that "callable" is > someone with a telephone, and an "argument" is when you don't > agree, "assigned" is where you sit, and so on. There's a lot of ideas > inside each of those words. We have to help students build each > idea, and then help put them together. > > Of course, it's better if they can experience it first. Then when you > name it, they already know it--then it's easy. Well, while they play with it, you can carefully inject the one or other word to name the things. While writing "addone(7)", you tell them that you call the function addone and give it the argument 7. You might want to avoid "first class" for your first class 101 students, instead you would explain how to fetch the function itself, as seen above. There isn't much more about it. I think I touched some of the points you asked. Now you should play for yourself and feel the difference. good luck - waiting for the next questions - 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 Wed Apr 7 14:04:34 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Wed, 07 Apr 1999 15:04:34 +0200 Subject: [Tutor] Teaching computer programming References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> <3.0.3.32.19990407062318.006864f4@mail.meta3.net> Message-ID: <370B57E2.59A4A6B6@pop.vet.uu.nl> John Kleinjans wrote: > > At 03:13 PM 4/5/99 +0200, Christian Tismer wrote: [mentions 'script'] > You call it a "script". Is this the same as a "program"? Or is there > a functional/conceptual difference? I know Python is sometimes > called a "scripting language"--maybe you can tell me what that is? There isn't any hard difference between 'script' and 'program'; 'script' has a rather fuzzy definition. However, some properties of scripts (as opposed to programs): * 'scripts' tend to be smaller than 'programs' * A script is usually interpreted, not compiled * Some scripting languages (but not Python, Perl, Tcl) are limited in general power; they may be handy for some things, but absolutely unsuited for others. (MSDOS .bat files are an example, though I've seen them twisted into horrible contraptions that *would* do those other things anyway..*shudder*). * Scripting languages often script applications; some are special purpose languages intended to increase the power and flexibility of an application: - VB for applications for MS Office - Lingo for Macromedia Director - JavaScript for web browsers - shell scripts for Unix shells etc Python, Perl and Tcl however are general purpose scripting languages; while they are excellent at scripting particular applications, they can adapt to do just about anything. I don't particularly like scripting languages that grow from one particular application domain into a generic programming languages; their design tends to suffer from such straining. These are some factors that make people call something a script as opposed to a program. But the difference is really fuzzy. Python can be used to write programs just fine. Python is an interpreter and not a compiler, but an interpreted language is not automatically a scripting language; Java works with an interpreter too, for instance; many Lisps do; Smalltalk traditionally does. There are even C interpreters. The use of the word 'script' in the context of Python is more tradition, and perhaps indication of program size and complexity, than any qualitative difference. > >You seem to be in the happy situation to teach kids. > >They are in highschool (and cannot run off if it's boring), > >and they are in fact able to learn a different kind of thinking > >in that age. > > Yes, I do teach kids. I teach in a poor school district, and most of the > kids are two years (or more) below grade level. My biggest problem > is to get them to _try_, to get the kids to make an effort, to attempt to > actually think--because they got along until now, and maybe never > saw much thinking before. They think that thinking is hard work, not > fun! And that living on government aid is a career... and that fighting > and being in a gang is cool... Ooh, but thinking is lots of fun. :) Programming can be a pain, but also a craft, a sport, an art. And there's the feeling of accomplishment, and power to do new things. > So I can have a big impact on someone's whole life, if they want it. I > keep telling them "a teacher can only bring knowledge to your eyeballs > and eardrums--YOU have to move it the last 3 inches" (about 8 cm). And > if they can start doing _that_, then we can go somewhere. I don't know if internet access is very feasible for them, but you might want to try to introduce the more enthusiastic ones to the Python community on the net. A community can be very stimulating and helpful; and the Python community is one of the most civilized ones I've encountered on the net (I post an April Fool's joke on a Python chip, and this quickly mutates into a discussion on Forth chips, Lips chips, Java chips, Pascal chips -- where else but in comp.lang.python? :) > And if they make an effort, they will have some success--and if they have > some success, they might make an effort again... Keep us informed on how things go with your class, please. I'm curious. [big snip] > >Well, let me dig in here. It is correct to give this simple > >view to beginners in the first place. But yu need to be aware > >that this is not very true in a language like Python. Some > >day later, you must try to get the full truth to them. > > This is why I (John) put this here. I don't know objects--this is one > reason why I feel that Python is a good next step for me. And I want to > test ideas with you. This doesn't have to do with objects so much, though (although everything in Python is an object, really). Every variable in Python is a *pointer* to something; an object. Lots of objects are simple and immutable, for instance, numbers: a = 1 # variable 'a' points to a number object with value '1' b = 2 # 'b' points to 2 a = b # a now points to the 2 object too (1 isn't pointed to anymore) a = a + 1 # a point to the object resulting from the addition With immutable objects (in Python, numbers, strings, tuples among others), this all behaves just like one would expect. The 'trouble' starts when you use mutable objects, such as lists, dictionaries, or class instantations (classic 'objects'): a = [1] # variable 'a' points to a list containing one element (1) b = [] # variable 'b' points to a list containing no elements a = b # 'a' points now to the same list as 'b' does b.append(2) # we append '2' to the b list (b now points to [2]) # but a now also points to [2], as it pointed to the same list as b did! As long the objects these variables point to can't change (are immutable), the semantics is as if the objects are being copied. The reference semantics (as opposed to copying semantics) only becomes apparant when you deal with mutable objects. The advantage of reference semantics (among other things) is that it's much more efficient to pass a reference to an object instead of copying the object itself. Python is consistent in applying reference semantics, so once one knows what is going on it's not often a problem. > When teaching procedural languages, we need to teach variables > quite soon, because programs with no variables don't let us do > interesting things. I'll reiterate that Python works fine as a procedural language as well. :) Python is a language that has object oriented *facilities*, but it can be used for procedural code just as well. > I have this feeling that objects are different ('feeling' because my ideas > aren't clear, because I don't know, and I know that I don't know). So, > what should you teach to a person learning programming for the very first > time? Is there a more productive first look to show them? > > >Variables in Python have almost nothing in common with variables > >in QBasic or any other compiled language. Actually there are plenty of compiled languages with reference semantics (though they are not always consistent). Delphi uses reference semantics for objects, for instance. Also, in C you have pointer variables which are basically references (though you need to state this explicitly). In Python, there's a consistency that's absent in many other languages; everything, from the most basic number to a complicated datastructure is treated as a 'first class object'. This makes reference semantics easier to follow. But the use of reference semantics as opposed to copying semantics is not exclusive to object oriented languages. > >Boxes are ok so far. Boxes take the values. > >But variables are better seen as lables, sticked to the > >boxes. They just hold a reference, not the value. > >This is hard to recognise with simle number or string > >variables, but as soon as you are dealing with structures > >like lists an tuples, the difference will be very visible. Not with tuples, as they're immutable, but with lists and objects made from classes, yes. > So maybe we tell learners that 'box1' and 'box2' (or 'x' and 'y' and > 'total') are _labels_ on the boxes. That is, when I type in "John", that > has to go somewhere (into a "box"); and maybe we label the box > 'fname', say. Similar idea, but a different emphasis. Is this a more > productive way to present it? Or am I still stuck in the old thinking? No, the use of labels that point to boxes works fine for this. All variables are labels, that point to boxes. The boxes contain the real data. With immutable box content, it doesn't matter if two labels point to the same box; making a new label point to the same box is semantically equivalent to making a new box with a copy of the old content, and making the label point to that. With mutable box content, it isn't equivalent, however. If you have two labels point to the same box, and you change the content of the box, both labels now point to the new data. If instead you had copied the box (explicitly, as you need to in Python), or just produced a new box for the new label, changing one box through one label doesn't change the contents of the box that the other label is pointing to. These are equivalent to the outside world: a, b -> [immutable, data 'foo'] a -> [immutable, data 'foo'] b -> [immutable, data 'foo'] These are not: a, b -> [mutable, data 'foo'] (what if you change the value b points to, to 'bar'? a changes too) a -> [mutable, data 'foo'] b -> [mutable, data 'foo'] (if you change the value b points to, a doesn't change) > >Maybe you could use this opportunity to introduce functions > >as first class objects in he first place? You don't need to > >use difficult wording, but give them just an "input" or > >some other function like "max" and let them play with it. > >Tell them there is a thing like "max" which can be assigned > >to any variable as well. It just happens to be callable. > >They can invoke it by putting arguments in parentheses > >behind it. But they also can inspect it, look at its __doc__, > >take a dir() from it, and so on. > >This is the basic interactive playing with mud which so many > >other languages are lacking. This can become real fun when > >they begin to find out things alone. > > There's some language here that I don't understand. > "first class objects" Basically, everything can be treated like everything else, as an object (a box). A function can be assigned to a variable (in fact, all functions are just variables which are labels for 'function boxes'). def myfunction(foo): print foo anotherfunction = myfunction anotherfunction("hello") # does the same as myfunction does > "assigned" What '=' does. In Python, '=' only makes labels (variables) point to new boxes; it doesn't copy any data. > "callable" A first class object (a box) that can be called by code. 'myfunction' is for instance callable. With Python, you can also make class instances callable (so that they look like a function to the world, but in fact can also contain other data or other functions). A class in Python is also callable; __init__ is called to create an instance of a class when you call a class, for instance: class Foo: def __init__(self): # do some initialization self.mydata = "hey" myfoo = Foo() # call class Foo to instantiate it > "invoke" The same as 'call', really. Compare with magic (by the way, the magic metaphor would be good for students, I think!). You invoke (call upon) a function to do something. > "arguments" Labels (variables) you pass to the code of a function. The function code can then read or modify the content of the boxes these labels point to. > "inspect", 'look at' :) > "look at its __doc__", A function (and lots of other things) in Python can have a __doc__ string associated with it. This is just a textual string which you can fill with information on how the function works, for instance: def myfunction(): """Blah blah, some text on what this does. I am using three double quotes to quote a multiline block of text Here I put all kinds of interesting comments about myfunction. """ print "Hey, the actual thing the function does." They are like comments, but the intent is that tools can automatically extract this information to produce documentation. It is often more about *what* a function does than about *how* it works; use '#' style comments for that. > "take a dir()" ... Look this up in the Python Library reference, built in functions. :) > well, I know some of them--but students think that "callable" is > someone with a telephone, and an "argument" is when you don't > agree, "assigned" is where you sit, and so on. There's a lot of ideas > inside each of those words. We have to help students build each > idea, and then help put them together. Definitely agreed. Sorry if I provided explanations you didn't need. > Of course, it's better if they can experience it first. Then when you > name it, they already know it--then it's easy. > > (The best teaching is like the best writing--the learners (readers) think > it's real easy, and that the teacher (author) is doing nothing at all. When > they go "Oh, that's obvious", then you know you set them up well.) > > If you name it first, before they see it, most kids get scared and > can't think; or they define it (incorrectly) in terms of thingas they > already know--and may have to un-learn that before they can > understand. One way is to use labels and boxes; concepts they already know about. Another option could be to use little men (variables) instead of labels, which point to boxes (which may in fact be complicated contraptions such as more Python code). The advantage of little men that point is that little men can easily point to something else; a label tends to be put on something. Each little man has a name (the variable name, of course). Feel free to include women, dragons, and other critters. :) Callable guys are guys whom you give the names of some other individuals (arguments), and that go off and activate the contraption they're pointing to: Hank, please do your thing (what you're pointing at) with whatever Carl, Diane and Martijn are pointing to. *Hank walks over to the machine he's pointing at, fills in (on some display) the secret internal id codes of the things Carl Diane and Martijn point to, and pushes the 'start' button. The machine starts humming and steaming, and perhaps tells Foo the dragon to do the stuff he is pointing at, too, in the process. Etc. This can get very complicated, which shows once again organizing your code in a good way is probably the most important aspect of programming. Hm, this became a rather long post. I hope it was useful! I'm just interested in teaching people how to program; it's a good way to train one's mind along with a useful skill to have. Regards, Martijn From tismer@appliedbiometrics.com Wed Apr 7 14:49:29 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Wed, 07 Apr 1999 15:49:29 +0200 Subject: [Tutor] Teaching computer programming References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> <3.0.3.32.19990407062318.006864f4@mail.meta3.net> <370B57E2.59A4A6B6@pop.vet.uu.nl> Message-ID: <370B6269.1C0A0769@appliedbiometrics.com> Some minor points, without wanting to spoil your good work... Martijn Faassen wrote: > > John Kleinjans wrote: [skipping the "script" definiton - agreed all] [boxes:] > > >Boxes are ok so far. Boxes take the values. > > >But variables are better seen as lables, sticked to the > > >boxes. They just hold a reference, not the value. > > >This is hard to recognise with simle number or string > > >variables, but as soon as you are dealing with structures > > >like lists an tuples, the difference will be very visible. > > Not with tuples, as they're immutable, but with lists and objects made > from classes, yes. Well, you can put a mutable object into a tuple multiple times and then see that the elements are changing alltogether. You are right in the sense of it, I just meant examples for any objects with some structure and took these. It is exactly the time when they touch these, that they need to understand. [all fine, although I had avoided "class" in this early stage] > > "arguments" > > Labels (variables) you pass to the code of a function. The function code > can then read or modify the content of the boxes these labels point to. This is wrong. Arguments are values which are passed to a function. Arguments are the sight of the caller. The callee receives them by local variables which are the lables sticked to the actual arguments. Right? ... > > "take a dir()" ... > > Look this up in the Python Library reference, built in functions. :) This is one idiom which I usually address with "inspect". Meaning "apply a dir, print __doc__, or print the object, or pick an attribute and look at that" where dir() is most valuable to learn about imported modules, find its functions, and then look at them. Most valuable for beginners. I would always tell them and not wait until they read the docs :-) > One way is to use labels and boxes; concepts they already know about. > Another option could be to use little men (variables) instead of labels, > which point to boxes (which may in fact be complicated contraptions such > as more Python code). The advantage of little men that point is that > little men can easily point to something else; a label tends to be put > on something. Each little man has a name (the variable name, of course). > Feel free to include women, dragons, and other critters. :) Callable > guys are guys whom you give the names of some other individuals > (arguments), and that go off and activate the contraption they're > pointing to: > > Hank, please do your thing (what you're pointing at) with whatever Carl, > Diane and Martijn are pointing to. Hmm. Grading people down to be just a label? Changing their content with any assignment? I think, I would save people for something different, like class instances which can be like individuals. But an individual is not just a nobody who takes some identity by pointing. Are you successful with this model? > *Hank walks over to the machine he's pointing at, fills in (on some > display) the secret internal id codes of the things Carl Diane and > Martijn point to, and pushes the 'start' button. The machine starts > humming and steaming, and perhaps tells Foo the dragon to do the stuff > he is pointing at, too, in the process. Etc. This can get very > complicated, which shows once again organizing your code in a good way > is probably the most important aspect of programming. I think htis is ok if you are talking of objects as individuals. That they refer to each other by attributes is ok. But how to explain their own existence in the module namespace? Maybe they can play a role there. The module is a room with chairs. Or with marionette threads, tied to the people. Hmm, still easier for me with labels and boxes, but thinking... Anyway, this was great input - 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 Wed Apr 7 21:47:27 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Wed, 07 Apr 1999 22:47:27 +0200 Subject: [Tutor] Teaching computer programming References: <3.0.3.32.19990404143520.006b2ecc@mail.meta3.net> <3.0.3.32.19990407062318.006864f4@mail.meta3.net> <370B57E2.59A4A6B6@pop.vet.uu.nl> <370B6269.1C0A0769@appliedbiometrics.com> Message-ID: <370BC45F.8ED1D89@pop.vet.uu.nl> Christian Tismer wrote: > > Some minor points, without wanting to spoil your good work... No problem. :) [snip] > > > >Boxes are ok so far. Boxes take the values. > > > >But variables are better seen as lables, sticked to the > > > >boxes. They just hold a reference, not the value. > > > >This is hard to recognise with simle number or string > > > >variables, but as soon as you are dealing with structures > > > >like lists an tuples, the difference will be very visible. > > > > Not with tuples, as they're immutable, but with lists and objects made > > from classes, yes. > > Well, you can put a mutable object into a tuple > multiple times and then see that the elements are > changing alltogether. You are right in the sense of > it, I just meant examples for any objects with some > structure and took these. It is exactly the time > when they touch these, that they need to understand. True; I didn't think of tuples containing mutable objects -- my talk about 'with immutable objects copy and reference semantics are the same in practice' only applies to immutable objects that only contain immutable objects. :) > [all fine, although I had avoided "class" in this early stage] > > > > "arguments" > > > > Labels (variables) you pass to the code of a function. The function code > > can then read or modify the content of the boxes these labels point to. > > This is wrong. Arguments are values which are passed to a function. > Arguments are the sight of the caller. The callee receives them > by local variables which are the lables sticked to the actual > arguments. Right? No, as far as I'm aware you pass references to actual values to functions in Python: a = [1, 2] def append_something(alist): alist.append(3) append_something(a) print a # prints [1, 2, 3] You give a reference to a value/data/box/object to a function as an argument. The called function now has a local variable that references the same thing as the argument you passed. If this argument points to mutable data, and you change the data, the data is altered. So no values are in fact passed, only references. Anyway, I think you mean the same thing, but somehow we don't seem to be communicating this with each other without misunderstanding -- you seem to be saying here that an actual data value (not a reference) is passed to a function. [people pointing at things as reference variables] > Hmm. Grading people down to be just a label? Changing their > content with any assignment? You only change the way they point. labels don't have a content, they just point. That's what is confusing about a label; in the real world, you label something, and you then don't pull off the sticker and put it on another box, generally. You also don't tend to label the same box twice. People, however, can point to places. arrows can too, but they don't generally do things, like walk to the box they're pointing at, inserting arguments, and pressing the start button. :) But of course it's contrived; there must be a metaphor combining the advantage of labels with the advantage of people somewhere. :) > I think, I would save people > for something different, like class instances which can be > like individuals. Well, the people idea is contrived. :) > But an individual is not just a nobody > who takes some identity by pointing. Are you successful with > this model? No; I came up with it today and I got criticism from one person already ;). > > *Hank walks over to the machine he's pointing at, fills in (on some > > display) the secret internal id codes of the things Carl Diane and > > Martijn point to, and pushes the 'start' button. The machine starts > > humming and steaming, and perhaps tells Foo the dragon to do the stuff > > he is pointing at, too, in the process. Etc. This can get very > > complicated, which shows once again organizing your code in a good way > > is probably the most important aspect of programming. > > I think htis is ok if you are talking of objects as > individuals. Actually in this case I was talking about plain functions. A class would be a bunch of people in a group -- I'm thinking this through but realizes this gets messy while using either labels and boxes or people and boxes.. > That they refer to each other by attributes > is ok. But how to explain their own existence in the module > namespace? Maybe they can play a role there. The module > is a room with chairs. Or with marionette threads, tied to > the people. Modules get messy too. :) > Hmm, still easier for me with labels and boxes, but thinking... Good, good. We'll come up with that better metaphor yet! :) I admit I hardly ever think about people or labels myself in all this. I think about pointers (arrows) and data/objects/boxes in memory. Fairly low level C stuff, actually, though the arrow thing isn't that hard to grasp for a beginner, I think, just a bit abstract. > Anyway, this was great input - chris Thanks! Martijn From tim_one@email.msn.com Sun Apr 11 21:42:53 1999 From: tim_one@email.msn.com (Tim Peters) Date: Sun, 11 Apr 1999 16:42:53 -0400 Subject: [Tutor] Teaching computer programming In-Reply-To: <370BC45F.8ED1D89@pop.vet.uu.nl> Message-ID: <000b01be845b$df4cdf40$2a9e2299@tim> [Martijn Faassen] > ... > You only change the way they point. labels don't have a content, they > just point. That's what is confusing about a label; in the real world, > you label something, and you then don't pull off the sticker and put it > on another box, generally. Think of people and their many names. You stand in line at the bank, and the name "next, please" eventually gets ripped off the joker in front of you and passed on to you. Or the name "my girlfriend/boyfriend" typically gets applied to several different people before your third marriage . Heck, the name "Mr. Peters" even got pasted on me when my dad died. > You also don't tend to label the same box twice. Martijn, Mr. Fassen, dad, son, Mrs. Fassen's husband, "hey, you!" -- we all get lots of labels over the course of a day. > ... > But of course it's contrived; there must be a metaphor combining the > advantage of labels with the advantage of people somewhere. :) I'm not sure people have *any* advantages , but names are to people as references are to objects. Plus "immutable people" is familiar to anyone with a boss . call-me-uncle-timmy-or-call-me-xyz.a[i-1].who().name-i'm-still- id-number-0x037f21b8-ly y'rs - tim From Good2not@aol.com Mon Apr 12 04:40:27 1999 From: Good2not@aol.com (Good2not@aol.com) Date: Sun, 11 Apr 1999 23:40:27 EDT Subject: [Tutor] New to this idea (!) Message-ID: <214a79fc.2442c52b@aol.com> Sir/Madam, I'm fascinated with computer programing, but I have nothing for it to do with it right now! Any ideas/suggestions on what to write while learning? I'm using Win 98 (control that grimace, now...it's alright, I know CPR!), and, as stated before, have nothing to write! Any suggestions would be nice, and remember that I'm a novice! Thanx! Emerson B. Lancaster From M.Faassen@vet.uu.nl Mon Apr 12 09:38:03 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 12 Apr 1999 10:38:03 +0200 Subject: [Tutor] Teaching computer programming References: <000b01be845b$df4cdf40$2a9e2299@tim> Message-ID: <3711B0EB.FAF8DE6@pop.vet.uu.nl> Tim Peters wrote: > > [Martijn Faassen] > > ... > > You only change the way they point. labels don't have a content, they > > just point. That's what is confusing about a label; in the real world, > > you label something, and you then don't pull off the sticker and put it > > on another box, generally. > > Think of people and their many names. [snip good example where people are referred to in many different ways. Especially 'next' is a good example of what you'd see in many programs] > > You also don't tend to label the same box twice. > > Martijn, Mr. Fassen, dad, son, Mrs. Fassen's husband, "hey, you!" -- we all > get lots of labels over the course of a day. I'm not a box! Also some of those labels don't apply to me (unmarried, childless) Also it's 'Faassen'. Nitpick nitpick :) > > ... > > But of course it's contrived; there must be a metaphor combining the > > advantage of labels with the advantage of people somewhere. :) > > I'm not sure people have *any* advantages , but names are to people as > references are to objects. Plus "immutable people" is familiar to anyone > with a boss . I like the way we now compare references in natural languages 'that box' 'the next guy', 'that thing over there', 'it', to reference variables. That is a much more natural fit. 'labels' can be misinterpreted as the physical thing you can stick on boxes, and people pointing places is just plain confusing. I'd been pondering synonyms/homonyms as a way to try to explain things, but concluded this was too confusing. Regards, Martijn From M.Faassen@vet.uu.nl Mon Apr 12 17:27:37 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 12 Apr 1999 18:27:37 +0200 Subject: [Tutor] New to this idea (!) References: <214a79fc.2442c52b@aol.com> Message-ID: <37121EF9.75F3CB2C@pop.vet.uu.nl> Good2not@aol.com wrote: > > Sir/Madam, > I'm fascinated with computer programing, but I have nothing for it to > do with it right now! Any ideas/suggestions on what to write while learning? > I'm using Win 98 (control that grimace, now...it's alright, I know CPR!), > and, as stated before, have nothing to write! Any suggestions would be nice, > and remember that I'm a novice! Thanx! > Hm, first, try a program that does something extremely simple, like add up the numbers 1 to 10. (and possibly, 753 to 1049 and such too). Print the result on the screen. This isn't useful or anything, except that it'll set you a goal, and in trying to reach that goal you'll learn more about programming and Python. If that goal is too far away right now, then your goal could be simply a program that prints "Hello world!" to the screen. This is very easy, but it'll help you get familiar with an editor (where you type in your program (.py); for programs you don't generally use the python command line), and the way to get python to run your program. Regards, and good luck! Martijn From abruner@psci.net Tue Apr 13 12:17:30 1999 From: abruner@psci.net (abruner) Date: Tue, 13 Apr 1999 07:17:30 -0400 Subject: [Tutor] Hello, couple of questions Message-ID: <000d01be859f$38d91e40$9dffa0ce@default> This is a multi-part message in MIME format. ------=_NextPart_000_000A_01BE857D.B131F500 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hello, I am considering on starting to write programs and I was looking = around at different languages. Well, I was watching a ZDTV program and = the host said how Python was one of the easiest languages to learn like = VB. I know its not like VB. To tell you the truth, I have never = programmed. I know nothing about scripts or whatever. So could you = please give me some insight on what to do. Thanks Brad Bruner ------=_NextPart_000_000A_01BE857D.B131F500 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
Hello,
   I am considering on starting to write = programs=20 and I was looking around at different languages.  Well, I was = watching a=20 ZDTV program and the host said how Python was one of the easiest = languages to=20 learn like VB.  I know its not like VB.  To tell you the = truth, I have=20 never programmed.  I know nothing about scripts or whatever.  = So=20 could you please give me some insight on what to do.
 
Thanks
 
Brad Bruner
------=_NextPart_000_000A_01BE857D.B131F500-- From kdart@cisco.com Tue Apr 13 01:41:53 1999 From: kdart@cisco.com (Keith Dart) Date: Mon, 12 Apr 1999 17:41:53 -0700 (PDT) Subject: [Tutor] Hello, couple of questions In-Reply-To: <000d01be859f$38d91e40$9dffa0ce@default> Message-ID: On Tue, 13 Apr 1999, abruner wrote: > Hello, > I am considering on starting to write programs and I was looking > around at different languages. Well, I was watching a ZDTV program > and the host said how Python was one of the easiest languages to learn > like VB. I know its not like VB. To tell you the truth, I have never > programmed. I know nothing about scripts or whatever. So could you > please give me some insight on what to do. Go to the bookstore and pick up Robert Sedgwick's book entitled "Algorithms in Python"... No, wait! That book doesn't exist yet. ;-) Ok, how about waiting for the soon to be released "Learning Python", from O'Rielly? That should get you started. Note that I can't give any recommendations, or not, regarding this book as I've never seen it. But it's probably pretty good. ;-) -- -------------------------------------------------------------------------- Keith Dart, Devtest Engineer, Linux Bigot Cisco Systems phone: +1.408.527.1391 Network to User Business Unit pager: +1.800.365.4578 internal web page: external web page: ============================================================================= From deirdre@deirdre.net Tue Apr 13 01:45:43 1999 From: deirdre@deirdre.net (Deirdre Saoirse) Date: Mon, 12 Apr 1999 17:45:43 -0700 (PDT) Subject: [Tutor] Hello, couple of questions In-Reply-To: Message-ID: On Mon, 12 Apr 1999, Keith Dart wrote: > Go to the bookstore and pick up Robert Sedgwick's book entitled > "Algorithms in Python"... > > No, wait! That book doesn't exist yet. ;-) Actually, it wouldn't be a bad idea for someone to write this. Hrm. :) > Ok, how about waiting for the soon to be released "Learning Python", from > O'Rielly? That should get you started. Note that I can't give any > recommendations, or not, regarding this book as I've never seen it. But > it's probably pretty good. ;-) Imho, the author's other book sucked. No, not the little one. :) _Deirdre * http://www.linuxcabal.org * http://www.deirdre.net "At a risk of being called sexist, ageist and French, if you put multimedia, a leather skirt and lipstick on a grandmother and take her to a night club, she's still not going to get lucky." -- Jean Louis Gassee (of Be) on Windows 2000 being "multimedia." From a.mueller@icrf.icnet.uk Tue Apr 13 16:24:35 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Tue, 13 Apr 1999 16:24:35 +0100 Subject: [Tutor] stderr Message-ID: <371361B3.20EFF96C@icrf.icnet.uk> Hi All, is there an easy way like in C or perl to use 'print' to write to stderr instead stdout? python> print sys.stderr 'error' that doesn't work :-( assigning sys.stdout to sys.stderr is not a good solution. I dont want to reassign stderr/stdout everytime I switch between error messages and data output. python> sys.stdout = sys.stderr python> print 'error' ... work but is not usefull thanks, Arne From cwebster@math.tamu.edu Tue Apr 13 16:26:31 1999 From: cwebster@math.tamu.edu (Corran Webster) Date: Tue, 13 Apr 1999 10:26:31 -0500 (CDT) Subject: [Tutor] stderr In-Reply-To: <371361B3.20EFF96C@icrf.icnet.uk> Message-ID: <199904131526.KAA18572@radon.math.tamu.edu> On 13 Apr, Arne Mueller wrote: > Hi All, > > is there an easy way like in C or perl to use 'print' to write to stderr > instead stdout? > > python> print sys.stderr 'error' > > that doesn't work :-( > > assigning sys.stdout to sys.stderr is not a good solution. I dont want > to reassign stderr/stdout everytime I switch between error messages and > data output. > > python> sys.stdout = sys.stderr > python> print 'error' > > ... work but is not usefull sys.stderr is a file object, so sys.stderr.write("Oops!\n") is equivalent to printing "Oops" to stderr after switching. If you need to vary the contents of the message, you'll probably find the % string formatting commands useful: sys.stderr.write("Oops! Error: %d, %s\n" % (errnum, message)) Regards, Corran From joe@strout.net Tue Apr 13 16:32:21 1999 From: joe@strout.net (Joseph J. Strout) Date: Tue, 13 Apr 1999 08:32:21 -0700 Subject: [Tutor] stderr In-Reply-To: <371361B3.20EFF96C@icrf.icnet.uk> Message-ID: At 8:24 AM -0700 04/13/99, Arne Mueller wrote: >is there an easy way like in C or perl to use 'print' to write to stderr >instead stdout? =) C doesn't have anything as simple as "print". (Don't know perl.) >assigning sys.stdout to sys.stderr is not a good solution. I dont want >to reassign stderr/stdout everytime I switch between error messages and >data output. You can use sys.stdout.write("%s\n" % errmsg), or you can make a function which does basically the same thing. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From a.mueller@icrf.icnet.uk Tue Apr 13 17:19:11 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Tue, 13 Apr 1999 17:19:11 +0100 Subject: [Tutor] [LONG] help on self Message-ID: <37136E7F.5404CBB9@icrf.icnet.uk> Hi Again, one of my biggest problems in object oriented python is 'self' ... As far as I know it's a referecne to the calling object. Here's a program I'm writing. I cannot provide the complete example, because the datafile which is necessaty to run the program is rather VERY big :-( #!/eureka/bmm/mueller/bin/python from re import * import sys ### ### Class definitions ### ############################################################################### ### token or 'keyword' I'm looking for in text files ### a token is associated with it's match object and ### a function that can be executed if a match has ### been detected class Token: def __init__(self, token, action): self.token = compile(token) self.action = action # reference to a function self.m = None # regex match object self.string = None # the string where 'token' matches def match(self, string): self.string = string self.m = self.token.search(string) if self.m: return self else: return None ############################################################################### ### sort of pseudo parser that's used to look for keywords in ### text files class Parser: def __init__(self, f): self.f = f self.cont = compile('\S+') def parserError(self, token=None): if token: sys.stderr.write('Parser Error at: %s', token.pattern) else: sys.stderr.write('unknown parser Error!') sys.exit(1) ### retrun next non empty line def nextContensLine(self): while( 1 ): l = self.f.getLine() if not l or self.cont.search(l): return l ### looking for the current token - note, 'tokens' ### has to be defined in a subclass! def searchToken(self): l = self.nextContensLine() while( l ): for i in self.tokens: if i.match(l): return i l = self.nextContensLine() self.parserrError() ############################################################################### ### parsing an 'Iteration' (an iteration is a text block) ### datastructure that saves results is not implemented yet class Iteration(Parser): def __init__(self, f): self.f = f self.tokens = [] Parser.__init__(self, f) def parseIteration(self): print 'parsing iterations ...' self.tokens = [ Token('^Searching\.*done$', self.parseHeader) ] t = self.searchToken() # here's a problem: # 't' is a 'Token' object so I assume 't' # provides everything of the 'Token' class t.action() def parseHeader(self): print 'parsing header ...' # now we'll get an error, because self doesn't know anything # about the attribute 'string' - but why? This function was called # by an 'Token' object/instance! print self.string self.tokens = [ Token('^Results from round (\d+)$', self.parseOld), Token('^Sequences producing', self.parseOld) ] def parseOld(self): print 'parsing old hits ...' def parseNew(self): print 'parsing new hits ...' ### ### Testing ... ### f = IO('/v8/tmp/MG001.blast') i = Iteration(f) i.parseIteration() ------- running the above programm results in parsing iterations ... parsing header ... Traceback (innermost last): File "./Blast.py", line 130, in ? i.parseIteration() File "./Blast.py", line 109, in parseIteration t.action() File "./Blast.py", line 113, in parseHeader print self.string AttributeError: string Can anybody help with that strange behaviour? I think it's a 'self' problem, so maybe you can teach me how to understand (my)'self'? Thanks very much, Arne ps: if the above code is too confusing I may be able to generate a more simple example that demonstrate the 'self' problem ... From joe@strout.net Tue Apr 13 17:37:06 1999 From: joe@strout.net (Joseph J. Strout) Date: Tue, 13 Apr 1999 09:37:06 -0700 Subject: [Tutor] Know Thy Self In-Reply-To: <37136E7F.5404CBB9@icrf.icnet.uk> Message-ID: At 9:19 AM -0700 04/13/99, Arne Mueller wrote: >As far as I know it's a referecne to the calling object. No, it's a reference to the object by which a method was invoked. Let's make a simpler example: class Spammer: def __init__(self): self.str = "spam " # note: don't use 'string' for a variable; it's a module! def spam(self,n): print self.str * n foo = Spammer() # create a Spammer object foo.spam(5) # tell it to spam You see, when you say "foo.spam(5)", this is implicitly converted to: Spammer.spam(foo,5) And so within that method, 'self' refers to 'foo'. That's it. That's all that's going on. Note that it does *not* refer to the calling object... in the example above, there is NO calling object it might refer to! If you want to pass a reference to the calling object to another object's method, you'll have to pass it in explicitly like any other parameter. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From TomJenkins@zentuit.com Tue Apr 13 17:40:02 1999 From: TomJenkins@zentuit.com (Tom Jenkins) Date: Tue, 13 Apr 1999 12:40:02 -0400 Subject: [Tutor] [LONG] help on self In-Reply-To: <37136E7F.5404CBB9@icrf.icnet.uk> Message-ID: <199904131643.MAA09454@mail.digiweb.com> Hello Arne, I've snipped your message down to what I consider the essentials... > As far as I know it's a referecne to the calling object. Yes, it is a reference to the calling object. But Self has to be an instance of the class. Looking at your code I see that in the Token class, the 'action' parameter references a function. Further down in the code, where the Token instance is created, an Iteration instance's parseHeader method (or function) is passed to the Token constructor. What this means is that the Token instance (t) has a method (or function) called Action that points to a specific Iteration instance's (i) parseHeader method. So in your call to t.action gets sent to i.parseHeader. But the Iteration instance (i) doesn't have a string attribute... t does. I don't feel I have a grasp of your problem domain to offer help in how to restructure. I just hope that the above makes sense. If it doesn't, yell and I'll give it another try. > > class Token: > > def __init__(self, token, action): > self.token = compile(token) > self.action = action # reference to a function > self.m = None # regex match object > self.string = None # the string where 'token' matches > > class Parser: > > def __init__(self, f): > self.f = f > self.cont = compile('\S+') > class Iteration(Parser): > > def parseIteration(self): > print 'parsing iterations ...' > self.tokens = [ Token('^Searching\.*done$', self.parseHeader) ] > t = self.searchToken() > # here's a problem: > # 't' is a 'Token' object so I assume 't' > # provides everything of the 'Token' class > t.action() > > def parseHeader(self): > print 'parsing header ...' > # now we'll get an error, because self doesn't know anything > # about the attribute 'string' - but why? This function was called > # by an 'Token' object/instance! > print self.string > ### Testing ... > ### > > f = IO('/v8/tmp/MG001.blast') > i = Iteration(f) > i.parseIteration() > > ------- > running the above programm results in > > parsing iterations ... > parsing header ... > Traceback (innermost last): > File "./Blast.py", line 130, in ? > i.parseIteration() > File "./Blast.py", line 109, in parseIteration > t.action() > File "./Blast.py", line 113, in parseHeader > print self.string > AttributeError: string > > > Can anybody help with that strange behaviour? I think it's a 'self' > problem, so maybe you can teach me how to understand (my)'self'? > > Thanks very much, > > Arne > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Tom Jenkins DevIS (http://www.devis.com) "In a world without fences, who needs Gates?" From TomJenkins@zentuit.com Tue Apr 13 17:52:53 1999 From: TomJenkins@zentuit.com (Tom Jenkins) Date: Tue, 13 Apr 1999 12:52:53 -0400 Subject: [Tutor] Know Thy Self In-Reply-To: References: <37136E7F.5404CBB9@icrf.icnet.uk> Message-ID: <199904131655.MAA28116@mail.digiweb.com> Arne, Joe is more technically correct since you could say Spammer.spam(foo, 5) as he points out. I just never think about it like that. > > >As far as I know it's a referecne to the calling object. > > No, it's a reference to the object by which a method was invoked. Let's > make a simpler example: > > class Spammer: > > def __init__(self): > self.str = "spam " > # note: don't use 'string' for a variable; it's a module! > > def spam(self,n): > print self.str * n > > foo = Spammer() # create a Spammer object > foo.spam(5) # tell it to spam > > > You see, when you say "foo.spam(5)", this is implicitly converted to: > Spammer.spam(foo,5) > > And so within that method, 'self' refers to 'foo'. That's it. That's all > that's going on. Note that it does *not* refer to the calling object... in > the example above, there is NO calling object it might refer to! If you > want to pass a reference to the calling object to another object's method, > you'll have to pass it in explicitly like any other parameter. > > Cheers, > -- Joe > ,------------------------------------------------------------------. > | Joseph J. Strout Biocomputing -- The Salk Institute | > | joe@strout.net http://www.strout.net | > `------------------------------------------------------------------' > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://www.python.org/mailman/listinfo/tutor > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Tom Jenkins DevIS (http://www.devis.com) "In a world without fences, who needs Gates?" From alan.gauld@bt.com Wed Apr 14 09:53:36 1999 From: alan.gauld@bt.com (alan.gauld@bt.com) Date: Wed, 14 Apr 1999 09:53:36 +0100 Subject: [Tutor] [LONG] help on self Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB24E090E@mbtlipnt02.btlabs.bt.co.uk> > one of my biggest problems in object oriented python is 'self' ... > > As far as I know it's a referecne to the calling object. No, it refers to the *called* object. Thus in your case there is no self.string attribute in either parser nor iteration classes. You actually want to somehow get the token to print its string prior to calling parseHeader. The whole point of OOP is that objects know nothing about who is calling them. Thats what gives the independance that allows objects to be reused in ither applications. You can of course explicitly pass the token in as an object this parseHeader starts like: def parseHeader(self, # the parser tok) # the token calling the parser print tok.string # better if token had a print method tho'... .... Does that help? Alan G. From a.mueller@icrf.icnet.uk Fri Apr 16 13:56:21 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Fri, 16 Apr 1999 13:56:21 +0100 Subject: [Tutor] long lines in print Message-ID: <37173375.387284C8@icrf.icnet.uk> Hi All, is there a chance to split a long python 'statements' line into several lines? The following statement is far too long for one emacs line and I'd line to split it up so that the statement becomes more readable. Is there a way to put the list of values (hsp.score, hsp.e, hsp.identity) in the next line? I mean, that'd collide with python indentation, wouldn't it? print 'HSP: score = %f, e = %f, identity = %d\%' % (hsp.score, hsp.e, hsp.identity) thanks for help, Arne From geek+@cmu.edu Fri Apr 16 14:22:23 1999 From: geek+@cmu.edu (geek+@cmu.edu) Date: 16 Apr 1999 09:22:23 -0400 Subject: [Tutor] long lines in print In-Reply-To: <37173375.387284C8@icrf.icnet.uk> Message-ID: --pgp-sign-Multipart_Fri_Apr_16_09:22:22_1999-1 Content-Type: text/plain; charset=US-ASCII Then spoke up and said: > is there a chance to split a long python 'statements' > line into several lines? Sure: print " here is a part and %s" \ % ('here is another part') Note, that the \ is IMMEDIATELY followed by a newline. If you put a space after it, it doesn't do what you want. -- ===================================================================== | JAVA must have been developed in the wilds of West Virginia. | | After all, why else would it support only single inheritance?? | ===================================================================== | Finger geek@cmu.edu for my public key. | ===================================================================== --pgp-sign-Multipart_Fri_Apr_16_09:22:22_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 iQBVAwUBNxc5j4dzVnzma+gdAQGI1gIAiyp1sj7Y/rS6fDnNpTMxAOMG8cOoFtwN z6IvPb6jrBAkMU13oQUQ36xHv4PhP/kF7Oyj+ZLcCcdFE0bNbR6nwA== =BDtu -----END PGP MESSAGE----- --pgp-sign-Multipart_Fri_Apr_16_09:22:22_1999-1-- From tismer@appliedbiometrics.com Fri Apr 16 14:28:41 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Fri, 16 Apr 1999 15:28:41 +0200 Subject: [Tutor] long lines in print References: <37173375.387284C8@icrf.icnet.uk> Message-ID: <37173B09.7521F0D9@appliedbiometrics.com> Arne Mueller wrote: > > Hi All, > > is there a chance to split a long python 'statements' > line into several lines? > > The following statement is far too long for one emacs > line and I'd line to split it up so that the statement > becomes more readable. Is there a way to put the list > of values (hsp.score, hsp.e, hsp.identity) in the next > line? I mean, that'd collide with python indentation, > wouldn't it? The Python indentation rules do only apply for a new statement line. If you can manage to continue your statement, indentation is no problem. Continuation is done by ending a line with a backslash. > print 'HSP: score = %f, e = %f, identity = %d\%' % (hsp.score, hsp.e, > hsp.identity) print 'HSP: score = %f, e = %f, identity = %d\%' % \ (hsp.score, hsp.e, hsp.identity) will do it. Another way is to build your format string dynamically, like my_fmt = 'HSP: score = %f, e = %f, identity = %d\%' print my_fmt % (hsp.score, hsp.e, hsp.identity) This can sometimes make it easier to change the formatting of output, especially if you need the same formats in different lines, maybe with slight modifications. 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 Fri Apr 16 14:31:41 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Fri, 16 Apr 1999 15:31:41 +0200 Subject: [Tutor] long lines in print References: <37173375.387284C8@icrf.icnet.uk> Message-ID: <37173BBD.2BF9211E@appliedbiometrics.com> - please drop the former post, I found another mistake here - Arne Mueller wrote: > > Hi All, > > is there a chance to split a long python 'statements' > line into several lines? > > The following statement is far too long for one emacs > line and I'd line to split it up so that the statement > becomes more readable. Is there a way to put the list > of values (hsp.score, hsp.e, hsp.identity) in the next > line? I mean, that'd collide with python indentation, > wouldn't it? The Python indentation rules do only apply for a new statement line. If you can manage to continue your statement, indentation is no problem. Continuation is done by ending a line with a backslash. > print 'HSP: score = %f, e = %f, identity = %d\%' % (hsp.score, hsp.e, > hsp.identity) print 'HSP: score = %f, e = %f, identity = %d%%' % \ (hsp.score, hsp.e, hsp.identity) will do it. Please note that you cannot escape your trailing "%" by backslash. It has to be doubled instead. Another way is to build your format string dynamically, like my_fmt = 'HSP: score = %f, e = %f, identity = %d%%' print my_fmt % (hsp.score, hsp.e, hsp.identity) This can sometimes make it easier to change the formatting of output, especially if you need the same formats in different lines, maybe with slight modifications. 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 a.mueller@icrf.icnet.uk Fri Apr 16 16:08:02 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Fri, 16 Apr 1999 16:08:02 +0100 Subject: [Tutor] Classes + inheritance Message-ID: <37175252.4E07ED98@icrf.icnet.uk> Hi All (again ...), first of all: thanks very much with help on 'long statements' and now to something completely different ...: I've written a modul 'blast.py' which defines some classes (e.g. Blast, Iteration). A program test.py uses this modul import sys from blast import * and defines it's own version of class 'iteration' (in file test.py) class Iteration(Iteration): def __init__(self, f): sys.stderr.write('My redefined class Iteration ...') Iteration.__init__(self, f) def parseBlock(self, token): sys.stderr.write('My redefined parseBlock ...') return I create an obejct of class Blast f = IO('myfile', 'r', 100) # create an io object b = Blast(f) # create an empty blast object b.createBlastTree() # do something on it ... and call a method of that object (createBlastTree). This method (internally) creates several objects of class 'Iteration' (but class Blast does NOT inherit from class Iteration). I want to change the behaviour of several functions of the 'Iteration' class, so in my program I define a new version of class Iteration (see above) - but it turned out that b.createBlastTree() still creates objects of the old Iteration class! Confusing ??? Hm, I'm confused. How can I make b.createBlastTree() using the redefined/extended version of 'Iteration' without modifying the source in modul 'blast.py'. THese extension are program specific, and I intended to use inheritance to cope with the problem - alas, it doesn't seem to work :-( . So, now tell me that I'm completely wrong, and that all my work of the last 3 days cannot work because I misunderstood python's object orientation :-((((( sorry for frequently asking question ;-), Arne From geek+@cmu.edu Fri Apr 16 16:16:55 1999 From: geek+@cmu.edu (geek+@cmu.edu) Date: 16 Apr 1999 11:16:55 -0400 Subject: [Tutor] Classes + inheritance In-Reply-To: <37175252.4E07ED98@icrf.icnet.uk> Message-ID: --pgp-sign-Multipart_Fri_Apr_16_11:16:54_1999-1 Content-Type: text/plain; charset=US-ASCII Then spoke up and said: > from blast import * [snip] > class Iteration(Iteration): This is really the source of your problems. This Iteration overwrites the one imported from blast. Why don't you try doing something like: import blast class Iteration(blast.Iteration): sys.stderr.write('My redefined class Iteration ...') blast.Iteration.__init__(self, f) -- ===================================================================== | JAVA must have been developed in the wilds of West Virginia. | | After all, why else would it support only single inheritance?? | ===================================================================== | Finger geek@cmu.edu for my public key. | ===================================================================== --pgp-sign-Multipart_Fri_Apr_16_11:16:54_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 iQBVAwUBNxdUZ4dzVnzma+gdAQE4DQIAxoHUmV4P6ifG5igD+0wyR/TJey6YKJXP uR/2AnKpTzRnGNQRpwms5H2FUOknFJ/gRidhNlChupNVPInnSWIkCA== =PTCe -----END PGP MESSAGE----- --pgp-sign-Multipart_Fri_Apr_16_11:16:54_1999-1-- From a.mueller@icrf.icnet.uk Fri Apr 16 16:41:08 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Fri, 16 Apr 1999 16:41:08 +0100 Subject: [Tutor] Classes + inheritance References: Message-ID: <37175A14.2E50A811@icrf.icnet.uk> geek+@cmu.edu wrote: > > Then spoke up and said: > > from blast import * > [snip] > > class Iteration(Iteration): > > This is really the source of your problems. This Iteration overwrites > the one imported from blast. Why don't you try doing something like: > > import blast > class Iteration(blast.Iteration): def __init__(self, f): > sys.stderr.write('My redefined class Iteration ...') > blast.Iteration.__init__(self, f) that doen't work, either. The class Iteration is not used by the class (Blast) which is defined in another module. Does a class always look for another class it uses in the module where it's defined? That might be my problem - I thought it looks for the class definition in the module/file that on top of the 'execution' stack. I've to think about a new idea how to solve my problem. I do have to provide the opportunity to extend/redefine classes or at least class methods in module 'a' which are originally defined in module 'b' - classes in module 'b' then use the redefined methods of module 'a' and ignore the original definitoon in their own module. ??? ok, I'll think about a simple solution, maybe it's the wrong point to start with object orientation ... From a.mueller@icrf.icnet.uk Fri Apr 16 17:32:01 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Fri, 16 Apr 1999 17:32:01 +0100 Subject: [Tutor] Classes + inheritance References: <37175252.4E07ED98@icrf.icnet.uk> Message-ID: <37176601.58E8FF8@icrf.icnet.uk> Arne Mueller wrote: > > Hi All (again ...), > > first of all: thanks very much with help on 'long statements' > > and now to something completely different ...: > I've written a modul 'blast.py' which defines some classes (e.g. Blast, > Iteration). > > A program test.py uses this modul > > import sys > from blast import * > > and defines it's own version of class 'iteration' (in file test.py) > > class Iteration(Iteration): > > def __init__(self, f): > sys.stderr.write('My redefined class Iteration ...') > Iteration.__init__(self, f) > > def parseBlock(self, token): > sys.stderr.write('My redefined parseBlock ...') > return > > I create an obejct of class Blast > > f = IO('myfile', 'r', 100) # create an io object > b = Blast(f) # create an empty blast object > b.createBlastTree() # do something on it ... > > and call a method of that object (createBlastTree). This method > (internally) creates several objects of class 'Iteration' (but class > Blast does NOT inherit from class Iteration). I want to change the > behaviour of several functions of the 'Iteration' class, so in my > program I define a new version of class Iteration (see above) - but it > turned out that b.createBlastTree() still creates objects of the old > Iteration class! > > Confusing ??? Hm, I'm confused. How can I make b.createBlastTree() using > the redefined/extended version of 'Iteration' without modifying the > source in modul 'blast.py'. THese extension are program specific, and I > intended to use inheritance to cope with the problem - alas, it doesn't > seem to work :-( . > > So, now tell me that I'm completely wrong, and that all my work of the > last 3 days cannot work because I misunderstood python's object > orientation :-((((( > > sorry for frequently asking question ;-), > > Arne > I've found a solution for my problem: The facts are: 1. in module m1 class a creates object of class b (also defined in module m1) 2. in module m2 I'd like to extend/redefine class b, so that class a in module m1 uses the redefined version (of module m2). ----------------------------------- in file m1.py: class b: def do_something(self): print 'doing class b in module m1' class a: def __init__(self, cref): self.cref = cref def create(self): x = self.cref() x.do_something() ----------------------------------- in file m2.py: from m1 import * class my_b(b): def do_something(self): print 'doing class b in module m2' b.do_something(self) ------------------------------------- Python 1.5.2b2 (#5, Mar 2 1999, 14:24:17) [C] on irix646 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam python> from m1 import * python> bla = a(b) python> bla.create() doing class b in module m1 python> python> from m2 import * python> bla = a(my_b) python> bla.create() doing class b in module m2 doing class b in module m1 The problem is solved by passing a reference of a class to a class that will create instances of the passed class ... ;-) It works but I think it's bad style and has nothing to do with object orientaion :-( . Any suggestions for a more elegant solution ? thanks, Arne From deirdre@deirdre.net Fri Apr 16 17:38:44 1999 From: deirdre@deirdre.net (Deirdre Saoirse) Date: Fri, 16 Apr 1999 09:38:44 -0700 (PDT) Subject: [Tutor] long lines in print In-Reply-To: <37173375.387284C8@icrf.icnet.uk> Message-ID: On Fri, 16 Apr 1999, Arne Mueller wrote: > The following statement is far too long for one emacs > line and I'd line to split it up so that the statement > becomes more readable. Is there a way to put the list > of values (hsp.score, hsp.e, hsp.identity) in the next > line? I mean, that'd collide with python indentation, > wouldn't it? End the line with a \ and continue on the next line. (Just like in C). Indentation on the subsequent line(s) is usually greater but I'm not sure that's required. _Deirdre * http://www.linuxcabal.org * http://www.deirdre.net "At a risk of being called sexist, ageist and French, if you put multimedia, a leather skirt and lipstick on a grandmother and take her to a night club, she's still not going to get lucky." -- Jean Louis Gassee (of Be) on Windows 2000 being "multimedia." From joe@strout.net Fri Apr 16 17:53:29 1999 From: joe@strout.net (Joseph J. Strout) Date: Fri, 16 Apr 1999 09:53:29 -0700 Subject: [Tutor] Classes + inheritance In-Reply-To: <37176601.58E8FF8@icrf.icnet.uk> References: <37175252.4E07ED98@icrf.icnet.uk> Message-ID: At 9:32 AM -0700 04/16/99, Arne Mueller wrote: >1. in module m1 class a creates object of class b (also defined in >module m1) >2. in module m2 I'd like to extend/redefine class b, so that class a in >module m1 > uses the redefined version (of module m2). If you want class a to do something different, you must either (extend/redefine (i.e. subclass) class a, or you must pass it some information that tells it to do something different. Your solution does the latter, and it's a perfectly reasonable solution. Other solutions (drawing from Design Patterns): 1. Factory Method: give m1.a a create() method that creates an m1.b object. But if you decide to change this behavior from m2, then do it by instantiating not an m1.a object, but an m2.a object. Class m2.a differs from m1.a in only one way: its create() method creates objects of class m2.b rather than m1.b. ...or... 2. Prototype: have your a.create() method take a prototype of the object to create, and do its work by cloning that object. Then you can have it create anything by passing in an example. This is very similar to your solution (and certainly no better in this case). Or, there may be a way to restructure your program altogether so that a does not have to create any b's. Without knowing more about your application, it's hard to say. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From a.mueller@icrf.icnet.uk Fri Apr 16 22:47:51 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Fri, 16 Apr 1999 22:47:51 +0100 Subject: [Tutor] memory management Message-ID: <3717B007.76D56181@icrf.icnet.uk> Hi All, I've a very large data structure in memory (100 MB) which I've to delete sequential. THe structure is a tree. it looks like this: (root(list1(dictionary(list2)))) I can traverse the tree using the following loops for i in root.list1: for k in keys(): for l in i.hits[l].list2: action(l) l.remove del i.dictionary.[k] i.remove After action(l) is executed l can be deleted, after all keys in i.dictionary are processed the dictionary can be deleted ... . It's important to delete the structure level by level because 'action' creates another very big structure, so building the new one and deleting 'root' at one is not a good idea. I've monitore memory usage on my computer and after executing the three above loops the memory usage should go down - but it doesn't! Whats' up? Is the memory collected for internal usage by python, would it be reused when creating new objects, or is the above way to free lists and dictionaries of objects wrong? good old malloc -> free thanks very much, Arne From tismer@appliedbiometrics.com Fri Apr 16 23:07:13 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sat, 17 Apr 1999 00:07:13 +0200 Subject: [Tutor] memory management References: <3717B007.76D56181@icrf.icnet.uk> Message-ID: <3717B491.37BF6F96@appliedbiometrics.com> Arne Mueller wrote: > I've monitore memory usage on my computer and after executing the three > above loops the memory usage should go down - but it doesn't! Whats' up? > Is the memory collected for internal usage by python, would it be reused > when creating new objects, or is the above way to free lists and > dictionaries of objects wrong? No, AFAIK Python does never free memory which it had acquired before, but it will reuse it. It is better to avoid such tremendous memory usage, maybe you should write your results out to a marshal file and spawn a new process, or try to change your algorithm to be less greedy :-) 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 psychic777@bigfoot.com Sat Apr 17 01:32:54 1999 From: psychic777@bigfoot.com (psychic777@bigfoot.com) Date: Fri, 16 Apr 1999 19:32:54 -0500 Subject: [Tutor] A special message for tutor Message-ID: Home Page

 

Tired of calling those 900 numbers and paying $3.99 - $4.99 per minute
only to find your didn't get the answers you sought?
Tired of hunting for a clairvoyant or psychic that can and will connect with you and your needs?
...STOP PLEASE DON'T DELETE US!
We are a personalized group of Live Clairvoyants on call.  You only pay for the minutes you spend with one of our advisors, not the time spent deciding on which advisor to use or speaking with one of our pleasant connecting operators.
...WAIT!
We only charge Only $1.99 per minute.
Visa, Master Card, American Express excepted.
...CALL TOLL FREE
Call 1 (800) 821-6601 Ext. 3963 Today! toll-free for US calls only. CALL NOW 1 (800) 821-6601
You Must be 18+
You can purchase a 15, 30 or 60 minute reading. It's your choice!
International Callers, please dial 011 + 1 + (406)777-0859 or check with your local
operator.
Plus if you call NOW and give us this special number #3963, we will give You FREE THREE MINUTES !!!
*** BONUS *** To say thanks for allowing us the opportunity to serve you, we will send you a FREE
              Love, Prosperity or Calming/Healing Power Prayer Card with a Special Herbal Pouch !
              These Powerful Special Herb Bags & Prayers can Help YOU...
...STILL NOT INTERESTED?
Don't just delete this email.  We have attached our business card for your convenience so that you may save our information in your address book just incase you require the expertise of our services in the future.  We may not send this email to you again for a long time if ever because we do not wish to offend anyone.
PLEASE SAVE OUR BUSINESS CARD INFO.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DANCING SPIRITS ®
24 HOUR Consulting & Counseling Services
We are a Credit Card Merchant & ACH Check Processor
"Solutions tailored for guaranteed answers"
1 (800) 821-6601 Ext. 3963
1 (406) 777-0859
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you DON'T HAVE A CREDIT CARD - THAT'S OK! JUST CALL 900-288-7474 $3.99 a minute, adult and entertainment only, sponsored by Dancing Spirits.

We are here for you when ever you need us and it is easy to always get the same advisor time after time either by first come first serve or appointment.  We look forward to speaking with you. You Must be 18+
----------------------------------------------------------------
This message is sent in compliance of the new e-mail bill: SECTION 301.Sender: Mike Goldstein, p.o.box 17, seleron, NY 14720, goldstein_mike_@HOTMAIL.COM
Per Section 301, Paragraph (a)(2)(C) of S.1618, further transmissions to you by the sender of this email may be stopped at no cost to you by using the Remove Address below. If you have received this message in error, please accept our apologies, and use the following remove e-mail address: psychic777@bigfoot.com
From da@ski.org Sat Apr 17 04:32:56 1999 From: da@ski.org (David Ascher) Date: Fri, 16 Apr 1999 20:32:56 -0700 (Pacific Daylight Time) Subject: [Tutor] memory management In-Reply-To: <3717B491.37BF6F96@appliedbiometrics.com> Message-ID: On Sat, 17 Apr 1999, Christian Tismer wrote: > > No, AFAIK Python does never free memory which it had > acquired before, but it will reuse it. Uh? Sorry, Christian, that's false. Python frees the memory just fine when no references are held (for those who care, The *operating system* may not show it as freed -- that's what Linux does, for example. Windows NT, on the other hand, shows the memory as freed. I have a specific answer to the original post coming up. --david From da@ski.org Sat Apr 17 04:48:11 1999 From: da@ski.org (David Ascher) Date: Fri, 16 Apr 1999 20:48:11 -0700 (Pacific Daylight Time) Subject: [Tutor] memory management In-Reply-To: <3717B007.76D56181@icrf.icnet.uk> Message-ID: On Fri, 16 Apr 1999, Arne Mueller wrote: > I can traverse the tree using the following loops > > for i in root.list1: > for k in keys(): > for l in i.hits[l].list2: > action(l) > l.remove > del i.dictionary.[k] > i.remove Several comments: 1) Taking the code above at face value, you're forgetting to call the remove method as your code doesn't have the required ()'s -- it should read l.remove() # note the ()! and i.remove() # same here. That wouldn't help, though, since remove is a method of lists which takes an element as argument. 2) You have a line which reads: for l in i.hits[l].list2: but l isn't defined the first time around, at least not in the snippet you gave. 3) Similarly, you call the "keys()" function which isn't defined. 4) Similarly, the line: del i.dictionary.[k] is not syntactically valid Python. When posting code, please post working code, not pseudocode -- Python is so simple and clear, there's no need to make up a new syntax. With a lot of guess work, I'd say that you need something like: for outer_index in range(len(outer_list)): outer_element = outer_list[outer_index] for key in outer_element.keys(): for inner_index in range(len(outer_element[key])): action(outer_element[key][inner_index]) del outer_element[key][inner_index] # delete inner element del outer_element[key] # delete inner list del outer_element # delete dictionary del outer_list[outer_index] # delete outer element This gives you maximum control over the deletion of each reference -- it is probably overkill. Note that it does not guarantee that the memory is freed -- Python frees memory when no references to an object exist. So, if you have a memory leak, the problem is that you have some references to an object lying around somewhere -- usually in a dictionary or a list. Christian's comment about rethinking the code is a valid one -- it might save you time to think a bit about whether you really need to have all 100 Mb in memory at the same time, or whether you can pipeline the process somewhat. Without knowing more about the specifics, it's hard to know how to help. --david ascher From tim_one@email.msn.com Sat Apr 17 07:31:05 1999 From: tim_one@email.msn.com (Tim Peters) Date: Sat, 17 Apr 1999 02:31:05 -0400 Subject: [Tutor] Classes + inheritance In-Reply-To: <37175A14.2E50A811@icrf.icnet.uk> Message-ID: <000e01be889b$deb40240$ee9e2299@tim> [Arne Mueller] > ... > Does a class always look for another class it uses in the module where > it's defined? Yes or no, depending on what you mean by each of those words . The general rule has no exceptions: every name in every context is first looked up in the local scope; if not found there, then in the global scope; if not found there, in the builtin scope; and if not found there either NameError is raised. "The global scope" is usally "the module" containing the code containing the name being looked up. There is never any magical leaking of names across module boundaries; Python's "global" is much more like C's file-scope static than like C's extern. scoped-out-ly y'rs - tim From ivnowa@hvision.nl Sat Apr 17 14:39:25 1999 From: ivnowa@hvision.nl (Hans Nowak) Date: Sat, 17 Apr 1999 14:39:25 +0100 Subject: [Tutor] A special message for tutor In-Reply-To: Message-ID: <199904171237.OAA24012@axil.hvision.nl> Times New RomanOn 16 Apr 99, Ce'Nedra took her magical amulet and heard psychic777@bigfoot.com say: trebuchet ms, arial, helveticaTired of hunting for a clairvoyant or psychic that can and will connect with you and your needs? We are a personalized group of Live Clairvoyants on call. You only pay for the minutes you spend with one of our advisors, not the time spent deciding on which advisor to use or speaking with one of our pleasant connecting operators. Times New RomanStrange that a bunch of clairvoyants did not foresee that we don't like spam... + 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 Rush Limbaugh jump for your legs! From tismer@appliedbiometrics.com Sun Apr 18 16:01:52 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Sun, 18 Apr 1999 17:01:52 +0200 Subject: [Tutor] memory management References: Message-ID: <3719F3E0.663198C@appliedbiometrics.com> David Ascher wrote: > > On Sat, 17 Apr 1999, Christian Tismer wrote: > > > > No, AFAIK Python does never free memory which it had > > acquired before, but it will reuse it. > > Uh? Sorry, Christian, that's false. Python frees the memory just fine > when no references are held (for those who care, The *operating system* > may not show it as freed -- that's what Linux does, for example. Windows > NT, on the other hand, shows the memory as freed. (ick!) Is this really so? I thought I'd read this some time ago and never investigated further, since I had the experience that my WIndoze swapfile never shrunk after PythonWin had used and freed a large chunk of memory. When I shut down my session and wait a couple of seconds, I can see my swapfile shrunk again. Maybe this mislead me to make wrong assumptions. Hmm. You are absolutely sure? Can it be an effect of memory fragmentation that it doesn't get released under circumstances? I just did (using PythonWin) >>> big = range(10000000) >>> and watched my swapfile frow from small to 233 MB. Then I did a del on big. This took even more time than creating it, btw. Touching all the refcounts again seems to be quite a challenge for my harddisk. I have the strong impression that releasing objects should try to do this in reverse order. Without explicit measure, my guess is it takes 5 times as long to release this chunk. After a couple of seconds, my swapfile melted down to 192 MB. You are right. Some memory is freed. I'm just wondering about the rest? After closing my PyWin session, the swap file quickly became as small as before. Can it be that I'm about to find a memory leak? 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 a.mueller@icrf.icnet.uk Sun Apr 18 18:43:10 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Sun, 18 Apr 1999 18:43:10 +0100 Subject: [Tutor] memory management Message-ID: <371A19AE.85172503@icrf.icnet.uk> Dear All, David Ascher wrote: > > On Fri, 16 Apr 1999, Arne Mueller wrote: > > > When posting code, please post working code, not pseudocode -- Python is > so simple and clear, there's no need to make up a new syntax. Sorry for that, yes it was quick & dirty posting and it's not correct, I appoligize for that! > > Christian's comment about rethinking the code is a valid one -- it might > save you time to think a bit about whether you really need to have all 100 > Mb in memory at the same time, or whether you can pipeline the process > somewhat. Without knowing more about the specifics, it's hard to know how > to help. Hm, 100 MB memory usage is not a big problem, 200 MB is (in my case)! However, in I summary: I've to read in data. Whether a dataset is read into memory depends on what is already in the datastructure, it may replace an existing dataset or not, so I've to compare each new dataset to all existing datasets. After reading in the data, a sorting is applied to the structure, the sorted datastructure is written to a file. greetings, Arne From da@ski.org Sun Apr 18 21:34:19 1999 From: da@ski.org (David Ascher) Date: Sun, 18 Apr 1999 13:34:19 -0700 (Pacific Daylight Time) Subject: [Tutor] memory management In-Reply-To: <3719F3E0.663198C@appliedbiometrics.com> Message-ID: On Sun, 18 Apr 1999, Christian Tismer wrote: > (ick!) Is this really so? I thought I'd read this some time ago > and never investigated further, since I had the experience > that my WIndoze swapfile never shrunk after PythonWin had used > and freed a large chunk of memory. When I shut down my session > and wait a couple of seconds, I can see my swapfile shrunk again. > Maybe this mislead me to make wrong assumptions. > > Hmm. You are absolutely sure? > Can it be an effect of memory fragmentation that it doesn't > get released under circumstances? > > and watched my swapfile frow from small to 233 MB. > Then I did a del on big. This took even more time than > creating it, btw. Touching all the refcounts again seems > to be quite a challenge for my harddisk. I have the strong > impression that releasing objects should try to do this in > reverse order. Do what in reverse order? > Without explicit measure, my guess is it takes > 5 times as long to release this chunk. My guess is that you're seeing OS-specific behavior. > After a couple of seconds, my swapfile melted down to 192 MB. > You are right. Some memory is freed. I'm just wondering about > the rest? After closing my PyWin session, the swap file quickly > became as small as before. Can it be that I'm about to > find a memory leak? Maybe, but I'd be surprised. A bit more about memory management (this is not really what I had in mind for content for the tutor list, and most Python programmers should feel free to ignore all of these issues, especially at first). The general statement that Python releases memory when an object's refcount drops to 0 is mostly true. However, there are some special cases and caveats: - Python's memory management is somewhat object-type-specific -- some objects are allocated from buffers which are indeed not completely released when the objects aren't needed -- for example, frame objects (used internally) and integers are taken from preallocated buffers when possible, to speed up the common case of allocation and deallocation. You might be seeing an effect of that with your range() test. Details are in the code (see e.g. intobject.c and frameobject.c). Interning of strings is another special-case behavior which can lead to apparent memory leask which aren't real memory leaks. - The vast majority of memory leaks in Python are due to the Python programmer forgetting to delete all the references to an object. A special case of that is circular references. E.g.: x = [1,2] y = {0:x} x[0] = y Now x refers to y and y refers to x -- so even if x and y are local variables in a function (which has a consequence that the named references would be removed when the function exits), then the "circular" or "mutual" references between the two will prevent Python from releasing the memory allocated to them. To solve this, one needs to 'break' the cycle, by e.g.: x[0] = None - When Python does free() a chunk of memory, it's up to the operating system (Linux, NT, Windows95, whatever) to decide how to deal with it. Some systems really free the memory right away, while others wait. It is very hard to find out exactly how much memory is being used by a Python program without knowing quite a bit about how the underlying system manages memory. For example, I believe that Linux keeps in the "ps" table the high-watermark of the memory ever allocated by the program. So, if you have a program which occasionally uses huge amounts of memory, it will have that amount of memory apparently allocated to that program. In fact, Linux keeps track of what memory is in fact used by the program, and will allocate the freed memory to other programs as needed. Cheers, --david ascher PS: I know that Christian at least knows some of the above -- I'm writing it more for didactic reasons. From da@ski.org Sun Apr 18 21:38:24 1999 From: da@ski.org (David Ascher) Date: Sun, 18 Apr 1999 13:38:24 -0700 (Pacific Daylight Time) Subject: [Tutor] memory management In-Reply-To: <371A19AE.85172503@icrf.icnet.uk> Message-ID: On Sun, 18 Apr 1999, Arne Mueller wrote: > Hm, 100 MB memory usage is not a big problem, 200 MB is (in my case)! > However, in I summary: I've to read in data. Whether a dataset is read > into memory depends on what is already in the datastructure, it may > replace an existing dataset or not, so I've to compare each new dataset > to all existing datasets. After reading in the data, a sorting is > applied to the structure, the sorted datastructure is written to a file. Something which may help speed things up is to use a hash table -- instead of comparing each dataset to each other dataset, compare the datasets' hash values -- these will be equal if the datasets are equal -- you can use that as a fast filter, then only really loading up the datasets which have the same hash value. Clearly, the datasets need to be loaded to compute their hash values -- but that can be done sequentially (unload a dataset before you load the next), and the hash values can be stored on disk, so you only need to compute the hash value when the datasets change. Whether this is a useful trick depends on the specifics of your problem, of course. Cheers, --David Ascher From davebrener@yahoo.com Sun Apr 18 23:29:00 1999 From: davebrener@yahoo.com (Dave Brener) Date: Sun, 18 Apr 1999 15:29:00 -0700 (PDT) Subject: [Tutor] Information Message-ID: <19990418222900.7227.rocketmail@web115.yahoomail.com> I am new to the Python programming language, and have no experience in programming at all. Where should I begin? Are there any books out there to help me? Thanks, davebrener@yahoo.com _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com From deirdre@deirdre.net Sun Apr 18 23:42:58 1999 From: deirdre@deirdre.net (Deirdre Saoirse) Date: Sun, 18 Apr 1999 15:42:58 -0700 (PDT) Subject: [Tutor] Information In-Reply-To: <19990418222900.7227.rocketmail@web115.yahoomail.com> Message-ID: On Sun, 18 Apr 1999, Dave Brener wrote: > I am new to the Python programming language, and have > no experience in programming at all. Where should I > begin? Are there any books out there to help me? There are four books. One is so new I haven't seen it. There are only two I'd recommend: the Pocket Reference published by O'Reilly (for all of $6.95) and "Internet Programming with Python." _Deirdre * http://www.linuxcabal.org * http://www.deirdre.net "At a risk of being called sexist, ageist and French, if you put multimedia, a leather skirt and lipstick on a grandmother and take her to a night club, she's still not going to get lucky." -- Jean Louis Gassee (of Be) on Windows 2000 being "multimedia." From da@ski.org Mon Apr 19 06:22:13 1999 From: da@ski.org (David Ascher) Date: Sun, 18 Apr 1999 22:22:13 -0700 (Pacific Daylight Time) Subject: [Tutor] Information In-Reply-To: <19990418222900.7227.rocketmail@web115.yahoomail.com> Message-ID: On Sun, 18 Apr 1999, Dave Brener wrote: > I am new to the Python programming language, and have > no experience in programming at all. Where should I > begin? Are there any books out there to help me? Browse the web pages starting under http://www.python.org/doc/ for some pointers. I'd recommend looking especially at http://www.python.org/doc/Intros.html and some of the introductions to Python in there. The most appropriate book currently available is probably _Learning Python_, which I coauthored, but it was not designed as a textbook to teach programming, so I wouldn't be surprised if it was too hard to use as your sole reference. I would suggest browsing it in a bookstore to see if it might be helpful anyway. It is described, along with others, at: http://www.python.org/doc/Books.html Other than that, I'd suggest asking more questions here -- we'll be glad to help. --David Ascher Obvious disclaimer applies. From johnk@meta3.net Mon Apr 19 12:54:33 1999 From: johnk@meta3.net (John Kleinjans) Date: Mon, 19 Apr 1999 06:54:33 -0500 Subject: [Tutor] Teaching Objects Message-ID: <3.0.3.32.19990419065433.006b9790@mail.meta3.net> Re: teaching programming (to people who don't know programming) (at all) using Python. So let's say, just to set the scene, that someone who has *never programmed before at all* has now messed around with Python a bit in interactive mode; and then has written a couple short scripts to, maybe, solve quadratic equations or make a calculator, something like that. We told this person about variables and assignments, about sequence and branching and loops... so this person is just *beginning* to get a feeling for (I can't think of the word now... imperative? Like a language like C, or QBasic does.) programming. I'd think that what this person needs is a sequence of some `packages' that introduce a tool (command, function) with an example short, simple application program, and a couple simple projects that use that tool; then another tool, another sample program, and a few more related projects; and so on. And along the way, when appropriate, include objects in the sample code. Explain *why* to make objects and *how* to do it, too; what they are and when to use them; and begin some discussion of programming style (start good habits now). Anybody out there have some cool easy Python tricks? Anybody want to explain Who What When Where Why How of objects in Python? (This is a change: instead of asking others to to my homework for me, it ooks like I'm asking them to give me homework! What would they think in comp.lang.c?) If I remember correctly... john k From M.Faassen@vet.uu.nl Mon Apr 19 13:56:20 1999 From: M.Faassen@vet.uu.nl (Martijn Faassen) Date: Mon, 19 Apr 1999 14:56:20 +0200 Subject: [Tutor] Teaching Objects References: <3.0.3.32.19990419065433.006b9790@mail.meta3.net> Message-ID: <371B27F4.3C45024A@pop.vet.uu.nl> John Kleinjans wrote: > > Re: teaching programming (to people who don't know > programming) (at all) using Python. > > So let's say, just to set the scene, that someone who has > *never programmed before at all* has now messed around > with Python a bit in interactive mode; and then has written > a couple short scripts to, maybe, solve quadratic equations > or make a calculator, something like that. > > We told this person about variables and assignments, about > sequence and branching and loops... so this person is just > *beginning* to get a feeling for (I can't think of the word > now... imperative? Like a language like C, or QBasic does.) > programming. Yes, that's generally called 'imperative programming'. I think I've seen 'procedural programming' too in this context. Displined use of all these facilities is called 'structured programming'; though in fact the time when structured programming was the big methodology (the place object oriented programming is in now) was before my time. :) To compare, we have: functional programming Lisp, Scheme, Haskell, etc. Emphasis (I'm not overly familiar with these) on making functions that call functions that call functions, often with recursion thrown in. All this function calling finally gives you the result. Rumored to be very pure, powerful and elegant. See Python's 'map', 'filter' and 'reduce' functions for examples of this in Python. Python, though it can be made to do just about anything, is however not a natural language to do function programming. logic programming Prolog. I'm not very familiar with this either, but basically you write up a lot of declarations (i.e. "if A is male and B is a parent of A, then A is the son of B"). Then you ask the system a question and it automagically gives you the answer. Shares a lot of the elegace, power and recursion with functional programming. :) object oriented programming This is usually associated with imperative programming; though one hears about people doing OOP with Lisp or Prolog too, this often does not seem to be the most natural way to do things in these languages. The procedures/functions of imperative programming are called methods or member functions, and are bundled together with the data they manipulate into classes. The classes can be put into a hierarchy where classes are related to each other, but add or change functionality (additional data, and additional/changed methods). The actual work in OOP programs is done by objects, which are instantiations of the general class template (Class Elephant, and Dumbo is an object of class Elephant..or perhaps of derived class FlyingElephant, really :). > I'd think that what this person needs is a sequence of some > `packages' that introduce a tool (command, function) with > an example short, simple application program, and a > couple simple projects that use that tool; then another tool, > another sample program, and a few more related projects; > and so on. Yes, this sounds like a good idea, and Python's modules are a natural fit. Take for instance the 'string' module. It contains lots of powerful ways to manipulate strings. What you could do is to make a learn_string.py module, that imports string and demonstrates some of its capabilities (in functions that can be called from within the Python interactive mode, perhaps). Perhaps it also wraps up some of the more difficult to understand functions into more easily understood ones, though perhaps the 'string' module is easy enough to grasp by itself (function by function, of course). Take a look by the way at the 'turtle.py' module that is now distributed with the new Python 1.5.2 distribution. It's not documented yet, but it is based on the Logo method to teach children programming. I'm not familiar with Logo at all, but basically you learn to program playfully by programmatically instructing a turtle to move around in patterns on the screen. The turtle draws a line wherever it goes, so you can make simple drawings. Beginners get get good visual feedback on what you're doing this way. In fact, unconsciously (I wanted to make games) I applied the same visual feedback technique by using moving graphics a lot when I learned to program. :) > And along the way, when appropriate, include objects in the > sample code. Explain *why* to make objects and *how* to > do it, too; what they are and when to use them; and begin > some discussion of programming style (start good habits now). Good habits can't start early enough, of course. When you introduce variables, tell them to use consistent variable names, and better long names that are understandable than short ones, etc. Same for function names. Objects can be introduced when talking about 'file objects' in Python, for instance. The file object in Python is relatively simple, and demonstrates methods and encapsulating data well. It is not too hard for people to make their own file objects, for instance a memory based file based on a Python list. You can then demonstrate how it's easy to replace one file object type with the other in a program. Instead of writing to a file, you write to the screen, or vice versa. Ideas of objects are also introduced when discussing special methods of the built-in sequence objects (dictionary.has_key("foo") for instance). The problem here is that in the current Python implementation there is a split between these built in 'types' objects, and Python class instance objects; you can't directly inherit from a built-in type. This can get confusing, though it's very well possible that I'm overestimating this confusion right now. :) > Anybody out there have some cool easy Python tricks? > > Anybody want to explain Who What When Where Why How > of objects in Python? Okay, just gave you some pointers. Feel free to ask away! Regards, Martijn From tismer@appliedbiometrics.com Mon Apr 19 17:25:24 1999 From: tismer@appliedbiometrics.com (Christian Tismer) Date: Mon, 19 Apr 1999 18:25:24 +0200 Subject: [Tutor] memory management References: Message-ID: <371B58F4.BA3DF276@appliedbiometrics.com> David Ascher wrote: > > On Sun, 18 Apr 1999, Christian Tismer wrote: > ... > > and watched my swapfile frow from small to 233 MB. > > Then I did a del on big. This took even more time than > > creating it, btw. Touching all the refcounts again seems > > to be quite a challenge for my harddisk. I have the strong > > impression that releasing objects should try to do this in > > reverse order. > > Do what in reverse order? I believe that trying to release objects in reverse order might be faster than in-order. At least I'm quite sure that it will not behave worse. Releasing objects by age is for sure a good guess. Python cannot know the object's age, but releasing list elements from back to front might more often be related to the object's age. > > > Without explicit measure, my guess is it takes > > 5 times as long to release this chunk. > > My guess is that you're seeing OS-specific behavior. Well, but there are many who suffer from this OS. [most of nice didactic excourse skipped] > - Python's memory management is somewhat object-type-specific -- some > objects are allocated from buffers which are indeed not completely > released when the objects aren't needed -- for example, frame objects > (used internally) and integers are taken from preallocated buffers > when possible, to speed up the common case of allocation and > deallocation. You might be seeing an effect of that with your range() > test. Details are in the code (see e.g. intobject.c and > frameobject.c). Interning of strings is another special-case behavior > which can lead to apparent memory leask which aren't real memory > leaks. Integers are allocated in a table of 1k blocks. They are chained to each other, forming a freelist. When a new integer is requested, it is taken from the freelist. Dropped integers are linked into the freelist, but never freed but at the program end. This explains the size of my swap file very well. An integer takes 12 bytes, this makes about 120 MB in my example, so this is ok. Now, assuming you have a machine with 64 MB of memory, try this in a fresh PyWin session: >>> from ptools import timing >>> def test(amount): ... global x ... x=range(amount) ... >>> timing(test, 1000000) (0.49, None) >>> timing(test, 0) (0.27, None) >>> timing(test, 1000000) (0.28, None) >>> timing(test, 0) (0.22, None) >>> timing(test, 2000000) (0.72, None) >>> timing(test, 0) (0.5, None) >>> timing(test, 3000000) (1.32, None) >>> timing(test, 0) (0.77, None) >>> timing(test, 4000000) (10.0, None) >>> timing(test, 0) (141.65, None) >>> timing(test, 3000000) (4.17, None) >>> timing(test, 0) (0.71, None) >>> timing(test, 4000000) (43.34, None) >>> timing(test, 0) (107.6, None) >>> As we can see, everything works fine upto 3 million numbers. 4 million is really bad, especially for deallocation. A few calculations: In the 3 million case, the array created by range is 4 * 3 million = 12 MB, the data for the integers is 12 * 3 million = 36 MB, together this is 48 MB which fits into memory after swapping most of Win98 to the disk, ok. With 4 million elements, we reach the 64 MB limit, and the system goes nuts. Everything is at least 10 times slower, releasing seems to be at least 20 times slower. So what happens? First, the list array is created in memory and filled with NULL. Then, all the integer objects are created and inserted into the array. Since the system cannot keep everything in memory, and since every place in the array and the integer freelist blocks will be touched once now, the whole memory will be written out in (small?) chunks in order to make room for the next chunk. So far ok, this seems to be impossible to avoid. On deallocation, the situation seems to be similar. The list array is read in order, and the numbers refcounts are decremented. This results in freeing most of the numbers, but instead of returning them into the global memory pool, they are inserted into the freelist. This means, the freed integer object is written with the current freelist head pointer. This will again pour the whole memory through the disk, but doesn't explain the time behavior. I just tested it with my 16 MB Linux machine, and no, it is not OS specific. Instead on timing with a function, I did >>> x=range(1000000) >>> x=0 >>> and counted cursor blinks of my telnet shell. Creating the range took 12 blinks, destroying took 37 blinks. But I think I should move this topic to the main list. 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 da@ski.org Mon Apr 19 17:31:32 1999 From: da@ski.org (David Ascher) Date: Mon, 19 Apr 1999 09:31:32 -0700 (Pacific Daylight Time) Subject: [Tutor] memory management In-Reply-To: <371B58F4.BA3DF276@appliedbiometrics.com> Message-ID: On Mon, 19 Apr 1999, Christian Tismer wrote: > > Do what in reverse order? > > I believe that trying to release objects in reverse order > might be faster than in-order. At least I'm quite sure that > it will not behave worse. Releasing objects by age is for > sure a good guess. Python cannot know the object's age, > but releasing list elements from back to front might > more often be related to the object's age. As with all optimization suggestions, the answer is: try it, profile it on multiple machines with realistic usage patterns, and if it's really good, submit it to Guido. I doubt you'll see a percentage point on any well-designed OS with a realistic test, but feel free to prove me wrong. Cheers, --david From DOUGS@oceanic.com Mon Apr 19 17:42:40 1999 From: DOUGS@oceanic.com (Doug Stanfield) Date: Mon, 19 Apr 1999 06:42:40 -1000 Subject: [Tutor] memory management Message-ID: <5650A1190E4FD111BC7E0000F8034D264A9F1B@HUINA> Might I respectfully submit that this discussion has exceeded the intent of the 'Tutor List'. I might be wrong but it seems more appropriate to c.l.py or maybe an offline discussion. -Doug- > -----Original Message----- > From: Christian Tismer [mailto:tismer@appliedbiometrics.com] > Sent: Monday, April 19, 1999 6:25 AM > To: David Ascher > Cc: Arne Mueller; tutor > Subject: Re: [Tutor] memory management > > > > > David Ascher wrote: > > > > On Sun, 18 Apr 1999, Christian Tismer wrote: > > > ... > > > and watched my swapfile frow from small to 233 MB. > > > Then I did a del on big. This took even more time than > > > creating it, btw. Touching all the refcounts again seems > > > to be quite a challenge for my harddisk. I have the strong > > > impression that releasing objects should try to do this in > > > reverse order. > > > > Do what in reverse order? > > I believe that trying to release objects in reverse order > might be faster than in-order. At least I'm quite sure that > it will not behave worse. Releasing objects by age is for > sure a good guess. Python cannot know the object's age, > but releasing list elements from back to front might > more often be related to the object's age. > > > > > > Without explicit measure, my guess is it takes > > > 5 times as long to release this chunk. > > > > My guess is that you're seeing OS-specific behavior. > > Well, but there are many who suffer from this OS. > > [most of nice didactic excourse skipped] > > > - Python's memory management is somewhat > object-type-specific -- some > > objects are allocated from buffers which are indeed not > completely > > released when the objects aren't needed -- for example, > frame objects > > (used internally) and integers are taken from > preallocated buffers > > when possible, to speed up the common case of allocation and > > deallocation. You might be seeing an effect of that > with your range() > > test. Details are in the code (see e.g. intobject.c and > > frameobject.c). Interning of strings is another > special-case behavior > > which can lead to apparent memory leask which aren't real memory > > leaks. > > Integers are allocated in a table of 1k blocks. They are chained > to each other, forming a freelist. When a new integer is requested, > it is taken from the freelist. Dropped integers are linked into the > freelist, but never freed but at the program end. > This explains the size of my swap file very well. > An integer takes 12 bytes, this makes about 120 MB in my example, > so this is ok. > > Now, assuming you have a machine with 64 MB of memory, > try this in a fresh PyWin session: > > >>> from ptools import timing > >>> def test(amount): > ... global x > ... x=range(amount) > ... > >>> timing(test, 1000000) > (0.49, None) > >>> timing(test, 0) > (0.27, None) > >>> timing(test, 1000000) > (0.28, None) > >>> timing(test, 0) > (0.22, None) > >>> timing(test, 2000000) > (0.72, None) > >>> timing(test, 0) > (0.5, None) > >>> timing(test, 3000000) > (1.32, None) > >>> timing(test, 0) > (0.77, None) > >>> timing(test, 4000000) > (10.0, None) > >>> timing(test, 0) > (141.65, None) > >>> timing(test, 3000000) > (4.17, None) > >>> timing(test, 0) > (0.71, None) > >>> timing(test, 4000000) > (43.34, None) > >>> timing(test, 0) > (107.6, None) > >>> > > As we can see, everything works fine upto 3 million numbers. > 4 million is really bad, especially for deallocation. > A few calculations: > In the 3 million case, the array created by range is 4 * 3 million > = 12 MB, the data for the integers is 12 * 3 million = 36 MB, > together this is 48 MB which fits into memory after swapping > most of Win98 to the disk, ok. > > With 4 million elements, we reach the 64 MB limit, and the system > goes nuts. Everything is at least 10 times slower, releasing > seems to be at least 20 times slower. So what happens? > > First, the list array is created in memory and filled with NULL. > Then, all the integer objects are created and inserted into > the array. Since the system cannot keep everything in memory, > and since every place in the array and the integer freelist > blocks will be touched once now, the whole memory will be written > out in (small?) chunks in order to make room for the next chunk. > So far ok, this seems to be impossible to avoid. > > On deallocation, the situation seems to be similar. > The list array is read in order, and the numbers refcounts > are decremented. This results in freeing most of the numbers, > but instead of returning them into the global memory pool, > they are inserted into the freelist. > This means, the freed integer object is written with the current > freelist head pointer. This will again pour the whole memory > through the disk, but doesn't explain the time behavior. > > I just tested it with my 16 MB Linux machine, and no, it is not > OS specific. Instead on timing with a function, I did > > >>> x=range(1000000) > >>> x=0 > >>> > > and counted cursor blinks of my telnet shell. > Creating the range took 12 blinks, destroying took 37 blinks. > > But I think I should move this topic to the main list. > > 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 > > _______________________________________________ > Tutor maillist - Tutor@python.org > http://www.python.org/mailman/listinfo/tutor > From a.mueller@icrf.icnet.uk Mon Apr 19 20:24:59 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Mon, 19 Apr 1999 20:24:59 +0100 Subject: [Tutor] logging stderr Message-ID: <371B830B.68DA0D@icrf.icnet.uk> Hi All, is there a way to write messages normally going to 'sys.stderr' (e.g. pythons error messages) to a file AND to 'sys.stderr' (on unix) without changing all my 'sys.stderr.write('...')' statements of the source files? thanks for help, Arne From joe@strout.net Mon Apr 19 20:35:39 1999 From: joe@strout.net (Joseph J. Strout) Date: Mon, 19 Apr 1999 12:35:39 -0700 Subject: [Tutor] logging stderr In-Reply-To: <371B830B.68DA0D@icrf.icnet.uk> Message-ID: At 12:24 PM -0700 04/19/99, Arne Mueller wrote: >is there a way to write messages normally going to 'sys.stderr' (e.g. >pythons error messages) to a file AND to 'sys.stderr' (on unix) without >changing all my 'sys.stderr.write('...')' statements of the source >files? Sure! (It's Python -- there's always a way!) Just create an object that has a write() method. The code of this method will log to a file, and to whatever the previous sys.stderr went to (you'll need to save that, probably in a member variable). Then assign sys.stderr to this method. Presto! Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From a.mueller@icrf.icnet.uk Mon Apr 19 21:20:48 1999 From: a.mueller@icrf.icnet.uk (Arne Mueller) Date: Mon, 19 Apr 1999 21:20:48 +0100 Subject: [Tutor] logging stderr References: Message-ID: <371B9020.E9EFA187@icrf.icnet.uk> "Joseph J. Strout" wrote: > > At 12:24 PM -0700 04/19/99, Arne Mueller wrote: > > >is there a way to write messages normally going to 'sys.stderr' (e.g. > >pythons error messages) to a file AND to 'sys.stderr' (on unix) without > >changing all my 'sys.stderr.write('...')' statements of the source > >files? > > Sure! (It's Python -- there's always a way!) Just create an object that > has a write() method. The code of this method will log to a file, and to > whatever the previous sys.stderr went to (you'll need to save that, > probably in a member variable). Then assign sys.stderr to this method. > Presto! Brilliant! Cool, I'm realy excited! class StreamCP: def __init__(self, src=sys.stderr, dst=sys.stdout): self.src = src self.dst = dst def write(self, msg): self.src.write(msg) self.dst.write(msg) log_file = open('./blastflt.log', 'a+') log = StreamCP(sys.stderr, log_file) sys.stderr = log Please note, the above assignment wokrs but assigning sys.stderr to log.write doesn't. greetings, Arne From joe@strout.net Mon Apr 19 21:25:47 1999 From: joe@strout.net (Joseph J. Strout) Date: Mon, 19 Apr 1999 13:25:47 -0700 Subject: [Tutor] logging stderr In-Reply-To: <371B9020.E9EFA187@icrf.icnet.uk> References: Message-ID: At 1:20 PM -0700 04/19/99, Arne Mueller wrote: >log_file = open('./blastflt.log', 'a+') >log = StreamCP(sys.stderr, log_file) >sys.stderr = log Nicely done! >Please note, the above assignment wokrs but assigning sys.stderr to >log.write doesn't. Yep. That's because sys.stderr needs to be an object with a "write" method. log.write doesn't have a "write" method (it IS one, but it doesn't HAVE one), and would be equivalent to trying to say "log.write.write('spam!')" which obviously won't work. Cheers, -- Joe ,------------------------------------------------------------------. | Joseph J. Strout Biocomputing -- The Salk Institute | | joe@strout.net http://www.strout.net | `------------------------------------------------------------------' From kuppler@vnet.net Mon Apr 26 05:08:27 1999 From: kuppler@vnet.net (kuppler@vnet.net) Date: Mon, 26 Apr 1999 04:08:27 Subject: [Tutor] AD:Family Reunion T Shirts & More Message-ID: <199904261153.HAA15522@python.org> Message sent by: Kuppler Graphics, 32 West Main Street, Maple Shade, New Jersey, 08052, 1-800-810-4330. This list will NOT be sold. All addresses are automatically added to our remove list. Hello. My name is Bill from Kuppler Graphics. We do screenprinting on T Shirts, Sweatshirts, Jackets, Hats, Tote Bags and more! Do you or someone you know have a Family Reunion coming up? Kuppler Graphics would like to provide you with some great looking T Shirts for your Reunion. Kuppler Graphics can also provide you with custom T's and promotional items such as imprinted magnets, keychains, pens, mugs, hats, etc. for your business or any fundraising activity (church, school, business etc.) We also can provide you with quality embroidery. We are a family owned company with over 15 years of experience. All work is done at this location. No middle man. Our prices are great! Click reply to email us or call 1-800-810-4330 for more info Bill Kuppler Graphics