Re: If Statement Error (Tic Tac Toe)

2005-11-02 Thread Jim Segrave
row not in ['1', '2', '3' ] or \
   column not in ['1', '2', '3']:
print "Invalid selection, please try again"
continue

# convert row and column to array index
loc = 3 * (int(row) - 1) + int(column) - 1
if board[loc] == ' ':
break

print "This cell is already filled."

# now we have a valid location, fill it in
board[loc] = ['X', 'O'][player]

for i in range(3):
# check for horizontal win
if board[3 * i] == board[ 3 * i + 1] == board[3 * i + 2] and \
   board[3 * i] != ' ':
win = 1
break
if board[i] == board[i + 3] == board[i + 6] and \
   board[i] != ' ':
win = 1
break
else:
# no horizontal or vertical win yet
# test the diagonals
if (board[0] == board[4] == board[8] or 
board[2] == board[4] == board[6]) and board[4] != ' ':
win = 1

if win:
break

# if we reach here, the game isn't over,  flip players
turns += 1
player = (player + 1) % 2

# the game has finished
if win:
print "\nPlayer %d wins!" % player
for r in range(0, 9, 3):
print "[%s]" * 3 % tuple (board[r : r + 3])
print
else:
print "Tie"



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: strange sockets

2005-11-04 Thread Jim Segrave
In article <[EMAIL PROTECTED]>, Skink  <[EMAIL PROTECTED]> wrote:
>Hi,
>
>I'm preparing a python server that sends java classes and resources to
>custom java class loader. In order to make it faster I don't want to use
>URLClassLoader that uses HTTP protocol 1.0 and for each class/resource
>creates own connection.
>Instead I'd like to use raw sockets with simple protocol:
>
> - class loader sends a line terminated with \n with resource to get
> - python server reads that line, gets the file and sends back an
>integer with file length and then the file itself
> - class loader reads a lenght integer and then reads the remainig data
>
>
>The problem is when I try to read several files the first one is read
>quite fast, but the rest is read 40 x slower. For example (time is in
>seconds):
>
>% python client.py client.py client.py client.py server.py server.py
>init 0.00066089630127
>client.py 0.000954866409302
>client.py 0.0408389568329
>client.py 0.0409188270569
>server.py 0.0409059524536
>server.py 0.0409259796143
>
>what's wrong here?

At a guess, what you've measured is how long it takes to transfer the
data to the underlying OS socket buffers. The first transfer fills the
buffers, subsequent ones have to wait until the data has been put on
the wire and acknowledged before there's space for the writes. 

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Tkinter- checkbutton

2005-11-04 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Tuvas <[EMAIL PROTECTED]> wrote:
>Ere, ignore the mis-capped Checkbutton and the missed master call in
>it...
>

You need to use a Tkinter variable (IntVar, StringVar or whatever),
associate it with the Checkbutton, and access it with the get() and
set() methods:

from Tkinter import *

root = Tk()

v = IntVar()
v.set(1)

def do_stuff_here():
print "Value is zero"

def do_other_stuff_here():
print "Value is not zero"

def check():
if v.get() == 0:
do_stuff_here()
elif v.get() == 1:
do_other_stuff_here()
else:
print "This is impossible, but it happened"

b = Checkbutton(root, text = 'Press Me', command = check, variable = v)
b.grid(row = 0, column = 0)
root.mainloop()

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Tkinter- New Window

2005-11-04 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Tuvas <[EMAIL PROTECTED]> wrote:
>Is there a way to make a new window pop up using Tkinter? I have some
>functions that require more data in my interface than I have space for,
>and would like to be able to pop up a new window to request this
>information. Thanks!

Dialogue boxes pop up new windows for gathering information. If you
want a more permanent second window, then the Toplevel() widget is
like a frame, but is a separte window with window manager
decorations, can be sparately iconfied etc.

from Tkinter import *
root = Tk()
root.title('Root')
rootlabel = Label(root, text = 'This is the root window', relief = RIDGE)
rootlabel.pack(side = TOP, fill = BOTH, expand = YES)
other = Toplevel()
other.title('Second Window')
otherlabel = Label(other, text = 'This is the other window', relief = RIDGE)
otherlabel.pack(side = TOP, fill = BOTH, expand = YES)
root.mainloop()



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: fcntl.flock() not working when called from a function

2005-11-04 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
thakadu <[EMAIL PROTECTED]> wrote:
>The following code works as expected when run in the main body of a
>python script (ver 2.3.5) on OpenBSD v3.8. but when it is in the body
>of a function definition it does not work. It does not raise any errors
>but it simply does not block as expected. I have repeated this in both
>a cgi envirnoment and a non-cgi environment. I also have repeated it
>under OpenBSD 3.6 Python Version 2.3.4. To test this you need to run
>the code from two shells or if testing the cgi version from two
>browsers.
>The first call to flock() should pass without blocking while the second
>call should block.
>I have tried varying the file open mode by using 'r', 'r+', 'w', 'rw',
>'w+', and always I get the same results.
>Does anyone have an idea why this would work in the main body of the
>script but not in a function?
>
>This code works if in the main body of a script:
>
>import fcntl
>f=open('/tmp/lockfile')
>fcntl.flock(f,fcntl.LOCK_EX)
>
>but this does not work:
>
>import fcntl
>
>def lock():
>f=open('/tmp/lockfile')
>fcntl.flock(f,fcntl.LOCK_EX)
>
>lock()

Doesn't f go out of scope when you exit lock()? Python closes the
file, as it's no longer referenced and Unix removes locks on calls to
close().
To make this work, you'd have to keep a reference to f:

import fcntl

def lock():
f=open('/tmp/lockfile')
fcntl.flock(f,fcntl.LOCK_EX)
return f
saveme = lock()

print "OK"
while True:
pass

Under FreeBSD, the first copy prints OK and waits for a SIGINT, the
second copy prints nothing. Killing the first copy prints OK on the
second one



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: mod_python

2005-11-06 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Little <[EMAIL PROTECTED]> wrote:
>I have created the following database but the following errors occur
>when trying to execute the code.
>
>html source:
>
>
>Click here to display information from Chocolate menu:
>
>
>Press to view the display
>
>
>
>
>Please provide data for chocolate to be added:
>
>
>
>Name:
>Rating:  
>Price :  
>
>
>
>
>
>
>form.py source
>
>import MySQLdb
>
>def addchocolate(z_Name, z_rating, z_price):
>
># make sure the user provided all the parameters
>if not (z_Name and z_rating and z_price):
>return "A required parameter is missing, \
>   please go back and correct the error"
>db =
>MySQLdb.connect(host="localhost",user="hayward",passwd="hayward",db="hayward")
>cursor = db.cursor()
>cursor.execute(
>"""INSERT INTO InventoryList (artist, title, rating) VALUES (%s,
>%s, %s)""", (z_Name, z_rating, z_price) )


I hate to ask, but what happens when I enter "a, b, c);DROP DATABASE;" as
the entry for z_name? (Or some similar attempt to close the
SQL statement and start a new one). I think you want to google for "SQL
injection" and think about sanitising user input a bit.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: how do i use "tkinter.createfilehandler" with a regular c program?

2005-11-14 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Jo Schambach  <[EMAIL PROTECTED]> wrote:
>I am trying to write a GUI with tkinter that displays the stdout from a
>regular C/C++ program in a text widget.
>The idea i was trying to use was as follows:
>
>1) use "popen" to execute the C/C++ program
>2) then use "tkinter.createfilehandler" to create a callback that  would
>be called when the C/C++ program creates output on stdout.
>
>Somehow, I can't get this to  work. here is what I have tried so  far:
>
>import sys,os
>from Tkinter import *
>
>root = Tk()
>mainFrame = Frame(root)
>textBox = Text(mainFrame)
>textBox.pack(fill=BOTH, expand=YES)
>mainFrame.pack(fill=BOTH, expand=YES)
>
>fh = os.popen('/homes/jschamba/tof/pcan/pcanloop')
>
>def readfh(filehandle, stateMask):
>global textBox
>newText = filehandle.read()
>textBox.insert(END, newText)
>
>tkinter.createfilehandler(fh, tkinter.READABLE, readfh)
>root.mainloop()

Changingfilehandle.read() to filehandle.readline() and running a
separate output generator, this seems to work, although the Text
widget fills rapidly:

= test generator - creates a pipe and writes the time once/second
#!/usr/local/bin/python
import os, time

try:
pipe = os.mkfifo('./pipe', 0660)
except OSError, (errno):
if errno == 17:
pass

fh = open('./pipe', 'w')
rh = open('./pipe', 'r') # keep the pipe having a reader
while True:
fh.write("%s\n" % time.asctime(time.localtime()))
fh.flush()
time.sleep(1)

