Re: Pygobject style question

2020-08-02 Thread Cameron Simpson
On 01Aug2020 13:32, Chris Green  wrote:
>Having (after lots of help from here, thank you) finally converted my
>Python 2, gtk 2 program to Python 3 and pygobject gtk 3 I'm left with
>a couple of what might be called style questions.
>
>I guess it's mostly down to what feels right to me but there may be
>good reasons for choosing one way over another and, if so, I'd like to
>know what they are.
>
>So, my original code had:-
>...
>self.buffer = gtk.TextBuffer()
>self.view = gtk.TextView(self.buffer)
>
>This doesn't work in gtk+ 3 (or at least I don't think it does, the
>converter script changed it) and there seem to be several ways of
>doing it now:-
>
>self.buffer = Gtk.TextBuffer()
>self.view = Gtk.TextView(buffer = self.buffer)

I like this first one. It is least verbose, and it makes the buffer 
before it makes the view, which I prefer.

If they are all legal and all correct and equivalent, go with the one 
which is easiest to read.

Cheers,
Cameron Simpson 
-- 
https://mail.python.org/mailman/listinfo/python-list


Pygobject style question

2020-08-01 Thread Chris Green
Having (after lots of help from here, thank you) finally converted my
Python 2, gtk 2 program to Python 3 and pygobject gtk 3 I'm left with
a couple of what might be called style questions.

I guess it's mostly down to what feels right to me but there may be
good reasons for choosing one way over another and, if so, I'd like to
know what they are.

So, my original code had:-

...
...
self.buffer = gtk.TextBuffer()
self.view = gtk.TextView(self.buffer)
...
...


This doesn't work in gtk+ 3 (or at least I don't think it does, the
converter script changed it) and there seem to be several ways of
doing it now:-

...
...
self.buffer = Gtk.TextBuffer()
self.view = Gtk.TextView(buffer = self.buffer)
...
...


...
...
self.buffer = Gtk.TextBuffer()
self.view = Gtk.TextView.new_with_buffer(self.buffer)
...
...


...
...
self.view = Gtk.TextView()
self.buffer = self.view.get_buffer()
...
...


...
...
self.view = Gtk.TextView()
self.buffer = Gtk.TextBuffer()
self.view.set_buffer(self.buffer)
...
...

Is there any reason to prefer any one of the above over the others?

Obviously the last one is a line more but lends itself to using
several Gtk.TextBuffer objects in on Gtk.TextView.

-- 
Chris Green
·
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Package setup best practice style question

2016-05-28 Thread Steven D'Aprano
On Sun, 29 May 2016 03:00 am, Steven D'Aprano wrote:

> On Sun, 29 May 2016 02:15 am, Gerald Britton wrote:
> 
>> suppose I have a simple python project setup like this:
[...]

To which I responded:

> If this is a single project, why do you set it up like this? Is there a
> reason why you don't just have:
[...]


I'm sorry, on re-reading my post I realise that it might come across as a
bit confrontational. Sorry Gerald, it wasn't intended that way. I was just
intending to point out that we aren't forced to use a package structure at
all, unless it brings actual advantages to the project.



-- 
Steven

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


Re: Package setup best practice style question

2016-05-28 Thread Steven D'Aprano
On Sun, 29 May 2016 02:15 am, Gerald Britton wrote:

> suppose I have a simple python project setup like this:
> 
> Project diectory
>  prog.py
>  pkg directory
>   __init__.py
>   mod1.py
>class A:

If this is a single project, why do you set it up like this? Is there a
reason why you don't just have:

prog.py  # contains class A

or even:

prog.py
mod1.py  # contains class A


Or if the project is so big it needs to be a package, make it executable:

prog/
__init__.py
mod1.py
__main__.py


This layout is now executable using:

python -m prog

which automatically calls __main__.py.


But if you don't have a good reason for using a package, don't use a
package. Use the simplest project layout that solves your problem.

But for the rest of my comments, I'm going to assume that you DO have a good
reason.



> In order to have class A (unqualified) available from prog.py, there are a
> few options that I know about.  I'm currently considering two of them and
> would like some feedback on best practices.
> 
> 1. in pkg.__init__.py add:
> 
>from pkg.mod1 import A

This kinda-sorta defeats the purpose, or at least one purpose, of using a
package. Which is fine, so long as you understand that's what you are
doing.

Generally speaking, one of the purposes of using a package layout is to
allow unused sub-modules to be left unloaded unless needed. So pkg.mod1
doesn't get loaded unless you need it, in which case you explicitly call 

import pkg.mod1

or 

from pkg.mod1 import A

as you prefer. By putting that import in the pkg __init__ file, you're
making it automatically occur as soon as pkg is imported. Is that what you
intend? If so, then it is fine, and feel free to do it.

But in that case, why not just move class A into pkg/__init__.py?


> in prog.py add:
> 
>from pkg import A

*shrug* This entirely depends on the purpose and use of pkg. When you give
generic, meaningless names, I can only respond with wishy-washy, sit-on-
the-fence generic advice.

If the appropriate API is for callers to say:

from pkg import A

then this is the right way to design your package. But if the right API is:

from pkg.mod1 import A

then don't do it this way, instead do it as follows.


> 2. leave __init__.py empty
> in prog.py add:
> 
>  from pkg.mod1 import A
> 
> 
> Is there a preference or best practice that would indicate to prefer
> method
> 1 or method 2?  Are there methods 3, 4, 5, ... that I should consider that
> are even better?

One purpose of using a package is to have alternative implementations. For
instance I have a package which has to support Python 2.4 where the "with"
statement is not available, so I design it like this:

package/
__init__.py
module.py
module24.py

Since the user doesn't choose which implementation to use, I have this in
the init file:


try:
from module import thing
except SyntaxError:
from module24 import thing


and then the caller uses:

from package import thing

and is none the wiser.

On the other hand, if the user was supposed to choose, then I would have
then call:

from package.redblack import Tree
from package.avl import Tree
from package.scapegoat import Tree

and let the user choose which implementation they wanted.


-- 
Steven

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


Package setup best practice style question

2016-05-28 Thread Gerald Britton
suppose I have a simple python project setup like this:

Project diectory
 prog.py
 pkg directory
  __init__.py
  mod1.py
   class A:

In order to have class A (unqualified) available from prog.py, there are a
few options that I know about.  I'm currently considering two of them and
would like some feedback on best practices.

1. in pkg.__init__.py add:

   from pkg.mod1 import A

in prog.py add:

   from pkg import A

2. leave __init__.py empty
in prog.py add:

 from pkg.mod1 import A


Is there a preference or best practice that would indicate to prefer method
1 or method 2?  Are there methods 3, 4, 5, ... that I should consider that
are even better?
-- 
Gerald Britton, MCSE-DP, MVP
LinkedIn Profile: http://ca.linkedin.com/in/geraldbritton
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 12/03/2014 12:02 PM, Chris Angelico wrote:

When importing a module from a subpackage, it's sometimes convenient
to refer to it throughout the code with a one-part name rather than
two. I'm going to use 'os.path' for the examples, but my actual
use-case is a custom package where the package name is, in the
application, quite superfluous.

Throughout the code, I want to refer to path.split(),
path.isfile(), etc, without the os. in front of them. I could do
either of these:

import os.path as path
from os import path

Which one would you recommend? Does it depend on context?



One argument not yet brought up by anyone else:

if you ever wanted to make the module part of your own package and turn 
the import into a relative one, only the second, but not the first form 
lets you replace the package name with . :


from . import path (while import .path is a SyntaxError, so you'd need a 
slightly more complicated rewrite).


Wolfgang


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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Jean-Michel Pichavant
- Original Message -
 From: Chris Angelico ros...@gmail.com
 To: python-list@python.org
 Sent: Wednesday, 3 December, 2014 12:02:17 PM
 Subject: Style question: Importing modules from packages - 'from' vs 'as'
 
 When importing a module from a subpackage, it's sometimes convenient
 to refer to it throughout the code with a one-part name rather than
 two. I'm going to use 'os.path' for the examples, but my actual
 use-case is a custom package where the package name is, in the
 application, quite superfluous.
 
 Throughout the code, I want to refer to path.split(),
 path.isfile(), etc, without the os. in front of them. I could do
 either of these:
 
 import os.path as path
 from os import path
 
 Which one would you recommend? Does it depend on context?
 
 An as import works only if it's a module in a package, where the
 from import can also import other objects (you can't go import
 pprint.pprint as pprint). I'm fairly sure that's an argument... on
 one side or another. :)
 
 Thoughts?
 
 ChrisA
 --
 https://mail.python.org/mailman/listinfo/python-list
 

I know you specifically stated you didn't want to do this but

import os

os.path.isfile()

is the best option imo, especially from the reader point of view (Namespaces 
are one honking great idea).



-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Ethan Furman
On 12/04/2014 09:36 AM, Jean-Michel Pichavant wrote:
 
 I know you specifically stated you didn't want to do this but
 
   import os
 
   os.path.isfile()
 
 is the best option imo, especially from the reader point of view (Namespaces 
 are one honking great idea).

But, Flat is better than nested !  ;)

--
~Ethan~



signature.asc
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Ethan Furman
On 12/03/2014 03:02 AM, Chris Angelico wrote:
 
 Throughout the code, I want to refer to path.split(),
 path.isfile(), etc, without the os. in front of them. I could do
 either of these:
 
 import os.path as path
 from os import path
 
 Which one would you recommend? Does it depend on context?

I recommend the one with less typing.  ;)

--
~Ethan~



signature.asc
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 4:36 AM, Jean-Michel Pichavant
jeanmic...@sequans.com wrote:
 I know you specifically stated you didn't want to do this but

 import os

 os.path.isfile()

 is the best option imo, especially from the reader point of view (Namespaces 
 are one honking great idea).

With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is import module2 etc - and I was writing an
external script that calls on one of the modules. So it makes sense to
reference it through the code the exact same way, as module.blah
rather than package.module.blah.

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 04.12.2014 19:05, Chris Angelico wrote:


With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is import module2 etc - and I was writing an
external script that calls on one of the modules.


What ? I'm usually thinking Python 3 not 2 and I'm never sure which 
Python 2.x has backported which feature of 3, but I thought implicit 
relative imports like you seem to describe are not working in 2.7 ?


Wolfgang

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:
 On 04.12.2014 19:05, Chris Angelico wrote:


 With os.path it definitely is. With the actual code in question, it's
 a Python 2.7 project that mostly uses relative imports - inside
 package.module1 is import module2 etc - and I was writing an
 external script that calls on one of the modules.


 What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python
 2.x has backported which feature of 3, but I thought implicit relative
 imports like you seem to describe are not working in 2.7 ?

Hmm, I'm not sure, but certainly it does seem to work that way. Typing
import foo from inside a package will import foo.py from the package
directory. I haven't dug into the details of _why_, and if ever the
project shifts to Python 3 (which I would like it to), we might have
to change some of the import lines, but I'd still like to be able to
reference foo.bar as meaning the bar top-level object in foo.py.

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 04.12.2014 22:30, Chris Angelico wrote:

On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:

On 04.12.2014 19:05, Chris Angelico wrote:



With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is import module2 etc - and I was writing an
external script that calls on one of the modules.



What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python
2.x has backported which feature of 3, but I thought implicit relative
imports like you seem to describe are not working in 2.7 ?


Hmm, I'm not sure, but certainly it does seem to work that way. Typing
import foo from inside a package will import foo.py from the package
directory. I haven't dug into the details of _why_, and if ever the
project shifts to Python 3 (which I would like it to), we might have
to change some of the import lines, but I'd still like to be able to
reference foo.bar as meaning the bar top-level object in foo.py.



I checked what the docs say about this and it is totally confusing (at 
least me):


https://docs.python.org/3/howto/pyporting.html#from-future-import-absolute-import 
says:



from __future__ import absolute_import

Implicit relative imports (e.g., importing spam.bacon from within 
spam.eggs with the statement import bacon) do not work in Python 3. This 
future statement moves away from that and allows the use of explicit 
relative imports (e.g., from . import bacon).


In Python 2.5 you must use the __future__ statement to get to use 
explicit relative imports and prevent implicit ones. In Python 2.6 
explicit relative imports are available without the statement, but you 
still want the __future__ statement to prevent implicit relative 
imports. In Python 2.7 the __future__ statement is not needed. In other 
words, unless you are only supporting Python 2.7 or a version earlier 
than Python 2.5, use this __future__ statement.



