Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Steven D'Aprano
On Thu, Aug 25, 2016 at 08:46:54PM -0700, Ken Kundert wrote:

> This idea is new to general purpose languages, 

For the record, at least some HP calculators include a "units" data type 
as part of the programming language "RPL", e.g. the HP-28 and HP-48 
series. I've been using those for 20+ years so I'm quite familiar with 
how useful this feature can be.


> but it has been used for over 40 
> years in the circuit design community. Specifically, SPICE, an extremely 
> heavily 
> used circuit simulation package, introduced this concept in 1974. In SPICE 
> the 
> scale factor is honored but any thing after the scale factor is ignored.  
> Being 
> both a heavy user and developer of SPICE, I can tell you that in all that 
> time 
> this issue has never come up. In fact, the users never expected there to be 
> any 
> support for dimensional analysis, nor did they request it.

I can't comment about the circuit design community, but you're trying to 
extrapolate from a single specialist application to a general purpose 
programming language used by people of many, many varied levels of 
expertise, of competence, with many different needs.

It makes a lot of sense for applications to allow SI prefixes as 
suffixes within a restricted range. For example, the dd application 
allows the user to specify the amount of data to copy using either bytes 
or blocks, with optional suffixes:

BLOCKS  and BYTES may be followed by the following multiplicative 
suffixes: xM M, c 1, w 2, b 512, kB 1000, K 1024, MB 1000*1000, 
M 1024*1024, GB 1000*1000*1000, G 1024*1024*1024, and so on for  
T, P, E, Z, Y.

(Quoting from the man page.)

That makes excellent sense for a specialist application where numeric 
quantities always mean the same thing, or in this case, one of two 
things. As purely multiplicative suffixes, that even makes sense for 
Python: earlier I said that it was a good idea to add a simple module 
defining SI and IEC multiplicative constants in the std lib so that we 
could do x = 42*M or similar.

But that's a far cry from allowing and ignoring units.


> > Don't think of people writing code like this:
> > 
> > result = 23mA + 75MHz
> > 
> > which is obviously wrong. Think about them writing code like this:
> > 
> > total = sum_resistors_in_parallel(input, extra)
> 
> You say that '23mA + 75MHz' is obviously wrong, but it is only obviously 
> wrong 
> because the units are included, which is my point. If I had written '0.023 
> + 76e6', it would not be obviously wrong.

I understand your point and the benefit of dimensional analysis. But the 
problem is, as users of specialised applications we may be used to 
doing direct arithmetic on numeric literal values, with or without 
attached units:

23mA + 75MHz  # error is visible
23 + 75  # error is hidden

but as *programmers* we rarely do that. Generally speaking, it is rare 
to be doing arithmetic on literals where we might have the opportunity 
to attach a unit. We doing arithmetic on *variables* that have come from 
elsewhere. Reading the source code doesn't show us something that might 
be improved by adding a unit:

# we hardly ever see this
23 + 75

# we almost always see something like this
input + argument


At best, we can choose descriptive variable names that hint what the 
correct dimensions should be:

weight_of_contents + weight_of_container


The argument that units would make it easier for the programmer to spot 
errors is, I think, invalid, because the programmer will hardly ever get 
to see the units.


[...]
> Indeed that is the point of dimensional analysis. However, despite the 
> availability of all these packages, they are rarely if ever used because you 
> have to invest a tremendous effort before they can be effective. For example, 
> consider the simple case of Ohms Law:
> 
> V = R*I
> 
> To perform dimensional analysis we need to know the units of V, R, and I. 
> These 
> are variables not literals, so some mechanism needs to be provided for 
> specifying the units of variables, even those that don't exist yet, like V. 

This is not difficult, and you exaggerate the amount of effort required. 

To my sorrow, I'm not actually familiar with any of the Python libraries 
for this, so I'll give an example using the HP-48GX RPL language. 
Suppose I have a value which I am expecting to be current in amperes. 
(On the HP calculator, it will be passed to me on the stack, but the 
equivalent in Python will be a argument passed to a function.) For 
simplicity, let's assume that if it is a raw number, I will trust that 
the user knows what they are doing and just convert it to a unit object 
with dimension "ampere", otherwise I expect some sort of unit object 
which is dimensionally compatible:

1_A CONV

is the RPL program to perform this conversion on the top of the stack, 
and raise an error if the dimensions are incompatible. Converting to a 
more familiar Python-like API, I would expect so

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ivan Levkivskyi
On 26 August 2016 at 08:34, Nick Coghlan  wrote:

> On 26 August 2016 at 13:46, Ken Kundert 
> wrote:
> > On Fri, Aug 26, 2016 at 10:14:53AM +1000, Steven D'Aprano wrote:
> >> On Thu, Aug 25, 2016 at 11:02:11AM -0700, Ken Kundert wrote:
> >>
> >> > Even if the language completely ignores the units, we have still
> gained by
> >> > allowing the units to be there, just like we gain when we allow user
> to add
> >> > comments to their code even though the compiler ignores them.
> >>
> >> This part of your proposal would be *worse*: you would fool the casual
> or
> >> naive user into believing that Python did dimensional analysis, while
> in fact
> >> not doing so. You would give them a false sense of security.
> >
> > This idea is new to general purpose languages, but it has been used for
> over 40
> > years in the circuit design community. Specifically, SPICE, an extremely
> heavily
> > used circuit simulation package, introduced this concept in 1974. In
> SPICE the
> > scale factor is honored but any thing after the scale factor is
> ignored.  Being
> > both a heavy user and developer of SPICE, I can tell you that in all
> that time
> > this issue has never come up. In fact, the users never expected there to
> be any
> > support for dimensional analysis, nor did they request it.
>
> [snip]
>
> > And it has little to do with my proposal, which is basically this:
> >
> > Numbers with SI scale factor and units have become very popular. Using
> them is
> > a very common way of expressing either large or small numbers. And that
> is true
> > in the scientific and engineering communities, in the programming
> community
> > (even the linux sort command supports sorting on numbers with SI scale
> factors:
> > --human-numeric-sort), and even in popular culture.
> >
> > Python should support them. And I mean support with a capital S. I can
> come up
> > with many different hacks to support these ideas in Python today, and I
> have.
> > But this should not be a hack. This should be built into the language
> front and
> > center. It should be the preferred way that we specify and output real
> numbers.
>
> Thanks for the additional background Ken - that does start to build a
> much more compelling case.
>
> I now think there's another analogy you'll be able to draw on to make
> it even more compelling at a language design level: just because the
> *runtime* doesn't do dimensional analysis on static unit annotations
> doesn't mean that sufficiently clever static analysers couldn't do so
> at some point in the future. That then puts this proposal squarely in
> the same category as function annotations and gradual typing: semantic
> annotations that more clearly expressed developer intent, and aren't
> checked at runtime, but can be checked by a human during code review,
> and (optionally) by static analysers as a quality gate.
>

Unfortunately, I didn't read the whole thread, but it seems to me that
this would be just a more sophisticated version of NewType.
mypy type checker already supports NewType (not sure about pytype).
So that one can write (assuming PEP 526):

USD = NewType('USD', float)
EUR = NewType('EUR', float)

amount = EUR(100)
# later in code
new_amount: USD = amount # flagged as error by type checker

The same idea applies to physical units.
Of course type checkers do not know that e.g. 1m / 1s is 1 m/s, but
it is something they could be taught (for example by adding @overload
for division operator).

--
Ivan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Pavol Lisy
On 8/25/16, Ken Kundert  wrote:

[...]

> Just allowing the units to be present, even it not
>
> retained, is a big advantage because it can bring a great deal of clarity to
> the
> meaning of the number. For example, even if the language does not flag an
> error
> when a user writes:
>
> vdiff = 1mV - 30uA

It reminds me: "Metric mishap caused loss of NASA's Mars Climate
orbiter. It could be nice to have language support helping to avoid
something similar.

[...]

> 2. Or accept X in lieu of E. After all, the e is silent anyway.  Thus, on 
> input
>we accept ...
>
> 1Y -> 1e+24
> 1Z -> 1e+21
>  -> 1X -> 1e+18 <- only difference
> 1P -> 1e+15

