> Date: Thu, 7 Jun 2018 12:33:29 +0000
> From: Robert Vanden Eynde <robertvandeneynde(a)hotmail.com>
> To: python-ideas <python-ideas(a)python.org>
> Subject: [Python-ideas] Trigonometry in degrees
> Message-ID:
> >
> I suggest adding degrees version of the trigonometric functions in the math module.
>
> - Useful in Teaching and replacing calculators by python, importing something is seen by the young students much more easy than to define a function.
I agree that degrees are useful for teaching. They are also very
useful for graphics
programming, especially with my favourite OpenGL API. But I think that
the use of
radians in programming language APIs is more prevalent, so the initial advantage
of easy learning will be outweighed by the long term inconvenience of
adjusting to
what everyone else is doing.
Writing degrees(x) and radians(x) is a little inconvenient, but it
does make it clear
what units are being used. And even if your proposal is adopted, there
is still going
to be a lot of code around that uses the older math routines. With the
current API
it is a least safe to assume that angles are radians unless stated otherwise.
> - Special values could be treated, aka when the angle is a multiple of 90, young students are often surprise to see that cos(pi/2) != 0
>
> Testing for a special value Isn't very costly (x % 90 == 0) but it could be pointed out that there is a small overhead using the "degrees" equivalent of trig function because of the radians to degrees conversion And the special values testing.
Not just young students :-) I agree with this, but I would prefer the
check to be in
the implementation of the existing functions as well. Any sin/cos very
close to 0
becomes 0, any close to 1 becomes 1.
> - Standard names will be chosen so that everyone will use the same name convention. I suggest adding a "d" like sind, cosd, tand, acosd, asind, atand, atan2d.
Not "d". In the OpenGL 3D API, and many 3D languages/APIs since, appending "d"
means "double precision". It's even sort of implied by the C math
library which has
sinf and friends for single precision.
>
> Creating a new package like 'from math.degrees import cos' however I would not recommend that because "cos" in the source code would mean to lookup the import to know if it's in degrees or radians (and that leads to very filthy bugs). Also "degrees" is already so the name would have to change the name of the package.
Agree, not a good idea.
--
cheers,
Hugh Fisher
This idea was proposed to me at the core sprints last month by Larry
Hastings. I've discussed it with a few people, who seem generally
positive about it, and we've tweaked it a little bit. I've spent some
time implementing it, and I think it's doable. I thought I'd post it
here for any additional feedback.
Here’s the idea: for f-strings, we add a !d conversion operator, which
is superficially similar to !s, !r, and !a. The meaning of !d is:
produce the text of the expression (not its value!), followed by an
equal sign, followed by the repr of the value of the expression. So:
value = 10
s = 'a string!'
print(f'{value!d}')
print(f'next: {value+1!d}')
print(f'{s!d}')
produces:
value=10
next: value+1=11
s='a string!'
I’m not proposing this for str.format(). It would only really make sense
for named arguments, and I don’t think
print('{value!d}'.format(value=value) is much of a win.
The result is a string, so if you really wanted to, you could use a
string formatting spec. So:
print(f'*{value!d:^20}*'
would produce:
* value=10 *
Although I don’t think that would be very useful in general.
The mnemonic is !d for “debugging”. I’d wanted to use !=, because
there’s an equal sign involved in the result, but = is the one character
that can’t be used after ! (it’s “not equal” in expressions, and
f-strings look specifically for that case). I also mentioned !!, but I
think I prefer !d as being less confusing.
This would be used in debugging print statements, that currently end up
looking like:
print(f'value={value!r}')
and would now be:
print(f'{value!d}')
There have been discussions about ways to specify str() vs. repr(),
using characters other than '=', adding spaces, etc. But they all end up
over-complicating what should be a simple tool, not a Swiss Army knife.
Thoughts?
Eric
I'd like to suggest what I think would be a simple addition to `def` and
`class` blocks. I don't know if calling those "Assignment Blocks" is
accurate, but I just mean to refer to block syntaxes that assign to a name.
Anyway, I propose a combined return-def structure, and optionally also
allowing a return-class version. Omitting the name would be allowable, as
well.
This would only apply to a `def` or `class` statement made as the last part
of the function body, of course.
def ignore_exc(exc_type):
return def (func):
@wraps(func)
return def (*args, **kwargs):
try:
return func(*args, **kwargs)
except exc_type:
pass
Thanks for considering and for any comments, thoughts, or feedback on the
idea!
Hi,
I suggest to allow defining awaitable classes in terms of `async def`-s:
class FeynmanAlgorithm:
async def __await__(self):
await self.write_down_the_problem()
await self.think_real_hard()
await self.write_down_the_solution()
IMO, this would be the "one obvious way" for anyone who's using it for
anything other than defining low-level primitives. It is also easier to
teach and and more consistent with how you can define iterables - where
`__iter__` is explicitly allowed to be defined in terms of generator
function (which I would consider the equivalent to the async defs of
awaitables).
The implementation could be as easy as calling `__await__` as long as
the returned object is not an iterator instead of going straight to
TypeError.
Currently `__await__` must return an iterator, and one has to define a
separate function or method (or use a decorator) to do the same, e.g.:
class FeynmanAlgorithm:
def __await__(self):
return self.perform().__await__()
async def perform(self):
[...]
IMO, this is far from obvious and has been subject to a few subtle
differences between python versions. For example:
import asyncio
class Waiter:
def __await__(self):
return asyncio.sleep(1).__await__()
asyncio.get_event_loop().run_until_complete(
asyncio.ensure_future(Waiter()))
works fine on python 3.7 but fails on python 3.5 with "AttributeError:
'generator' object has no attribute '__await__'" because some awaitables
are implemented using generator type coroutines.
Adding to potential confusion, `async def __await__` seems to be work in
certain situations:
import asyncio
class Waiter:
async def __await__(self):
await asyncio.sleep(1)
# this works on py3.7:
asyncio.get_event_loop().run_until_complete(
asyncio.ensure_future(Waiter()))
but, awaiting them in a coroutine context causes an error:
async def foo():
await Waiter()
# "TypeError: __await__() returned a coroutine":
asyncio.get_event_loop().run_until_complete(
asyncio.ensure_future(foo()))
In earlier python versions (at least up to 3.5) the situation is
somewhat reversed. The `yield from` analogue of the above used to work
in coroutine context:
import asyncio
class Waiter:
def __iter__(self):
yield from asyncio.sleep(1)
@asyncio.coroutine
def foo():
yield from Waiter()
# works on py3.5:
asyncio.get_event_loop().run_until_complete(
asyncio.ensure_future(foo()))
While the following doesn't:
# "TypeError: An asyncio.Future, a coroutine or an awaitable is
required":
asyncio.get_event_loop().run_until_complete(
asyncio.ensure_future(Waiter()))
What do you think?
Kind regards,
Thomas
See also:
https://stackoverflow.com/questions/33409888/how-can-i-await-inside-future-…
Hello,
I'd like to propose an update to PEP8. Indeed, the 80 characters per line
guideline is, I feel, outdated.
I understand the need for it, back when monitors were small, and everyone
coded on terminals, but nowadays, I feel like that guideline is more of a
hinderance, and that it promotes poor code.
Indeed, people abiding by this rule tend to choose shorter variable names,
reduce the amount of indentation, and other tricks to just keep the
character count under 80. I think a 100 or even 120 suggested characters
per line count is much more realistic by today's standards. It still allow
for the code to be completely displayed, even on just half of a screen.
I've started this thread, because I think long string literals are
somewhat special, and may have an easy resolution.
According to PEP 8 a good reason to ignore the line-length (or any
other) guideline is that "applying the guideline would make the code
less readable, even for someone who is used to reading code that
follows this PEP."
PEP 8 also says "Limit all lines to a maximum of 79 characters."
So perhaps it is enough, for long string literals, to add a note to
PEP 8: When sensible to do so, lines containing a long string literal
can exceed this length.
It might also help to add to PEP 8 some Programming Recommendations
for Long String Literals. (PEP 8 already has recommendations for
Function and Variable Annotations.)
Finally, tools such as pep8 and pylint would need some changes, to
treat differently lines that contain a long string constant.
--
Jonathan
Hi!
To help automatic document generators and static type checkers reason more
about the code, the possible side-effects and raised exceptions could also
be annotated in a standardized way.
I'll let some example code talk on my behalf. Here's a simple decorator for
annotating exceptions:
In [1]: import typing as t
In [2]: def raises(exc: Exception) -> t.Callable:
...: def decorator(fn: t.Callable) -> t.Callable:
...: fn.__annotations__["__raises__"] = exc
...: return fn
...: return decorator
...:
In [3]: @raises(ValueError)
...: def hello_if_5(x: int) -> None:
...: if x != 5:
...: raise ValueError("number other than 5 given")
...: print("Hello!")
...:
In [4]: hello_if_5.__annotations__
Out[4]: {'x': int, 'return': None, '__raises__': ValueError}
In [5]: hello_if_5(1)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-5-7fb1d79ce3f4> in <module>
----> 1 hello_if_5(1)
<ipython-input-3-1084d197ce1b> in hello_if_5(x)
2 def hello_if_5(x: int) -> None:
3 if x != 5:
----> 4 raise ValueError("number other than 5 given")
5 print("Hello!")
6
ValueError: number other than 5 given
In [6]: hello_if_5(5)
Hello!
In [7]:
and here's a simple decorator for annotating side-effects:
In [1]: import typing as t
In [2]: def side_effect(has_side_effect: bool) -> t.Callable:
...: def decorator(fn: t.Callable) -> t.Callable:
...: fn.__annotations__["__side_effect__"] = has_side_effect
...: return fn
...: return decorator
...:
In [3]: a = 10
In [4]: @side_effect(True)
...: def change_a(val: int) -> None:
...: global a
...: a = val
...:
In [5]: change_a.__annotations__
Out[5]: {'val': int, 'return': None, '__side_effect__': True}
In [6]: change_a(100)
In [7]: a
Out[7]: 100
In [8]: @side_effect(True)
...: def mutate_list(items: t.List) -> None:
...: items.append("new item")
...:
In [9]: mutate_list.__annotations__
Out[9]: {'items': typing.List, 'return': None, '__side_effect__': True}
In [10]: l = ["old item"]
In [11]: mutate_list(l)
In [12]: l
Out[12]: ['old item', 'new item']
In [13]:
The example implementations have some obvious limitations, such as only
allowing one error type. What do you think of the idea in general? Do you
feel this is something that could be included in Python? typing would
probably be a good module to store such decorators, I guess…
Miikka Salminen
miikka.salminen(a)gmail.com
Dear all,
Who might also be interested in setting up a project that supports localization for Unicode block description and character description.
Translations are available from https://github.com/unicode-table/unicode-table-data/tree/master/loc
<https://github.com/unicode-table/unicode-table-data/tree/master/loc> If possible, use a gettext approach similar to https://pypi.org/project/pycountry/ <https://pypi.org/project/pycountry/>
Implementing this feature will allow users to read Unicode descriptions in their own language, other than English.
For example, now is possible only in English:
from unicodedata import name
print(name('ß'))
LATIN SMALL LETTER SHARP S
So unicodedata could provide a way to translate LATIN SMALL LETTER SHARP S to e.g. German with:
from unicodedata import name
from unicodedata_l10n import LOCALED_DIR
from gettext import translation
german = translation('UnicodeData' LOCALED_DIR, languages=['de'])
german.install()
print(_(name('ß')))
LATEINISCHER KLEINBUCHSTABE SCHARFES S
and something similar for unicodedata.category
Best,
Pander
I agree that 80 columns produces too much artificial wrapping that is not
more readable and harder to maintain. To that point see the bug in Chris
Barker's email :)
raise ValueError(f"Expected woozle to be between"
"{self.min_woozle} and {self.max_woozle}")
The missing f prefix on the second row is hard to spot.
In my work we have settled on 100 characters. It's below the practical
limitation where code review tools such as github pull request falls apart
and still easily allows side by side editing.
On Thu, Feb 21, 2019 at 3:20 PM <python-ideas-request(a)python.org> wrote:
> Send Python-ideas mailing list submissions to
> python-ideas(a)python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://mail.python.org/mailman/listinfo/python-ideas
> or, via email, send a message with subject or body 'help' to
> python-ideas-request(a)python.org
>
> You can reach the person managing the list at
> python-ideas-owner(a)python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Python-ideas digest..."
> Today's Topics:
>
> 1. Re: PEP 8 update on line length (pylang)
> 2. Re: PEP 8 update on line length (Chris Barker)
> 3. Re: Type hints for functions with side-effects and for
> functions raising exceptions (Juancarlo A?ez)
>
>
>
> ---------- Forwarded message ----------
> From: pylang <pylang3(a)gmail.com>
> To: Mike Miller <python-ideas(a)mgmiller.net>
> Cc: "python-ideas(a)python.org" <python-ideas(a)python.org>
> Bcc:
> Date: Thu, 21 Feb 2019 17:32:12 -0500
> Subject: Re: [Python-ideas] PEP 8 update on line length
> Some feedback:
>
> I code on a 13.5 inch laptop. I split my screen between my browser on the
> left half and editor on the right half of the screen.
> The 80 character suggestion has been helpful to me in reading code.
> Otherwise I'd use up time with random horizontal scrolling.
>
> On Thu, Feb 21, 2019 at 4:11 PM Mike Miller <python-ideas(a)mgmiller.net>
> wrote:
>
>>
>> On 2/21/19 10:53 AM, Paul Ferrell wrote:
>> > I think the solution is for everyone to rotate their widescreen
>> monitors 90°
>> > into a really tall portrait mode. :)
>>
>> Yep, that's what I do, but would prefer a squarer monitor so I could get
>> two
>> windows side by side on that one also. My old 1600x1200 4:3 in portrait
>> allowed
>> that comfortably. 16:10 might.
>>
>> -Mike
>>
>> _______________________________________________
>> Python-ideas mailing list
>> Python-ideas(a)python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
>
> ---------- Forwarded message ----------
> From: Chris Barker <chris.barker(a)noaa.gov>
> To: Python-Ideas <python-ideas(a)python.org>
> Cc:
> Bcc:
> Date: Thu, 21 Feb 2019 17:06:51 -0800
> Subject: Re: [Python-ideas] PEP 8 update on line length
> On Thu, Feb 21, 2019 at 12:01 PM Raymond Hettinger <
> raymond.hettinger(a)gmail.com> wrote:
>
>> I concur. We now put expressions in f-strings and have assignment
>> expressions that easily spill over 80 characters if one uses all but the
>> most compact variable names. Comprehensions tend to make expressions
>> longer. Queries and filters in Pandas also easily spill over. The 80
>> character limit pre-dates these evolutions of the language.
>>
>
>
>> In particular, the case where I most want to let people run with long
>> lines is in forming messages to be displayed to a user.
>
>
> I agree here -- and if it's messages (also comments - a twenty char
> comment after a 70 char line should be fine!) then it's not part of the
> logic of the code -- so not as bd if there is some spill off the screen for
> those folks that do code on tablets ;-) Actually for me, the issue s comes
> up when I'm showing code on a projector -- I use a huge font so folks in
> the back can see)
>
>
>> class Frabawidget:
>> ...
>> @wozzle.setter
>> def (self, woozle):
>> if not (self.min_woozle < woozle < self.max_woozle):
>> raise ValueError(f"Expected woozle to be between
>> {self.min_woozle} and {self.max_woozle}")
>> self._wozzle = normalize(woozle)
>>
>
> That's 103 chars long -- and very readable. But, is this that much worse?
>
> class Frabawidget:
> ...
> @wozzle.setter
> def (self, woozle):
> if not (self.min_woozle < woozle < self.max_woozle):
> raise ValueError(f"Expected woozle to be between"
> "{self.min_woozle} and {self.max_woozle}")
> self._wozzle = normalize(woozle)
>
> (it IS harder to write, that's for sure)
>
> In doing code reviews, I see many fewer atrocities from long lines than I
>> do from weird line-wraps and from variable names that have been
>> over-shortened to make the line fit in 80 characters. To avoid these
>> issues, my clients typically set their line limits at 90 or 100
>
>
> and yet the above example was 103 ... you do need a limit somewhere.
>
> I actually would really like the "limit" to depend on what the line is --
> that is, it's OK to go longer if it's essentially text -- message to the
> user, comment, etc., rather than part of the code logic.
>
> In fact, now that I write that, I think I actually DO do that -- and even
> add a # noqa sometimes so my linter will stop bugging me. A smart linter
> would be nice here.
>
> PEP 8 is mostly about readability. However, the line length limit often
>> seems to cause less readable code.
>>
>
> So what do you suggest? simply increase the recommended line length? Or
> would softening the language about extending it be enough?
>
> Maybe something along the lines of:
>
> A line length limit should be well defined for each project / organization
> -- 80 char per line is safest for all users, but anything up to 100 is
> appropriate if the team maintaining the code agrees.
>
> Raymond: As a core dev -- are suggesting extending the line limit for the
> standard library?
>
> To all the folks quoting theory: let's be honest. Yes, really long lines
> are harder to read, but the 80 char limit comes from old terminals, NOT any
> analysis that somehow that is optimum for readability.
>
> -CHB
>
> --
>
> Christopher Barker, Ph.D.
> Oceanographer
>
> Emergency Response Division
> NOAA/NOS/OR&R (206) 526-6959 voice
> 7600 Sand Point Way NE (206) 526-6329 fax
> Seattle, WA 98115 (206) 526-6317 main reception
>
> Chris.Barker(a)noaa.gov
>
>
>
> ---------- Forwarded message ----------
> From: "Juancarlo Añez" <apalala(a)gmail.com>
> To: Ivan Levkivskyi <levkivskyi(a)gmail.com>
> Cc: Miikka Salminen <miikka.salminen(a)gmail.com>, python-ideas <
> python-ideas(a)python.org>
> Bcc:
> Date: Thu, 21 Feb 2019 21:20:38 -0400
> Subject: Re: [Python-ideas] Type hints for functions with side-effects and
> for functions raising exceptions
>
>
> On Thu, Feb 21, 2019 at 6:28 PM Ivan Levkivskyi <levkivskyi(a)gmail.com>
> wrote:
>
>> The idea about "checked exceptions" appeared several times in various
>> places. I used to think that this would be hard to support for any
>> realistic use cases. But now I think there may be a chance
>> to turn this into a usable feature if one frames it correctly (e.g. the
>> focus could be on user defined exceptions, rather than on standard ones,
>> since there is no way we can annotate every function in typeshed).
>>
>
> It's well documented how checked exceptions lead to bad code. That's why
> C#, which came after Java, didn't include them.
>
> Exceptions may be logically thought as of part of the type of a method,
> and of the type of the method's class, but that requires that the type
> catches every exception that may be raised from the implementation and
> either handles it, or translates it to one belonging to the type. It's a
> lot of work, it's cumbersome, and it is fragile, as the exception handling
> may need to change over minor implementation changes. If dependencies don't
> treat the exceptions that may escape from them as part of the type, then
> our own types will need to be changes every time a dependency changes its
> implementation.
>
> The strategy of catching only exceptions of interest and letting others
> pass produces less fragile and easier to test code.
>
> --
> Juancarlo *Añez*
> _______________________________________________
> Python-ideas mailing list
> Python-ideas(a)python.org
> https://mail.python.org/mailman/listinfo/python-ideas
>
--
*Philip Bergen*
P: +1(415)200-7340
*"Without data you are just another person with an opinion" -- W. Edwards
Deming*