which I read as there has been a stepwise transition between 2.5 and 2.7 
so that 2.7 now behaves like Python 3 even without the __future__ statement.
OTOH, I believe you, of course, if you're saying implicit relative 
imports are working just fine in 2.7, but then how to interpret the In 
Python 2.7 the __future__ statement is not needed. above ?


Wolfgang

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 9:10 AM, Wolfgang Maier
wolfgang.ma...@biologie.uni-freiburg.de wrote:
 which I read as there has been a stepwise transition between 2.5 and 2.7 so
 that 2.7 now behaves like Python 3 even without the __future__ statement.
 OTOH, I believe you, of course, if you're saying implicit relative imports
 are working just fine in 2.7, but then how to interpret the In Python 2.7
 the __future__ statement is not needed. above ?

Hmm. To be honest, I'm not sure. The Python 2.7 __future__ module
claims that absolute_import became standard in 3.0, not 2.7, which
seems to conflict with what you're seeing.

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


Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Chris Angelico
When importing a module from a subpackage, it's sometimes convenient
to refer to it throughout the code with a one-part name rather than
two. I'm going to use 'os.path' for the examples, but my actual
use-case is a custom package where the package name is, in the
application, quite superfluous.

Throughout the code, I want to refer to path.split(),
path.isfile(), etc, without the os. in front of them. I could do
either of these:

import os.path as path
from os import path

Which one would you recommend? Does it depend on context?

An as import works only if it's a module in a package, where the
from import can also import other objects (you can't go import
pprint.pprint as pprint). I'm fairly sure that's an argument... on
one side or another. :)

Thoughts?

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Tim Delaney
On 3 December 2014 at 22:02, Chris Angelico ros...@gmail.com wrote:


 import os.path as path
 from os import path


Bah - deleted the list and sent directly to Chris ... time to go to bed.

The advantage of the former is that if you want to use a different name,
it's a smaller change. But the disadvantage of the former is that if you
*don't* want to rename, it violates DRY (don't repeat yourself).

The difference is so marginal that I'd leave it to personal preference, and
wouldn't pull someone up for either in a code review.

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Peter Otten
Chris Angelico wrote:

 When importing a module from a subpackage, it's sometimes convenient
 to refer to it throughout the code with a one-part name rather than
 two. I'm going to use 'os.path' for the examples, but my actual
 use-case is a custom package where the package name is, in the
 application, quite superfluous.
 
 Throughout the code, I want to refer to path.split(),
 path.isfile(), etc, without the os. in front of them. I could do
 either of these:
 
 import os.path as path
 from os import path
 
 Which one would you recommend? Does it depend on context?

Don't repeat yourself, so

from os import path

always. On the other hand I have never thought about actual renames, e. g.

from os import path as stdpath

versus

import os.path as stdpath

I think I'd use the latter as it looks simpler.

 An as import works only if it's a module in a package, where the
 from import can also import other objects (you can't go import
 pprint.pprint as pprint). I'm fairly sure that's an argument... on
 one side or another. :)

In theory you could sometimes catch erroneous assumptions about 
pprint.pprint's type. But I don't care.

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Chris Angelico
On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten __pete...@web.de wrote:
 Don't repeat yourself, so

 from os import path

 always. On the other hand I have never thought about actual renames, e. g.

 from os import path as stdpath

 versus

 import os.path as stdpath

 I think I'd use the latter as it looks simpler.

Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's
raining as I type this...), and I won't be renaming in this, so the
from-import wins - but as Tim says, it's a close race.

I do like the turn-around times on this list. Although, of course,
it's entirely possible there'll be a week's worth of posts coming when
someone hits on a controversial subaspect of the question somewhere;
any volunteers? :) :)

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


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Ian Kelly
On Dec 3, 2014 4:34 AM, Chris Angelico ros...@gmail.com wrote:

 On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten __pete...@web.de wrote:
  Don't repeat yourself, so
 
  from os import path
 
  always. On the other hand I have never thought about actual renames, e.
g.
 
  from os import path as stdpath
 
  versus
 
  import os.path as stdpath
 
  I think I'd use the latter as it looks simpler.

 Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's
 raining as I type this...), and I won't be renaming in this, so the
 from-import wins - but as Tim says, it's a close race.

To offer a counterpoint, the from import is also less explicit. With
import os.path as path, path must be a module. With the from import, path
could be either a module or just any attribute of the os module.

My preference when importing modules is to use the fully qualified name --
os.path, not path. If I do a submodule import, I'm probably assigning a
local name anyway, so I still prefer the import as over the from import
as.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Terry Reedy

On 12/3/2014 6:02 AM, Chris Angelico wrote:

When importing a module from a subpackage, it's sometimes convenient
to refer to it throughout the code with a one-part name rather than
two. I'm going to use 'os.path' for the examples, but my actual
use-case is a custom package where the package name is, in the
application, quite superfluous.

Throughout the code, I want to refer to path.split(),
path.isfile(), etc, without the os. in front of them. I could do
either of these:

import os.path as path
from os import path

Which one would you recommend? Does it depend on context?


I confirmed that they do the same thing for submodules.
 import os.path as pth
 from os import path
 pth
module 'ntpath' from 'C:\\Programs\\Python34\\lib\\ntpath.py'
 path
module 'ntpath' from 'C:\\Programs\\Python34\\lib\\ntpath.py'
 id(pth)
4319096
 id(path)
4319096

I and most code I have seen uses from tkinter import ttk.


An as import works only if it's a module in a package, where the
from import can also import other objects (you can't go import
pprint.pprint as pprint). I'm fairly sure that's an argument... on
one side or another.


import tkinter.ttk as ttk makes it clear that ttk is a module rather 
than, say, a class.  That might make things easier for the reader.  On 
the other hand, duplication implies that there might be a real renaming, 
so having to compare to see that there is not, is extra work.


from idlelib import EditorWindow
import idlelib.EditorWindow as EditorWindow

--
Terry Jan Reedy

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


Re: Python Style Question

2014-11-12 Thread Anton
On Thursday, October 30, 2014 4:10:23 AM UTC-7, Steven D'Aprano wrote:
 I don't particularly like either version. I prefer this:
 
 def load_int(obj):
 if isinstance(obj, int):
 # Case 1), an int, e.g. 7
 return obj

 elif isinstance(obj, str):
 # Case 2) and 3), a str or JSON serialised int.
 # E.g. '7' or '7'.
 try:
 return int(obj)
 except ValueError:
 return int(json.loads(obj))
 raise TypeError('require int or str, got %s' % type(obj).__name__)

This will definitely work, but then I don't see a benefit of EAFP and 
duck-typing: 
Let's say I have a class 
class FakeInt(object):
   def __int__(self):
  return 42

In this case:
 fi = FakeInt()
 isinstance(fi, int)
False
 int(fi)
42

So probably I need to rephrase 1) something, that I can cast to int.

Same for 
 elif isinstance(obj, str):
As long as it behaves like string (can be some sort if bytearray). For 
particularly this case, it will probably won't happen, but again, it looks like 
an overloaded function with strongly typed argument.

or a functional form:

 def tolerant_load_int(obj, default=None):
 try:
 return load_int(obj)
 except (ValueError, TypeError):
 return default

 values = [n for n in map(tolerant_load_int, l) if n is not None]

 # alternative to using map
 values = [n for n in (tolerant_load_int(obj) for obj in l) if n is not None] 

I like the idea of wrapping it up in a function and being able to use it in 
these functional forms.

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


Re: Python Style Question

2014-10-30 Thread Steven D'Aprano
Anton wrote:

 Let's say I have an incoming list of values *l*. Every element of *l* can
 be one of the following options: 
 1) an integer value 
 2) a string in form of 'int_value', e.g. '7'
 3) a string with a json serialization of an integer value, e.g. '7'
 4) something else that should be ignored
 
 I need to transform this list into another list with values from options
 1)-3) coerced to int. The code below should do this.

I don't particularly like either version. I prefer this:

def load_int(obj):
if isinstance(obj, int):
# Case 1), an int, e.g. 7
return obj
elif isinstance(obj, str):
# Case 2) and 3), a str or JSON serialised int.
# E.g. '7' or '7'.
try:
return int(obj)
except ValueError:
return int(json.loads(obj))
raise TypeError('require int or str, got %s' % type(obj).__name__)

load_int() covers the three cases you mention, and raises either ValueError
for malformed strings (e.g. 'x') or TypeError for things which aren't ints
(e.g. floats, dicts, etc.). Any other exception is probably a bug that
needs to be fixed.

Then, to cover case 4), ignoring everything else, you have a choice between
a procedural form:

values = []
for obj in l:
try:
values.append(load_int(obj))
except (ValueError, TypeError):
pass


or a functional form:

def tolerant_load_int(obj, default=None):
try:
return load_int(obj)
except (ValueError, TypeError):
return default

values = [n for n in map(tolerant_load_int, l) if n is not None]

# alternative to using map
values = [n for n in (tolerant_load_int(obj) for obj in l) if n is not None]



-- 
Steven

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


Re: Python Style Question

2014-10-30 Thread MRAB

On 2014-10-30 11:10, Steven D'Aprano wrote:

Anton wrote:


Let's say I have an incoming list of values *l*. Every element of *l* can
be one of the following options:
1) an integer value
2) a string in form of 'int_value', e.g. '7'
3) a string with a json serialization of an integer value, e.g. '7'
4) something else that should be ignored

I need to transform this list into another list with values from options
1)-3) coerced to int. The code below should do this.


I don't particularly like either version. I prefer this:

def load_int(obj):
 if isinstance(obj, int):
 # Case 1), an int, e.g. 7
 return obj
 elif isinstance(obj, str):
 # Case 2) and 3), a str or JSON serialised int.
 # E.g. '7' or '7'.
 try:
 return int(obj)
 except ValueError:
 return int(json.loads(obj))
 raise TypeError('require int or str, got %s' % type(obj).__name__)


[snip]

How about:

int(str(obj).strip(''))

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


Re: Python Style Question

2014-10-30 Thread Steven D'Aprano
MRAB wrote:

 On 2014-10-30 11:10, Steven D'Aprano wrote:
 Anton wrote:

 Let's say I have an incoming list of values *l*. Every element of *l*
 can be one of the following options:
 1) an integer value
 2) a string in form of 'int_value', e.g. '7'
 3) a string with a json serialization of an integer value, e.g. '7'
 4) something else that should be ignored

 I need to transform this list into another list with values from options
 1)-3) coerced to int. The code below should do this.

 I don't particularly like either version. I prefer this:

 def load_int(obj):
  if isinstance(obj, int):
  # Case 1), an int, e.g. 7
  return obj
  elif isinstance(obj, str):
  # Case 2) and 3), a str or JSON serialised int.
  # E.g. '7' or '7'.
  try:
  return int(obj)
  except ValueError:
  return int(json.loads(obj))
  raise TypeError('require int or str, got %s' % type(obj).__name__)

 [snip]
 
 How about:
 
 int(str(obj).strip(''))

Absolutely not.

obj = '1\n\n\n\n'  # not valid JSON
load_int(obj)
= raises ValueError
int(str(obj).strip(''))
= wrongly returns 1


-- 
Steven

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


Re: Python Style Question

2014-10-30 Thread Roy Smith
In article 54521c8f$0$12982$c3e8da3$54964...@news.astraweb.com,
 Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote:

 Anton wrote:
 
  Let's say I have an incoming list of values *l*. Every element of *l* can
  be one of the following options: 
  1) an integer value 
  2) a string in form of 'int_value', e.g. '7'
  3) a string with a json serialization of an integer value, e.g. '7'
  4) something else that should be ignored
  
  I need to transform this list into another list with values from options
  1)-3) coerced to int. The code below should do this.
 
 I don't particularly like either version. I prefer this:
 
 def load_int(obj):
 if isinstance(obj, int):
 # Case 1), an int, e.g. 7
 return obj
 elif isinstance(obj, str):
 # Case 2) and 3), a str or JSON serialised int.
 # E.g. '7' or '7'.
 try:
 return int(obj)
 except ValueError:
 return int(json.loads(obj))
 raise TypeError('require int or str, got %s' % type(obj).__name__)

Depending on how strictly you're trying to do input validation, the 
int(json.loads(obj)) may not be what you want.  It allows well-formed 
json encoding floats, for example.

And, of course, since

 isinstance(True, int)
True

this code accepts booleans.  Oh, but wait, that's by design :-)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python Style Question

