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