Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

question of style

 

 

First page Previous page 1 2 3 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded


lie.1296 at gmail

Jul 2, 2009, 11:33 PM

Post #26 of 65 (948 views)
Permalink
Re: question of style [In reply to]

Paul Rubin wrote:
> Generally, having a special
> value like None to denote a missing datum was considered standard
> practice a few decades ago,

I guess in python, None as the missing datum idiom is still quite prevalent:

def cat_list(a=None, b=None):
# poor man's list concatenation
if a is None and b is None: return []
if a is None: return b
if b is None: return a
return a + b
--
http://mail.python.org/mailman/listinfo/python-list


lie.1296 at gmail

Jul 2, 2009, 11:37 PM

Post #27 of 65 (948 views)
Permalink
Re: question of style [In reply to]

Lie Ryan wrote:
> Tim Harig wrote:
>>> Speaking only to the style issue, when I've wanted to do something like
>>> that, I find:
>>> if self.higher is None is self.lower:
>>> more readable, by making clear they are both being compared to a
>>> constant, rather than compared to each other.
>> By comparing them to *any* constant with 'is' you end up with the same
>> potential problems as to whether something with a value of None is actually
>> None?
>
> Oh really? None is a Singleton and all None always point to the same
> None object. And the fact that it is impossible to override `is`
> operator is the reason for the "is None" idiom.
>

http://docs.python.org/c-api/none.html
--
http://mail.python.org/mailman/listinfo/python-list


lie.1296 at gmail

Jul 2, 2009, 11:40 PM

Post #28 of 65 (948 views)
Permalink
Re: question of style [In reply to]

Paul Rubin wrote:
> Tim Harig <usernet [at] ilthio> writes:
>> That being the case, it might be a good idea either to handle the situation
>> and raise an exception or add:
>>
>> assert self.lower <= self.higher
>>
>> That way an exception will be raised if there is an error somewhere else
>> in the code rather then silently passing a possibly incorrect value.
>
> Well, that assert is not right because you have to handle the case
> where one of the values is None. The general sentiment is reasonable
> though, if you're concerned that the precondition may not be valid.

Well, it depends on where you put the assert statement. If your code is
like this:

if self.higher is self.lower is None: return
if self.lower is None: return self.higher
if self.higher is None: return self.lower
assert self.lower <= self.higher

then the assert statement is correct.

Some people might prefer to keep all asserts at the top of function though.
--
http://mail.python.org/mailman/listinfo/python-list


lie.1296 at gmail

Jul 2, 2009, 11:47 PM

Post #29 of 65 (947 views)
Permalink
Re: question of style [In reply to]

Simon Forman wrote:
> Hey I was hoping to get your opinions on a sort of minor stylistic
> point.
> These two snippets of code are functionally identical. Which would you
> use and why?

If self is an object (and it must have been), it would be preferrable to
set self.higher and self.lower to a known value inside self.__init__ and
avoid having the comparison.

I'm guessing you have something like this in your __init__:

def __init__(self, lower=None, higher=None):
self.lower = lower
self.higher = higher


that should be changed to:

def __init__(self, lower=None, higher=None):
self.lower = lower if lower is not None else higher
self.higher = higher if lower is not None else lower

or whatever else-value you see is appropriate for the context.
--
http://mail.python.org/mailman/listinfo/python-list


http://phr.cx at NOSPAM

Jul 3, 2009, 12:27 AM

Post #30 of 65 (949 views)
Permalink
Re: question of style [In reply to]

Lie Ryan <lie.1296 [at] gmail> writes:
> I guess in python, None as the missing datum idiom is still quite prevalent:

Well, sometimes there is no way around it, but:

> def cat_list(a=None, b=None):
> # poor man's list concatenation
> if a is None and b is None: return []
> if a is None: return b
> if b is None: return a
> return a + b

def cat_list(a=[], b=[]):
return a + b
--
http://mail.python.org/mailman/listinfo/python-list


steve at REMOVE-THIS-cybersource

Jul 3, 2009, 12:50 AM

Post #31 of 65 (945 views)
Permalink
Re: question of style [In reply to]

On Thu, 02 Jul 2009 21:56:40 -0700, Paul Rubin wrote:

>> Well I wouldn't know, I've been fortunate enough to program mostly in
>> python for over half a decade now and None and 0 are as close as I've
>> gotten to NULL in a long time.
>
> Right, and how many times have you had to debug
>
> AttributeError: 'NoneType' object has no attribute 'foo'

Hardly ever, and mostly when I do something silly like:

another_list = alist.sort()