2014-10-30 Thread Steven D'Aprano
Roy Smith wrote:

 In article 54521c8f$0$12982$c3e8da3$54964...@news.astraweb.com,
  Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote:
 
 Anton wrote:
 
  Let's say I have an incoming list of values *l*. Every element of *l*
  can be one of the following options:
  1) an integer value
  2) a string in form of 'int_value', e.g. '7'
  3) a string with a json serialization of an integer value, e.g. '7'
  4) something else that should be ignored
  
  I need to transform this list into another list with values from
  options 1)-3) coerced to int. The code below should do this.
 
 I don't particularly like either version. I prefer this:
 
 def load_int(obj):
 if isinstance(obj, int):
 # Case 1), an int, e.g. 7
 return obj
 elif isinstance(obj, str):
 # Case 2) and 3), a str or JSON serialised int.
 # E.g. '7' or '7'.
 try:
 return int(obj)
 except ValueError:
 return int(json.loads(obj))
 raise TypeError('require int or str, got %s' % type(obj).__name__)
 
 Depending on how strictly you're trying to do input validation, the
 int(json.loads(obj)) may not be what you want.  It allows well-formed
 json encoding floats, for example.

Really?

py int(json.loads(json.dumps(23.5)))
23

Damn! You're right.

Back to Plan A:

elif isinstance(obj, str):
try:
return int(obj)
except ValueError:
if obj and obj.startswith('') and obj.endswith(''):
return int(obj[1:-1])
raise


But of course even the int() function itself may be a little more flexible
than we might want:

py int('1')
1


So I guess the lessons are:

* before writing code, you need to decide what the code is meant to do;

* and that includes what input must be rejected, not just what input 
  must be accepted.


 And, of course, since
 
 isinstance(True, int)
 True
 
 this code accepts booleans.  Oh, but wait, that's by design :-)

Naturally :-)

If you wanted to avoid it, that's easy, add a clause:

if isinstance(obj, bool):
raise TypeError

at the start of the function.


-- 
Steven

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


Re: Python Style Question

2014-10-30 Thread Denis McMahon
On Fri, 31 Oct 2014 09:48:10 +1100, Steven D'Aprano wrote:

 MRAB wrote:

 How about:
 
 int(str(obj).strip(''))
 
 Absolutely not.
 
 obj = '1\n\n\n\n'  # not valid JSON load_int(obj)
 = raises ValueError int(str(obj).strip(''))
 = wrongly returns 1

How about

#!/usr/bin/python

import re, json

l = [1, -1, 0, '+2', '2', '-2', '0', '+3', '3', '-3', '0', 
 json.dumps(-4), json.dumps(4), json.dumps(0), 
 'x', 'sqjklsqjk__', (5, 6), 
 7.7, -7.7, '8.8', '+8.8', '-8.8', '9.9', '+9.9', '-9.9']

patt1 = re.compile(r'^([-+]?\d+)$')
patt2 = re.compile(r'^([-+]?\d+)$')

def getTheInt(x):

if isinstance(x,int):
return x

if isinstance(x,str):
tmp = patt1.match(x)

if tmp:
return int(tmp.group(1))

tmp = patt2.match(x)

if tmp:
return int(tmp.group(1))

return None

a = []

for n in l:
a.append(getTheInt(n))

print a

# end of code

prints:

[1, -1, 0, 2, 2, -2, 0, 3, 3, -3, 0, -4, 4, 0, None, None, None, None, 
None, None, None, None, None, None, None]

I know re matching the strings may be overkill, but it may be the best 
way of checking that the string contains the expected character format to 
convert to an int.

-- 
Denis McMahon, denismfmcma...@gmail.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Python Style Question

2014-10-29 Thread Anton
Let's say I have an incoming list of values *l*. Every element of *l* can be 
one of the following options:
1) an integer value 
2) a string in form of 'int_value', e.g. '7'
3) a string with a json serialization of an integer value, e.g. '7'
4) something else that should be ignored

I need to transform this list into another list with values from options 1)-3) 
coerced to int. The code below should do this.


Variant 1
===

values = []
for c in l:
# Case 1) or 2)
try:
c_int = int(c)
except ValueError:
pass
else:
values.add(c_int)
continue

# Case 3)
try:
c_int = int(json.loads(c))
except ValueError:
pass
else:
values.add(c_int)
continue

===

Is this code ugly? 
Does it follow EAFP? 
Am I missing something in language best practice?

Or maybe below is more preferable way with a nested try...except clause?

Variant 2
===
values = []
for c in l:
# Case 1) or 2)
try:
c_int = int(c)
except ValueError:

# Case 3)
try:
c_int = int(json.loads(c))
except ValueError:
pass
else:
values.add(c_int)
continue

else:
values.add(c_int)
continue
===

Thanks,
Anton.


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


Re: Python Style Question

2014-10-29 Thread Martin Kemp
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 29/10/2014 10:45, Anton wrote:
 Let's say I have an incoming list of values *l*. Every element of
 *l* can be one of the following options: 1) an integer value 2) a
 string in form of 'int_value', e.g. '7' 3) a string with a json
 serialization of an integer value, e.g. '7' 4) something else
 that should be ignored
 
 I need to transform this list into another list with values from
 options 1)-3) coerced to int. The code below should do this.
 
 
 Variant 1 ===
 
 values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except
 ValueError: pass else: values.add(c_int) continue
 
 # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass 
 else: values.add(c_int) continue
 
 ===
 
 Is this code ugly? Does it follow EAFP? Am I missing something in
 language best practice?
 
 Or maybe below is more preferable way with a nested try...except
 clause?
 
 Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int =
 int(c) except ValueError:  # Case 3) try: c_int =
 int(json.loads(c)) except ValueError: pass else: values.add(c_int) 
 continue  else: values.add(c_int) continue ===
 
 Thanks, Anton.
 
 

Your first example is perfectly fine and is EAFP

Personally, I prefer to avoid nesting when it's not necessary.

- -- 
Martin Kemp (martin.k...@ingg.com)
-BEGIN PGP SIGNATURE-
Version: GnuPG v2

iQEcBAEBAgAGBQJUUM7zAAoJEJ0Re0UIDzSucugIALn/zY8RdpP8iaMShHoszzqf
I0zl0mFHyqhNtwgQ0ZF7VGO+H+U0Dk8rhzTYOmEMzPTKNBGwll3fda9mOnrK9Xvp
9gQjII6DyQIWH7Z3dLcLr2e1j8OMNUSL6UmAYs8urNSIKZLowdV3JI4G/bLyW0KS
y5Ko8dI6y5nOJ1P9XCmPTmags43UZfR8DrBUaAbzNcS8FGwmUE2KBkEhLQOvmpJi
jmMc7wMOpq0jL+XbA+7pHUqoVZ7w1tUFjuy9I3h45tgPuTFAFB0gX+FpE+oVgO5o
spQpVaOPEYN9ceLgHdKSxzdVIhOQLE6H/SYNHlsEW/ZNM6aR9n4yipgkOmtJ0+M=
=WzHA
-END PGP SIGNATURE-
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python Style Question

2014-10-29 Thread Rafael Romero Carmona
Hi, first in Python 2.7.6 and Python 3.4.0 list haven't got any add
function but they have append.

I think you could do better with something like

==
import json
l = [1, -1, 0, '1', '-1', '0', json.dumps(-1), json.dumps(1),
json.dumps(0), 'x', 'sqjklsqjk__', (1, 2)]

values = []

for c in l:
try:
c_int = int(c)
except ValueError:
pass
except TypeError:
pass
else:
values.append(c_int)
continue
print(values)
==

The code has been tested in Python 2.7.6 and 3.4 and returns [1, -1,
0, 1, -1, 0, -1, 1, 0]

You don't need to do two try because you can process both exceptions
in the same way. You don't really need to do json.loads because if you
have a json string which is an integer, you could do that directly
with int(c) which can take a string and transform in an integer.

With ValueError it captures the exception when it tries to transform
the characters' strings and with TypeError it captures the exception
when it tries to work with the tuples.

Have a good day and hope it works for you!

2014-10-29 11:42 GMT+01:00 Anton anton.schattenf...@gmail.com:
 Let's say I have an incoming list of values *l*. Every element of *l* can be 
 one of the following options:
 1) an integer value
 2) a string in form of 'int_value', e.g. '7'
 3) a string with a json serialization of an integer value, e.g. '7'
 4) something else that should be ignored

 I need to transform this list into another list with values from options 
 1)-3) coerced to int. The code below should do this.


 Variant 1
 ===

 values = []
 for c in l:
 # Case 1) or 2)
 try:
 c_int = int(c)
 except ValueError:
 pass
 else:
 values.add(c_int)
 continue

 # Case 3)
 try:
 c_int = int(json.loads(c))
 except ValueError:
 pass
 else:
 values.add(c_int)
 continue

 ===

 Is this code ugly?
 Does it follow EAFP?
 Am I missing something in language best practice?

 Or maybe below is more preferable way with a nested try...except clause?

 Variant 2
 ===
 values = []
 for c in l:
 # Case 1) or 2)
 try:
 c_int = int(c)
 except ValueError:

 # Case 3)
 try:
 c_int = int(json.loads(c))
 except ValueError:
 pass
 else:
 values.add(c_int)
 continue

 else:
 values.add(c_int)
 continue
 ===

 Thanks,
 Anton.


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


Re: Python Style Question

2014-10-29 Thread Rafael Romero Carmona
2014-10-29 12:25 GMT+01:00 Martin Kemp martin.k...@ingg.com:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 On 29/10/2014 10:45, Anton wrote:
 Let's say I have an incoming list of values *l*. Every element of
 *l* can be one of the following options: 1) an integer value 2) a
 string in form of 'int_value', e.g. '7' 3) a string with a json
 serialization of an integer value, e.g. '7' 4) something else
 that should be ignored

 I need to transform this list into another list with values from
 options 1)-3) coerced to int. The code below should do this.


 Variant 1 ===

 values = [] for c in l: # Case 1) or 2) try: c_int = int(c) except
 ValueError: pass else: values.add(c_int) continue

 # Case 3) try: c_int = int(json.loads(c)) except ValueError: pass
 else: values.add(c_int) continue

 ===

 Is this code ugly? Does it follow EAFP? Am I missing something in
 language best practice?

 Or maybe below is more preferable way with a nested try...except
 clause?

 Variant 2 === values = [] for c in l: # Case 1) or 2) try: c_int =
 int(c) except ValueError:  # Case 3) try: c_int =
 int(json.loads(c)) except ValueError: pass else: values.add(c_int)
 continue  else: values.add(c_int) continue ===

 Thanks, Anton.



 Your first example is perfectly fine and is EAFP


Actually it doesn't work because there is no add function and it
doesn't catch the TypeError function to ignore other exceptions than
ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4.

 Personally, I prefer to avoid nesting when it's not necessary.

 - --
 Martin Kemp (martin.k...@ingg.com)
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v2

 iQEcBAEBAgAGBQJUUM7zAAoJEJ0Re0UIDzSucugIALn/zY8RdpP8iaMShHoszzqf
 I0zl0mFHyqhNtwgQ0ZF7VGO+H+U0Dk8rhzTYOmEMzPTKNBGwll3fda9mOnrK9Xvp
 9gQjII6DyQIWH7Z3dLcLr2e1j8OMNUSL6UmAYs8urNSIKZLowdV3JI4G/bLyW0KS
 y5Ko8dI6y5nOJ1P9XCmPTmags43UZfR8DrBUaAbzNcS8FGwmUE2KBkEhLQOvmpJi
 jmMc7wMOpq0jL+XbA+7pHUqoVZ7w1tUFjuy9I3h45tgPuTFAFB0gX+FpE+oVgO5o
 spQpVaOPEYN9ceLgHdKSxzdVIhOQLE6H/SYNHlsEW/ZNM6aR9n4yipgkOmtJ0+M=
 =WzHA
 -END PGP SIGNATURE-
 --
 https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python Style Question

