Re: [Python-Dev] Example for PEP 343

2005-05-18 Thread Michael Chermside
Phillip writes:
> >@do_template
> >def with_extra_precision(places=2):
> > "Performs nested computation with extra digits of precision."
> > decimal.getcontext().prec += 2
> > yield None
> > decimal.getcontext().prec -= 2
>
> Won't this do the wrong thing if something within the block alters
> the precision?

Depends on what behavior you want. I wrote it this way partly because
that's how the example in the manual was written, and partly because
I was thinking "if someone increased the precision by 3 within the
block, then we probably want to leave it increased by 3 on block
exit".

On careful re-consideration, I think it'd be better to require that
the block NOT make unbalanced changes to the precision... we
could verify it using an assert statement.

I avoided caching the context and restoring it, because I WANTED to
allow code in the block to make OTHER alterations to the context and
not clobber them after the block exits (eg: setting or clearing some
trap). It's debatable whether that was a good design choice... there's
a great deal of elegence to Guido's version used like this:

Guido:
>   do with_decimal_context() as ctx:
>   ctx.prec += 2
>   # change other settings
>   # algorithm goes here

However, all of these are minor details compared to the bug that
Raymond points out:

Raymond:
> The final "return +s" should be unindented.  It should
> be at the same level as the "do with_extra_precision()".  The purpose of
> the "+s" is to force the result to be rounded back to the *original*
> precision.

In effect, the "with_extra_precision" wrapper causes the calculations
to be done with higher precision, AND causes any variables set during
the block will retain their higher precision. (It's because context
controls OPERATIONS but changing context never affects individual
Decimal OBJECTS.) So I fear that the whole with_extra_precision()
idea is just likely to tempt people into introducing subtle bugs, and
it should probably be scrapped anyhow. Guido's approach to save-and-
restore context works fine.

-- Michael Chermside

(PS: Another reason that I avoided a basic save-and-restore is that we
have plenty of examples already of 'do' statements that save-and-restore,
I was trying to do something different. It's interesting that what I
tried may have turned out to be a poor idea.)

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-18 Thread Nick Coghlan
Guido van Rossum wrote:
> Anyway, perhaps we should provide this most general template:
> 
>   @do_template
>   def with_decimal_context():
>   oldctx = decimal.getcontext()
>   newctx = oldctx.copy()
>   decimal.setcontext(newctx)
>   yield newctx
>   decimal.setcontext(oldctx)
> 
> To be used like this:
> 
>   do with_decimal_context() as ctx:
>   ctx.prec += 2
>   # change other settings
>   # algorithm goes here


For the 'with' keyword, and the appropriate __enter__/__exit__ methods on 
decimal Contexts, this can be written:

   with decimal.getcontext() as ctx:
   ctx.prec += 2
   # change other settings
   # algorithm goes here
   # Pre-with context guaranteed to be restored here

The decimal.Context methods to make this work:

   def __enter__(self):
   current = getcontext()
   if current is self:
   self._saved_context = self.copy()
   else:
   self._saved_context = current
   setcontext(self)

   def __exit___(self, *exc_info):
   if self._saved_context is None:
   raise RuntimeError("No context saved")
   try:
   setcontext(self._saved_context)
   finally:
   self._saved_context = None

Cheers,
Nick.

-- 
Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
---
 http://boredomandlaziness.blogspot.com
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Bob Ippolito

On May 17, 2005, at 11:39 PM, Guido van Rossum wrote:

> [Raymond Hettinger]
>
>> However, for a general purpose wrapper, it is preferable to make a
>> context copy and then restore the context after the enclosed is run.
>> That guards against the enclosed block making any unexpected context
>> changes.
>>
>
> (Although if people get in the habit of using the provided wrappers
> and the do-statement, there won't be any unexpected changes.)
>
>
>> Also, since the wrapper is intended to work like a try/finally, it  
>> will
>> make sure the context gets restored even if an exception is raised at
>> some unexpected point in the middle of the computation.
>>
>
> Yes, that's the point of the do-statement. :-
>
> Anyway, perhaps we should provide this most general template:
>
>   @do_template
>   def with_decimal_context():
>   oldctx = decimal.getcontext()
>   newctx = oldctx.copy()
>   decimal.setcontext(newctx)
>   yield newctx
>   decimal.setcontext(oldctx)
>
> To be used like this:
>
>   do with_decimal_context() as ctx:
>   ctx.prec += 2
>   # change other settings
>   # algorithm goes here

I have yet to use the decimal module much, so I may be completely off  
here.. but why not write it like this:

@do_template
def with_decimal_context():
 curctx = decimal.getcontext()
 oldctx = curctx.copy()
 yield curctx
 decimal.setcontext(oldctx)

Saves a line and a context set :)

