Re: Python slang

2016-08-10 Thread Anders J. Munch

Lawrence D’Oliveiro:
>> [...] as much like C++ as
>> possible.
>
> Nevertheless, Python copied the C misfeature [...]

You segued a little too easily from C++ to C.  When talking language
evolution and inspirations, they are entirely different things.

- Anders

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


Re: Python slang

2016-08-07 Thread Anders J. Munch via Python-list

Marco Sulla via Python-list:
> Well, they are the most used languages.

They weren't when Python was created.

Python's terms raise/except and self were normal for the time. C++ was
the odd one out.  throw/catch and this are Stroustrup's inventions, no
other language used those terms.

It was only later that language designers fell into the notion that it
was crucial for a new language's success to look as much like C++ as
possible.

regards, Anders

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


Re: sobering observation, python vs. perl

2016-03-19 Thread Anders J. Munch

Charles T. Smith:

I've really learned to love working with python, but it's too soon
to pack perl away.  I was amazed at how long a simple file search took
so I ran some statistics:


Write Python in pythonic style instead of translated-from-Perl style, and the 
tables are turned:


$ cat find-rel.py
| import sys
| def main():
| for fn in sys.argv[1:]:
| tn = None
| with open(fn, 'rt') as fd:
| for line in fd:
| if ' is ready' in line:
| tn = line.split(' is ready', 1)[0]
| elif 'release_req' in line:
| print tn
| main()


$ time python find-rel.py *.out
real0m0.647s
user0m0.616s
sys0m0.029s

$ time perl find-rel.pl *.out
real0m0.935s
user0m0.910s
sys0m0.023s

I don't have your log files and my quickly assembled test file doesn't actually 
contain the phrase 'release_req', so my results may be misleading. Perhaps 
you'll try it and post your results?


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-15 Thread Anders J. Munch

Steven D'Aprano:

I'll give you the benefit of the doubt, and assume that when you first
posted you hadn't realised that the audience here does not have the
relevant experience, but by refusing to ask the question elsewhere, and
by making snide comments that they don't like beer, that pretty much
gives the game away that you're looking to have your opinion confirmed
rather than looking for an honest answer.


I really did run out of time when I said I did: I spent the last 5 days running 
a chess tournament with 137 participants, with the tournament management 
software written in Python by yours truly. Which worked beautifully, Python is a 
great language. And I'm going to Iceland on vacation tomorrow, so I'm not going 
to start a new discussion of a different mailing list just now, maybe later. Not 
everyone is as prolific a writer as you are, Steven.


The talk about the wrong list would have carried more weight if you had 
started out by saying wrong list, instead of going through every other 
argument first, before punting like that. By the way, which list is the 
appropriate one? The numpy and SciPy mailing lists are first and foremost about 
numpy and SciPy, I presume. Is there a general numerics-list somewhere also? I 
don't see any on https://mail.python.org/mailman/listinfo.


By the way, you guys seem to have overlooked the opportunity for arbitrage: 
*Anyone* can go to a numerical list, poll for examples, and come back and earn 
some beer :)


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-14 Thread Anders J. Munch

alister wrote:

I don't have time to start this discussion over again on another mailing
list.
Don't anyone on those lists read python-list also?

they possibly do, but prefer to keep discussions to the proper forum


The semantics of the Python programming language is on-topic for python-list. 
This is about float.__eq__, not about numpy or SciPy.

Maybe they just don't like beer?

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

I wrote:

| class Monitor(Thread):
| def run(self):
| old = self.get_current_value()
| while not self.Terminated:
| new = self.get_current_value()
| if new != old:
| print(time.asctime(), changed to, new)
| old = new
| time.sleep(1)



Huh, I don't know what happened to the identation here, I'l try again:

class Monitor(Thread):
def run(self):
old = self.get_current_value()
while not self.Terminated:
new = self.get_current_value()
if new != old:
print(time.asctime(), changed to, new)
old = new
time.sleep(1)

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

Steven D'Aprano wrote:

It seems to me that the trivial work-around is:

* gather packed floats from some device, as ints
* process them *as ints* in some way which requires reflexivity
* unpack back into floats
* (maybe) much later perform numeric calculations on them


Although perhaps I don't understand your use-case.


Clearly you do not. floats are not ints. I have no idea how you imagine 
processing IEEE-754 floating-point values in int form.


My use case is: Working with IEEE-754 floating-point values. That means storing 
and retrieving them, serialising and transferring them, accepting them as user 
input, printing them, all the usual things you do with values.


And doing so in a way that does not require special handling in algorithms that 
are otherwise generic.
When the same algorithm is capable of dealing with ints, bytestrings, text 
string, tuples, list, dictionaries, time stamps, NoneType's, bools, 
floating-point floats and a thousand other things, then NaNs stand out as the 
values that have special algorithm-breaking magic.


I gave an example of such an algorithm in an earlier reply to Chris.

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

Chris Angelico:

If you need to do bitwise comparisons, then the easiest way is to use
the bitpattern, converted to an integer. A 64-bit float becomes a
64-bit integer. It's then very simple to compare them, and reflexivity
is maintained. At what point do you actually need them to be floats?
What are you really doing with them?


What does one do with floats? Add, subtract, multipy, divide, display, input, 
store and retrieve to and from various formats.

All the usual stuff. Why would my use be different from anyone elses?