2014-10-29 Thread Martin Kemp
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 29/10/2014 12:01, Rafael Romero Carmona wrote:
 2014-10-29 12:25 GMT+01:00 Martin Kemp martin.k...@ingg.com: On
 29/10/2014 10:45, Anton wrote:
 Let's say I have an incoming list of values *l*. Every
 element of *l* can be one of the following options: 1) an
 integer value 2) a string in form of 'int_value', e.g. '7'
 3) a string with a json serialization of an integer value,
 e.g. '7' 4) something else that should be ignored
 
 I need to transform this list into another list with values
 from options 1)-3) coerced to int. The code below should do
 this.
 
 
 Variant 1 ===
 
 values = [] for c in l: # Case 1) or 2) try: c_int = int(c)
 except ValueError: pass else: values.add(c_int) continue
 
 # Case 3) try: c_int = int(json.loads(c)) except ValueError:
 pass else: values.add(c_int) continue
 
 ===
 
 Is this code ugly? Does it follow EAFP? Am I missing
 something in language best practice?
 
 Or maybe below is more preferable way with a nested
 try...except clause?
 
 Variant 2 === values = [] for c in l: # Case 1) or 2) try:
 c_int = int(c) except ValueError:  # Case 3) try: c_int = 
 int(json.loads(c)) except ValueError: pass else:
 values.add(c_int) continue  else: values.add(c_int) continue
 ===
 
 Thanks, Anton.
 
 
 
 Your first example is perfectly fine and is EAFP
 
 
 Actually it doesn't work because there is no add function and it 
 doesn't catch the TypeError function to ignore other exceptions
 than ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4.
 
 Personally, I prefer to avoid nesting when it's not necessary.
 
 -- https://mail.python.org/mailman/listinfo/python-list

Ah ok, style-wise it was fine.

- -- 
Martin Kemp (martin.k...@ingg.com)

-BEGIN PGP SIGNATURE-
Version: GnuPG v2

iQEcBAEBAgAGBQJUUOD+AAoJEJ0Re0UIDzSu1KQIAK6aCMOv4VqOjmm/zoQrmzLf
UGBCLwtHrnDkbXFAIweTSFiM1uf9TDaRpJqY1IrPbJHI4/EAP0Hu07nyx3V6HgzM
/+Wb3DkpjW+JQoVqDSGzE/dTPJcU3/b1/EWWpbu72JHplqz9laEAFt9muWyDPs9u
kDgM06mDd50lsi83W3i0H1iGL6YbLtsik+/x4G4mMjdq1o9BvRpUjkIiOx7yJ/BR
OYzdudltXGqlXcToufHTU2lUv2C0RoHHNO4kytiLoUekCBdGE+Jy/6gQq/AKQu4G
0RYjCOnKNgugfdmDuHi0julPtTEzc+MdY/CcPob4cyy8RDzfQGklGKHP7f9+SJs=
=hjWU
-END PGP SIGNATURE-
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python Style Question

2014-10-29 Thread Anton
On Wednesday, October 29, 2014 4:43:33 AM UTC-7, Rafael Romero Carmona wrote:
 Hi, first in Python 2.7.6 and Python 3.4.0 list haven't got any add
 function but they have append.
You are right, in my original code I use set instead of array, so it should be 
either values = set() or values.append() in the original code.
 
 I think you could do better with something like
 
 ==
 import json
 l = [1, -1, 0, '1', '-1', '0', json.dumps(-1), json.dumps(1),
 json.dumps(0), 'x', 'sqjklsqjk__', (1, 2)]
It should also work with cases like [1, json.dumps('-1')], which is case 3), 
sorry if it was not clear in the initial post.
 
 values = []
 
 for c in l:
 try:
 c_int = int(c)
 except ValueError:
 pass
 except TypeError:
 pass
 else:
 values.append(c_int)
 continue
 print(values)
 ==
 
 The code has been tested in Python 2.7.6 and 3.4 and returns [1, -1,
 0, 1, -1, 0, -1, 1, 0]
 
 You don't need to do two try because you can process both exceptions
 in the same way. You don't really need to do json.loads because if you
 have a json string which is an integer, you could do that directly
 with int(c) which can take a string and transform in an integer.
In case of 3) an element can be a string like '1', which will fail int(...), 
in this case it tries to parse it with json.


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


Re: Python Style Question

2014-10-29 Thread Anton
On Wednesday, October 29, 2014 4:59:25 AM UTC-7, Rafael Romero Carmona wrote:
 2014-10-29 12:25 GMT+01:00 Martin Kemp mar...@ingg.com:
 Actually it doesn't work because there is no add function and it
 doesn't catch the TypeError function to ignore other exceptions than
 ValueError. Doesn't it? I tested in Python 2.7.6 and 3.4.
Originally I was using set instead of list. So it should have been either 
values = set() or values.append(), but it is not relevant to the question.
Regarding TypeError, I don't catch it on purpose, because I want this type of 
Exception to bubble up and surface as an error and be logged, because this 
should never be the case. I expect an element to be either something coercible 
to int or a string. If for some reason it is an object, then there is something 
wrong one layer up, so I want it to fail explicitly. 


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


Re: Style question -- plural of class name?

2013-05-09 Thread Thomas Rachel

Am 09.05.2013 02:38 schrieb Colin J. Williams:

On 08/05/2013 4:20 PM, Roy Smith wrote:


A list of FooEntry's  +1


Go back to school. Both of you...

That is NOT the way to build a plural form...


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


Re: Style question -- plural of class name?

2013-05-09 Thread Neil Cerutti
On 2013-05-08, Denis McMahon denismfmcma...@gmail.com wrote:
 On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

 FooEntry is a class.  How would you describe a list of these in a
 docstring?
 
 A list of FooEntries
 
 A list of FooEntrys
 
 A list of FooEntry's
 
 A list of FooEntry instances
 
 The first one certainly sounds the best, but it seems wierd to change
 the spelling of the class name to make it plural.

 I wouldn't use an apostrophe for pluralisation.

If there's no chance for confusion between a class named FooEntry
and another named FooEntries, then the first attempt seems best.
Pluralize a class name by following the usual rules, e.g.,
strings and ints.

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


Re: Style question -- plural of class name?

2013-05-09 Thread Jussi Piitulainen
Neil Cerutti writes:

 If there's no chance for confusion between a class named FooEntry
 and another named FooEntries, then the first attempt seems best.
 Pluralize a class name by following the usual rules, e.g.,
 strings and ints.

Like strings would be foo entries. Which might work well.

(I mean, isn't the class named str?)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Neil Cerutti
On 2013-05-09, Jussi Piitulainen jpiit...@ling.helsinki.fi wrote:
 Neil Cerutti writes:
 If there's no chance for confusion between a class named
 FooEntry and another named FooEntries, then the first attempt
 seems best. Pluralize a class name by following the usual
 rules, e.g., strings and ints.

 Like strings would be foo entries. Which might work well.

 (I mean, isn't the class named str?)

Yeah, that's not such a good Python example. I used it to replace
chars and felt good at the time. ;)

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


Re: Style question -- plural of class name?

2013-05-09 Thread Robert Kern

On 2013-05-08 21:20, Roy Smith wrote:

FooEntry is a class.  How would you describe a list of these in a
docstring?

A list of FooEntries

A list of FooEntrys

A list of FooEntry's

A list of FooEntry instances

The first one certainly sounds the best, but it seems wierd to change
the spelling of the class name to make it plural.


I'm using services like Github more and more to talk about code, so I have taken 
to adopting its inline markup for `code` when referring to identifiers. Thus, I 
will often write


  A list of `FooEntry`s

But I don't mind

  A list of FooEntries

Hopefully there isn't also a `FooEntries` class.

--
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

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


Style question -- plural of class name?

2013-05-08 Thread Roy Smith
FooEntry is a class.  How would you describe a list of these in a
docstring?

A list of FooEntries

A list of FooEntrys

A list of FooEntry's

A list of FooEntry instances

The first one certainly sounds the best, but it seems wierd to change
the spelling of the class name to make it plural.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Skip Montanaro
This one:

 A list of FooEntry instances

Besides the obvious spelling issues in the others, it's not
immediately clear if the list contains just FooEntry instances,
FooEntry classes (perhaps subclasses) or a mix of the two.  #4 makes
it clear.

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


Re: Style question -- plural of class name?

2013-05-08 Thread John Downs
On Wed, May 8, 2013 at 4:20 PM, Roy Smith r...@panix.com wrote:

 FooEntry is a class.  How would you describe a list of these in a
 docstring?

 A list of FooEntries

 A list of FooEntrys

 A list of FooEntry's

 A list of FooEntry instances

 The first one certainly sounds the best, but it seems wierd to change
 the spelling of the class name to make it plural.
 --
 http://mail.python.org/mailman/listinfo/python-list


How about: A list with elements of type FooEntry?  I also like the last
one: A list of FooEntry instances.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Ian Kelly
On Wed, May 8, 2013 at 2:37 PM, John Downs john.a.do...@gmail.com wrote:
 On Wed, May 8, 2013 at 4:20 PM, Roy Smith r...@panix.com wrote:

 FooEntry is a class.  How would you describe a list of these in a
 docstring?

 A list of FooEntries

 A list of FooEntrys

 A list of FooEntry's

 A list of FooEntry instances

 The first one certainly sounds the best, but it seems wierd to change
 the spelling of the class name to make it plural.
 --
 http://mail.python.org/mailman/listinfo/python-list


 How about: A list with elements of type FooEntry?  I also like the last
 one: A list of FooEntry instances.

listFooEntry

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


Re: Style question -- plural of class name?

2013-05-08 Thread Denis McMahon
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

 FooEntry is a class.  How would you describe a list of these in a
 docstring?
 
 A list of FooEntries
 
 A list of FooEntrys
 
 A list of FooEntry's
 
 A list of FooEntry instances
 
 The first one certainly sounds the best, but it seems wierd to change
 the spelling of the class name to make it plural.

I wouldn't use an apostrophe for pluralisation.

The Normal pluralisation of FooEntry would be FooEntries. Who are you 
expecting to read the docstring? English majors, grammar nazis, wikipedia 
editors, programmers, or all 4?

-- 
Denis McMahon, denismfmcma...@gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

 FooEntry is a class.  How would you describe a list of these in a
 docstring?


Which language are you writing your docstrings in? Obey the normal rules 
of spelling, grammar and punctuation for your language, which I assume is 
English.


 A list of FooEntries

Perfectly acceptable.


 A list of FooEntrys

There is no standard variant or dialect of English (British English, 
American English, etc.) that pluralises Entry as Entrys, so that would be 
absolutely not.


 A list of FooEntry's

Here come's an S! Quick, jam on an apostrophe!

This is called the grocer's apostrophe, and is universally held in 
contempt no matter what variant of English you write in. Don't do this.

The only acceptable use of an apostrophe to make a plural is if the thing 
being pluralised is a single letter. E.g. one a, two a's.

 
 A list of FooEntry instances

This is also acceptable, although a little wordy. Do you write a list of 
strings or a list of str instances?


 The first one certainly sounds the best, but it seems wierd to change
 the spelling of the class name to make it plural.

No weirder (note spelling) than changing any other noun. Whether you 
change int to ints or FooEntry to FooEntries, you're still 
changing it. That's how you make it plural.


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


Re: Style question -- plural of class name?

2013-05-08 Thread Chris Angelico
On Thu, May 9, 2013 at 6:20 AM, Roy Smith r...@panix.com wrote:
 A list of FooEntry's

Only if you put another apostrophe in:

A list of 'FooEntry's

But the delimited style is almost never of use. I'd go for this only
if there were some sort of automated markup being applied - if the
word FooEntry were turned into a hyperlink or something.

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


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 15:33:07 -0500, Skip Montanaro wrote:

 This one:
 
 A list of FooEntry instances
 
 Besides the obvious spelling issues in the others, it's not immediately
 clear if the list contains just FooEntry instances, FooEntry classes
 (perhaps subclasses) or a mix of the two.  #4 makes it clear.


I don't think this is a real issue. There isn't normally any ambiguity 
between instances and subclasses. When you read a list of ints, do you 
assume that the list looks like [int, MyInt, AnotherInt, FooInt] or do 
you expect it to look like [2, 7, 6, 1]?

The normal interpretation of one or more Foo is that we're talking 
about Foo *instances*, not subclasses of Foo. If that is not that case, 
then the onus is on the author of the documentation to make it clear that 
they are talking about subclasses.


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


Re: Style question -- plural of class name?

2013-05-08 Thread Colin J. Williams

On 08/05/2013 4:20 PM, Roy Smith wrote:

FooEntry is a class.  How would you describe a list of these in a
docstring?

A list of FooEntries  0

A list of FooEntrys   -1

A list of FooEntry's  +1

A list of FooEntry instances  No FooEntry is specified as a class.

The first one certainly sounds the best, but it seems wierd to change
the spelling of the class name to make it plural.



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


Re: Style question -- plural of class name?

2013-05-08 Thread Cameron Simpson
On 09May2013 00:02, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info 
wrote:
| On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:
|  A list of FooEntry's
| 
| Here come's an S! Quick, jam on an apostrophe!
| 
| This is called the grocer's apostrophe, and is universally held in 
| contempt no matter what variant of English you write in. Don't do this.
| 
| The only acceptable use of an apostrophe to make a plural is if the thing 
| being pluralised is a single letter. E.g. one a, two a's.

Frankly, not even then for me. I spell that one A, two As.

|  A list of FooEntry instances
| 
| This is also acceptable, although a little wordy. Do you write a list of 
| strings or a list of str instances?

How about a FooEntry list?
-- 
Cameron Simpson c...@zip.com.au

Yes Officer, yes Officer, I will Officer. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Michele Simionato
The standard is to use `cls`. In the __new__ method you can use `mcl` or `meta`.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Ian Kelly
On Tue, Jul 17, 2012 at 6:23 AM, Michele Simionato
michele.simion...@gmail.com wrote:
 The standard is to use `cls`. In the __new__ method you can use `mcl` or 
 `meta`.

I've also seen `mcs` a fair amount.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Ian Kelly
On Tue, Jul 17, 2012 at 12:10 AM, alex23 wuwe...@gmail.com wrote:
 On Jul 17, 1:29 am, Steven D'Aprano steve
 +comp.lang.pyt...@pearwood.info wrote:
 Here's a style question for you: in a metaclass, what should I call the
 instance parameter of methods, cls or self?

 Maybe portmanteu it as clasself? :)