Of course, YMMV.



> or the equivalent null pointer exceptions in Java, C, or whatever? They
> are very common. And the basic idea is that if you avoid using null
> pointers in the first place, you'll get fewer accidental null pointer
> exceptions.

And some other error instead, due to the bugs in your more complicated
code *wink*



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


lie.1296 at gmail

Jul 3, 2009, 1:06 AM

Post #32 of 65 (950 views)
Permalink
Re: question of style [In reply to]

Paul Rubin wrote:
> Lie Ryan <lie.1296 [at] gmail> writes:
>> I guess in python, None as the missing datum idiom is still quite prevalent:
>
> Well, sometimes there is no way around it, but:
>
>> def cat_list(a=None, b=None):
>> # poor man's list concatenation
>> if a is None and b is None: return []
>> if a is None: return b
>> if b is None: return a
>> return a + b
>
> def cat_list(a=[], b=[]):
> return a + b

Being super contrived is why I tagged it as poor man's concat.
Generally, there will be a processing:

...
if b is None: return a
# processing here
return retlist
...

and it will not be about concatenating two lists, but something more
complex. But I thought that was unnecessary since I just want to mention
about the None argument idiom.
--
http://mail.python.org/mailman/listinfo/python-list


steve at REMOVE-THIS-cybersource

Jul 3, 2009, 1:18 AM

Post #33 of 65 (950 views)
Permalink
Re: question of style [In reply to]

On Thu, 02 Jul 2009 22:14:18 +0000, Tim Harig wrote:

> On 2009-07-02, Paul Rubin <http> wrote:
>> Tim Harig <usernet [at] ilthio> writes:
>>> If lower is 5 and higher is 3, then it returns 3 because 3 != None in
>>> the first if.
>> Sorry, the presumption was that lower <= higher, i.e. the comparison
>> had already been made and the invariant was enforced by the class
>> constructor. The comment should have been more explicit, I guess.
>
> That being the case, it might be a good idea either to handle the
> situation and raise an exception or add:
>
> assert self.lower <= self.higher

Only if you want strange and mysterious bugs whenever somebody runs your
code with the -O flag.


> That way an exception will be raised if there is an error somewhere else
> in the code rather then silently passing a possibly incorrect value.

asserts are disabled when the -O flag is given.

You should never use asserts for testing data. That's not what they're
for. They're for testing program logic (and unit-testing).

This is wrong, because it will sometimes fail when running under -O:

def parrot(colour):
assert colour.lower() in ('red', 'green', 'blue')
return "Norwegian %s" % colour.title()

That should be written as test followed by an explicit raise:

def parrot(colour):
if colour.lower() not in ('red', 'green', 'blue'):
raise ValueError
return "Norwegian %s" % colour.title()


An acceptable use for assert is to verify your program logic by testing
something which should never fail. If it does fail, then you know
something bizarre and unexpected has happened, and you have a program bug
rather than bad data. Here's a silly example:


def cheese_available(kind):
"""Return True if the kind of cheese specified is in stock
in the cheeseshop run by Michael Palin.

This function always returns False.
"""
return False


def get_cheese():
exchange_amusing_banter()
for kind in ('Cheddar', 'Gouda', 'Swiss', 'Camembert'):
ask_proprietor("Do you have any %s?" % kind)
flag = cheese_available(kind)
assert not flag
if flag:
buy_cheese(kind)
return None
else:
express_disappointment()
# We only get here if no cheese is bought.
print "Cleese: Does this cheeseshop actually have ANY cheese?"
print "Palin: No sir, I'm afraid I've been wasting your time."
print "Cleese: Well then, I'm going to have to shoot you."



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


usernet at ilthio

Jul 3, 2009, 2:07 AM

Post #34 of 65 (949 views)
Permalink
Re: question of style [In reply to]

On 2009-07-03, Steven D'Aprano <steve [at] REMOVE-THIS-cybersource> wrote:
> On Thu, 02 Jul 2009 22:14:18 +0000, Tim Harig wrote:
>> On 2009-07-02, Paul Rubin <http> wrote:
>>> Tim Harig <usernet [at] ilthio> writes:
>>>> If lower is 5 and higher is 3, then it returns 3 because 3 != None in
>>>> the first if.
>>> Sorry, the presumption was that lower <= higher, i.e. the comparison
>>> had already been made and the invariant was enforced by the class
>>> constructor. The comment should have been more explicit, I guess.
>> That being the case, it might be a good idea either to handle the
>> situation and raise an exception or add:
>> assert self.lower <= self.higher
> Only if you want strange and mysterious bugs whenever somebody runs your
> code with the -O flag.