Are SI prefixes frozen? Could not be safer to use E_ instead of X in
case of possible new future prefixes?

--

What you are proposing reminds me " [Python-ideas] Trial balloon:
adding variable type declarations in support of PEP 484". Instead of
adding constant type declaration.

Sorry this is just really quick idea around thinking that it could be
good to have parser possibility to check metric mishaps.

   distance1 = 1:km# or? ->  distance1:length = 1:km
   distance2 = 1000:cm  # or? ->  distance2:length = 1000:cm
   length = distance1 + distance2 # our parser could yell :) (or
compiler could translate it with warning)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Nick Coghlan
On 26 August 2016 at 13:46, Ken Kundert  wrote:
> On Fri, Aug 26, 2016 at 10:14:53AM +1000, Steven D'Aprano wrote:
>> On Thu, Aug 25, 2016 at 11:02:11AM -0700, Ken Kundert wrote:
>>
>> > Even if the language completely ignores the units, we have still gained by
>> > allowing the units to be there, just like we gain when we allow user to add
>> > comments to their code even though the compiler ignores them.
>>
>> This part of your proposal would be *worse*: you would fool the casual or
>> naive user into believing that Python did dimensional analysis, while in fact
>> not doing so. You would give them a false sense of security.
>
> This idea is new to general purpose languages, but it has been used for over 
> 40
> years in the circuit design community. Specifically, SPICE, an extremely 
> heavily
> used circuit simulation package, introduced this concept in 1974. In SPICE the
> scale factor is honored but any thing after the scale factor is ignored.  
> Being
> both a heavy user and developer of SPICE, I can tell you that in all that time
> this issue has never come up. In fact, the users never expected there to be 
> any
> support for dimensional analysis, nor did they request it.

[snip]

> And it has little to do with my proposal, which is basically this:
>
> Numbers with SI scale factor and units have become very popular. Using them is
> a very common way of expressing either large or small numbers. And that is 
> true
> in the scientific and engineering communities, in the programming community
> (even the linux sort command supports sorting on numbers with SI scale 
> factors:
> --human-numeric-sort), and even in popular culture.
>
> Python should support them. And I mean support with a capital S. I can come up
> with many different hacks to support these ideas in Python today, and I have.
> But this should not be a hack. This should be built into the language front 
> and
> center. It should be the preferred way that we specify and output real 
> numbers.

Thanks for the additional background Ken - that does start to build a
much more compelling case.

I now think there's another analogy you'll be able to draw on to make
it even more compelling at a language design level: just because the
*runtime* doesn't do dimensional analysis on static unit annotations
doesn't mean that sufficiently clever static analysers couldn't do so
at some point in the future. That then puts this proposal squarely in
the same category as function annotations and gradual typing: semantic
annotations that more clearly expressed developer intent, and aren't
checked at runtime, but can be checked by a human during code review,
and (optionally) by static analysers as a quality gate.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ken Kundert
On Fri, Aug 26, 2016 at 10:14:53AM +1000, Steven D'Aprano wrote:
> On Thu, Aug 25, 2016 at 11:02:11AM -0700, Ken Kundert wrote:
> 
> > Even if the language completely ignores the units, we have still gained by 
> > allowing the units to be there, just like we gain when we allow user to add 
> > comments to their code even though the compiler ignores them.
> 
> This part of your proposal would be *worse*: you would fool the casual or 
> naive user into believing that Python did dimensional analysis, while in fact 
> not doing so. You would give them a false sense of security.

This idea is new to general purpose languages, but it has been used for over 40 
years in the circuit design community. Specifically, SPICE, an extremely 
heavily 
used circuit simulation package, introduced this concept in 1974. In SPICE the 
scale factor is honored but any thing after the scale factor is ignored.  Being 
both a heavy user and developer of SPICE, I can tell you that in all that time 
this issue has never come up. In fact, the users never expected there to be any 
support for dimensional analysis, nor did they request it.

> Don't think of people writing code like this:
> 
> result = 23mA + 75MHz
> 
> which is obviously wrong. Think about them writing code like this:
> 
> total = sum_resistors_in_parallel(input, extra)

You say that '23mA + 75MHz' is obviously wrong, but it is only obviously wrong 
because the units are included, which is my point. If I had written '0.023 
+ 76e6', it would not be obviously wrong.

> > Some people have suggested that we take the next step and use the units for 
> > dimensional analysis, but that is highly problematic because you cannot do 
> > dimensional analysis unless everything is specified with the correct units, 
> > and that can be a huge burden for the user.
> 
> What?
> 
> That's the *whole point* of dimensional analysis: to ensure that the 
> user is not adding a length to a weight and then treating the result as 
> a time. To say that "it is too hard to specify the correct units, so we 
> should just ignore the units" boggles my mind.
> 
> Any reasonable dimensional program should perform automatic unit 
> conversions: you can add inches to metres, but not inches to pounds. 
> There are already many of these available for Python.

Indeed that is the point of dimensional analysis. However, despite the 
availability of all these packages, they are rarely if ever used because you 
have to invest a tremendous effort before they can be effective. For example, 
consider the simple case of Ohms Law:

V = R*I

To perform dimensional analysis we need to know the units of V, R, and I. These 
are variables not literals, so some mechanism needs to be provided for 
specifying the units of variables, even those that don't exist yet, like V. And 
what if the following is encountered:

V = I

Dimensional analysis says this is wrong, but the it may be that the resistance 
is simply being suppressed because it is unity.  False positives of this sort 
are a tremendous problem with this form of automated dimensional analysis. Then 
there are things like this:

V = 2*sin(f*t)

In this case dimensional analysis (DA) indicates an error, but it is the wrong 
error. DA will complain about the fact that a dimensionless number is being 
assigned to a variable intended to carry a voltage. But in this case 2 has 
units 
of voltage, but they were not explicitly specified, so this is another false 
positive.  The real error is the argument of the sin function. The sin function 
expects radians, which is dimensionless, and f*t is dimensionless, so there is 
no complaint, but it is not in radians, and so there should be an error.  You 
could put a 'unit' of radians on pi, but that is not right either. Really it is 
2*pi that gives you radians, and if you put radians on py and then used pi to 
compute the area of a unit circle, you would get pi*r^2 where r=1 meter, and 
the 
resulting units would be radians*m^2, which is nonsensical.

Turns out there are many kinds of dimensionless numbers. For example, the 
following represents a voltage amplifier:

Av = 4   # voltage gain (V/V)
Ai = 0.03# current gain (A/A)
Vout = Ai*Vin

In this case Ai is expected to be unitless, which it is, so there is no error.  
However Ai is the ratio of two currents, not two voltages, so there actually 
should be an error.

Now consider an expression that contains an arbitrary function call:

V = f(I)

How do we determine the units of the return value of f?

Now, finally consider the BSIM4 MOSFET model equations. They are described in 


http://www-device.eecs.berkeley.edu/bsim/Files/BSIM4/BSIM460/doc/BSIM460_Manual.pdf

If you look at this document you will find over 200 pages of extremely 
complicated and tedious model equations. The parameters of these models can 
have 
extremely complicated units. Well beyond anything I am proposing for real 
literals. For example, consider NOIA,

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Random832
On Thu, Aug 25, 2016, at 19:50, Steven D'Aprano wrote:
> Historically, there are *three* different meanings for "MB", only one of 
> which is an official standard:
> 
> http://physics.nist.gov/cuu/Units/binary.html

The link doesn't work for me... is the third one the 1,024,000 bytes
implicit in describing standard-formatted floppy disks as "1.44 MB"
(they are actually 1440 bytes: 80 tracks, 2 sides, 18 512-byte sectors)
or "1.2 MB" (15 sectors).
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Nick Coghlan
On 26 August 2016 at 06:06, Ken Kundert  wrote:
> Here is a fairly typical example that illustrates the usefulness of supporting
> SI scale factors and units in Python.

Ken,