-bob

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Guido van Rossum
[Raymond Hettinger]
> The sin() example is correct.  The precision is changed and restored in
> the current context.

I got that eventually. :-)

> However, for a general purpose wrapper, it is preferable to make a
> context copy and then restore the context after the enclosed is run.
> That guards against the enclosed block making any unexpected context
> changes.

(Although if people get in the habit of using the provided wrappers
and the do-statement, there won't be any unexpected changes.)

> Also, since the wrapper is intended to work like a try/finally, it will
> make sure the context gets restored even if an exception is raised at
> some unexpected point in the middle of the computation.

Yes, that's the point of the do-statement. :-

Anyway, perhaps we should provide this most general template:

  @do_template
  def with_decimal_context():
  oldctx = decimal.getcontext()
  newctx = oldctx.copy()
  decimal.setcontext(newctx)
  yield newctx
  decimal.setcontext(oldctx)

To be used like this:

  do with_decimal_context() as ctx:
  ctx.prec += 2
  # change other settings
  # algorithm goes here

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Raymond Hettinger
> I don't see a call to setcontext() in the sin() example in the library
> reference. Is that document wrong? I thought that simply modifying the
> parameters of the current context would be sufficient.

The sin() example is correct.  The precision is changed and restored in
the current context.

However, for a general purpose wrapper, it is preferable to make a
context copy and then restore the context after the enclosed is run.
That guards against the enclosed block making any unexpected context
changes.

Also, since the wrapper is intended to work like a try/finally, it will
make sure the context gets restored even if an exception is raised at
some unexpected point in the middle of the computation.



Raymond 
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Bob Ippolito

On May 17, 2005, at 10:36 PM, Guido van Rossum wrote:

> On 5/17/05, Raymond Hettinger <[EMAIL PROTECTED]> wrote:
>
>>> I think you're missing a decimal.setcontext(newcontext) before the
>>> yield..
>>>
>>
>> Right.
>>
>
> I don't see a call to setcontext() in the sin() example in the library
> reference. Is that document wrong? I thought that simply modifying the
> parameters of the current context would be sufficient.

The library reference isn't modifying the parameters in a *copy* of  
the current context.

-bob

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Guido van Rossum
On 5/17/05, Raymond Hettinger <[EMAIL PROTECTED]> wrote:
> > I think you're missing a decimal.setcontext(newcontext) before the
> > yield..
> 
> Right.

I don't see a call to setcontext() in the sin() example in the library
reference. Is that document wrong? I thought that simply modifying the
parameters of the current context would be sufficient.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Raymond Hettinger
> I think you're missing a decimal.setcontext(newcontext) before the
> yield..

Right.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Delaney, Timothy C (Timothy)
Bob Ippolito wrote:

>> One more thought:  Rather than just saving the precision, it is
>> likely wiser, safer, and more general to just save and restore the
>> whole context and let the wrapped block only work with a copy.
>> 
>> oldcontext = decimal.getcontext()
>> newcontext = oldcontext.copy()
>> newcontext.prec += 2
>> yield None
>> decimal.setcontext(oldcontext)
>> 
>> This approach defends against various kinds of unruly behavior by the
>> yield target.
> 
> I think you're missing a decimal.setcontext(newcontext) before the
> yield..

Seems to me this should be in the standard library ;)

Tim Delaney
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Bob Ippolito

On May 17, 2005, at 9:02 PM, Raymond Hettinger wrote:

>>> What's the advantage of using two calls to getcontext() vs. saving
>>>
> the
>
>>> context in a local variable?
>>>
>>
>> I also prefer saving the context in a local variable but that is just
>>
> a
>
>> micro-optimization.  The presentation with multiple calls to
>> getcontext() was kept just to match the style of the original -- the
>> important change was the absolute save and restore versus the  
>> original
>> relative adjust up and adjust down.
>>
>
> One more thought:  Rather than just saving the precision, it is likely
> wiser, safer, and more general to just save and restore the whole
> context and let the wrapped block only work with a copy.
>
> oldcontext = decimal.getcontext()
> newcontext = oldcontext.copy()
> newcontext.prec += 2
> yield None
> decimal.setcontext(oldcontext)
>
> This approach defends against various kinds of unruly behavior by the
> yield target.