What you and Steven seem to be saying is that I should employ strategies to 
avoid NaNs ever being compared. I'll take that one step further and say that as 
long as NaN!=NaN, everyone should seek to avoid NaNs ever being compared.


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

Steven D'Aprano wrote:

I assumed that you realised that the 64-bit(?) values you were receiving
in binary could be interpreted as ints. After all, you have to unpack
them from some bytes.



Since that's not what you're doing, I have no idea what it is.


Stop obsessing over how NaN's came to exist in my software. That's just context.
The argument is over how those NaNs should behave. Their provenance is not 
relevant.


I have no idea how you imagine
processing IEEE-754 floating-point values in int form.

Cast your 64-bit float into a 64-bit int.


I can construct a bijective mapping between any data structure and a subset of 
the natural numbers, but that has nothing to do with practical programming.

A cast value would be impossible to work with.




My use case is: Working with IEEE-754 floating-point values. That means
storing and retrieving them, serialising and transferring them,
accepting them as user input, printing them, all the usual things you do
with values.

But apparently not arithmetic?
Of course also arithmetic. I left it out of the list because then you would say 
hah! if you're doing arithmetic then it's not a generic algorithm. Apparently 
I can't win, you are going to nitpick anything I write.


Ah, well there's your problem. NANs are special, as a signed zeroes and INFs. 
Does it distress you that x + x = x when x is an INF?

No.


When the same algorithm is capable of dealing with ints, bytestrings,
text string, tuples, list, dictionaries, time stamps, NoneType's, bools,
floating-point floats and a thousand other things,

   ^

Obviously not, or you wouldn't be complaining about the inability to
handle floats.


NaNs are not floating-point values. A floating-point value has a sign, an 
exponent and a mantissa.  They are IEEE 754 floating point values, though.



The hardware devices generating your float data... do they also generate
ints, bytestrings, text strings, tuples, lists, dicts, time stamps, None,
bools, and a thousand other things? If not, I wonder why you are
insisting that you have to handle a *specialised* data type using a
*generic* algorithm.
All the other types are also specialised, for their separate purpose. That 
doesn't make them non-reflexive.




I'm not unsympathetic to your problem, which is why I proposed two new
operators, === and !==, and a change to == and !=, in another thread.
Would == always doing an identity test before calling __eq__ solve your
problem? If not, what would it take to solve your problem?

It would not solve it. Two bitwise identical NaNs would still compare different.
What would solve the problem is making identical NaNs compare equal.

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

Ethan Furman:
I would suggest you ask for this on the numerical mailing lists instead of 
here -- and you may not want to offer a beer to everyone that has an anecdote 
for NaN behavior being useful.
I don't have time to start this discussion over again on another mailing list. 
Don't anyone on those lists read python-list also?


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-09 Thread Anders J. Munch

Joel Goldstick wrote:
I've been following along here, and it seems you haven't received the answer 
you want or need.


So far I received exactly the answer I was expecting.  0 examples of NaN!=NaN 
being beneficial.
I wasn't asking for help, I was making a point.  Whether that will lead to 
improvement of Python, well, I'm not too optimistic, but I feel the point was 
worth making regardless.


regards, Anders

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


NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch

Most people don't need to deal with NaN's in Python at all,
fortunately. They just don't appear in normal computation, because the
interpreter raises an exception instead.

It happens in my work I come across them quite a lot. I'm writing
software that talks to embedded applications that can contain NaN
values for a variety of reasons - never-initialised storage,
initialise-to-NaN, hardware failures etc.

So when my software reads these values in binary, unpack them using
the struct module, and goes to work. And NaN's are no different from
any other value, it's something to store, compare, display etc.

And that worked fine in my Python 2.4 apps.  Then I upgraded to 2.7
and it broke.  Because 2.7 goes out of it's way to ensure that NaN's
don't compare equal to themselves.

I discovered it when a sanity check told me that two functions,
to_binary and from_binary, weren't each other's inverse, as they were
intended to be.  Apparently,
bitPattern==to_binary(from_binary(bitPattern)) wasn't true for this
particular value of bitPattern.  Of course, the bit pattern in
question was the binary representation for a floating-point NaN.

Panic time! If I can't trust == to return True for (mathematically)
equal objects, that means that every single algorithm I had ever written
that explicitly or implicitly does .__eq__ or .__ne__ comparison was
suspect!

That meant I had 3 lines of code to review.  Every time there's a
comparison, if there was any chance that either value could be a
float NaN, I would have to change e.g.
   if x==y:
to
   if x==y or (isinstance(x, float) and isinstance(y, float) and
 math.isnan(x) and math.isnan(y)):
To make it bearable, I could wrap the pattern up in a function and
write
   if my_equal(x,y):
but I would still lose, because the standard library does == and !=
all over the place without calling my_equal.

In the end I came up with this hack: Every time I struct.unpack'd a
float, I check if it's a NaN, and if it is, then I replace it with a
reference to a single, shared, canonical NaN. That means that
container objects that skip __equal__ when comparing an object to
itself will work -- e.g. hash keys.

It's half a solution, of course: Any further computation with a NaN
value will change it to a different NaN object, so I still needed to
do explicit NaN-checks in various places.  I'm sure there are still
NaN-related bugs in my code, but right now it's good enough - I
haven't seen NaN-related bugs in a good while.

