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


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


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


Re: If/then style question

2010-12-17 Thread Kev Dwyer
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
 
 

Another way to look at this is as question of object-oriented style, as you
 are using a method in your example...

Arguably, rather than branching your code based on the arguments being 
passed to your method, you can embody the required behaviour in subclasses
of your class, and at runtime just use an object that does the right 
thing.  Of course, you end up writing the same branching in some factory 
object instead, but at least it isn't cluttering up your business logic 
any longer.  Trying to write an OO-style program without using any if 
statements in the business logic can be an interesting exercise, albeit 
not a terribly realistic one.

Apologies if your choice of a method for your example was entirely
incidental to your question :)

Kev

-- 
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 10:53:45 -0500, Steve Holden wrote about 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.

Yes, I find I don't need it often, but it is useful from time to time.

I wonder whether it would have been more useful to reverse the sense of 
the else, and have it run only if the for loop *didn't* run to 
completion. That seemed more intuitive to me, and I've wanted to do this 
more than once. Here's a toy example:

for x in sequence:
if x == spam:
print(exiting early)
break
elif x == ham:
print(exiting early)
break
do_something(x)


would become:

for x in sequence:
if x == spam:
break
elif x == ham:
break
do_something(x)
else:
print(exiting early)



 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.

Indeed :)




-- 
Steven
-- 
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 17:26:08 +, Grant Edwards wrote:

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

Well, in that case, you'll love my new operating system, written in 100% 
pure Python:

[start code]
print(this is an operating system)
[end code]

I expect it to rapidly make Windows, Linux and OS-X all obsolete. Bill 
Gates and Steve Jobs, look out!

*grin*


Surely your attitude towards usefulness vs. readability will depend 
strongly on whether you are intending to *use* the code, or *maintain* 
the code?



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


If/then style question