What is this, 1st edition DD?  Elf is a race, not a class.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Steven D'Aprano
On Tue, 17 Jul 2012 05:23:22 -0700, Michele Simionato wrote:

 The standard is to use `cls`. In the __new__ method you can use `mcl` or
 `meta`.

Thanks to everyone who answered.

I think I will stick with meta and cls.


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


Style question: metaclass self vs cls?

2012-07-16 Thread Steven D'Aprano
Here's a style question for you: in a metaclass, what should I call the 
instance parameter of methods, cls or self?

class ExampleMeta(type):
def method(self, *args): ...

I'm not quite sure if that feels right. On the one hand, self is the 
ExampleMeta instance alright... but on the other, self is actually a 
class, so I feel I want to call it cls rather than self, which makes 
it more obvious that you're looking at a metaclass.

On the third-hand, it may be confusing that the argument is called cls 
but not decorated with classdecorator.

I'm very slightly leaning towards writing metaclasses like this:

class ExampleMeta(type):
def __new__(meta, *args): ...
def method(cls, *args): ...

class Example(metaclass=ExampleMeta):
def another_method(self): ...


What do others do?



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


Re: Style question: metaclass self vs cls?

2012-07-16 Thread Terry Reedy

On 7/16/2012 11:29 AM, Steven D'Aprano wrote:

Here's a style question for you: in a metaclass, what should I call the
instance parameter of methods, cls or self?

class ExampleMeta(type):
 def method(self, *args): ...

I'm not quite sure if that feels right. On the one hand, self is the
ExampleMeta instance alright... but on the other, self is actually a
class, so I feel I want to call it cls rather than self, which makes
it more obvious that you're looking at a metaclass.


I have never seriously written a metaclass, but as a reader I would 
prefer 'cls'.



On the third-hand, it may be confusing that the argument is called cls
but not decorated with classdecorator.


To me, that reinforces 'looking as a metaclass'.

An @classmethod in a class is a class method specific to the particular 
class. A method in a metaclass is a method common to all classes of the 
metaclass. They could be written differently, yet calling the first 
param 'cls' either way seems reasonable.



I'm very slightly leaning towards writing metaclasses like this:

class ExampleMeta(type):
 def __new__(meta, *args): ...
 def method(cls, *args): ...

class Example(metaclass=ExampleMeta):
 def another_method(self): ...



What do others do?


Not too many people write real metaclasses. Python lets you chose. Have 
you looked at the C code of type? (Not that you are bound by it.)


--
Terry Jan Reedy



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


Re: Style question (Poll)

2012-03-15 Thread Jon Clements
On Wednesday, 14 March 2012 21:16:05 UTC, Terry Reedy  wrote:
 On 3/14/2012 4:49 PM, Arnaud Delobelle wrote:
  On 14 March 2012 20:37, Croephacroe...@gmail.com  wrote:
  Which is preferred:
 
  for value in list:
if not value is another_value:
  value.do_something()
  break
 
 Do you really mean 'is' or '=='?
 
 If you mean x is not y, write it that way.
 'not x is y' can be misread and misunderstood, depending on whether
 the 'is' is true or not.
 
   not 1 is 1
 False
   not (1 is 1)
 False
   (not 1) is 1
 False
 
 Does not matter how read.
 
   not (1 is 0)
 True
   (not 1) is 0
 False
   not 1 is 0
 True
 
 Does matter how read.
 
  if list and not list[0] is another_value:
list[0].do_something()
 
 Or
 try:
value = mylist[0]
if value is not another_value: value.dosomething
 except IndexError:
pass
 
 I would not do this in this case of index 0, but if the index were a 
 complicated expression or expensive function call, making 'if list' an 
 inadequate test, I might.
 
  Hard to say, since they don't do the same thing :)
 
  I suspect you meant:
 
  for value in list:
  if not value is another_value:
  value.do_something()
  break
 
  I always feel uncomfortable with this because it's misleading: a loop
  that never loops.
 
 I agree. Please do not do this in public ;-).
 
 -- 
 Terry Jan Reedy

I'm not sure it's efficient or even if I like it, but it avoids try/except and 
the use of a for loop.

if next( iter(mylist), object() ) is not another_value:
# ...

Just my 2p,

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


Style question (Poll)

2012-03-14 Thread Croepha
Which is preferred:

for value in list:
 if not value is another_value:
   value.do_something()
   break

--or--

if list and not list[0] is another_value:
 list[0].do_something()

Comments are welcome, Thanks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Arnaud Delobelle
On 14 March 2012 20:37, Croepha croe...@gmail.com wrote:
 Which is preferred:

 for value in list:
  if not value is another_value:
    value.do_something()
    break

 --or--

 if list and not list[0] is another_value:
  list[0].do_something()

Hard to say, since they don't do the same thing :)

I suspect you meant:

for value in list:
   if not value is another_value:
   value.do_something()
   break

I always feel uncomfortable with this because it's misleading: a loop
that never loops.

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


Re: Style question (Poll)

2012-03-14 Thread Terry Reedy

On 3/14/2012 4:49 PM, Arnaud Delobelle wrote:

On 14 March 2012 20:37, Croephacroe...@gmail.com  wrote:

Which is preferred:

for value in list:
  if not value is another_value:
value.do_something()
break


Do you really mean 'is' or '=='?

If you mean x is not y, write it that way.
'not x is y' can be misread and misunderstood, depending on whether
the 'is' is true or not.

 not 1 is 1
False
 not (1 is 1)
False
 (not 1) is 1
False

Does not matter how read.

 not (1 is 0)
True
 (not 1) is 0
False
 not 1 is 0
True

Does matter how read.


if list and not list[0] is another_value:
  list[0].do_something()


Or
try:
  value = mylist[0]
  if value is not another_value: value.dosomething
except IndexError:
  pass

I would not do this in this case of index 0, but if the index were a 
complicated expression or expensive function call, making 'if list' an 
inadequate test, I might.



Hard to say, since they don't do the same thing :)

I suspect you meant:

for value in list:
if not value is another_value:
value.do_something()
break

I always feel uncomfortable with this because it's misleading: a loop
that never loops.


I agree. Please do not do this in public ;-).

--
Terry Jan Reedy

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


RE: Style question (Poll)

2012-03-14 Thread Prasad, Ramit
  Which is preferred:
 
  for value in list:
if not value is another_value:
  value.do_something()
  break
 
 Do you really mean 'is' or '=='?

Let me expound on how 'is' and '==' are very different. It may work 
for some comparisons but often not for others. Certain examples work
because of the Python implementation. 

 c = 1
 d = 1
 c is d # This only works because CPython caches small values.
True
 c == d
True
 a = 10
 b = 10
 a is b
False
 a == b
True
 10 is 10 
True

'10 is 10' works because the interpreter caches
the number because it is on the same line.


Only use 'is' if you are looking for objects like True,
False, None or something that MUST be exactly the same object.

In general, use '=='.



Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--

This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Arnaud Delobelle
On 14 March 2012 22:15, Prasad, Ramit ramit.pra...@jpmorgan.com wrote:
 Only use 'is' if you are looking for objects like True,
 False, None or something that MUST be exactly the same object.

I've rarely seen valid uses of 'is True' or 'is False'.

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


RE: Style question (Poll)

2012-03-14 Thread Prasad, Ramit
  Only use 'is' if you are looking for objects like True,
  False, None or something that MUST be exactly the same object.
 
 I've rarely seen valid uses of 'is True' or 'is False'.

It can be useful when you think something might be None or False. Although,
I suppose you could always just use 'is None' instead.

 1 == True
True
 1 is True
False
 0 == False
True
 0 is False
False

Granted, the above example is a pretty facetious case; not sure I 
can come up with a reasonably real world use case. 

Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Chris Angelico
On Thu, Mar 15, 2012 at 7:37 AM, Croepha croe...@gmail.com wrote:
 Which is preferred:

 for value in list:
  if not value is another_value:
    value.do_something()
    break

 --or--

 if list and not list[0] is another_value:
  list[0].do_something()

 Comments are welcome, Thanks

General principle: Make the code look like what it's doing. I don't
mean text art and making code in the shape of pi that prints the
digits of pi (although that can be awesome too), but more that a loop
should not be used when you don't intend for it to loop. Consider the
For-Case Paradigm[1] and the amazing confusion value that it can
offer. A loop needn't execute more than once (it needn't even execute
the first time), but it should at least have the _potential_ to
execute the same code multiple times, otherwise it's hardly a loop.

I had a particularly nasty example of a loop-that-wasn't-a-loop at
work a while ago; it was PHP, not Python, so I won't share it here,
but it had a do-while loop and an insidious bug in it. Very tricky.

ChrisA
[1] http://thedailywtf.com/Articles/The_FOR-CASE_paradigm.aspx
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-02-03 Thread Jean-Michel Pichavant

Gerald Britton wrote:


however, considering what

import a.module.that.is.quite.nested as myModule



Won't work since I get the objects at run time


  
myModule = __import__('whatever.module.imported.at.run.time', globals(), 
locals(), [], -1)


See http://docs.python.org/library/functions.html#__import__

JM


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


Re: Style question: Nicknames for deeply nested objects

2011-02-03 Thread Jean-Michel Pichavant

Gerald Britton wrote:



Nope. it's nothing to do with imports.  It's about objects passed to
methods at run time.  Complicated objects with many levels.  Not about
modules at all.
  


Who is providing these objects ?
- Your code ? = as said before, you can fix your design with a proper 
object model
- 3rd party libraries ? = I'd be curious to know which one, because 
they usually do a good job providing a clean minimal public interface.


However, do not redesign anything to get only shorter names. You can 
easily live with that, the way you're doing it is up to you and 
suggestions have been given. But keep in mind that you should'nt have 
got nested names that long in the first pace, no matter how complicated 
the internal implementation.


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


Re: Style question: Nicknames for deeply nested objects

2011-01-31 Thread Jean-Michel Pichavant

Gerald Britton wrote:

Hi all,

Today I was thinking about a problem I often encounter.  
[snip]


1. You need to call this thing many times with different arguments, so
you wind up with:

   x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
   y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
   z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3)
[snip]
--
Gerald Britton
  

This is not solved by style but by design.
You simply don't use too much nested objects. That's a sign of something 
wrong in your overall object model.


Since I do not encounter this problem as often as you are, I guess it is 
a matter of habbits.


however, considering what

import a.module.that.is.quite.nested as myModule

is doing, I guess using a local variable to store your nested method is 
just fine.


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


Style question: Nicknames for deeply nested objects

2011-01-30 Thread Gerald Britton
Hi all,

Today I was thinking about a problem I often encounter.  Say that I
have (seems I often do!) a deeply nested object, by which I mean
object within object with object, etc.

For example:

   x = some.deeply.nested.object.method(some.other.deeply.nested.object.value)

Well, that's extreme but I've worked with code approaching that level
of nested-ness.  Now, consider two scenarios:

1. You need to call this thing many times with different arguments, so
you wind up with:

   x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
   y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
   z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3)

2. You call it inside a loop:

   for item in some_iterable:
       x = 
some.deeply.nested.object.method(some.other.deeply.nested.object.value)

For one thing, I find the long lines unattractive at best and
error-prone at worst, especially if I also have

   some.other.deeply.nested.object.method