The point here is that Rubin presumed that the condition where lower >
higher should never exist. Therefore, because the program given segment of
program doesn't test it elswhere, it is possible that a bug in the code
that sets lower > higher could go unoticed while silently passing the wrong
data.

Therefore, It is better to test that assumption in a way that *will* crash
if something is wrong, for instance, if another method accidently changes
one of the values. That would tend to make errors in another method of the
class (or even higher up in this method), more likely to be found.

> asserts are disabled when the -O flag is given.

Right, like defining NDEBUG in C. In _Writing Solid Code_ by Steve
Maguire, he likens it to having two pieces of code: one for testing where
any errors should cause crashes as early as possible and one for shipping
where it may be better to handle errors if possible from within the code.

> You should never use asserts for testing data. That's not what they're
> for. They're for testing program logic (and unit-testing).

What I am suggesting here is exactly that. If lower is always defined such
that it should always be equal to or lower then higher, then there is an
error in the code somewhere if lower is higher by the time this code is
called. Either the constructor didn't didn't reject input properly or
another method within the class has inadvertantly changed higher or lower
in an uncorrect way.

In any event, whether I am using it 100% correctly, I want to find any
errors in my code. If there is an error, I want the program to crash
during testing rather then silently passing bad data. assert will help
here.

Unfortunatly, Rubin is right. I did make the mistake that the assert will
fail with higher or lower values of None, which is allowed here. The same
basic premise is correct but will require more complex assertions to allow
that through.
--
http://mail.python.org/mailman/listinfo/python-list


jeanmichel at sequans

Jul 3, 2009, 3:33 AM

Post #35 of 65 (948 views)
Permalink
Re: question of style [In reply to]

Simon Forman wrote:
> Hey I was hoping to get your opinions on a sort of minor stylistic
> point.
> These two snippets of code are functionally identical. Which would you
> use and why?
> The first one is easier [for me anyway] to read and understand, but
>
Easier for you but not for those who are familiar with the standard way
of python coding. (by standard I don't mean the "only Godly way of
coding", there's room for custom rules)
But I think most of the people will write:
if self.higher is None:
return self.lower
if self.lower is None:
return self.higher
# here neither are None

> slightly less efficient, while the second is [marginally] harder to
> follow but more efficient.
>
> ## First snippet
>
> if self.higher is self.lower is None: return
> if self.lower is None: return self.higher
> if self.higher is None: return self.lower
>
> ## Second snippet
>
> if self.higher is None:
> if self.lower is None:
> return
> return self.lower
> if self.lower is None:
> return self.higher
>
> What do you think?
>
> (One minor point: in the first snippet, the "is None" in the first
> line is superfluous in the context in which it will be used, the only
> time "self.lower is self.higher" will be true is when they are both
> None.)
>

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


sajmikins at gmail

Jul 3, 2009, 1:04 PM

Post #36 of 65 (932 views)
Permalink
Re: question of style [In reply to]

On Jul 3, 2:09 am, Lie Ryan <lie.1...@gmail.com> wrote:
> Simon Forman wrote:
> > On Jul 2, 3:57 pm, Scott David Daniels <Scott.Dani...@Acm.Org> wrote:
> >> Duncan Booth wrote:
> >>> Simon Forman <sajmik...@gmail.com> wrote:
> >>>> ...
> >>>> if self.higher is self.lower is None: return
> >>>> ...
> >>> As a matter of style however I wouldn't use the shorthand to run two 'is'
> >>> comparisons together, I'd write that out in full if it was actually needed
> >>> here.
> >> Speaking only to the style issue, when I've wanted to do something like
> >> that, I find:
>
> >>        if self.higher is None is self.lower:
> >>            ...
>
> >> more readable, by making clear they are both being compared to a
> >> constant, rather than compared to each other.
>
> > I was going to do it that way for aesthetics if nothing else, but in
> > this particular code "self.higher is self.lower" could only have been
> > True if they were both None, so the final "is None" was redundant and
> > I only included it as a "just-in-case" check in case someone someday
> > used the code in such a way as to assign the same object (not None) to
> > both self.higher and self.lower...  Totally pointless, I'm sorry to
> > say.  I'm glad the whole line was redundant really.
>
> I say, you should keep the `is None` for readability and to safe guard
> against immutable optimization and/or Singleton objects. Due to an
> implementation detail, python does not guarantee that two immutable
> object will return different objects; you have:
>
> >>> a = 1
> >>> b = 1
> >>> a is b
>
> True

I probably would have kept the 'is None' for those reasons except that
this code was never meant to be used by anyone but me, and it turned
out the entire line was redundant anyway. :]
--
http://mail.python.org/mailman/listinfo/python-list