2010-12-16 Thread John Gordon
(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.

-- 
John Gordon   A is for Amy, who fell down the stairs
gor...@panix.com  B is for Basil, assaulted by bears
-- Edward Gorey, The Gashlycrumb Tinies

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


Re: If/then style question

2010-12-16 Thread Ethan Furman

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.


As far as if/else goes, I prefer the second style also.

As far as returning bad codes, you are better off raising exceptions:

def myMethod(self, arg1, arg2):
if some_bad_condition:
raise Bad1()
elif some_other_bad_condition:
raise Bad2()
elif yet_another_bad_condition:
raise Bad3()
do_some_useful_stuff
# no need to return 'good' code -- success means no problems

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


Re: If/then style question

2010-12-16 Thread Tim Harig
On 2010-12-16, John Gordon gor...@panix.com wrote:
 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.

So, take the good intentation from one and the single exit from the other:

   def myMethod(self, arg1, arg2):

 if some_bad_condition:
   exitCode = bad1

 elif some_other_bad_condition:
   exitCode = bad2

 elif yet_another_bad_condition:
   exitCode = bad3

 else:
   exitCode = do_some_useful_stuff()

 # possible common cleanup code here

 return exitCode

Or, raise an exception on bad condtions rather then passing an error code.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-16 Thread Grant Edwards
On 2010-12-16, John Gordon gor...@panix.com 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.

There's nothing inherently wrong with indentation, but in this case
the latter style is a _lot_ easier to read (and modify without
breaking).

 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?

I think the check/exit style is far more readable.

It can trip you up if there is cleanup stuff that needs to happen
before you return from the function.  In that case putting the whole
function in a try statement and raising exceptions for the bad
conditions works nicely.  Then you get the more readable style of the
check/exit style, plus the advantage of a single exit (it's easy to
verify visually that all the required cleanup is happening).

-- 
Grant Edwards   grant.b.edwardsYow! I want a WESSON OIL
  at   lease!!
  gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-16 Thread Stefan Sonnenberg-Carstens

Am 16.12.2010 22:49, schrieb John Gordon:

(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


else:

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.






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


P.S.:
Sorry, I could not resist:
return bad1 if some_bad_condition else bad2 if some_other_bad_condition 
else bad3 if yet_another_bad_condition else good1 if 
do_some_useful_stuff() else good1

Or consider this:
return [x for x,y in 
((bad1,some_bad_condition),(bad2,some_other_bad_condition),(bad3,yet_another_bad_condition),(good1,do_some_useful_stuff() 
or True)) if x][0]


Neither self explanatory nor readable :-(
--
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-16 Thread Ryan Kelly
On Thu, 2010-12-16 at 21:49 +, 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?


one entry, one exit has its good points, but it's *way* overquoted and
overused.

Do you raise any exceptions? Do you call any functions that might raise
exceptions?  If so, you've got multiple exit points already.

I think this style a lot more important in a language like C where you
have to be super-careful about cleaning up after yourself.  The single
exit point makes it easier to verify that all cleanup tasks have been
performed.  Assuming you're using with or try-finally then you just
don't need such guarantees in python.

I'm not a PEP-8 pedant by any means, but I think that the first section
of PEP-8 contains the best advice I've ever read about programming
language style.  In fact, I'm going to quote it right here:



  A Foolish Consistency is the Hobgoblin of Little Minds
  ==
One of Guido's key insights is that code is read much more often than it
is written.  The guidelines provided here are intended to improve the
readability of code and make it consistent across the wide spectrum of
Python code.  As PEP 20 says, Readability counts.

...snip...

But most importantly: know when to be inconsistent -- sometimes the style
guide just doesn't apply.  When in doubt, use your best judgment.  Look
at other examples and decide what looks best.  And don't hesitate to ask!



In your example, the first style is difficult to read wile the second
style is easy to read.  You don't need any further justification for
preferring the latter.


  Cheers,


 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-16 Thread Ian Kelly
On Thu, Dec 16, 2010 at 3:41 PM, Stefan Sonnenberg-Carstens
stefan.sonnenb...@pythonmeister.com wrote:
 return [x for x,y in
 ((bad1,some_bad_condition),(bad2,some_other_bad_condition),(bad3,yet_another_bad_condition),(good1,do_some_useful_stuff()
 or True)) if x][0]

This doesn't work.  do_some_usefull_stuff() gets called during the
tuple construction regardless of the conditions, not during the list
comprehension execution as you would want.

Here's my take on an unreadable one-liner:

return reduce(lambda x, y: (x or (y[0]() and y[1])),
[(some_bad_condition, bad1), (some_other_bad_condition, bad2),
(yet_another_bad_condition, bad3), (lambda: (do_some_useful_stuff() or
True), good1)], None)

This of course assumes that bad1, bad2, and bad3 all evaluate as true.

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


Re: If/then style question

2010-12-16 Thread Steven D'Aprano
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 :(

The above would be more Pythonically written as:


def myMethod(self, arg1, arg2):
if not some_good_condition:
raise SomeException(message)
if not some_other_good_condition:
raise SomeOtherException(another message)
if yet_another_good_condition:
do_some_useful_stuff()
else:
raise SomeThirdException(whatever)


using exceptions to communicate errors out-of-band. Since no return 
result is needed, no explicit return is used and the method is the 
closest thing to a procedure that Python can offer.

The problem with in-band transmission of errors is that they invite the 
anti-pattern of this:

result = obj.myMethod(arg1, arg2)
if result == good1:
do_something_good()
elif result == bad1:
handle_error1()
elif result == bad2:
handle_error2()
elif result == bad3():
handle_error3()
else:
print This can't ever happen, but if it does...


which all too often becomes:

result = obj.myMethod(arg1, arg2)
if result == good1:
do_something_good()
else:  # assume result is bad1
handle_error1()


or even:

who_cares = obj.myMethod(arg1, arg2)
do_something_good()



 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.

Well, that's better, but still more like C rather than Python. Avoid the 
anti-pattern of returning in-band error codes. In some languages, either 
exceptions aren't available at all, or the overhead of them is so great 
that for performance you have to avoid them, but Python is not one of 
those languages.

In Python, exceptions are *the* primary way of communicating exceptional 
cases such as (but not limited to) errors. I can only think of two, er, 
exceptions to this rule: str.find() and some of the regular expression 
methods.


 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.

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.

If one entry is pointless (all functions have one entry!) then one 
exit is actively harmful. It leads to adding unnecessary complexity to 
functions, purely to meet the requirements of a rule invented to 
discourage spaghetti code. This hides bugs and increases the maintenance 
burden.

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!


Over 40% of the code in the first version

Re: If/then style question

2010-12-16 Thread alex23
John Gordon gor...@panix.com wrote:
 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

For more than 2 tests in a function like this, I'd probably use
dictionary dispatch:

def myMethod(self, arg1, arg2):
branches = dict(
cond1:  bad1,
cond2:  bad2,
cond3:  bad3
)

cond = expression

if cond == cond_good:
do_some_useful_stuff()
exitCode = good1
else:
exitCode = branches[cond]

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


Re: If/then style question

2010-12-16 Thread Joel Koltner
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote in message 
news:4d0aa5e7$0$29997$c3e8da3$54964...@news.astraweb.com...

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


True, although in many cases one has to interface to legacy C code where it'd 
be rather more code to start throwing exceptions left or right... since sooner 
or later those exceptions would still have to be turned into a single status 
(error) code!



which all too often becomes:

result = obj.myMethod(arg1, arg2)
if result == good1:
   do_something_good()
else:  # assume result is bad1
   handle_error1()


This really isn't a bad way to go *if you weren't planning on spending the 
time to really, fully flesh out the individual error cases anyway.*  I see 
this pretty often: Peple put in sophisticated exception handling 
infrastructure, but when an error actually occurs, all six dozen cases handled 
individually end up just printing some generic message and exiting the program 
anyway.


In an ideal world all the error cases would do something smart, but 
pragmatically one has to balance how likely an error is to occur and how much 
damage it does with how much time you want to spend making a really smart 
error handler.



or even:

who_cares = obj.myMethod(arg1, arg2)
do_something_good()


Even this can be OK if do_something_good() behaves in a relatively benign 
fashion when feed gibberish.  I mean, how many people actually check to see 
whether or not printf() succeeded, you know?


But I would agree that often you see...

who_care = obj.myMethod(arg1, arg2)
do_something_really_dangerous_that_depends_on_the_success_of_myMethod()

:-)


Well, that's better, but still more like C rather than Python. Avoid the
anti-pattern of returning in-band error codes.


The main sticky point here is that what's an error vs. a warning or note 
(but not success) is often rather a grey area.  E.g., Pyhton's open() raises 
an IOError is the file can't be opened, but in my mind that's still a common 
enough/expected occurrence that elevating its behavior to an exception is more 
a judgement call than something everyone would agree on.  (On the other hand, 
trying to read or write to an un-opened file is now clearly in the realm of an 
error and deserves an exception.)


---Joel

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


Re: If/then style question

2010-12-16 Thread Carl Banks
On Dec 16, 2:56 pm, Ryan Kelly r...@rfk.id.au wrote:
 On Thu, 2010-12-16 at 21:49 +, 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?

 one entry, one exit has its good points, but it's *way* overquoted and
 overused.

 Do you raise any exceptions? Do you call any functions that might raise
 exceptions?  If so, you've got multiple exit points already.

 I think this style a lot more important in a language like C where you
 have to be super-careful about cleaning up after yourself.  The single
 exit point makes it easier to verify that all cleanup tasks have been
 performed.  Assuming you're using with or try-finally then you just
 don't need such guarantees in python.

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.

It's a trade-off.  Readability and/or conciseness versus error
robustness.  I tend to go for the former but mileage varies.


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


Re: If/then style question

2010-12-16 Thread Steve Holden
On 12/16/2010 11:32 PM, Carl Banks wrote:
 On Dec 16, 2:56 pm, Ryan Kelly r...@rfk.id.au wrote:
 On Thu, 2010-12-16 at 21:49 +, 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?

 one entry, one exit has its good points, but it's *way* overquoted and
 overused.

 Do you raise any exceptions? Do you call any functions that might raise
 exceptions?  If so, you've got multiple exit points already.

 I think this style a lot more important in a language like C where you
 have to be super-careful about cleaning up after yourself.  The single
 exit point makes it easier to verify that all cleanup tasks have been
 performed.  Assuming you're using with or try-finally then you just
 don't need such guarantees in python.
 
 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.
 
 It's a trade-off.  Readability and/or conciseness versus error
 robustness.  I tend to go for the former but mileage varies.
 
Heaven forfend you should just wrap the existing function inside another
one which takes its name, if all its returns need to be altered.

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: Python Style Question

2009-01-22 Thread Steve Holden
K-Dawg wrote:
 I am trying to become more pythonic as I learn python and get my mind
 around it instead of other languages I have used.
 
 I have an app that has a series of classes for objects it uses.  From a
 style perspective, which should be done:
 
 Different py file for each class
 
 or
 
 One py file with all the classes
 
 The classes are small with a constructor and a few methods, no more than
 a couple, some with just one other method.
 
 Which is more pythonic?
 
One .py file with all the classes. But it's also very pythonic that you
have the choice, and can select the option that suits you best ;-)

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

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


Re: Python Style Question

2009-01-22 Thread Terry Reedy

Steve Holden wrote:

K-Dawg wrote:

I am trying to become more pythonic as I learn python and get my mind
around it instead of other languages I have used.

I have an app that has a series of classes for objects it uses.  From a
style perspective, which should be done:

Different py file for each class


Python is not Java!



or

One py file with all the classes

The classes are small with a constructor and a few methods, no more than
a couple, some with just one other method.


Or if that gets to be too much, a few files each with several related 
classes.



Which is more pythonic?


One .py file with all the classes. But it's also very pythonic that you
have the choice, and can select the option that suits you best ;-)


Nice put Steve.

tjr

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


Re: docstrings style question

2008-01-10 Thread Russ P.
On Jan 9, 11:51 pm, Fredrik Lundh [EMAIL PROTECTED] wrote:
 Steve Brown wrote:
  I've got a series of modules which look like this:

  #
  #
  # Temperature Sense Test
  #
  #
  class Test3(ar_test.AR_TEST):
  Temperature Sense Test

  I don't like the duplicated information: But the comment is attractive, and
  the docstring self.__doc__ is already in use in the test log. I've read that
  all modules and classes should have docstrings, but I don't really have
  anything else to say, and each module contains only one class. I don't think
  that

  Temperature Sense Test
  class Test3(ar_test.AR_TEST):
  Temperature Sense Test

  would be a real improvement.

  What do you think?

 since you already seem to cater to your audience (clearly marked
 comments for people browsing the code, brief docstrings for the test
 log), I don't really see why you should change anything.

   I've read that all modules and classes should have docstrings

 if nobody's going to read them, there's no reason to add them.  don't
 treat generic style advice as dogma.

 /F

Well, trivial modules certainly don't need much documentation, but he
didn't say they were trivial. I assumed there was more to them then he
showed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: docstrings style question

2008-01-10 Thread Jeroen Ruigrok van der Werven
-On [20080110 06:51], Steve Brown ([EMAIL PROTECTED]) wrote:
I don't like the duplicated information: But the comment is attractive,

I find it unattractive to be honest.

and the docstring self.__doc__ is already in use in the test log. I've read
that all modules and classes should have docstrings, but I don't really have
anything else to say, and each module contains only one class.

The ultimate test is running `pydoc your.module` or running epydoc on your
source and see how well the resulting documentation is built up.

-- 
Jeroen Ruigrok van der Werven asmodai(-at-)in-nomine.org / asmodai
イェルーン ラウフロック ヴァン デル ウェルヴェン
http://www.in-nomine.org/ | http://www.rangaku.org/
The quieter you become, the more you are able to hear...
-- 
http://mail.python.org/mailman/listinfo/python-list

RE: docstrings style question

2008-01-10 Thread Ryan Ginstrom
 On Behalf Of Steve Brown
 What do you think?

I think that comments are for maintainers, and docstrings are for users. 

Some of the things I use comments for:
* Visually separate classes (using a syntax-highlighting editor)
* Explain algorithm choices
* Explain bug fixes so I don't later fix code back to the buggy version

Some of the things I use docstrings for:
* Describe interface (inputs/outputs)
* Sample usage

I personally don't use doctests, but that's one more use of docstrings.

Regards,
Ryan Ginstrom

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


Re: docstrings style question

2008-01-10 Thread Martin Marcher
Russ P. wrote:

 On Jan 9, 9:47 pm, Steve Brown [EMAIL PROTECTED] wrote:
 I've got a series of modules which look like this:

 #
 #
 # Temperature Sense Test
 #
 #
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test

 I don't like the duplicated information: But the comment is attractive,
 and the docstring self.__doc__ is already in use in the test log. I've
 read that all modules and classes should have docstrings, but I don't
 really have anything else to say, and each module contains only one
 class. I don't think that

 Temperature Sense Test
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test

 would be a real improvement.

 What do you think?

It's still duplicated information.

 I tend to be a bit skimpy with one-line comments for classes and
 methods, but I think a more complete ( style) comment is often
 appropriate for the top of the file.
 
 I'm sure you can think of more to say than Temperature Sense Test.

exactly my opinion

 What temperature? What kind of temperature sensor? What kind of test
 is it, and why are you doing it? That may all be obvious in context,
 but you've provided no context in your post. Also, if the module is of
 any significant size, you might want to provide a clue about who wrote
 it. Then, if someone has a question about it later, they will know who
 to ask.

I tend to mention the main use cases for test classes (especially) and also
a human readable description of what can happen (forgive me the missing
line breaks). Something like this:

class Test3(ar_test.AR_TEST):
Temperature Sense Test.
This class assures that the connection to the hardware sensor can be
established. It also checks a reference sensor that always reports a
certain value so that one can be sure correct data values are reported.


hth
martin

-- 
http://noneisyours.marcher.name
http://feeds.feedburner.com/NoneIsYours

You are not free to read this message,
by doing so, you have violated my licence
and are required to urinate publicly. Thank you.

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


Re: docstrings style question

2008-01-10 Thread Steve Brown

Russ P. [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 On Jan 9, 11:51 pm, Fredrik Lundh [EMAIL PROTECTED] wrote:
 Steve Brown wrote:
  I've got a series of modules which look like this:

  #
  #
  # Temperature Sense Test
  #
  #
  class Test3(ar_test.AR_TEST):
  Temperature Sense Test

  I don't like the duplicated information: But the comment is attractive, 
  and
  the docstring self.__doc__ is already in use in the test log. I've read 
  that
  all modules and classes should have docstrings, but I don't really have
  anything else to say, and each module contains only one class. I don't 
  think
  that

  Temperature Sense Test
  class Test3(ar_test.AR_TEST):
  Temperature Sense Test

  would be a real improvement.

  What do you think?

 since you already seem to cater to your audience (clearly marked
 comments for people browsing the code, brief docstrings for the test
 log), I don't really see why you should change anything.

   I've read that all modules and classes should have docstrings

 if nobody's going to read them, there's no reason to add them.  don't
 treat generic style advice as dogma.

 /F

 Well, trivial modules certainly don't need much documentation, but he
 didn't say they were trivial. I assumed there was more to them then he
 showed.

All of the complexity is in the test framework. I've been working on paring 
back the tests to make them simple to understand, create and modify, which 
is how I've come to this: I'm still trying to remove lines. The test itself 
is a now a linear script of 20-40 lines, and I'm still working on them.

However, it is relatively important to make the documentation right for 
these simple scripts.

The docstring/comment does need to show some embedded dependancies, I just 
chose one without any.

I realise from reading Jeroen Ruigrok van der Werven's comment that I should 
probably also
care what epydoc makes of my doc strings, -- that's an additional 
constraint. 


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


Re: docstrings style question

2008-01-10 Thread Neil Cerutti
On Jan 10, 2008 12:47 AM, Steve Brown [EMAIL PROTECTED] wrote:
 I've got a series of modules which look like this:

 #
 #
 # Temperature Sense Test
 #
 #
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test


 I don't like the duplicated information: But the comment is attractive, and
 the docstring self.__doc__ is already in use in the test log. I've read that
 all modules and classes should have docstrings, but I don't really have
 anything else to say, and each module contains only one class. I don't think
 that

 Temperature Sense Test
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test

 would be a real improvement.

 What do you think?

I recommend a careful reading of PEP 257.

You shouldn't waste your time creating (at best) decorative comments, like:
#
#
# Temperature Sense Test
#
#
class Test3(ar_test.AR_TEST):
 Temperature Sense Test

Remember that comments have to maintained along with the rest of the
code, so unnecessary ones just create more work for you. Any time you
can replace a comment with self-explanatory code, you should.

Here's a vast improvement:

class TemperatureSenseTester(ar_test.AR_TEST):

-- 
Neil Cerutti [EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: docstrings style question

2008-01-10 Thread Steve Brown

Neil Cerutti [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 On Jan 10, 2008 12:47 AM, Steve Brown [EMAIL PROTECTED] wrote:
 I've got a series of modules which look like this:

 #
 #
 # Temperature Sense Test
 #
 #
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test


 I don't like the duplicated information: But the comment is attractive, 
 and
 the docstring self.__doc__ is already in use in the test log. I've read 
 that
 all modules and classes should have docstrings, but I don't really have
 anything else to say, and each module contains only one class. I don't 
 think
 that

 Temperature Sense Test
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test

 would be a real improvement.

 What do you think?

 I recommend a careful reading of PEP 257.

 You shouldn't waste your time creating (at best) decorative comments, 
 like:
 #
 #
 # Temperature Sense Test
 #
 #
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test

 Remember that comments have to maintained along with the rest of the
 code, so unnecessary ones just create more work for you. Any time you
 can replace a comment with self-explanatory code, you should.

 Here's a vast improvement:

 class TemperatureSenseTester(ar_test.AR_TEST):

 -- 
 Neil Cerutti [EMAIL PROTECTED]

Yes, I'm working in that direction. At present there is still code that
parses the test sequence to get the class name, but I'm rebuilding that.

However, there will still be sufficient information for some of the tests
to justify one doc string or comment as well as the class name.

Is it possible to get from an object to a class module doc string?

Something like self.class.module.__doc__ ?

I'm not able to do an assignment inside the test class, because I have
to keep that clean, but I can do assignments inside the parent test class.


Steve 


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


Re: docstrings style question

2008-01-10 Thread Steve Brown
What I'm trying to do with the tests is pare them back so that
the code explicitly and concisely documents the tests.

It is important that the comments and doc strings NOT contain
information about how Temperature Sense works because that
is outside the scope of the test.

More generally, comments like this

i++#increments i

indicate that the author thinks that the most complex thing
present is the syntax, a comment like this:

i++#next voltage

indicates that the author thinks the most complex thing present
is the variable mapping.

For the readers and maintainers of these tests, the most complex
thing present is the syntax, not the test logic, so if I need to add
more documentation, it will look like this:

# Temperature Sense Test
# Lines starting with # are comments
# Variables are case sensitive
# Tab characters will break this file

-- and go from there.

Steve


Martin Marcher [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 Russ P. wrote:



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


Re: docstrings style question

2008-01-10 Thread Steven D'Aprano
On Fri, 11 Jan 2008 13:09:26 +1100, Steve Brown wrote:

 What I'm trying to do with the tests is pare them back so that the code
 explicitly and concisely documents the tests.

Yes, this is good.


 It is important that the comments and doc strings NOT contain
 information about how Temperature Sense works because that is outside
 the scope of the test.
 
 More generally, comments like this
 
 i++#increments i
 
 indicate that the author thinks that the most complex thing present is
 the syntax, 

I would suggest that it indicates an author who hates writing  
documentation, but has been told that (s)he *must* do it.

That is the archetypal example of the pointless comment that is worse 
than no comment at all.


 a comment like this:
 
 i++#next voltage
 
 indicates that the author thinks the most complex thing present is the
 variable mapping.

To me, that indicates the author both hates writing documentation, and 
either can't think of descriptive variable names, or refuses to use them 
out of some misguided sense of optimization.


 For the readers and maintainers of these tests, the most complex thing
 present is the syntax, not the test logic, so if I need to add more
 documentation, it will look like this:
 
 # Temperature Sense Test
 # Lines starting with # are comments
 # Variables are case sensitive
 # Tab characters will break this file
 
 -- and go from there.

Your trusting your production code to developers who don't even know the 
most basic elements of syntax like what is a comment? That's pretty 
foolh^H^H^H^H^H brave.



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


Re: docstrings style question

2008-01-09 Thread Fredrik Lundh
Steve Brown wrote:

 I've got a series of modules which look like this:
 
 #
 #
 # Temperature Sense Test
 #
 #
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test
 
 
 I don't like the duplicated information: But the comment is attractive, and 
 the docstring self.__doc__ is already in use in the test log. I've read that 
 all modules and classes should have docstrings, but I don't really have 
 anything else to say, and each module contains only one class. I don't think 
 that
 
 Temperature Sense Test
 class Test3(ar_test.AR_TEST):
 Temperature Sense Test
 
 would be a real improvement.
 
 What do you think?

since you already seem to cater to your audience (clearly marked 
comments for people browsing the code, brief docstrings for the test 
log), I don't really see why you should change anything.

  I've read that all modules and classes should have docstrings

if nobody's going to read them, there's no reason to add them.  don't 
treat generic style advice as dogma.

/F

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


Non-ASCII languages (was: Re: style question)

2006-07-01 Thread Jorgen Grahn
On Thu, 29 Jun 2006 23:19:34 +0200, Fredrik Lundh [EMAIL PROTECTED] wrote:
 Jorgen Grahn wrote:
...
 (I like well-typeset code in print though. Bjarne Stroustrup uses an elegant
 system for C++ code, where identifiers and strings are in Times italic,
 operators in Courier, and so on.)

 the idea of printing everything in courier (or some other monospace 
 font) is a rather new idea; if you read seventies stuff, the program 
 code is often as carefully designed as the rest of the document.

Possibly true, and definitely for Knuth.  But WYSIWYG was unknown at the
time; these people all programmed using fixed-width fonts, on teletypes or
character-mapped terminals. Hell, even full-screen editors were new and
controversial until the late 1970s!

Program editing and displaying/typesetting can be treated as separate from
each other. Personally, I think they /should/ be -- I prefer troff or LaTeX
to MS Word, after all.

 (for an indication that we might be moving back to nicely rendered code, 
 see Sun's new Fortress language, which provides extraordinarily detailed 
 control over how identifiers are rendered, including extensive support 
 for Unicode and math notation.  it also mandates the use of proportional 
 fonts for things like identifiers and comments...)

And Sun apparently think they should not be separate.
To me, it looks like they are planning for this language to fail.

If I wanted to try out this language, I would have to give up most of my
existing toolbox -- which works flawlessly with everything from TI assembly
to Python. And what would people discuss on comp.lang.fortress? Google
destroys Python code well enough ...

/Jorgen

-- 
  // Jorgen Grahn grahn@Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.dyndns.org  R'lyeh wgah'nagl fhtagn!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Non-ASCII languages (was: Re: style question)

2006-07-01 Thread Nick Maclaren

In article [EMAIL PROTECTED],
Jorgen Grahn [EMAIL PROTECTED] writes:
| 
| Possibly true, and definitely for Knuth.  But WYSIWYG was unknown at the
| time; these people all programmed using fixed-width fonts, on teletypes or
| character-mapped terminals. Hell, even full-screen editors were new and
| controversial until the late 1970s!

A slight niggle - WYSIWYG wasn't unknown, just both rare and not yet
called that!  I have programmed using devices with half-line shifts,
real backspacing and so on - and some languages did mandate that a
character created by overprinting was to be treated as a composite
character.

Also, there were full-screen editors for things like IBM 3270s, though
they were absolutely ghastly for editing text (being designed for form
filling).

I agree with you that neither those days nor gimmicky approaches like
that of Fortress are worth pursuing.  One of the main reasons that
'program proving' has never taken off outside its cabal is that it
uses bizarre notations unlike anything else on earth that can't be
edited in a normal fashion.


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


calling functions style question

2006-06-06 Thread Brian
I just have a basic style question here.  Suppose you have the program:

def foo1():
do something

def foo2()
do something else

Assume that you want to call these functions at execution.  Is it more
proper to call them directly like:

foo1()
foo2()

or in an if __name__ == __main__: ?

Both will execute when the script is called directly, I was just
wondering if there is a preference, and what the pros and cons to each
method were.

Thanks,
Brian

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


Re: calling functions style question

2006-06-06 Thread Thomas Nelson
The difference becomes clear when you import your program into another
program (or the command line python editor).  __name__!='__main__' when
you import, so the functions will not be called if they're inside the
block.  This is why you see this block so often at the end of scripts;
so that the script runs its main functions when called as a standalone
program, but you can also import the code and do something with it
without setting off those functions.

THN

Brian wrote:
 I just have a basic style question here.  Suppose you have the program:

 def foo1():
 do something

 def foo2()
 do something else

 Assume that you want to call these functions at execution.  Is it more
 proper to call them directly like:

 foo1()
 foo2()

 or in an if __name__ == __main__: ?

 Both will execute when the script is called directly, I was just
 wondering if there is a preference, and what the pros and cons to each
 method were.
 
 Thanks,
 Brian

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


Re: calling functions style question

2006-06-06 Thread Kay Schluehr

Brian wrote:
 I just have a basic style question here.  Suppose you have the program:

 def foo1():
 do something

 def foo2()
 do something else

 Assume that you want to call these functions at execution.  Is it more
 proper to call them directly like:

 foo1()
 foo2()

 or in an if __name__ == __main__: ?

 Both will execute when the script is called directly, I was just
 wondering if there is a preference, and what the pros and cons to each
 method were.

 Thanks,
 Brian

If you want those functions to be called each time your module gets
imported you have to apply calls out of the if __name__ ...
statement. If your module is, for certain reasons, always the __main__
module and never gets imported there is no obvious preference because
behaviour will be the same.

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