Now, all this bothers me.  Not that I had to do some work to get stuff
to work in an imperfect world.  No, what bothers me is that this
behaviour was explicitly and deliberately put in for no good reason.
The only reason is standard says so. Not that there's any legal
requirement for Python to follow the IEEE-754 standard. Or for that
matter, for Python's spelling of IEEE-754 comparisons to be ==.

So I make this claim: float.__eq__ implementing IEEE-754 NaN
comparison rules creates real problems for developers. And it has
never, ever, helped anyone do anything.

Never is a strong claim, and easily disproven if false: Simply
provide a counterexample.  So that is my challenge: If you have a
program (a pre-existing and useful one, not something artificial
created for this challenge) that benefits from NaN!=NaN and that would
fail if x==x for all float objects x, then please come forward and
show it, and I'll buy you a beer the next time I'm at PyCon.

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch

Chris Angelico wrote:


Why *should* all NaNs be equal to each other? You said on the other
list that NaN==NaN was equivalent to (2+2)==(1+3), but that assumes
that NaN is a single thing.


I don't actually care if all NaN bitpatterns are in the same equivalence group 
or if each bitpattern is its own equivalence group. I just want the == 
equivalence relation to be sound.



For hash keys, float object identity will successfully look them up:


Except you can't expect to rely on object identity in most interesting cases.

 x = float('nan')
 import struct
 y = struct.unpack('f', struct.pack('f', x))[0]
 d[x] = found
 d[y]
Traceback (most recent call last):
File stdin, line 1, in module
KeyError: nan

and also:

 def f(): return float('inf')/float('inf')
 f() == f()
False
 f() is f()
False


But any time you compare floats for equality, you *already* have to
understand what you're doing (because of rounding and such), so I
don't see why the special case on NaN is significant, unless as
mentioned above, you want all NaNs to be equal, which doesn't make
sense.

Let me conjure up a simple example:

| class Monitor(Thread):
| def run(self):
| old = self.get_current_value()
| while not self.Terminated:
| new = self.get_current_value()
| if new != old:
| print(time.asctime(), changed to, new)
| old = new
| time.sleep(1)

This is a completely generic change detection algorithm, and not a 
floating-point algorithm in any way: It will work on strings, lists, sets, 
anything that get_current_value returns, including non-NaN floats. You don't 
need to know anything about floating-point representation to write or use such 
an algorithm, why should you? It works on tuples, sets, lists, serial port 
handles, module objects, pretty much anything you can imagine -- except NaN floats.


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch


Ian Kelly wrote:

As far as I know nothing changed between 2.4 and 2.7 in this regard.
Python has always had NaN compare unequal to everything, per the
standard.

It might have been platform-specific in 2.4.


Okay, here's your problem: there isn't just one binary representation
for NaN.
I'm fully aware of that. Whether NaN's are one equivalence class or several is 
not the issue. What matters is the integrity of the equivalence relation.


Following the standard isn't a good reason itself? 


If a standard tells you to jump of a cliff...

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch

Steven D'Aprano wrote:
Oh, you've read the IEEE-754 standard, and that's what it says? We're going 
to specify this behaviour for NANs just to annoy people perhaps? 
I was referring to the deliberate choice to enforce IEEE-754 rules in Python. 
There is no force of law that requires Python to do so.


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch

Ethan Furman skrev:
What exception? Apparently your claims about NaN in Python are all wrong -- 
have you been using a custom interpreter?

 float('inf') - float('inf')
nan

If you deliberately try to manufacture NaN's, you can. I never said otherwise.

regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch


Den 14-07-08 19:23, Skip Montanaro skrev:


In addition to what others have written, I will add one thing. There
are certainly situations where raising an exception is bad. Consider
all the people in the scientific computing community doing fancy
linear algebra sorts of things, often with missing data. They
generally want NaN propagated and not have some long running
calculation crash in the middle.


NaN!=NaN doesn't cause NaN's to propagate any more or any less. It simply causes 
a different branch of code to run, quite often the wrong one.


regards, Anders

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


Re: NaN comparisons - Call For Anecdotes

2014-07-08 Thread Anders J. Munch

I wrote:

Steven D'Aprano wrote:
Oh, you've read the IEEE-754 standard, and that's what it says? We're going 
to specify this behaviour for NANs just to annoy people perhaps? 
I was referring to the deliberate choice to enforce IEEE-754 rules in Python. 
There is no force of law that requires Python to do so.




And just to be clear, I didn't mean python-dev did this to annoy people either. 
I just meant that the choice made is not supported by any use case, so there's 
no upside to outweigh the problems it creates.


At least I've yet to hear any use case. So far I'm 0 beers in debt.

regards, Anders
--
https://mail.python.org/mailman/listinfo/python-list


Re: [Python-Dev] == on object tests identity in 3.x

2014-07-08 Thread Anders J. Munch

Steven D'Aprano wrote:


- Dropping reflexivity preserves the useful property that NANs compare
   unequal to everything.


Please present an example from real life where that turned out useful, and earn 
yourself a beer!

I've only experienced examples to the contrary.


- Keeping reflexivity for NANs would have implied some pretty nasty
   things, e.g. if log(-3) == log(-5), then -3 == -5.


 log(-3)
Traceback (most recent call last):
File stdin, line 1, in module
ValueError: math domain error

You were perhaps referring to the log functions in C and Fortran, not math.log?
The tradeoffs are different in those languages, so choices the IEEE-754 
committee made with C and Fortran in mind may be less relevant for Python.


