Re: New Ordered Dictionery to Criticise

2005-12-02 Thread Fuzzyman
Hello Bengt,

Bengt Richter wrote:
 On 1 Dec 2005 03:38:37 -0800, Fuzzyman [EMAIL PROTECTED] wrote:

 
 Fuzzyman wrote:
  Sorry for this hurried message - I've done a new implementation of out
  ordered dict. This comes out of the discussion on this newsgroup (see
  blog entry for link to archive of discussion).
 
  See the latest blog entry to get at it :
  http://www.voidspace.org.uk/python/weblog/index.shtml
 
 
 Hello all,
 
 I've just done a new beta 2 version. It has a full version of
 FancyODict with the custome callable sequence objects for keys,
 values and items. They are almost completely covered by tests.
 
 You can download the new(er) version from :
 http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=odictbeta2.py
 
 Ran my tests on it: this one may be of interest:
  __ entrypoint: test_popitem 
 ___

  def test_popitem():
  d = CandidateDict([(k,i*100) for i,k in enumerate('abcde')])
 assert d.popitem() == ('e', 400)

  [C:\pywk\ut\test\test_odicts.py:228]
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
 _ _
  ...
  ...
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
 _ _

  def __getattr__(self, name):
  
  Implemented so that access to ``sequence`` raises a warning.

   d = OrderedDict()
   d.sequence
  []
  
  if name == 'sequence':
  warn('use of sequence attribute is deprecated. Use keys method '
  'instead.', DeprecationWarning)
  # NOTE: Still (currently) returns a direct reference. Need to
  #   because code that uses sequence will expect to be able to
  #   mutate it in place.
  return self._sequence
  else:
  # NOTE: strictly unnecessary, but it raises the appropriate error
 getattr(self, name)

  [c:\pywk\clp\odictbeta2.py:309]
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
 _ _
  Recursion detected (same locals  position)
  
 !!!
  = tests finished: 19 passed, 9 failed in 1.57 seconds 
 =


Yep the line :

getattr(self, name)

is a bug.

I've replaced it now (not yet published) with
object.__getattr__(self, name)
It could equally just be replaced with a raise AttributeError

You've picked up on another typo in the code, whichis odd because
``popitem`` is tested.

Oh well - works now.

[snip..]
 You can currently alter the order (of keys, values *and* items) by
 passing an iterable into those methods.
 I'm playing this game, but I wonder how much of it really makes sense ;-)


Can you explain what you mean ?


 
 Someone has suggested that this smells bad - and it ought to be
 done through separate `setkeys``, ``setvalues``, and ``setitems``
 methods.
 
 I'm *inclined* to agree, but I don't feel strongly about it. Anyone
 else got any opinions ?
 I don't see a big difference. What's important, if you ask me, is
 whether you get an idea of what will happen when you pass the iterable as
 an argument. OTTOMH that suggests that keys/values/items[slice] = iterable
 have more expectation-generating precedent, and in fact perhaps should define
 what is to happen if no other constraints are violated.

Don't completely follow.

Are you saying that

d = OrderedDict(some_iterable)
d.keys[slice] = iterable

is more *understandable*  (expectation-generating precedent WTF) ?

The alternative being : d.keys(iterable)

In which case I'm inclined to agree. *However* - having custom objects
for items/keys/values is undoubtably less efficient.

Therefore I'm supplying two classes OrderedDict and FancyODict (name
not yet fixed).

OrderedDict needs a way of changing the keys - so it needs either

d.keys(iterable)

*or*

d.setkeys(iterable)

Which is preferable, is my question.

I think you're saying you don't care :-)
In which case I will leave it as it presently is.

 
 * ``repr`` ought to return a value that ``eval`` could use to turn back
 into an OrderedDict.
 
 I have actually done an implementation of this, but it would mean
 that *all* the doctests need to be changed. I *will* do this at some
 point.
 Point in favor of py.test's separation of test/tested I guess.


Probably. :-)

doctest is part of the standard library - which is a point in it's
favour.


 
 * Slice assignment.
 
 The semantics for slice assignment are fiddly.
 
 For example, what do you do if in a slice assignment a key collides
 with an existing key ?
 IMO, a slice defines the sliced-out as well as the untouched, and I think
 it is an error to collide with the unouched part, since it requires either
 modifying the untouched or ignoring incoming slice data.
 Incoming can go by the rules of a plain dict constuctor, except preserving 
 order,
 and the rest should really 

Re: New Ordered Dictionery to Criticise

2005-12-01 Thread Fuzzyman

Fuzzyman wrote:
 Sorry for this hurried message - I've done a new implementation of out
 ordered dict. This comes out of the discussion on this newsgroup (see
 blog entry for link to archive of discussion).

 See the latest blog entry to get at it :
 http://www.voidspace.org.uk/python/weblog/index.shtml


Hello all,

I've just done a new beta 2 version. It has a full version of
FancyODict with the custome callable sequence objects for keys,
values and items. They are almost completely covered by tests.

You can download the new(er) version from :
http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=odictbeta2.py

Full discussion of the remaining issues below, or at :
http://www.voidspace.org.uk/python/weblog/arch_d7_2005_11_26.shtml#e147

Progress on the updated implementation of dict continues. (I hestitate
to say *new* version, as it's just a heavy makeover for the old code -
which was basically sound).

``FancyODict`` is now a full implementation of an Ordered Dictionary,
with custom *callable sequence objects* for ``keys``, ``values``, and
``items``. These can be called like normal methods, but can also be
accessed directly as sequence objects. This includes assigning to,
indexing, and slicing - as well as all the other relevant sequence
methods. {sm;:-)}

I've also added an optional index to ``OrderedDict.popitem``.

I'm sure there are lots of ways this can be optimised for efficiency -
but the new objects have got pretty full test coverage.

You can download the new version (for testing) from `odict Beta 2
http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=odictbeta2.py`_

The following issues still remain :

* ``FancyOdict`` is a separate class from ``OrderedDict``.

Because this version is *undoubtably* less efficient than
OrderedDict, my current thinking is that I should leave them separate
(and have both available). Being able to operate on the
keys/values/items as sequences is for convenience only.

Anyone got a suggestion for a better name than ``FancyODict`` ?

* You can no longer access the key order directly. The old ``sequence``
attribute is depracated and will eventually go away.

You can currently alter the order (of keys, values *and* items) by
passing an iterable into those methods.

Someone has suggested that this smells bad - and it ought to be
done through separate `setkeys``, ``setvalues``, and ``setitems``
methods.