that I might confuse with the first.  To make it look better I might do this:

   _o = some.deeply.nested.object
   _o.method(_o.value)

which is fine, I suppose.

Then, putting on my company hat, I remembered that, from VBA, you could do this:

   with some.deeply.nested.object
       .method(.value)
   end with

I like the structure of this, since the subordinate block can be
indented, which makes it stand out.  Also, it avoids temporary
variables.

So, I was thinking of how to get close to this in Python.  I came up
with two approaches:

1.

   _o = some.deeply.nested.object
   if 1:
       _o.method(_o.value)

The if 1: forces me to indent the subordinate code, which sets it
apart from the surrounding code.  Note that I cannot just
indent because I feel like it since Python is persnickety about indentation.

2.

for _o in [some.deeply.nested.object]:
       _o.method(_o.value)

The for... sets up the iterator and forces me to indent the subordinate code.

As an aside, approach 1 generates less byte-code since approach 2 sets
up loop machinery which you don't really need in this case.

I have a couple of questions:

1. If you had to choose between approaches 1 and 2, which one would
you go for, and why?

2. What other techniques have you used in such a situation?


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


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 11:51 am, Gerald Britton gerald.brit...@gmail.com wrote:

[...]

 that I might confuse with the first.  To make it look better I might do this:

    _o = some.deeply.nested.object
    _o.method(_o.value)

 which is fine, I suppose.

It is very fine. And you supposed correctly!


 Then, putting on my company hat, I remembered that, from VBA, you could do 
 this:

    with some.deeply.nested.object
        .method(.value)
    end with

 I like the structure of this, since the subordinate block can be
 indented, which makes it stand out.  Also, it avoids temporary
 variables.

Yes it is a good idea! Well forgetting the horrendous VBA syntax this
is. I brought this up many moons back as a feature request: Local
Blocks. Here is how a pythonic local block would look

with this as localvar:
localvar.do_something()


 So, I was thinking of how to get close to this in Python.  I came up
 with two approaches:

 1.

    _o = some.deeply.nested.object
    if 1:
        _o.method(_o.value)

bad idea!


 2.

     for _o in [some.deeply.nested.object]:
        _o.method(_o.value)

even worse idea!


 I have a couple of questions:

 1. If you had to choose between approaches 1 and 2, which one would
 you go for, and why?

neither! Stick with the original.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Roy Smith
In article mailman.1469.1296409883.6505.python-l...@python.org,
 Gerald Britton gerald.brit...@gmail.com wrote:

 1. You need to call this thing many times with different arguments, so
 you wind up with:
 
    x = 
 some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
    y = 
 some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
    z = 
 some.deeply.nested.object.method(some.other.deeply.nested.object.value3)

I would probably turn that into:

object = some.deeply.nested.object
object.method(object.value1)
object.method(object.value2)
object.method(object.value3)

i.e. make the temporary variable have the exact same name as the last 
component of the deeply nested thing you're trying to refactor.  If the 
scope of use is small and the meaning is obvious from context, sometimes 
I'll shorten the name, i.e.

 obj = some.deeply.nested.object

or even

 o = some.deeply.nested.object

but I tend to avoid doing that.  I'd rather be a little more verbose in 
preference to being a little more cryptic.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 9:51 AM, Gerald Britton wrote:
 1. If you had to choose between approaches 1 and 2, which one would
 you go for, and why?

Neither. Ideally, I'd tweak the API around so the deeply nested
structure isn't something I need to access regularly. But! If you can't
do that, I'd do something like:

--- start
from contextlib import contextmanager

class Item(object): pass

deeply = Item()
deeply.nested = Item()
deeply.nested.thing = Item()

@contextmanager
def my(thing):
yield thing


with my(deeply.nested.thing) as o:
o.hello = 1

print deeply.nested.thing.hello
--- end

That's a dummy context-manager which basically does nothing: it just
abuses the context manager protocol to basically make a local variable
and indent its usage. Its really just a run-around and slightly less
efficient to do:

_o = some.deeply.nested.object
_o.method(_o.value)

But with the whitespace added on.

Personally, I'd usually just make a local variable and skip any tricks.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 12:23 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote:

 --- start
 from contextlib import contextmanager

 class Item(object): pass

 deeply = Item()
 deeply.nested = Item()
 deeply.nested.thing = Item()

 @contextmanager
 def my(thing):
     yield thing

 with my(deeply.nested.thing) as o:
     o.hello = 1

 print deeply.nested.thing.hello
 --- end

Well congratulations Stephen, you win the obfuscation prize of the
year!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 10:35 AM, rantingrick wrote:
 Well congratulations Stephen, you win the obfuscation prize of the
 year!

Yes,

On 1/30/11 10:09 AM, rantingrick wrote:
 Here is how a pythonic local block would look

 with this as localvar:
 localvar.do_something()

verses

with my(this) as localvar:
localvar.do_something()

Is dreadfully more, er, obfuscated.

I mean someone would have to know what the 'my' function does to
understand what's going on!

OH MY GOD. How can someone be expected to understand what a function does!

Be serious! You can't expect that of them.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Ian

On 30/01/2011 17:51, Gerald Britton wrote:

Hi all,

Today I was thinking about a problem I often encounter.  Say that I
have (seems I often do!) a deeply nested object, by which I mean
object within object with object, etc.

For example:

x = some.deeply.nested.object.method(some.other.deeply.nested.object.value)

Well, that's extreme but I've worked with code approaching that level
of nested-ness.  Now, consider two scenarios:

1. You need to call this thing many times with different arguments, so
you wind up with:

x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3)


Neither.  You should tell. Don't ask if you can avoid it.

Compare...

queen.getButter()

and
queen.dairymaid.alderney.getButter()

see  http://www.timelessteacherstuff.com/readerstheater/KingsBreakfast.pdf

king doesn't care where or how the butter is brought.  Neither should 
your code!


What are you doing with value1, value2 and value3 when you have them 
anyway? Stuffing them 3 levels deep into something else?


Stop writing procedural code, and write object oriented code instead!

If you you make some tell  deeply.nested.object  about 
other.deeply.nested.object it can fetch its own values, but it might be 
better
to have some tell other.deeply.nested.object about deeply.nested.object 
to it can issue the correct commands.


Then you tell some to  do Somthing by writing

  some.takeMeaningfullAction()

and it all happens under the covers.

Regards

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


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote:
 On 1/30/11 10:35 AM, rantingrick wrote:

  Well congratulations Stephen, you win the obfuscation prize of the
  year!

 Yes,

 On 1/30/11 10:09 AM, rantingrick wrote:

  Here is how a pythonic local block would look

  with this as localvar:
      localvar.do_something()

 verses

 with my(this) as localvar:
     localvar.do_something()

 Is dreadfully more, er, obfuscated.

Absolutely!

 I mean someone would have to know what the 'my' function does to
 understand what's going on!

Yes, and also how decorators word and generators work, and ...

 OH MY GOD. How can someone be expected to understand what a function does!

Yes, and also how decorators word and generators work, and ...

 Be serious! You can't expect that of them.

I don't. I don't expect anyone to write 10 lines of obfuscation code
when just two will suffice. Maybe you should join the perl group as
they would proud!

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


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Jerry Hill

 I don't. I don't expect anyone to write 10 lines of obfuscation code
 when just two will suffice. Maybe you should join the perl group as
 they would proud!


But Stephen's 10 lines of somewhat obscure code actually works, and your two
lines of code doesn't.  I know which one I would prefer.

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


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Steven D'Aprano
On Sun, 30 Jan 2011 12:51:20 -0500, Gerald Britton wrote:

 Hi all,
 
 Today I was thinking about a problem I often encounter.  Say that I have
 (seems I often do!) a deeply nested object, by which I mean object
 within object with object, etc.
 
 For example:
 
    x =
    some.deeply.nested.object.method
(some.other.deeply.nested.object.value)
 
 Well, that's extreme but I've worked with code approaching that level of
 nested-ness.

Then you're probably living in a state of sin, programming-wise, and you 
should stop doing that! You are violating the Law of Demeter. One dot, 
good. Two, acceptable. Three is a code smell. Four is a code reek.

The Law of Demeter (more of a guideline than a law, really) says:

If you want to get your dog to walk, call the dog. Don't talk to its 
legs, it confuses the dog and doesn't get it anywhere.

http://en.wikipedia.org/wiki/Law_of_Demeter

Another analogy: if you have to pay the paperboy for delivering the 
newspaper, you don't let him reach into your pocket, take out your 
wallet, open the wallet, take out whatever money he feels like, and put 
the wallet back.

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-
boy/demeter.pdf


Despite my comment above, the Law of Demeter is not *really* a dot-
counting exercise, although that's a handy short-cut for detecting 
potential problems. It can also apply to other data structures. If you've 
every seen C or Pascal code where you have a pointer to a pointer to a 
pointer to a pointer to a pointer to a pointer to some data, you've seen 
a violation.

Consider your example:

some.other.deeply.nested.object.value

This is very tightly coupled code: the caller, who knows about the object 
`some`, needs to know the internal details of not just `some` but also 
`other`, `deeply`, `nested`, and `object`. As a basic principle, this is 
poor design! Which would you rather deal with?

car.start()

car.ignition.turn(key).connect(car.starter(battery), car.spark_plug)

In particular, using temporary variables merely disguises the problem:

temp = some.other
temp = temp.deeply.nested
x = temp.object.value

Even though you never use more than two dots, you still have tight 
coupling. The point of Demeter is not to save dots (they're a renewable 
resource) but to reduce tight coupling.


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


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 1:13 PM, rantingrick wrote:
 On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote:
 OH MY GOD. How can someone be expected to understand what a function does!
 
 Yes, and also how decorators word and generators work, and ...
 
 Be serious! You can't expect that of them.
 
 I don't. I don't expect anyone to write 10 lines of obfuscation code
 when just two will suffice. Maybe you should join the perl group as
 they would proud!

Riiight.

suffice doesn't mean what you think it means. Generally, if something
suffices -- it actually, you know, ... works.

My four lines of setup can get put into a library and treated as a
recipe if they don't want to get into understanding generators or
decorators: then its two lines to use, and those two lines are exactly
like your two lines except for two little details:

  1. They add a function call to the syntax.
  2. They actually work.

The OP doesn't have to understand decorators or generators if he doesn't
want to: though I encourage him to do so, as they are beautiful and
elegant tools that can very clearly and concisely help solve a lot of
problems.

Now, me? I wouldn't use the recipe, as I originally said in my response.
I'd just use a local variable. But the OP didn't like that, and he
wanted some indenting and whitespace to clearly demarcate where he
intended to use the local. So I gave him a way to do that.

You gave him... uh, what was it again?

Oh, right.

Nothing.

As usual.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-21 Thread Francesco

I'd bet you would stress your point Steven! But you don't need to persuade me, 
I do already agree.
I just meant to say that, when the advantage is little, there's no need to 
rewrite a working function.
And that with modern CPUs, if tests take so little time, that even some 
redundant one is not so much of a nuisance.
in your working example, the payload is just a couple of integer calculations, that take very little time too. So the overhead due 
to redundant if tests does show clearly. And also in that not-really-real situation, 60% overhead just meant less than 3 seconds. 
Just for the sake of discussion, I tried to give both functions some plough to pull, and a worst-case situation too:


 t1 = Timer('for x in range(100): print func1(0),',
...  'from __main__ import func1')

 t2 = Timer('for x in range(100): print func2(0),',
...  'from __main__ import func2')

 min(t1.repeat(number=1, repeat=1))
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
53.011015366479114
 min(t2.repeat(number=1, repeat=1))
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
47.55442856564332

that accounts for a scant 11% overhead, on more than one million tests per 
cycle.

That said,  let's make really clear that I would heartily prefer func2 to func1, based both on readability and speed. Thank you for 
having spent some time playing with me!

Francesco

On 19/12/2010 1.05, Steven D'Aprano wrote:

Well, let's try it with a working (albeit contrived) example. This is
just an example -- obviously I wouldn't write the function like this in
real life, I'd use a while loop, but to illustrate the issue it will do.

def func1(n):
 result = -1
 done = False
 n = (n+1)//2
 if n%2 == 1:
 result = n
 done = True
 if not done:
 n = (n+1)//2
 if n%2 == 1:
 result = n
 done = True
 if not done:
 n = (n+1)//2
 if n%2 == 1:
 result = n
 done = True
 if not done:
 for i in range(100):
 if not done:
 n = (n+1)//2
 if n%2 == 1:
 result = n
 done = True
 return result


