1.. _tut-brieftour:
2
3**********************************
4Brief Tour of the Standard Library
5**********************************
6
7
8.. _tut-os-interface:
9
10Operating System Interface
11==========================
12
13The :mod:`os` module provides dozens of functions for interacting with the
14operating system::
15
16   >>> import os
17   >>> os.getcwd()      # Return the current working directory
18   'C:\\Python38'
19   >>> os.chdir('/server/accesslogs')   # Change current working directory
20   >>> os.system('mkdir today')   # Run the command mkdir in the system shell
21   0
22
23Be sure to use the ``import os`` style instead of ``from os import *``.  This
24will keep :func:`os.open` from shadowing the built-in :func:`open` function which
25operates much differently.
26
27.. index:: builtin: help
28
29The built-in :func:`dir` and :func:`help` functions are useful as interactive
30aids for working with large modules like :mod:`os`::
31
32   >>> import os
33   >>> dir(os)
34   <returns a list of all module functions>
35   >>> help(os)
36   <returns an extensive manual page created from the module's docstrings>
37
38For daily file and directory management tasks, the :mod:`shutil` module provides
39a higher level interface that is easier to use::
40
41   >>> import shutil
42   >>> shutil.copyfile('data.db', 'archive.db')
43   'archive.db'
44   >>> shutil.move('/build/executables', 'installdir')
45   'installdir'
46
47
48.. _tut-file-wildcards:
49
50File Wildcards
51==============
52
53The :mod:`glob` module provides a function for making file lists from directory
54wildcard searches::
55
56   >>> import glob
57   >>> glob.glob('*.py')
58   ['primes.py', 'random.py', 'quote.py']
59
60
61.. _tut-command-line-arguments:
62
63Command Line Arguments
64======================
65
66Common utility scripts often need to process command line arguments. These
67arguments are stored in the :mod:`sys` module's *argv* attribute as a list.  For
68instance the following output results from running ``python demo.py one two
69three`` at the command line::
70
71   >>> import sys
72   >>> print(sys.argv)
73   ['demo.py', 'one', 'two', 'three']
74
75The :mod:`argparse` module provides a more sophisticated mechanism to process
76command line arguments.  The following script extracts one or more filenames
77and an optional number of lines to be displayed::
78
79    import argparse
80
81    parser = argparse.ArgumentParser(prog = 'top',
82        description = 'Show top lines from each file')
83    parser.add_argument('filenames', nargs='+')
84    parser.add_argument('-l', '--lines', type=int, default=10)
85    args = parser.parse_args()
86    print(args)
87
88When run at the command line with ``python top.py --lines=5 alpha.txt
89beta.txt``, the script sets ``args.lines`` to ``5`` and ``args.filenames``
90to ``['alpha.txt', 'beta.txt']``.
91
92
93.. _tut-stderr:
94
95Error Output Redirection and Program Termination
96================================================
97
98The :mod:`sys` module also has attributes for *stdin*, *stdout*, and *stderr*.
99The latter is useful for emitting warnings and error messages to make them
100visible even when *stdout* has been redirected::
101
102   >>> sys.stderr.write('Warning, log file not found starting a new one\n')
103   Warning, log file not found starting a new one
104
105The most direct way to terminate a script is to use ``sys.exit()``.
106
107
108.. _tut-string-pattern-matching:
109
110String Pattern Matching
111=======================
112
113The :mod:`re` module provides regular expression tools for advanced string
114processing. For complex matching and manipulation, regular expressions offer
115succinct, optimized solutions::
116
117   >>> import re
118   >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
119   ['foot', 'fell', 'fastest']
120   >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
121   'cat in the hat'
122
123When only simple capabilities are needed, string methods are preferred because
124they are easier to read and debug::
125
126   >>> 'tea for too'.replace('too', 'two')
127   'tea for two'
128
129
130.. _tut-mathematics:
131
132Mathematics
133===========
134
135The :mod:`math` module gives access to the underlying C library functions for
136floating point math::
137
138   >>> import math
139   >>> math.cos(math.pi / 4)
140   0.70710678118654757
141   >>> math.log(1024, 2)
142   10.0
143
144The :mod:`random` module provides tools for making random selections::
145
146   >>> import random
147   >>> random.choice(['apple', 'pear', 'banana'])
148   'apple'
149   >>> random.sample(range(100), 10)   # sampling without replacement
150   [30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
151   >>> random.random()    # random float
152   0.17970987693706186
153   >>> random.randrange(6)    # random integer chosen from range(6)
154   4
155
156The :mod:`statistics` module calculates basic statistical properties
157(the mean, median, variance, etc.) of numeric data::
158
159    >>> import statistics
160    >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
161    >>> statistics.mean(data)
162    1.6071428571428572
163    >>> statistics.median(data)
164    1.25
165    >>> statistics.variance(data)
166    1.3720238095238095
167
168The SciPy project <https://scipy.org> has many other modules for numerical
169computations.
170
171.. _tut-internet-access:
172
173Internet Access
174===============
175
176There are a number of modules for accessing the internet and processing internet
177protocols. Two of the simplest are :mod:`urllib.request` for retrieving data
178from URLs and :mod:`smtplib` for sending mail::
179
180   >>> from urllib.request import urlopen
181   >>> with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response:
182   ...     for line in response:
183   ...         line = line.decode('utf-8')  # Decoding the binary data to text.
184   ...         if 'EST' in line or 'EDT' in line:  # look for Eastern Time
185   ...             print(line)
186
187   <BR>Nov. 25, 09:43:32 PM EST
188
189   >>> import smtplib
190   >>> server = smtplib.SMTP('localhost')
191   >>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
192   ... """To: jcaesar@example.org
193   ... From: soothsayer@example.org
194   ...
195   ... Beware the Ides of March.
196   ... """)
197   >>> server.quit()
198
199(Note that the second example needs a mailserver running on localhost.)
200
201
202.. _tut-dates-and-times:
203
204Dates and Times
205===============
206
207The :mod:`datetime` module supplies classes for manipulating dates and times in
208both simple and complex ways. While date and time arithmetic is supported, the
209focus of the implementation is on efficient member extraction for output
210formatting and manipulation.  The module also supports objects that are timezone
211aware. ::
212
213   >>> # dates are easily constructed and formatted
214   >>> from datetime import date
215   >>> now = date.today()
216   >>> now
217   datetime.date(2003, 12, 2)
218   >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
219   '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'
220
221   >>> # dates support calendar arithmetic
222   >>> birthday = date(1964, 7, 31)
223   >>> age = now - birthday
224   >>> age.days
225   14368
226
227
228.. _tut-data-compression:
229
230Data Compression
231================
232
233Common data archiving and compression formats are directly supported by modules
234including: :mod:`zlib`, :mod:`gzip`, :mod:`bz2`, :mod:`lzma`, :mod:`zipfile` and
235:mod:`tarfile`. ::
236
237   >>> import zlib
238   >>> s = b'witch which has which witches wrist watch'
239   >>> len(s)
240   41
241   >>> t = zlib.compress(s)
242   >>> len(t)
243   37
244   >>> zlib.decompress(t)
245   b'witch which has which witches wrist watch'
246   >>> zlib.crc32(s)
247   226805979
248
249
250.. _tut-performance-measurement:
251
252Performance Measurement
253=======================
254
255Some Python users develop a deep interest in knowing the relative performance of
256different approaches to the same problem. Python provides a measurement tool
257that answers those questions immediately.
258
259For example, it may be tempting to use the tuple packing and unpacking feature
260instead of the traditional approach to swapping arguments. The :mod:`timeit`
261module quickly demonstrates a modest performance advantage::
262
263   >>> from timeit import Timer
264   >>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
265   0.57535828626024577
266   >>> Timer('a,b = b,a', 'a=1; b=2').timeit()
267   0.54962537085770791
268
269In contrast to :mod:`timeit`'s fine level of granularity, the :mod:`profile` and
270:mod:`pstats` modules provide tools for identifying time critical sections in
271larger blocks of code.
272
273
274.. _tut-quality-control:
275
276Quality Control
277===============
278
279One approach for developing high quality software is to write tests for each
280function as it is developed and to run those tests frequently during the
281development process.
282
283The :mod:`doctest` module provides a tool for scanning a module and validating
284tests embedded in a program's docstrings.  Test construction is as simple as
285cutting-and-pasting a typical call along with its results into the docstring.
286This improves the documentation by providing the user with an example and it
287allows the doctest module to make sure the code remains true to the
288documentation::
289
290   def average(values):
291       """Computes the arithmetic mean of a list of numbers.
292
293       >>> print(average([20, 30, 70]))
294       40.0
295       """
296       return sum(values) / len(values)
297
298   import doctest
299   doctest.testmod()   # automatically validate the embedded tests
300
301The :mod:`unittest` module is not as effortless as the :mod:`doctest` module,
302but it allows a more comprehensive set of tests to be maintained in a separate
303file::
304
305   import unittest
306
307   class TestStatisticalFunctions(unittest.TestCase):
308
309       def test_average(self):
310           self.assertEqual(average([20, 30, 70]), 40.0)
311           self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
312           with self.assertRaises(ZeroDivisionError):
313               average([])
314           with self.assertRaises(TypeError):
315               average(20, 30, 70)
316
317   unittest.main()  # Calling from the command line invokes all tests
318
319
320.. _tut-batteries-included:
321
322Batteries Included
323==================
324
325Python has a "batteries included" philosophy.  This is best seen through the
326sophisticated and robust capabilities of its larger packages. For example:
327
328* The :mod:`xmlrpc.client` and :mod:`xmlrpc.server` modules make implementing
329  remote procedure calls into an almost trivial task.  Despite the modules
330  names, no direct knowledge or handling of XML is needed.
331
332* The :mod:`email` package is a library for managing email messages, including
333  MIME and other :rfc:`2822`-based message documents. Unlike :mod:`smtplib` and
334  :mod:`poplib` which actually send and receive messages, the email package has
335  a complete toolset for building or decoding complex message structures
336  (including attachments) and for implementing internet encoding and header
337  protocols.
338
339* The :mod:`json` package provides robust support for parsing this
340  popular data interchange format.  The :mod:`csv` module supports
341  direct reading and writing of files in Comma-Separated Value format,
342  commonly supported by databases and spreadsheets.  XML processing is
343  supported by the :mod:`xml.etree.ElementTree`, :mod:`xml.dom` and
344  :mod:`xml.sax` packages. Together, these modules and packages
345  greatly simplify data interchange between Python applications and
346  other tools.
347
348* The :mod:`sqlite3` module is a wrapper for the SQLite database
349  library, providing a persistent database that can be updated and
350  accessed using slightly nonstandard SQL syntax.
351
352* Internationalization is supported by a number of modules including
353  :mod:`gettext`, :mod:`locale`, and the :mod:`codecs` package.
354