I'm *inclined* to agree, but I don't feel strongly about it. Anyone
else got any opinions ?

* ``repr`` ought to return a value that ``eval`` could use to turn back
into an OrderedDict.

I have actually done an implementation of this, but it would mean
that *all* the doctests need to be changed. I *will* do this at some
point.

* Slice assignment.

The semantics for slice assignment are fiddly.

For example, what do you do if in a slice assignment a key collides
with an existing key ?

My current implementation does what an ordinary dictionary does,
the new value overwrites the previous one. This means that the
dictionary can reduce in size as the assignment progresses. {sm;:?}

I think this is preferable to raising an error and preventing
assignment. It does prevent an optimisation whereby I calculate the
indexes of all the new items in advance.

It also means you can't rely on the index of a key from a slice
assignment, unless you know that there will be no key collisions.

 In general I'm *against* preventing programmers from doing things,
so long as the documentation carries an appropriate warning.

An example will probably help illustrate this :

.. raw:: html

{+coloring}

d = OrderedDict()
d[1] = 1
d[2] = 2
d[3] = 3
d[4] = 4
d.keys()
[1, 2, 3]

# fetching every other key
# using an extended slice
# this actually returns an OrderedDict
d[::2]
{1: 1, 3: 3}

# we can assign to every other key
# using an ordered dict
d[::2] = OrderedDict([(2, 9), (4, 8)])
len(d) == 4
False

d
{2: 9, 4: 8}


Because of the key collisions the length of
d has changed - it now only has two keys instead
of four.


   {-coloring}


 Criticism solicited (honestly) :-)

 We (Nicola Larosa and I) haven't yet made any optimisations - but there
 are two implementations to play with.

 One allows you to access the keys attribute as if it was a sequence (as
 well as a method).

 All the best,
 
 Fuzzyman
  http://www.voidspace.org.uk/python/index.shtml

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


Re: New Ordered Dictionery to Criticise

2005-12-01 Thread Bengt Richter
On 1 Dec 2005 03:38:37 -0800, Fuzzyman [EMAIL PROTECTED] wrote:


Fuzzyman wrote:
 Sorry for this hurried message - I've done a new implementation of out
 ordered dict. This comes out of the discussion on this newsgroup (see
 blog entry for link to archive of discussion).

 See the latest blog entry to get at it :
 http://www.voidspace.org.uk/python/weblog/index.shtml


Hello all,

I've just done a new beta 2 version. It has a full version of
FancyODict with the custome callable sequence objects for keys,
values and items. They are almost completely covered by tests.

You can download the new(er) version from :
http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=odictbeta2.py

Ran my tests on it: this one may be of interest:
 __ entrypoint: test_popitem ___

 def test_popitem():
 d = CandidateDict([(k,i*100) for i,k in enumerate('abcde')])