def func2(n):
 n = (n+1)//2
 if n%2 == 1:
 return n
 n = (n+1)//2
 if n%2 == 1:
 return n
 n = (n+1)//2
 if n%2 == 1:
 return n
 for i in range(100):
 n = (n+1)//2
 if n%2 == 1:
 return n
 return -1


Not only is the second far more readable that the first, but it's also
significantly faster:


from timeit import Timer
t1 = Timer('for i in range(20): x = func1(i)',

... 'from __main__ import func1')

t2 = Timer('for i in range(20): x = func2(i)',

... 'from __main__ import func2')

min(t1.repeat(number=10, repeat=5))

7.3219029903411865

min(t2.repeat(number=10, repeat=5))

4.530779838562012

The first function does approximately 60% more work than the first, all
of it unnecessary overhead.





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


Re: If/then style question

2010-12-19 Thread Steven D'Aprano
On Sat, 18 Dec 2010 19:59:45 -0800, Carl Banks wrote:

 On Dec 17, 12:23 am, Steven D'Aprano steve
 +comp.lang.pyt...@pearwood.info wrote:
 On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote:
  Even without the cleanup issue, sometimes you want to edit a function
  to affect all return values somehow.  If you have a single exit point
  you just make the change there; if you have mulitple you have to hunt
  them down and change all of them--if you remember to.  I just got bit
  by that one.

 If your function has so many exit points that you can miss some of them
 while editing, your function is too big, does too much, or both.
 
 Sanctimonious much?  In the real world, people miss things and make
 mistakes and not necessarily because they are working on something too
 complex to handle.  It happens.


Really? I had no idea. I've never made a misteak, I asumed evrybody else 
was equally brilliant. No, wait, there was that one time...

*wink*

Of course people make mistakes. So what's your point?

The point I was trying to make is that rather than encouraging an idiom 
(only one return statement, even if the algorithm is more clearly written 
with multiple exists) that leads to more complex, less efficient code 
just in case you might someday need to modify the return result, there 
are simple alternatives that avoid the need for anti-patterns like copy-
and-paste coding or enforced single exit point. I gave two: 

- refactor the complex code so that it's less complex (e.g. instead of 20 
exit points, which makes it easy to miss one or two, refactor it so there 
are two or three exit points); or if that's not practical:

- wrap it in a decorator that performs the post-processing you need.

Both can be simple, effective and Pythonic. Neither require the coder to 
use an artificial idiom just in case of some future need. The decorator 
solution works even if you don't have access to the source code, or if 
the function is a complex black box that nobody understands well enough 
to touch.



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


Re: If/then style question

2010-12-18 Thread Francesco

On 17/12/2010 0.51, Steven D'Aprano wrote:

Don't get me wrong... spaghetti code is*bad*. But there are other ways
of writing bad code too, and hanging around inside a function long after
you've finished is also bad:

def function(arg):
 done = False
 do_something()
 if some_condition:
 result = finished
 done = True
 if not done:
 do_something_else()
 if another_condition:
 result = now we're finished
 done = True
 if not done:
 do_yet_more_work()
 if third_condition:
 result = finished this time for sure
 done = True
 if not done:
 for i in range(100):
 if not done:
 do_something_small()
 if yet_another_condition:
 result = finally done!
 done = True
 return result

It's far more complicated than it need be, and does*lots*  of unnecessary
work. This can be written more simply and efficiently as:

def function(arg):
 do_something()
 if some_condition:
 return finished
 do_something_else()
 if another_condition:
 return now we're finished
 do_yet_more_work()
 if third_condition:
 return finished this time for sure
 for i in range(100):
 do_something_small()
 if yet_another_condition:
 return finally done!


I agree to your point, but I'm afraid you chose a wrong example (AFAIK, and 
that's not much).
Sure, the second version of function(arg) is much more readable, but why do you think the first one would do *lots*  of unnecessary 
work?

All the overhead in that function would be:
  if some_condition, three IF tests, and you know that's NOT a lot!
  if no conditions were met, (worst case) the first version would return an exception (unless result was globally defined) while 
the second would happily return None. Apart from this, the overhead in the first one would amount to one million IF tests, again not 
a lot these days. I don't think I would rewrite that function, if I found it written in the first way...

I don't mean that the fist example is better, just I'm sure you could imagine a 
more compelling proof of your concept.
Maybe there's something I don't know... in that case, please enlighten me!

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


Re: If/then style question

2010-12-18 Thread Steven D'Aprano
On Sat, 18 Dec 2010 12:29:31 +0100, Francesco wrote:

[...]
 I agree to your point, but I'm afraid you chose a wrong example (AFAIK,
 and that's not much). Sure, the second version of function(arg) is much
 more readable, but why do you think the first one would do *lots*  of
 unnecessary work?
 All the overhead in that function would be:
if some_condition, three IF tests, and you know that's NOT a lot! 

Well, let's try it with a working (albeit contrived) example. This is 
just an example -- obviously I wouldn't write the function like this in 
real life, I'd use a while loop, but to illustrate the issue it will do.

def func1(n):
result = -1
done = False
n = (n+1)//2
if n%2 == 1:
result = n
done = True
if not done:
n = (n+1)//2
if n%2 == 1:
result = n
done = True
if not done:
n = (n+1)//2
if n%2 == 1:
result = n
done = True
if not done:
for i in range(100):
if not done:
n = (n+1)//2
if n%2 == 1:
result = n
done = True
return result


def func2(n):
n = (n+1)//2
if n%2 == 1:
return n
n = (n+1)//2
if n%2 == 1:
return n
n = (n+1)//2
if n%2 == 1:
return n
for i in range(100):
n = (n+1)//2
if n%2 == 1:
return n
return -1


Not only is the second far more readable that the first, but it's also 
significantly faster:

 from timeit import Timer
 t1 = Timer('for i in range(20): x = func1(i)', 
... 'from __main__ import func1')
 t2 = Timer('for i in range(20): x = func2(i)', 
... 'from __main__ import func2')
 min(t1.repeat(number=10, repeat=5))
7.3219029903411865
 min(t2.repeat(number=10, repeat=5))
4.530779838562012

The first function does approximately 60% more work than the first, all 
of it unnecessary overhead.



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


Re: If/then style question

2010-12-18 Thread Carl Banks
On Dec 17, 12:23 am, Steven D'Aprano steve
+comp.lang.pyt...@pearwood.info wrote:
 On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote:
  Even without the cleanup issue, sometimes you want to edit a function to
  affect all return values somehow.  If you have a single exit point you
  just make the change there; if you have mulitple you have to hunt them
  down and change all of them--if you remember to.  I just got bit by that
  one.

 If your function has so many exit points that you can miss some of them
 while editing, your function is too big, does too much, or both.

Sanctimonious much?  In the real world, people miss things and make
mistakes and not necessarily because they are working on something
too complex to handle.  It happens.


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


Re: If/then style question

2010-12-17 Thread Steven D'Aprano
On Thu, 16 Dec 2010 20:32:29 -0800, Carl Banks wrote:

 Even without the cleanup issue, sometimes you want to edit a function to
 affect all return values somehow.  If you have a single exit point you
 just make the change there; if you have mulitple you have to hunt them
 down and change all of them--if you remember to.  I just got bit by that
 one.


If your function has so many exit points that you can miss some of them 
while editing, your function is too big, does too much, or both. Refactor 
and simplify. 

Or wrap the function in a decorator:

def affect_all_return_values(func):
@functools.wraps(func)
def inner(*args, **kwargs):
result = func(*args, **kwargs)
do_something_to(result)
return result
return inner

@affect_all_return_values
def my_big_complicated_function(args):
do_something_with_many_exit_points()



-- 
Steven


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


Re: If/then style question

2010-12-17 Thread Jean-Michel Pichavant

John Gordon wrote:

(This is mostly a style question, and perhaps one that has already been
discussed elsewhere.  If so, a pointer to that discussion will be
appreciated!)

When I started learning Python, I wrote a lot of methods that looked like
this:


  def myMethod(self, arg1, arg2):

if some_good_condition:

  if some_other_good_condition:

if yet_another_good_condition:

  do_some_useful_stuff()
  exitCode = good1

else:
  exitCode = bad3

  else:
exitCode = bad2

else:
  exitCode = bad1

return exitCode


But lately I've been preferring this style:


  def myMethod(self, arg1, arg2):

if some_bad_condition:
  return bad1

elif some_other_bad_condition:
  return bad2

elif yet_another_bad_condition:
  return bad3

do_some_useful_stuff()
return good1

I like this style more, mostly because it eliminates a lot of indentation.

However I recall one of my college CS courses stating that one entry,
one exit was a good way to write code, and this style has lots of exits.

Are there any concrete advantages of one style over the other?

Thanks.

  


What about,


def myMethod():
   for condition, exitCode in [
   (cond1, 'error1'),
   (cond2, 'very bad error'),
   ]:
   if not condition:
   break
   else:
  do_some_usefull_stuff() # executed only if the we never hit the 
break statement.

  exitCode = good1

   return exitCode

This version uses the 'for ... else' statement. You can easily add 
conditions by simply adding a line in the list, that's it.
Note that this code uses a shadow declaration of exitCode in the for 
loop. If you're not comfortable with that, you'll have to use a properly 
'declared' variable retCode and write retCode = exitCode before 
breaking. Actually I would advise to do so.


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


RE: If/then style question

2010-12-17 Thread Rob Richardson
-Original Message-
What about,


def myMethod():
for condition, exitCode in [
(cond1, 'error1'),
(cond2, 'very bad error'),
]:
if not condition:
break
else:
   do_some_usefull_stuff() # executed only if the we never hit the 
break statement.
   exitCode = good1

return exitCode

 I reply -

This is interesting, but I don't understand it (which speaks volumes
about the level of my understanding of Python).

First, just to clarify, I don't think the indentation I saw was what was
originally posted.  The else must be indented to match the if, and
the two statements under else are in the else block.  The return
statement is indented at the same level as the for statement, so that it
will be executed after the for loop exits.  Correct?

Now, the for loop will set condition to cond1 and exitCode to 'error1'.
Then it checks the contents of the condition variable.  But what does
not variable_name by itself mean?  I'm guessing that it checks that
the variable refers to an object.  So, the first time through, condition
refers to cond1, the if condition is false, and the else block gets
executed, and exitCode is changed to refer to good1.  The next time
through the loop, condition is set to refer to cond2 and exitCode is set
to refer to 'very bad error'.  Again, condition is refering to
something, so the else block is executed and we do useful stuff again,
which is probably not helpful and could well be harmful.  exitCode is
set to good1, we're finished with the loop, and we return exitCode.  

What happens if we try to do useful stuff, and we can't?  Where does the
error indication get set?  And once it does get set, the only way we can
exit the for loop is for condition to not refer to anything.  How can
that happen?

Thank you very much for your explanation and your patience with one who
only uses Python in very simplistic ways.

RobR

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


Re: If/then style question

2010-12-17 Thread Steven D'Aprano
On Fri, 17 Dec 2010 09:09:49 -0500, Rob Richardson wrote:


 First, just to clarify, I don't think the indentation I saw was what was
 originally posted.  The else must be indented to match the if, and
 the two statements under else are in the else block.  The return
 statement is indented at the same level as the for statement, so that it
 will be executed after the for loop exits.  Correct?

I think that what you are missing is that for-loops can include an else 
clause too, like this:


 for x in (1,2,3):
... print(x)
... else:
... print(finished)
...
1
2
3
finished



The else block runs after the for block, unless you exit the entire block 
by returning, raising an exception, or using break:


 for x in (1,2,3):
... print(x)
... if x == 3: break
... else:
... print(finished)
...
1
2
3
 


Does that clear up what is going on?


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


Re: If/then style question

2010-12-17 Thread Jean-Michel Pichavant

Rob Richardson wrote:

-Original Message-
What about,


def myMethod():
for condition, exitCode in [
(cond1, 'error1'),
(cond2, 'very bad error'),
]:
if not condition:
break
else:
   do_some_usefull_stuff() # executed only if the we never hit the 
break statement.

   exitCode = good1

return exitCode

 I reply -

This is interesting, but I don't understand it (which speaks volumes
about the level of my understanding of Python).

First, just to clarify, I don't think the indentation I saw was what was
originally posted.  The else must be indented to match the if, and
the two statements under else are in the else block.  

No, the else is indented to the for loop.
for ... else is a python statement, the else block is executed only if 
the loop did never break.

http://docs.python.org/reference/compound_stmts.html#for

The return
statement is indented at the same level as the for statement, so that it
will be executed after the for loop exits.  Correct?