To build a persuasive case, you'll find it's necessary to stop
comparing Python-with-syntactic-support to
Python-with-no-syntactic-support-and-no-third-party-libraries, and
instead bring in the existing dimensional analysis libraries and
tooling, and show how this change would improve *those*.

That is, compare your proposed syntax *not* to plain Python code, but
to Python code using some of the support libraries Steven D'Aprano
mentioned, whether that's SymPy (as in
http://docs.sympy.org/latest/modules/physics/unitsystems/examples.html
) or one of the other unit conversion libraries (as in
http://stackoverflow.com/questions/2125076/unit-conversion-in-python )

It's also worth explicitly highlighting that the main intended
beneficiaries would *NOT* be traditional software applications (where
the data entry UI is clearly distinct from the source code) and
instead engineers, scientists, and other data analysts using
environments like Project Jupyter, where the code frequently *is* the
data entry UI.

And given that target audience, a further question that needs to be
addressed is whether or not native syntactic support would be superior
to what's already possible through Jupyter/IPython cell magics like
https://bitbucket.org/birkenfeld/ipython-physics

The matrix multiplication PEP
(https://www.python.org/dev/peps/pep-0465/ ) is one of the best
examples to study on how to make this kind of case well - it surveys
the available options, explains how they all have a shared challenge
with the status quo, and requests the simplest possible enabling
change to the language definition to help them solve the problem.

One potentially fruitful argument to pursue might be to make Python a
better tool for teaching maths and science concepts at primary and
secondary level (since Jupyter et al are frequently seen as
introducing too much tooling complexity to be accessible at that
level), but again, you'd need to explore whether or not anyone is
currently using Python in that way, and what their feedback is in
terms of the deficiencies of the status quo.

Regards,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Steven D'Aprano
On Thu, Aug 25, 2016 at 11:02:11AM -0700, Ken Kundert wrote:

> Once you 
> allow SI scale factors on numbers, the natural tendency is for people to want 
> to 
> add units, which is a good thing because it gives important information about 
> the number. We should allow it because it improves the code by making it more 
> self documenting. Even if the language completely ignores the units, we have 
> still gained by allowing the units to be there, just like we gain when we 
> allow 
> user to add comments to their code even though the compiler ignores them.

This is dangerously wrong, and the analogy with comments is misleading. 
Everyone knows that comments are ignored by the interpreter, and even 
then, the ideal is to write self-documenting code, not comments:

"At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. "
--Michael Foord paraphrases Christian Muirhead on python-dev, 2009-03-22

This part of your proposal would be *worse*: you would fool the casual 
or naive user into believing that Python did dimensional analysis, while 
in fact not doing so. You would give them a false sense of security.

Don't think of people writing code like this:

result = 23mA + 75MHz

which is obviously wrong. Think about them writing code like this:

total = sum_resistors_in_parallel(input, extra)

where the arguments may themselves have been passed to the current 
function as parameters from somewhere else. Or they may be data values 
read from a file. Their definitions may be buried deep in another part 
of the program. Their units aren't obvious to the reader without serious 
work.

This part of your proposal makes the language *worse*: we lose the 
simple data validation that "23mA" is not a valid number, but without 
gaining the protection of dimensional analysis.

To give an analogy, you are suggesting that we stick a sticker on the 
dashboard of our car saying "Airbag" but without actually installing an 
airbag. And you've removed the seat belt. The driver has to read the 
manual to learn that the "Airbag" is just a label, not an actual 
functioning airbag.


> Some people have suggested that we take the next step and use the units for 
> dimensional analysis, but that is highly problematic because you cannot do 
> dimensional analysis unless everything is specified with the correct units, 
> and 
> that can be a huge burden for the user.

What?

That's the *whole point* of dimensional analysis: to ensure that the 
user is not adding a length to a weight and then treating the result as 
a time. To say that "it is too hard to specify the correct units, so we 
should just ignore the units" boggles my mind.

Any reasonable dimensional program should perform automatic unit 
conversions: you can add inches to metres, but not inches to pounds. 
There are already many of these available for Python.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Steven D'Aprano
On Thu, Aug 25, 2016 at 09:03:32PM +0100, Paul Moore wrote:

> That's not to say there's no room for debate here - the proposal is
> interesting, and not without precedent (for example Windows Powershell
> supports constants of the form 1MB, 1GB 

That's great! I know a few command line tools and scripts which do that, 
and it's really useful.

> - which ironically are
> computing-style 2*20 and 2*30 rather than SI-style 10*6 and 10*9). 

Do I remember correctly that Windows file Explorer displays disk sizes 
is decimal SI units? If so, how very Microsoft, to take a standard and 
confuse it rather than encourage it :-(

Historically, there are *three* different meanings for "MB", only one of 
which is an official standard:

http://physics.nist.gov/cuu/Units/binary.html


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Xavier Combelle


On 25/08/2016 22:06, Ken Kundert wrote:
> Here is a fairly typical example that illustrates the usefulness of 
> supporting 
> SI scale factors and units in Python.
>
> This is simple simulation code that is used to test a current mirror driving 
> an 
> 100kOhm resistor ...
>
> Here is some simulation code that uses SI scale factors
>
> for delta in [-500nA, 0, 500nA]:
> input = 2.75uA + delta
> wait(1us)
> expected = 100kOhm*(2.75uA + delta)
> tolerance = 2.2mV
> fails = check_output(expected, tolerance)
> print('%s: I(in)=%rA, measured V(out)=%rV, expected V(out)=%rV, 
> diff=%rV.' % (
> 'FAIL' if fails else 'pass',
> input, get_output(), expected, get_output() - expected
> ))
>
> with the output being:
>
> pass: I(in)=2.25uA, measured V(out)=226.7mV, expected V(out)=225mV, 
> diff=1.7mV.
> pass: I(in)=2.75uA, measured V(out)=276.8mV, expected V(out)=275mV, 
> diff=1.8mV.
> FAIL: I(in)=3.25uA, measured V(out)=327.4mV, expected V(out)=325mV, 
> diff=2.4mV.
>
> And the same code in Python today ...
>
> for delta in [-5e-7, 0, 5e-7]:
> input = 2.75e-6 + delta
> wait(1e-6)
> expected = 1e5*(2.75e-6 + delta)
> tolerance = 2.2e-3
> fails = check_output(expected, tolerance)
> print('%s: I(in)=%eA, measured V(out)=%eV, expected V(out)=%eV, 
> diff=%eV.' % (
> 'FAIL' if fails else 'pass',
> input, get_output(), expected, get_output() - expected
> ))
>
> with the output being:
>
> pass: I(in)=2.25e-6A, measured V(out)=226.7e-3V, expected V(out)=225e-3V, 
> diff=1.7e-3V.
> pass: I(in)=2.75e-6A, measured V(out)=276.8e-3V, expected V(out)=275e-3V, 
> diff=1.8e-3V.
> FAIL: I(in)=3.25e-6A, measured V(out)=327.4e-3V, expected V(out)=325e-3V, 
> diff=2.4e-3V.
>
> There are two things to notice. In the first example the numbers are easier to
> read: for example, 500nA is easier to read the 5e-7. Second, there is 
> information in the units that provides provides useful information. One can 
> easily see that the input signal is a current and that the output is a 
> voltage.  
> Furthermore, anybody can look at this code and do a simple sanity check on 
> the 
> expressions even if they don't understand the system being simulated. They 
> can 
> check the units on the input and output expressions to assure that they are 
> all 
> consistent.
>
> -Ken
> ___
>
And the same code with python today


def wait(delay):
pass
def check_output(expected, tolerance):
return False
def get_output():
return 1*uA
def f():
for delta in [-500*nA, 0, 500*nA]:
input = 2.75*uA + delta
wait(1*us)
expected = 100*kOhm*(2.75*uA + delta)
tolerance = 2.2*mV
fails = check_output(expected, tolerance)
print('%s: I(in)=%rA, measured V(out)=%rV, expected V(out)=%rV,
diff=%rV.' % (
'FAIL' if fails else 'pass',
input, get_output(), expected, get_output() - expected
))
f()