sajmikins at gmail

Jul 3, 2009, 1:17 PM

Post #37 of 65 (933 views)
Permalink
Re: question of style [In reply to]

On Jul 3, 12:56 am, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> Simon Forman <sajmik...@gmail.com> writes:
> > > Yes, but the concept of null pointers is considered kludgy these days.
> > Seriously? "kludgy"?  (I really AM getting old.)
>
>  http://math.andrej.com/2009/04/11/on-programming-language-design/
>
> discusses the issue (scroll down to "Undefined values" section).

Hmm, I'm not convinced. I read that post with interest, but his
argument against None et. al. was just this:

"...stick to the principle: NULL is wrong because it causes horrible
and tricky mistakes which appear even after the program was tested
thoroughly. You cannot introduce NULL into the language and tell the
programmer to be careful about it. The programmer is not capable of
being careful!"

To me that seems weak and too general, you could say /anything/
"...causes horrible and tricky mistakes which appear even after the
program was tested thoroughly."

He does go on to say, in a reply to a comment, "In my opinion, at the
end of the day the quality of the code depends more on the quality of
its author than on the quality of the language he uses. But this does
not mean that the quality of the programming language does not
matter."

Which I agree with wholeheartedly. I just don't see that he made a
strong case that the inclusion of NULLs directly implies poor quality
of language.

(I like Haskell's Maybe, but saying A is better than B doesn't imply
that B is therefore terrible.)



> > Well I wouldn't know, I've been fortunate enough to program mostly in
> > python for over half a decade now and None and 0 are as close as I've
> > gotten to NULL in a long time.
>
> Right, and how many times have you had to debug
>
>    AttributeError: 'NoneType' object has no attribute 'foo'
>
> or the equivalent null pointer exceptions in Java, C, or whatever?
> They are very common.  And the basic idea is that if you avoid using
> null pointers in the first place, you'll get fewer accidental null
> pointer exceptions.

I have encountered exceptions like that, but usually as a result of
e.g. omitting a return statement (so the caller gets None instead of
whatever should have been returned.)

I don't usually write "pointer" style code in python. In fact, other
than this BTree and the Dancing Links algorithm I mentioned earlier I
can't recall ever having done it. Indeed, python's omission of
pointers is one of the reasons I'm so fond of it.

In my experience with python exceptions like that one are indicators
of something bad wrong with my code, not of misuse of None (as NULL
pointer.)



> > That sounds very interesting, but I'm only writing a BTree to then use
> > it to play with "persistent data structures"
>
> But you have implemented a mutable tree.  If you want to write a
> persistent one, then write a persistent one!  You also use a wishful

The paper I'm working from is about general techniques for making
persistent data structures from mutable forms, thus I wanted a mutable
BTree to then "overwrite" with a persistent form.


> heuristic in the hope of keeping the tree balanced--if you want a
> balanced tree, why not use one that's guaranteed to stay in balance?
> AVL trees are pretty easy to implement; maybe you could try writing a
> persistent one:
>
>  http://en.wikipedia.org/wiki/AVL_tree

The balance (or lack thereof) of the tree is not important (in this
use.) I threw in that heuristic in the delete function because it was
easy enough and it was mentioned in the wikipedia article on BTrees.
AVL trees are easy too, but still more complicated than I need.


> > In this particular case it's somewhat more elegant (IMO) to check "is
> > None".
>
> Well, I can't understand why that might be, but it's surely
> subjective, so ok.

It's a matter of this:

if a is None:
return b
if b is None:
return a
# handle both non-None here...

vs. this:

if a is not None:
if b is not None:
# handle both non-None here...
else:
return a
return b

Everything is subjective, but I think the first one is more elegant
IMO.



> > > I'm sorry but I find that class rather ugly.  The code would be a lot
> > > smaller and have fewer corner cases with a different data representation.
>
> > Um, thanks?  Seriously though, care to put your money where your mouth
> > is? I'd be interested to see a BTree implemented as you indicated above.
>
> Er, I'm not trying to argue with you.  You asked for people's advice
> and impressions, so I gave you some.  I don't feel like rewriting that

I know, I asked for it. :] But it still stings a little to hear
someone call my code "rather ugly". No hard feelings. I'm not trying
to argue with you either. :]


