comp.lang.python - 25 new messages in 15 topics - digest
comp.lang.python
http://groups.google.com/group/comp.lang.python?hl=en
comp.lang.python@googlegroups.com
Today's topics:
* Don't work __getattr__ with __add__ - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.python/t/b3ba794a11708e9b?hl=en
* Draft PEP on RSON configuration file format - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/09ce33197b330e90?hl=en
* My four-yorkshireprogrammers contribution - 7 messages, 2 authors
http://groups.google.com/group/comp.lang.python/t/dea5c94f3d058e26?hl=en
* case do problem - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.python/t/d73f6f6a59d3bbfd?hl=en
* taking python enterprise level?... - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/3dca28b82d10655c?hl=en
* Adding to a module's __dict__? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/40837c4567d64745?hl=en
* Queue peek? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/ba3cb62c81d4cb7a?hl=en
* Pylint Argument number differs from overridden method - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/12977374ae8461dc?hl=en
* Partly erratic wrong behaviour, Python 3, lxml - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/cc11fa023e436ad5?hl=en
* A "scopeguard" for Python - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/8c752e871801c223?hl=en
* Method / Functions - What are the differences? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/72ab93ba395822ed?hl=en
* Working group for Python CPAN-equivalence? - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.python/t/c2c452cc4aaa6e98?hl=en
* Generic singleton - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/9228a3763eb552b3?hl=en
* memory usage, temporary and otherwise - 1 messages, 1 author
http://groups.google.com/group/comp.lang.python/t/da72d362a5b77618?hl=en
* Interest check in some delicious syntactic sugar for "except:pass" - 1
messages, 1 author
http://groups.google.com/group/comp.lang.python/t/b493c6208ea724a2?hl=en
==============================================================================
TOPIC: Don't work __getattr__ with __add__
http://groups.google.com/group/comp.lang.python/t/b3ba794a11708e9b?hl=en
==============================================================================
== 1 of 3 ==
Date: Thurs, Mar 4 2010 12:25 am
From: Андрей Симурзин
It is object of the class A, in conteiner's class tmpA. Not all method
from A are in the tmpA. So for exapmle:
A + B -- yes , tmpA + B no. I try to call method from A for tmpA. I
can to call simple method, such as change(), bit __add__ - don't
work. If to remove inheritance from object, the code work's. Help me,
please
#--------------------------------------
class A(object):
def __init__( self, x, y ):
self.x = x
self.y = y
pass
#-------
def __add__( self, arg ):
tmp1 = self.x + arg.x
tmp2 = self.y + arg.y
return tmpA( A( tmp1, tmp2 ) )
def change( self, x, y ):
self.x = x
self.y = y
pass
pass
#------------------------------------------
class tmpA( object ):
def __init__( self, theA ):
self.A = theA
pass
#-------
def __call__( self ):
return self.A
#-------
def __coerce__( self, *args ):
return None
#-------
def __getattr__( self, *args ):
name = args[ 0 ]
try:
attr = None
exec "attr = self.__call__().%s" % name
return attr
except :
raise AttributeError
#--------------------------------------
class B( object ):
def __init__( self, x, y):
self.x = x
self.y = y
pass
#-------------------------------------
a=A( 1,2 )
b=B( 3,4 )
tmp_a = a + b #well
tmp_a.change( 0, 0 ) # very well !!!
v = tmp_a + b #TypeError: "unsupported operand type(s) for +: 'tmpA'
and 'B'"
== 2 of 3 ==
Date: Thurs, Mar 4 2010 12:38 am
From: Chris Rebert
On Thu, Mar 4, 2010 at 12:25 AM, Андрей Симурзин <asimurzin@gmail.com> wrote:
> It is object of the class A, in conteiner's class tmpA. Not all method
> from A are in the tmpA. So for exapmle:
> A + B -- yes , tmpA + B no. I try to call method from A for tmpA. I
> can to call simple method, such as change(), bit __add__ - don't
> work. If to remove inheritance from object, the code work's. Help me,
> please
Some clarity has been lost in translation, but I think I get what you're saying.
__add__ and the other double-underscore special methods are not looked
up using __getattr__ or __getattribute__, hence trying to do addition
on tmpA, which does not define an __add__ method, fails.
For a full explanation, read:
http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes
Cheers,
Chris
--
http://blog.rebertia.com
== 3 of 3 ==
Date: Thurs, Mar 4 2010 12:54 am
From: Andrey Simurzin
On 4 мар, 11:38, Chris Rebert <c...@rebertia.com> wrote:
> On Thu, Mar 4, 2010 at 12:25 AM, Андрей Симурзин <asimur...@gmail.com> wrote:
> > It is object of the class A, in conteiner's class tmpA. Not all method
> > from A are in the tmpA. So for exapmle:
> > A + B -- yes , tmpA + B no. I try to call method from A for tmpA. I
> > can to call simple method, such as change(), bit __add__ - don't
> > work. If to remove inheritance from object, the code work's. Help me,
> > please
>
> Some clarity has been lost in translation, but I think I get what you're saying.
> __add__ and the other double-underscore special methods are not looked
> up using __getattr__ or __getattribute__, hence trying to do addition
> on tmpA, which does not define an __add__ method, fails.
>
> For a full explanation, read:http://docs.python.org/reference/datamodel.html#special-method-lookup...
>
> Cheers,
> Chris
> --http://blog.rebertia.com
Thank you very much
==============================================================================
TOPIC: Draft PEP on RSON configuration file format
http://groups.google.com/group/comp.lang.python/t/09ce33197b330e90?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 12:52 am
From: Paul Rubin
mk <mrkafk@gmail.com> writes:
> OK, but how? How would you make up e.g. for JSON's lack of comments?
Modify the JSON standard so that "JSON 2.0" allows comments.
> OTOH, if YAML produces net benefit for as few as, say, 200 people in
> real world, the effort to make it has been well worth it.
Not if 200,000 other people have to deal with it but don't receive the
benefit.
> http://myarch.com/why-xml-is-bad-for-humans
> http://www.ibm.com/developerworks/xml/library/x-sbxml.html
You might like this one too:
http://www.schnada.de/grapt/eriknaggum-xmlrant.html
>
> I also have to maintain a few applications that internally use XML as
> data format: while they are tolerable, they still leave smth to be
> desired, as those applications are really slow for larger datasets,
I thought we were talking about configuration files, not "larger datasets".
> There are demonstrable benefits to this too: I for one am happy that
> ReST is available for me and I don't have to learn a behemoth such as
> DocBook to write documentation.
DocBook is so far off my radar I'd have never thought of it. I just now
learned that it's not Windows-only. There is already POD, Pydoc,
Texinfo, a billion or so flavors of wiki markup, vanilla LaTeX, and most
straightforwardly of all, plain old ascii. ReST was another solution in
search of a problem.
==============================================================================
TOPIC: My four-yorkshireprogrammers contribution
http://groups.google.com/group/comp.lang.python/t/dea5c94f3d058e26?hl=en
==============================================================================
== 1 of 7 ==
Date: Thurs, Mar 4 2010 2:01 am
From: Gregory Ewing
MRAB wrote:
> Mk14 from Science of Cambridge, a kit with hex keypad and 7-segment
> display, which I had to solder together, and also make my own power
> supply. I had the extra RAM and the I/O chip, so that's 256B (including
> the memory used by the monitor) + 256B additional RAM + 128B more in the
> I/O chip.
Luxury! Mine was a Miniscamp, based on a design published in
Electronics Australia in the 70s. 256 bytes RAM, 8 switches
for input, 8 LEDs for output. No ROM -- program had to be
toggled in each time.
Looked something like this:
http://oldcomputermuseum.com/mini_scamp.html
except that mine wasn't built from a kit and didn't look
quite as professional as that one.
It got expanded in various ways, of course ("hacked" would
be a more accurate word). Memory expanded to 1.5KB, hex keyboard
and display (built into an old calculator case), cassette tape
interface based on a circuit scrounged from another magazine
article (never quite got it to work properly, wouldn't go at
more than about 4 bytes/sec, probably because I used resistors
and capacitors salvaged from old TV sets). Still no ROM, though.
Had to toggle in a bootstrap to load the keyboard/display
monitor (256 bytes) from tape.
Somewhere along the way I replaced the CPU with a 6800 -
much nicer instruction set! (Note for newtimers -- that's
*two* zeroes, not three.)
During that period, my holy grail was alphanumeric I/O. I was
envious of people who wrote articles about hooking surplus
teleprinters, paper tape equipment and other such cool
hardware to their homebrew micros -- sadly, no such thing was
available in NZ.
Then one day a breakthrough came -- a relative who worked
in the telephone business (government-owned in NZ at the time)
managed to get me an old teleprinter. It was Baudot, not ASCII,
which meant uppercase only, not much punctuation, and an
annoyingly stateful protocol involving letters/figures shift
characters, but it was heaps better than nothing. A bit of
hackery, of both hardware and software varieties, and I got
it working. It was as noisy as hell, but I could input and
output ACTUAL LETTERS! It was AMAZING!
As a proof of concept, I wrote an extremely small BASIC
interpreter that used one-character keywords. The amount of
room left over for a program was even smaller, making it
completely useless. But it worked, and I had fun writing it.
One thing I never really got a grip on with that computer
was a decent means of program storage. Towards the end of it's
life, I was experimenting with trying to turn an old 8-track
cartridge player into a random access block storage device,
using a tape loop. I actually got it to work, more or less,
and wrote a small "TOS" (Tape Operating System) for it that
could store and retrieve files. But it was never reliable
enough to be practical.
By that stage, umpteen layers of hackery using extremely
dubious construction techniques had turned the machine into
something of a Frankenstein monster. Calling it a bird's nest
would have been an insult to most birds. I wish I'd taken
some photos, they would have been good for scaring potential
future grandchildren.
My next computer was a Dick Smith Super 80 (*not* System 80,
which would have been a much better machine), Z80-based, built
from a kit. I had a lot of fun hacking around with that, too...
but that's another story!
--
Greg
== 2 of 7 ==
Date: Thurs, Mar 4 2010 2:05 am
From: Gregory Ewing
D'Arcy J.M. Cain wrote:
> And that is why text files in MS-DOS and CP/M before it end with ^Z.
> They needed a way to tell where the end of the information was. Why
> they used ^Z (SUB - Substitute) instead of ^C (ETX - End of TeXt) or
> even ^D (EOT - End Of Transmission) is anyone's guess.
Well, ^C is what people used for interrupting their BASIC
programs. And ^D would have made it almost compatible with
unix, which would have been far too sensible!
My guess is that it was chosen for its mnemonic value --
end of alphabet, end of file.
Also remember there were programs like Wordstar that used
control key combinations for all manner of things. It might
have been the only key left on the keyboard that wasn't
used for anything else.
--
Greg
== 3 of 7 ==
Date: Thurs, Mar 4 2010 2:09 am
From: Gregory Ewing
Richard Brodie wrote:
> It goes back to ancient PDP operating systems, so may well
> predate Unix, depending which exact OS was the first to use it.
Yes, I think it was used in RT-11, which also had
block-oriented disk files.
There were two kinds of devices in RT-11, character
and block, and the APIs for dealing with them were
quite different. They hadn't fully got their heads
around the concept of "device independent I/O" in
those days, although they were trying.
--
Greg
== 4 of 7 ==
Date: Thurs, Mar 4 2010 2:15 am
From: Gregory Ewing
Steve Holden wrote:
> Puts me in mind of Mario Wolczko's early attempts to implement SmallTalk
> on a VAX 11/750. The only bitmapped display we had available was a Three
> Rivers PERQ, connected by a 9600bps serial line. We left it running at
> seven o'clock one evening, and by nine am the next day it had brought up
> about two thirds of the initial VM loader screen ...
A couple of my contemporary postgraduate students worked on
getting Smalltalk to run on an Apple Lisa. Their first attempt
at a VM implementation was written in Pascal, and it wasn't
very efficient. I remember walking into their room one day
and seeing one of them sitting there watching it boot, drawing
stuff on the screen v...e...r...y... s...l...o...w...l...y...
At least their display was wired directly to the machine
running the code. I hate to think what bitmapped graphics at
9600 baud would be like!
--
Greg
== 5 of 7 ==
Date: Thurs, Mar 4 2010 2:38 am
From: Gregory Ewing
D'Arcy J.M. Cain wrote:
> Did you ever play Star Trek with sound effects?
Not on that machine, but I played a version on an Apple II
that had normal speaker-generated sounds. I can still
remember the sound that a photon torpedo (a # character IIRC)
made as it lurched its way drunkenly across the sector and
hit its target. Bwoop... bwoop... bwoop... bwoop... bwoop...
bwoowoowoowoowoop! (Yes, a photon torpedo makes exactly
five bwoops when it explodes. Apparently.)
I carried a listing of it around with me for many years
afterwards, and attempted to port it to various machines,
with varying degrees of success. The most successful port
was for a BBC Master that I picked up in a junk shop one
day.
But I couldn't get the sounds right, because the BBC's
sound hardware was too intelligent. The Apple made sounds
by directly twiddling the output bit connected to the
loudspeaker, but you can't do that with a BBC -- you
have to go through its fancy 3-voice waveform generating
chip. And I couldn't get it to ramp up the pitch rapidly
enough to make a proper photon-torpedo "bwoop" sound. :-(
I also discovered that the lovely low-pitched beep that
the original game used to make at the command prompt had
a lot to do with the resonant properties of the Apple
II's big plastic case. Playing a square wave through
something too high-fidelity doesn't sound the same at
all.
> I was never able to
> get it to work but supposedly if you put an AM radio tuned to a
> specific frequency near the side with the I/O card it would generate
> static that was supposed to be the sound of explosions.
>
> Of course, the explosions were happening in a vaccum so maybe the
> silence was accurate. :-)
Something like that might possibly happen for real. I could
imagine an explosion in space radiating electromagnetic
noise that would sound explosion-like if you picked it
up on a radio.
This might explain why the Enterprise crew could hear things
exploding when they shot them. They were listening in at RF!
--
Greg
== 6 of 7 ==
Date: Thurs, Mar 4 2010 2:38 am
From: Gregory Ewing
Steven D'Aprano wrote:
> True, but one can look at "best practice", or even "standard practice".
> For Python coders, using docstrings is standard practice if not best
> practice. Using strings as comments is not.
In that particular case, yes, it would be possible to
objectively examine the code and determine whether docstrings
were being used as opposed to above-the-function comments.
However, that's only a very small part of what goes to make
good code. Much more important are questions like: Are the
comments meaningful and helpful? Is the code reasonably
self-explanatory outside of the comments? Is it well
modularised, and common functionality factored out where
appropriate? Are couplings between different parts
minimised? Does it make good use of library code instead
of re-inventing things? Is it free of obvious security
flaws?
You can't *measure* these things. You can't objectively
boil them down to a number and say things like "This code
is 78.3% good; the customer requires it to be at least
75% good, so it meets the requirements in that area."
That's the way in which I believe that software engineering
is fundamentally different from hardware engineering.
--
Greg
== 7 of 7 ==
Date: Thurs, Mar 4 2010 3:57 am
From: Ben Finney
Gregory Ewing <greg.ewing@canterbury.ac.nz> writes:
> However, that's only a very small part of what goes to make good code.
> Much more important are questions like: Are the comments meaningful
> and helpful? Is the code reasonably self-explanatory outside of the
> comments? Is it well modularised, and common functionality factored
> out where appropriate? Are couplings between different parts
> minimised? Does it make good use of library code instead of
> re-inventing things? Is it free of obvious security flaws?
>
> You can't *measure* these things. You can't objectively boil them down
> to a number and say things like "This code is 78.3% good; the customer
> requires it to be at least 75% good, so it meets the requirements in
> that area."
That doesn't reduce the value of automating and testing those measures
we *can* make.
> That's the way in which I believe that software engineering is
> fundamentally different from hardware engineering.
Not at all. There are many quality issues in hardware engineering that
defy simple measurement; that does not reduce the value of standardising
quality minima for those measures that *can* be achieved simply.
--
\ "Spam will be a thing of the past in two years' time." —Bill |
`\ Gates, 2004-01-24 |
_o__) |
Ben Finney
==============================================================================
TOPIC: case do problem
http://groups.google.com/group/comp.lang.python/t/d73f6f6a59d3bbfd?hl=en
==============================================================================
== 1 of 2 ==
Date: Thurs, Mar 4 2010 2:09 am
From: Michael Rudolf
Am 03.03.2010 18:38, schrieb Tracubik:
> Il Wed, 03 Mar 2010 09:39:54 +0100, Peter Otten ha scritto:
>> def loop():
>> count = 0
>> m = 0
>> lookup = {1: 1, 2: 10, 3: 100}
>> for iterations in range(20): # off by one
>> # ...
>> print "%2d %1d %3d" % (iterations, count, m) # ...
>> if generic_condition():
>> count += 1
>> # ...
>> m = lookup.get(count, m)
>> if count == 4:
>> break
>>
>> if __name__ == "__main__":
>> loop()
>> print "That's all, folks"
>>
>> Something must be wrong with me today because I find the Pascal code
>> /more/ readable..
>
> i was think the same, Pascal seem to generate a great more readable code.
> I'm a newbie, so my opinion is probably wrong, but i still think that
> don't have CASE OF and REPEAT UNTIL code block return in difficult-to-
> read code.
That is probably a side-effect of literal code translation.
No one would write something like you did when he writes in python the
first place.
>> Tracubik wrote:
>>
>>> hi, i've to convert from Pascal this code:
>>
>> program loop;
>>
>> function generic_condition: boolean;
>> begin
>> generic_condition := random> 0.7
>> end;
>>
>> procedure loop;
>> var
>> iterations, count, m: integer;
>> begin
>> iterations := 0;
>> count := 0;
>> m := 0;
>> repeat
>> iterations := iterations+1;
>> (*...*)
>> writeln(iterations:2, count:2, m:4);
>> (*...*)
>> if generic_condition then
>> inc(count);
>> (*...*)
>> case count of
>> 1: m := 1;
>> 2: m := 10;
>> 3: m := 100
>> end
>> until (count = 4) or (iterations = 20)
>> end;
>>
>> begin
>> loop;
>> writeln("That's all, folks")
>> end.
Hmmm lets see...
We have somewhat obscure and complicated logic.
If we cannot get rid of it, lets hide it:
class Loop:
def __init__(self, maxiterations=0, maxcount=1, m=0):
assert generic_condition.__call__
self.maxiterations = maxiterations
self.maxcount = maxcount
self.m=m
self.count=0
self.iterations=0
def __iter__(self):
while True:
yield self.next()
def next(self):
self.iterations+=1
if self.iterations > self.maxiterations:
raise StopIteration
if generic_condition():
self.count += 1
if self.count >= self.maxcount:
raise StopIteration
self.m = (None,1,10,100)[self.count]
return self, self.m
##### So we have:
#from complicatedlogic import Loop
from random import random
def generic_condition():
return random() > 0.7
if __name__ == '__main__':
for loop, m in Loop(maxiterations=20, maxcount=4):
print("%2d %1d %3d" % (loop.iterations, loop.count, m))
print("That's all, folks")
better? worse? I honestly do not know.
Note that while this is valid py3 and runs as intended, there might be
some off-by-one or something left.
Also, this is of course not production level code ;)
Regards,
Michael
== 2 of 2 ==
Date: Thurs, Mar 4 2010 2:58 am
From: Gregory Ewing
Peter Otten wrote:
> Something must be wrong with me today because I find the Pascal code /more/
> readable...
Actually I don't find either of them very readable. The
control flow is pretty convoluted either way. It might
be better if it used real-life variable and function
names to give some context, though.
--
Greg
==============================================================================
TOPIC: taking python enterprise level?...
http://groups.google.com/group/comp.lang.python/t/3dca28b82d10655c?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:30 am
From: simn_stv
till i think i absolutely need to trade-off easier and less
complicated code, better db structure (from a relational perspective)
and generally less "head aches" for speed, i think i'll stick with the
joins for now!...;)
the thought of denormalization really doesnt appeal to me...
==============================================================================
TOPIC: Adding to a module's __dict__?
http://groups.google.com/group/comp.lang.python/t/40837c4567d64745?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:43 am
From: Gregory Ewing
Roy Smith wrote:
> The idea is I want to put in the beginning of the module:
>
> declare('XYZ_FOO', 0, "The foo property")
> declare('XYZ_BAR', 1, "The bar property")
> declare('XYZ_BAZ', 2, "reserved for future use")
Okay, that seems like a passable excuse.
One thing to watch out for is that if your 'declare' function
is defined in a different module, when it calls globals() it
will get the globals of the module it's defined in, not the
one it's being called from.
There's a hackish way of getting around that, but it might
be better to put all of these symbols in a module of their
own and import them from it. The declare() function can then
be defined in that same module so that it accesses the right
globals.
--
Greg
==============================================================================
TOPIC: Queue peek?
http://groups.google.com/group/comp.lang.python/t/ba3cb62c81d4cb7a?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:49 am
From: Gregory Ewing
Floris Bruynooghe wrote:
> I was just wondering if
> other people ever missed the "q.put_at_front_of_queue()" method or if
> it is just me.
Sounds like you don't want a queue, but a stack. Or
maybe a double-ended queue.
--
Greg
==============================================================================
TOPIC: Pylint Argument number differs from overridden method
http://groups.google.com/group/comp.lang.python/t/12977374ae8461dc?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:45 am
From: Jean-Michel Pichavant
Wanderer wrote:
> On Mar 3, 2:33 pm, Robert Kern <robert.k...@gmail.com> wrote:
>
>> On 2010-03-03 11:39 AM, Wanderer wrote:
>>
>>
>>> Pylint W0221 gives the warning
>>> Argument number differs from overridden method.
>>>
>>> Why is this a problem? I'm overriding the method to add additional
>>> functionality.
>>>
>> There are exceptions to every guideline. Doing this could easily be a mistake,
>> so it's one of the many things that Pylint checks for. Silence the warning if
>> you like.
>>
>> --
>> Robert Kern
>>
>> "I have come to believe that the whole world is an enigma, a harmless enigma
>> that is made terrible by our own mad attempt to interpret it as though it had
>> an underlying truth."
>> -- Umberto Eco
>>
>
> Thanks I was just wondering if I was overlooking something about
> inheritance.
>
This is only my opinion but you get this warning because of 2 disctinct
issues:
1/ you just made a basic mistake in your signature and need to correct it
2/ you did not make any mistake in the signature, but this warning may
reveal a (small) flaw in your class design.
I don't know the exact context for your code, but it's better to have a
consistant interface over your methods and mask the implementation
details from the user.
In your case, the getRays method may always ask for the lambda
parameters and just ignore it for one of its implementation.
And don't write empty doctrings to trick pylint. Either write them, or
remove this rule, you are loosing all the tool benefits.
JM
==============================================================================
TOPIC: Partly erratic wrong behaviour, Python 3, lxml
http://groups.google.com/group/comp.lang.python/t/cc11fa023e436ad5?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:46 am
From: Jussi Piitulainen
Dear group,
I am observing weird semi-erratic behaviour that involves Python 3 and
lxml, is extremely sensitive to changes in the input data, and only
occurs when I name a partial result. I would like some help with this,
please. (Python 3.1.1; GNU/Linux; how do I find lxml version?)
The test script regress/Tribug is at the end of this message, with a
snippet to show the form of regress/tridata.py where the XML is.
What I observe is this. Parsing an XML document (wrapped in BytesIO)
with lxml.etree.parse and then extracting certain elements with xpath
sometimes fails so that I get three times the correct number of
elements. On the first run of the script, it fails in one way, and on
each subsequent run in another way: subsequent runs are repeatable.
Second, the bug only occurs when I give a name to the result from
lxml.etree.parse! This is seen below in the lines labeled "name1" or
"name2" that sometimes exhibit the bug, and lines labeled "nest1" or
"nest2" that never do. That is, this fails in some complex way:
result = etree.parse(BytesIO(body))
n = len(result.xpath(title))
This fails to fail:
n = len(etree.parse(BytesIO(body)).xpath(title))
I have failed to observe the error interactively. I believe the
erroneus result lists are of the form [x x x y y y z z z] when they
should be [x y z] but I do not know if the x's are identical or
copies. I will know more later, of course, when I have written more
complex tests, unless somebody can lead me to a more profitable way of
debugging this.
Two versions of the test runs follow, before and after a trivial
change to the test data. Since the numbers are repeated n's of the
above snippets, they should all be the same: 5 observed 1000 times.
A first run after removing regress/tridata.pyc:
[1202] $ regress/Tribug
name1: size 5 observed 969 times
name1: size 15 observed 31 times
name2: size 5 observed 1000 times
nest1: size 5 observed 1000 times
nest2: size 5 observed 1000 times
All subsequent runs, with regress/tridata.pyc recreated:
[1203] $ regress/Tribug
name1: size 5 observed 1000 times
name2: size 5 observed 978 times
name2: size 15 observed 22 times
nest1: size 5 observed 1000 times
nest2: size 5 observed 1000 times
Adding an empty comment <!-- --> to the XML document;
a first run:
[1207] $ regress/Tribug
name1: size 5 observed 992 times
name1: size 15 observed 8 times
name2: size 5 observed 1000 times
nest1: size 5 observed 1000 times
nest2: size 5 observed 1000 times
And subsequent runs:
[1208] $ regress/Tribug
name1: size 5 observed 991 times
name1: size 15 observed 9 times
name2: size 5 observed 998 times
name2: size 15 observed 2 times
nest1: size 5 observed 1000 times
nest2: size 5 observed 1000 times
---start of regress/Tribug---
#! /bin/env python3
# -*- mode: Python; -*-
from io import BytesIO
from lxml import etree
from tridata import body, title
def naming():
sizes = dict()
for k in range(0,1000):
result = etree.parse(BytesIO(body))
n = len(result.xpath(title))
sizes[n] = 1 + sizes.get(n, 0)
return sizes
def nesting():
sizes = dict()
for k in range(0,1000):
n = len(etree.parse(BytesIO(body)).xpath(title))
sizes[n] = 1 + sizes.get(n, 0)
return sizes
def report(label, sizes):
for size, count in sizes.items():
print('{}: size {} observed {} times'
.format(label, size, count))
report('name1', naming())
report('name2', naming())
report('nest1', nesting())
report('nest2', nesting())
---end of regress/Tribug---
The file regress/tridata.py contains only the two constants. I omit
most of the XML. It would be several screenfuls.
---start of regress/tridata.py---
body = b'''<OAI-PMH xmlns="http://www.opena...
...
</OAI-PMH>
'''
title = '//*[name()="record"]//*[name()="dc:title"]'
---end of regress/tridata.py---
==============================================================================
TOPIC: A "scopeguard" for Python
http://groups.google.com/group/comp.lang.python/t/8c752e871801c223?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:50 am
From: Jean-Michel Pichavant
Alf P. Steinbach wrote:
>> From your post, the scope guard technique is used "to ensure some
>> desired cleanup at the end of a scope, even when the scope is exited
>> via an exception." This is precisely what the try: finally: syntax is
>> for.
>
> You'd have to nest it. That's ugly. And more importantly, now two
> people in this thread (namely you and Mike) have demonstrated that
> they do not grok the try functionality and manage to write incorrect
> code, even arguing that it's correct when informed that it's not, so
> it's a pretty fragile construct, like goto.
You want to execute some cleanup when things go wrong, use try except.
You want to do it when things go right, use try else. You want to
cleanup no matter what happen, use try finally.
There is no need of any Cleanup class, except for some technical
alternative concern.
JM
==============================================================================
TOPIC: Method / Functions - What are the differences?
http://groups.google.com/group/comp.lang.python/t/72ab93ba395822ed?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 2:59 am
From: Bruno Desthuilliers
Eike Welk a écrit :
> Bruno Desthuilliers wrote:
>> John Posner a écrit :
>>> Done -- see http://wiki.python.org/moin/FromFunctionToMethod
>> Done and well done !-)
>> Thanks again for the good job John.
>
> I like it too, thanks to both of you!
>
> I have two small ideas for improvement:
> - Swap the first two paragraphs. First say what it is, and then give the
> motivation.
Mmm... As far as I'm concerned, I like it the way its. John ?
> - The section about the descriptor protocol is a bit difficult to
> understand.
I may eventually try to rework it a bit when I'll have time (death march
here currently, duh...)
> But judging from the official descriptor documentation, it seems
> to be hard to explain
Not that easy, indeed. I once posted on c.l.py a longer explanation of
the whole lookup rule stuff, that IIRC included a "naive python
implementation" example. Might be worth trying to google for it and
turning it into another "overview" article.
>: The official documentation is nearly incomprehensible
> (IMHO).
I should probably have a look at it !-)
==============================================================================
TOPIC: Working group for Python CPAN-equivalence?
http://groups.google.com/group/comp.lang.python/t/c2c452cc4aaa6e98?hl=en
==============================================================================
== 1 of 2 ==
Date: Thurs, Mar 4 2010 3:21 am
From: Gregory Ewing
Peter Billam wrote:
> A very important thing about CPAN modules is the consistent
> basic install method: perl Makefile.PL ; make ; make install
Well, we more or less have that with Python, too:
python setup.py install
It may not always work smoothly, but it's the
one obvious thing to try when you've downloaded
a Python package in source form.
--
Greg
== 2 of 2 ==
Date: Thurs, Mar 4 2010 3:45 am
From: Olof Bjarnason
2010/3/4 Gregory Ewing <greg.ewing@canterbury.ac.nz>:
> Peter Billam wrote:
>
>> A very important thing about CPAN modules is the consistent
>> basic install method: perl Makefile.PL ; make ; make install
>
> Well, we more or less have that with Python, too:
>
> python setup.py install
>
> It may not always work smoothly, but it's the
> one obvious thing to try when you've downloaded
> a Python package in source form.
>
> --
> Greg
> --
> http://mail.python.org/mailman/listinfo/python-list
>
I want to say thanks to all that have given information regarding the
original question - for example the blog mention was valuable, aswell
as the disctintion between CPAN and cpan.
It was definately *not* my intention to start another "Where is CPAN
for Python?"-thread, but it seems we're already there. :)
==============================================================================
TOPIC: Generic singleton
http://groups.google.com/group/comp.lang.python/t/9228a3763eb552b3?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 3:50 am
From: mk
Steven D'Aprano wrote:
> Groan. What is it with the Singleton design pattern? It is one of the
> least useful design patterns, and yet it's *everywhere* in Java and C++
> world.
It's useful when larking about in language internals for learning
purposes, for instance. I don't recall ever actually having significant
need for it.
>> def __new__(cls, impclass, *args, **kwargs):
>> impid = id(impclass)
>
> Yuck. Why are you using the id of the class as the key, instead of the
> class itself?
Bc I didn't know whether it was safe to do that: like Arnaud pointed
out, the *type* of bultins is hashable.
Regards,
mk
==============================================================================
TOPIC: memory usage, temporary and otherwise
http://groups.google.com/group/comp.lang.python/t/da72d362a5b77618?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 3:56 am
From: mk
Bruno Desthuilliers wrote:
> mk a écrit :
>> Obviously, don't try this on low-memory machine:
>>
>>>>> a={}
>>>>> for i in range(10000000):
> Note that in Python 2, this will build a list of 10000000 int objects.
> You may want to use xrange instead...
Huh? I was under impression that some time after 2.0 range was made to
work "under the covers" like xrange when used in a loop? Or is it 3.0
that does that?
> And this build yet another list of 10000000 int objects.
Well this explains much of the overhead.
> (overly simplified)
>
> When an object is garbage-collected, the memory is not necessarily
> "returned" to the system - and the system doesn't necessarily claim it
> back neither until it _really_ needs it.
>
> This avoid a _lot_ of possibly useless work for both the python
> interpreter (keeping already allocated memory costs less than immediatly
> returning it, just to try and allocate some more memory a couple
> instructions later) and the system (ditto - FWIW, how linux handles
> memory allocations is somewhat funny, if you ever programmed in C).
Ah! That explains a lot. Thanks to you, I have again expanded my
knowledge of Python!
Hmm I would definitely like to read smth on how CPython handles memory
on Python wiki. Thanks for that doc on wiki on "functions & methods" to
you and John Posner, I'm reading it every day like a bible. ;-)
Regards,
mk
==============================================================================
TOPIC: Interest check in some delicious syntactic sugar for "except:pass"
http://groups.google.com/group/comp.lang.python/t/b493c6208ea724a2?hl=en
==============================================================================
== 1 of 1 ==
Date: Thurs, Mar 4 2010 3:59 am
From: Bruno Desthuilliers
Oren Elrad a écrit :
> Howdy all, longtime appreciative user, first time mailer-inner.
>
> I'm wondering if there is any support (tepid better than none) for the
> following syntactic sugar:
>
> silence:
> ........ block
>
> ------------------------->
>
> try:
> ........block
> except:
> ........pass
>
Hopefully not.
> The logic here is that there are a ton of "except: pass" statements[1]
> floating around in code that do not need to be there.
s/do not need to be/NEVER should have been at first/
==============================================================================
You received this message because you are subscribed to the Google Groups "comp.lang.python"
group.
To post to this group, visit http://groups.google.com/group/comp.lang.python?hl=en
To unsubscribe from this group, send email to comp.lang.python+unsubscribe@googlegroups.com
To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.python/subscribe?hl=en
To report abuse, send email explaining the problem to abuse@googlegroups.com
==============================================================================
Google Groups: http://groups.google.com/?hl=en
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home