regards, Anders

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


Re: grimace: a fluent regular expression generator in Python

2013-07-16 Thread Anders J. Munch

Ben Last wrote:

north_american_number_re = (RE().start

.literal('(').followed_by.exactly(3).digits.then.literal(')')
 
.then.one.literal(-).then.exactly(3).digits

.then.one.dash.followed_by.exactly(4).digits.then.end
 .as_string())


Very cool.  It's a bit verbose for my taste, and I'm not sure how well it will 
cope with nested structure.


Here's my take on what readable regexps could look like:

north_american_number_re = RE.compile(r
^
( digit{3} )  # And why shouldn't a regexp
- digit{3}  # include en embedded comment?
- digit{4}
$
)

The problem with Perl-style regexp notation isn't so much that it's terse - it's 
that the syntax is irregular (sic) and doesn't follow modern principles for 
lexical structure in computer languages.  You can get a long way just by 
ignoring whitespace, putting literals in quotes and allowing embedded comments.


Setting the re.VERBOSE flag achieves two out of three, so you can write:

north_american_number_re = RE.compile(r
^
( \d{3} )   # Definite improvement, though I really miss putting
- \d{3} # literals in quotes.
- \d{4}
$
)

It's too bad re.VERBOSE isn't the default.

regards, Anders

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


Re: Tabs -vs- Spaces: Tabs should have won.

2011-07-18 Thread Anders J. Munch

Thomas 'PointedEars' Lahn wrote:
 I am getting the idea here that you mean the right thing, but that you
 explain it wrong.

Feel free to write the much longer essay that explains it all unambiguously, I'm 
not going to.


regards, Anders


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


Re: Tabs -vs- Spaces: Tabs should have won.

2011-07-17 Thread Anders J. Munch

Steven D'Aprano wrote:
 I can't fathom why 8 position tabs were *ever* the default, let alone why
 they are still the default.

That's because they were not invented as a means for programmers to vary 
indentation.


Originally, tabs were a navigation device: When you press the tab key, you skip 
ahead to the next tab column.  The notion that whitespace characters are 
inserted into the text would have been very alien to someone using text 
processing software anno 1970.  Same thing with space and enter; on typewriters
the space bar doesn't type anything onto the paper, it moves to the next 
column, and that thinking carried over to computers.


The reason the tab stop is a full 8 positions: for faster navigation.  If it 
were 3 positions, it would take forever to skip from the start of line to column 
60.  You'd appreciate that, if you were e.g. writing a fiduciary report with 
some text to the left and two number columns to the right, back in the day 
before spreadsheets and word processor tables.  Skip a column or two too far? 
Adjust by backspacing (another navigation key).


As for why 8 is still the default - well, what else should it be? 2, 3, 4, 5?  I 
for one am thankful that we have so far been spared the flamewar armegeddon of 
all the world's programmers trying to agree on that.


 Cameron Simpson wrote:
 Personally, I like to use the tab _key_ as an input device, but to have
 my editor write real spaces to the file in consequence.

Just like in the old days:)

regards, Anders

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


Re: Q: finding distance between 2 time's

2009-05-31 Thread Anders J. Munch

jkv wrote:

Hi Martin,

What i usally do is to convert the two times to seconds since epoch and
compare the two values in seconds. You can use time.mktime to convert
localtime to seconds since epoch.


There's no need to convert - simply retrieve the times as absolute times to 
begin with:


  file_age_in_seconds = time.time() - os.path.getmtime(filename)

Only convert to local time for presentation.

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


[issue2736] datetime needs and epoch method

2008-11-18 Thread Anders J. Munch

Anders J. Munch [EMAIL PROTECTED] added the comment:

Any thoughts to time zone/DST handling for naive datetime objects? E.g.
suppose the datetime object was created by .utcnow or .utcfromtimestamp.

For aware datetime objects, I think the time.mktime(dt.timetuple())
approach doesn't work; the tz info is lost in the conversion to time tuple.

--
nosy: +andersjm

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue2736
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1759845] subprocess.call fails with unicode strings in command line

2008-08-26 Thread Anders J. Munch

Changes by Anders J. Munch [EMAIL PROTECTED]:


--
nosy: +andersjm

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1759845
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1220212] os.kill on windows

2008-08-25 Thread Anders J. Munch

Changes by Anders J. Munch [EMAIL PROTECTED]:


--
nosy: +andersjm

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue1220212
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



Re: Boolean tests

2008-08-01 Thread Anders J. Munch

Ethan Furman wrote:

  Even if we find out that C.__nonzero__ is called, what was it that
  __nonzero__ did again?

reinforce the impression that he is unaware of the double-underscore 
functions and what they do and how they work.  


Only if your newsreader malfunctioned and refused to let you read the rest of 
the paragraph.


Of course I know what __nonzero__ does.

regards, Anders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-29 Thread Anders J. Munch

Steven D'Aprano wrote:

On Tue, 29 Jul 2008 00:23:02 +, Steven D'Aprano wrote:


Dude. Dude. Just... learn some Python before you embarrass yourself
further.



I'm sorry Anders, that was a needlessly harsh thing for me to say. I 
apologize for the unpleasant tone. 

Still, __nonzero__ is a fundamental part of Python's behaviour. You 
should learn about it.