> whole class, but I'll do a method or two, using [] to represent an
> empty node.  (Hmm, actually changing the empty node representation did
> less to shorten the code than just getting rid of a bunch of
> duplication.  Really, I'd tend to look for a slightly different tree
> structure which tried to avoid these issues).

Hmm, I really don't see that using an empty list rather than None as a
stand-in for NULL pointer bought you anything there. In fact, this
code would work identically if you replaced [] with None.

I was hoping to see some clever code-fu involving list manipulation or
something. When would you ever store a value in the empty list
"nodes" anyway?

> Untested:
>
> class BinaryTree:
>     def __init__(self, key, value):
>         self.key = key
>         self.value = value
>         self.higher = self.lower = []
>
>     def get(self, key):
>         if key == self.key:
>             return self.value
>         branch = self.lower if key < self.key else self.higher
>         return branch.get(key) if branch else []
>
>     def insert(self, key, value):
>         def xinsert(xtree):  # xtree is either a tree or []
>            if not xtree: xtree = BinaryTree(key, value)
>            else: xtree.insert(key, value)
>            return xtree
>
>         if key == self.key:
>             self.value = value
>         elif key < self.key:
>             self.lower = xinsert(self.lower)
>         else:
>             self.higher = xinsert(self.higher)
>
> and so forth.

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


http://phr.cx at NOSPAM

Jul 3, 2009, 1:50 PM

Post #38 of 65 (933 views)
Permalink
Re: question of style [In reply to]

Simon Forman <sajmikins [at] gmail> writes:
> "...stick to the principle: NULL is wrong because it causes horrible
> and tricky mistakes which appear even after the program was tested
> thoroughly. You cannot introduce NULL into the language and tell the
> programmer to be careful about it. The programmer is not capable of
> being careful!"
>
> To me that seems weak and too general, you could say /anything/
> "...causes horrible and tricky mistakes which appear even after the
> program was tested thoroughly."

On the contrary, general means powerful :). For example, you can say
that malloc/free in C causes horrible and tricky mistakes etc. Python
avoids the mistakes by having automatic storage management.

> Which I agree with wholeheartedly. I just don't see that he made a
> strong case that the inclusion of NULLs directly implies poor quality
> of language.
>
> (I like Haskell's Maybe, but saying A is better than B doesn't imply
> that B is therefore terrible.)

I wouldn't say Python's None is terrible, but the programming style in
which None is used as a marker for "absent value" is genuinely a
source of bugs, requiring care when used. Often it's easy to just
avoid it and all the bugs that come with it.

Haskell's Maybe type, ML's Option type, and various similar constructs
in other recently designed languages all are responses to the
shortcomings of None-like constructs in older languages. I'm not
going purely by that one guy's blog post, though I do think that post
was pretty good.

> Hmm, I really don't see that using an empty list rather than None as a
> stand-in for NULL pointer bought you anything there. In fact, this
> code would work identically if you replaced [] with None.

Yes I noticed that too (and mentioned it) after writing the code. I
think the real problem is that the class has unnatural semantics and
Python's OOP system (well, OOP in general) is also sort of kludgy.
I will think about a possible rewrite.
--
http://mail.python.org/mailman/listinfo/python-list


gallium.arsenide at gmail

Jul 3, 2009, 4:26 PM

Post #39 of 65 (927 views)
Permalink
Re: question of style [In reply to]

On Jul 3, 4:50 pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> I wouldn't say Python's None is terrible, but the
> programming style in which None is used as a marker
> for "absent value" is genuinely a source of bugs,
> requiring care when used.  Often it's easy to just
> avoid it and all the bugs that come with it.

While other languages may make it easier to avoid these types of bugs,
I think it's pretty natural to use Python's None as a marker for
"absent value", if you're coding in Python. Python seems to encourage
this by having functions return None when there is no explicit return
value, and by having the interactive command line print nothing at all
when the expression evaluates to None.

I won't argue with anyone who wants to call these design flaws, but it
seems to me that using None this way in one's own Python code is
reasonably Pythonic.

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


steve at REMOVE-THIS-cybersource

Jul 3, 2009, 7:04 PM

Post #40 of 65 (930 views)
Permalink
Re: question of style [In reply to]

On Fri, 03 Jul 2009 13:50:12 -0700, Paul Rubin wrote:

> I wouldn't say Python's None is terrible, but the programming style in
> which None is used as a marker for "absent value" is genuinely a source
> of bugs, requiring care when used. Often it's easy to just avoid it and
> all the bugs that come with it.

