Re: Is this pythonic?

2016-11-24 Thread Marko Rauhamaa
Chris Angelico :

> On Thu, Nov 24, 2016 at 10:14 PM, Marko Rauhamaa  wrote:
>> When you use threads, you call read(2) in the blocking mode. Then the
>> read(2) operation will block "for ever." There's no clean way to
>> cancel the system call.
>
> Signals will usually interrupt system calls, causing them to return
> EINTR. There are exceptions (the aforementioned uninterruptible calls,
> but they're not available in nonblocking form, so they're the same for
> threads and coroutines), but the bulk of system calls will halt
> cleanly on receipt of a signal. And yes, you CAN send signals to
> specific threads; there are limitations, but for a language like
> Python, there's no difficulty in having a single disposition for (say)
> SIGINT, and then using thread signalling to figure out which thread
> should have KeyboardInterrupt raised in it.

Yes, pthread_kill(3) has been made available in Python-3.3, I'm
noticing.

Also:

   Changed in version 3.5: Python now retries system calls when a
   syscall is interrupted by a signal, except if the signal handler
   raises an exception (see PEP 475 for the rationale), instead of
   raising InterruptedError.

   https://docs.python.org/3/library/exceptions.html#Interrupt
   edError>


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


Re: Is this pythonic?

2016-11-24 Thread Chris Angelico
On Thu, Nov 24, 2016 at 10:14 PM, Marko Rauhamaa  wrote:
> When you use threads, you call read(2) in the blocking mode. Then the
> read(2) operation will block "for ever." There's no clean way to cancel
> the system call.

Signals will usually interrupt system calls, causing them to return
EINTR. There are exceptions (the aforementioned uninterruptible calls,
but they're not available in nonblocking form, so they're the same for
threads and coroutines), but the bulk of system calls will halt
cleanly on receipt of a signal. And yes, you CAN send signals to
specific threads; there are limitations, but for a language like
Python, there's no difficulty in having a single disposition for (say)
SIGINT, and then using thread signalling to figure out which thread
should have KeyboardInterrupt raised in it.

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


Re: Is this pythonic?

2016-11-24 Thread Marko Rauhamaa
Chris Angelico :

> On Thu, Nov 24, 2016 at 9:59 PM, Marko Rauhamaa  wrote:
>> Chris Angelico :
>>> A coroutine can be abandoned at an await point, but the
>>> currently-executed call is still going to complete (usually);
>>
>> I don't quite understand. Say you are awaiting on receiving bytes from a
>> socket. That means there has been a nonblocking call to read(2),
>> recvmsg(2) or equivalent that has returned EAGAIN. If you now abandon
>> the coroutine, there is no resumption of the system call but the
>> coroutine can finish instantaneously.
>
> Is the read(2) still going to consume data from the pipe/socket?

Only if the kernel has already buffered data it has received previously.

If there isn't yet any data available in the kernel, read(2) returns
with errno=EAGAIN, and the control is returned to the main loop. The
main loop then goes to sleep in epoll_wait(2) or equivalent.

> If so, the operation is still going to continue, whether you use
> coroutines or threads. If not, it would have been cancelled whether
> you use coroutines or threads.

When you use threads, you call read(2) in the blocking mode. Then the
read(2) operation will block "for ever." There's no clean way to cancel
the system call.


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


Re: Is this pythonic?

2016-11-24 Thread Chris Angelico
On Thu, Nov 24, 2016 at 9:59 PM, Marko Rauhamaa  wrote:
> Chris Angelico :
>
>> On Thu, Nov 24, 2016 at 7:39 PM, Marko Rauhamaa  wrote:
>>>  * Coroutines can be killed, threads cannot.
>>
>> Not strictly true. A coroutine can be abandoned at an await point, but
>> the currently-executed call is still going to complete (usually);
>
> I don't quite understand. Say you are awaiting on receiving bytes from a
> socket. That means there has been a nonblocking call to read(2),
> recvmsg(2) or equivalent that has returned EAGAIN. If you now abandon
> the coroutine, there is no resumption of the system call but the
> coroutine can finish instantaneously.

Is the read(2) still going to consume data from the pipe/socket? If
so, the operation is still going to continue, whether you use
coroutines or threads. If not, it would have been cancelled whether
you use coroutines or threads.

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


Re: Is this pythonic?

2016-11-24 Thread Marko Rauhamaa
Chris Angelico :

> On Thu, Nov 24, 2016 at 7:39 PM, Marko Rauhamaa  wrote:
>>  * Coroutines can be killed, threads cannot.
>
> Not strictly true. A coroutine can be abandoned at an await point, but
> the currently-executed call is still going to complete (usually);

I don't quite understand. Say you are awaiting on receiving bytes from a
socket. That means there has been a nonblocking call to read(2),
recvmsg(2) or equivalent that has returned EAGAIN. If you now abandon
the coroutine, there is no resumption of the system call but the
coroutine can finish instantaneously.

> a thread can be killed, but certain non-interruptible operations will
> delay the termination until after that operation. So either way, the
> operation still runs to completion.

There *could* be such noninterruptible operations (which would be a big
shame). They would have to be implemented with the help of a separate
thread. The surface coroutine can never sit in a blocking operation.


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


Re: Is this pythonic?

2016-11-24 Thread Chris Angelico
On Thu, Nov 24, 2016 at 7:39 PM, Marko Rauhamaa  wrote:
>  * Coroutines can be killed, threads cannot.
>

Not strictly true. A coroutine can be abandoned at an await point, but
the currently-executed call is still going to complete (usually); a
thread can be killed, but certain non-interruptible operations will
delay the termination until after that operation. So either way, the
operation still runs to completion.

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


Re: Is this pythonic?

2016-11-24 Thread Marko Rauhamaa
"Frank Millman" :

> "Steven D'Aprano"  wrote in message
> news:58368358$0$1513$c3e8da3$54964...@news.astraweb.com...

>> I'm a newbie to asyncio, but if I were doing this using threads, [...]
>
> To me, the beauty of asyncio (or I suppose async in general) is that I
> don't have to worry about any of what you describe above.

The programming model for threads and asyncio coroutines is identical.
The differences for the programmer are smallish details:

 * In asyncio, all functions that can potentially block must be tagged
   with "async" and all calls to such functions must be tagged with
   "await".

 * Not all blocking functions have an equivalent coroutine. All
   functions are readily available to threads.

 * Coroutines can be killed, threads cannot.

 * Coroutines can be multiplexed, threads cannot.


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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman
"Steven D'Aprano"  wrote in message 
news:58368358$0$1513$c3e8da3$54964...@news.astraweb.com...



On Thursday 24 November 2016 15:55, Frank Millman wrote:

> "Steve D'Aprano"  wrote in message
> news:583653bb$0$1603$c3e8da3$54964...@news.astraweb.com...
>
>> Even if the computation of the memoised value is done asynchronously, 
>> you
>> can easily split the computation off to a separate method (as you 
>> already

>> talked about doing!) and make getval() block until it returns.
>
> Surely that defeats the whole purpose of asyncio. Anything that blocks 
> holds
> up the entire process. I strenuously try to avoid blocking in any shape 
> or

> form.

Perhaps I'm not understanding your task correctly, but surely you have to 
wait
for the computation to occur at some point? Even if that's just you 
hitting

Refresh waiting for the value of the column to eventually show up.

