17db96d56Sopenharmony_ci.. _tut-brieftourtwo:
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci**********************************************
47db96d56Sopenharmony_ciBrief Tour of the Standard Library --- Part II
57db96d56Sopenharmony_ci**********************************************
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ciThis second tour covers more advanced modules that support professional
87db96d56Sopenharmony_ciprogramming needs.  These modules rarely occur in small scripts.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci.. _tut-output-formatting:
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciOutput Formatting
147db96d56Sopenharmony_ci=================
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciThe :mod:`reprlib` module provides a version of :func:`repr` customized for
177db96d56Sopenharmony_ciabbreviated displays of large or deeply nested containers::
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci   >>> import reprlib
207db96d56Sopenharmony_ci   >>> reprlib.repr(set('supercalifragilisticexpialidocious'))
217db96d56Sopenharmony_ci   "{'a', 'c', 'd', 'e', 'f', 'g', ...}"
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ciThe :mod:`pprint` module offers more sophisticated control over printing both
247db96d56Sopenharmony_cibuilt-in and user defined objects in a way that is readable by the interpreter.
257db96d56Sopenharmony_ciWhen the result is longer than one line, the "pretty printer" adds line breaks
267db96d56Sopenharmony_ciand indentation to more clearly reveal data structure::
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci   >>> import pprint
297db96d56Sopenharmony_ci   >>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
307db96d56Sopenharmony_ci   ...     'yellow'], 'blue']]]
317db96d56Sopenharmony_ci   ...
327db96d56Sopenharmony_ci   >>> pprint.pprint(t, width=30)
337db96d56Sopenharmony_ci   [[[['black', 'cyan'],
347db96d56Sopenharmony_ci      'white',
357db96d56Sopenharmony_ci      ['green', 'red']],
367db96d56Sopenharmony_ci     [['magenta', 'yellow'],
377db96d56Sopenharmony_ci      'blue']]]
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciThe :mod:`textwrap` module formats paragraphs of text to fit a given screen
407db96d56Sopenharmony_ciwidth::
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_ci   >>> import textwrap
437db96d56Sopenharmony_ci   >>> doc = """The wrap() method is just like fill() except that it returns
447db96d56Sopenharmony_ci   ... a list of strings instead of one big string with newlines to separate
457db96d56Sopenharmony_ci   ... the wrapped lines."""
467db96d56Sopenharmony_ci   ...
477db96d56Sopenharmony_ci   >>> print(textwrap.fill(doc, width=40))
487db96d56Sopenharmony_ci   The wrap() method is just like fill()
497db96d56Sopenharmony_ci   except that it returns a list of strings
507db96d56Sopenharmony_ci   instead of one big string with newlines
517db96d56Sopenharmony_ci   to separate the wrapped lines.
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ciThe :mod:`locale` module accesses a database of culture specific data formats.
547db96d56Sopenharmony_ciThe grouping attribute of locale's format function provides a direct way of
557db96d56Sopenharmony_ciformatting numbers with group separators::
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci   >>> import locale
587db96d56Sopenharmony_ci   >>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
597db96d56Sopenharmony_ci   'English_United States.1252'
607db96d56Sopenharmony_ci   >>> conv = locale.localeconv()          # get a mapping of conventions
617db96d56Sopenharmony_ci   >>> x = 1234567.8
627db96d56Sopenharmony_ci   >>> locale.format("%d", x, grouping=True)
637db96d56Sopenharmony_ci   '1,234,567'
647db96d56Sopenharmony_ci   >>> locale.format_string("%s%.*f", (conv['currency_symbol'],
657db96d56Sopenharmony_ci   ...                      conv['frac_digits'], x), grouping=True)
667db96d56Sopenharmony_ci   '$1,234,567.80'
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci.. _tut-templating:
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ciTemplating
727db96d56Sopenharmony_ci==========
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ciThe :mod:`string` module includes a versatile :class:`~string.Template` class
757db96d56Sopenharmony_ciwith a simplified syntax suitable for editing by end-users.  This allows users
767db96d56Sopenharmony_cito customize their applications without having to alter the application.
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ciThe format uses placeholder names formed by ``$`` with valid Python identifiers
797db96d56Sopenharmony_ci(alphanumeric characters and underscores).  Surrounding the placeholder with
807db96d56Sopenharmony_cibraces allows it to be followed by more alphanumeric letters with no intervening
817db96d56Sopenharmony_cispaces.  Writing ``$$`` creates a single escaped ``$``::
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci   >>> from string import Template
847db96d56Sopenharmony_ci   >>> t = Template('${village}folk send $$10 to $cause.')
857db96d56Sopenharmony_ci   >>> t.substitute(village='Nottingham', cause='the ditch fund')
867db96d56Sopenharmony_ci   'Nottinghamfolk send $10 to the ditch fund.'
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ciThe :meth:`~string.Template.substitute` method raises a :exc:`KeyError` when a
897db96d56Sopenharmony_ciplaceholder is not supplied in a dictionary or a keyword argument.  For
907db96d56Sopenharmony_cimail-merge style applications, user supplied data may be incomplete and the
917db96d56Sopenharmony_ci:meth:`~string.Template.safe_substitute` method may be more appropriate ---
927db96d56Sopenharmony_ciit will leave placeholders unchanged if data is missing::
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci   >>> t = Template('Return the $item to $owner.')
957db96d56Sopenharmony_ci   >>> d = dict(item='unladen swallow')
967db96d56Sopenharmony_ci   >>> t.substitute(d)
977db96d56Sopenharmony_ci   Traceback (most recent call last):
987db96d56Sopenharmony_ci     ...
997db96d56Sopenharmony_ci   KeyError: 'owner'
1007db96d56Sopenharmony_ci   >>> t.safe_substitute(d)
1017db96d56Sopenharmony_ci   'Return the unladen swallow to $owner.'
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ciTemplate subclasses can specify a custom delimiter.  For example, a batch
1047db96d56Sopenharmony_cirenaming utility for a photo browser may elect to use percent signs for
1057db96d56Sopenharmony_ciplaceholders such as the current date, image sequence number, or file format::
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci   >>> import time, os.path
1087db96d56Sopenharmony_ci   >>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
1097db96d56Sopenharmony_ci   >>> class BatchRename(Template):
1107db96d56Sopenharmony_ci   ...     delimiter = '%'
1117db96d56Sopenharmony_ci   ...
1127db96d56Sopenharmony_ci   >>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format):  ')
1137db96d56Sopenharmony_ci   Enter rename style (%d-date %n-seqnum %f-format):  Ashley_%n%f
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci   >>> t = BatchRename(fmt)
1167db96d56Sopenharmony_ci   >>> date = time.strftime('%d%b%y')
1177db96d56Sopenharmony_ci   >>> for i, filename in enumerate(photofiles):
1187db96d56Sopenharmony_ci   ...     base, ext = os.path.splitext(filename)
1197db96d56Sopenharmony_ci   ...     newname = t.substitute(d=date, n=i, f=ext)
1207db96d56Sopenharmony_ci   ...     print('{0} --> {1}'.format(filename, newname))
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci   img_1074.jpg --> Ashley_0.jpg
1237db96d56Sopenharmony_ci   img_1076.jpg --> Ashley_1.jpg
1247db96d56Sopenharmony_ci   img_1077.jpg --> Ashley_2.jpg
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_ciAnother application for templating is separating program logic from the details
1277db96d56Sopenharmony_ciof multiple output formats.  This makes it possible to substitute custom
1287db96d56Sopenharmony_citemplates for XML files, plain text reports, and HTML web reports.
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci.. _tut-binary-formats:
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ciWorking with Binary Data Record Layouts
1347db96d56Sopenharmony_ci=======================================
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ciThe :mod:`struct` module provides :func:`~struct.pack` and
1377db96d56Sopenharmony_ci:func:`~struct.unpack` functions for working with variable length binary
1387db96d56Sopenharmony_cirecord formats.  The following example shows
1397db96d56Sopenharmony_cihow to loop through header information in a ZIP file without using the
1407db96d56Sopenharmony_ci:mod:`zipfile` module.  Pack codes ``"H"`` and ``"I"`` represent two and four
1417db96d56Sopenharmony_cibyte unsigned numbers respectively.  The ``"<"`` indicates that they are
1427db96d56Sopenharmony_cistandard size and in little-endian byte order::
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ci   import struct
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci   with open('myfile.zip', 'rb') as f:
1477db96d56Sopenharmony_ci       data = f.read()
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci   start = 0
1507db96d56Sopenharmony_ci   for i in range(3):                      # show the first 3 file headers
1517db96d56Sopenharmony_ci       start += 14
1527db96d56Sopenharmony_ci       fields = struct.unpack('<IIIHH', data[start:start+16])
1537db96d56Sopenharmony_ci       crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci       start += 16
1567db96d56Sopenharmony_ci       filename = data[start:start+filenamesize]
1577db96d56Sopenharmony_ci       start += filenamesize
1587db96d56Sopenharmony_ci       extra = data[start:start+extra_size]
1597db96d56Sopenharmony_ci       print(filename, hex(crc32), comp_size, uncomp_size)
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci       start += extra_size + comp_size     # skip to the next header
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci.. _tut-multi-threading:
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ciMulti-threading
1677db96d56Sopenharmony_ci===============
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ciThreading is a technique for decoupling tasks which are not sequentially
1707db96d56Sopenharmony_cidependent.  Threads can be used to improve the responsiveness of applications
1717db96d56Sopenharmony_cithat accept user input while other tasks run in the background.  A related use
1727db96d56Sopenharmony_cicase is running I/O in parallel with computations in another thread.
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ciThe following code shows how the high level :mod:`threading` module can run
1757db96d56Sopenharmony_citasks in background while the main program continues to run::
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci   import threading, zipfile
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci   class AsyncZip(threading.Thread):
1807db96d56Sopenharmony_ci       def __init__(self, infile, outfile):
1817db96d56Sopenharmony_ci           threading.Thread.__init__(self)
1827db96d56Sopenharmony_ci           self.infile = infile
1837db96d56Sopenharmony_ci           self.outfile = outfile
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci       def run(self):
1867db96d56Sopenharmony_ci           f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
1877db96d56Sopenharmony_ci           f.write(self.infile)
1887db96d56Sopenharmony_ci           f.close()
1897db96d56Sopenharmony_ci           print('Finished background zip of:', self.infile)
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci   background = AsyncZip('mydata.txt', 'myarchive.zip')
1927db96d56Sopenharmony_ci   background.start()
1937db96d56Sopenharmony_ci   print('The main program continues to run in foreground.')
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci   background.join()    # Wait for the background task to finish
1967db96d56Sopenharmony_ci   print('Main program waited until background was done.')
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ciThe principal challenge of multi-threaded applications is coordinating threads
1997db96d56Sopenharmony_cithat share data or other resources.  To that end, the threading module provides
2007db96d56Sopenharmony_cia number of synchronization primitives including locks, events, condition
2017db96d56Sopenharmony_civariables, and semaphores.
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ciWhile those tools are powerful, minor design errors can result in problems that
2047db96d56Sopenharmony_ciare difficult to reproduce.  So, the preferred approach to task coordination is
2057db96d56Sopenharmony_cito concentrate all access to a resource in a single thread and then use the
2067db96d56Sopenharmony_ci:mod:`queue` module to feed that thread with requests from other threads.
2077db96d56Sopenharmony_ciApplications using :class:`~queue.Queue` objects for inter-thread communication and
2087db96d56Sopenharmony_cicoordination are easier to design, more readable, and more reliable.
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci.. _tut-logging:
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ciLogging
2147db96d56Sopenharmony_ci=======
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ciThe :mod:`logging` module offers a full featured and flexible logging system.
2177db96d56Sopenharmony_ciAt its simplest, log messages are sent to a file or to ``sys.stderr``::
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci   import logging
2207db96d56Sopenharmony_ci   logging.debug('Debugging information')
2217db96d56Sopenharmony_ci   logging.info('Informational message')
2227db96d56Sopenharmony_ci   logging.warning('Warning:config file %s not found', 'server.conf')
2237db96d56Sopenharmony_ci   logging.error('Error occurred')
2247db96d56Sopenharmony_ci   logging.critical('Critical error -- shutting down')
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ciThis produces the following output:
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci.. code-block:: none
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci   WARNING:root:Warning:config file server.conf not found
2317db96d56Sopenharmony_ci   ERROR:root:Error occurred
2327db96d56Sopenharmony_ci   CRITICAL:root:Critical error -- shutting down
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ciBy default, informational and debugging messages are suppressed and the output
2357db96d56Sopenharmony_ciis sent to standard error.  Other output options include routing messages
2367db96d56Sopenharmony_cithrough email, datagrams, sockets, or to an HTTP Server.  New filters can select
2377db96d56Sopenharmony_cidifferent routing based on message priority: :const:`~logging.DEBUG`,
2387db96d56Sopenharmony_ci:const:`~logging.INFO`, :const:`~logging.WARNING`, :const:`~logging.ERROR`,
2397db96d56Sopenharmony_ciand :const:`~logging.CRITICAL`.
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ciThe logging system can be configured directly from Python or can be loaded from
2427db96d56Sopenharmony_cia user editable configuration file for customized logging without altering the
2437db96d56Sopenharmony_ciapplication.
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci.. _tut-weak-references:
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ciWeak References
2497db96d56Sopenharmony_ci===============
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_ciPython does automatic memory management (reference counting for most objects and
2527db96d56Sopenharmony_ci:term:`garbage collection` to eliminate cycles).  The memory is freed shortly
2537db96d56Sopenharmony_ciafter the last reference to it has been eliminated.
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ciThis approach works fine for most applications but occasionally there is a need
2567db96d56Sopenharmony_cito track objects only as long as they are being used by something else.
2577db96d56Sopenharmony_ciUnfortunately, just tracking them creates a reference that makes them permanent.
2587db96d56Sopenharmony_ciThe :mod:`weakref` module provides tools for tracking objects without creating a
2597db96d56Sopenharmony_cireference.  When the object is no longer needed, it is automatically removed
2607db96d56Sopenharmony_cifrom a weakref table and a callback is triggered for weakref objects.  Typical
2617db96d56Sopenharmony_ciapplications include caching objects that are expensive to create::
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci   >>> import weakref, gc
2647db96d56Sopenharmony_ci   >>> class A:
2657db96d56Sopenharmony_ci   ...     def __init__(self, value):
2667db96d56Sopenharmony_ci   ...         self.value = value
2677db96d56Sopenharmony_ci   ...     def __repr__(self):
2687db96d56Sopenharmony_ci   ...         return str(self.value)
2697db96d56Sopenharmony_ci   ...
2707db96d56Sopenharmony_ci   >>> a = A(10)                   # create a reference
2717db96d56Sopenharmony_ci   >>> d = weakref.WeakValueDictionary()
2727db96d56Sopenharmony_ci   >>> d['primary'] = a            # does not create a reference
2737db96d56Sopenharmony_ci   >>> d['primary']                # fetch the object if it is still alive
2747db96d56Sopenharmony_ci   10
2757db96d56Sopenharmony_ci   >>> del a                       # remove the one reference
2767db96d56Sopenharmony_ci   >>> gc.collect()                # run garbage collection right away
2777db96d56Sopenharmony_ci   0
2787db96d56Sopenharmony_ci   >>> d['primary']                # entry was automatically removed
2797db96d56Sopenharmony_ci   Traceback (most recent call last):
2807db96d56Sopenharmony_ci     File "<stdin>", line 1, in <module>
2817db96d56Sopenharmony_ci       d['primary']                # entry was automatically removed
2827db96d56Sopenharmony_ci     File "C:/python311/lib/weakref.py", line 46, in __getitem__
2837db96d56Sopenharmony_ci       o = self.data[key]()
2847db96d56Sopenharmony_ci   KeyError: 'primary'
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci.. _tut-list-tools:
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_ciTools for Working with Lists
2907db96d56Sopenharmony_ci============================
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ciMany data structure needs can be met with the built-in list type. However,
2937db96d56Sopenharmony_cisometimes there is a need for alternative implementations with different
2947db96d56Sopenharmony_ciperformance trade-offs.
2957db96d56Sopenharmony_ci
2967db96d56Sopenharmony_ciThe :mod:`array` module provides an :class:`~array.array()` object that is like
2977db96d56Sopenharmony_cia list that stores only homogeneous data and stores it more compactly.  The
2987db96d56Sopenharmony_cifollowing example shows an array of numbers stored as two byte unsigned binary
2997db96d56Sopenharmony_cinumbers (typecode ``"H"``) rather than the usual 16 bytes per entry for regular
3007db96d56Sopenharmony_cilists of Python int objects::
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci   >>> from array import array
3037db96d56Sopenharmony_ci   >>> a = array('H', [4000, 10, 700, 22222])
3047db96d56Sopenharmony_ci   >>> sum(a)
3057db96d56Sopenharmony_ci   26932
3067db96d56Sopenharmony_ci   >>> a[1:3]
3077db96d56Sopenharmony_ci   array('H', [10, 700])
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ciThe :mod:`collections` module provides a :class:`~collections.deque()` object
3107db96d56Sopenharmony_cithat is like a list with faster appends and pops from the left side but slower
3117db96d56Sopenharmony_cilookups in the middle. These objects are well suited for implementing queues
3127db96d56Sopenharmony_ciand breadth first tree searches::
3137db96d56Sopenharmony_ci
3147db96d56Sopenharmony_ci   >>> from collections import deque
3157db96d56Sopenharmony_ci   >>> d = deque(["task1", "task2", "task3"])
3167db96d56Sopenharmony_ci   >>> d.append("task4")
3177db96d56Sopenharmony_ci   >>> print("Handling", d.popleft())
3187db96d56Sopenharmony_ci   Handling task1
3197db96d56Sopenharmony_ci
3207db96d56Sopenharmony_ci::
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci   unsearched = deque([starting_node])
3237db96d56Sopenharmony_ci   def breadth_first_search(unsearched):
3247db96d56Sopenharmony_ci       node = unsearched.popleft()
3257db96d56Sopenharmony_ci       for m in gen_moves(node):
3267db96d56Sopenharmony_ci           if is_goal(m):
3277db96d56Sopenharmony_ci               return m
3287db96d56Sopenharmony_ci           unsearched.append(m)
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ciIn addition to alternative list implementations, the library also offers other
3317db96d56Sopenharmony_citools such as the :mod:`bisect` module with functions for manipulating sorted
3327db96d56Sopenharmony_cilists::
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci   >>> import bisect
3357db96d56Sopenharmony_ci   >>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
3367db96d56Sopenharmony_ci   >>> bisect.insort(scores, (300, 'ruby'))
3377db96d56Sopenharmony_ci   >>> scores
3387db96d56Sopenharmony_ci   [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
3397db96d56Sopenharmony_ci
3407db96d56Sopenharmony_ciThe :mod:`heapq` module provides functions for implementing heaps based on
3417db96d56Sopenharmony_ciregular lists.  The lowest valued entry is always kept at position zero.  This
3427db96d56Sopenharmony_ciis useful for applications which repeatedly access the smallest element but do
3437db96d56Sopenharmony_cinot want to run a full list sort::
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci   >>> from heapq import heapify, heappop, heappush
3467db96d56Sopenharmony_ci   >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
3477db96d56Sopenharmony_ci   >>> heapify(data)                      # rearrange the list into heap order
3487db96d56Sopenharmony_ci   >>> heappush(data, -5)                 # add a new entry
3497db96d56Sopenharmony_ci   >>> [heappop(data) for i in range(3)]  # fetch the three smallest entries
3507db96d56Sopenharmony_ci   [-5, 0, 1]
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci.. _tut-decimal-fp:
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ciDecimal Floating Point Arithmetic
3567db96d56Sopenharmony_ci=================================
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ciThe :mod:`decimal` module offers a :class:`~decimal.Decimal` datatype for
3597db96d56Sopenharmony_cidecimal floating point arithmetic.  Compared to the built-in :class:`float`
3607db96d56Sopenharmony_ciimplementation of binary floating point, the class is especially helpful for
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci* financial applications and other uses which require exact decimal
3637db96d56Sopenharmony_ci  representation,
3647db96d56Sopenharmony_ci* control over precision,
3657db96d56Sopenharmony_ci* control over rounding to meet legal or regulatory requirements,
3667db96d56Sopenharmony_ci* tracking of significant decimal places, or
3677db96d56Sopenharmony_ci* applications where the user expects the results to match calculations done by
3687db96d56Sopenharmony_ci  hand.
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_ciFor example, calculating a 5% tax on a 70 cent phone charge gives different
3717db96d56Sopenharmony_ciresults in decimal floating point and binary floating point. The difference
3727db96d56Sopenharmony_cibecomes significant if the results are rounded to the nearest cent::
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_ci   >>> from decimal import *
3757db96d56Sopenharmony_ci   >>> round(Decimal('0.70') * Decimal('1.05'), 2)
3767db96d56Sopenharmony_ci   Decimal('0.74')
3777db96d56Sopenharmony_ci   >>> round(.70 * 1.05, 2)
3787db96d56Sopenharmony_ci   0.73
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ciThe :class:`~decimal.Decimal` result keeps a trailing zero, automatically
3817db96d56Sopenharmony_ciinferring four place significance from multiplicands with two place
3827db96d56Sopenharmony_cisignificance.  Decimal reproduces mathematics as done by hand and avoids
3837db96d56Sopenharmony_ciissues that can arise when binary floating point cannot exactly represent
3847db96d56Sopenharmony_cidecimal quantities.
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ciExact representation enables the :class:`~decimal.Decimal` class to perform
3877db96d56Sopenharmony_cimodulo calculations and equality tests that are unsuitable for binary floating
3887db96d56Sopenharmony_cipoint::
3897db96d56Sopenharmony_ci
3907db96d56Sopenharmony_ci   >>> Decimal('1.00') % Decimal('.10')
3917db96d56Sopenharmony_ci   Decimal('0.00')
3927db96d56Sopenharmony_ci   >>> 1.00 % 0.10
3937db96d56Sopenharmony_ci   0.09999999999999995
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci   >>> sum([Decimal('0.1')]*10) == Decimal('1.0')
3967db96d56Sopenharmony_ci   True
3977db96d56Sopenharmony_ci   >>> sum([0.1]*10) == 1.0
3987db96d56Sopenharmony_ci   False
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ciThe :mod:`decimal` module provides arithmetic with as much precision as needed::
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci   >>> getcontext().prec = 36
4037db96d56Sopenharmony_ci   >>> Decimal(1) / Decimal(7)
4047db96d56Sopenharmony_ci   Decimal('0.142857142857142857142857142857142857')
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ci
407