Modifying the value of a float-like object

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Wed Apr 15 01:13:51 EDT 2009


On Tue, 14 Apr 2009 12:36:02 -0700, Eric.Le.Bigot wrote:

> I'll give more details, as David S. and David R. were asking for.  The
> code could look like this:
> 
>   import crystals
>   my_crystal = crystals.Crystal("Quartz 111")
> 
> which would set some attributes of my_crystal as "floats with
> uncertainty" FloatWithUncert, which behave exactly like floats in
> calculations (they return the central value of the confidence interval:
> x returns the value, as for floats, while, x.uncert returns the
> uncertainty).

So far so good -- this is just straight-forward interval arithmetic. 
Nothing about this requires mutability.


> Now, I'd like to perform a calculation of some physical
> quantity associated to the crystal:
> 
>   print my_crystal.lattice_spacing(temperature = 273.15) setup =
>   Experiment(my_crystal, my_mirror); print setup.bragg_angle
> ()  # An Experiment object also defines and uses FloatWithUncert objects
> 
> Everything is fine up to now (I have a FloatWithUncert class which
> inherits from float).

Your programming model is not clear. Does the Experiment class represent 
the things you do to perform the experimental procedure? Or does it 
represent the result(s) you get after you perform the experimental 
procedure?


> Now, I would like to get the uncertainty on the result, 

What's "the result"? Is setup "the result"? Or setup.bragg_angle? Or 
something else? 


> even though we
> have no idea of what quantities are used in lattice_spacing() for the
> calculation (it can be attribute that are floats, attributes that are
> FloatWithUncert, module globals defined as FloatWithUncert, etc.).


I'm going to assume that you have a valid way of combining floats with 
FloatWithUncert that doesn't invalidate your error estimates.

Still there's nothing here that requires mutability.


> The
> idea that prompted my initial post was as follows: perform the same
> calculation of lattice_spacing() many times, but each time change on of
> existing FloatWithUncert numbers (this is akin to the derive() function
> of Peter) and deduce the uncertainty on lattice_spacing() 

I think you are asking for this behaviour:

>>> my_crystal.magic = 1  # hidden input as an attribute (say)
>>> x = my_crystal.lattice_spacing(temperature=290)
>>> print x, x.uncert
(1.234, 0.001)
>>> my_crystal.magic = 2  # change an attribute
>>> print x, x.uncert  # and magic happens
(4.567, 0.003)

If so, that is bad and evil. You might think it is a good idea now, but 
trust me, it will lead to tears.


Do this instead:

>>> my_crystal.magic = 1  # hidden input as an attribute (say)
>>> x = my_crystal.lattice_spacing(temperature=290)
>>> print x, x.uncert
(1.234, 0.001)
>>> my_crystal.magic = 2  # change an attribute
>>> y = my_crystal.lattice_spacing(temperature=290)
>>> print x, x.uncert  # stability is a good thing
(1.234, 0.001)
>>> print y, t.uncert
(4.567, 0.003)



You might think mutable values changing by magic is a good thing now, but 
trust me, it isn't. Let me put it this way... if you were doing a real 
experiment, and you had a note pad and *wrote down* the lattice spacing 
after an experiment, and then a week later somebody came into the lab and 
changed some component in the experimental setup, and the numbers in your 
notepad changed, that would be a disaster. What you're suggesting (or at 
least what I think you're suggesting) is the same thing, only not quite 
as extreme.



-- 
Steven



More information about the Python-list mailing list