pass: I(in)=2.25e-05A, measured V(out)=1e-05V, expected V(out)=22.5V,
diff=-22.4V.
pass: I(in)=2.75e-05A, measured V(out)=1e-05V, expected V(out)=27.5V,
diff=-27.4V.
pass: I(in)=3.2504e-05A, measured V(out)=1e-05V, expected
V(out)=32.51V, diff=-32.404V.

Do you really see fundamental difference with your original code?




___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Chris Angelico
On Fri, Aug 26, 2016 at 6:06 AM, Ken Kundert
 wrote:
> Here is some simulation code that uses SI scale factors
>
> for delta in [-500nA, 0, 500nA]:
> input = 2.75uA + delta
> wait(1us)
> expected = 100kOhm*(2.75uA + delta)
> tolerance = 2.2mV
> fails = check_output(expected, tolerance)
> print('%s: I(in)=%rA, measured V(out)=%rV, expected V(out)=%rV, 
> diff=%rV.' % (
> 'FAIL' if fails else 'pass',
> input, get_output(), expected, get_output() - expected
> ))
>
> And the same code in Python today ...
>
> for delta in [-5e-7, 0, 5e-7]:
> input = 2.75e-6 + delta
> wait(1e-6)
> expected = 1e5*(2.75e-6 + delta)
> tolerance = 2.2e-3
> fails = check_output(expected, tolerance)
> print('%s: I(in)=%eA, measured V(out)=%eV, expected V(out)=%eV, 
> diff=%eV.' % (
> 'FAIL' if fails else 'pass',
> input, get_output(), expected, get_output() - expected
> ))

Rename a few things:

for deltaA in [-5e-7, 0, 5e-7]:
inputA = 2.75e-6 + deltaA
wait(1e-6)
expectedA = 1e5*(2.75e-6 + deltaA)
toleranceV = 2.2e-3
fails = check_output(expectedA, toleranceV)
print('%s: I(in)=%eA, measured V(out)=%eV, expected
V(out)=%eV, diff=%eV.' % (
'FAIL' if fails else 'pass',
inputA, get_output(), expectedA, get_output() - expectedA
))

I may have something wrong here (for instance, I'm not sure if
check_output should be taking an expected amperage and a tolerance in
volts), but you get the idea: it's the variables, not the literals,
that get tagged.

Another way to do this would be to use MyPy and type hinting to create
several subtypes of floating-point number:

class V(float): pass
class A(float): pass

for delta in [A(-5e-7), A(0), A(5e-7)]:
input = A(2.75e-6) + delta
# etc

or in some other way have static analysis tag the variables, based on
their origins.

> There are two things to notice. In the first example the numbers are easier to
> read: for example, 500nA is easier to read the 5e-7.

This is useful, but doesn't depend on the "A" at the end.

> Second, there is
> information in the units that provides provides useful information. One can
> easily see that the input signal is a current and that the output is a 
> voltage.
> Furthermore, anybody can look at this code and do a simple sanity check on the
> expressions even if they don't understand the system being simulated. They can
> check the units on the input and output expressions to assure that they are 
> all
> consistent.

These two are better served by marking the variables rather than the
literals; in fact, if properly done, the tagging can be verified by a
program, not just a human. (That's what tools like MyPy are aiming to
do.)

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ken Kundert
Here is a fairly typical example that illustrates the usefulness of supporting 
SI scale factors and units in Python.

This is simple simulation code that is used to test a current mirror driving an 
100kOhm resistor ...

Here is some simulation code that uses SI scale factors

for delta in [-500nA, 0, 500nA]:
input = 2.75uA + delta
wait(1us)
expected = 100kOhm*(2.75uA + delta)
tolerance = 2.2mV
fails = check_output(expected, tolerance)
print('%s: I(in)=%rA, measured V(out)=%rV, expected V(out)=%rV, 
diff=%rV.' % (
'FAIL' if fails else 'pass',
input, get_output(), expected, get_output() - expected
))

with the output being:

pass: I(in)=2.25uA, measured V(out)=226.7mV, expected V(out)=225mV, 
diff=1.7mV.
pass: I(in)=2.75uA, measured V(out)=276.8mV, expected V(out)=275mV, 
diff=1.8mV.
FAIL: I(in)=3.25uA, measured V(out)=327.4mV, expected V(out)=325mV, 
diff=2.4mV.

And the same code in Python today ...

for delta in [-5e-7, 0, 5e-7]:
input = 2.75e-6 + delta
wait(1e-6)
expected = 1e5*(2.75e-6 + delta)
tolerance = 2.2e-3
fails = check_output(expected, tolerance)
print('%s: I(in)=%eA, measured V(out)=%eV, expected V(out)=%eV, 
diff=%eV.' % (
'FAIL' if fails else 'pass',
input, get_output(), expected, get_output() - expected
))

with the output being:

pass: I(in)=2.25e-6A, measured V(out)=226.7e-3V, expected V(out)=225e-3V, 
diff=1.7e-3V.
pass: I(in)=2.75e-6A, measured V(out)=276.8e-3V, expected V(out)=275e-3V, 
diff=1.8e-3V.
FAIL: I(in)=3.25e-6A, measured V(out)=327.4e-3V, expected V(out)=325e-3V, 
diff=2.4e-3V.

There are two things to notice. In the first example the numbers are easier to
read: for example, 500nA is easier to read the 5e-7. Second, there is 
information in the units that provides provides useful information. One can 
easily see that the input signal is a current and that the output is a voltage. 
 
Furthermore, anybody can look at this code and do a simple sanity check on the 
expressions even if they don't understand the system being simulated. They can 
check the units on the input and output expressions to assure that they are all 
consistent.

-Ken
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Paul Moore
On 25 August 2016 at 19:02, Ken Kundert  wrote:
> This proposal basically has two parts. One part is that Python should
> naturally support printing real numbers with SI scale factors.  Currently 
> there
> are three formats for printing real number: %f, %d, %g. They all become
> difficult to read for even moderately large or small numbers.  Exponential
> notation is hard for humans to read. That is why SI scale factors have largely
> replaced exponential notation everywhere except in programming.  Adding 
> another
> format for printing real numbers in human readable form seems like a modest
> extension that is long past due in all programming languages. I am asking that
> Python be the leader here. I am sure other languages will pick it up once it 
> is
> implemented in Python.

This part would be easy to implement as a small PyPI module, with a
formatting function siformat(num) -> str. If that proved popular (and
it well might) then there's more of a case for adding it as a language
feature, Maybe as a custom string formatting code, or maybe just as a
standard library function. But without that sort of real-world
experience, it's likely that any proposal will get bogged down in
"what if" theoretical debate.

> The second part is the logical dual to the first: input. People should be able
> to enter numbers in Python using SI scale factors. This means as real 
> literals,
> such as 2.4G, but it should also work with casting, float('2.4G').  Once you
> allow SI scale factors on numbers, the natural tendency is for people to want 
> to
> add units, which is a good thing because it gives important information about
> the number. We should allow it because it improves the code by making it more
> self documenting. Even if the language completely ignores the units, we have
> still gained by allowing the units to be there, just like we gain when we 
> allow
> user to add comments to their code even though the compiler ignores them.

This is much more problematic. Currently, even the long-established
decimal and rational types don't enjoy syntactic support, so I'd be
surprised if SI scale factors got syntax support first. But following
their lead, by (again) starting with a conversion function along the
lines of SI("3k") -> 3000 would be a good test of applicability. It
could easily go in the same module as you're using to trial the string
formatting function above.

I'd expect that a function to do this conversion would be a good way
of thrashing out the more controversial aspects of the proposal -
whether E means "exponent" or "exa", whether M and G get
misinterpreted as computing-style 2**20 and 2**30, etc. Having real
world experience of how to solve these questions would be invaluable
in moving forward with a proposal to add language support.


> Some people have suggested that we take the next step and use the units for
> dimensional analysis, but that is highly problematic because you cannot do
> dimensional analysis unless everything is specified with the correct units, 
> and
> that can be a huge burden for the user. So instead, I am suggesting that we
> provide simple hooks that simply allow access to the units.  That way people 
> can
> build dimensional analysis packages using the units if they felt the need.