assert d.popitem() == ('e', 400)

 [C:\pywk\ut\test\test_odicts.py:228]
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
 ...
 ...
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

 def __getattr__(self, name):
 
 Implemented so that access to ``sequence`` raises a warning.  

  d = OrderedDict()
  d.sequence
 []
 
 if name == 'sequence':
 warn('use of sequence attribute is deprecated. Use keys method '
 'instead.', DeprecationWarning)
 # NOTE: Still (currently) returns a direct reference. Need to
 #   because code that uses sequence will expect to be able to
 #   mutate it in place.
 return self._sequence
 else:
 # NOTE: strictly unnecessary, but it raises the appropriate error
getattr(self, name)

 [c:\pywk\clp\odictbeta2.py:309]
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
 Recursion detected (same locals  position)
 !!!
 = tests finished: 19 passed, 9 failed in 1.57 seconds =

Full discussion of the remaining issues below, or at :
http://www.voidspace.org.uk/python/weblog/arch_d7_2005_11_26.shtml#e147

Progress on the updated implementation of dict continues. (I hestitate
to say *new* version, as it's just a heavy makeover for the old code -
which was basically sound).

``FancyODict`` is now a full implementation of an Ordered Dictionary,
with custom *callable sequence objects* for ``keys``, ``values``, and
``items``. These can be called like normal methods, but can also be
accessed directly as sequence objects. This includes assigning to,
indexing, and slicing - as well as all the other relevant sequence
methods. {sm;:-)}

I've also added an optional index to ``OrderedDict.popitem``.

I'm sure there are lots of ways this can be optimised for efficiency -
but the new objects have got pretty full test coverage.

You can download the new version (for testing) from `odict Beta 2
http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=odictbeta2.py`_

The following issues still remain :

* ``FancyOdict`` is a separate class from ``OrderedDict``.

Because this version is *undoubtably* less efficient than
OrderedDict, my current thinking is that I should leave them separate
(and have both available). Being able to operate on the
keys/values/items as sequences is for convenience only.

Anyone got a suggestion for a better name than ``FancyODict`` ?

* You can no longer access the key order directly. The old ``sequence``
attribute is depracated and will eventually go away.

You can currently alter the order (of keys, values *and* items) by
passing an iterable into those methods.
I'm playing this game, but I wonder how much of it really makes sense ;-)