I'm a newbie to asyncio, but if I were doing this using threads, I'd have
getval() set the self._cached_value to "pending..." (say), start the
computation thread running, and then return. The computation thread will
eventually write the true value to _cached_value, and in the meantime the
getval() method (and hence __str__ will happily use the "pending..." 
value. The

only tricky part is to make sure you only start the thread once.



I am not really qualified to answer this - I *use* asyncio, but I don’t 
really understand what goes on under the covers.


With that caveat, here goes.

To me, the beauty of asyncio (or I suppose async in general) is that I don't 
have to worry about any of what you describe above.


I just have to 'await' whatever I am waiting for. There could be a long 
chain of function calls (which I suppose I should call coroutine calls) but 
at some point one of them is actually going to wait for some I/O, and yield 
control back to the event loop.


At that point, the entire chain is suspended, pending return of the value. 
Once received, control passes back down the chain to the originating 
coroutine, which can then carry on exactly where it left off.


Frank


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


Re: Is this pythonic?

2016-11-23 Thread Steven D'Aprano
On Thursday 24 November 2016 15:55, Frank Millman wrote:

> "Steve D'Aprano"  wrote in message
> news:583653bb$0$1603$c3e8da3$54964...@news.astraweb.com...
> 
>> Even if the computation of the memoised value is done asynchronously, you
>> can easily split the computation off to a separate method (as you already
>> talked about doing!) and make getval() block until it returns.
> 
> Surely that defeats the whole purpose of asyncio. Anything that blocks holds
> up the entire process. I strenuously try to avoid blocking in any shape or
> form.

Perhaps I'm not understanding your task correctly, but surely you have to wait 
for the computation to occur at some point? Even if that's just you hitting 
Refresh waiting for the value of the column to eventually show up.

I'm a newbie to asyncio, but if I were doing this using threads, I'd have 
getval() set the self._cached_value to "pending..." (say), start the 
computation thread running, and then return. The computation thread will 
eventually write the true value to _cached_value, and in the meantime the 
getval() method (and hence __str__ will happily use the "pending..." value. The 
only tricky part is to make sure you only start the thread once.



-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!

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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman
"Steve D'Aprano"  wrote in message 
news:583653bb$0$1603$c3e8da3$54964...@news.astraweb.com...



Even if the computation of the memoised value is done asynchronously, you
can easily split the computation off to a separate method (as you already
talked about doing!) and make getval() block until it returns.


Surely that defeats the whole purpose of asyncio. Anything that blocks holds 
up the entire process. I strenuously try to avoid blocking in any shape or 
form.



> I can say 'print(await obj.__str__())', and it works, but I lose the
> ability to include it in a larger print statement.


Any time you find yourself directly calling dunder methods, you're 
probably

doing it wrong. This is one of those times.


Yes. Having slept on it, I realise I over-reacted.

The __str__() method is convenient for me, but I only use it for testing and 
debugging to see what is going on. It is not part of my app per se.


I now realise that the solution is -

1. Keep the __str__ method, but replace calls to getval() with a direct 
reference to the underlying attribute. It means that any 'computable' 
objects that have not already been computed will return None, but that is ok 
for my purposes.


2. Write a separate method, retaining the calls to getval(), to be called 
independently using 'await' if I ever need to see the full result after 
computation.


Frank


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


Re: Is this pythonic?

2016-11-23 Thread Steve D'Aprano
On Wed, 23 Nov 2016 10:11 pm, Frank Millman wrote:

> Gah! The law of unintended consequences strikes again!
> 
> As I mentioned, the class in question represents a database column. 

Yes, you mentioned that.

> A 
> separate class represents a database row. I have a __str__() method on the
> 'row' class that prints a nicely formatted representation of the object
> with all of its column objects and their values.

You didn't mention that, but it shouldn't matter.

 
> With the above changes, I had to turn getval() into a coroutine.

You what?

I'm gobsmacked by this assertion. Nobody else seems to have commented on
this, so perhaps I'm missing something, but this strikes me as astonishing.
Nothing in your earlier post even hinted that you were using coroutines or
async, and as sure as the day is long memoisation doesn't force you to
start.

Even if the computation of the memoised value is done asynchronously, you
can easily split the computation off to a separate method (as you already
talked about doing!) and make getval() block until it returns.


[...]
> I can say 'print(await obj.__str__())', and it works, but I lose the
> ability to include it in a larger print statement.

Any time you find yourself directly calling dunder methods, you're probably
doing it wrong. This is one of those times.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Is this pythonic?

2016-11-23 Thread Steve D'Aprano
On Wed, 23 Nov 2016 11:27 pm, Frank Millman wrote:

> It is a bit like quantum theory. I have no way of telling whether the
> computation has been carried out without looking at it, but the act of
> looking at it triggers the computation. I can tell, of course, by looking
> at the underlying attribute, but not by using the public methods.

Then give it a public method (or better, a property) to tell.


@property
def needs_computation(self):
return not hasattr(self, '_cached_value')




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Is this pythonic?

2016-11-23 Thread Gregory Ewing

Frank Millman wrote:
For the time being I will use 'print(await obj.__str__())', as this is a 
good compromise.


It seems more like a very *bad* compromise to me.

I can't see how this gains you anything over just doing
print(await obj.getvalue()), and you lose the ability to
do anything that calls __str__ implicitly.

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


Re: Is this pythonic?

2016-11-23 Thread Tim Chase
On 2016-11-23 22:15, Steve D'Aprano wrote:
> On Wed, 23 Nov 2016 08:10 pm, Frank Millman wrote:
> > The class has a getval() method to return the current value.
> > 
> > Usually the value is stored in the instance, and can be returned
> > immediately, but sometimes it has to be computed, incurring
> > further database lookups.  
> 
> This is called memoisation, or caching, and is a perfectly standard
> programming technique. It's not without its traps though: there's a
> famous quote that says there are only two hard problems in
> computing, naming things and cache invalidation.

Fortunately, you can offload some odd edge-cases to the standard
library, no?

  from functools import lru_cache
  # ...
  @lru_cache(maxsize=1)
  def getval(...):
return long_computation()

It doesn't cache across multiple instances of the same class, but
does cache multiple calls to the same instance's function:

  >>> from functools import lru_cache
  >>> class Foo:
  ...   def __init__(self, name):
  ... self.name = name
  ...   @lru_cache(maxsize=1)
  ...   def getval(self):
  ... print("Long process")
  ... return self.name
  ... 
  >>> f1 = Foo("f1")
  >>> f2 = Foo("f2")
  >>> f1.getval()
  Long process
  'f1'
  >>> f1.getval()
  'f1'
  >>> f2.getval()
  Long process
  'f2'
  >>> f2.getval()
  'f2'

-tkc





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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman
"Chris Angelico"  wrote in message 
news:CAPTjJmqGEwHPVyrR+Ti9bV=S5MsLt3nquF4TvE=xpees188...@mail.gmail.com...


On Wed, Nov 23, 2016 at 11:27 PM, Frank Millman  
wrote:

>
> @Chris
>>
>> This strongly suggests that str(x) is the wrong way to get the
>> information. You shouldn't be doing database requests inside __str__
>> or __repr__.
>
>
> I guess you are right, but still it is a pity. __str__ has been working 
> for
> me beautifully for a long time now. The only change is that, previously, 
> all
> the values had been read in or computed before calling __str__(), now I 
> am

> delaying the computation until requested.
>
> It is a bit like quantum theory. I have no way of telling whether the
> computation has been carried out without looking at it, but the act of
> looking at it triggers the computation. I can tell, of course, by 
> looking at

> the underlying attribute, but not by using the public methods.

That makes sense. What you could do is have __repr__ do something like 
this:


def __repr__(self):
if self.has_data:
return "<%s: %r>" % (self.col_name, self.data)
return "<%s:  >" % self.col_name

I'm not sure that that would be appropriate for __str__, though; maybe
it could return the string of data if it exists, otherwise it could
fall back on __repr__?



Thanks for the ideas. I will have to experiment a bit.

There is a certain irony in all this. When I started using asyncio, I just 
converted the networking functions into coroutines and waited for it to 
stabilise. Then I wanted to extend it, and found that coroutines can only be 
called by other coroutines, and I had some long chains of function calls, so 
I backed off. Then I eventually bit the bullet, converted everything in the 
chain to a coroutine, and let it settle down again. I have done this a few 
times, and each time I sensed an improvement in the way that my entire 
application was beginning to 'flow' in an async manner, which was good. 
However, I have managed to avoid turning getval() into a coroutine, until 
now. Now I am ready to embrace the change, but this time it is Python that 
is tripping me up.


For the time being I will use 'print(await obj.__str__())', as this is a 
good compromise. Of course I don't have to use __str__, I can call it 
anything, so I will probably create a helper function to make it easy to 
call on any object.


One of the things that was deterring me from turning getval() into a 
coroutine was the inability to use a coroutine inside a comprehension. I see 
that Python 3.6 now allows this, so I must download a beta version and try 
it out.


Frank


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


Re: Is this pythonic?

2016-11-23 Thread Chris Angelico
On Wed, Nov 23, 2016 at 11:27 PM, Frank Millman  wrote:
>
> @Chris
>>
>> This strongly suggests that str(x) is the wrong way to get the
>> information. You shouldn't be doing database requests inside __str__
>> or __repr__.
>
>
> I guess you are right, but still it is a pity. __str__ has been working for
> me beautifully for a long time now. The only change is that, previously, all
> the values had been read in or computed before calling __str__(), now I am
> delaying the computation until requested.
>
> It is a bit like quantum theory. I have no way of telling whether the
> computation has been carried out without looking at it, but the act of
> looking at it triggers the computation. I can tell, of course, by looking at
> the underlying attribute, but not by using the public methods.

That makes sense. What you could do is have __repr__ do something like this:

def __repr__(self):
if self.has_data:
return "<%s: %r>" % (self.col_name, self.data)
return "<%s:  >" % self.col_name

I'm not sure that that would be appropriate for __str__, though; maybe
it could return the string of data if it exists, otherwise it could
fall back on __repr__?

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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman

"Frank Millman"  wrote in message news:o13meh$p2g$1...@blaine.gmane.org...


3. When instantiating an object, check if it would need computation -
if computation_required:
self.getval = self._getval_with_comp
else:
self.getval = self._getval

4. In _getval_with_comp, perform the computation, then add the following -
   self.getval = self._getval
return self._getval()

What is the verdict? -1, 0, or +1?



Thanks for the responses. I will reply to them all here -

@Peter

You can also have the method replace itself ...


I like it. Thanks for the suggestion.

@Steve
So this check only happens once, on instantiation? And you're sure that 
once

the instance is created, there will never be any circumstances where you
want to re-calculate the value?


Well, the process that I call 'computation' includes setting up some 
variables that will trigger a recalculation when certain values change.


Part of my motivation was to avoid all of this if the value is never 
accessed.



def __getval_with_comp(self):
value = ... # long computation
self._cached_value = value
self.getval = self._getval
# return value
return self._getval()
# why call the method when you already know the answer?

How are subclasses supposed to override getval?



Two questions there, but the answer is the same.

I don't want subclasses to override the computation part of the process. I 
just want then to 'massage' the result before returning it. Therefore the 
answer to the first question is, to force the subclass to return the result, 
if it has its own _getval(). The answer to the second question is that they 
override _getval(), and therefore they will be invoked when getval() is 
called, provided getval has been set to be equal to _getval.


Hope that makes sense.

@Chris

This strongly suggests that str(x) is the wrong way to get the
information. You shouldn't be doing database requests inside __str__
or __repr__.


I guess you are right, but still it is a pity. __str__ has been working for 
me beautifully for a long time now. The only change is that, previously, all 
the values had been read in or computed before calling __str__(), now I am 
delaying the computation until requested.


It is a bit like quantum theory. I have no way of telling whether the 
computation has been carried out without looking at it, but the act of 
looking at it triggers the computation. I can tell, of course, by looking at 
the underlying attribute, but not by using the public methods.


Frank


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


Re: Is this pythonic?

2016-11-23 Thread Peter Otten
Frank Millman wrote:

> Hi all
> 
> Sometimes I write something that I think is quite clever, but later on I
> look at it and ask 'What was I thinking?'.
> 
> I have just come up with a 'clever' solution to a problem. Would this
> cause raised eyebrows if you were reviewing this?
> 
> I have a class that represents a single database column - there could be
> hundreds of instances at any time.
> 
> The class has a getval() method to return the current value.
> 
> Usually the value is stored in the instance, and can be returned
> immediately, but sometimes it has to be computed, incurring further
> database lookups.
> 
> In many cases the computed value is never actually requested, so I want to
> delay the computation until the first call to getval().
> 
> I could add an 'if computation_required: ' block to getval(), but I am
> trying to avoid that, partly because this would have to be checked for
> every call to getval() but would only used in a small number of cases, and
> partly because I have a few subclasses where getval() is over-ridden so I
> would have to add the extra code to every one (or call the superclass on
> every one).
> 
> This is what I have come up with.
> 
> 1. Rename all instances of 'getval()' to '_getval()'.
> 
> 2. Add a new method '_getval_with_comp()'.
> 
> 3. When instantiating an object, check if it would need computation -
> if computation_required:
> self.getval = self._getval_with_comp
> else:
> self.getval = self._getval

You can also have the method replace itself:

>>> class Foo:
... def get_val(self):
... print("computing...")
... val = self._val = 42
... self.get_val = self.get_cached_val
... return val
... def get_cached_val(self):
... return self._val
... 
>>> foo = Foo()
>>> foo.get_val()
computing...
42
>>> foo.get_val()
42

 
> 4. In _getval_with_comp, perform the computation, then add the following -
> self.getval = self._getval
> return self._getval()
> 
> What is the verdict? -1, 0, or +1?
> 
> Frank Millman


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


Re: Is this pythonic?

2016-11-23 Thread Chris Angelico
On Wed, Nov 23, 2016 at 10:11 PM, Frank Millman  wrote:
> Gah! The law of unintended consequences strikes again!
>
> As I mentioned, the class in question represents a database column. A
> separate class represents a database row. I have a __str__() method on the
> 'row' class that prints a nicely formatted representation of the object with
> all of its column objects and their values.
>
> With the above changes, I had to turn getval() into a coroutine. My
> __str__() method uses getval() to obtain the values, so I had to prefix
> getval() with 'await', but then I get a syntax error on __str__(). I can add
> 'async' to remove the syntax error, but then print(obj) does not work -
> TypeError: __str__ returned non-string (type coroutine)
>
> I don't think there is an answer to this, but any suggestions will be
> appreciated.
>
> I can say 'print(await obj.__str__())', and it works, but I lose the ability
> to include it in a larger print statement.
>
> Ah well :-(

This strongly suggests that str(x) is the wrong way to get the
information. You shouldn't be doing database requests inside __str__
or __repr__.

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


Re: Is this pythonic?

2016-11-23 Thread Steve D'Aprano
On Wed, 23 Nov 2016 08:10 pm, Frank Millman wrote:

[...]
> The class has a getval() method to return the current value.
> 
> Usually the value is stored in the instance, and can be returned
> immediately, but sometimes it has to be computed, incurring further
> database lookups.

This is called memoisation, or caching, and is a perfectly standard
programming technique. It's not without its traps though: there's a famous
quote that says there are only two hard problems in computing, naming
things and cache invalidation. But putting that aside:


def getval(self):
sentinel = object()
value = getattr(self, '_cached_value', sentinel)
if value is sentinel:
# compute the value and store it
value = ...
self._cached_value = value
return value

To invalidate the cache and force a recalculation:

del self._cached_value


Now it's easy to override:

class Subclass(ParentClass):
def getval(self):
value = super(Subclass, self).getval()
return value + 1



> This is what I have come up with.
> 
> 1. Rename all instances of 'getval()' to '_getval()'.
> 
> 2. Add a new method '_getval_with_comp()'.
> 
> 3. When instantiating an object, check if it would need computation -
> if computation_required:
> self.getval = self._getval_with_comp
> else:
> self.getval = self._getval

So this check only happens once, on instantiation? And you're sure that once
the instance is created, there will never be any circumstances where you
want to re-calculate the value?



> 4. In _getval_with_comp, perform the computation, then add the following -
> self.getval = self._getval
> return self._getval()

So you have something like this?

def _getval(self):
return self._cached_value

def __getval_with_comp(self):
value = ... # long computation
self._cached_value = value
self.getval = self._getval
# return value
return self._getval()
# why call the method when you already know the answer?


How are subclasses supposed to override getval?




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman

"Marko Rauhamaa"  wrote in message news:87inrer0dl@elektro.pacujo.net...

"Frank Millman" :


> 3. When instantiating an object, check if it would need computation -
>if computation_required:
>self.getval = self._getval_with_comp
>else:
>self.getval = self._getval
>
> 4. In _getval_with_comp, perform the computation, then add the 
> following -

>self.getval = self._getval
>return self._getval()
>
> What is the verdict? -1, 0, or +1?

Perfectly cromulent, run-of-the-mill Python code.



Gah! The law of unintended consequences strikes again!

As I mentioned, the class in question represents a database column. A 
separate class represents a database row. I have a __str__() method on the 
'row' class that prints a nicely formatted representation of the object with 
all of its column objects and their values.


With the above changes, I had to turn getval() into a coroutine. My 
__str__() method uses getval() to obtain the values, so I had to prefix 
getval() with 'await', but then I get a syntax error on __str__(). I can add 
'async' to remove the syntax error, but then print(obj) does not work - 
TypeError: __str__ returned non-string (type coroutine)


I don't think there is an answer to this, but any suggestions will be 
appreciated.


I can say 'print(await obj.__str__())', and it works, but I lose the ability 
to include it in a larger print statement.


Ah well :-(

Frank


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


Re: Is this pythonic?

2016-11-23 Thread Frank Millman

"Marko Rauhamaa"  wrote in message news:87inrer0dl@elektro.pacujo.net...


"Frank Millman" :




> What is the verdict? -1, 0, or +1?

Perfectly cromulent, run-of-the-mill Python code.



A new word to add to my vocabulary - thanks :-)

Frank


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


Re: Is this pythonic?

2016-11-23 Thread Marko Rauhamaa
"Frank Millman" :

> 3. When instantiating an object, check if it would need computation -
>if computation_required:
>self.getval = self._getval_with_comp
>else:
>self.getval = self._getval
>
> 4. In _getval_with_comp, perform the computation, then add the following -
>self.getval = self._getval
>return self._getval()
>
> What is the verdict? -1, 0, or +1?

Perfectly cromulent, run-of-the-mill Python code.


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


Is this pythonic?

2016-11-23 Thread Frank Millman

Hi all

Sometimes I write something that I think is quite clever, but later on I 
look at it and ask 'What was I thinking?'.


I have just come up with a 'clever' solution to a problem. Would this cause 
raised eyebrows if you were reviewing this?


I have a class that represents a single database column - there could be 
hundreds of instances at any time.


The class has a getval() method to return the current value.

Usually the value is stored in the instance, and can be returned 
immediately, but sometimes it has to be computed, incurring further database 
lookups.


In many cases the computed value is never actually requested, so I want to 
delay the computation until the first call to getval().


I could add an 'if computation_required: ' block to getval(), but I am 
trying to avoid that, partly because this would have to be checked for every 
call to getval() but would only used in a small number of cases, and partly 
because I have a few subclasses where getval() is over-ridden so I would 
have to add the extra code to every one (or call the superclass on every 
one).


This is what I have come up with.

1. Rename all instances of 'getval()' to '_getval()'.

2. Add a new method '_getval_with_comp()'.

3. When instantiating an object, check if it would need computation -
   if computation_required:
   self.getval = self._getval_with_comp
   else:
   self.getval = self._getval

4. In _getval_with_comp, perform the computation, then add the following -
   self.getval = self._getval
   return self._getval()

What is the verdict? -1, 0, or +1?

Frank Millman


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


Re: Is this pythonic?

2009-01-27 Thread Baby Coder
On 18 déc 2008, 13:51, Jason Scheirer 
wrote:

> I'd say it's fine but breaking up the statement once or twice is a
> good idea just because if one of the function calls in this nested
> thing throws an exception, a smaller statement with fewer calls makes
> for a far more readable traceback. And I hope that this whole
> statement all lives inside of a method in the same x class, or is a
> higher-level class that makes use of this behavior? If not, you may
> want to consider doing so.
>
> class X(object):
>   @property
>   def todays_filepattern(self):
>       return self.match_filename(
>               self.determine_filename_pattern(
>                    datetime.datetime.now()))
>   def validate_todays_files(self):
>      return self.validate_output(self.find_text
> (self.todays_filepattern))

Thanks for this lesson in application design. Just what I was looking
for.
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-22 Thread pruebauno
On Jan 21, 4:23 pm, Scott David Daniels  wrote:
> prueba...@latinmail.com wrote:
> > ... If you have duplicates this will not work. You will have to do
> > something like this instead:
>
>  o=[]
>  i=0
>  ln=len(l)
>  while i >    if l[i]['title']=='ti':
> >            o.append(l.pop(i))
> >            ln-=1
> >    else:
> >            i+=1
>
> Or the following:
>      indices = [i for i,d in enumerate(l) if d['title']=='ti']
>      for i in reversed(indices): # so del doesn't affect later positions
>          del l[i]
>
> --Scott David Daniels
> scott.dani...@acm.org

Cool. How come I didn't think of that!. Now I can write my evil one
liner >:-).

o=[l.pop(i) for i in reversed(xrange(len(l))) if l[i]['title']=='ti']
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-22 Thread pruebauno
On Jan 21, 4:23 pm, Scott David Daniels  wrote:
> prueba...@latinmail.com wrote:
> > ... If you have duplicates this will not work. You will have to do
> > something like this instead:
>
>  o=[]
>  i=0
>  ln=len(l)
>  while i >    if l[i]['title']=='ti':
> >            o.append(l.pop(i))
> >            ln-=1
> >    else:
> >            i+=1
>
> Or the following:
>      indices = [i for i,d in enumerate(l) if d['title']=='ti']
>      for i in reversed(indices): # so del doesn't affect later positions
>          del l[i]
>
> --Scott David Daniels
> scott.dani...@acm.org

Cool. How come I didn't think of that! That means I can create an evil
one liner now >:-).

replacecount=len([o.append(l.pop(i)) for i in reversed(xrange(len(l)))
if l[i]['title']=='ti'])
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-22 Thread TP
Peter Otten wrote:

> If you can change the rest of your program to work smoothly with a
> dictionary I would suggest the following:
[snip]
>>> from collections import defaultdict
[snip]

Thanks a lot.
I didn't know defaultdict. It is powerful.

I begin to understand that people prefer using dictionaries than lists, so
as to take advantage of their automatic lookup feature.

-- 
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
9&1+,\'Z4(55l4('])"