So you keep saying, but I don't believe it. I've never found this to be a
problem in my own code: a few silly mistakes where I accidentally assign
the result of a function that operates by side-effect:

blist = alist.sort()

or similar, and I haven't done that for years now.

No, wait, I tell I lie... re.search() sometimes bites me, because
sometimes it returns None and sometimes it returns a matchobject and I
don't use re often enough to have good habits with it yet. But that's a
good example of why removing NULL (None, nul, nil, whatever you want to
call it) doesn't lower the number of bugs, it just changes their nature:
if re.search didn't return None, I'd still have trouble with it.

There are three natural approaches to (say) re.search() for dealing with
failure:

(1) return a sentinel value like None;

(2) return a matchobject which tests False;

(3) raise an exception.

Here's how you would use them correctly:


# 1 or 2 are handled identically
o = re.search(s)
if o:
process_match(o)
else:
print "Not found"


# 3 is different
try:
process_match(re.search(s))
except Exception:
print "Not found"


There's essentially little or no difference in the handling. In all three
cases, if you assume search will always succeed or forget to handle the
failure case, you will write incorrect code:

process_match(re.search(s))

and get an unexpected exception. The only difference is that the specific
exception will differ between the cases. Remove None from the scenario
doesn't reduce the number of bugs, it just changes their nature.



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


aahz at pythoncraft

Jul 3, 2009, 9:47 PM

Post #41 of 65 (924 views)
Permalink
Re: question of style [In reply to]

In article <7xhbxtjxtn.fsf [at] ruckus>,
Paul Rubin <http://phr.cx [at] NOSPAM> wrote:
>Simon Forman <sajmikins [at] gmail> writes:
>>
>> (I like Haskell's Maybe, but saying A is better than B doesn't imply
>> that B is therefore terrible.)
>
>I wouldn't say Python's None is terrible, but the programming style in
>which None is used as a marker for "absent value" is genuinely a
>source of bugs, requiring care when used. Often it's easy to just
>avoid it and all the bugs that come with it.
>
>Haskell's Maybe type, ML's Option type, and various similar constructs
>in other recently designed languages all are responses to the
>shortcomings of None-like constructs in older languages. I'm not
>going purely by that one guy's blog post, though I do think that post
>was pretty good.

AFAICT, in order for Maybe and Option to work, you need to have some
kind of static typing system. Am I missing something?
--
Aahz (aahz [at] pythoncraft) <*> http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha
--
http://mail.python.org/mailman/listinfo/python-list


upwestdon at gmail

Jul 3, 2009, 11:03 PM

Post #42 of 65 (920 views)
Permalink
Re: question of style [In reply to]

On Jul 2, 1:23 pm, Simon Forman <sajmik...@gmail.com> wrote:
> Hey I was hoping to get your opinions on a sort of minor stylistic
> point.
> These two snippets of code are functionally identical. Which would you
> use and why?
> The first one is easier [for me anyway] to read and understand, but
> slightly less efficient, while the second is [marginally] harder to
> follow but more efficient.
>
> ## First snippet
>
> if self.higher is self.lower is None: return
> if self.lower is None: return self.higher
> if self.higher is None: return self.lower
>
> ## Second snippet
>
> if self.higher is None:
>     if self.lower is None:
>         return
>     return self.lower
> if self.lower is None:
>     return self.higher
>
> What do you think?
>
> (One minor point: in the first snippet, the "is None" in the first
> line is superfluous in the context in which it will be used, the only
> time "self.lower is self.higher" will be true is when they are both
> None.)

How about just:

if not (self.higher and self.lower):
return self.higher or self.lower
--
http://mail.python.org/mailman/listinfo/python-list


Scott.Daniels at Acm

Jul 4, 2009, 5:28 AM

Post #43 of 65 (892 views)
Permalink
Re: question of style [In reply to]

upwestdon wrote:
> if not (self.higher and self.lower):
> return self.higher or self.lower

self.lower = 0
self.higher = 123
???
More than just None is False
--
http://mail.python.org/mailman/listinfo/python-list


http://phr.cx at NOSPAM

Jul 4, 2009, 6:29 AM

Post #44 of 65 (894 views)
Permalink
Re: question of style [In reply to]

aahz [at] pythoncraft (Aahz) writes:
> AFAICT, in order for Maybe and Option to work, you need to have some
> kind of static typing system. Am I missing something?