== read the output and put in a Text widget:
#!/usr/bin/python
import sys,os
from Tkinter import *

root = Tk()
mainFrame = Frame(root)
textBox = Text(mainFrame)
textBox.pack(fill=BOTH, expand=YES)
mainFrame.pack(fill=BOTH, expand=YES)

fh = os.popen('/bin/cat /tmp/pipe', 'r', 1)

def readfh(filehandle, stateMask):
global textBox
newText = filehandle.readline()
textBox.insert(END, newText)

tkinter.createfilehandler(fh, tkinter.READABLE, readfh)
root.mainloop()

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Detecting problems in a forked process

2005-12-29 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
James Colannino  <[EMAIL PROTECTED]> wrote:
>Hey everyone.  I'm writing a small application in Python that uses 
>os.fork() to create a separate process in which another application is 
>run in the background.  The problem is that I need to know whether or 
>not that separate application managed to start and return from within 
>the parent appropriately.  Here's, roughly, a pseudo example of what I 
>want to do (I know the code itself is not correct):
>
>def function():
>
>pid = os.fork()
>
>if pid:
> do parent stuff
>else:
> try:
>  execute the application
> exeption:
>  somehow return -1 from within the parent process
>
>#try to start another application in the background from within a forked 
>process
>if (function() == -1):
>fail
>
>Is there a way that I can do this?  I thought, only for a *VERY* brief 
>second, about cheating my way around this with a global variable, but 
>then I realized that this wouldn't work due to the fact that I will have 
>multiple forks doing the same thing at the same time.  Thanks in advance :)

options:

Have the child set it's exit code to indicate success or failure and
use one of the various os.wait functions in the parent to retrieve it.

or

create a pipe before forking and you can pass data back and forth
between the parent and child

or

look at one of the shared memory libraries



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: stderr, stdout, and errno 24

2006-07-12 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Wesley Henwood <[EMAIL PROTECTED]> wrote:
>To capture output from python scripts run from a C++ app I've added the
>following code at the beggening of the C++ app:
>
>PyRun_SimpleString("import grabber");
>PyRun_SimpleString("import sys");
>PyRun_SimpleString("class a:\n\tdef
>write(self,s):\n\t\tograbber.grab(s)\n");
>PyRun_SimpleString("import sys\nsys.stderr=a()\nsys.stdout=a()");
>
>Its hard to read that way, here's what it expands to:
>import grabber
>import sys
>class a:
>def write(self, s)
>grabber.grab(s)
>
>grabber is a C++ extension, the grab function prints displays the
>captured text in a Windows app.  After running about 450+ scripts in a
>row, I get "IOError Errno 24 Too many open files."
>
>I've searched this group and the net and determined that stderr and
>stdout may open files, is that correct?  If so would each running of a
>script be opening new files related to stderr and stdout and not
>closing them?  I'm just guessing.

I'm guessing, but it sounds like perhaps you're creating an object which has
an open file handle for output for each script that's run. When the
script finishes, if that object still exists, it will keep a file
handle open and eventually you'll hit the system limit on open file
handles for one process. 

It's also possible that your C++ app is the one which is failing to
close file handles created for running the scripts - there's no easy
way to tell from the information posted. 

You need to examine carefully what happens to any stdin/stdout/stderr
files which are created to execute scripts and ensure that they are
all properly closed (or, in the case of Python, if you don't
explicitly close them, that any references to the files cease to exist
after the script runs). I'd personally recommend explicit closing
here.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to lock files (the easiest/best way)?

2006-07-16 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Eric S. Johansson <[EMAIL PROTECTED]> wrote:
>Elmo Mäntynen wrote:
>> Is there something better than using fnctl? It seems a bit intimidating
>> with a quick look.
>
>try the portlocker wrapper from the active state cookbook.  I have a 
>version which has been slightly updated for more modern pythons.  I 
>really need to make my darcs repository visible so you could get it.
>
>Alternatively, you can try the makedir trick.  Creating directories are 
>atomic operations if it exists, you will get error message.  If it 
>doesn't, you will get a directory and thereby capture the lock.  You 
>delete the directory when you release the lock.
>
>crude but effective.  I used it in building a file based queue system. 
>You know, I really should learn how to build eggs because I have a whole 
>bunch of little pieces of software that would probably be useful to others.

Here's a more complete file locking scheme which uses a lockfile with
the O_CREAT and O_EXCL flags to make the creation atomic. If it gets
the lock, it writes its PID in readable form in the file. It also does
two other things:

If you know that no process should lock the file for more than a fixed
period of time, it will retry once/second as long as the lock file is
not older than that fixed period of time. If it is older, it will
report the problem, including the PID of the locking process and exit.

This caters for a process which has set the lock file and then
terminates without removing it (which can happen do to an application
or server crash).

--

import os
import errno
import sys
import time
import stat

# the maximum reasonable time for aprocesstobe
max_wait = 10

lockfile = "/tmp/mylock"

while True:
try:
fd = os.open(lockfile, os.O_EXCL | os.O_RDWR | os.O_CREAT)
# we created the lockfile, so we're the owner
break
except OSError, e:
if e.errno != errno.EEXIST:
# should not occur
raise

try:
# the lock file exists, try to stat it to get its age
# and read it's contents to report the owner PID
f = open(lockfile, "r")
s = os.stat(lockfile)
except OSError, e:
if e.errno != errno.EEXIST:
sys.exit("%s exists but stat() failed: %s" %
 (lockfile, e.strerror))
# we didn't create the lockfile, so it did exist, but it's
# gone now. Just try again
continue

# we didn't create the lockfile and it's still there, check
# its age
now = int(time.time())
if now - s[stat.ST_MTIME] > max_wait:
pid = f.readline()
sys.exit("%s has been locked for more than " \
 "%d seconds (PID %s)" % (lockfile, max_wait,
 pid))

# it's not been locked too long, wait a while and retry
f.close()
time.sleep(1)

# if we get here. we have the lockfile. Convert the os.open file
# descriptor into a Python file object and record our PID in it

f = os.fdopen(fd, "w")
f.write("%d\n" % os.getpid())
f.close()




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list

Re: How to lock files (the easiest/best way)?

2006-07-16 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Jim Segrave  <[EMAIL PROTECTED]> wrote:
>except OSError, e:
>if e.errno != errno.EEXIST:

this should read:
 if e.errno != errno.ENOENT:

(it was left with EEXIST from testing this code by forcing an error,
as the code for this failure requires a very tight race condition to test)

>sys.exit("%s exists but stat() failed: %s" %
> (lockfile, e.strerror))
># we didn't create the lockfile, so it did exist, but it's


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: iterator? way of generating all possible combinations?

2006-05-31 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Scott David Daniels  <[EMAIL PROTECTED]> wrote:
>
>This works if-and-only-if it is only in use once at a time.
>If you have multiple simultaneous accesses, you need to do
>something like:
>
> class FileReIterable2(object):
> def __init__(self, file):
> if isinstance(file, basestring):
> self.file = open(file, 'rU')
> else:
> self.file = file
> def __iter__(self):
> self.file.seek(0)
> for line in self.file:
> nextpos = self.file.tell()
> yield line
> self.file.seek(nextpos)

Hmm - I tried this with 'one.file' being just the lower case letters,
one per line:

class FileReIterable2(object):
def __init__(self, file):
if isinstance(file, basestring):
self.file = open(file, 'rU')
else:
self.file = file


def __iter__(self):
self.file.seek(0)
for line in self.file:
nextpos = self.file.tell()
yield line
self.file.seek(nextpos)


gen = FileReIterable2("one.file")

for a in gen:
for b in gen:
print "", a.strip(), b.strip()


gen = FileReIterable2("one.file")
for a in gen:
  for b in gen:
print a.strip(), b.strip()

which didn't produce lines 'a a', 'a b', etc. It produced the single
line 'a a', then stopped. A judicious proint or two showed that after
the first execution of 'for line in self.file:', the file pointer was
at EOF, not at 2, as one would expect.

Rewriting the __iter__ method to not internally iterate over the file
object, as follows, works - it now generates
a a
...
a z
b a
...
z z


class FileReIterable2(object):
def __init__(self, file):
self.file = open(file, 'rU')

def __iter__(self):
self.file.seek(0)
while True:
line = self.file.readline()
if line == '': raise StopIteration
nextpos = self.file.tell()
yield line
self.file.seek(nextpos)



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: An oddity in list comparison and element assignment

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
 <[EMAIL PROTECTED]> wrote:
>Hi Alex,
>With all due respect to your well-deserved standing in the Python
>community, I'm not convinced that equality shouldn't imply invariance
>under identical operations.
>
>Perhaps the most fundamental notion is mathematics is that the left and
>right sides of an equation remain identical after any operation applied
>to both sides.  Our experience of the physical world is similar.  If I
>make identical modifications to the engines of two identical
>automobiles, I expect the difference in performance to be identical.
>If my expectation is met, I would assert that either the two vehicles
>were not identical to begin with or that my modifications were not
>performed identically.
>
>As to containers,  would you say that envelope containing five $100
>bills is the same as an envelope containing a single $100 bill and 4
>xerox copies of it? If so, I'd like to engage in some envelope
>exchanges with you :-)
>
>As I see it, reference copying is a very useful performance and memory
>optimization.  But I don't think it should undermine the validity of
>assert(a==b) as a predictor of invariance under identical operations.

I think you end up with a totally unwieldy definition of '==' for
containers, since you have to check for _identical_ aliasing to
whatever depth it might occur, and, if you insist on equality
modeling the physical world, two lists can only be equal if:

for each corresponding element in the two lists, either the element is
a reference to the same underlying object or the corresponding
elements are references to objects which do not have and never will
have other references bound to them.

For example:

ra = ['a', 'a']
rb = ['b', 'b']

l1 = [ra, rb]
l2 = [ra, rb]

This will be equal by your definition and will preserve equality over
identical operations on l1 and l2

l3 = [ ['a', 'b'], ['a', 'b']]

This list will be identical, under your definition, so long as we
don't have anyone doing anything to the references ra or rb. Your
equality test has to claim that l1 and l3 are not equal, since ra
could be changed and that's not an operation on l1 or l3

This also leaves out the complexity of analysiing nested structures -
if you have a tuple, containing tuples which contain lists, then are
those top level tuples 'equal' if there are aliases in the lists? How
many levels deep should an equality test go? 

Does the more common test, to see if the elements of a sequence are
identical at the time of comparision need a new operator or hand
coding, since most of the time programmers aren't interested in future
equality or not of the structures.

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: An oddity in list comparison and element assignment

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
 <[EMAIL PROTECTED]> wrote:
>Yes. You stated it quite precisely.  I believe l1==l2 should always
>return True and l1==l3 should always be False. (unless l3 is reassigned
>as l3=l1).  Your idea of a separate operator for 'all elements have
>numerically equal values at the moment of comparision' is a good one.
>For want of a better name, it could be called DeepCopyEquality(a,b) and
>would be equivalent to a byte-by-byte comparison of two distinct
>regions in memory created by a deep copies of a and b.

The operator which works at the moment of comaprision is already there
- that's what == does. 
If you really think there's a need for a comparision which includes
dealing with aliasing, then it seems to me a python module with a
set of functions for comparisions would make more sense. 



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: grouping a flat list of number by range

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
 <[EMAIL PROTECTED]> wrote:
>hello,
>
>i'm looking for a way to have a list of number grouped by consecutive
>interval, after a search, for example :
>
>[3, 6, 7, 8, 12, 13, 15]
>
>=>
>
>[[3, 4], [6,9], [12, 14], [15, 16]]
>
>(6, not following 3, so 3 => [3:4] ; 7, 8 following 6 so 6, 7, 8 =>
>[6:9], and so on)
>
>i was able to to it without generators/yield but i think it could be
>better with them, may be do you an idea?

There are probably better ways, but this works

>
>best regards,
>
>J.

class IterInterval(object):
"""Create an iterator which, given a list of integers,
for each run of consecutive integers i...j, yields a two
element list [i, j + 1]

Singleton lists [i] return [i, i + 1]
Empty lists return None
"""
def __init__(self, seq):
self.seq = seq
self.firstval = None
self.index = 0

def __iter__(self):
# firstval = the start of a run of consecutive integers
# lastval = the last value found in the run
# nextval = the most recent value taken from the input list
if not self.firstval:
# set up the first iteration
if self.index >= len(self.seq):
# empty list, return
raise StopIteration
self.firstval = lastval = int(self.seq[self.index])
self.index += 1
while True:
if self.index >= len(self.seq):
# list exhausted, output the last value read
yield [self.firstval, lastval + 1]
raise StopIteration
nextval = int(self.seq[self.index])
self.index += 1
if nextval == lastval + 1:
lastval = nextval
continue
else:
# end of run - output the run, reset for next call
yield [self.firstval, lastval + 1]
self.firstval = lastval = nextval
continue

if __name__ == '__main__':
for l in [[3, 6, 7, 8, 12, 13, 15], [2], []]:
print l, "=>", [lst for lst in  IterInterval(l)]

/usr/home/jes% python interval.py 
[3, 6, 7, 8, 12, 13, 15] => [[3, 4], [6, 9], [12, 14], [15, 16]]
[3] => [[3, 4]]
[] => []



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: grouping a flat list of number by range

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paddy <[EMAIL PROTECTED]> wrote:
>=== interv2 ===
>>>> def interv2(inlist):
>...for i,val in enumerate(inlist):
>...if i==0:
>...tmp = val
>...elif val != valinc:
>...yield [tmp, valinc]
>... tmp = val
>...valinc = val+1
>...yield [tmp, valinc]
>...
>>>> list(interv2(inlist))
>[[3, 4], [6, 9], [12, 14], [15, 16]]
>
>=== END interv2 ===

This doesn't actually run, changing it to make it do so:

def interv2(inlist):
tmp = valinc = 0
for i,val in enumerate(inlist):
if i==0:
tmp = val
valinc = val + 1
elif val != valinc:
yield [tmp, valinc]
tmp = val
valinc = val+1
yield [tmp, valinc]

it now works, but returns [0, 0] when passed an empty list, when it
should return nothing at all





-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: grouping a flat list of number by range

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paddy <[EMAIL PROTECTED]> wrote:
>I did a little re-arranging of the generator version:
>
>def interv3(inlist):
>tmp = inlist[0]
>valinc = tmp+1
>for val in inlist[1:]:
>if val != valinc:
>yield [tmp, valinc];
>tmp = val
>valinc = val+1
>yield [tmp, valinc]

Still fails when passed an empty list, the initial assignment to tmp
is an IndexError




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: grouping a flat list of number by range

2006-06-01 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paddy <[EMAIL PROTECTED]> wrote:
>
>What I ran was more like the version below, but i did a quick
>separation of the line that has the ';' in it and goofed.
>
>>>> def interv2(inlist):
>...for i,val in enumerate(inlist):
>...if i==0:
>...tmp = val
>...elif val != valinc:
>...yield [tmp, valinc]; tmp = val
>...valinc = val+1
>...yield [tmp, valinc]
>... 
>>>> list(interv2(inlist))
>[[3, 4], [6, 9], [12, 14], [15, 16]]

Fails on an empty list, as tmp is not defined when it hits the yield


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: grouping a flat list of number by range

2006-06-02 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paddy <[EMAIL PROTECTED]> wrote:
>
>John Machin wrote:
>> On 2/06/2006 8:36 AM, Paddy wrote:
>
>>
>> Oh the siren call of every new feature in the language!
>> enumerate() just to get a first-time test, and then botch it??
>>
>> Read the following; the replacement version uses a simple old-fashioned
>> inelegant flag, works with an empty sequence, and doesn't depend on the
>> input being sliceable or indexable.
>>
>> HTH,
>> John
>>
>
>Thanks, un-botchable John. What if the poster doesn't send a null list?
>What if the correct result for a null list is "spam"; or an exception?
>What if ... we toned down the language?

I'd still rate Ben Cartwright's solution as the best. The one I posted
tried to do the same, but I didn't see the right way to iterate over
the supplied list inside the function, wheras he did. It's short,
simple and correct.

If you really wanted to return 'spam' or an exception in his solution,
it's a simple if statement at the start of the function.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: wxpython wxgrid question

2006-06-03 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
 <[EMAIL PROTECTED]> wrote:
>Hi,
>
>  I am looking for example code that consists of just a frame and a
>grid(10x2).  The grid must fill the its parent even if the frame is
>resized.

This simple program makes a two element window, the lower half of
which is a gridded set of labels which resize with the window. The
important part is the columnconfigure() and rowconfigure() method
calls on the container widget for the grid.
See 
http://infohost.nmt.edu/tcc/help/pubs/tkinter/grid-config.html>
http://infohost.nmt.edu/tcc/help/pubs/tkinter/grid-config.html

#!/usr/local/bin/python

from Tkinter import *

root = Tk()
# create a frame (unused, but shared with gridded frame)
f = Frame(height = 100)
f.pack(expand = YES, fill = BOTH)

# create a frame for a gridded display
gf = Frame()
gf.pack(expand = YES, fill = BOTH)

# create a 3 x 4 array of labels, each with a different background
# Make each row and column have equal weights, so they'll
# grow and shrink together
for row in range(3):
gf.rowconfigure(row, weight = 1)
for col in range(4):
gf.columnconfigure(col, weight = 1)
Label(gf, text = "Row: %d\nCol: %d" % (row, col),
  bg = "#%02x%02x%02x" % ((row * 4 + col) * 16,
  (row * 4 + col) * 16,
  (row * 4 + col) * 16),
  fg = "#ff"
  ).grid(row = row, column = col, sticky = NSEW)



root.mainloop()





-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Large Dictionaries

2006-06-05 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Tim Peters <[EMAIL PROTECTED]> wrote:
>[Scott David Daniels]
>>> For example, time timsort (Python's internal sort) on pre-sorted
>>> data; you'll find it is handled faster than random data.
>
>O(N) vs O(N log N), in fact.
>
>[Lawrence D'Oliveiro]
>> But isn't that how a reasonable sorting algorithm should behave? Less
>> work to do if the data is already sorted?
>
>For example, the O(N log N) heapsort is unreasonable compared to the
>O(N**2) bubblesort by that reasoning (pre-sorted is actually a bad
>case for heapsort, but a good case for bubblesort)?  O(N log N)
>sorting algorithms helped by pre-existing order are uncommon, unless
>they do extra work to detect and exploit pre-existing order.

Actually, presorted lists are not a bad case for heapsort - it's quite
immune to any existing order or lack thereof, whereas some other
sorts, quicksort being a prime example, require great care to
avoid pathological cases.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Large Dictionaries

2006-06-05 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Tim Peters <[EMAIL PROTECTED]> wrote:
>[Jim Segrave]
>> Actually, presorted lists are not a bad case for heapsort - it's quite
>> immune to any existing order or lack thereof,
>
>Write a heapsort and time it.  It's not a difference in O() behavior,
>but more memory movement is required for a sorted list because
>transforming the list into a max-heap at the start requires shuffling
>the largest elements from the end of the list to its start.  Initially
>reverse-sorted is a "good case" for heapsort in the same sense
>(because the list is already a max-heap then; initially sorted is as
>far from being a max-heap as is possible).  "good" and "bad" are both
>O(N log N) here, though.

I did implement a crude heapsort before posting this and measured the
number of comparisions and the number of swaps.

==

#!/usr/local/bin/python

import random

class HeapSorter(object):
def __init__(self, seq):
self.compares = 0
self.swaps = 0
self.length = len(seq)
self.seq = seq

def __sift(self, i):
while True:
j = 2 * i + 1
if j + 1 < self.length:
self.compares += 1
if self.seq[j + 1] > self.seq[j]:
j = j + 1
if j >= self.length:
return

self.compares += 1
if self.seq[i] > self.seq[j]:
return

self.swaps += 1
self.seq[i], self.seq[j] = (self.seq[j], self.seq[i])
i = j

def __makeheap(self):
for i in range(self.length / 2, -1, -1):
self.__sift(i)

def sort(self):
self.__makeheap()
for i in range(self.length - 1, -1, -1):
self.swaps += 1
self.seq[i], self.seq[0] = (self.seq[0], self.seq[i])
self.length -= 1
self.__sift(0)

if __name__ == '__main__':

s = list(range(10))
random.shuffle(s)

heap = HeapSorter(s)
heap.sort()
print "Random list: comapres %d, swaps %d" % \
  (heap.compares, heap.swaps)
heap = HeapSorter(s)
heap.sort()
print "Sorted list: comapres %d, swaps %d" % \
  (heap.compares, heap.swaps)

s.reverse()
heap = HeapSorter(s)
heap.sort()
print "Reverse Sorted list: comapres %d, swaps %d" % \
  (heap.compares, heap.swaps)

==

Which gave the following results:

/usr/home/jes% python ./heapsort
Random list: comapres 3019969, swaps 1575263
Sorted list: comapres 3112517, swaps 1650855
Reverse Sorted list: comapres 2926640, swaps 1497435

Assuming compares and swaps dominate other bookkeeping, then heapsort
is quite stable in its performance, although the constant in the O(N log N)
is much larger than for other sorts. 



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: locating strings approximately

2006-06-29 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Irmen de Jong  <[EMAIL PROTECTED]> wrote:
>BBands wrote:
>> I'd like to see if a string exists, even approximately, in another. For
>> example if "black" exists in "blakbird" or if "beatles" exists in
>> "beatlemania". The application is to look though a long list of songs
>> and return any approximate matches along with a confidence factor. I
>> have looked at edit distance, but that isn't a good choice for finding
>> a short string in a longer one. I have also explored
>> difflib.SequenceMatcher and .get_close_matches, but what I'd really
>> like is something like:
>> 
>> a = FindApprox("beatles", "beatlemania")
>> print a
>> 0.857
>> 
>> Any ideas?
>> 
>> jab
>> 
>
>I collected a few pointers in this article:
>
>http://www.razorvine.net/frog/user/irmen/article/2005-05-28/53
>
>It contains one or two additional methods besides the ones you mentioned.
>Sorry, it's in Dutch, but you can find the links without much trouble i guess.

For those who don't read Dutch, here's a translation of that page:



Python 

By fuzzy string comparision, I mean comparing two strings and getting
a result that indicates how similar the strings are to each
other. That is, it's not an absoulte string compaision (that only
tells if the two strings are absolutely the same or not), but a more
quantative string comparision.

It can be used to, for example, to remove typos from commands, a
specific form of spelling checker or for other natural language
processing.

Python has a few modules which offer a fuzzy string comparision.

—

QWERTY - or protein distances

Recently, BoB Hooft posted an interesting module in comp.lang.python
which uses an algorithm that is normally used for comparing proteins,
but now works for ASCII strings. The result is a float which is
negative if the strings are very different and increases up to
len(string) + 1 if the strings are identical, the score can be viewd
as 'the number of correspondingn letters'. The algorithm uses the
layout of the QWERTY keyboard to specifiy the distance between the
stings and therefore is restricted to ASCII strings (and only makes
sense if one uses a QWERTY keyboard), but therefor is very well suited
to compare an imput command with all the possible commands and thus to
identify typos. 

Why not use a normalised score between 0.0 and 1.0? 
Rob: It doesn't matter if you only want the 'best score' from a number
of strings. Negative results appear if the strings are not similar and
also don't even have the same length.

The module can be found here: : comparestrings.py
<http://starship.python.net/crew/hooft/comparestrings.py>.

*Python standard library*

In de standard lib hebben we difflib met de functie get_close_matches
<http://docs.python.org/lib/module-difflib.html#l2h-922>. Groot voordeel
dat deze dus standaard bij Python zit.

The standard library has difflib with the function get_close_matches
<http://docs.python.org/lib/module-difflib.html#l2h-922>. The big
advantage is that this is standard with Python.

*Febrl (biometrisch)*

Febrl <https://sourceforge.net/projects/febrl/> has a number of string
comparision functions, including the 'edit distance' or 'Levenshtein
distance' function. For the latter, there is an implementation on
Useless Python
<http://www.uselesspython.com/download.php?script_id=108>.

*Apse*

An extension module (written in C):  Apse
<http://www.personal.psu.edu/staff/i/u/iua1/python/apse/>. 

Requires python, SWIG, and a C compiler

*Java*

SecondString <http://sourceforge.net/projects/secondstring/> is an
open source package with Java implementations of a large number of
string comparision algorithms. They should not be too difficult to
port to Python.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Regular Expression - old regex module vs. re module

2006-06-30 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Steve <[EMAIL PROTECTED]> wrote:
>Hi All,
>
>I'm having a tough time converting the following regex.compile patterns
>into the new re.compile format.  There is also a differences in the
>regsub.sub() vs. re.sub()
>
>Could anyone lend a hand?
>
>
>import regsub
>import regex
>
>import re# << need conversion to this module
>
>
>
>"""Convert perl style format symbology to printf tokens.
>
>Take a string and substitute computed printf tokens for perl style
>format symbology.
>
>For example:
>
>###.##yields %6.2f
>  yields %8d
><<<<< yields %-5s
>"""

Perhaps not optimal, but this processes things as requested. Note that
all floats have to be done before any integer patterns are replaced.

==
#!/usr/local/bin/python

import re

"""Convert perl style format symbology to printf tokens.
Take a string and substitute computed printf tokens for perl style
format symbology.

For example:

###.##yields %6.2f
  yields %8d
<<<<< yields %-5s
"""


# handle cases where there's no integer or no fractional chars
floatPattern = re.compile(r'(?+)')

def float_sub(matchobj):
# fractional part may be in either groups()[1] or groups()[2]
if matchobj.groups()[1] is not None:
return "%%%d.%df" % (len(matchobj.groups()[0]),
 len(matchobj.groups()[1]))
else:
return "%%%d.%df" % (len(matchobj.groups()[0]),
 len(matchobj.groups()[2]))


def unperl_format(s):
changed_things = 1
while changed_things:
# lather, rinse and repeat until nothing new happens
changed_things = 0

mat_obj = leftJustifiedStringPattern.search(s)
if mat_obj:
s = re.sub(leftJustifiedStringPattern, "%%-%ds" %
   len(mat_obj.groups()[0]), s, 1)
changed_things = 1

mat_obj = rightJustifiedStringPattern.search(s)
if mat_obj:
s = re.sub(rightJustifiedStringPattern, "%%%ds" %
   len(mat_obj.groups()[0]), s, 1)
changed_things = 1

# must do all floats before ints
mat_obj = floatPattern.search(s)
if mat_obj:
s = re.sub(floatPattern, float_sub, s, 1)
changed_things = 1
# don't fall through to the int code
continue

mat_obj = integerPattern.search(s)
if mat_obj:
s = re.sub(integerPattern, "%%%dd" % len(mat_obj.groups()[0]),
   s, 1)
changed_things = 1
return s

if __name__ == '__main__':
   testarray = ["integer: , integer # integer at end #",
"float .## no decimals ###. no int .### at end ###.",
"Left string  <<<<<< short left string  <",
"right string >>>>>> short right string >",
"escaped chars \\ \\.## \\<\\<<<< \\>\\><<<"]


   for s in testarray:
   print("Testing: %s" % s)
   print "Result: %s" % unperl_format(s)
   print

==

Running this gives

Testing: integer: , integer # integer at end #
Result: integer: %4d, integer %1d integer at end %1d

Testing: float .## no decimals ###. no int .### at end ###.
Result: float %7.2f no decimals %4.0f no int %4.3f at end %4.0f

Testing: Left string  <<<<<< short left string  <
Result: Left string  %-6s short left string  %-1s

Testing: right string >>>>>> short right string >
Result: right string %6s short right string %1s

Testing: escaped chars \ \.## \<\<<<< \>\><<<
Result: escaped chars \#%3d \#%6.2f \<\<%-3s \>\>%-3s



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: string replace

2006-06-30 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Michele Petrazzo  <[EMAIL PROTECTED]> wrote:
>Hi,
>a lot of times I need to replace more than one char into a string, so I
>have to do something like
>
>value = "test"
>chars = "e"
>for c in chars:
>   value = value.replace(c, "")
>
>A solution could be that "replace" accept a tuple/list of chars, like
>that was add into the new 2.5 for startswith.
>
>I don't know, but can be this feature included into a future python release?

Let's say you want to make every vowel uppercase:

import string

trans_table = string.maketrans('aeiou', 'AEIOU')
"I don't know, but can be this feature included into".translate(trans_table)

prints:
"I dOn't knOw, bUt cAn bE thIs fEAtUrE InclUdEd IntO"

That more than addresses your requirements, as it can do multiple
character substitutions multiple times in one call.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Regular Expression - old regex module vs. re module

2006-06-30 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paul McGuire <[EMAIL PROTECTED]> wrote:

>Not an re solution, but pyparsing makes for an easy-to-follow program.
>TransformString only needs to scan through the string once - the
>"reals-before-ints" testing is factored into the definition of the
>formatters variable.
>
>Pyparsing's project wiki is at http://pyparsing.wikispaces.com.

If fails for floats specified as ###. or .###, it outputs an integer
format and the decimal point separately. It also ignores \# which
should prevent the '#' from being included in a format.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Regular Expression - old regex module vs. re module

2006-06-30 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paul McGuire <[EMAIL PROTECTED]> wrote:
>"Jim Segrave" <[EMAIL PROTECTED]> wrote in message
>news:[EMAIL PROTECTED]
>> In article <[EMAIL PROTECTED]>,
>> Paul McGuire <[EMAIL PROTECTED]> wrote:
>>
>> >Not an re solution, but pyparsing makes for an easy-to-follow program.
>> >TransformString only needs to scan through the string once - the
>> >"reals-before-ints" testing is factored into the definition of the
>> >formatters variable.
>> >
>> >Pyparsing's project wiki is at http://pyparsing.wikispaces.com.
>>
>> If fails for floats specified as ###. or .###, it outputs an integer
>> format and the decimal point separately. It also ignores \# which
>> should prevent the '#' from being included in a format.
>>
>Ah!  This may be making some sense to me now.  Here are the OP's original
>re's for matching.
>
>exponentPattern = regex.compile('\(^\|[^\\#]\)\(#+\.#+\*\*\*\*\)')
>floatPattern = regex.compile('\(^\|[^\\#]\)\(#+\.#+\)')
>integerPattern = regex.compile('\(^\|[^\\#]\)\(##+\)')
>leftJustifiedStringPattern = regex.compile('\(^\|[^\\<]\)\(<<+\)')
>rightJustifiedStringPattern = regex.compile('\(^\|[^\\>]\)\(>>+\)')
>
>Each re seems to have two parts to it.  The leading parts appear to be
>guards against escaped #, <, or > characters, yes?  The second part of each
>re shows the actual pattern to be matched.  If so:
>
>It seems that we *don't* want "###." or ".###" to be recognized as floats,
>floatPattern requires at least one "#" character on either side of the ".".
>Also note that single #, <, and > characters don't seem to be desired, but
>at least two or more are required for matching.  Pyparsing's Word class
>accepts an optional min=2 constructor argument if this really is the case.
>And it also seems that the pattern is supposed to be enclosed in ()'s.  This
>seems especially odd to me, since one of the main points of this funky
>format seems to be to set up formatting that preserves column alignment of
>text, as if creating a tabular output - enclosing ()'s just junks this up.
>

The poster was excluding escaped (with a '\' character, but I've just
looked up the Perl format statement and in fact fields always begin
with a '@', and yes having no digits on one side of the decimal point
is legal. Strings can be left or right justified '@<<<<', '@>>>>', or
centred '@', numerics begin with an @, contain '#' and may contain
a decimal point. Fields beginning with '^' instead of '@' are omitted
if the format is a numeric ('#' with/without decimal). I assumed from
the poster's original patterns that one has to worry about '@', but
that's incorrect, they need to be present to be a format as opposed to
ordinary text and there's appears to be no way to embed a '@' in an
format. It's worth noting that PERL does implicit float to int
coercion, so it treats @### the same for ints and floats (no decimal
printed).

For the grisly details:

http://perl.com/doc/manual/html/pod/perlform.html

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Regular Expression - old regex module vs. re module

2006-06-30 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Paul McGuire <[EMAIL PROTECTED]> wrote:
>"Jim Segrave" <[EMAIL PROTECTED]> wrote in message
>news:[EMAIL PROTECTED]
>
>I can see that the OP omitted the concept of "@|||" centering, since the
>Python string interpolation forms only support right or left justified
>fields, and it seems he is trying to do some form of format->string interp
>automation.  Adding centering would require not only composing a suitable
>string interp format, but also some sort of pad() operation in the arg
>passed to the string interp operation.  I suspect this also rules out simple
>handling of the '^' operator as mentioned in the spec, and likewise for the
>trailing ellipsis if a field is not long enough for the formatted value.
>
>The '@' itself seems to be part of the field, so "@<<<<" would be a 5
>column, left-justified string.  A bare '@' seems to be a single string
>placeholder (meaningless to ask right or left justified :) ), since this is
>used in the doc's hack for including a "@" in the output.  (That is, as you
>said, the original spec provides no mechanism for escaping in a '@'
>character, it has to get hacked in as a value dropped into a single
>character field.)
>
>The Perl docs say that fields that are too long are truncated.  This does
>not happen in Python string interps for numeric values, but it can be done
>with strings (using the precision field).
>>>> print "%-10s" % string.ascii_uppercase
>ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>>> print "%-10.10s" % string.ascii_uppercase
>ABCDEFGHIJ
>
>So if we were to focus on support for "@", "@>>>", "@<<<", "@###" and
>"@###.##" (with and without leading or trailing digits about the decimal)
>style format fields, this shouldn't be overly difficult, and may even meet
>the OP's requirements.  (The OP seemed to also want some support for
>something like "@##.###" for scientific notation, again, not a
>dealbreaker.)

One would need a much clearer spec on what the OP really wants to do - note
that` Perl formats have the variable names embeeded as part of the
format string, so writing a simple Perl->Python converter isn't going
to work,

I've given him a good start for an re based solution, you've given one
for a pyparsing based one, at this point I'd hope the OP can take it
from there or can come back with more specific questions on how to
deal with some of the awfulness of the formats he's working with.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Regular Expression - old regex module vs. re module

2006-07-01 Thread Jim Segrave
 containing a template or a
template itself. A misspelled file name won't raise
an error, it will simply be processed as a fixed output. I would have
passed a flag to say if the template argument was file name or a
template and terminated with an error if it was a non-existant file.

[SNIP]

>def _format( self, dataobj ):
>"""Return the values of the given data object substituted into
>the template format stored in this object.
>"""
># value[] is a list of lists of values from the dataobj
># body[] is the list of strings with %tokens to print
># if value[i] == None just print the string without the %
>argument
>s = ''
>value = []
>
>for i in range(self.nrows):
>value.append([])
>
>for i in range(self.nrows):
>for vname in self.vars[i]:
>try:
>if string.find(vname, '[') < 0:
># this is the nominal case and a simple get
>will be faster
>value[i].append(getattr(dataobj, vname))
>else:
># I use eval so that I can support sequence
>values
># although it's slow.
>value[i].append(eval('dataobj.'+vname))
>except AttributeError, SyntaxError:
>value[i].append('')

There's another way to do this - use getattr to retrieve the sequence,
then use __getitem__ to index it

Something like this would work, again using a regex to separate out
the index (you might want the regex compiled once at __init__
time). The regex looks for a run of characters valid in a python
variable name followed by an optional integer (with or without sign)
index in square brackets. m.groups()[0] is the variable name portion,
m.grousp()[1] is the index if there's a subscripting term.

 try:
   m = 
re.match(r'([a-zA-Z_][a-zA-Z0-9._]*)\s*(?:\[\s*([+-]?\d+)\s*\])?\s*',
 value[i])
   if not m: raise SyntaxError
   if m.groups()[1] is None:
  value[i].append(getattr(dataobj, vname))
   else:
  value[i].append(getattr(m.groups()[0]).\
 __getitem__(int(m.groups()[1])))
 except AttributeError, SyntaxError, IndexError:
>value[i].append('')

This is a bit ugly, but avoids eval with all the dangers it carries -
a deliberately hacked template file can be used to do a lot of damage,
a badly written one could be hard to debug

>if value[i][0] != '':
>try:
>temp_vals = []
>for item in value[i]:
># items on the list of values for this line
># can be either literals or lists
>        if type(item) == ListType:

Might you be better off asking if item has a __getitem__? It would
then work with tuples and Extending to dictionaries would then be easier

>def isReportTemplate(obj):
>"""Return 1 if obj is an instance of class ReportTemplate.
>"""
>if  type(obj) == InstanceType and \
>string.find(`obj.__class__` , ' ReportTemplate ') > -1:
>return 1
>else:
>return 0

Why not just use isinstance(obj, classname)?

>###
>#  ColumnReportTemplate   #
>###
>
>class ColumnReportTemplate:
>"""This class allows one to specify column oriented output formats.
>


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Can I do it using python?? about xterm and telnet

2006-07-02 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
valpa <[EMAIL PROTECTED]> wrote:
>I'm a net admin for about 20 unix servers, and I need to frequently
>telnet on to them and configure them.
>It is a tiring job to open a xterm and telnet, username, password to
>each server.

Don't use telnet. it's clumsy and has security issues.

Use ssh with RSA or DSA keys. Then you simply do:

ssh [EMAIL PROTECTED]

in an xterm and you are loggedis as user username on server
machinename. It's vastly more secure and more reliable. 

If you're talking about initial setup of a machine (OS installation or
whatever), our solution was to have a post-install CD or floppy which
fetched standard server configuration data. This included an ssh
public key for our ssh-key distribution, so after running the
post-install disc, we could push out staff ssh-keys and logins were
available.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: socket buffer flush question

2006-07-05 Thread Jim Segrave
ver, the printout after the machine recovers has some extra data at
>the end.  This is the data I want to flush out of the buffer, but I
>cant really figure out how to do so.

What I see is that you continued sending new commands while not
getting responses from the device. The device has received them, since
it acknowledges that it has seen up to byte 565 of your output. This
is not an unflushed buffer problem - the data has reached the TCP/IP
stack of the device and what happens to it next depends on the
application layer in the device. If it is reading and discarding
commands, then you have a problem that you have sent several commands
which won't receive replies. If the device's application works
correctly, it will continue to dequeue commands 12 bytes at a time and
send replies. If it reads whatever is available and only processes 12
bytes from the read, then the device end application is sub-optimal
and you will have to ensure you don't issue any new commands until the
previous command has been processed. Once you transfer data to your
machine's network stack, there's no way to stop it being sent to the
remote end - in fact there's no practical way to determine if it's
been put in a packet, sent to the remote end and lost or put in a
packet, sent to the remote end and is awaiting processing, or is
waiting to be put into a packet and hasn't left your machine at all. 

What happens if your application simply stops transmitting new
commands after a timeout? Do you eventually get all the responses in?

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: how can I avoid abusing lists?

2006-07-08 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Rob Cowie <[EMAIL PROTECTED]> wrote:
>Just forget the lists...
>
>counters = {0:0, 1:0, 2:0, 3:0, 4:0}
>
>def increment(value):
>counters[value] += 1
>
>increment(1)
>increment(1)
>increment(3)
>increment(4)
>
>print counters[0]
>>>> 0
>print counters[1]
>>>> 2
>print coutners[2]
>>>> 0
>print counters[3]
>>>> 1
>print coutners[4]
>>>> 1
>
>The increment function should probably include a try:...except:
>statement to catch KeyErrors that would arise if you passed a value
>that is not a key in the counters dictionary.
>
>Rob C
>

counters = {}
def increment(value):
counters[value] = counters.get(value, 0) + 1

increment(1)
increment(1)
increment(3)
increment(4)
increment('a string key')


keyz = counters.keys()
keyz.sort()
for k in keyz:
print k, counters[k]

Takes care of IndexError and ValueError. It does not report keys that
don't get incremented. If that's important, then initalise counters as
in the quoted posting.

For Python 2.4 and later, you can replace the keyz =
counts.keys()/keyz.sourt() for k in keyz: with

for k in sorted(counters.heys()):
   print k, counters[k]


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Detecting 64bit vs. 32bit Linux

2006-07-08 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
dwelch91  <[EMAIL PROTECTED]> wrote:
>I need to detect whether the operating system I am running on (not the 
>Python version) is 64bit or 32bit. One requirement is that I need to 
>include support for non-Intel/AMD architectures.
>
>The 2 ways I have thought detecting 64bit are:
>
>1. struct.calcsize("P") == 8
>2. '64' in os.uname()[4]
>
>I'm not convinced that either one of these is really adequate. Does 
>anybody have any other ideas on how to do this?

Does sys.maxint give what you need? 

I think for most machines this will give you the answer you are
looking for - either 2**31 -1 for a 32 bit version or 2**63-1 for a 64
bit version. It's set up during the configure phase of building python

If you want to detect a 64bit OS running a compatibility mode for a 32
bit version of Python, then you'll need to figure out how to build and
incorporate a Python extension which can detect this situation




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Augument assignment versus regular assignment

2006-07-10 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Antoon Pardon  <[EMAIL PROTECTED]> wrote:
>On 2006-07-09, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
>> Frank Millman wrote:
>>
>>> So it looks as if x +=  [] modifies the list in place, while x = x + []
>>> creates a new list.
>>
>> objects can override the += operator (by defining the __iadd__ method), 
>> and the list type maps __iadd__ to extend.  other containers may treat 
>> += differently, but in-place behaviour is recommended by the language
>> reference:
>>
>>An augmented assignment expression like x += 1 can be rewritten as
>>x = x + 1 to achieve a similar, but not exactly equal effect.  In
>>the augmented version, x is only evaluated once. Also, when possible,
>>the actual operation is performed in-place, meaning that rather than
>>creating a new object and assigning that to the target, the old object
>>is modified instead.
>
>What does it mean that x is only evaluated once.  I have an avltree module,
>with an interface much like a directory.  So I added print statements to
>__setitem__ and __getitem__ and then tried the following code.
>
>>>> from avltree import Tree
>>>> t=Tree()
>>>> t['a'] = 1
>__setitem__, key = a
>>>> t['a']
>__getitem__, key = a
>1
>>>> t['a'] = t['a'] + 1
>__getitem__, key = a
>__setitem__, key = a
>>>> t['a'] += 1
>__getitem__, key = a
>__setitem__, key = a
>>>> t['b'] = []
>__setitem__, key = b
>>>> t['b'] = t['b'] + [1]
>__getitem__, key = b
>__setitem__, key = b
>>>> t['b'] += [2]
>__getitem__, key = b
>__setitem__, key = b
>
>So to me it seems that when we substitute t['a'] or t['b'] for x,
>x is evaluated twice with the augmented version, just like it
>is with the not augmented version.

$ cat x.py

def getindex(ind = 0):
print 'getindex() called'
return ind

a = [0, 1, 2, 3, 4, 5]
a[getindex(0)] = a[getindex(0)] + 17
print a
a[getindex(1)] += 22
print a

$ python x.py
getindex() called
getindex() called
[17, 1, 2, 3, 4, 5]
getindex() called
[17, 23, 2, 3, 4, 5]

In this case, getindex() is a rather pointless function, but it could
be an expensive one or one with side effects or even one which alters
state, so that it gives different values on subsequent calls with the
same argument.

The += version finds the object to be operated upon once, the expanded
version does it twice.


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: re question

2006-07-10 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Schüle Daniel  <[EMAIL PROTECTED]> wrote:
>Hello,
>
>consider the following code
>
> >>> re.search("[a-z](?i)[a-z]","AA")
><_sre.SRE_Match object at 0x40177e20>
>
>this gives a match
>if we provide an extra group for the first character it still works
>
> >>> re.search("([a-z])(?i)[a-z]","AA").group(1)
>'A'
> >>>
>
>it doesn't matter where (?i) is placed, right?
>the re engine would glance at once on the entire pattern string
>analize it (complain if pattern doesn't make sense, eg invalid)
>and it would be the same as if the option was given expicitely
>as re.IGNORECASE.
>
>Is there a way to switch-off the option resp.
>switch-on the option in the middle of the pattern?

The docs say:

(?iLmsux)
(One or more letters from the set "i", "L", "m", "s", "u", "x".)
The group matches the empty string; the letters set the
corresponding flags (re.I, re.L, re.M, re.S, re.U, re.X) for the
 ^^^  
entire regular expression. This is useful if you wish to include
^

the flags as part of the regular expression, instead of passing a
flag argument to the compile() function.


Some regex packages, but not Python's, support (?-) and this
allows turning the flag off and on for parts of the regex.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Python vs C for a mail server

2006-01-28 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Ravi Teja <[EMAIL PROTECTED]> wrote:
>>> Why don't you use an existing mail server?
>
>Probably because that was his homework assignment for a networking
>class. Not uncommon to be told to implement a server from the scratch
>from the RFC. Although that does not explain his concern about
>performance.
>
>Abhinav, if that is the case, using sockets is more or less the same
>from any language. Python as usual will be cleaner than C. You might
>want to look at Twisted Mail. Use SocketServer module in the standard
>library to implement the RFC. Other than that it is silly to try to
>write a Mail Server unless you have some extra ordinary need.

Any lecturer assigning "write a mail server" as a class project is
doing his/her students a true dis-service. Mail server RFC compliance is a
nightmare to get right, performance issues and mail routeing are both
material for at least a full year's university study.

A student who tries to make an even vaguely RFC compliant mail server
probably won't finish their project, as student who completes such a
project might come away with the mistaken belief that they actually
have done it correctly. 

The number of software products which use eail and do so incorrectly
is astounding and depressing. There's a reason that the source for
sendmail is about 120K lines, exim is nearly 270K lines. Doing it
right is _hard_.





-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python vs C for a mail server

2006-01-29 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
abhinav <[EMAIL PROTECTED]> wrote:
>ya its supposed to be some stupid 6 month project which my friend has
>to do.I am just helping him out.he may not be implementing a full
>fledged rfc compliance mail server but may support some of the major
>functionalities.so basically its an extra ordinary need.I just wanted
>to know which language would be better for implementation and has
>faster development cycle.I have heard a lot about python and its ease
>of use.My point is it should be worth a 6 month project and speedy
>development since he is already proficient in C/C++ socket programming
>and taking the pain of learning python should be worth the effort.
>

In that case, you'll come closer to having a working mail server in
Python. I just hope that it's understood you won't have a mail server
which is ready to be used on the Internet for any but very limited
applications.


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python vs C for a mail server

2006-01-29 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Dan Lowe  <[EMAIL PROTECTED]> wrote:
>
>On Jan 28, 2006, at 8:39 PM, Dennis Lee Bieber wrote:
>
>> On Sat, 28 Jan 2006 18:03:56 +1100, Steven D'Aprano said:
>>>
>>> Google is your friend. The first four mail servers listed are, in  
>>> order:
>>>
>>> sendmail
>>> postfix
>>> Microsoft Exchange
>>> qmail
>>>
>>  Dig a bit deeper, and exim might be a candidate for the list. I'm
>> pretty sure O'Reilly has books for sendmail, postfix, and exim; don't
>> know about qmail.
>
>O'Reilly does have an Exim book, but it is out of date. It covers the  
>3.x family, while 4.x has been out for quite a while now. The 4.x  
>family is very different from 3.x, so the book isn't worth a whole  
>lot these days.
>
>I'm on my second major mail system deployment built around Exim, and  
>would recommend it to anybody needing a robust, flexible mail server.

There is an exim 4 book out, but not via O'Reilly - I gather sales
were insufficient to persuade O'Reilly to do an update. As we use Exim
heavily, we have both the 3 and 4 books in our NOC, as well as sending
almost all new staff to Phil Hazel's excellent courses in Cambridge.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: MySQLdb question... using table name as arg

2006-02-03 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Sean Berry <[EMAIL PROTECTED]> wrote:
>I have four tables that all have the same column names (50 in each.)
>
>I have created an admin program to edit, delete and add records to the 
>tables and would like to use the table name as a variable in each query so 
>the code can be used for each of the 4 tables.  Usually I would do something 
>like this by having 1 table with special column to categorize the records as 
>I am doing with each table, but this specific application requires that I do 
>it with 4 tables instead.
>
>To ensure that string are quoted properly without any hassle I use the 
>execute function like so assuming c is my cursor object...
>
>c.execute("update tableName set col1 = %s, col2 = %s, col3 = %s, ...", 
>(val1, val2, val3, ...))
>
>But, not I want to do this with a variable tableName.  If I add it to the 
>tuple of parameters in the second arg before val1 and replace tableName with 
>%s, then the tableName will be quoted in the query, causing an error.
>
>What is the best (easiest) way for me to accomplish this?  I know it may be 
>a stupid question but I just can't figure it out.

How about interpolating the table name into the string:

c.execute("update %s set col1 = %%s, col2 = %%s, col3=%%s" % (sometable), \
  ['the', 'cat', 'in the hat'])

Note the need to double the %'s for the parameters to be bound.




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 'error reading datastream' -- loading file only when transfer is complete?

2006-05-20 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Andrew Robert  <[EMAIL PROTECTED]> wrote:
>[EMAIL PROTECTED] wrote:
>> hello --
>> 
>> i'm running python/pygame on maemo (nokia 770). my situation is that
>> i'm continually scouring this one directory for incoming files. if i
>> see if there's a new file (coming in via wireless scp), i proceed to
>> load it and process it.
>> 
>> however, i think i am running into the issue that my program starts to
>> load the file after it recognises there is new data, but before the
>> file has completely transferred, so at unpredictable times i get a
>> pygame.error: Error reading from datastream.
>> 
>> what is the easiest way to work out this issue? easy being the key
>> word. :) thank you very much!
>> 
>> christine
>> 
>
>You might want to test for file locking before attempting to use


Or, really crude - when you see the file, record the time and the file
size, but don't attempt to process it yet. Wait for a short interval,
then check the size again. If it's changed, wait again. When it gives
the same size after a delay period, assume all the data is there. 

This isn't a good method, but it's simple to implement and will reduce
the occurrence of attempts to process a file which is still in
transit/

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: buffers readlines and general popen2 confusion...

2006-05-20 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
[EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
>I'm interested in taking the output of a daemonized shell script that
>greps for patterns which would act as an argument to a script. Is it
>better to write this stuff to file and visit the file every few seconds
>or can this be done a better way. I'm hoping for a more elegant
>solution. So far I've seen some troubling info about buffer overflows
>with popen2 but it looks like the low-hanging fruit. I'm not a unixpro
>so I want to make sure anything I tackle is best practice. Suggestions
>welcomed.

I'm puzzled - a daemonised program normally closes stdin/stdout/stderr
and disconnects from its controlling terminal, so where is its output
going? 




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: regex in python

2006-05-25 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
gisleyt <[EMAIL PROTECTED]> wrote:
>I'm trying to compile a perfectly valid regex, but get the error
>message:
>
> r =
>re.compile(r'([^\d]*)(\d{1,3}\.\d{0,2})?(\d*)(\,\d{1,3}\.\d{0,2})?(\d*)?.*')
>Traceback (most recent call last):
>  File "", line 1, in ?
>  File "/usr/lib/python2.3/sre.py", line 179, in compile
>return _compile(pattern, flags)
>  File "/usr/lib/python2.3/sre.py", line 230, in _compile
>raise error, v # invalid expression
>sre_constants.error: nothing to repeat
>>>>
>
>What does this mean? I know that the regex
>([^\d]*)(\d{1,3}\.\d{0,2})?(\d*)(\,\d{1,3}\.\d{0,2})?(\d*)?.*
>is valid because i'm able to use it in Regex Coach. But is Python's
>regex syntax different that an ordinary syntax?

Your problem lies right near the end:

>>> import re
>>> r = re.compile(r'(\d*)?')
Traceback (most recent call last):
  File "", line 1, in ?
  File "/usr/local/lib/python2.4/sre.py", line 180, in compile
return _compile(pattern, flags)
  File "/usr/local/lib/python2.4/sre.py", line 227, in _compile
raise error, v # invalid expression
sre_constants.error: nothing to repeat

Since the term \d* can be matched by the empty string, what would it
mean to ask for 0 or 1 copies of the empty string? How is that
different from 17 copies of the empty string.  

So:
r =
re.compile(r'([^\d]*)(\d{1,3}\.\d{0,2})?(\d*)(\,\d{1,3}\.\d{0,2})?(\d*).*')

will be accepted.

>By the way, i'm using it to normalise strings like:
>
>London|country/uk/region/europe/geocoord/32.3244,42,1221244
>to:
>London|country/uk/region/europe/geocoord/32.32,42,12
>
>By using \1\2\4 as replace. I'm open for other suggestions to achieve
>this!

But you're looking for a string followed by two floats and your sample
input is a string, a float, an integer, a comma and another
integer. If you actually mean the input is

London|country/uk/region/europe/geocoord/32.3244,42.1221244

and you want to convert it to:

London|country/uk/region/europe/geocoord/32.32,42.12

then the above regex will work

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: hi,everyone. a problem with shelve Module

2006-05-26 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
softwindow <[EMAIL PROTECTED]> wrote:
[some context restored]
>> Sometimes you add records but the size of the database does not  
>> change... :-)
>really
>
>in which case?

whenever the database is big enough to add them without it's having to
grow :)




-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: time series calculation in list comprehension?

2006-03-12 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
falcon <[EMAIL PROTECTED]> wrote:
>Is there a way I can do time series calculation, such as a moving
>average in list comprehension syntax?  I'm new to python but it looks
>like list comprehension's 'head' can only work at a value at a time.  I
>also tried using the reduce function and passed in my list and another
>function which calculates a moving average outside the list comp. ...
>but I'm not clear how to do it.  Any ideas?  Thanks.

I used the following to return an array of the average of the last n
values -it's not particularly pretty, but it works

# set number of values to average
weighting = 10

# an array of values we want to calculate a running average on
ratings = []
# an array of running averages
running_avg = []

# some routine to fill ratings with the values
r = random.Random()
for i in range(0, 20):
  ratings.append(float(r.randint(0, 99)))

for i in range(1, 1 + len(ratings)):
  if i < weighting:
running_avg.append(ratings[i - 1])
  else:
running_avg.append(reduce(lambda s, a: s+ a,
  ratings[i - weighting : i]) /
   len(ratings[i - weighting : i]))

for i in range(0, len(ratings)):
print "%3d: %3d %5.2f" % (i, ratings[i], running_avg[i])


sample output:
  0:  34 34.00
  1:  28 28.00
  2:  58 58.00
  3:  16 34.00
  4:  74 44.00
  5:  32 45.00
  6:  74 49.00
  7:  21 50.25
  8:  78 51.25
  9:  28 50.25
 10:  32 39.75
 11:  93 57.75
 12:   2 38.75
 13:   7 33.50
 14:   8 27.50
 15:  30 11.75
 16:   1 11.50
 17:   8 11.75
 18:  40 19.75
 19:   8 14.25

For all but the first 3 rows, the third column is the average of the
values in the 2nd column for this and the preceding 3 rows. 



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: put multiple condition in if statement

2006-03-12 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Dennis Lee Bieber  <[EMAIL PROTECTED]> wrote:
>On 10 Mar 2006 21:12:57 -0800, [EMAIL PROTECTED] declaimed the
>following in comp.lang.python:
>
>> How can I put multiple condition in if statement?
>>
>   Lesson one: Python is NOT C
> 
>> I try this, but I can't get that to work.
>> 
>> if ( (str != " ") && (str != "") ):
>
>   Lesson two: an empty (aka, null) string is "false", and a non-empty
>string is "true", so that gives us
>
>   Lesson three: " " is not equal to "  " or "" so you
>might want to do strip whitespace first...
>
>>>> "" == " "
>False
>>>> " " == "  "
>False
>>>> "".strip() == "  ".strip()
>True
>>>> 
>
>   So... Your mixed C/Python simplifies to just...
>
>   if str.strip(): # after removing leading/trailing spaces, 
>   # if not empty, do something

str = " "
and
str = "\t" 
fail with your substitution - the OP was looking only for strings
containing one space or empty strings. Tab characters and multi-spaces
would not match. 

-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Server.sendmail with no "to_addrs" parameter.

2006-03-22 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Dennis Lee Bieber  <[EMAIL PROTECTED]> wrote:
>On 22 Mar 2006 08:31:16 -0800, "EdWhyatt" <[EMAIL PROTECTED]>
>declaimed the following in comp.lang.python:
>
>> So it's a restriction of Python?
>>
>   RFC822 is the /standard/ (well, there are newer versions -- 2822?)
>for email... It is not Python specific.
> 
>> What I am trying to simulate here is the sending of mail to addresses
>> solely in the CC and/or BCC fields - both of which are possible through
>> Outlook.
>
>   Technically, then -- Outlook is in violation of the standard (you
>expected Microsoft to be following standards?)

RFC822 and its followup 2822 do not require a To: address line in the
headers - rfc2822 has the minimum number listed as 0

There is a difference between the SMTP time recipient address list
(RCPT TO:) which detemines what the receiving MTA should do with the
message and the email header To:/CC:/Bcc: lines, which don't (or
should not in any working system) affect mail routing at all. You
can't get mail delivered via SMTP without a RCPT TO command at SMTP
time. Many programs extract this address, in the absence of some other
means of specifying it, by taking the addresses from the To:, CC: and
Bcc: headers, but that's a programming convenience, not an RFC
requirement. Since most people composing emails would find it annoying
to have to enter the RCPT TO addresses separately, the message
composition builds header lines, then sends the message to an MTA
using those addresses. But consider bouncing a mail - then the
desintation for SMTP is the address you are bouncing the mail to, and
the header lines are unchanged (one hopes, if not, replace your mail client)

Much as it pains me to admit it, Outlook, for all its many faults is
correct if it allows sending messages where the To: CC: and or Bcc:
headers are empty.


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Server.sendmail with no "to_addrs" parameter.

2006-03-22 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
Jeffrey Froman  <[EMAIL PROTECTED]> wrote:
>EdWhyatt wrote:
>
>> But are you serious about that RFC Compliant thing?
>
>RFC 2822 obsoletes RFC 822, and I don't know of any specification in RFC
>2822 that requires an email address to be present in the To: header. My
>mail seems to generally work fine without a To: header.
>
>I haven't memorized RFC 2822 though, so you may want to read it yourself if
>you're concerned ;-)
>

>From RFC 2822:

   The following table indicates limits on the number of times each
   field may occur in a message header as well as any special
   limitations on the use of those fields.  An asterisk next to a
   value
   in the minimum or maximum column indicates that a special
   restriction
   appears in the Notes column.

Field   Min number  Max number  Notes
...
to  0   1

cc  0   1

bcc 0   1

...


So the answere is, that it's not required to have any destinations
listed in the headers of the message.

It appears that it's not kosher to have an empty To: header, though
I think that few MUAs will balk at this


-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to create a tear off menu in TKinter. Help Needed

2006-04-06 Thread Jim Segrave
In article <[EMAIL PROTECTED]>,
ishtar2020 <[EMAIL PROTECTED]> wrote:
>Hi everybody
>
>I'd appreciate some help on creating a tear off menu with TkInter. I've
>been reading some documentation but still no luck.
>
>Please don't get confused: when I mean "tear off" menu I don't mean a
>drop-down or a pop-up menu, but those options which yield to another
>batch of sub-options when scrolled over, (as for example, the File->New
>option from internet explorer).
>
>I'm sure TkInter supports those widgets because the IDLE editor is
>built on it and it's got some tear off options like File->Recent Files.

I created an extension for Tkinter which allows for popup menus (onesl
which appear when a parent menu item is under the cursor and close if
you then move away). It was an early experiment for me with Tkinter,
so I'm sure it can be heavily improved. It's available on 

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442500

(see the notes, the demonstration program doesn't work correctly on
Windows, because I forgot the directory separator is a  '\'. But the
code itself works to create cascading auto-pop-up menus, or any other
widget you want to pop-up as part of a menu.



-- 
Jim Segrave   ([EMAIL PROTECTED])

-- 
http://mail.python.org/mailman/listinfo/python-list