Dimensional analysis packages already exist (I believe) and they don't
rely on syntactic support. Any proposal to add something to the
language *really* needs to demonstrate that

1. Those packages are currently suffering from the lack of language support.
2. The proposed change would allow them to resolve existing problems
that they haven't been able to address any other way.
3. The proposed change isn't some sort of "attractive nuisance" for
naive users, leading them to think they can write dimensionally
correct programs *without* using one of the existing packages.

Python has a track record of being open to adding syntactic support if
it demonstrably helps 3rd party tools (for example, the matrix
multiplication operator was added specifically to help the numeric
Python folks address a long-standing issue they had), so this is a
genuine possibility - but such proposals need support from the groups
they are intended to help. At the moment, I'm not even aware of a
particular "dimensional analysis with Python" community, or any
particular "best of breed" package in this area that might lead such a
proposal - and a language change of this nature probably does need
that sort of backing.

That's not to say there's no room for debate here - the proposal is
interesting, and not without precedent (for example Windows Powershell
supports constants of the form 1MB, 1GB - which ironically are
computing-style 2*20 and 2*30 rather than SI-style 10*6 and 10*9). But
there's a pretty high bar for a language change like this, and it's
worth doing the groundwork to avoid wasting a lot of time on something
that's not going to be accepted in its current form.

Hope this helps,
Paul
_

Re: [Python-ideas] Adding optional parameter to shutil.rmtree to not delete root.

2016-08-25 Thread Alexander Belopolsky


> On Aug 25, 2016, at 3:27 PM, Nick Jacobson via Python-ideas 
>  wrote:
> 
> +1 for clear_dir()
> 
> I agree that there's no other obvious meaning that it could have.

+1, but I think "cleardir" would better match naming conventions in the shutil 
module. 

(My personal rule of thumb on the use of underscores in function names is to 
omit them if any name component is abbreviated.  So either spell it out as 
clear_directory or shorten as cleardir.)___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Adding optional parameter to shutil.rmtree to not delete root.

2016-08-25 Thread Nick Jacobson via Python-ideas
+1 for clear_dir()
I agree that there's no other obvious meaning that it could have.
 

On Thursday, August 25, 2016 9:44 AM, Nick Coghlan  
wrote:
 

 On 25 August 2016 at 23:14, Victor Stinner  wrote:
> Maybe add a different function rather add a flag? Something like
> shutil.remove_dir_files().

The typical Python term for the concept would be "clear", giving
shutil.clear_dir(). Like the ".clear()" method on containers, it would
delete the contents, but leave the container itself alone. rmtree()
could then be a thin wrapper around clear_dir() that also deletes the
base directory.

Alternatively, if we wanted to stick with the "rm" prefix, we could
use "shutil.rmcontents()" as the name. The main downside I'd see to
that is that I'd half expect it to work on files as well (truncating
them to a length of zero), while clear_dir() is unambiguous.

Cheers,
Nick.

-- 
Nick Coghlan  |  ncogh...@gmail.com  |  Brisbane, Australia


  ___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Atomic counter / atomic increment

2016-08-25 Thread Guido van Rossum
The only reason I can think of for wanting this simple class in the stdlib
would be that on GIL-free Python implementations you could replace it with
a lock-free version. But I think we'd probably want to rethink a bunch of
other datastructures to be lock-free, and a 3rd party package on PyPI makes
more sense to me than jumping right into the stdlib.

On Thu, Aug 25, 2016 at 11:10 AM, Ben Hoyt  wrote:

>
> As long as Python uses a GIL to protect C level function
>> calls, you can use an iterator for this:
>>
>> import itertools
>> x = itertools.count()
>> ...
>> mycount = next(x)
>>
>
> Yeah, that's a neat hack -- I saw it recommended on StackOverflow, and saw
> it used in the standard library somewhere. I think that's probably okay in
> the *CPython* stdlib, because it's CPython so you know it has the GIL. But
> this wouldn't work in other Python implementations, would it (IronPython
> and Jython don't have a GIL). Or when itertools.count() is implemented in
> pure Python on some system? Seems like it could blow up in someone's face
> when they're least expecting it. I also think using *iter*tools is a pretty
> non-obvious way to get a thread-safe counter.
>
> -Ben
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Atomic counter / atomic increment

2016-08-25 Thread M.-A. Lemburg
On 25.08.2016 20:10, Ben Hoyt wrote:
>> As long as Python uses a GIL to protect C level function
>> calls, you can use an iterator for this:
>>
>> import itertools
>> x = itertools.count()
>> ...
>> mycount = next(x)
>>
> 
> Yeah, that's a neat hack -- I saw it recommended on StackOverflow, and saw
> it used in the standard library somewhere. I think that's probably okay in
> the *CPython* stdlib, because it's CPython so you know it has the GIL. But
> this wouldn't work in other Python implementations, would it (IronPython
> and Jython don't have a GIL). Or when itertools.count() is implemented in
> pure Python on some system? Seems like it could blow up in someone's face
> when they're least expecting it. I also think using *iter*tools is a pretty
> non-obvious way to get a thread-safe counter.

All true.

Having an implementation in threading which hides away the
details would be nice. On CPython using iterators would
certainly be one of the most efficient ways of doing this.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Aug 25 2016)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...   http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...   http://zope.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
  http://www.malemburg.com/

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Atomic counter / atomic increment

2016-08-25 Thread Ben Hoyt
> As long as Python uses a GIL to protect C level function
> calls, you can use an iterator for this:
>
> import itertools
> x = itertools.count()
> ...
> mycount = next(x)
>

Yeah, that's a neat hack -- I saw it recommended on StackOverflow, and saw
it used in the standard library somewhere. I think that's probably okay in
the *CPython* stdlib, because it's CPython so you know it has the GIL. But
this wouldn't work in other Python implementations, would it (IronPython
and Jython don't have a GIL). Or when itertools.count() is implemented in
pure Python on some system? Seems like it could blow up in someone's face
when they're least expecting it. I also think using *iter*tools is a pretty
non-obvious way to get a thread-safe counter.

-Ben
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ken Kundert
All,
This proposal basically has two parts. One part is that Python should 
naturally support printing real numbers with SI scale factors.  Currently there 
are three formats for printing real number: %f, %d, %g. They all become 
difficult to read for even moderately large or small numbers.  Exponential 
notation is hard for humans to read. That is why SI scale factors have largely 
replaced exponential notation everywhere except in programming.  Adding another 
format for printing real numbers in human readable form seems like a modest 
extension that is long past due in all programming languages. I am asking that 
Python be the leader here. I am sure other languages will pick it up once it is 
implemented in Python.

The second part is the logical dual to the first: input. People should be able 
to enter numbers in Python using SI scale factors. This means as real literals, 
such as 2.4G, but it should also work with casting, float('2.4G').  Once you 
allow SI scale factors on numbers, the natural tendency is for people to want 
to 
add units, which is a good thing because it gives important information about 
the number. We should allow it because it improves the code by making it more 
self documenting. Even if the language completely ignores the units, we have 
still gained by allowing the units to be there, just like we gain when we allow 
user to add comments to their code even though the compiler ignores them.

Some people have suggested that we take the next step and use the units for 
dimensional analysis, but that is highly problematic because you cannot do 
dimensional analysis unless everything is specified with the correct units, and 
that can be a huge burden for the user. So instead, I am suggesting that we 
provide simple hooks that simply allow access to the units.  That way people 
can 
build dimensional analysis packages using the units if they felt the need.

-Ken
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Atomic counter / atomic increment

2016-08-25 Thread M.-A. Lemburg
On 25.08.2016 19:31, Ben Hoyt wrote:
> I had to implement a simple atomic counter the other day to count the total
> number of requests processed in a multi-threaded Python web server.
> 
> I was doing a demo of "how cool Python is" to my colleagues, and they were
> generally wowed, but one of the things that made them do a double-take
> (coming mostly from Scala/Java) was that there was no atomic counter in the
> standard library.
> 
> The fact that I and many other folks have implemented such things makes me
> wonder if it should be in the standard library.