Now, the for loop will set condition to cond1 and exitCode to 'error1'.
Then it checks the contents of the condition variable.  But what does
not variable_name by itself mean?  


condition is a bool value.

if not condition is evaluated to True, if the condition is False.
condition = False
not condition = True
condition = ('Foo' == 'Foo')
not condition = False

[snip]

RobR

  


My mail client could have messed up with the indentation.

Here is the code:
http://paste-it.net/public/t8a4acd/python/



JM


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


Re: If/then style question

2010-12-17 Thread David Robinow
On Thu, Dec 16, 2010 at 6:51 PM, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
...
 Functions always have one entry. The only way to have multiple entry
 points is if the language allows you to GOTO into the middle of a
 function, and Python sensibly does not allow this. The one entry, one
 exit rule comes from the days when people would routinely write
 spaghetti code, jumping into and out of blocks of code without using
 functions at all.
Only 99.7% true. Fortran still allows the appalling ENTRY statement.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-17 Thread Steve Holden
On 12/17/2010 9:38 AM, Steven D'Aprano wrote:
 On Fri, 17 Dec 2010 09:09:49 -0500, Rob Richardson wrote:
 
 
 First, just to clarify, I don't think the indentation I saw was what was
 originally posted.  The else must be indented to match the if, and
 the two statements under else are in the else block.  The return
 statement is indented at the same level as the for statement, so that it
 will be executed after the for loop exits.  Correct?
 
 I think that what you are missing is that for-loops can include an else 
 clause too, like this:
 
 
 for x in (1,2,3):
 ... print(x)
 ... else:
 ... print(finished)
 ...
 1
 2
 3
 finished

 
 
 The else block runs after the for block, unless you exit the entire block 
 by returning, raising an exception, or using break:
 
 
 for x in (1,2,3):
 ... print(x)
 ... if x == 3: break
 ... else:
 ... print(finished)
 ...
 1
 2
 3

 
 
 Does that clear up what is going on?
 
 
This construct appears to be unpopular in actual use, and when it comes
up in classes and seminars there is always interesting debate as people
discuss potential uses and realise there are useful applications.

I think the choice of keyword is probably not Guido's crowning language
achievement, but then since the English keywords don't make natural
sense to those who speak other languages it's at least fair that there
should be one that isn't totally natural to English speakers. A small
price to pay for all the other keywords not being Dutch.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

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


RE: If/then style question

2010-12-17 Thread Rob Richardson
My thanks for pointing out the existence of the else: suite in the for
statement.  However, I remain confused.  For reference, here's the
original code:

 def myMethod():
 for condition, exitCode in [
 (cond1, 'error1'),
 (cond2, 'very bad error'),
 ]:
 if not condition:
 break
 else:
do_some_usefull_stuff() # executed only if the we never hit the

 break statement.
exitCode = good1

 return exitCode

What do we know about cond1 and cond2?  Do they have to be assigned
before this for statement is executed?  The sample code doesn't show it.


The loop is going to to execute once for condition = cond1 and exitCode
= 'error1'.  The only thing it's going to do is check to see what
condition is.  Since we can assume (I hope) that cond1 is not false,
then the for loop continues.  Now condition = cond2 and exitCode = 'very
bad error'.  The if condition is still false, so the loop continues.
We've come to the end now, and the else: suite is executed.  We finally
do some useful stuff and exitCode = good1.  (Should that have been in
quotes, or doesn't it matter?)  But now the for loop's job is done and
we return the exitCode, which at this point is good1.  

But I still don't understand what happens if we can't do useful stuff.
Where does an error code get set, and where is that error code checked?
We don't have a chance to check it in the for loop, because once we're
in the else: suite the loop condition is never rechecked.  Or is it?

Thanks again!

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


Re: If/then style question

2010-12-17 Thread Tim Golden

On 17/12/2010 15:53, Steve Holden wrote:

[... snip example of for-else ...]


This construct appears to be unpopular in actual use, and when it comes
up in classes and seminars there is always interesting debate as people
discuss potential uses and realise there are useful applications.


I use this not infrequently, and I like it when it seems to be an
elegant way to express the code path. But I still misremember from
time to time and assume that the else clause fires when the for
loop is empty.

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


Re: If/then style question

2010-12-17 Thread Paul Rubin
Jean-Michel Pichavant jeanmic...@sequans.com writes:
 What about,

 def myMethod():
for condition, exitCode in [
(cond1, 'error1'),
(cond2, 'very bad error'),
]:
if not condition:
break
else:
   do_some_usefull_stuff() # executed only if the we never hit the
 break statement.
   exitCode = good1

return exitCode

 This version uses the 'for ... else' statement. 

For..else always has seemed ugly and confusing to me, as does that thing
of using the captured loop indexes after the loop finishes.  I'd prefer
a more functional style (untested):

   def myMethod():
  def success():
 do_some_usefull_stuff()
 return good1
  cond_table = [
   (cond1, lambda: 'error1'),
   (cond2, lambda: 'very bad error'),
   (True, success)
  ]
  func = next(f for c,f in cond_table if c)
  return func()

This uses the next() builtin from Python 2.6.  You could make it more
concise:

   def myMethod():
  cond_table = [
   (cond1, lambda: 'error1'),
   (cond2, lambda: 'very bad error'),
   (True, lambda: (do_some_usefull_stuff(), good1)[1])
  ]
  return next(f for c,f in cond_table if c)()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-17 Thread Ethan Furman

Rob Richardson wrote:

My thanks for pointing out the existence of the else: suite in the for
statement.  However, I remain confused.  For reference, here's the
original code:


def myMethod():
for condition, exitCode in [
(cond1, 'error1'),
(cond2, 'very bad error'),
]:
if not condition:
break
else:
   do_some_usefull_stuff() # executed only if the we never hit the



break statement.
   exitCode = good1

return exitCode


What do we know about cond1 and cond2?  Do they have to be assigned
before this for statement is executed?  The sample code doesn't show it.


cond1 and cond2 should be expressions of some sort, e.g.  check_files() 
or feedback (feedback being a variable of some sort).




The loop is going to to execute once for condition = cond1 and exitCode
= 'error1'.  The only thing it's going to do is check to see what
condition is.  Since we can assume (I hope) that cond1 is not false,
then the for loop continues.  Now condition = cond2 and exitCode = 'very
bad error'.  The if condition is still false, so the loop continues.
We've come to the end now, and the else: suite is executed.  We finally
do some useful stuff and exitCode = good1.  (Should that have been in
quotes, or doesn't it matter?)  But now the for loop's job is done and
we return the exitCode, which at this point is good1.  


But I still don't understand what happens if we can't do useful stuff.
Where does an error code get set, and where is that error code checked?
We don't have a chance to check it in the for loop, because once we're
in the else: suite the loop condition is never rechecked.  Or is it?


You have outlined what happens when cond1 and cond2 both evaluate to 
True -- what happens if, say, cond2 evaluates to False?


.

.

.

.

.

if not cond2 becomes True, we hit the break, do not do 
do_some_usefull_stuff(), but proceed to return exitCode -- and exitCode 
was set in the for loop to 'very bad error' when condition was set to cond2.


The exitCode no longer needs to be checked inside the function, because 
there is no chance of do_some_useful_stuff running if any of the 
conditions are False.


Hope this helps.

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


Re: If/then style question

2010-12-17 Thread Steve Holden
On 12/17/2010 11:13 AM, Tim Golden wrote:
 On 17/12/2010 15:53, Steve Holden wrote:
 
 [... snip example of for-else ...]
 
 This construct appears to be unpopular in actual use, and when it comes
 up in classes and seminars there is always interesting debate as people
 discuss potential uses and realise there are useful applications.
 
 I use this not infrequently, and I like it when it seems to be an
 elegant way to express the code path. But I still misremember from
 time to time and assume that the else clause fires when the for
 loop is empty.
 
Yes, that's a common misconception. The classical use is something like

for item in possibilities:
if item == target:
break
else:
raise NotFound(Didn't find it)

Though of course arguably that logic might be expressed in other ways,
such as

if target not in possibilities:
raise NotFound(Didn't find it)

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
PyCon 2011 Atlanta March 9-17   http://us.pycon.org/
See Python Video!   http://python.mirocommunity.org/
Holden Web LLC http://www.holdenweb.com/

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


Re: If/then style question

2010-12-17 Thread Mark Wooding
Steve Holden st...@holdenweb.com writes:

 I think the choice of keyword is probably not Guido's crowning
 language achievement,

I remember the behaviour by considering a typical application:

for thing in things:
  if shinyp(thing):
break
else:
  raise DullError, 'nothing shiny found'

In this kind of search loop, `break' signifies a kind of successful
completion: the `for' loop can be considered to be a test acting over an
iterable, and `else' therefore denotes the action if the test fails.

I don't know whether that's the official intuition, or even if there is
an official intuition, but it works well enough for me.  I'm quite fond
of Python's extra `else' clauses in `for' and (particularly) `try'.

-- [mdw]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-17 Thread Arnaud Delobelle
Tim Golden m...@timgolden.me.uk writes:

 On 17/12/2010 15:53, Steve Holden wrote:

 [... snip example of for-else ...]

 This construct appears to be unpopular in actual use, and when it comes
 up in classes and seminars there is always interesting debate as people
 discuss potential uses and realise there are useful applications.

 I use this not infrequently, and I like it when it seems to be an
 elegant way to express the code path. But I still misremember from
 time to time and assume that the else clause fires when the for
 loop is empty.

I use it from time to time, even though, like you, I used to always be
unsure when the else: suite would be executed.  I now remember this
idiom as the break else construct: either the loop breaks, or the
else: suite is executed.

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


Re: If/then style question

2010-12-17 Thread python
 I now remember this idiom as the break else construct: either the loop 
 breaks, or the else: suite is executed.

A perfect description.

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


Re: If/then style question

2010-12-17 Thread Grant Edwards
On 2010-12-16, Stefan Sonnenberg-Carstens stefan.sonnenb...@pythonmeister.com 
wrote:

 The advantage in latter case is fewer operations, because you can
 skip the assignments, and it is more readable.

 The one entry, one exit is an advice. Not a law.
 Your code is OK.

 As long as it works ;-)

Even that last bit isn't that important.

Give me code that's easy-to-read and doesn't work rather code that
works and can't be read any day.


-- 
Grant Edwards   grant.b.edwardsYow! What's the MATTER
  at   Sid? ... Is your BEVERAGE
  gmail.comunsatisfactory?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-17 Thread Grant Edwards
On 2010-12-16, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote:
 On Thu, 16 Dec 2010 21:49:07 +, John Gordon wrote:

 (This is mostly a style question, and perhaps one that has already been
 discussed elsewhere.  If so, a pointer to that discussion will be
 appreciated!)
 
 When I started learning Python, I wrote a lot of methods that looked
 like this:
 
   def myMethod(self, arg1, arg2):
 if some_good_condition:
   if some_other_good_condition:
 if yet_another_good_condition:
   do_some_useful_stuff()
   exitCode = good1
 else:
   exitCode = bad3
   else:
 exitCode = bad2
 else:
   exitCode = bad1
 return exitCode


 It doesn't look like you were learning Python. It looks like you were 
 learning C with Python syntax :(

Let's not blame C for bad program structure.  No good C programmer
would use that construct either.

One choice in C would look like this:

  if (some_condition)
return code1;

  if (other_condition)
return code2;

  if (condition3)
return code3;

  //do whatever work really needs to be done here.

  return successCode;

Or, if there's cleanup that needs to be done, then you raise a an
exception:


  if (condition1)
{
  ret  = code1;
  goto errexit;  
}

  if (condition2)
{
  ret  = code2;
  goto errexit;  
}

  if (condition3)
{
  ret  = code3;
  goto errexit;  
}


  // do the normal bit of work


  errexit:

  //cleanup  

  return ret;

  
-- 
Grant Edwards   grant.b.edwardsYow! Awright, which one of
  at   you hid my PENIS ENVY?
  gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: If/then style question

2010-12-17 Thread Rob Richardson

-Original Message-
You have outlined what happens when cond1 and cond2 both evaluate to 
True -- what happens if, say, cond2 evaluates to False?

- I reply 

And the light goes on!  (And palm strikes forehead.)  I was thinking
that the error we were processing was raised by the
do_some_useful_stuff() function.  But the whole purpose of this thread
was to evaluate error conditions that might have been set before we do
useful stuff!  Which, of course, was what the original poster was
asking.  

My thanks again for your patience.

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


  1   2   3   >