diff options
| author | Steven D'Aprano <steve@pearwood.info> | 2016-08-24 02:40:31 +1000 | 
|---|---|---|
| committer | Steven D'Aprano <steve@pearwood.info> | 2016-08-24 02:40:31 +1000 | 
| commit | 9ff4fb36199f94818d97be56d0b3ab1c9e989209 (patch) | |
| tree | a4ee9040e52bfe8f73278c90f543ef64cd55b766 | |
| parent | f06c7b6f377692b82f2da449cb7e9460f474f434 (diff) | |
| parent | 0a21c729ebaca9e2e929a1e04c7404c5349aa1f4 (diff) | |
| download | cpython-git-9ff4fb36199f94818d97be56d0b3ab1c9e989209.tar.gz | |
Automated merge with ssh://hg.python.org/cpython
| -rw-r--r-- | Doc/library/code.rst | 18 | ||||
| -rw-r--r-- | Doc/library/statistics.rst | 58 | ||||
| -rw-r--r-- | Lib/code.py | 17 | ||||
| -rw-r--r-- | Lib/statistics.py | 17 | ||||
| -rw-r--r-- | Lib/test/test_code_module.py | 20 | 
5 files changed, 104 insertions, 26 deletions
diff --git a/Doc/library/code.rst b/Doc/library/code.rst index c573087af3..4cce1fab34 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -30,15 +30,19 @@ build applications which provide an interactive interpreter prompt.     ``sys.ps1`` and ``sys.ps2``, and input buffering. -.. function:: interact(banner=None, readfunc=None, local=None) +.. function:: interact(banner=None, readfunc=None, local=None, exitmsg=None)     Convenience function to run a read-eval-print loop.  This creates a new     instance of :class:`InteractiveConsole` and sets *readfunc* to be used as     the :meth:`InteractiveConsole.raw_input` method, if provided.  If *local* is     provided, it is passed to the :class:`InteractiveConsole` constructor for     use as the default namespace for the interpreter loop.  The :meth:`interact` -   method of the instance is then run with *banner* passed as the banner to -   use, if provided.  The console object is discarded after use. +   method of the instance is then run with *banner* and *exitmsg* passed as the +   banner and exit message to use, if provided.  The console object is discarded +   after use. + +   .. versionchanged:: 3.6 +      Added *exitmsg* parameter.  .. function:: compile_command(source, filename="<input>", symbol="single") @@ -136,7 +140,7 @@ The :class:`InteractiveConsole` class is a subclass of  interpreter objects as well as the following additions. -.. method:: InteractiveConsole.interact(banner=None) +.. method:: InteractiveConsole.interact(banner=None, exitmsg=None)     Closely emulate the interactive Python console. The optional *banner* argument     specify the banner to print before the first interaction; by default it prints a @@ -144,11 +148,15 @@ interpreter objects as well as the following additions.     by the class name of the console object in parentheses (so as not to confuse     this with the real interpreter -- since it's so close!). +   The optional *exitmsg* argument specifies an exit message printed when exiting. +   Pass the empty string to suppress the exit message. If *exitmsg* is not given or +   None, a default message is printed. +     .. versionchanged:: 3.4        To suppress printing any banner, pass an empty string.     .. versionchanged:: 3.6 -      Now prints a brief message when exiting. +      Print an exit message when exiting.  .. method:: InteractiveConsole.push(line) diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index ea3d7dab0f..d62d55a161 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -39,6 +39,8 @@ or sample.  =======================  =============================================  :func:`mean`             Arithmetic mean ("average") of data. +:func:`geometric_mean`   Geometric mean of data. +:func:`harmonic_mean`    Harmonic mean of data.  :func:`median`           Median (middle value) of data.  :func:`median_low`       Low median of data.  :func:`median_high`      High median of data. @@ -111,6 +113,62 @@ However, for reading convenience, most of the examples show sorted sequences.        ``mean(data)`` is equivalent to calculating the true population mean μ. +.. function:: geometric_mean(data) + +   Return the geometric mean of *data*, a sequence or iterator of +   real-valued numbers. + +   The geometric mean is the *n*-th root of the product of *n* data points. +   It is a type of average, a measure of the central location of the data. + +   The geometric mean is appropriate when averaging quantities which +   are multiplied together rather than added, for example growth rates. +   Suppose an investment grows by 10% in the first year, falls by 5% in +   the second, then grows by 12% in the third, what is the average rate +   of growth over the three years? + +   .. doctest:: + +      >>> geometric_mean([1.10, 0.95, 1.12]) +      1.0538483123382172 + +   giving an average growth of 5.385%. Using the arithmetic mean will +   give approximately 5.667%, which is too high. + +   :exc:``StatisticsError`` is raised if *data* is empty, or any +   element is less than zero. + + +.. function:: harmonic_mean(data) + +   Return the harmonic mean of *data*, a sequence or iterator of +   real-valued numbers. + +   The harmonic mean, sometimes called the subcontrary mean, is the +   reciprocal of the arithmetic :func:``mean`` of the reciprocals of the +   data. For example, the harmonic mean of three values *a*, *b* and *c* +   will be equivalent to ``3/(1/a + 1/b + 1/c)``. + +   The harmonic mean is a type of average, a measure of the central +   location of the data.  It is often appropriate when averaging quantities +   which are rates or ratios, for example speeds. For example: + +   Suppose an investor purchases an equal value of shares in each of +   three companies, with P/E (price/earning) ratios of 2.5, 3 and 10. +   What is the average P/E ratio for the investor's portfolio? + +   .. doctest:: + +      >>> harmonic_mean([2.5, 3, 10])  # For an equal investment portfolio. +      3.6 + +   Using the arithmetic mean would give an average of about 5.167, which +   is too high. + +   :exc:``StatisticsError`` is raised if *data* is empty, or any element +   is less than zero. + +  .. function:: median(data)     Return the median (middle value) of numeric data, using the common "mean of diff --git a/Lib/code.py b/Lib/code.py index c8b72042e0..23295f4cf5 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -186,7 +186,7 @@ class InteractiveConsole(InteractiveInterpreter):          """Reset the input buffer."""          self.buffer = [] -    def interact(self, banner=None): +    def interact(self, banner=None, exitmsg=None):          """Closely emulate the interactive Python console.          The optional banner argument specifies the banner to print @@ -196,6 +196,11 @@ class InteractiveConsole(InteractiveInterpreter):          to confuse this with the real interpreter -- since it's so          close!). +        The optional exitmsg argument specifies the exit message +        printed when exiting. Pass the empty string to suppress +        printing an exit message. If exitmsg is not given or None, +        a default message is printed. +          """          try:              sys.ps1 @@ -230,7 +235,10 @@ class InteractiveConsole(InteractiveInterpreter):                  self.write("\nKeyboardInterrupt\n")                  self.resetbuffer()                  more = 0 -        self.write('now exiting %s...\n' % self.__class__.__name__) +        if exitmsg is None: +            self.write('now exiting %s...\n' % self.__class__.__name__) +        elif exitmsg != '': +            self.write('%s\n' % exitmsg)      def push(self, line):          """Push a line to the interpreter. @@ -268,7 +276,7 @@ class InteractiveConsole(InteractiveInterpreter): -def interact(banner=None, readfunc=None, local=None): +def interact(banner=None, readfunc=None, local=None, exitmsg=None):      """Closely emulate the interactive Python interpreter.      This is a backwards compatible interface to the InteractiveConsole @@ -280,6 +288,7 @@ def interact(banner=None, readfunc=None, local=None):      banner -- passed to InteractiveConsole.interact()      readfunc -- if not None, replaces InteractiveConsole.raw_input()      local -- passed to InteractiveInterpreter.__init__() +    exitmsg -- passed to InteractiveConsole.interact()      """      console = InteractiveConsole(local) @@ -290,7 +299,7 @@ def interact(banner=None, readfunc=None, local=None):              import readline          except ImportError:              pass -    console.interact(banner) +    console.interact(banner, exitmsg)  if __name__ == "__main__": diff --git a/Lib/statistics.py b/Lib/statistics.py index f4b49b5d0c..17e471bb56 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -1,20 +1,3 @@ -##  Module statistics.py -## -##  Copyright (c) 2013 Steven D'Aprano <steve+python@pearwood.info>. -## -##  Licensed under the Apache License, Version 2.0 (the "License"); -##  you may not use this file except in compliance with the License. -##  You may obtain a copy of the License at -## -##  http://www.apache.org/licenses/LICENSE-2.0 -## -##  Unless required by applicable law or agreed to in writing, software -##  distributed under the License is distributed on an "AS IS" BASIS, -##  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -##  See the License for the specific language governing permissions and -##  limitations under the License. - -  """  Basic statistics module. diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 08ba3f3704..1a8f6990df 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -80,6 +80,7 @@ class TestInteractiveConsole(unittest.TestCase):          self.assertEqual(len(self.stderr.method_calls), 2)      def test_exit_msg(self): +        # default exit message          self.infunc.side_effect = EOFError('Finished')          self.console.interact(banner='')          self.assertEqual(len(self.stderr.method_calls), 2) @@ -87,6 +88,25 @@ class TestInteractiveConsole(unittest.TestCase):          expected = 'now exiting InteractiveConsole...\n'          self.assertEqual(err_msg, ['write', (expected,), {}]) +        # no exit message +        self.stderr.reset_mock() +        self.infunc.side_effect = EOFError('Finished') +        self.console.interact(banner='', exitmsg='') +        self.assertEqual(len(self.stderr.method_calls), 1) + +        # custom exit message +        self.stderr.reset_mock() +        message = ( +            'bye! \N{GREEK SMALL LETTER ZETA}\N{CYRILLIC SMALL LETTER ZHE}' +            ) +        self.infunc.side_effect = EOFError('Finished') +        self.console.interact(banner='', exitmsg=message) +        self.assertEqual(len(self.stderr.method_calls), 2) +        err_msg = self.stderr.method_calls[1] +        expected = message + '\n' +        self.assertEqual(err_msg, ['write', (expected,), {}]) + +      def test_cause_tb(self):          self.infunc.side_effect = ["raise ValueError('') from AttributeError",                                      EOFError('Finished')]  | 