Hm, first you apologize, then you repeat the insult?  That's no basis for a 
conversation.  Bye from here.


regards, Anders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Boolean tests [was Re: Attack a sacred Python Cow]

2008-07-28 Thread Anders J. Munch

Steven D'Aprano wrote:

On Sun, 27 Jul 2008 23:45:26 -0700, Carl Banks wrote:


I want something where if x will do but a simple explicit test won't.


Explicit tests aren't simple unless you know what type x is. 


If you don't even know a duck-type for x, you have no business invoking any 
methods on that object.


If you do know a duck-type for x, then you also know which explicit test to 
perform.

Explicit tests are not necessarily simple for custom classes. Testing for 
emptiness could be arbitrarily complex. That's why we have __nonzero__, 
so you don't have to fill your code with complex expressions like (say)


if len(x.method()[x.attribute])  -1

Instead you write it once, in the __nonzero__ method, and never need to 
think about it again.


Okay, so you have this interesting object property that you often need to test 
for, so you wrap the code for the test up in a method, because that way you only 
need to write the complex formula once.  I'm with you so far.  But then you 
decide to name the method __nonzero__, instead of some nice descriptive name? 
 What's up with that?


This is the kind of code I would write:
   class C:
  def attribute_is_nonnegative(self):
 return len(self.method()[self.attribute])  -1
   ...
   c = get_a_C()
   if c.attribute_is_nonnegative():
  ...

Now suppose you were reading these last few lines and got to wondering if 
get_a_C might ever return None.


The answer is obviously no.  get_a_C must always return a C object or something 
compatible.  If not, it's a bug and an AttributeError will ensue.  The code 
tells you that.  By giving the method a name the intent of the test is perfectly 
documented.


In comparison, I gather you would write something like this:
   class C:
  def __nonzero__(self):
 return len(self.method()[self.attribute])  -1
   ...
   c = get_a_C()
   if c:
  ...

Again, the question is, can get_a_C return None?  Well that's hard to say 
really.  It could be that if c is intended to test for None.  Or it could be 
intended to call C.__nonzero__.  Or it could be cleverly intended to test 
not-None and C.__nonzero__ at the same time.  It may be impossible to discern 
the writer's true intent.


Even if we find out that C.__nonzero__ is called, what was it that __nonzero__ 
did again?  Did it test for the queue being non-empty?  Did it test for the 
queue being not-full?  Did it test whether for the consumer thread is running? 
Did it test for if there are any threads blocked on the queue?  Better dig up 
the class C documentation and find out, because there is no single obvious 
interpretation of what is means for an object to evaluate to true.


if x is simple to type, but not so simple to read. if x.namedPredicate() is 
harder to type, but easier to read.  I prefer the latter because code is read 
more often than it is written.


regards,
Anders
--
http://mail.python.org/mailman/listinfo/python-list