As long as Python uses a GIL to protect C level function
calls, you can use an iterator for this:

import itertools
x = itertools.count()
...
mycount = next(x)
...

The trick here is that the CALL_FUNCTION byte code will trigger
the increment of the iterator. Since this is implemented in C,
the GIL will serve as lock on the iterator while it is
being incremented.

With Python 4.0, this will all be different, though :-)

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Aug 25 2016)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...   http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...   http://zope.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   http://www.egenix.com/company/contact/
  http://www.malemburg.com/

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Atomic counter / atomic increment

2016-08-25 Thread Ben Hoyt
I had to implement a simple atomic counter the other day to count the total
number of requests processed in a multi-threaded Python web server.

I was doing a demo of "how cool Python is" to my colleagues, and they were
generally wowed, but one of the things that made them do a double-take
(coming mostly from Scala/Java) was that there was no atomic counter in the
standard library.

The fact that I and many other folks have implemented such things makes me
wonder if it should be in the standard library.

It's pretty simple to implement, basically the handful of lines of code
below (full version on GitHub Gist at
https://gist.github.com/benhoyt/8c8a8d62debe8e5aa5340373f9c509c7):

import threading

class AtomicCounter:
def __init__(self, initial=0):
self.value = initial
self._lock = threading.Lock()

def increment(self, num=1):
with self._lock:
self.value += num
return self.value

And if you just want a one-off and don't want to write a class, it's like
so:

import threading

counter_lock = threading.Lock()
counter = 0

with counter_lock:
counter += 1
value = counter
print(value)

But it could be this much more obvious code:

import threading
counter = threading.AtomicCounter()
value = counter.increment()
print(value)

Thoughts? Would such a class make a good candidate for the standard
library? (API could probably be improved.)

-Ben
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] Adding optional parameter to shutil.rmtree to not delete root.

2016-08-25 Thread Nick Coghlan
On 25 August 2016 at 23:14, Victor Stinner  wrote:
> Maybe add a different function rather add a flag? Something like
> shutil.remove_dir_files().

The typical Python term for the concept would be "clear", giving
shutil.clear_dir(). Like the ".clear()" method on containers, it would
delete the contents, but leave the container itself alone. rmtree()
could then be a thin wrapper around clear_dir() that also deletes the
base directory.

Alternatively, if we wanted to stick with the "rm" prefix, we could
use "shutil.rmcontents()" as the name. The main downside I'd see to
that is that I'd half expect it to work on files as well (truncating
them to a length of zero), while clear_dir() is unambiguous.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP 525: Asynchronous Generators

2016-08-25 Thread Nathaniel Smith
Hi Yury et al,

Apologies for not participating in this discussion before -- unfortunately
I've been dealing with some boring medical issues and haven't been able to
contribute as much as early as I should have... But I do have two concerns,
one minor and one not.

Minor comment: this is purely an aesthetic issue, but the PEP should
probably have some discussion of the choice between "async yield" vs bare
"yield" as the syntax. Arguments for "async yield" would be consistency
with the other async syntax ("async for" etc.) and potentially reduced
confusion about how inside an async def, "await" yields, and "yield"
yields, but in totally different senses. Arguments for "yield" would be
terseness, I guess. Probably this is just something for Guido to pick...

Major issue: I have serious concerns about the whole async finalizer design.

1) there is a very general problem of how to handle cleanup in async code,
which isn't specific to async generators at all -- really any object that
holds resources that need async cleanup has exactly the same issue. So the
special purpose solution here makes me uncomfortable.

2) our understanding of this problem (resource cleanup in async code) is
*really* immature. You can check the async-sig archives for some discussion
-- I think it's safe to say that all the "experts" are extremely confused
about this problem's shape/scope/best practices. I guess probably there are
10ish people who kind of understand the problem and 0 people who deeply
understand it. (I was working on at least writing something up try and make
the issue more accessible, but have not managed yet, which I feel bad about
:-(.)  But given this, trying to freeze one particular strategy into the
language on the 3.6 timeline raises a red flag for me.

3) specifically, I don't understand how the proposed solution in the pep
can work reliably in the presence of non-prompt garbage collection (e.g. in
the presence of cycles on cpython, or on pypy in general). What happens
when the async generator object gets collected after the event loop exits?
We could require event loops to force a full collection before exiting, but
this is a rather uncomfortable coupling! (Do all python implementations
even have a way to force a guaranteed-to-collect-ALL-garbage collection?
What are the performance implications of async code triggering such full
collections at inopportune times?) And even this didn't necessarily solve
the problem, since async generators frames could still be "live" from the
GC point of view, even if we know that their resources should be released.
(E.g. consider an exception thrown from an async gen that propagates out of
the event loop, so the event loop exits while the async gen's frame is
pinned by the traceback object.)

Python in general has been moving towards more explicit/deterministic
cleanup through "with" statements, and I think this is great. My feeling is
that we should try to continue in this vein, rather than jumping through
hoops to let people get away with sloppy coding that relies on __del__ and
usually works except when it doesn't.

For example, what if we added an optional __abreak__ coroutine to the async
iterator protocol, with the semantics that an "async for" will always
either iterate to exhaustion, or else call __abreak__, i.e.

# new style code
async for x in aiter:
...

becomes sugar for

# 3.5 style code
try:
async for x in aiter:
...
finally:
if for_loop_exited_early and hasattr(aiter, "___abreak__"):
await aiter.__abreak__(...)

Basically the idea here is that currently, what we should *really* be doing
if we care about reliable+deterministic resource cleanup is never writing
bare "for" loops but instead always writing

async with ... as aiter:
async for ... in aiter:
...

But that's really tiresome and no one does it, so let's build the "with"
into the for loop.

Of course there are cases where you want to reuse a single iterator object
in multiple loops; this would look like:

# doing something clever, so we have to explicitly take charge of cleanup
ourselves:
async with ... as aiter:
# read header (= first non-comment line)
async for header in iterlib.unclosing(aiter):
if not header.startswith("#"):
break
# continue with same iterator to read body
 async for line in iterlib.unclosing(aiter):
 ...

where iterlib.unclosing returns a simple proxy object that passes through
__anext__ and friends but swallows __abreak__ to make it a no-op.

Or maybe not, this isn't a fully worked out proposal :-). My main concern
is that we don't rush to make a decision for 3.6, skip the hard work of
considering different designs, and end up with something we regret in
retrospect.

Some other options to consider:
- add async generators to 3.6, but defer the full cleanup discussion for
now -- so in 3.6 people will have to use "async with aclosing(aiter): ..."
or whatever, but at least we can start getting experience w

Re: [Python-ideas] Adding optional parameter to shutil.rmtree to not delete root.

2016-08-25 Thread Victor Stinner
Maybe add a different function rather add a flag? Something like
shutil.remove_dir_files().

Victor

Le 25 août 2016 4:32 AM, "Nick Jacobson via Python-ideas" <
python-ideas@python.org> a écrit :