"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-22 Thread Peter Otten
TP wrote:

> Hi,
> 
> Is the following code pythonic:
> 
 l=[{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
 dict = [ dict for dict in l if dict['title']=='ti']
 l.remove(*dict)
 l
> [{'title': 'to', 'value': 2}]
> 
> Precision: I have stored data in the list of dictionaries l, because in my
> application I am sure that "title" is unique for each record. But perhaps
> it is better to imagine that someday it will not be anymore the case? And
> rather use a data storage as the following?
> 
> l = { '001':{"title":"to", "value":2}, '002'
> {"title":"ti","value":"coucou"}}
> 
> The problem with this storage is that it implies to manipulate some "ids"
> that have not any meaning for a humain being (001, 002, etc).
> 
> Thanks a lot for you opinion,

If you can change the rest of your program to work smoothly with a
dictionary I would suggest the following:

>>> items = [{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
>>> lookup = dict((item["title"], item) for item in items)
>>> lookup
{'to': {'value': 2, 'title': 'to'}, 'ti':
{'value': 'coucou', 'title': 'ti'}}
>>> del lookup["ti"]
>>> lookup
{'to': {'value': 2, 'title': 'to'}}

If you later have to accomodate for multiple dictionaries with the same
title use lists of dictionaries as values:

>> from collections import defaultdict
>>> lookup = defaultdict(list)
>>> for item in items:
... lookup[item["title"]].append(item)
...
>>> lookup
defaultdict(, {'to': [{'value': 2, 'title': 'to'}], 'ti':
[{'value': 'coucou', 'title': 'ti'}]})
>>> del lookup["ti"] 
>>> lookup
defaultdict(, {'to': [{'value': 2, 'title': 'to'}]})

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


Re: is this pythonic?

2009-01-21 Thread Scott David Daniels

prueba...@latinmail.com wrote:

... If you have duplicates this will not work. You will have to do
something like this instead:


o=[]
i=0
ln=len(l)
while i
if l[i]['title']=='ti':
o.append(l.pop(i))
ln-=1
else:
i+=1


Or the following:
indices = [i for i,d in enumerate(l) if d['title']=='ti']
for i in reversed(indices): # so del doesn't affect later positions
del l[i]


--Scott David Daniels
scott.dani...@acm.org
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread pruebauno
On Jan 21, 12:34 pm, TP  wrote:
> alex23 wrote:
> > Try not to use 'dict' or the name of any of the other built-in types
>
> So my list is rather:
> l=[{"title":"to", "color":"blue", "value":2}
> {"title":"ti", "color":"red", "value":"coucou"}]
>
> So, I will rather use your solution:
>
> for index, record in enumerate(l):
>     if record['title'] == 'ti':
>         to_add_in_another_list = l.pop(index)
> another_list.append(to_add_in_another_list )
>
If you have duplicates this will not work. You will have to do
something like this instead:

>>> o=[]
>>> i=0
>>> ln=len(l)
>>> while i>> for index, record in enumerate(l):
if record['title'] == 'ti':
to_add_in_another_list = l.pop(index)
break

I don't know if these are more pythonic, they should be more efficient
for longer lists though.
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread alex23
On Jan 22, 3:56 am, MRAB  wrote:
> I was referring to the code:
>
>      for index, record in enumerate(l):
>          if record['title'] == 'ti':
>              l.pop(index)
>
> where you are enumerating and iterating over 'l', but also modifying 'l'
> with 'l.pop(index)'.

Ack, you're absolutely correct.

TP: my mistake, the for loop won't work at all. I'd really recommend
using the dictionary-based solution.

Apologies all around.
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread alex23
On Jan 22, 3:34 am, TP  wrote:
> >     for index, record in enumerate(l):
> >         if record['title'] == 'ti':
> >             l.pop(index)
>
> Ok, I will use this solution. But it is less pythonic than list
> comprehensions.

Are you asking if it's less pythonic, or asserting? Because you'll
find a lot of disagreement here: list comprehensions are used for
constructing lists, not manipulating them.

> Perhaps you mean rather:
>
> l = [d for d in l if d['title'] != 'ti']
> ?

You are correct. I should never post past 3am :)

> In fact, in my case, in cannot use this simple solution, because there are
> other fields in each dictionary, not only 2. I was not clear in my post.
> So my list is rather:
> l=[{"title":"to", "color":"blue", "value":2}
> {"title":"ti", "color":"red", "value":"coucou"}]

I still find this a lot simpler:

  records = {'to': {'color': 'blue', 'value': '2'}, 'ti': {'color':
'red', 'value': 'coucou'}}

> > It's always better to design for what you know you need, not what you
> > may possibly need in the future.
>
> Ok. Do all the programmers agree with this principle?

Have you seen the size of some of the threads here? It's hard to get
two programmers to agree on variable names... :) But it's a practice
that has served me well and it even has a catchy name[1]. Getting what
you -need- to work is effort enough, if you don't have a definite use
case for a feature then how do you know you've implemented it
correctly? Write it when you need it.

1: http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread MRAB

alex23 wrote:

On Jan 22, 3:27 am, MRAB  wrote:

FYI, you shouldn't modify a list you're iterating over.


But I'm not. I'm building a new list and binding it to the same name
as the original, which works perfectly fine (unless I'm missing
something):


[snip]
I was referring to the code:

for index, record in enumerate(l):
if record['title'] == 'ti':
l.pop(index)

where you are enumerating and iterating over 'l', but also modifying 'l' 
with 'l.pop(index)'.

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


Re: is this pythonic?

2009-01-21 Thread alex23
On Jan 22, 3:27 am, MRAB  wrote:
> FYI, you shouldn't modify a list you're iterating over.

But I'm not. I'm building a new list and binding it to the same name
as the original, which works perfectly fine (unless I'm missing
something):

>>> l = range(100)
>>> l = [d for d in l if not d % 5]
>>> l
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85,
90, 95]

> The for-loop was removing the item where there's a match, so the list
> comprehension in this case should keep the item where there _isn't_ a match:
>
> l = [d for d in l if d['title'] != 'ti']

Now that's a mistake. Cheers for the catch.
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread TP
alex23 wrote:

> Try not to use 'dict' or the name of any of the other built-in types
> as labels.

Ops... Moreover I know it...

> You're stepping through an entire list just to pass another list to
> l.remove to step through and remove items from...in fact, given that
> list.remove deletes the -first- occurance of the item, you're asking
> it to loop through -again- to find the matching element which you've -
> already- detected. A better and cleaner approach would be to step
> through the list -once- and remove the item when you find it:
> 
> for index, record in enumerate(l):
> if record['title'] == 'ti':
> l.pop(index)

Ok, I will use this solution. But it is less pythonic than list
comprehensions.

> Or you could just use a list comprehension:
> 
> l = [d for d in l if d['title'] == 'ti']

Perhaps you mean rather:

l = [d for d in l if d['title'] != 'ti']
?

In fact, I cannot use this solution, because I want to get back the
dictionary with title 'ti', for another use (in fact, to add it to another
list, see below).

>> Precision: I have stored data in the list of dictionaries l, because in
>> my application I am sure that "title" is unique for each record. But
>> perhaps it is better to imagine that someday it will not be anymore the
>> case?
> 
> It's always better to design for what you know you need, not what you
> may possibly need in the future. You say that you are sure that record
> titles are unique, so why not use them as the dictionary keys, with
> the values as the values:
> 
>   records = {'ti': 1, 'to': 2}
> 
> This way your code can be replaced with:
> 
>   value = records.pop('ti') # if you want to know the value
>   del records['ti'] # if you just want to delete the entry
> 
> It's a lot simpler to work with and extend.

In fact, in my case, in cannot use this simple solution, because there are
other fields in each dictionary, not only 2. I was not clear in my post.
So my list is rather:
l=[{"title":"to", "color":"blue", "value":2}
{"title":"ti", "color":"red", "value":"coucou"}]

So, I will rather use your solution:

for index, record in enumerate(l):
if record['title'] == 'ti':
to_add_in_another_list = l.pop(index)
another_list.append(to_add_in_another_list )

> It's always better to design for what you know you need, not what you
> may possibly need in the future.

Ok. Do all the programmers agree with this principle?

-- 
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
9&1+,\'Z4(55l4('])"