I'm not sure. Maybe there could be some kind of syntactic support in
a dynamic language (not that I'm suggesting adding that to Python).
I've been meaning to look up how Erlang does it. For the limited
purpose of regexps that might or might not match, Perl has some
special support.

A kludgy Python counterpart to Option might be to use a pair (present, x)
where present is a bool saying whether the value is available. If
present is True, then x is the value. That could make it harder to
forget to test the flag before using the value.

In the stuff I'm doing, I often find it best to just use a list value,
so instead of:

y = f(x) if x is not None else None

I can just write

y = map(f, x)

In many cases it later turns out that list really was the natural
representation and it ends up growing additional potential elements.
I saw some article about database design recently that claimed as a
program evolves, all relationships end up becoming many-to-many. It
gave as an example, if your program deals with names and addresses, it
will eventually have to handle the case where someone has more than
one residence address.
--
http://mail.python.org/mailman/listinfo/python-list


davea at ieee

Jul 4, 2009, 6:31 AM

Post #45 of 65 (893 views)
Permalink
Re: Re: question of style [In reply to]

upwestdon wrote:
> On Jul 2, 1:23 pm, Simon Forman <sajmik...@gmail.com> wrote:
>
>> Hey I was hoping to get your opinions on a sort of minor stylistic
>> point.
>> These two snippets of code are functionally identical. Which would you
>> use and why?
>> The first one is easier [for me anyway] to read and understand, but
>> slightly less efficient, while the second is [marginally] harder to
>> follow but more efficient.
>>
>> ## First snippet
>>
>> if self.higher is self.lower is None: return
>> if self.lower is None: return self.higher
>> if self.higher is None: return self.lower
>>
>> ## Second snippet
>>
>> if self.higher is None:
>> if self.lower is None:
>> return
>> return self.lower
>> if self.lower is None:
>> return self.higher
>>
>> What do you think?
>>
>> (One minor point: in the first snippet, the "is None" in the first
>> line is superfluous in the context in which it will be used, the only
>> time "self.lower is self.higher" will be true is when they are both
>> None.)
>>
>
> How about just:
>
> if not (self.higher and self.lower):
> return self.higher or self.lower
>
>
But if self.higher is 0 and self.lower is None, this'll return None,
which wasn't the original intent.

Without having some documented constraints on the self.higher and lower
types and values, it's difficult to simplify further.

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


sajmikins at gmail

Jul 4, 2009, 7:54 AM

Post #46 of 65 (889 views)
Permalink
Re: question of style [In reply to]

On Jul 4, 2:03 am, upwestdon <upwest...@gmail.com> wrote:
> On Jul 2, 1:23 pm, Simon Forman <sajmik...@gmail.com> wrote:
>
>
>
> > Hey I was hoping to get your opinions on a sort of minor stylistic
> > point.
> > These two snippets of code are functionally identical. Which would you
> > use and why?
> > The first one is easier [for me anyway] to read and understand, but
> > slightly less efficient, while the second is [marginally] harder to
> > follow but more efficient.
>
> > ## First snippet
>
> > if self.higher is self.lower is None: return
> > if self.lower is None: return self.higher
> > if self.higher is None: return self.lower
>
> > ## Second snippet
>
> > if self.higher is None:
> >     if self.lower is None:
> >         return
> >     return self.lower
> > if self.lower is None:
> >     return self.higher
>
> > What do you think?
>
> > (One minor point: in the first snippet, the "is None" in the first
> > line is superfluous in the context in which it will be used, the only
> > time "self.lower is self.higher" will be true is when they are both
> > None.)
>
> How about just:
>
> if not (self.higher and self.lower):
>     return self.higher or self.lower

That would work too in this case, both higher and lower are expected
to be either None or an object (that doesn't override the default all-
objects-are-true rule.)

Thanks,
~Simon
--
http://mail.python.org/mailman/listinfo/python-list


aahz at pythoncraft

Jul 4, 2009, 8:48 AM

Post #47 of 65 (890 views)
Permalink
Re: question of style [In reply to]

In article <7xws6oa862.fsf [at] ruckus>,
Paul Rubin <http://phr.cx [at] NOSPAM> wrote:
>
>In many cases it later turns out that list really was the natural
>representation and it ends up growing additional potential elements.
>I saw some article about database design recently that claimed as a
>program evolves, all relationships end up becoming many-to-many. It
>gave as an example, if your program deals with names and addresses, it
>will eventually have to handle the case where someone has more than
>one residence address.

That's definitely a critical point, and I absolutely agree that this
should get rubbed into people's faces.
--
Aahz (aahz [at] pythoncraft) <*> http://www.pythoncraft.com/

"as long as we like the same operating system, things are cool." --piranha
--
http://mail.python.org/mailman/listinfo/python-list


http://phr.cx at NOSPAM

Jul 4, 2009, 11:10 AM

Post #48 of 65 (883 views)
Permalink
Re: question of style [In reply to]

Simon Forman <sajmikins [at] gmail> writes:
> > if not (self.higher and self.lower):
> >     return self.higher or self.lower
>
> That would work too in this case, both higher and lower are expected
> to be either None or an object (that doesn't override the default all-
> objects-are-true rule.)

-1.

Objects can support methods like __bool__, __len__ (a tree might use
this to compute the number of nodes or something like that), and
__nonzero__. If len(object)==0 then the object is treated as false.
So that test can fail if a __len__ method gets added to the tree class
sometime. Or you might decide you want to support empty trees which
would test as false.

Anyway, Python's overloading of bool(...) is yet another misfeature
and although it's convenient, the "explicit is better than implicit"
principle indicates to avoid that sort of trick.
--
http://mail.python.org/mailman/listinfo/python-list


sajmikins at gmail

Jul 4, 2009, 1:05 PM

Post #49 of 65 (878 views)
Permalink
Re: question of style [In reply to]

On Jul 4, 2:10 pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> Simon Forman <sajmik...@gmail.com> writes:
> > > if not (self.higher and self.lower):
> > >     return self.higher or self.lower
>
> > That would work too in this case, both higher and lower are expected
> > to be either None or an object (that doesn't override the default all-
> > objects-are-true rule.)
>
> -1.

Heh heh heh, I figured someone might call me on this, but I stopped
short of adding further elucidation to that parenthetical clause.

What I meant (of course, *wink*) was "...an instance of a user-defined
class that doesn't override the special double-underscore methods in a
way that causes it (the instance) to be considered False in a 'boolean
context', as they say in perl."

In [1]: class bar: pass
...:

In [2]: b = bar()

In [3]: bool(b)
Out[3]: True



> Objects can support methods like __bool__, __len__ (a tree might use
> this to compute the number of nodes or something like that), and
> __nonzero__.  If len(object)==0 then the object is treated as false.
> So that test can fail if a __len__ method gets added to the tree class
> sometime.  Or you might decide you want to support empty trees which
> would test as false.

Ya, that's exactly why I stuck to checking explicitly against None in
that tree code. :]