Re: Rant (was Re: x*x if x10

2008-07-27 Thread Anders J. Munch

Gary Herron wrote:

  A = [1,2,3]
  B = [4,5,6]
  C = [7,8,9]

  A+B+C
[1, 2, 3, 4, 5, 6, 7, 8, 9]

  sum([A,B,C], [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]


Careful now, this can be very slow.  sum uses __add__, not __iadd__, which gives 
this approach quadratic worst-case runtime.


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


Re: Recursion Performance Question

2008-07-24 Thread Anders J. Munch

B wrote:

 # pass in window handle and parent node
 def gwl(node, hwnd):
 if hwnd:
 yield node, hwnd
 for nd, wnd in Wnd.gwl(node.children[-1], GetWindow(hwnd,
 GW_CHILD)):
 yield nd, wnd
 for nd, wnd in Wnd.gwl(node, GetWindow(hwnd, GW_HWNDNEXT)):
 yield nd, wnd
[...]

 Now it works, but it runs quite slow (compared to the c++ app).  I
 changed gwl from strait recursion to use a generator and that helped,
 but it still takes 0.5-1.0 seconds to populate the tree.

Actually the generator could well be the problem here, because of time
spent on yield propagation: gwl has worst-case quadratic
performance, the worst case being if the tree is unbalanced and deep,
because every yielded value must pass through a chain of propagation
for-loops.

Straight recursion should be faster; I don't know what you did to make
it slow, but try something along these lines:

def gwl_helper(node, hwnd, collect):
if hwnd:
collect((node,hwnd))
gwl_helper(node.children[-1], GetWindow(hwnd, GW_CHILD), collect)
gwl_helper(node, GetWindow(hwnd, GW_HWNDNEXT), collect)

def gwl(node, hwnd):
result = []
gwl_helper(node, hwnd, result.append)
return result

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


Re: Python's only one way to do it philosophy isn't good?

2007-06-13 Thread Anders J. Munch
Neil Cerutti wrote:
 On 2007-06-12, Anders J. Munch [EMAIL PROTECTED] wrote:
 Converting tail-recursion to iteration is trivial, and
 perfectly reasonable for a human to do by hand.  
 
 For simple recursive tail calls, yeah, it can be. Translating a
 tail-recursive Factorial function into a while loop is easy. But
 tail-call optimization technically works for any tail-call,
 including mutual recursion, and non-recursive tail-calls. You
 can't reasonably hand-optimize away the stack frame for all
 tail-calls.

I may have misunderstood, I thought we were talking about tail recursion only. 
The general tail-call optimisation, where all leaf calls become jumps and the 
called function usurps the current stack frame, is a different ballgame 
entirely.  There's no pure-Python transformation for that, but that still 
doesn't mean you need CPS.

General tail-call optimisation is of course completely out-of-bounds for 
Python, 
because it ruins tracebacks.  Unlike tail recursion, which could use recursion 
counters.

- Anders

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


Re: Python's only one way to do it philosophy isn't good?

2007-06-13 Thread Anders J. Munch
Alexander Schmolck wrote:
 Anders J. Munch [EMAIL PROTECTED] writes:
 
 Like Steven said, tail-call optimisation is not necessary as you can always
 hand-optimise it yourself.
 
 Care to demonstrate on some code written in CPS (a compiler or parser, say)?

I meant tail recursion, not tail-call, sorry, that was just my fingers trying 
to 
save typing.

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


Re: Python's only one way to do it philosophy isn't good?

2007-06-12 Thread Anders J. Munch
Paul Rubin wrote:
 Steven D'Aprano [EMAIL PROTECTED] writes:
 Not tail calls, in general, no.
 Sorry, how does that work? You're suggesting that there is an algorithm
 which the compiler could follow to optimize away tail-recursion, but human
 beings can't follow the same algorithm?

 Now I'm confused.
 
 The usual compiler method is to translate the code into
 continuation-passing style and thereby gain tail-recursion
 optimization automagically.  

There's no need to go into CPS just to optimise tail-recursion.  After all, 
compilers were optimising tail-calls decades before Appel's work on SML/NJ.

Converting tail-recursion to iteration is trivial, and perfectly reasonable for 
a human to do by hand.  You add an outer while True-loop, the recursive call 
becomes a tuple assignment, and other code paths end with a break out of the 
loop.  Completely mechanical and the resulting code doesn't even look that bad.

Like Steven said, tail-call optimisation is not necessary as you can always 
hand-optimise it yourself.

- Anders

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


Re: Where can I suggest an enchantment for Python Zip lib?

2007-06-10 Thread Anders J. Munch
durumdara wrote:
 Only one way I have to control this: if I modify the ZipFile module.

Since you already have the desired feature implemented, why don't you submit a 
patch.

See http://www.python.org/patches/

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


Re: PEP 3131: Supporting Non-ASCII Identifiers

2007-05-14 Thread Anders J. Munch
Eric Brunel wrote:
 You could tell that the rule should be that if the project has the 
 slightest chance of becoming open-source, or shared with people not 
 speaking the same language as the original coders, one should not use 
 non-ASCII identifiers. I'm personnally convinced that *any* industrial 
 project falls into this category. So accepting non-ASCII identifiers is 
 just introducing a disaster waiting to happen.

Not at all.  If the need arises, you just translate the whole thing.  Contrary 
to popular belief, this is a quick and easy thing to do.

So YAGNI applies, and even if you find that you do need it, you may still have 
won on the balance! As the time saved by using your native language just might 
outweigh the time spent translating.

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


Re: PEP 3131: Supporting Non-ASCII Identifiers

2007-05-14 Thread Anders J. Munch
Hendrik van Rooyen wrote:
 And we have been through the Macro thingy here, and the consensus
 seemed to be that we don't want people to write their own dialects.

Macros create dialects that are understood only by the three people in your 
project group.  It's unreasonable to compare that to a dialect such as 
Mandarin, which is exclusive to a tiny little clique of one billion people.

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


Re: PEP 3131: Supporting Non-ASCII Identifiers

2007-05-13 Thread Anders J. Munch
Josiah Carlson wrote:
 On the other hand, the introduction of some 60k+ valid unicode glyphs 
 into the set of characters that can be seen as a name in Python would 
 make any such attempts by anyone who is not a native speaker (and even 
 native speakers in the case of the more obscure Kanji glyphs) an 
 exercise in futility.
 

So you gather up a list of identifiers and and send out for translation.  
Having 
actual Kanji glyphs instead a mix of transliterations and bad English will only 
make that easier.

That won't even cost you anything, since you were already having docstrings 
translated, along with comments and documentation, right?

 But this issue isn't limited to different characters sharing glyphs! 
 It's also about being able to type names to use them in your own code 
 (generally very difficult if not impossible for many non-Latin 
 characters), or even be able to display them.

For display, tell your editor the utf-8 source file is really latin-1.  For 
entry, copy-paste.

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


Re: PEP 3131: Supporting Non-ASCII Identifiers

2007-05-13 Thread Anders J. Munch
Michael Torrie wrote:
 
 So given that people can already transliterate their language for use as
 identifiers, I think avoiding non-ASCII character sets is a good idea.

Transliteration makes people choose bad variable names, I see it all the time 
with Danish programmers.  Say e.g. the most descriptive name for a process is 
kør forlæns (run forward).  But koer_forlaens is ugly, so instead he'll 
write run_fremad, combining an English word with a slightly less appropriate 
Danish word.  Sprinkle in some English spelling errors and badly-chosen English 
words, and you have the sorry state of the art that is today.

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


Re: PEP 3131: Supporting Non-ASCII Identifiers

2007-05-13 Thread Anders J. Munch
Alex Martelli wrote:
 
 Homoglyphic characters _introduced by accident_ should not be discounted
 as a risk, as, it seems to me, was done early in this thread after the
 issue had been mentioned.  In the past, it has happened to me to
 erroneously introduce such homoglyphs in a document I was preparing with
 a word processor, by a slight error in the use of the system- provided
 way for inserting characters not present on the keyboard; I found out
 when later I went looking for the name I _thought_ I had input (but I
 was looking for it spelled with the right glyph, not the one I had
 actually used which looked just the same) and just could not find it.

There's any number of things to be done about that.
1. # -*- encoding: ascii -*-
(I'd like to see you sneak those homoglyphic characters past *that*.)
2. pychecker and pylint - I'm sure you realise what they could do for you.
3. Use a font that doesn't have those characters or deliberately makes them 
distinct (that could help web browsing safety too).

I'm not discounting the problem, I just dont believe it's a big one.  Can we 
chose a codepoint subset that doesn't have these dupes?

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


Re: merits of Lisp vs Python

2006-12-21 Thread Anders J. Munch
Rob Thorpe wrote:
 Anders J. Munch wrote:
 Let u(t) be the actual memory used by the program at time t.
 Let r(t) be the size of reachable memory at time t.

 Require that u(t) is a member of O(t - max{t'=t: r(t')})

 There. That wasn't so hard, was it?
 
 That's quite a clever definition actually.
 But, let's say I have a lisp machine.  It has an unusual architecture,
 it's made entirely of SRAM cells of ~9bits.  Sometimes these cells are
 used as storage, sometimes their contents represent logic circuits and
 the routing between them is configured to form them into a processor.
 Please tell me what reachable memory is ;).  (The above processor is
 not science fiction, it could easily be done with FPGAs)

Reachable memory is the set of interpreter objects (conses, closures, scopes, 
atoms and what have you) reachable from from some appropriately defined root 
set.  It can be unambiguously defined with respect to a virtual machine, with 
no 
regard to how actual implementations represent these things.

For actual memory use, a simple byte count would do fine.  If code and data are 
intermingled, just use the combined size of both of them.

If you're worried about comparing incompatible units, don't be: apples and 
oranges compare just fine under big-Oh.

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


Re: merits of Lisp vs Python

2006-12-20 Thread Anders J. Munch
jayessay wrote:
   Please note: GC is not part of CL's definition.  It is likely not part
 of any Lisp's definition (for reasons that should be obvious), and for
 the same reasons likely not part of any language's definition.  

Really?  So how do you write a portable program in CL, that is to run 
for unbounded lengths of time?

- Anders

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


Re: merits of Lisp vs Python

2006-12-20 Thread Anders J. Munch
Rob Thorpe wrote:
  Anders J. Munch wrote:
  Really?  So how do you write a portable program in CL, that is to
  run for unbounded lengths of time?
 
  You can't.
 
  The thing about the spec not defining GC is almost a bit of humour.
  No-one would use an implementation with no GC.
 
  The issue with specifying it is: How would you do it?  The memory
  used by a program is an aspect of the language implementation and
  the system the program is running on, so how can it be defined in a
  useful way?

Let u(t) be the actual memory used by the program at time t.
Let r(t) be the size of reachable memory at time t.

Require that u(t) is a member of O(t - max{t'=t: r(t')})

