From bc9eb9d3425a0210bed0de820de8368a2979397d Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 26 Nov 2016 10:41:40 -0800 Subject: [PATCH 1/5] Convert PEP 303 to reST Prep the file for conversion by restify script Add colon where necessary --- pep-0303.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pep-0303.txt b/pep-0303.txt index 3e0a862008f..72d5afcf9f7 100644 --- a/pep-0303.txt +++ b/pep-0303.txt @@ -76,7 +76,7 @@ Motivation If instead the divmod() built-in is changed according the proposal, the code for converting seconds to weeks, days, hours, minutes and - seconds then become + seconds then become: def secs_to_wdhms(seconds): w,d,h,m,s = divmod(seconds, 7, 24, 60, 60) @@ -146,7 +146,7 @@ Rationale product = product * x + y return product - could also be useful. However, writing + could also be useful. However, writing: seconds = (((((w * 7) + d) * 24 + h) * 60 + m) * 60 + s) From 4c796b3f7707439661b08ffdc0b1e69faad185d2 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 26 Nov 2016 10:42:45 -0800 Subject: [PATCH 2/5] Convert PEP 303 to reST Output from restify script --- pep-0303.txt | 305 ++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 147 deletions(-) diff --git a/pep-0303.txt b/pep-0303.txt index 72d5afcf9f7..e6244cd283c 100644 --- a/pep-0303.txt +++ b/pep-0303.txt @@ -5,192 +5,203 @@ Last-Modified: $Date$ Author: Thomas Bellman Status: Rejected Type: Standards Track -Content-Type: text/plain +Content-Type: text/x-rst Created: 31-Dec-2002 Python-Version: 2.3 Post-History: Abstract +======== + +This PEP describes an extension to the built-in ``divmod()`` function, +allowing it to take multiple divisors, chaining several calls to +``divmod()`` into one. - This PEP describes an extension to the built-in divmod() function, - allowing it to take multiple divisors, chaining several calls to - divmod() into one. Pronouncement +============= + +This PEP is rejected. Most uses for chained ``divmod()`` involve a +constant modulus (in radix conversions for example) and are more +properly coded as a loop. The example of splitting seconds +into days/hours/minutes/seconds does not generalize to months +and years; rather, the whole use case is handled more flexibly and +robustly by date and time modules. The other use cases mentioned +in the PEP are somewhat rare in real code. The proposal is also +problematic in terms of clarity and obviousness. In the examples, +it is not immediately clear that the argument order is correct or +that the target tuple is of the right length. Users from other +languages are more likely to understand the standard two argument +form without having to re-read the documentation. See python-dev +discussion on 17 June 2005. - This PEP is rejected. Most uses for chained divmod() involve a - constant modulus (in radix conversions for example) and are more - properly coded as a loop. The example of splitting seconds - into days/hours/minutes/seconds does not generalize to months - and years; rather, the whole use case is handled more flexibly and - robustly by date and time modules. The other use cases mentioned - in the PEP are somewhat rare in real code. The proposal is also - problematic in terms of clarity and obviousness. In the examples, - it is not immediately clear that the argument order is correct or - that the target tuple is of the right length. Users from other - languages are more likely to understand the standard two argument - form without having to re-read the documentation. See python-dev - discussion on 17 June 2005. Specification - - The built-in divmod() function would be changed to accept multiple - divisors, changing its signature from divmod(dividend, divisor) to - divmod(dividend, *divisors). The dividend is divided by the last - divisor, giving a quotient and a remainder. The quotient is then - divided by the second to last divisor, giving a new quotient and - remainder. This is repeated until all divisors have been used, - and divmod() then returns a tuple consisting of the quotient from - the last step, and the remainders from all the steps. - - A Python implementation of the new divmod() behaviour could look - like: - - def divmod(dividend, *divisors): - modulos = () - q = dividend - while divisors: - q,r = q.__divmod__(divisors[-1]) - modulos = (r,) + modulos - divisors = divisors[:-1] - return (q,) + modulos +============= + +The built-in ``divmod()`` function would be changed to accept multiple +divisors, changing its signature from ``divmod(dividend, divisor)`` to +divmod(dividend, \*divisors). The dividend is divided by the last +divisor, giving a quotient and a remainder. The quotient is then +divided by the second to last divisor, giving a new quotient and +remainder. This is repeated until all divisors have been used, +and ``divmod()`` then returns a tuple consisting of the quotient from +the last step, and the remainders from all the steps. + +A Python implementation of the new ``divmod()`` behaviour could look +like:: + + def divmod(dividend, *divisors): + modulos = () + q = dividend + while divisors: + q,r = q.__divmod__(divisors[-1]) + modulos = (r,) + modulos + divisors = divisors[:-1] + return (q,) + modulos Motivation +========== - Occasionally one wants to perform a chain of divmod() operations, - calling divmod() on the quotient from the previous step, with - varying divisors. The most common case is probably converting a - number of seconds into weeks, days, hours, minutes and seconds. - This would today be written as: +Occasionally one wants to perform a chain of ``divmod()`` operations, +calling ``divmod()`` on the quotient from the previous step, with +varying divisors. The most common case is probably converting a +number of seconds into weeks, days, hours, minutes and seconds. +This would today be written as:: - def secs_to_wdhms(seconds): - m,s = divmod(seconds, 60) - h,m = divmod(m, 60) - d,h = divmod(h, 24) - w,d = divmod(d, 7) - return (w,d,h,m,s) + def secs_to_wdhms(seconds): + m,s = divmod(seconds, 60) + h,m = divmod(m, 60) + d,h = divmod(h, 24) + w,d = divmod(d, 7) + return (w,d,h,m,s) - This is tedious and easy to get wrong each time you need it. +This is tedious and easy to get wrong each time you need it. - If instead the divmod() built-in is changed according the proposal, - the code for converting seconds to weeks, days, hours, minutes and - seconds then become: +If instead the ``divmod()`` built-in is changed according the proposal, +the code for converting seconds to weeks, days, hours, minutes and +seconds then become:: - def secs_to_wdhms(seconds): - w,d,h,m,s = divmod(seconds, 7, 24, 60, 60) - return (w,d,h,m,s) + def secs_to_wdhms(seconds): + w,d,h,m,s = divmod(seconds, 7, 24, 60, 60) + return (w,d,h,m,s) - which is easier to type, easier to type correctly, and easier to - read. +which is easier to type, easier to type correctly, and easier to +read. - Other applications are: +Other applications are:: - - Astronomical angles (declination is measured in degrees, minutes - and seconds, right ascension is measured in hours, minutes and - seconds). - - Old British currency (1 pound = 20 shilling, 1 shilling = 12 pence) - - Anglo-Saxon length units: 1 mile = 1760 yards, 1 yard = 3 feet, - 1 foot = 12 inches. - - Anglo-Saxon weight units: 1 long ton = 160 stone, 1 stone = 14 - pounds, 1 pound = 16 ounce, 1 ounce = 16 dram - - British volumes: 1 gallon = 4 quart, 1 quart = 2 pint, 1 pint - = 20 fluid ounces +- Astronomical angles (declination is measured in degrees, minutes +and seconds, right ascension is measured in hours, minutes and +seconds). +- Old British currency (1 pound = 20 shilling, 1 shilling = 12 pence) +- Anglo-Saxon length units: 1 mile = 1760 yards, 1 yard = 3 feet, +1 foot = 12 inches. +- Anglo-Saxon weight units: 1 long ton = 160 stone, 1 stone = 14 +pounds, 1 pound = 16 ounce, 1 ounce = 16 dram +- British volumes: 1 gallon = 4 quart, 1 quart = 2 pint, 1 pint += 20 fluid ounces Rationale - - The idea comes from APL, which has an operator that does this. (I - don't remember what the operator looks like, and it would probably - be impossible to render in ASCII anyway.) - - The APL operator takes a list as its second operand, while this - PEP proposes that each divisor should be a separate argument to - the divmod() function. This is mainly because it is expected that - the most common uses will have the divisors as constants right in - the call (as the 7, 24, 60, 60 above), and adding a set of - parentheses or brackets would just clutter the call. - - Requiring an explicit sequence as the second argument to divmod() - would seriously break backwards compatibility. Making divmod() - check its second argument for being a sequence is deemed to be too - ugly to contemplate. And in the case where one *does* have a - sequence that is computed other-where, it is easy enough to write - divmod(x, *divs) instead. - - Requiring at least one divisor, i.e rejecting divmod(x), has been - considered, but no good reason to do so has come to mind, and is - thus allowed in the name of generality. - - Calling divmod() with no divisors should still return a tuple (of - one element). Code that calls divmod() with a varying number of - divisors, and thus gets a return value with an "unknown" number of - elements, would otherwise have to special case that case. Code - that *knows* it is calling divmod() with no divisors is considered - to be too silly to warrant a special case. - - Processing the divisors in the other direction, i.e dividing with - the first divisor first, instead of dividing with the last divisor - first, has been considered. However, the result comes with the - most significant part first and the least significant part last - (think of the chained divmod as a way of splitting a number into - "digits", with varying weights), and it is reasonable to specify - the divisors (weights) in the same order as the result. - - The inverse operation: - - def inverse_divmod(seq, *factors): - product = seq[0] - for x,y in zip(factors, seq[1:]): - product = product * x + y - return product - - could also be useful. However, writing: - - seconds = (((((w * 7) + d) * 24 + h) * 60 + m) * 60 + s) - - is less cumbersome both to write and to read than the chained - divmods. It is therefore deemed to be less important, and its - introduction can be deferred to its own PEP. Also, such a - function needs a good name, and the PEP author has not managed to - come up with one yet. - - Calling divmod("spam") does not raise an error, despite strings - supporting neither division nor modulo. However, unless we know - the other object too, we can't determine whether divmod() would - work or not, and thus it seems silly to forbid it. +========= + +The idea comes from APL, which has an operator that does this. (I +don't remember what the operator looks like, and it would probably +be impossible to render in ASCII anyway.) + +The APL operator takes a list as its second operand, while this +PEP proposes that each divisor should be a separate argument to +the ``divmod()`` function. This is mainly because it is expected that +the most common uses will have the divisors as constants right in +the call (as the 7, 24, 60, 60 above), and adding a set of +parentheses or brackets would just clutter the call. + +Requiring an explicit sequence as the second argument to ``divmod()`` +would seriously break backwards compatibility. Making ``divmod()`` +check its second argument for being a sequence is deemed to be too +ugly to contemplate. And in the case where one *does* have a +sequence that is computed other-where, it is easy enough to write +divmod(x, \*divs) instead. + +Requiring at least one divisor, i.e rejecting ``divmod(x)``, has been +considered, but no good reason to do so has come to mind, and is +thus allowed in the name of generality. + +Calling ``divmod()`` with no divisors should still return a tuple (of +one element). Code that calls ``divmod()`` with a varying number of +divisors, and thus gets a return value with an "unknown" number of +elements, would otherwise have to special case that case. Code +that *knows* it is calling ``divmod()`` with no divisors is considered +to be too silly to warrant a special case. + +Processing the divisors in the other direction, i.e dividing with +the first divisor first, instead of dividing with the last divisor +first, has been considered. However, the result comes with the +most significant part first and the least significant part last +(think of the chained divmod as a way of splitting a number into +"digits", with varying weights), and it is reasonable to specify +the divisors (weights) in the same order as the result. + +The inverse operation:: + + def inverse_divmod(seq, *factors): + product = seq[0] + for x,y in zip(factors, seq[1:]): + product = product * x + y + return product + +could also be useful. However, writing: + + seconds = (((((w * 7) + d) * 24 + h) * 60 + m) * 60 + s) + +is less cumbersome both to write and to read than the chained +divmods. It is therefore deemed to be less important, and its +introduction can be deferred to its own PEP. Also, such a +function needs a good name, and the PEP author has not managed to +come up with one yet. + +Calling ``divmod("spam")`` does not raise an error, despite strings +supporting neither division nor modulo. However, unless we know +the other object too, we can't determine whether ``divmod()`` would +work or not, and thus it seems silly to forbid it. Backwards Compatibility +======================= - Any module that replaces the divmod() function in the __builtin__ - module, may cause other modules using the new syntax to break. It - is expected that this is very uncommon. +Any module that replaces the ``divmod()`` function in the ``__builtin__`` +module, may cause other modules using the new syntax to break. It +is expected that this is very uncommon. - Code that expects a TypeError exception when calling divmod() with - anything but two arguments will break. This is also expected to - be very uncommon. +Code that expects a ``TypeError`` exception when calling ``divmod()`` with +anything but two arguments will break. This is also expected to +be very uncommon. - No other issues regarding backwards compatibility are known. +No other issues regarding backwards compatibility are known. Reference Implementation +======================== - Not finished yet, but it seems a rather straightforward - new implementation of the function builtin_divmod() in - Python/bltinmodule.c +Not finished yet, but it seems a rather straightforward +new implementation of the function builtin_``divmod()`` in +Python/bltinmodule.c Copyright +========= + +This document has been placed in the public domain. - This document has been placed in the public domain. - -Local Variables: -mode: indented-text -indent-tabs-mode: nil -sentence-end-double-space: t -fill-column: 70 -End: +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: From 8a51245ff3a9fc6dd9027510c0089c6cf85856b7 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 26 Nov 2016 10:50:26 -0800 Subject: [PATCH 3/5] Convert PEP 303 to reSt Some manual adjustments --- pep-0303.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pep-0303.txt b/pep-0303.txt index e6244cd283c..0aae8cee466 100644 --- a/pep-0303.txt +++ b/pep-0303.txt @@ -91,18 +91,18 @@ seconds then become:: which is easier to type, easier to type correctly, and easier to read. -Other applications are:: +Other applications are: - Astronomical angles (declination is measured in degrees, minutes -and seconds, right ascension is measured in hours, minutes and -seconds). + and seconds, right ascension is measured in hours, minutes and + seconds). - Old British currency (1 pound = 20 shilling, 1 shilling = 12 pence) - Anglo-Saxon length units: 1 mile = 1760 yards, 1 yard = 3 feet, -1 foot = 12 inches. + 1 foot = 12 inches. - Anglo-Saxon weight units: 1 long ton = 160 stone, 1 stone = 14 -pounds, 1 pound = 16 ounce, 1 ounce = 16 dram + pounds, 1 pound = 16 ounce, 1 ounce = 16 dram - British volumes: 1 gallon = 4 quart, 1 quart = 2 pint, 1 pint -= 20 fluid ounces + = 20 fluid ounces Rationale @@ -153,7 +153,7 @@ The inverse operation:: product = product * x + y return product -could also be useful. However, writing: +could also be useful. However, writing:: seconds = (((((w * 7) + d) * 24 + h) * 60 + m) * 60 + s) @@ -187,7 +187,7 @@ Reference Implementation ======================== Not finished yet, but it seems a rather straightforward -new implementation of the function builtin_``divmod()`` in +new implementation of the function builtin_divmod() in Python/bltinmodule.c From 1ccefa7a136cde168734c6799650575463c85860 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 27 Nov 2016 10:25:12 -0800 Subject: [PATCH 4/5] more fixes for PEP 303 --- pep-0303.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pep-0303.txt b/pep-0303.txt index 0aae8cee466..515be53cf36 100644 --- a/pep-0303.txt +++ b/pep-0303.txt @@ -42,7 +42,7 @@ Specification The built-in ``divmod()`` function would be changed to accept multiple divisors, changing its signature from ``divmod(dividend, divisor)`` to -divmod(dividend, \*divisors). The dividend is divided by the last +``divmod(dividend, divisors)``. The dividend is divided by the last divisor, giving a quotient and a remainder. The quotient is then divided by the second to last divisor, giving a new quotient and remainder. This is repeated until all divisors have been used, @@ -124,7 +124,7 @@ would seriously break backwards compatibility. Making ``divmod()`` check its second argument for being a sequence is deemed to be too ugly to contemplate. And in the case where one *does* have a sequence that is computed other-where, it is easy enough to write -divmod(x, \*divs) instead. +``divmod(x, *divs)`` instead. Requiring at least one divisor, i.e rejecting ``divmod(x)``, has been considered, but no good reason to do so has come to mind, and is @@ -187,8 +187,8 @@ Reference Implementation ======================== Not finished yet, but it seems a rather straightforward -new implementation of the function builtin_divmod() in -Python/bltinmodule.c +new implementation of the function ``builtin_divmod()` in +``Python/bltinmodule.c``. Copyright From 99c347cef417cd5a33271fc7aa478770794a5b8c Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 27 Nov 2016 16:05:55 -0800 Subject: [PATCH 5/5] Add reference link to python-dev discussion thread --- pep-0303.txt | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pep-0303.txt b/pep-0303.txt index 515be53cf36..dcc963f7e89 100644 --- a/pep-0303.txt +++ b/pep-0303.txt @@ -34,7 +34,7 @@ it is not immediately clear that the argument order is correct or that the target tuple is of the right length. Users from other languages are more likely to understand the standard two argument form without having to re-read the documentation. See python-dev -discussion on 17 June 2005. +discussion on 17 June 2005 [1]_. Specification @@ -56,7 +56,7 @@ like:: modulos = () q = dividend while divisors: - q,r = q.__divmod__(divisors[-1]) + q, r = q.__divmod__(divisors[-1]) modulos = (r,) + modulos divisors = divisors[:-1] return (q,) + modulos @@ -72,11 +72,11 @@ number of seconds into weeks, days, hours, minutes and seconds. This would today be written as:: def secs_to_wdhms(seconds): - m,s = divmod(seconds, 60) - h,m = divmod(m, 60) - d,h = divmod(h, 24) - w,d = divmod(d, 7) - return (w,d,h,m,s) + m, s = divmod(seconds, 60) + h, m = divmod(m, 60) + d, h = divmod(h, 24) + w, d = divmod(d, 7) + return (w, d, h, m, s) This is tedious and easy to get wrong each time you need it. @@ -85,8 +85,8 @@ the code for converting seconds to weeks, days, hours, minutes and seconds then become:: def secs_to_wdhms(seconds): - w,d,h,m,s = divmod(seconds, 7, 24, 60, 60) - return (w,d,h,m,s) + w, d, h, m, s = divmod(seconds, 7, 24, 60, 60) + return (w, d, h, m, s) which is easier to type, easier to type correctly, and easier to read. @@ -149,7 +149,7 @@ The inverse operation:: def inverse_divmod(seq, *factors): product = seq[0] - for x,y in zip(factors, seq[1:]): + for x, y in zip(factors, seq[1:]): product = product * x + y return product @@ -187,10 +187,17 @@ Reference Implementation ======================== Not finished yet, but it seems a rather straightforward -new implementation of the function ``builtin_divmod()` in +new implementation of the function ``builtin_divmod()`` in ``Python/bltinmodule.c``. +References +========== + +.. [1] Raymond Hettinger, "Propose rejection of PEP 303 -- Extend divmod() for + Multiple Divisors" http://mail.python.org/pipermail/python-dev/2003-January/032492.html + + Copyright =========