Someone has suggested that this smells bad - and it ought to be
done through separate `setkeys``, ``setvalues``, and ``setitems``
methods.

I'm *inclined* to agree, but I don't feel strongly about it. Anyone
else got any opinions ?
I don't see a big difference. What's important, if you ask me, is
whether you get an idea of what will happen when you pass the iterable as
an argument. OTTOMH that suggests that keys/values/items[slice] = iterable
have more expectation-generating precedent, and in fact perhaps should define
what is to happen if no other constraints are violated.

* ``repr`` ought to return a value that ``eval`` could use to turn back
into an OrderedDict.

I have actually done an implementation of this, but it would mean
that *all* the doctests need to be changed. I *will* do this at some
point.
Point in favor of py.test's separation of test/tested I guess.


* Slice assignment.

The semantics for slice assignment are fiddly.

For example, what do you do if in a slice assignment a key collides
with an existing key ?
IMO, a slice defines 

Re: New Ordered Dictionery to Criticise

2005-11-29 Thread Fuzzyman

Martin v. Löwis wrote:
 Fuzzyman wrote:
  Criticism solicited (honestly) :-)

 A couple of minor points:
 - I would drop 2.2 compatibility

There are a lot of cheap hosting accounts where Python 2.2 is all that
is available. I would only drop support if there is some *compelling*
reason to do so.

 - self=self isn't needed in the functions, because of
nested scopes

Cool, I'll test this out.

 - popitem(self) can be rewritten as

def popitem(self):
try:
key = self._sequence.pop()
except IndexError:
# always try to give the same exception string as
# dict
raise KeyError(popitem(): dictionary is empty)
return key, self.pop(key)


Yup, that's nicer - thanks.

 - One problem with the FancyDict is that it allows
d.keys.append(100)

Are you sure ?

No file given.
Alias   System Command
--
cls cls
copycopy
ddirdir /ad /on
dir dir /on
echoecho
ldirdir /ad /on
ls  dir /on
mkdir   mkdir
ren ren
rmdir   rmdir
--
Total number of aliases: 10
Movable Python
IPython Interactive Shell. See the manual for a list of features and
tips.
Ctrl-D to exit.

 from odict import FancyODict
 d = FancyODict()
 d
  Out[3]:{}

 d.keys
-- d.keys()
   Out[4]:[]

 d.keys.append('anything')
---
exceptions.TypeError Traceback (most
recent call
 last)

\configobj4\pythonutils\odict.py in append(self, item)
713 def __iadd__(self, other): raise TypeError('Can\'t add in
place to keys')
714 def __imul__(self, n): raise TypeError('Can\'t multiply
keys in place')
-- 715 def append(self, item): raise TypeError('Can\'t append
items to keys')
716 def insert(self, i, item): raise TypeError('Can\'t insert
items into keys')
717 def pop(self, i=-1): raise TypeError('Can\'t pop items from
keys')

TypeError: Can't append items to keys



All the best,

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

 
 Regards,
 Martin

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


Re: New Ordered Dictionery to Criticise

2005-11-29 Thread Fuzzyman

Christoph Zwerschke wrote:
 Fuzzyman wrote:
  Sorry for this hurried message - I've done a new implementation of out
  ordered dict. This comes out of the discussion on this newsgroup (see
  blog entry for link to archive of discussion).

 Thanks. I'll try to check it out and put my oar in over the next
 weekend.

Cool, thanks.

Someone has commented on my blog that passing lists to ``keys``,
``values``, and ``items`` to assign to them smells funny.

They've suggested new methods ``setkeys``, ``setitems``, ``setvalues``
instead. Any opinions ?

 One thing I already noticed: str() and repr() both output the
 OrderedDict as if it was an ordinary dictionary. For str() this may be
 acceptable, but repr() should output a valid Python expression that
 could be used to recreate an object with the same value.


Yup. If you look in the code, there is already a commented out version
of ``__repr__`` that does this.

*Unfortunately*, it means changing *all* the doctests - so it will have
to wait until one of us can be bothered. :-)

It  will happen in the course of time I guess.

All the best,


Fuzzyman
http://www.voidspace.org.uk/python/index.shtml

 -- Christoph

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


Re: New Ordered Dictionery to Criticise

2005-11-29 Thread Martin v. Löwis
Fuzzyman wrote:
- One problem with the FancyDict is that it allows
   d.keys.append(100)
 
 
 Are you sure ?

Not at all. This was from inspection only; I propably
misinterpreted the code.

Regards,
Martin
-- 
http://mail.python.org/mailman/listinfo/python-list


New Ordered Dictionery to Criticise

2005-11-28 Thread Fuzzyman
Sorry for this hurried message - I've done a new implementation of out
ordered dict. This comes out of the discussion on this newsgroup (see
blog entry for link to archive of discussion).

See the latest blog entry to get at it :
http://www.voidspace.org.uk/python/weblog/index.shtml

Criticism solicited (honestly) :-)

We (Nicola Larosa and I) haven't yet made any optimisations - but there
are two implementations to play with.

One allows you to access the keys attribute as if it was a sequence (as
well as a method).

All the best,

Fuzzyman
 http://www.voidspace.org.uk/python/index.shtml

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


Re: New Ordered Dictionery to Criticise

2005-11-28 Thread Martin v. Löwis
Fuzzyman wrote:
 Criticism solicited (honestly) :-)

A couple of minor points:
- I would drop 2.2 compatibility
- self=self isn't needed in the functions, because of
   nested scopes
- popitem(self) can be rewritten as

   def popitem(self):
   try:
   key = self._sequence.pop()
   except IndexError:
   # always try to give the same exception string as
   # dict
   raise KeyError(popitem(): dictionary is empty)
   return key, self.pop(key)

- One problem with the FancyDict is that it allows
   d.keys.append(100)

Regards,
Martin

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


RE: New Ordered Dictionery to Criticise

2005-11-28 Thread Delaney, Timothy (Tim)
Martin v. Löwis wrote:

 A couple of minor points:
 - I would drop 2.2 compatibility

Unfortunately, there are a *lot* of systems out there where only 2.2 is support 
(Red Hat 3.0 anyone?).

I know we'd like to be able to not support earlier versions (yes, I saw today's 
messages on the djgpp port) but I think where it's not too arduous it's 
worthwhile.

From my quick scan, that's pop().

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


Re: New Ordered Dictionery to Criticise

2005-11-28 Thread Christoph Zwerschke
Fuzzyman wrote:
 Sorry for this hurried message - I've done a new implementation of out
 ordered dict. This comes out of the discussion on this newsgroup (see
 blog entry for link to archive of discussion).

Thanks. I'll try to check it out and put my oar in over the next 
weekend. One thing I already noticed: str() and repr() both output the 
OrderedDict as if it was an ordinary dictionary. For str() this may be 
acceptable, but repr() should output a valid Python expression that 
could be used to recreate an object with the same value.

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