There. That wasn't so hard, was it?

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


Re: enumerate improvement proposal

2006-10-30 Thread Anders J. Munch
Ben Finney wrote:
 
  def obstinate_economist_enumerate(items):
 ... enum_iter = iter((i+1, x) for (i, x) in enumerate(items))
 ... return enum_iter

iter is redundant here.

def natural_enumerate_improvement(items, start=0):
 return ((i+start, x) for (i, x) in enumerate(items))

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


Re: QuoteSQL

2006-09-24 Thread Anders J. Munch
Robert Kern wrote:
 Anders J. Munch wrote:
 
 Always sad to see an SQL DBMS willfully violate the SQL standard.
 
 You must be a constantly depressed person, then.  :-)

Nah, I just look the other way most of the time *g*

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


Re: QuoteSQL

2006-09-24 Thread Anders J. Munch
Lawrence D'Oliveiro wrote:
 elif Ch == ' or Ch == \ or Ch == \\ :
 Ch = \\ + Ch
 Always sad to see an SQL DBMS willfully violate the SQL standard.
 
 Why is that a violation of SQL?

Taking another look, I might be wrong: Your code uses double quotes, and 
since SQL uses single quotes for string literals, it just might be a 
compatible extension.

Otherwise I would have taken note of the backslash escapes.  E.g. '\\' 
is a two-character SQL string literal.

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


Re: QuoteSQL

2006-09-23 Thread Anders J. Munch
Lawrence D'Oliveiro wrote:
 Why doesn't MySQLdb provide a function like this:
 
 def QuoteSQL(Str, DoWild) :
 returns a MySQL string literal which evaluates to Str. Needed
 for those times when MySQLdb's automatic quoting isn't good enough.

Presumably because you're expected to use placeholders.  When is that 
not good enough?

 elif Ch == ' or Ch == \ or Ch == \\ :
 Ch = \\ + Ch

Always sad to see an SQL DBMS willfully violate the SQL standard.

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


Relative import first impressions