"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread MRAB

alex23 wrote:

On Jan 22, 1:16 am, TP  wrote:

Is the following code pythonic:

l=[{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
dict = [ dict for dict in l if dict['title']=='ti']
l.remove(*dict)
l

[{'title': 'to', 'value': 2}]


Try not to use 'dict' or the name of any of the other built-in types
as labels.

You're stepping through an entire list just to pass another list to
l.remove to step through and remove items from...in fact, given that
list.remove deletes the -first- occurance of the item, you're asking
it to loop through -again- to find the matching element which you've -
already- detected. A better and cleaner approach would be to step
through the list -once- and remove the item when you find it:

for index, record in enumerate(l):
if record['title'] == 'ti':
l.pop(index)


[snip]
FYI, you shouldn't modify a list you're iterating over.


Or you could just use a list comprehension:

l = [d for d in l if d['title'] == 'ti']

The for-loop was removing the item where there's a match, so the list 
comprehension in this case should keep the item where there _isn't_ a match:


l = [d for d in l if d['title'] != 'ti']

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


Re: is this pythonic?

2009-01-21 Thread alex23
On Jan 22, 1:16 am, TP  wrote:
> Is the following code pythonic:
> >>> l=[{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
> >>> dict = [ dict for dict in l if dict['title']=='ti']
> >>> l.remove(*dict)
> >>> l
> [{'title': 'to', 'value': 2}]

Try not to use 'dict' or the name of any of the other built-in types
as labels.

You're stepping through an entire list just to pass another list to
l.remove to step through and remove items from...in fact, given that
list.remove deletes the -first- occurance of the item, you're asking
it to loop through -again- to find the matching element which you've -
already- detected. A better and cleaner approach would be to step
through the list -once- and remove the item when you find it:

for index, record in enumerate(l):
if record['title'] == 'ti':
l.pop(index)

Or you could just use a list comprehension:

l = [d for d in l if d['title'] == 'ti']

> Precision: I have stored data in the list of dictionaries l, because in my
> application I am sure that "title" is unique for each record. But perhaps
> it is better to imagine that someday it will not be anymore the case?

It's always better to design for what you know you need, not what you
may possibly need in the future. You say that you are sure that record
titles are unique, so why not use them as the dictionary keys, with
the values as the values:

  records = {'ti': 1, 'to': 2}

This way your code can be replaced with:

  value = records.pop('ti') # if you want to know the value
  del records['ti'] # if you just want to delete the entry

It's a lot simpler to work with and extend.
--
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2009-01-21 Thread Peter Pearson
On Wed, 21 Jan 2009 16:16:32 +0100, TP wrote:
>
> Is the following code pythonic:
>
 l=[{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
 dict = [ dict for dict in l if dict['title']=='ti']
 l.remove(*dict)
 l
> [{'title': 'to', 'value': 2}]
>
> Precision: I have stored data in the list of dictionaries l, because in my
> application I am sure that "title" is unique for each record. But perhaps
> it is better to imagine that someday it will not be anymore the case?
[snip]

1. You probably don't want to use the name "dict".

2. I believe this code will fail if the number of dictionaries
   with title="ti" is not exactly 1.  It that your intention?
   (You probably answered this question in the last paragraph
   quoted above, but I can't make it out.)

-- 
To email me, substitute nowhere->spamcop, invalid->net.
--
http://mail.python.org/mailman/listinfo/python-list


is this pythonic?

2009-01-21 Thread TP
Hi,

Is the following code pythonic:

>>> l=[{"title":"to", "value":2},{"title":"ti","value":"coucou"}]
>>> dict = [ dict for dict in l if dict['title']=='ti']
>>> l.remove(*dict)
>>> l
[{'title': 'to', 'value': 2}]

Precision: I have stored data in the list of dictionaries l, because in my
application I am sure that "title" is unique for each record. But perhaps
it is better to imagine that someday it will not be anymore the case? And
rather use a data storage as the following?

l = { '001':{"title":"to", "value":2}, '002'
{"title":"ti","value":"coucou"}}

The problem with this storage is that it implies to manipulate some "ids"
that have not any meaning for a humain being (001, 002, etc).

Thanks a lot for you opinion,

-- 
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
9&1+,\'Z4(55l4('])"

"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this pythonic?

2008-12-18 Thread Hendrik van Rooyen
"Bruno Desthuilliers"  wrote:

>ipyt...@gmail.com a écrit :
>> x.validate_output(x.find_text(x.match_filename
>> (x.determine_filename_pattern(datetime.datetime.now()
>>
>> Is it even good programming form?
>
>functional programming addicts might say yes. But as far as I'm
>concerned, I find it a bit too nested...
>
+1

I would call it onionskin programming.

There is of course nothing technically wrong with it,
and you can do the same kind of thing in C, but
every time I see something like it, my reaction is
WTF.

- Hendrik

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


Re: Is this pythonic?

2008-12-18 Thread Russ P.
On Dec 18, 8:08 am, ipyt...@gmail.com wrote:
> x.validate_output(x.find_text(x.match_filename
> (x.determine_filename_pattern(datetime.datetime.now()
>
> Is it even good programming form?

I hope you're kidding.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this pythonic?

2008-12-18 Thread Jason Scheirer
On Dec 18, 8:45 am, prueba...@latinmail.com wrote:
> On Dec 18, 11:08 am, ipyt...@gmail.com wrote:
>
> > x.validate_output(x.find_text(x.match_filename
> > (x.determine_filename_pattern(datetime.datetime.now()
>
> > Is it even good programming form?
>
> Lisp and Scheme programmers love that style. You can tell by the
> number of parentheses :-). In Python people usually use an
> intermediate variable to break things up a bit but the amount of
> acceptable nesting is a matter of personal style.

I'd say it's fine but breaking up the statement once or twice is a
good idea just because if one of the function calls in this nested
thing throws an exception, a smaller statement with fewer calls makes
for a far more readable traceback. And I hope that this whole
statement all lives inside of a method in the same x class, or is a
higher-level class that makes use of this behavior? If not, you may
want to consider doing so.

class X(object):
  @property
  def todays_filepattern(self):
  return self.match_filename(
  self.determine_filename_pattern(
   datetime.datetime.now()))
  def validate_todays_files(self):
 return self.validate_output(self.find_text
(self.todays_filepattern))
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this pythonic?

2008-12-18 Thread pruebauno
On Dec 18, 11:08 am, ipyt...@gmail.com wrote:
> x.validate_output(x.find_text(x.match_filename
> (x.determine_filename_pattern(datetime.datetime.now()
>
> Is it even good programming form?

Lisp and Scheme programmers love that style. You can tell by the
number of parentheses :-). In Python people usually use an
intermediate variable to break things up a bit but the amount of
acceptable nesting is a matter of personal style.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this pythonic?

2008-12-18 Thread Laszlo Nagy

ipyt...@gmail.com wrote:

x.validate_output(x.find_text(x.match_filename
(x.determine_filename_pattern(datetime.datetime.now()

Is it even good programming form?
  

You should try LISP. :-)
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this pythonic?

2008-12-18 Thread Bruno Desthuilliers

ipyt...@gmail.com a écrit :

x.validate_output(x.find_text(x.match_filename
(x.determine_filename_pattern(datetime.datetime.now()

Is it even good programming form?


functional programming addicts might say yes. But as far as I'm 
concerned, I find it a bit too nested...

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


Is this pythonic?

2008-12-18 Thread ipytest
x.validate_output(x.find_text(x.match_filename
(x.determine_filename_pattern(datetime.datetime.now()

Is it even good programming form?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is this Pythonic?

2005-08-02 Thread Michael Hudson
[EMAIL PROTECTED] (phil hunt) writes:

>>It would (possibly) be more Pythonic to
>>define an interface instead,
>
> Does Python have the concept of an interface? When was that added?

It doesn't have one included, but there are at least two
implementations, zope.interface and PyProtocols (I'm sure google will
find you more on both of these).

-- 
  ... with these conditions cam the realisation that ... nothing
  turned a perfectly normal healthy individual into a great political
  or military leader better than irreversible brain damage.
   -- The Hitch-Hikers Guide to the Galaxy, Episode 11
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this Pythonic?

2005-08-02 Thread phil hunt
On Tue, 02 Aug 2005 08:31:27 GMT, Michael Hudson <[EMAIL PROTECTED]> wrote:
>[EMAIL PROTECTED] (phil hunt) writes:
>
>> Suppose I'm writing an abstract superclass which will have some 
>> concrete subclasses. I want to signal in my code that the subclasses 
>> will implement certan methods. Is this a Pythonic way of doing what 
>> I have in mind:
>>
>> class Foo: # abstract superclass
>>def bar(self):
>>   raise Exception, "Implemented by subclass"
>>def baz(self):
>>   raise Exception, "Implemented by subclass"
>>
>> class Concrete(Foo):
>>def bar(self):
>>   #...actual implemtation...
>>def baz(self):
>>   #...actual implemtation...
>
>Well, I guess you know this, but if Foo contains no implementation at
>all, why inherit from it?

(in fact the class I'm using/creating does contain some 
implementation)

>It would (possibly) be more Pythonic to
>define an interface instead,

Does Python have the concept of an interface? When was that added?


-- 
Email: zen19725 at zen dot co dot uk


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


Re: Is this Pythonic?

2005-08-02 Thread Michael Hudson
[EMAIL PROTECTED] (phil hunt) writes:

> Suppose I'm writing an abstract superclass which will have some 
> concrete subclasses. I want to signal in my code that the subclasses 
> will implement certan methods. Is this a Pythonic way of doing what 
> I have in mind:
>
> class Foo: # abstract superclass
>def bar(self):
>   raise Exception, "Implemented by subclass"
>def baz(self):
>   raise Exception, "Implemented by subclass"
>
> class Concrete(Foo):
>def bar(self):
>   #...actual implemtation...
>def baz(self):
>   #...actual implemtation...

Well, I guess you know this, but if Foo contains no implementation at
all, why inherit from it?  It would (possibly) be more Pythonic to
define an interface instead, or just use duck typing.

Cheers,
mwh

-- 
  nonono, while we're making wild conjectures about the behavior
  of completely irrelevant tasks, we must not also make serious
  mistakes, or the data might suddenly become statistically valid.
-- Erik Naggum, comp.lang.lisp
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this Pythonic?

2005-08-02 Thread Reinhold Birkenfeld
Delaney, Timothy (Tim) wrote:
> Peter Hansen wrote:
> 
>> Change those to "raise NotImplementedError('blah')" instead and you'll
>> be taking the more idiomatic approach.
> 
> One thing I've noticed, which I may raise on python-dev ...
> NotImplementedError does *not* play well with super() ...
> 
> class A (object):
> def test (self):
> raise NotImplementedError
> 
> class B (object):
> def test (self):
> print 'B'
> super(B, self).test()
> 
> class C (B, A):
> def test (self):
> print 'C'
> super(C, self).test()
> 
> It's actually worse than AttributeError, because the method actually
> exists. In both cases though you need to know when you create the base
> class how it's going to be used to work out whether a super() call is
> needed.
> 
> One option is to do a try: except (AttributeError, NotImplementedError).
> Yuk - talk about hiding errors :(

Hm... one could return NotImplemented from the abstract method. It won't raise
an error immediately, but will certainly be discovered at some point.

Not optimal though.

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


Re: Is this Pythonic?

2005-08-01 Thread Erik Max Francis
phil hunt wrote:

> That's a clever trick, but it's obvious from the code that the class 
> is intended to be abstract, so if people are stupid enough to shoot 
> themselves in the foot by creating an instance, I don't feel like 
> adding extra code to protect themselves from their stupidity.

Right.  But even if you're not worried about stupidity, it's useful to 
have it fail in an explicit way as early as possible, rather than later 
on.  With that addition, the moment you try to create an instance of an 
abstract class, you get an exception.  Even if it's just a typo, and not 
severe negligence, that helps the problem get fixed sooner, rather than 
later.

-- 
Erik Max Francis && [EMAIL PROTECTED] && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
   Morality is a weakness of the mind.
   -- Arthur Rimbaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this Pythonic?

2005-08-01 Thread phil hunt
On Mon, 01 Aug 2005 14:07:46 -0700, Erik Max Francis <[EMAIL PROTECTED]> wrote:
>
>Yes, but raise NotImplementedError instead of Exception.  Another trick 
>you can use is to prevent people from instantiating the abstract class:
>
>   class Foo:
>   def __init__(self):
>   if self.__class__ is Foo:
>   raise NotImplementedError
>   ...
>
>   def bar(self):
>   raise NotImplementedError

That's a clever trick, but it's obvious from the code that the class 
is intended to be abstract, so if people are stupid enough to shoot 
themselves in the foot by creating an instance, I don't feel like 
adding extra code to protect themselves from their stupidity.

-- 
Email: zen19725 at zen dot co dot uk


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


Re: Is this Pythonic?

2005-08-01 Thread phil hunt
On Mon, 01 Aug 2005 22:01:06 +0200, Caleb Hattingh <[EMAIL PROTECTED]> wrote:
>Peter
>
>To my mind, this kind of setup (interface class, or abstact class) is more  
>usually used in static languages to benefit polymorphism - but python is  
>dynamically typed, so in which situations would this setup be useful in a  
>python program?  You see, I expected your post to say that it wouldn't  
>even be necessary, but you didn't :)

I realise it's not necessary. I just thought it would be nice to 
document the interfaces my concrete classes will be using.

>I have spent a little effort training myself not to bother setting up  
>class hierarchies like this in python, due to the fact that I use Delphi a  
>lot at work (I do pretty much the code below to let myself know when an  
>inherited/abstract class method is being called in error).

I started doing OO stuff with Smalltalk, where it isn't necessary, 
then moved to C++, where it is, and liked it.

-- 
Email: zen19725 at zen dot co dot uk


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


RE: Is this Pythonic?

2005-08-01 Thread Delaney, Timothy (Tim)
Peter Hansen wrote:

> Change those to "raise NotImplementedError('blah')" instead and you'll
> be taking the more idiomatic approach.

One thing I've noticed, which I may raise on python-dev ...
NotImplementedError does *not* play well with super() ...

class A (object):
def test (self):
raise NotImplementedError

class B (object):
def test (self):
print 'B'
super(B, self).test()

class C (B, A):
def test (self):
print 'C'
super(C, self).test()

It's actually worse than AttributeError, because the method actually
exists. In both cases though you need to know when you create the base
class how it's going to be used to work out whether a super() call is
needed.

One option is to do a try: except (AttributeError, NotImplementedError).
Yuk - talk about hiding errors :(

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


Re: Is this Pythonic?

2005-08-01 Thread phil hunt
On Mon, 01 Aug 2005 12:52:02 -0400, Peter Hansen <[EMAIL PROTECTED]> wrote:
>phil hunt wrote:
>> Suppose I'm writing an abstract superclass which will have some 
>> concrete subclasses. I want to signal in my code that the subclasses 
>> will implement certan methods. Is this a Pythonic way of doing what 
>> I have in mind:
>> 
>> class Foo: # abstract superclass
>>def bar(self):
>>   raise Exception, "Implemented by subclass"
>>def baz(self):
>>   raise Exception, "Implemented by subclass"
>
>Change those to "raise NotImplementedError('blah')" instead and you'll 
>be taking the more idiomatic approach.

Ta

-- 
Email: zen19725 at zen dot co dot uk


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


Re: Is this Pythonic?

2005-08-01 Thread Erik Max Francis
phil hunt wrote:

> Suppose I'm writing an abstract superclass which will have some 
> concrete subclasses. I want to signal in my code that the subclasses 
> will implement certan methods. Is this a Pythonic way of doing what 
> I have in mind:
> 
> class Foo: # abstract superclass
>def bar(self):
>   raise Exception, "Implemented by subclass"
>def baz(self):
>   raise Exception, "Implemented by subclass"
> 
> class Concrete(Foo):
>def bar(self):
>   #...actual implemtation...
>def baz(self):
>   #...actual implemtation...

Yes, but raise NotImplementedError instead of Exception.  Another trick 
you can use is to prevent people from instantiating the abstract class:

class Foo:
def __init__(self):
if self.__class__ is Foo:
raise NotImplementedError
...

def bar(self):
raise NotImplementedError

-- 
Erik Max Francis && [EMAIL PROTECTED] && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
   Everything's gonna be all right / Everything's gonna be okay
   -- Sweetbox
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this Pythonic?

2005-08-01 Thread Bruno Desthuilliers
Caleb Hattingh a écrit :
> Peter
> 
> To my mind, this kind of setup (interface class, or abstact class

are two different things.

>) is 
> more  usually used in static languages  

True.

 >to benefit polymorphism

This is a good reason to use an interface in Java. C++ has no notion of 
'interface', so you have to use abstract classes to achieve the same result.

> - but 
> python is  dynamically typed, so in which situations would this setup be 
> useful in a  python program? 

Abstract classes ? When you want to factor out common implementation in 
a base class and force derived class to implement specific parts. One 
common use case is the template method (aka "hollywood", aka "don't call 
us, we'll call you") pattern.

> You see, I expected your post to say that 
> it wouldn't  even be necessary, but you didn't :)

Implementation inheritance is never "necessary". Nor are OO, modularity, 
structured programming, and human-readable programming languages !-)

It's a fact that inheritence being "only" (err... should I say "mostly" 
?) an implementation mechanism in dynamic languages, class hierarchies 
tends to be much more flat. But this doesn't mean that abstract base 
classes are useless.

> I have spent a little effort training myself not to bother setting up  
> class hierarchies like this in python

I had this pattern too.
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Is this Pythonic?

2005-08-01 Thread Caleb Hattingh
Peter

To my mind, this kind of setup (interface class, or abstact class) is more  
usually used in static languages to benefit polymorphism - but python is  
dynamically typed, so in which situations would this setup be useful in a  
python program?  You see, I expected your post to say that it wouldn't  
even be necessary, but you didn't :)

I have spent a little effort training myself not to bother setting up  
class hierarchies like this in python, due to the fact that I use Delphi a  
lot at work (I do pretty much the code below to let myself know when an  
inherited/abstract class method is being called in error).

regards
Caleb

On Mon, 01 Aug 2005 18:52:02 +0200, Peter Hansen <[EMAIL PROTECTED]> wrote:

> phil hunt wrote:
>> Suppose I'm writing an abstract superclass which will have some  
>> concrete subclasses. I want to signal in my code that the subclasses  
>> will implement certan methods. Is this a Pythonic way of doing what I  
>> have in mind:
>>  class Foo: # abstract superclass
>>def bar(self):
>>   raise Exception, "Implemented by subclass"
>>def baz(self):
>>   raise Exception, "Implemented by subclass"
>
> Change those to "raise NotImplementedError('blah')" instead and you'll  
> be taking the more idiomatic approach.
>
> -Peter

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


Re: Is this Pythonic?

2005-08-01 Thread Benji York
phil hunt wrote:
> Suppose I'm writing an abstract superclass which will have some 
> concrete subclasses. I want to signal in my code that the subclasses 
> will implement certan methods. Is this a Pythonic way of doing what 

See http://docs.python.org/lib/module-exceptions.html#l2h-298 
(NotImplementedError)
--
Benji York


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


Re: Is this Pythonic?

2005-08-01 Thread Peter Hansen
phil hunt wrote:
> Suppose I'm writing an abstract superclass which will have some 
> concrete subclasses. I want to signal in my code that the subclasses 
> will implement certan methods. Is this a Pythonic way of doing what 
> I have in mind:
> 
> class Foo: # abstract superclass
>def bar(self):
>   raise Exception, "Implemented by subclass"
>def baz(self):
>   raise Exception, "Implemented by subclass"

Change those to "raise NotImplementedError('blah')" instead and you'll 
be taking the more idiomatic approach.

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


Is this Pythonic?

2005-08-01 Thread phil hunt

Suppose I'm writing an abstract superclass which will have some 
concrete subclasses. I want to signal in my code that the subclasses 
will implement certan methods. Is this a Pythonic way of doing what 
I have in mind:

class Foo: # abstract superclass
   def bar(self):
  raise Exception, "Implemented by subclass"
   def baz(self):
  raise Exception, "Implemented by subclass"

class Concrete(Foo):
   def bar(self):
  #...actual implemtation...
   def baz(self):
  #...actual implemtation...




-- 
Email: zen19725 at zen dot co dot uk


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


Re: is this pythonic?

2005-07-23 Thread Eric Pederson
"Caleb Hattingh" <[EMAIL PROTECTED]> wrote:

>In another  
> newsgroup, I could have been flamed for letting Simon know he helped 
> more  
> than just the OP with his post :)


+1

OP asks, thousands are educated (perhaps).

The group's generosity is greatly appreciated, even if that appreciation is 
under-expressed.


-Anon (well, sort of)


P.S.  You mean this list isn't TFM?

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


Re: is this pythonic?

2005-07-22 Thread Chris Lambacher
On Thu, Jul 21, 2005 at 10:27:24AM -0400, Bill Mill wrote:
> On 7/21/05, Steven D'Aprano <[EMAIL PROTECTED]> wrote:
> > On Wed, 20 Jul 2005 16:30:10 -0400, Bill Mill wrote:
> > 
> > > On 7/20/05, Simon Brunning <[EMAIL PROTECTED]> wrote:
> > >> On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
> > >> > Or is there better way?
> > >> >
> > >> > for (i, url) in [(i,links[i]) for i in range(len(links))]:
> > >>
> > >> for i, url in enumerate(links):
> > >>
> > >
> > > +2 for creating seeing a need and crafting a reasonable solution, but
> > > -1 for not reading the section on builtins to see if it existed
> > > already.
> > 
> > To see if *what* existed already?
> > 
> > It is well and good to say RTFM, but there are 697 subsections to the
> > Python Library reference, and if you don't know what you are looking for,
> > and beginners rarely are, it isn't obvious which is the right section to
> > read. And the Library Reference isn't even "the" manual: there is also the
> > global module reference and language reference.
> > 
> > If you already know what you are looking for, reading the manual is great
> > advice. Browsing the manual looking for interesting tidbits can even be
> > fun for a certain mindset. But if you don't know enough to know what to
> > look for, where in the 2000-odd sections of the Python references will
> > you find it?
> > 
> 
> I said the *builtins* section. I think you learn pretty quick that
> figuring out what functions are builtins is pretty important in every
> language. There's a fair number of people out there giving the advice
> to read chapter 2 of the library reference cover-to-cover for a good
> starter on python.
The quick reference guide is also a nice place to find all the most important
information:
http://rgruet.free.fr/PQR24/PQR2.4.html
> 
> Furthermore, I wasn't being hard on the guy, he still added up to +1.
> Lighten up, I was joking.
> 
> > 
> > 
> > > (As for its pythonicity, I would have recommended isolating it into a
> > > function and making it a generator:
> > 
> > It is easy to take this to extremes. It isn't necessary to isolate
> > everything into its own object, or class, or module. Too much
> > encapsulation is just as bad as too little.
> > 
> 
> agreed; his listcomp just looks awkward inside the for loop statement;
> if it were my code, I would put it into a function. He asked if his
> code was pythonic, and I think the (non-extreme) pythonic thing to do
> would be to put his listcomp into a function.
> 
> > 
> > > def my_enumerate(enumerable):
> > > i = 0
> > > for elt in enumerable:
> > > yield (i, elt)
> > > i += 1
> > >
> > > for i, url in my_enumerate(links):
> > >
> > > but it's not too bad as it is. Also, my function is completely
> > > untested - it's close to right though.)
> > 
> > What is the advantage of your function my_enumerate over the Python
> > built-in enumerate?
> > 
> > 
> 
> absolutely none; I just was saying how I would encapsulate it into a function.

Except that enumerate was introduced in 2.3 so if you are working with an
older version of Python it won't be there.
> 
> Peace
> Bill Mill
> bill.mill at gmail.com
> -- 
> http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2005-07-22 Thread Caleb Hattingh
Terry

Yes, I must agree with you that it is something I should know.  I do try  
to keep with things but there are always some things that slip through the  
cracks, like enumerate, in this case.  That is why I am extremely grateful  
the for the activity, generosity and pure knowledge on this newsgroup to  
fill in the blanks for me.   It is guys like you who are willing to take  
the time to give responses that make it what it is.   In another  
newsgroup, I could have been flamed for letting Simon know he helped more  
than just the OP with his post :)

Thanks
Caleb


On Wed, 20 Jul 2005 23:41:36 +0200, Terry Reedy <[EMAIL PROTECTED]> wrote:

>
>> Wow, I didn't know about enumerate.
>
> It is listed and explained in Lib Ref Manual, Chapter 2, on builtin
> functions and types and their methods.  Everyone should read at least  
> that
> much of the Lib manual.
>
> Terry J. Reedy
>
>
>

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


Apology [was: is this pythonic]

2005-07-21 Thread Steven D'Aprano
It has been suggested to me off-list that my 
response(s) to Bill Mill in the "is this pythonic" 
thread were rude and hostile.

If that is what people saw in my posts, then I 
apologise, because that wasn't my intention. In fact, 
my comments weren't especially even aimed at Bill -- 
they were intended as more general comments about 
finding a balance between dismissing questions by 
pointing to the Python references, and guiding the 
questioner to learn the skills to be able to use the 
references effectively. I know I'm not yet at that 
stage: I still hit road-blocks in knowing where to look 
at times, and I guess that made me over-sensitive.

In hindsight, it would have been better for me to have 
cut Bill's comments from my reply, and just make 
allusions to a nebulous "they" who sometimes have a 
tendency towards using "RTFM" as an answer to anything, 
because Bill's specific was less dismissive and more 
supportive than what you can get on many newsgroups. I 
agree with his basic sentiments, although I might not 
have worded it in precisely the same way.

(Given how I put my foot in it when I did reply, 
perhaps that's not a bad thing.)

My apologies to Bill specifically, and [shameless 
brown-nosing here] thank you to the comp.lang.python 
community, which as a whole is far more tolerent than 
many other forums I've been on.


-- 
Steven.

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


Re: is this pythonic?

2005-07-21 Thread Terry Reedy

"Steven D'Aprano" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
> On Thu, 21 Jul 2005 10:27:24 -0400, Bill Mill wrote:
>
> [snip]
>
>> I said the *builtins* section. I think you learn pretty quick that
>> figuring out what functions are builtins is pretty important in every
>> language. There's a fair number of people out there giving the advice
>> to read chapter 2 of the library reference cover-to-cover for a good
>> starter on python.

Including me.
>
> Sure. But for a beginner to start learning the language by reading the
> language manual is a bit much to ask.

Sure, but who is suggesting that.  Suggesting that people specifically read 
chapter 2 of the Library manual (but only that to start -- I probably have 
still not read every chapter yet) is quite different.

> There is no need to get defensive, I was merely commenting on the need to
> understand that inexperienced programmers often don't know enough about
> the language to know where to start looking for the answer.

Which is precise why I try to help by telling them where to start.  A large 
number of beginner queries posted here are answered in the builtins 
chapter.

Terry J. Reedy



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


Re: is this pythonic?

2005-07-21 Thread Steven D'Aprano
On Thu, 21 Jul 2005 10:27:24 -0400, Bill Mill wrote:

[snip]

> I said the *builtins* section. I think you learn pretty quick that
> figuring out what functions are builtins is pretty important in every
> language. There's a fair number of people out there giving the advice
> to read chapter 2 of the library reference cover-to-cover for a good
> starter on python.

Sure. But for a beginner to start learning the language by reading the
language manual is a bit much to ask. Some people can do it, but most
learn best by doing, not by reading dry, abstract descriptions of what
various functions do. In my experience, iterators and generators don't
even make sense until you've spent some time playing with them.

> Furthermore, I wasn't being hard on the guy, he still added up to +1.
> Lighten up, I was joking.

There is no need to get defensive, I was merely commenting on the need to
understand that inexperienced programmers often don't know enough about
the language to know where to start looking for the answer.

In fact, it isn't just inexperienced programmers, but experienced
programmers too. I'm sure Guido doesn't need to look up enumerate in the
reference manual; but if he wanted to write a program to calculate the
positions of the anti-nodes of vibratory modes of the bound-state of a
muon and a proton/neutron pair, the odds are pretty good he wouldn't even
know where to start looking either :-)

The great thing about Usenet and the Internet is that we can pick each
other's brains for answers, instead of flailing around blindly in manuals
that don't understand the simplest natural language query. And isn't that
why we're here?



Regards,



-- 
Steven.

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


Re: is this pythonic?

2005-07-21 Thread Steven D'Aprano
On Thu, 21 Jul 2005 16:43:00 +0100, Michael Hoffman wrote:

> Personally, I feel my time is better served by answering questions that 
> would not be easy to find without assistance. I can't expect everyone to 
> know about or expect enumerate() from the beginning, so I don't have any 
> objections to it being asked here.
> 
> If people were to ask what the function signature for enumerate() was 
> when that is easy to Google, then I would think they were wasting 
> everyone's time.

And on that, I think we can agree!


-- 
Steven.

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


Re: is this pythonic?

2005-07-21 Thread Michael Hoffman
Steven D'Aprano wrote:

> The great thing about Usenet and the Internet is that we can pick each
> other's brains for answers, instead of flailing around blindly in manuals
> that don't understand the simplest natural language query. And isn't that
> why we're here?

Personally, I feel my time is better served by answering questions that 
would not be easy to find without assistance. I can't expect everyone to 
know about or expect enumerate() from the beginning, so I don't have any 
objections to it being asked here.

If people were to ask what the function signature for enumerate() was 
when that is easy to Google, then I would think they were wasting 
everyone's time.
-- 
Michael Hoffman
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2005-07-21 Thread Bill Mill
On 7/21/05, Steven D'Aprano <[EMAIL PROTECTED]> wrote:
> On Wed, 20 Jul 2005 16:30:10 -0400, Bill Mill wrote:
> 
> > On 7/20/05, Simon Brunning <[EMAIL PROTECTED]> wrote:
> >> On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
> >> > Or is there better way?
> >> >
> >> > for (i, url) in [(i,links[i]) for i in range(len(links))]:
> >>
> >> for i, url in enumerate(links):
> >>
> >
> > +2 for creating seeing a need and crafting a reasonable solution, but
> > -1 for not reading the section on builtins to see if it existed
> > already.
> 
> To see if *what* existed already?
> 
> It is well and good to say RTFM, but there are 697 subsections to the
> Python Library reference, and if you don't know what you are looking for,
> and beginners rarely are, it isn't obvious which is the right section to
> read. And the Library Reference isn't even "the" manual: there is also the
> global module reference and language reference.
> 
> If you already know what you are looking for, reading the manual is great
> advice. Browsing the manual looking for interesting tidbits can even be
> fun for a certain mindset. But if you don't know enough to know what to
> look for, where in the 2000-odd sections of the Python references will
> you find it?
> 

I said the *builtins* section. I think you learn pretty quick that
figuring out what functions are builtins is pretty important in every
language. There's a fair number of people out there giving the advice
to read chapter 2 of the library reference cover-to-cover for a good
starter on python.

Furthermore, I wasn't being hard on the guy, he still added up to +1.
Lighten up, I was joking.

> 
> 
> > (As for its pythonicity, I would have recommended isolating it into a
> > function and making it a generator:
> 
> It is easy to take this to extremes. It isn't necessary to isolate
> everything into its own object, or class, or module. Too much
> encapsulation is just as bad as too little.
> 

agreed; his listcomp just looks awkward inside the for loop statement;
if it were my code, I would put it into a function. He asked if his
code was pythonic, and I think the (non-extreme) pythonic thing to do
would be to put his listcomp into a function.

> 
> > def my_enumerate(enumerable):
> > i = 0
> > for elt in enumerable:
> > yield (i, elt)
> > i += 1
> >
> > for i, url in my_enumerate(links):
> >
> > but it's not too bad as it is. Also, my function is completely
> > untested - it's close to right though.)
> 
> What is the advantage of your function my_enumerate over the Python
> built-in enumerate?
> 
> 

absolutely none; I just was saying how I would encapsulate it into a function.

Peace
Bill Mill
bill.mill at gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2005-07-21 Thread Steven D'Aprano
On Wed, 20 Jul 2005 16:30:10 -0400, Bill Mill wrote:

> On 7/20/05, Simon Brunning <[EMAIL PROTECTED]> wrote:
>> On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
>> > Or is there better way?
>> >
>> > for (i, url) in [(i,links[i]) for i in range(len(links))]:
>> 
>> for i, url in enumerate(links):
>> 
> 
> +2 for creating seeing a need and crafting a reasonable solution, but
> -1 for not reading the section on builtins to see if it existed
> already.

To see if *what* existed already?

It is well and good to say RTFM, but there are 697 subsections to the
Python Library reference, and if you don't know what you are looking for,
and beginners rarely are, it isn't obvious which is the right section to
read. And the Library Reference isn't even "the" manual: there is also the
global module reference and language reference.

If you already know what you are looking for, reading the manual is great
advice. Browsing the manual looking for interesting tidbits can even be
fun for a certain mindset. But if you don't know enough to know what to
look for, where in the 2000-odd sections of the Python references will
you find it?



> (As for its pythonicity, I would have recommended isolating it into a
> function and making it a generator:

It is easy to take this to extremes. It isn't necessary to isolate
everything into its own object, or class, or module. Too much
encapsulation is just as bad as too little.


> def my_enumerate(enumerable):
> i = 0
> for elt in enumerable:
> yield (i, elt)
> i += 1
> 
> for i, url in my_enumerate(links):
> 
> but it's not too bad as it is. Also, my function is completely
> untested - it's close to right though.)

What is the advantage of your function my_enumerate over the Python
built-in enumerate?


-- 
Steven.

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


Re: is this pythonic?

2005-07-21 Thread Thomas Lotze
Mage wrote:

> Or is there better way?
> 
> for (i, url) in [(i,links[i]) for i in range(len(links))]:
>   ...
> 
> "links" is a list.

for i, url in enumerate(links):

-- 
Thomas

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


Re: is this pythonic?

2005-07-20 Thread Peter Hansen
Terry Reedy wrote:
>>Wow, I didn't know about enumerate.
> 
> It is listed and explained in Lib Ref Manual, Chapter 2, on builtin 
> functions and types and their methods.  Everyone should read at least that 
> much of the Lib manual.

Or be sure to read the "What's New in Python X.Y" pages that are 
released with new versions of Python, to stay current.  Then read them 
again a few months later.  Then again when you finally get around to 
installing the new version (if you lag behind).  And again a few months 
later... ;-)

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


Re: is this pythonic?

2005-07-20 Thread Terry Reedy

> Wow, I didn't know about enumerate.

It is listed and explained in Lib Ref Manual, Chapter 2, on builtin 
functions and types and their methods.  Everyone should read at least that 
much of the Lib manual.

Terry J. Reedy



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


Re: is this pythonic?

2005-07-20 Thread Bill Mill
On 7/20/05, Bill Mill <[EMAIL PROTECTED]> wrote:
> On 7/20/05, Simon Brunning <[EMAIL PROTECTED]> wrote:
> > On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
> > > Or is there better way?
> > >
> > > for (i, url) in [(i,links[i]) for i in range(len(links))]:
> >
> > for i, url in enumerate(links):
> >
> 
> +2 for creating seeing a need and crafting a reasonable solution, but
> -1 for not reading the section on builtins to see if it existed
> already.
> 

-1 for me for not reading over my email before sending. "creating
seeing" should be "seeing".

Peace
Bill Mill
bill.mill at gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2005-07-20 Thread Bill Mill
On 7/20/05, Simon Brunning <[EMAIL PROTECTED]> wrote:
> On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
> > Or is there better way?
> >
> > for (i, url) in [(i,links[i]) for i in range(len(links))]:
> 
> for i, url in enumerate(links):
> 

+2 for creating seeing a need and crafting a reasonable solution, but
-1 for not reading the section on builtins to see if it existed
already.

(As for its pythonicity, I would have recommended isolating it into a
function and making it a generator:

def my_enumerate(enumerable):
i = 0
for elt in enumerable:
yield (i, elt)
i += 1

for i, url in my_enumerate(links):

but it's not too bad as it is. Also, my function is completely
untested - it's close to right though.)

Peace
Bill Mill
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: is this pythonic?

2005-07-20 Thread Caleb Hattingh
Wow, I didn't know about enumerate.

Many thanks
Caleb

On Wed, 20 Jul 2005 15:19:50 +0200, Simon Brunning  
<[EMAIL PROTECTED]> wrote:

> On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
>> Or is there better way?
>>
>> for (i, url) in [(i,links[i]) for i in range(len(links))]:
>
> for i, url in enumerate(links):
>

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


Re: is this pythonic?

2005-07-20 Thread Simon Brunning
On 7/20/05, Mage <[EMAIL PROTECTED]> wrote:
> Or is there better way?
> 
> for (i, url) in [(i,links[i]) for i in range(len(links))]:

for i, url in enumerate(links):

-- 
Cheers,
Simon B,
[EMAIL PROTECTED],
http://www.brunningonline.net/simon/blog/
-- 
http://mail.python.org/mailman/listinfo/python-list


is this pythonic?

2005-07-20 Thread Mage
Or is there better way?

for (i, url) in [(i,links[i]) for i in range(len(links))]:
  ...

"links" is a list.

   Mage


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