> Anyway, Python's overloading of bool(...) is yet another misfeature
> and although it's convenient, the "explicit is better than implicit"
> principle indicates to avoid that sort of trick.  

I really like the "misfeature" myself. Python (to me) seems to
relieve you of gory details that get in the way (compare equivalent C+
+ and Python code) but still exposes you to gory details that, with
care in coding, can make your code easier to grok and more elegant in
general.

BTW, Paul, kind of a tangent: I reimplemented the same algorithm but
using tuples instead of instances (and empty tuples for "NULL"
values.) I was trying to mess around in the space you seemed to
indicate existed, i.e. a better implementation using other datatypes,
but I didn't have a clear idea what I was doing and, as I said, I
started by simply re-implementing with a different datatype.

Much to my surprise and delight, I discovered the tuple-based BTree
was /already/ a "persistent data type"! It was both awesome and a bit
of an anti-climax. :]
--
http://mail.python.org/mailman/listinfo/python-list


steve at REMOVE-THIS-cybersource

Jul 4, 2009, 6:36 PM

Post #50 of 65 (867 views)
Permalink
Re: question of style [In reply to]

On Sat, 04 Jul 2009 11:10:48 -0700, Paul Rubin wrote:

> Anyway, Python's overloading of bool(...) is yet another misfeature and
> although it's convenient, the "explicit is better than implicit"
> principle indicates to avoid that sort of trick.

"Overloading of bool()"?

I don't understand what that means -- you mean you dislike the ability to
overload __bool__ (__nonzero__ in older Pythons)? That seems strange.
Python allows you to overload __int__ and __str__ and __float__, why is
__bool__ a misfeature? If that's what you mean, then I'm perplexed.

Or do you mean that all Python objects are interpretable in a truth
context? If that's what you mean, then I'm not perplexed, I'm sure you're
utterly wrong. Certain people -- a tiny minority -- keep trying to argue
that the ability to say "if obj" for arbitrary objects is somehow a bad
thing, and their arguments seem to always boil down to:

"If you write code that assumes that only bools have a truth value, then
surprising things will happen because all objects have a truth value."

Well duh.

If you think you have a better reason for calling the truth value of
arbitrary objects a "misfeature", I'd like to hear it.



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

First page Previous page 1 2 3 Next page Last page  View All Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.