> I've been finding that a common scenario is where I want to remove
> everything in a directory, but leave the (empty) root directory behind, not
> removing it.
>
> So for example, if I have a directory C:\foo and it contains subdirectory
> C:\foo\bar and file C:\foo\myfile.txt, and I want to remove the
> subdirectory (and everything in it) and file, leaving only C:\foo behind.
>
> (This is useful e.g. when the root directory has special permissions, so
> it wouldn't be so simple to remove it and recreate it again.)
>
> A number of ways to do this have been offered here:
> http://stackoverflow.com/questions/185936/delete-folder-contents-in-python
>
> But it'd be simpler if there were an optional parameter added to
> shutil.rmtree, called removeroot. It would default to true so as to not
> break any backward compatibility. If it's set to false, then it leaves the
> root directory in place.
>
> Thanks,
>
> Nick
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Chris Angelico
On Thu, Aug 25, 2016 at 9:24 PM, Steven D'Aprano  wrote:
> If I try to add 30 feet to 6 metres and get either 36 feet or 36 metres,
> then your unit system is *worse* than useless, it is actively harmful. I
> don't mind if I get 15.144 metres or 49.685039 feet or even
> 5.0514947e-08 lightseconds, but I better not get 36 of anything.
>

To be fair, under the OP's proposal, you wouldn't get 36 *of anything*
- you'd just get the bare number 36. So it's not worse than useless,
just useless.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Steven D'Aprano
On Wed, Aug 24, 2016 at 09:28:03PM -0700, Ken Kundert wrote:
> All,
> I propose that support for SI scale factors be added to Python.

I think there's something to be said for these ideas, but you are 
combining multiple ideas into one suggestion.

First off, units with quantities: I think that is an excellent idea, but 
one best supported by a proper unit library that supports more than just 
SI units. There are already a few of those. See for example this 
Stackoverflow question:

http://stackoverflow.com/questions/2125076/unit-conversion-in-python

Sympy also does dimensional analysis:

http://docs.sympy.org/latest/modules/physics/unitsystems/examples.html

Google for more.

If I try to add 30 feet to 6 metres and get either 36 feet or 36 metres, 
then your unit system is *worse* than useless, it is actively harmful. I 
don't mind if I get 15.144 metres or 49.685039 feet or even 
5.0514947e-08 lightseconds, but I better not get 36 of anything.

And likewise for adding 30 kilograms to 6 metres. That has to be an 
error, or this system will just be an attractive nuisance, luring people 
into a false sense of security while actually not protecting them from 
dimensional and unit conversion bugs at all.

So I am an extremely strong -1 to the suggestion that we allow unit 
suffixes on numeric quantities but treat them as a no-op.

Should Python support a unit conversion library in the standard library? 
I think perhaps not -- there's plenty of competition in the unit 
conversion ecosystem, both in Python and out of it, and I don't think 
that there's any one library that is both sufficiently "best of breed" 
enough and stable enough to put into the std lib. Remember that the std 
lib is where good libraries go to die: once they hit the std lib, 
stability becomes much, much more important than new features.

But if you wish to argue differently, I'll be willing to hear your 
suggestions.

Now, on to the second part of the suggestion: support for SI prefixes. I 
think this is simple enough, and useful enough, that we could make it 
part of the std lib -- and possibly even in 3.6 (possibly under a 
provisional basis). The library could be dead simple:

# prefixes.py
# Usage:
# from prefixes import *
# x = 123*M  # like 12300
# y = 45*Ki  # like 45*1024

# SI unit prefixes
# http://physics.nist.gov/cuu/Units/prefixes.html
Y = yotta = 10**24
Z = zetta = 10**21
[...]
k = kilo = 10**3
K = k  # not strictly an SI prefix, but common enough to allow it
m = milli = 1e-3
µ = micro = 1e-6  # A minor PEP-8 violation, but (I hope) forgiveable.
u = µ  # not really an SI prefix, but very common
# etc


# International Electrotechnical Commission (IEC) binary prefixes
# http://physics.nist.gov/cuu/Units/binary.html
Ki = kibi = 1024
Mi = mibi = 1024**2
Gi = 1024**3
# etc


That's practically it.

Of course, this simple implementation would allow usage that was a 
technical violation of the SI system:

x = 45*M*µ*Ki

as well as usage that is semantically meaningless:

x = 45 + M

but those abuses are best covered by "consenting adults". (In other 
words, if you don't like it, don't do it.) And it wouldn't support the 
obsolete binary prefixes that use SI symbols with binary values (K=1024, 
M=1024**2, etc), but that's a good thing. They're an abomination that 
need to die as soon as possible.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread David Mertz
I have trouble imagining situations in which SI units would help
readability over scientific notation. On the one hand reading it always
involves mental conversion to the exponents, so this is just an extra step.
E.g. this equality is evident at a glance:

1e3 * 1e6 * 1e-9 == 1

This one would take me a few seconds, and I'd need to run it twice in my
head to make sure I wasn't doing it wrong:

1k * 1M * 1n == 1

The more complicated the expression, the bigger the cognitive advantage for
numeric exponents.

I think the OP is drawn astray by the utility of domain specific familiar
dimensional units. 1MeV means something in a domain. So does 1ps. Or 1km.
But really it's the units not the exponent that are helping us (plus
knowing that our specific domain deals with dimensional quantities of a
certain scale).

But even past the ease of mental arithmetic, I don't see why one would use
literals very often to start with. If they are constants, give them a
better name! If they are variables, likewise. If it helps your domain, add
the units to the *names*, e.g.:

lightyear_m = 9.5e15
galaxy_radians = calculate_arc()
dist_m = lighyear_m * galaxy_radians * arc_len

That looks a lot clearer to me than sticking together raw numbers, however
spelled.

On Aug 25, 2016 2:56 AM, "Joao S. O. Bueno"  wrote:

> On 25 August 2016 at 06:06, Paul Moore  wrote:
> > On 25 August 2016 at 09:54, Ken Kundert 
> wrote:
> >> 1G -> 1e+09
> >> 1M -> 1e+06
> >> 1k -> 1e+03
> >
> > While these suffixes are suitable for a scientific context, in a
> > computing context, 1k=1024, 1M=1024*1024 and 1G=1024*1024*1024 make
> > just as much, if not more, sense (and yes, I'm aware of Gigabyte vs
> > Gibibyte).
> >
> > If "1M" were a legal Python literal,. I would expect a lot of
> > confusion over what it meant - to the extent that it would hurt
> > readability badly.
> > Paul
>
>
> So, the idea of adding fixed sufixes to the core language I regard as
> awful - due to these and other considerations  -
> But maybe, oen thign to think about is about "operatorless"
> multiplication - jsut puting two tokens side by side, which currently
> yieds a Syntax Error could call `__mul__`
> (or a new `__direct_mul__` method on the second operator.
>
> That would enable a lot of interesting things in already existing
> packages like SymPy - and would allow a "physics measurements"
> packages that would take care of the ideas on the starting of the
> thread.
>
> I certainly would be more confortable for mathematicians and other
> people using Python in interactive environments such as iPython
> notebooks.
>
> But other than having this as a multiplication, I am against the whole
> thing.
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Chris Angelico
On Thu, Aug 25, 2016 at 6:19 PM, Ken Kundert
 wrote:
>> So you can have 1000mm or 0.001km but not 1m?
>
> If the scale factor is optional, then numbers like 1m are problematic because
> the m can represent either milli or meter. This is resolved by requiring the
> scale factor and defining a unity scale factor. I propose '_'. So 1m 
> represents
> milli and 1_m represents 1 meter.

This could also be hashed out using a constructor-only API. You'll
probably want to avoid '_', as it's just been added as a comma
separator for numeric literals.

>> If units are retained, what you have is no longer a simple number, but
>> a value with a unit, and is a quite different beast. (For instance,
>> addition would have to cope with unit mismatches (probably by throwing
>> an error), and multiplication would have to combine the units (length
>> * length = area).) That would be a huge new feature.
>
> Indeed. I am not proposing that anything be done with the units other than
> possibly retain them for later output. Doing dimensional analysis on 
> expressions
> would be a huge burden both for those implementing the language and for those
> using them in a program.  Just allowing the units to be present, even it not
> retained, is a big advantage because it can bring a great deal of clarity to 
> the
> meaning of the number. For example, even if the language does not flag an 
> error
> when a user writes:
>
> vdiff = 1mV - 30uA
>
> the person that wrote the line will generally see it as a problem and fix it.

How often do you do arithmetic on literals like that? More likely,
what you'd do is tag your variable names, so it'll be something like:

input_volts = 1m#V
inefficiency = 30u#A
vdiff = input_volts - inefficiency

> In my experience, providing units is the most efficient form of documentation
> available in numerical programming in the sense that one or two additional
> characters can often clarify otherwise very confusing code.
>
> My feeling is that retaining the units on real literals is of little value if
> you don't also extend the real variable type to hold units, or to create 
> another
> variable type that would carry the units. Extending reals does not seem like
> a good idea, but creating a new type, quantity, seems practical. In this case,
> the units would be rather ephemeral in that they would not survive any
> operation.  Thus, the result of an operation between a quantity and either
> a integer, real or quantity would always be a real, meaning that the units are
> lost.  In this way, units are very light-weight and only really serve as
> documentation (for both programmers and end users).
>
> But this idea of retaining the units is the least important aspect of this
> proposal. The important aspects are:
> 1. It allows numbers to be entered in a clean form that is easy to type and 
> easy
>to interpret
> 2. It allows numbers to be output in a clean form that is easy to interpret.
> 3. In many cases it allows units to be inserted into the code in a very 
> natural
>and clean way to improve the clarity of the code.

The decimal.Decimal and fractions.Fractions types have no syntactic
support. I would suggest imitating their styles initially, sorting out
all the details of which characters mean what, and appealing for
syntax once it's all settled - otherwise, it's too likely that
something will end up being baked into the language half-baked, if
that makes any sense.

>> Question, though: What happens with exa-? Currently, if the parser
>> sees "1E", it'll expect to see another number, eg 1E+1 == 10.0. Will
>> this double meaning cause confusion?
>
> Oh, I did not see this. Both SPICE and Verilog limit the scale factors to the
> common ones (T, G, M, k, _, m, u, n, p, f, a). I work in electrical 
> engineering,
> and in that domain exa never comes up. My suggestion would be to limit 
> ourselves
> to the common scale factors as most people know them. Using P, E, Z, Y, z, and
> y often actually works against us as most people are not familiar with them 
> and
> so cannot interpret them easily.

That seems pretty reasonable. At very least, it'd be something that
can be extended later. Even femto and atto are rare enough that they
could be dropped if necessary (pico too, perhaps).

Easy scaling seems general enough to include in the language. Tagging
numbers with units, though, feels like the domain of a third-party
library. Maybe I'm wrong.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Joao S. O. Bueno
On 25 August 2016 at 06:06, Paul Moore  wrote:
> On 25 August 2016 at 09:54, Ken Kundert  wrote:
>> 1G -> 1e+09
>> 1M -> 1e+06
>> 1k -> 1e+03
>
> While these suffixes are suitable for a scientific context, in a
> computing context, 1k=1024, 1M=1024*1024 and 1G=1024*1024*1024 make
> just as much, if not more, sense (and yes, I'm aware of Gigabyte vs
> Gibibyte).
>
> If "1M" were a legal Python literal,. I would expect a lot of
> confusion over what it meant - to the extent that it would hurt
> readability badly.
> Paul


So, the idea of adding fixed sufixes to the core language I regard as
awful - due to these and other considerations  -
But maybe, oen thign to think about is about "operatorless"
multiplication - jsut puting two tokens side by side, which currently
yieds a Syntax Error could call `__mul__`
(or a new `__direct_mul__` method on the second operator.

That would enable a lot of interesting things in already existing
packages like SymPy - and would allow a "physics measurements"
packages that would take care of the ideas on the starting of the
thread.

I certainly would be more confortable for mathematicians and other
people using Python in interactive environments such as iPython
notebooks.

But other than having this as a multiplication, I am against the whole thing.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Paul Moore
On 25 August 2016 at 09:54, Ken Kundert  wrote:
> 1G -> 1e+09
> 1M -> 1e+06
> 1k -> 1e+03

While these suffixes are suitable for a scientific context, in a
computing context, 1k=1024, 1M=1024*1024 and 1G=1024*1024*1024 make
just as much, if not more, sense (and yes, I'm aware of Gigabyte vs
Gibibyte).

If "1M" were a legal Python literal,. I would expect a lot of
confusion over what it meant - to the extent that it would hurt
readability badly.
Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ken Kundert
> Question, though: What happens with exa-? Currently, if the parser
> sees "1E", it'll expect to see another number, eg 1E+1 == 10.0. Will
> this double meaning cause confusion?

Allow me to refine my answer to this question ...

Yes, that is definitely problematic. I see two possible solutions.
1. Limit ourselves to the common scale factors:
 T, G, M, k, _, m, u, n, p, f, a
2. Or accept X in lieu of E. After all, the e is silent anyway.  Thus, on input 
   we accept ...

1Y -> 1e+24
1Z -> 1e+21
 -> 1X -> 1e+18 <- only difference
1P -> 1e+15
1T -> 1e+12
1G -> 1e+09
1M -> 1e+06
1k -> 1e+03
1_ -> 1e+00
1m -> 1e-03
1u -> 1e-06
1n -> 1e-09
1p -> 1e-12
1f -> 1e-15
1a -> 1e-18
1z -> 1e-21
1y -> 1e-24

But on output we use ...

1Y -> 1e+24  optional
1Z -> 1e+21  optional
 -> 1E -> 1e+18  optional
1P -> 1e+15  optional
1T -> 1e+12
1G -> 1e+09
1M -> 1e+06
1k -> 1e+03
1_ -> 1e+00
1m -> 1e-03
1u -> 1e-06
1n -> 1e-09
1p -> 1e-12
1f -> 1e-15
1a -> 1e-18
1z -> 1e-21  optional
1y -> 1e-24  optional

The optional scale factors are unfamiliar to most people, and if used might 
result in harder to read numbers. So I propose that '%r' only outputs the 
common 
scale factors, and %R outputs all the scale factors. Or we can use '#' in the 
format string to indicate the 'alternate' form should be used, in this case 
'alternate' means that the extended set of scale factors should be used.

-Ken
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] SI scale factors in Python

2016-08-25 Thread Ken Kundert
> So you can have 1000mm or 0.001km but not 1m?

If the scale factor is optional, then numbers like 1m are problematic because 
the m can represent either milli or meter. This is resolved by requiring the 
scale factor and defining a unity scale factor. I propose '_'. So 1m represents 
milli and 1_m represents 1 meter.


> If units are retained, what you have is no longer a simple number, but
> a value with a unit, and is a quite different beast. (For instance,
> addition would have to cope with unit mismatches (probably by throwing
> an error), and multiplication would have to combine the units (length
> * length = area).) That would be a huge new feature.

Indeed. I am not proposing that anything be done with the units other than 
possibly retain them for later output. Doing dimensional analysis on 
expressions 
would be a huge burden both for those implementing the language and for those 
using them in a program.  Just allowing the units to be present, even it not 
retained, is a big advantage because it can bring a great deal of clarity to 
the 
meaning of the number. For example, even if the language does not flag an error 
when a user writes:

vdiff = 1mV - 30uA

the person that wrote the line will generally see it as a problem and fix it.

In my experience, providing units is the most efficient form of documentation 
available in numerical programming in the sense that one or two additional 
characters can often clarify otherwise very confusing code.

My feeling is that retaining the units on real literals is of little value if 
you don't also extend the real variable type to hold units, or to create 
another 
variable type that would carry the units. Extending reals does not seem like 
a good idea, but creating a new type, quantity, seems practical. In this case, 
the units would be rather ephemeral in that they would not survive any 
operation.  Thus, the result of an operation between a quantity and either 
a integer, real or quantity would always be a real, meaning that the units are 
lost.  In this way, units are very light-weight and only really serve as 
documentation (for both programmers and end users).

But this idea of retaining the units is the least important aspect of this 
proposal. The important aspects are:
1. It allows numbers to be entered in a clean form that is easy to type and 
easy 
   to interpret
2. It allows numbers to be output in a clean form that is easy to interpret.
3. In many cases it allows units to be inserted into the code in a very natural 
   and clean way to improve the clarity of the code.

> Question, though: What happens with exa-? Currently, if the parser
> sees "1E", it'll expect to see another number, eg 1E+1 == 10.0. Will
> this double meaning cause confusion?

Oh, I did not see this. Both SPICE and Verilog limit the scale factors to the 
common ones (T, G, M, k, _, m, u, n, p, f, a). I work in electrical 
engineering, 
and in that domain exa never comes up. My suggestion would be to limit 
ourselves 
to the common scale factors as most people know them. Using P, E, Z, Y, z, and 
y often actually works against us as most people are not familiar with them and 
so cannot interpret them easily.

-Ken
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/