Re: [Tutor] Simulate Input from mouse and keyboard?
On 16/03/06, Ars <[EMAIL PROTECTED]> wrote: > I'd like to be able have a program that can call up a webpage, click on a > text box and type into it as though a person was actually doing it. I don't know the general solution, but you might be able to solve this particular problem with PAMIE: http://pamie.sourceforge.net/ """ P.A.M.I.E. - stands for Python Automated Module For I.E. Pamie's main use is for testing web sites by which you automate the Internet Explorer client using the Pamie scripting language. PAMIE is not a record playback engine! Pamie allows you to automate I.E. by manipulating I.E.'s Document Object Model via COM. This Free tool is for use by Quality Assurance Engineers and Developers. """ -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Game over program
Python should have made the file associations when it was installed, but you can just manually associate *.py files with C:\Python24\python.exe and then your program should run inside of a little DOS window. -Jack On 3/15/06, Brad Hills <[EMAIL PROTECTED]> wrote: I'm 45 minutes into learning how to program using python. I am reading "Python programming for the absolute begginer" by Michael Dawson, and the first thing I've done was write the "Game Over" program. Which I understand is also called the "Hello World" Program. My main problem at this point is when I try to run the program from the icon on my desktop it asks me which program to associate it with. The book makes it sound like it will automatically execute the program. Am I doing something wrong? ___Tutor maillist - Tutor@python.orghttp://mail.python.org/mailman/listinfo/tutor What operating system are you using? Windowz? Mac? Anna ___Tutor maillist - Tutor@python.orghttp://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Simulate Input from mouse and keyboard?
Is there a way to control the mouse cursor's position so I can tell it to move to X,Y position on the screen and click or double click automatically? Also, how can you simulate input from the keyboard? I'd like to be able have a program that can call up a webpage, click on a text box and type into it as though a person was actually doing it. I know this is kinda an obtuse way of getting things done, but I think it'd be neat to be able to do it that way. So to recap (this is for windows btw): 1. How do you control the cursor relative to the entire screen, not just locked inside the program's own window. 2. How do you simulate mouse clicks/doubleclicks. 3. How do you emulate keyboard input as though a real person is typing. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Matching against various login prompts
Hi again, I'm trying to improve on couple of python scripts that I wrote and trying to get a successful/failed login re-usable module sorted out. Is there any way to match a returned string against a predetermined list of strings using the telnetlib module? I'm wanting to use a while loop rather than an 'if ' so that I can get some error checking on the username/password (ie typo in username). uPrompt = ['Username: '] pPrompt = ['Password: '] gPrompt = ['>'] sPrompt = ['login:'] prompt = tn.read_until('', 1) while prompt == gPrompt: do stuff for device here While prompt == uPrompt: do stuff for different device here While prompt == sPrompt: do stuff for different OS here I've tried various combinations of tn.read_until's and tn.expect's but I don't seem to be able to capture the last line returned and match against conditions with it. I've read the telnetlib doco but can't figure out which one of the many options is what I'm after (probably if I define all the above as functions or something I could work it out but haven't got that part straight in my head yet). Cheers Gideon This e-mail (including any attachments) may contain confidential or privileged information and is intended for the sole use of the person(s) to whom it is addressed. If you are not the intended recipient, or the person responsible for delivering this message to the intended recipient, please notify the sender of the message or send an e-mail to mailto:[EMAIL PROTECTED] immediately, and delete all copies. Any unauthorised review, use, alteration, disclosure or distribution of this e-mail by an unintended recipient is prohibited. Ergon Energy accepts no responsibility for the content of any e-mail sent by an employee which is of a personal nature. Ergon Energy Corporation Limited ABN 50 087 646 062 Ergon Energy Pty Ltd ABN 66 078 875 902 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Dynamically naming functions
> > Very rarely, its easy to do backups of huge amounts of data if you > > know where to find it, its hard to trawl all over a changing structure > > looking for the things that need backing up. Particularly if, when you > > try to restore it, it needs to go in a different place to where you > > found > > it! > > Backing up is generally one of the lesser of my worries. Backing up is usually a no brainer, especially in a static structure, but even in a dynamic one you can just do a find on the file types. It's restoring a dynamic structure thats really hard, and usually a manual process... > Maintaining content is primary. Oddly enough I usually expect content maintenance to be a 'business as usual' kind of thing. The content goes in one place per author and the code picks it up as needed. > Unless you are dynamically generating static pages, > they are a nightmare to maintain. If the content is dynamic in any way I always generate them dynamically - and that includes anything with company logo etc on it. About the only pure html pages I use are the Error reports - 404s etc... > be quite repetitive. A large amount of the code on any page is the > same as on any other page (page structure, boilerplate, etc). But most of that is template code just picking up content from a folder someplace (logo images, standard menus etc) and CSS style settings. > I think it's a generally accepted principle that computers are better > at handling thousands of files like that better than humans are. The Absolutely. > > Yes but a CMS normally uses a static structure with dynamic content. > I think we might be using different meanings of structure. I'm > referring to the site structure, as in which page is a parent of which > other page. The site structure is just another aspect of the content. Ah, OK. I'm referring to the physical site structure, the folder heirarchy. > A reference to the parent/child pages is just another attribute like > content and title. Agreed, I'd expect those to be managed in the code and templates. > A (good) CMS would create a dynamic structure for the user to browse, > with folders and pages easily creatable and movable, I'm not sure I agree with that. It should allow movement of pages across folders with auto update iof relative paths etc, but not necessarily dynamic (ie at run time) changes. > and references to pages would be dynamic so that if yo0u move a > page internal links to it still work. I don;t necessarily see that as needing to be a dynamic feature, I'd probably prefer to do those kinds of changes under controlled circumstances and do the updates as a batch update process. >> Dynamic content is 'A Good Thing', dynamic structure is usually bad. > > But structure is just an aspect of content. If you mean navigation structure I agree, but physical structure - where the files live is absolutely not. And to make it so creates a huge headache for the site administrators - who usually cost a good deal more than the developers or content providers! Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Tix: binding
On 16/03/06, Adam <[EMAIL PROTECTED]> wrote: > On 15/03/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > I want to bind the cancel buttom of a ExFileSelectBox to a routine in my > > class, > Here's what I got from a little experimentation and print > box.cancel.bind.__doc__. > > >>> def bar(action): > ... print action > >>> import Tix > >>> root = Tix.Tk() > >>> box = Tix.ExFileSelectBox(root) > >>> box.pack() > >>> box.cancel.bind("", bar) > '-1212073588bar' > >>> > > This will bind to leftmouse-down, which is different from clicking a button. If you want to simulate a real button click with event bindings, you will need to set a flag on ButtonPress-1, then in ButtonRelease-1 check for the flag, check to see if the mouse is within the button, and then activate your callback. Something else you could try (which I haven't tested) --- instead of box.cancel.bind, do box.cancel.config(command= ...). -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help with Game over program
On 3/15/06, Brad Hills <[EMAIL PROTECTED]> wrote: I'm 45 minutes into learning how to program using python. I am reading "Python programming for the absolute begginer" by Michael Dawson, and the first thing I've done was write the "Game Over" program. Which I understand is also called the "Hello World" Program. My main problem at this point is when I try to run the program from the icon on my desktop it asks me which program to associate it with. The book makes it sound like it will automatically execute the program. Am I doing something wrong? ___Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutorWhat operating system are you using? Windowz? Mac? Anna ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Tix: binding
On 15/03/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > I am looking at Tix and I am stuck with what seems to be a simple problem: > > I want to bind the cancel buttom of a ExFileSelectBox to a routine in my > class, but can not make it work. > I guess the problem is the same for any binding of tix sub-widgets, so if > someone could send some sample code. > >>> import Tix > >>> root = Tix.Tk() > >>> box = Tix.ExFileSelectBox(root) > >>> print box.subwidget(name='cancel') > .11827520.bf.cancel#so the sub-widget cancel > buttom is there > > But how to bind it ? > > >>> box.cancel(command = lambda a,b : a+b ) > Traceback (most recent call last): > File "", line 1, in ? > box.cancel(command = lambda a,b : a+b ) > AttributeError: _dummyButton instance has no __call__ method > > Or > > >>> box.subwidget(name='cancel' , command = lambda a,b : a+b ) > Traceback (most recent call last): > File "", line 1, in ? > box.subwidget(name='cancel' , command = lambda a,b : a+b ) > TypeError: subwidget() got an unexpected keyword argument 'command' > > So, it seems I can not bind to command, but what then ? > >From the Tix docu I thought the buttoms are normal Tkinter widgets ? > -- > Harm Here's what I got from a little experimentation and print box.cancel.bind.__doc__. >>> def bar(action): ... print action >>> import Tix >>> root = Tix.Tk() >>> box = Tix.ExFileSelectBox(root) >>> box.pack() >>> box.cancel.bind("", bar) '-1212073588bar' >>> If you have a look at box.cancel.bind.__doc__ you can find everything you can put into the SEQUENCE string "" is left mouse click. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Help with Game over program
I'm 45 minutes into learning how to program using python. I am reading "Python programming for the absolute begginer" by Michael Dawson, and the first thing I've done was write the "Game Over" program. Which I understand is also called the "Hello World" Program. My main problem at this point is when I try to run the program from the icon on my desktop it asks me which program to associate it with. The book makes it sound like it will automatically execute the program. Am I doing something wrong? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] xemacs and python mode difficulty
Howdy,Relevant Data-Windows XP SP 2 or greaterPython 2.4.2 FinalXemacs 21.4.19--Problem:I really like xemacs as my editor of everything. However when I downloaded the installer for 21.4.19 to update my xemacs installation, python mode was gone. Searching for how to customize xemacs led me to a great deal of confusion.I would like to know the difference between ~/.emacs and .xemacs\custom.el and also how to install the python module, so that I can get syntax highlighting, the tab trick, C-c C-c, and the rest of the old python mode functionality.Thank you,FrancescoFrancesco Queirolo(+1)505.661.2670[EMAIL PROTECTED] Yahoo! Travel Find great deals to the top 10 hottest destinations!___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Converting String to Datetime
Ed Singleton wrote: > I seem to have a lot of questions today. Sorry. > > How can I convert a string in the format "%Y-%m-%d %H:%M:%S" into a > datetime object? > > I can work out how to convert it to a time object by: > > import time > timestring = "2005-09-01 12:30:09" > time_format = "%Y-%m-%d %H:%M:%S" > mytime = time.strptime(timestring,time_format) > > I can't seem to work out how to convert the time object into a > datetime object... Try datetime.datetime(*mytime[:6]) Gee, two questions in one day where the answer is, "Use extended function call syntax" ;) Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing Dictionaries to Functions
Ed Singleton wrote: > Thanks again. > > This does bring up an issue I occaiosionally have with the documentation. > > Presumambly myfunc(**mydict) is a fairly trivial thing, but it is very > hard to find when you don't know what you're looking for. Not sure > what the solution is, but the inability to search for things when you > don't know what they're called is a bit of a stumbling block > sometimes. Yes. This syntax is actually hard to find in the docs when you *do* know what you are looking for. The best coverage I could find is in the Language Reference which isn't exactly light reading: http://docs.python.org/ref/calls.html It's also mentioned in the docs for apply(), which is an older way to do the same thing: http://www.python.org/doc/2.4.2/lib/non-essential-built-in-funcs.html > > Maybe a page that very briefly summarises the 'unsearchable' with > links to fuller descriptions? Hmm. Sounds a little tricky to put together... Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Converting String to Datetime
Nevermind. i seem to have found the answer in that wonderful PLEAC site (I always forget about that. It appears that the following works: import time, datetime timestring = "2005-09-01 12:30:09" time_format = "%Y-%m-%d %H:%M:%S" datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime, time_format))) Ed On 15/03/06, Ed Singleton <[EMAIL PROTECTED]> wrote: > I seem to have a lot of questions today. Sorry. > > How can I convert a string in the format "%Y-%m-%d %H:%M:%S" into a > datetime object? > > I can work out how to convert it to a time object by: > > import time > timestring = "2005-09-01 12:30:09" > time_format = "%Y-%m-%d %H:%M:%S" > mytime = time.strptime(timestring,time_format) > > I can't seem to work out how to convert the time object into a > datetime object... > > Any help appreciated. > > Thanks > > Ed > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Converting String to Datetime
I seem to have a lot of questions today. Sorry. How can I convert a string in the format "%Y-%m-%d %H:%M:%S" into a datetime object? I can work out how to convert it to a time object by: import time timestring = "2005-09-01 12:30:09" time_format = "%Y-%m-%d %H:%M:%S" mytime = time.strptime(timestring,time_format) I can't seem to work out how to convert the time object into a datetime object... Any help appreciated. Thanks Ed ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing Dictionaries to Functions
Thanks again. This does bring up an issue I occaiosionally have with the documentation. Presumambly myfunc(**mydict) is a fairly trivial thing, but it is very hard to find when you don't know what you're looking for. Not sure what the solution is, but the inability to search for things when you don't know what they're called is a bit of a stumbling block sometimes. Maybe a page that very briefly summarises the 'unsearchable' with links to fuller descriptions? Ed On 15/03/06, Kent Johnson <[EMAIL PROTECTED]> wrote: > Ed Singleton wrote: > > If I have a dictionary: > > > > mydict{'var1':"a", 'var2':"b"} > > Presumably you mean >mydict = {'var1':"a", 'var2':"b"} > > > > and I want to pass it to a function as: > > > > myfunc(var1="a", var2="b") > > > > How would I do it? > > myfunc(**mydict) > > Kent > > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing Dictionaries to Functions
Ed Singleton wrote: > If I have a dictionary: > > mydict{'var1':"a", 'var2':"b"} Presumably you mean mydict = {'var1':"a", 'var2':"b"} > > and I want to pass it to a function as: > > myfunc(var1="a", var2="b") > > How would I do it? myfunc(**mydict) Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] "Unexcepted Python Error : Exceptions.IOError: [Errorno 9] Bad File descriptor"
K.Vijaya Balaji Chellamani wrote: > Respected Sir , > I am new and introducing myself as Vijaya Balaji > Chellmani . When i was using the python for my office application ( uses > VC++ ) unfortunately i was awarded with unexcepted python error .The > error is > "Unexcepted Python Error : Exceptions.IOError: [Errorno 9] Bad File > descriptor" You don't give us much to work with. Is there a stack trace associated with the error message? Can you show us the actual code that causes the error? Googling for the error message gives a hint that it may be caused by trying to write to stdout when the process does not have stdout defined. HTH Kent > > Situation for the occurance: > i worte a script for querying certain objects .This script was invoked > from vc++ through command prompt .Since the execution was slow , we > switched over a modification in the script .The modification was all > the process of querying were taken under single class .and then we > assigned a class id , other infomation for making this class as > component.After all modification the script was runned to make a > register process in the registry. Then the script was invoked from our > application through "OLE" instance.The querying showed a faster response > . but the thing is i was stucked sometimes with error message cited > above .But after ignoring the message and when i continue again with > some query process ( purpose of querying :finding a device name in > pickle database ) i stucked up with the error again . > > Is there is any remedy for this . how can i eliminate this . I will very > useful for me if you clarify this doubt . I will be thankful to you. > > > by > Vijaya Balaji Chellamani. > > > > > > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Passing Dictionaries to Functions
If I have a dictionary: mydict{'var1':"a", 'var2':"b"} and I want to pass it to a function as: myfunc(var1="a", var2="b") How would I do it? Thanks Ed ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] "Unexcepted Python Error : Exceptions.IOError: [Errorno 9] Bad File descriptor"
Respected Sir , I am new and introducing myself as Vijaya Balaji Chellmani . When i was using the python for my office application ( uses VC++ ) unfortunately i was awarded with unexcepted python error .The error is "Unexcepted Python Error : Exceptions.IOError: [Errorno 9] Bad File descriptor" Situation for the occurance: i worte a script for querying certain objects .This script was invoked from vc++ through command prompt .Since the execution was slow , we switched over a modification in the script .The modification was all the process of querying were taken under single class .and then we assigned a class id , other infomation for making this class as component.After all modification the script was runned to make a register process in the registry. Then the script was invoked from our application through "OLE" instance.The querying showed a faster response . but the thing is i was stucked sometimes with error message cited above .But after ignoring the message and when i continue again with some query process ( purpose of querying :finding a device name in pickle database ) i stucked up with the error again . Is there is any remedy for this . how can i eliminate this . I will very useful for me if you clarify this doubt . I will be thankful to you. by Vijaya Balaji Chellamani. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] OSError
Christopher Spears wrote: > I am trying to write a function that takes a directory > name and describes the contents of the directory (file > name and size) recursively. Here is what I have > written so far: > > import os, os.path > > def describeDirectory(directory): > if os.listdir(directory) == []: > print "Empty directory!" > else: > for files in os.listdir(directory): > if os.path.isdir(files): > print files, ' is a directory!' > else: > print files, 'SIZE: ', > os.path.getsize(files) > > print 'Current Directory: \n' > describeDirectory('.') > print '\n' > print './testFiles: \n' > describeDirectory('./testFiles') Chris, os.path.getsize() needs the full path or relative path to the file, but os.listdir() just returns the bare file name, so there is a slight mismatch here. describeDirectory() works for the current dir because the bare file name is the correct relative path. You should use os.path.join(directory, files) to create the full path to pass to os.path.getsize(). BTW 'files' is not such a great name because it is just one file, not multiple. But don't change it to 'file', that is the name of a built-in function! Maybe 'f' or 'name' or 'filename'. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Help me please
yogeshwarran Nadeson wrote: > Hello, > > I am a newbie in python programming without previous programming > experience.Here i would like to ask > a question based on the exercises given by Josh Cogliatti in his > tutorial.I'll paste the question.Hope you can help me to solve it.I'd > like to end it by saying thanks for all yourr help. Have you written a program that uses loops? Could you write a program that uses a loop to print "Hello" three times? Kent > > *:Modify the password guessing program to keep track of how many times > the user has entered the password wrong. If it is more than 3 times, > print ``That must have been complicated.'' * > > This is the previous password program: > > Password.py > > # Waits until a password has been entered. Use control-C to break out with > out > # the password > > #Note that this must not be the password so that the > # while loop runs at least once. > password = "foobar" > > #note that != means not equal > while password != "unicorn": > password = raw_input("Password:") > print "Welcome in" ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Splitting a string into n-sized bytes
Steve Nelson wrote: > Indeed - as I now have a function: > > def nsplit(s, n): > return [s[i:i+n] for i in range(0, len(s), n)] > > Incidentally I am currently going with: > > def nsplit(s, n): > while s: >yield s[:n] >s = s[n:] You can write the generator function to use the same method as the list comp and avoid creating all the intermediate (partial) lists: def nsplit(s, n): for i in range(0, len(s), n): yield s[i:i+n] One of the cool things about generators is that they make it so easy to maintain state between yields. In Python 2.4, all you have to do is rewrite your original list comp to a generator comprehension: def nsplit(s, n): return (s[i:i+n] for i in range(0, len(s), n)) Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] OSError
Hi Chris, I think I've found the problem. os.listdir() gives you all entries of the directory, but your not changing to that directory. The os.path.getsize() just does not find the file in the directory "testFiles" under your current directory. See my short example below. >>> import os >>> os.listdir( "trace" ) ['nbewer', 'installer_acb_2004-10-15.zip', 'epAnalyze.py', 'nbgene', 'ep20051201.txt', 'IPseconLinux.sxw', 'bbaseline', 'inner-classes.patch', 'jde-usages-0.9.1.zip', 'bleuch.ttf', 'privdebug'] >>> os.getcwd() '/users/trinomic/ewer' >>> import os.path >>> os.path.isfile ( "epAnalyze.py" ) False >>> os.path.isfile ( "trace/epAnalyze.py" ) True HTH Ewald Christopher Spears wrote: > I am trying to write a function that takes a directory > name and describes the contents of the directory (file > name and size) recursively. Here is what I have > written so far: > > import os, os.path > > def describeDirectory(directory): > if os.listdir(directory) == []: > print "Empty directory!" > else: > for files in os.listdir(directory): > if os.path.isdir(files): > print files, ' is a directory!' > else: > print files, 'SIZE: ', > os.path.getsize(files) > > print 'Current Directory: \n' > describeDirectory('.') > print '\n' > print './testFiles: \n' > describeDirectory('./testFiles') > > Here is the result: > > Current Directory: > > changePeppers.py SIZE: 915 > describeDirectory.py SIZE: 481 > describeDirectory.pyc SIZE: 514 > error_log SIZE: 0 > makezeros.py SIZE: 147 > makezeros.pyc SIZE: 481 > output SIZE: 387 > pepper.txt SIZE: 601 > testFiles is a directory! > textWrapper.py SIZE: 619 > textWrapper.pyc SIZE: 1092 > timings.py SIZE: 567 > timings.pyc SIZE: 733 > > > ./testFiles: > > renameFiles.py SIZE: > Traceback (most recent call last): > File "describeDirectory.py", line 17, in ? > describeDirectory('./testFiles') > File "describeDirectory.py", line 11, in > describeDirectory > print files, 'SIZE: ', os.path.getsize(files) > File "/usr/lib/python2.4/posixpath.py", line 139, in > getsize > return os.stat(filename).st_size > OSError: [Errno 2] No such file or directory: > 'renameFiles.py' > > I don't understand the OSError. The file > 'renameFiles.py' is in './testFiles' directory. Can > someone clarify this for me? > > -Chris > > "I'm the last person to pretend that I'm a radio. I'd rather go out and be a > color television set." > -David Bowie > > "Who dares wins" > -British military motto > > "I generally know what I'm doing." > -Buster Keaton > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor