Python Module Exposure

2005-07-07 Thread Jacob Page
I have created what I think may be a useful Python module, but I'd like 
to share it with the Python community to get feedback, i.e. if it's 
Pythonic.  If it's considered useful by Pythonistas, I'll see about 
hosting it on Sourceforge or something like that.  Is this a good forum 
for exposing modules to the public, or is there somewhere 
more-acceptable?  Does this newsgroup find attachments acceptable?

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


Re: Python Module Exposure

2005-07-07 Thread Jacob Page
Robert Kern wrote:

> Jacob Page wrote:
> 
>> I have created what I think may be a useful Python module, but I'd 
>> like to share it with the Python community to get feedback, i.e. if 
>> it's Pythonic.  If it's considered useful by Pythonistas, I'll see 
>> about hosting it on Sourceforge or something like that.  Is this a 
>> good forum for exposing modules to the public, or is there somewhere 
>> more-acceptable?  Does this newsgroup find attachments acceptable?
> 
> No. Please put files somewhere on the web and post a URL. This would be 
> a good forum to informally announce and discuss your module. Formal 
> announcements once you, e.g. put it on SF should go to c.l.py.announce .

Thanks for the information, Robert.  Anyway, here's my informal 
announcement:

The iset module is a pure Python module that provides the ISet class and 
some helper functions for creating them. Unlike Python sets, which are 
sets of discrete values, an ISet is a set of intervals. An ISet could, 
for example, stand for all values less than 0, all values from 2 up to, 
but not including 62, or all values not equal to zero. ISets can also 
pertain to non-numeric values.

ISets can be used in much the same way as sets. They can be or'ed, 
and'ed, xor'ed, added, subtracted, and inversed. Membership testing is 
done the same as with a set. The documentation has some examples of how 
to create and use ISets.

The iset module is for Python 2.4 or later.

I am seeking feedback from programmers and mathematicians on how to 
possibly make this module more user-friendly, better-named, 
better-documented, better-tested, and more Pythonic.  Then, if this 
module is considered acceptable by the community, I'll create a more 
permanent home for this project.

To download the iset module and view its pydoc-generated documentation, 
please visit http://members.cox.net/apoco/iset/.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Polling, Fifos, and Linux

2005-07-07 Thread Jacob Page
Jeremy Moles wrote:
> This is my first time working with some of the more lower-level python
> "stuff." I was wondering if someone could tell me what I'm doing wrong
> with my simple test here?
> 
> Basically, what I need is an easy way for application in userspace to
> simply echo values "down" to this fifo similar to the way proc files are
> used. Is my understanding of fifo's and their capabilities just totally
> off base?

You shouldn't need to use select.poll(), unless I'm missing something. 
I was able to get the following to work:

-=-=-

import os

fifo = os.open("fifo", os.O_RDONLY | os.O_NONBLOCK)

while True:
 string = os.read(fifo, 1)
 if len(string):
 print string
 # Perhaps add a delay under an else

-=-=-

The Python script, when run, does nothing until you put data into the 
fifo from another process.  Then it immediately spits the data out, 
character by character.

I'm assuming that you've already created the fifo and that it's in the 
current working directory.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Module Exposure

2005-07-08 Thread Jacob Page
Thomas Lotze wrote:
> Jacob Page wrote:
> 
>>better-named,
> 
> Just a quick remark, without even having looked at it yet: the name is not
> really descriptive and runs a chance of misleading people. The example I'm
> thinking of is using zope.interface in the same project: it's customary to
> name interfaces ISomething.

I've thought of IntervalSet (which is a very long name), IntSet (might 
be mistaken for integers), ItvlSet (doesn't roll off the fingers), 
ConSet, and many others.  Perhaps IntervalSet is the best choice out of 
these.  I'd love any suggestions.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Module Exposure

2005-07-09 Thread Jacob Page
George Sakkis wrote:
> 1. As already noted, ISet is not really descriptive of what the class
> does. How about RangeSet ? It's not that long and I find it pretty
> descriptive. In this case, it would be a good idea to change Interval
> to Range to make the association easier.

The reason I decided not to use the term Range was because that could be 
confused with the range function, which produces a discrete set of 
integers.  Interval isn't a term used in the standard/built-in library, 
AFAIK, so I may stick with it.  Is this sound reasoning?

> 2. The module's "helper functions" -- which are usually called factory
> functions/methods because they are essentially alternative constructors
> of ISets -- would perhaps better be defined as classmethods of ISet;
> that's a common way to define instance factories in python. Except for
> 'eq' and 'ne', the rest define an ISet of a single Interval, so they
> would rather be classmethods of Interval. Also the function names could
> take some improvement; at the very least they should not be 2-letter
> abbreviations. Finally I would omit 'eq', an "interval" of a single
> value; single values can be given in ISet's constructor anyway. Here's
> a different layout:

First, as far as having the factory functions create Interval instances 
(Range instances in your examples), I was hoping to avoid Intervals 
being publically "exposed."  I think it's cleaner if the end-programmer 
only has to deal with one object interface.

I like the idea of lengthening the factory function names, but I'm not 
sure that the factory methods would be better as class methods. 
Consider a use-case:

 >>> import iset
 >>> interval = iset.ISet.lowerThan(4)

as opposed to:

 >>> import iset
 >>> interval = iset.lowerThan(4)

This is less typing and probably eliminates some run-time overhead.  Can 
you list any advantages of making the factory functions class methods?

> class Range(object): # Interval
> 
> @classmethod
> def lowerThan(cls, value, closed=False):
> # lt, for closed==False
> # le, for closed==True
> return cls(None, False, value, closed)
> 
> @classmethod
> def greaterThan(cls, value, closed=False):
> # gt, for closed==False
> # ge, for closed==True
> return cls(value, closed, None, False)
> 
> @classmethod
> def between(cls, min, max, closed=False):
> # exInterval, for closed==False
> # incInterval, for closed==True
> return cls(min, closed, max, closed)

I like the function names, but in my dialect, lessThan would be more proper.

> class RangeSet(object):  # ISet
> 
> @classmethod
> def allExcept(cls, value): # ne
> return cls(Range.lowerThan(value), Range.greaterThan(value))
> 
> 3. Having more than one names for the same thing is good to be avoided
> in general. So keep either "none" or "empty" (preferably "empty" to
> avoid confusion with None) and remove ISet.__add__ since it is synonym
> to ISet.__or__.

I agree that "none" should be removed.  However, some programmers may 
prefer to use +, some |, so I'd like to provide both.

> 4. Intervals shouldn't be comparable; the way __cmp__ works is
> arbitrary and not obvious.

I agree that __cmp__ is being used arbitrarily.  I wanted sorting to be 
easy, but there's other ways of doing that.  I'll take your suggestion.

> 5. Interval.adjacentTo() could take an optional argument to control
> whether an endpoint is allowed to be in both ranges or not (e.g.
> whether (1,3], [3, 7] are adjacent or not).

Interval objects weren't meant to be public; adjacentTo is used by ISet 
for combinatory functions.  I could look into ways to hide the class 
from the public, but hiding things never seemed Pythonic to me; someone 
may want to use them for some reason.  Maybe pydoc can be made to not 
document certain objects.

> 6. Possible ideas in your TODO list:
> - Implement the whole interface of sets for ISet's so that a client
> can use either or them transparently.

That was my intention.  I'll have to see which interface functions I'm 
missing.

> - Add an ISet.remove() for removing elements, Intervals, ISets as
> complementary to ISet.append().
> - More generally, think about mutable vs immutable Intervals and
> ISets. The sets module in the standard library will give you a good
> idea of  the relevant design and implementation issues.

Both good ideas.

> After I look into the module's internals, I'll try to make some changes
> and send it back to you for feedback.

Thanks for your feedback, George.  I look forward to any additional 
comments you come up with.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Module Exposure

2005-07-09 Thread Jacob Page
George Sakkis wrote:
> "Jacob Page" <[EMAIL PROTECTED]> wrote:
> 
>>George Sakkis wrote:
>>
>>>1. As already noted, ISet is not really descriptive of what the class
>>>does. How about RangeSet ? It's not that long and I find it pretty
>>>descriptive. In this case, it would be a good idea to change Interval
>>>to Range to make the association easier.
>>
>>The reason I decided not to use the term Range was because that could be
>>confused with the range function, which produces a discrete set of
>>integers.  Interval isn't a term used in the standard/built-in library,
>>AFAIK, so I may stick with it.  Is this sound reasoning?
> 
> Yes, it is not unreasonable; I can't argue strongly against Interval.
> Still I'm a bit more in favor of Range and I don't think it is
> particularly confusing with range() because:
> 1. Range has to be either qualified with the name of the package (e.g.
> rangesets.Range) or imported as "from rangesets import Range", so one
> cannot mistake it for the range builtin.
> 2. Most popular naming conventions use lower first letter for functions
> and capital for classes.
> 3. If you insist that only RangeSet should be exposed from the module's
> interface and Range (Interval) should be hidden, the potential conflict
> between range() and RangeSet is even less.

Those are pretty good arguments, but after doing some poking around on 
planetmath.org and reading 
http://planetmath.org/encyclopedia/Interval.html, I've now settled on 
Interval, since that seems to be the proper use of the term.

>>>2. The module's "helper functions" -- which are usually called factory
>>>functions/methods because they are essentially alternative constructors
>>>of ISets -- would perhaps better be defined as classmethods of ISet;
>>>that's a common way to define instance factories in python. Except for
>>>'eq' and 'ne', the rest define an ISet of a single Interval, so they
>>>would rather be classmethods of Interval. Also the function names could
>>>take some improvement; at the very least they should not be 2-letter
>>>abbreviations.
>>
>>First, as far as having the factory functions create Interval instances
>>(Range instances in your examples), I was hoping to avoid Intervals
>>being publically "exposed."  I think it's cleaner if the end-programmer
>>only has to deal with one object interface.
> 
> First off, the python convention for names you intend to be 'private'
> is to prefix them with a single underscore, i.e. _Interval, so it was
> not obvious at all by reading the documentation that this was your
> intention. Assuming that Interval is to be exposed, I  found
> Interval.lowerThan(5) a bit more intuitive than
> IntervalSet.lowerThan(5). The only slight problem is the 'ne'/
> allExcept factory which doesn't return a continuous interval and
> therefore cannot be a classmethod in Interval.

If the factories resided in separate classes, it seems like they might 
be less convenient to use.  I wanted these things to be easily 
constructed.  Maybe a good compromise is to implement lessThan and 
greaterThan in both Interval and IntervalSet.

> On whether Interval should be exposed or not: I believe that interval
> is a useful abstraction by itself and has the important property of
> being continuous, which IntervalSet doesn't. 

Perhaps I should add a boolean function for IntervalSet called 
continuous (isContinuous?).

Having a simple
> single-class interface is a valid argument, but it may turn out to be
> restricted later. For example, I was thinking that a useful method of
> IntervalSet would be an iterator over its Intervals:
> for interval in myIntervalSet:
> print interval.min, interval.max

I like the idea of allowing iteration over the Intervals.

> There are several possible use cases where dealing directly with
> intervals would be appropriate or necessary, so it's good to have them
> supported directly by the module.

I think I will keep Interval exposed.  It sort of raises a bunch of 
hard-to-answer design questions having two class interfaces, though. 
For example, would Interval.between(2, 3) + Interval.between(5, 7) raise 
an error (as it currently does) because the intervals are disjoint or 
yield an IntervalSet, or should it not even be implemented?  How about 
subtraction, xoring, and anding?  An exposed class should have a more 
complete interface.

I think that IntervalSet.between(5, 7) | IntervalSet.between(2, 3) is 
more intuitive than IntervalSet(Interval.between(5, 7), 
Interval.between(2, 3)), but I can understand the reverse.  I think I'll

Re: Python Module Exposure

2005-07-09 Thread Jacob Page
George Sakkis wrote:
> "Jacob Page" <[EMAIL PROTECTED]> wrote:
> 
>>I think I will keep Interval exposed.  It sort of raises a bunch of
>>hard-to-answer design questions having two class interfaces, though.
>>For example, would Interval.between(2, 3) + Interval.between(5, 7) raise
>>an error (as it currently does) because the intervals are disjoint or
>>yield an IntervalSet, or should it not even be implemented?  How about
>>subtraction, xoring, and anding?  An exposed class should have a more
>>complete interface.
>>
>>I think that IntervalSet.between(5, 7) | IntervalSet.between(2, 3) is
>>more intuitive than IntervalSet(Interval.between(5, 7),
>>Interval.between(2, 3)), but I can understand the reverse.  I think I'll
>>just support both.
> 
> As I see it, there are two main options you have:
> 
> 1. Keep Intervals immutable and pass all the responsibility of
> combining them to IntervalSet. In this case Interval.__add__ would have
> to go. This is simple to implement, but it's probably not the most
> convenient to the user.
> 
> 2. Give Interval the same interface with IntervalSet, at least as far
> as interval combinations are concerned, so that Interval.between(2,3) |
> Interval.greaterThan(7) returns an IntervalSet. Apart from being user
> friendlier, an extra benefit is that you don't have to support
> factories for IntervalSets, so I am more in favor of this option.

I selected option one; Intervals are immutable.  However, this doesn't 
mean that __add__ has to go, as that function has no side-effects.  The 
reason I chose option one was because it's uncommon for a mathematical 
operation on two objects to return a different type altogether.

> Another hard design problem is how to combine intervals when
> inheritance comes to play. Say that you have FrozenInterval and
> FrozenIntervalSet subclasses. What should "Interval.between(2,3) |
> FrozenInterval.greaterThan(7)" return ?

For now, operations will return mutable instances.  They can always be 
frozen later if needs be.
-- 
http://mail.python.org/mailman/listinfo/python-list


ANN: interval module 0.2.0 (alpha)

2005-07-09 Thread Jacob Page
After some feedback from this newsgroup, I've updated and renamed the 
iset module to the interval module.  Many of the names within the module 
have also changed, and I've refactored a lot of the code.  The updated 
version can be found at http://members.cox.net/apoco/interval/, as well 
as a change log.

Again, any suggestions would be greatly appreciated.  I especially want 
to sort out big design-level changes first.  Then I can upgrade the 
project status to beta and try to keep interface compatibility intact.

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


Re: Python Module Exposure

2005-07-09 Thread Jacob Page
George Sakkis wrote:
> "Jacob Page" <[EMAIL PROTECTED]> wrote:
> 
>>I selected option one; Intervals are immutable.  However, this doesn't
>>mean that __add__ has to go, as that function has no side-effects.  The
>>reason I chose option one was because it's uncommon for a mathematical
>>operation on two objects to return a different type altogether.
> 
> Mathematically what you described corresponds to sets that are not
> closed under some operation and it's not uncommon at all; a few
> examples are:
> - The set of integers is not closed under division: int / int ->
> rational
> - The set of real numbers is not closed under square root: sqrt(real)
> -> complex
> - The set of positive number is not closed under subtraction:
> pos_number - pos_number -> number
> - And yes, the set of intervals is not closed under union.

Yes, but I wasn't talking about mathematical operations in general; I 
was talking about mathematical operations in Python.  Example: 6 / 5 
doesn't yield a float (though I heard that might change in future 
versions).  If the union of two integers yielded a set of integers, then 
it'd make more since for the union of two Intervals to yield an 
IntervalSet.  But it doesn't.  Just as set([2, 6]) creates a set of two 
integers, IntervalSet(Interval(...), Interval(...)) creates a set of two 
intervals.

> On another note, I noticed you use __contains__ both for membership and
> is-subset queries. This is problematic in case of Intervals that have
> other Intervals as members. The set builtin type uses __contains__  for
> membership checks and issubset for subset checks (with __le__ as
> synonym); it's good to keep the same interface.

Good catch.  I think I've made similar mistakes for a few of the other 
functions, too.

Thanks for your help.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python Module Exposure

2005-07-10 Thread Jacob Page
George Sakkis wrote:
> "Jacob Page" <[EMAIL PROTECTED]> wrote:
> 
>>If the union of two integers yielded a set of integers, then
>>it'd make more since for the union of two Intervals to yield an
>>IntervalSet.
> 
> AFAIK union is defined over sets, not numbers, so I'm not sure what you
> mean by the "union of two integers". What I'm saying is that while the
> union of two intervals is always defined (since intervals are sets),
> the result set is not guaranteed to be an interval. More specifically,
> the result is an interval if and only if the intervals overlap, e.g.
> (2,4] | [3,7] = (2,7]
> but
> (2,4] | [5,7] = { (2,4], [5,7] }
> That is, the set of intervals is not closed under union. OTOH, the set
> of intervals _is_ closed under intersection; intersecting two
> non-overlapping intervals gives the empty interval.

OK, you've convinced me now to support and, or, and xor between every 
combination of Intervals and IntervalSets, Intervals and IntervalSets, 
and IntervalSets and Intervals.  However, I'm not sure I  like the idea 
of an operation generating either one type or another.  Thus, I'll have 
| and ^ operations between Intervals always return an IntervalSet 
instead of returning either an IntervalSet or an Interval.  & will 
return an Interval.  I suppose that means I should just have + do a 
union and - return an IntervalSet.  It will just have to be documented 
which types are to be expected for the return values depending on the 
operands.
-- 
http://mail.python.org/mailman/listinfo/python-list


set and frozenset unit tests?

2005-07-11 Thread Jacob Page
I have released interval-0.2.1 at 
http://members.cox.net/apoco/interval/.  IntervalSet and 
FrozenIntervalSet objects are now (as far as I can tell) functionality 
equivalent to set and frozenset objects, except they can contain 
intervals as well as discrete values.

Though I have my own unit tests for verifying this claim, I'd like to 
run my code through actual set and frozenset unit tests.  Does any such 
code exist?  Is it in pure Python?  If so, where can it be obtained?

Oh, and again, I'd really appreciate additional feedback on the module, 
especially related to design, if you've got any.  My goal for this 
project is to make the classes built-in-data-type quality.

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


Re: set and frozenset unit tests?

2005-07-12 Thread Jacob Page
Reinhold Birkenfeld wrote:
> Jacob Page wrote:
> 
>>I'd like to 
>>run my code through actual set and frozenset unit tests.  Does any such 
>>code exist?  Is it in pure Python?  If so, where can it be obtained?
> 
> Look at /usr/lib/python2.x/test/ (on unix platforms).

Thanks for pointing that to me.  For some reason, the Debian package for 
python 2.4 doesn't include those tests, but I acquired them from an 
alternative source.

Oye, there's quite a number of set and frozenset features that aren't 
well-documented that I now need to implement.  What a fun chore!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: set and frozenset unit tests?

2005-07-14 Thread Jacob Page
Steven Bethard wrote:
> Jacob Page wrote:
> 
>> Oye, there's quite a number of set and frozenset features that aren't 
>> well-documented that I now need to implement.  What a fun chore!
> 
> It would be a great help if you could submit appropriate documentation 
> patches for the areas you don't think are well-documented:

Hmm, after closer scrutiny, I'm not sure if the documentation really 
does need modification.  The largest incompatibility between IntervalSet 
and set was that my code wasn't enforcing hashability, and that property 
of sets actually IS documented.  However, there are two minor things I 
don't see documented that caught me by surprise:

* Since the <=, <, >, and >= operators raise an exception if the 
right-hand operand is not a set or frozenset,  it seemed reasonable to 
me to assume that == and != should, too.  However, the test suite for 
sets expect the comparisons to be allowed; == between a set and non-set 
return False, != returns True.  Seems inconsistent with the rest of the 
operators, but then again, the odd use of > and < for purposes other 
than ordering also seems strange.

* Apparently, if fs is a frozenset instance, fs.copy() returns a 
reference to fs instead of a copy of fs, and frozenset(fs) does the 
same.  The unit tests also ensure that subclasses of frozenset don't do 
this.  It makes sense that it's done that way to save on storage space, 
but it's not documented that this happens.

Both issues seem to be pretty minor unless you're making functionally 
equivalent classes.  I'm sure neither one will confuse someone into 
using them improperly, so I think it's fine to leave the docs alone.

By the way, IntervalSet and FrozenIntervalSet, when used in place of set 
and frozenset, now pass most of the tests.  One notable difference 
between them is that whereas sets can contain any hashable object, 
IntervalSet elements must be both hashable and orderable (implement 
__cmp__).  Thus, commands like IntervalSet([FrozenIntervalSet(...)]) 
fail, unlike set([frozenset(...)]).

I've also changed the methods with mixedCase capitalization to 
lower_case_with_underscores, as recommended by PEP 8.

Version 0.2.2 of the module can now be downloaded from 
http://members.cox.net/apoco/interval/.  I'm about to freeze the 
interfaces and transition the module to beta, so if you have any 
interest in the project or design change ideas, please send feedback soon.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Compiling a Python File on Mac OS X Tiger

2005-07-26 Thread Jacob Page
Asad Habib wrote:
> Hello. I am working on Tiger and wanted to find out how to compile a
> Python (.py) file into a .pyc file and then into a .pyo file. Can the
> compilation be achieved within the interpreter? Also, I am
> new to Python and wanted to know the difference between .pyc and .pyo
> files. Is this comparison similar to C? Any help would be appreciated.
> Thanks.

http://www.network-theory.co.uk/docs/pytut/tut_48.html has some good 
explanations.  To generate the .pyo files from the interpreter, add the 
-O option.

The difference between .pyc and .pyo files is that .pyo files are 
optimized a bit; for example docstrings are removed (which will break 
pydoc tests).  According to the above link, .pyo files don't run any 
faster; they just load faster.
-- 
http://mail.python.org/mailman/listinfo/python-list