I think you're missing a decimal.setcontext(newcontext) before the  
yield..

-bob

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Raymond Hettinger
> > What's the advantage of using two calls to getcontext() vs. saving
the
> > context in a local variable?
> 
> I also prefer saving the context in a local variable but that is just
a
> micro-optimization.  The presentation with multiple calls to
> getcontext() was kept just to match the style of the original -- the
> important change was the absolute save and restore versus the original
> relative adjust up and adjust down.

One more thought:  Rather than just saving the precision, it is likely
wiser, safer, and more general to just save and restore the whole
context and let the wrapped block only work with a copy.

oldcontext = decimal.getcontext()
newcontext = oldcontext.copy()
newcontext.prec += 2
yield None
decimal.setcontext(oldcontext)

This approach defends against various kinds of unruly behavior by the
yield target.



Raymond Hettinger
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Raymond Hettinger
> What's the advantage of using two calls to getcontext() vs. saving the
> context in a local variable?

I prefer saving the context in a local variable but that is just a
micro-optimization.  The presentation with multiple calls to
getcontext() was kept just to match the style of the original -- the
important change was the absolute save and restore versus the original
relative adjust up and adjust down.


Raymond
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Guido van Rossum
What's the advantage of using two calls to getcontext() vs. saving the
context in a local variable?

On 5/17/05, Raymond Hettinger <[EMAIL PROTECTED]> wrote:
> 
> 
> > -Original Message-
> > From: [EMAIL PROTECTED] [mailto:python-dev-
> > [EMAIL PROTECTED] On Behalf Of Phillip J. Eby
> > Sent: Tuesday, May 17, 2005 6:06 PM
> > To: Michael Chermside; [EMAIL PROTECTED]
> > Cc: python-dev@python.org
> > Subject: Re: [Python-Dev] Example for PEP 343
> >
> > At 02:42 PM 5/17/2005 -0700, Michael Chermside wrote:
> >
> > ># = SAMPLE #1: increasing precision during a sub-calculation
> =
> > >
> > >import decimal
> > >
> > >@do_template
> > >def with_extra_precision(places=2):
> > > "Performs nested computation with extra digits of precision."
> > > decimal.getcontext().prec += 2
> > > yield None
> > > decimal.getcontext().prec -= 2
> >
> > Won't this do the wrong thing if something within the block alters the
> > precision?
> 
> Right.
> 
> It should save, alter, and then restore:
> 
>oldprec = decimal.getcontext().prec
>decimal.getcontext().prec += 2
>yield None
>decimal.getcontext().prec = oldprec
> 
> 
> Raymond Hettinger
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: 
> http://mail.python.org/mailman/options/python-dev/guido%40python.org
> 


-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Raymond Hettinger


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:python-dev-
> [EMAIL PROTECTED] On Behalf Of Phillip J. Eby
> Sent: Tuesday, May 17, 2005 6:06 PM
> To: Michael Chermside; [EMAIL PROTECTED]
> Cc: python-dev@python.org
> Subject: Re: [Python-Dev] Example for PEP 343
> 
> At 02:42 PM 5/17/2005 -0700, Michael Chermside wrote:
> 
> ># = SAMPLE #1: increasing precision during a sub-calculation
=
> >
> >import decimal
> >
> >@do_template
> >def with_extra_precision(places=2):
> > "Performs nested computation with extra digits of precision."
> > decimal.getcontext().prec += 2
> > yield None
> > decimal.getcontext().prec -= 2
> 
> Won't this do the wrong thing if something within the block alters the
> precision?

Right.

It should save, alter, and then restore:

   oldprec = decimal.getcontext().prec
   decimal.getcontext().prec += 2
   yield None
   decimal.getcontext().prec = oldprec


Raymond Hettinger
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Example for PEP 343

2005-05-17 Thread Phillip J. Eby
At 02:42 PM 5/17/2005 -0700, Michael Chermside wrote:

># = SAMPLE #1: increasing precision during a sub-calculation =
>
>import decimal
>
>@do_template
>def with_extra_precision(places=2):
> "Performs nested computation with extra digits of precision."
> decimal.getcontext().prec += 2
> yield None
> decimal.getcontext().prec -= 2

Won't this do the wrong thing if something within the block alters the 
precision?

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com