2006-09-23 Thread Anders J. Munch
Now 2.5 is out, and we have a syntax for explicit relative imports
(PEP 328, http://www.python.org/dev/peps/pep-0328/, in case anyone
wasn't paying attention).  The long-term plan is that the classical
import syntax becomes absolute import only, so that all imports are
explicitly one or the other.

You can only use relative import from within packages.  Trying to
import a top-level module relatively from within same directory,
produces the exception ValueError: Relative importpath too deep.

There's a certain logic to that: You can just omit from . and do a
regular absolute import.  However, that spells bad news for modules
that are both contained within packages, and executed from the top
level as well.

Accessing the same module both from within a package and outside it
may seem like a bad idea, and in many ways, it is.  You may get a
double import of the same module with subtle, mysterious bugs to
follow, when e.g. you suddenly have two copies of the same class,
and isinstance(obj,mymodule.Cls) fails unexpectedly.

But it's quite common all the same: The
if __name__ == __main__:
idiom is often used, even within packages.  But that is currently
incompatible with using relative imports.  It seems to me that unless
we rethink the main idiom competely (which may not be a bad idea by
the way, for the reasons given above), relative imports at the top
level will need to be allowed.

Another addition I'd like to see it the import .foo form.  Currently
only from-imports have a relative form.  The argument against is
that import X binds the name X, and it's not clear which name the
relative import binds.

I move that it's blindingly obvious: import .foo binds foo,
equivalent to from . import foo.  Did anyone really expect the name
.foo to be bound?

It's not a big deal though, as you only need to type from . once per
module anyway.  Using another improvement in 2.5, you can now write:

from . import (
 this,
 that,
 )

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


Re: Newbie question on code vetting

2006-05-07 Thread Anders J. Munch
[EMAIL PROTECTED] wrote:
 As it is now,
 one is pretty much left to rummage around on project web sites trying to get
 a gut feel for what is going on. Asking the higher-ups at work to reach
 technology management decisions based on my gut feel is an uphill climb. 

So what you need is a document that more or less formalises what you
already know from rummaging around.

The place for such a document would be the meta-PEP section at
http://python.org/peps/.

If the information you seek is in none of the existing meta-PEPs, that's
probably because noone has yet felt the need for such a document bad
enough to make the effort and write one.  Until you came along, that is.
So why don't you write a new PEP (or suggest changes to an existing
PEP) with the information you need?  You may not have all the answers,
but if you have good questions that's a pretty good start.

 From an earlier post:
 Is there any use of tools like BlackDuck ProtexIP or the
 competing Palamida product to scan for matches to code that is already
 licensed elsewhere?

If you have access to such tools, why don't you just scan the CPython
sources yourself?  And make the results available to the community, of
course.

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


Re: Speed ain't bad

2005-01-04 Thread Anders J. Munch
John Machin [EMAIL PROTECTED] wrote:
 1. Robustness: Both versions will crash (in the sense of an unhandled
 2. Efficiency: I don't see the disk I/O inefficiency in calling

3. Don't itemise perceived flaws in other people's postings. It may
give off a hostile impression.

 1. Robustness: Both versions will crash (in the sense of an unhandled
 exception) in the situation where zfdir exists but is not a directory.
 The revised version just crashes later than the OP's version :-(
 Trapping EnvironmentError seems not very useful -- the result will not
 distinguish (on Windows 2000 at least) between the 'existing dir' and
 'existing non-directory' cases.

Good point; my version has room for improvement. But at least it fixes
the race condition between isdir and makedirs.

What I like about EnvironmentError is that it it's easier to use than
figuring out which one of IOError or OSError applies (and whether that
can be relied on, cross-platform).

 2. Efficiency: I don't see the disk I/O inefficiency in calling
 os.path.isdir() before os.makedirs() -- if the relevant part of the
 filesystem wasn't already in memory, the isdir() call would make it
 so, and makedirs() would get a free ride, yes/no?

Perhaps. Looking stuff up in operating system tables and buffers takes
time too. And then there's network latency; how much local caching do
you get for an NFS mount or SMB share?

If you really want to know, measure.

- Anders


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


Re: Speed ain't bad

2005-01-01 Thread Anders J. Munch
Bulba! [EMAIL PROTECTED] wrote:

 One of the posters inspired me to do profiling on my newbie script
 (pasted below). After measurements I have found that the speed
 of Python, at least in the area where my script works, is surprisingly
 high.

Pretty good code for someone who calls himself a newbie.

One line that puzzles me:
 sfile=open(sfpath,'rb')

You never use sfile again.
In any case, you should explicitly close all files that you open. Even
if there's an exception:

sfile = open(sfpath, 'rb')
try:
stuff to do with the file open
finally:
sfile.close()


 The only thing I'm missing in this picture is knowledge if my script
 could be further optimised (not that I actually need better
 performance, I'm just curious what possible solutions could be).

 Any takers among the experienced guys?

Basically the way to optimise these things is to cut down on anything
that does I/O: Use as few calls to os.path.is{dir,file}, os.stat, open
and such that you can get away with.

One way to do that is caching; e.g. storing names of known directories
in a set (sets.Set()) and checking that set before calling
os.path.isdir.  I haven't spotted any obvious opportunities for that
in your script, though.

Another way is the strategy of it's easier to ask forgiveness than to
ask permission.
If you replace:
if(not os.path.isdir(zfdir)):
os.makedirs(zfdir)
with:
try:
os.makedirs(zfdir)
except EnvironmentError:
pass

then not only will your script become a micron more robust, but
assuming zfdir typically does not exist, you will have saved the call
to os.path.isdir.

- Anders


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