Skip to content

Commit 67a7a88

Browse files
committed
🎨 Rearrange string type and save data sections
1 parent 5b8c0d2 commit 67a7a88

File tree

18 files changed

+1273
-1155
lines changed

18 files changed

+1273
-1155
lines changed

docs/appendix/checks.rst

Lines changed: 136 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,8 @@ Checks
306306
File "<stdin>", line 1, in <module>
307307
TypeError: can't multiply sequence by non-int of type 'complex'
308308
309-
* How can you change a heading such as ``variables and expressions`` so that it
310-
contains hyphens instead of spaces and can therefore be better used as a file
311-
name?
312-
313-
.. code-block:: pycon
314-
315-
>>> ve = "variables and expressions"
316-
>>> "-".join(ve.split())
317-
'variables-and-expressions'
309+
:doc:`/types/strings/operators-functions`
310+
-----------------------------------------
318311

319312
* Which of the following strings cannot be converted into numbers and why?
320313

@@ -337,6 +330,16 @@ Checks
337330
338331
.. blacken-docs:on
339332
333+
* How can you change a heading such as ``variables and expressions`` so that it
334+
contains hyphens instead of spaces and can therefore be better used as a file
335+
name?
336+
337+
.. code-block:: pycon
338+
339+
>>> ve = "variables and expressions"
340+
>>> "-".join(ve.split())
341+
'variables-and-expressions'
342+
340343
* If you want to check whether a line begins with ``.. note::``, which method
341344
would you use? Are there any other options?
342345

@@ -368,6 +371,9 @@ Checks
368371
>>> hipy.translate(subs)
369372
'Hello-Pythonistas--'
370373
374+
:doc:`/types/strings/built-in-modules/re`
375+
-----------------------------------------
376+
371377
* Which regular expression would you use to find strings that represent the
372378
numbers between -3 and +3?
373379

@@ -383,127 +389,8 @@ Checks
383389
upper case ``x``, followed by one or more characters in the ranges
384390
``0-9``, ``a-f`` or ``A-F``.
385391

386-
:doc:`/types/files`
387-
-------------------
388-
389-
* Uses the functions of the :mod:`python3:os` module to take a path to a file
390-
named :file:`example.log` and create a new file path in the same directory for
391-
a file named :file:`example.log1`.
392-
393-
.. code-block:: pycon
394-
395-
>>> import os
396-
>>> path = os.path.abspath("example.log")
397-
>>> print(path)
398-
/Users/veit/python-basics-tutorial-de/example.log
399-
>>> new_path = f"{path}2"
400-
>>> print(new_path)
401-
/Users/veit/python-basics-tutorial-de/example.log2
402-
403-
* What is the significance of adding ``b`` as a parameter to
404-
:func:`python3:open`?
405-
406-
This opens the file in binary mode, which means that bytes and not characters
407-
are read and written.
408-
409-
* Open a file :file:`my_file.txt` and insert additional text at the end of the
410-
file. Which command would you use to open :file:`my_file.txt`? Which command
411-
would you use to reopen the file and read it from the beginning?
412-
413-
.. code-block:: pycon
414-
415-
>>> with open("my_file", "a") as f:
416-
... f.write("Hi, Pythinistas!\n")
417-
...
418-
17
419-
>>> with open("my_file") as f:
420-
... print(f.readlines())
421-
...
422-
['Hi, Pythinistas!\n', 'Hi, Pythinistas!\n']
423-
424-
* What use cases can you imagine in which the :mod:`python3:struct` module would
425-
be useful for reading or writing binary data?
426-
427-
* when reading and writing a binary file
428-
* when reading from an external interface, where the data should be stored
429-
exactly as it was transmitted
430-
431-
* Why :doc:`pickle <python3:library/pickle>` may or may not be suitable for the
432-
following use cases:
433-
434-
#. Saving some state variables from one run to the next ✅
435-
#. Storing evaluation results ❌, as pickle is dependent on the respective
436-
Python version
437-
#. Saving user names and passwords ❌, as pickles are not secure
438-
#. Saving a large dictionary with English terms ❌, as the entire pickle would
439-
have to be loaded into memory
440-
441-
* If you look at the `man page for the wc utility
442-
<https://linux.die.net/man/1/wc>`_, you will see two command line options:
443-
444-
``-c``
445-
counts the bytes in the file
446-
``-m``
447-
counts the characters, which in the case of some Unicode characters can be
448-
two or more bytes long
449-
450-
Also, if a file is specified, our module should read from and process that
451-
file, but if no file is specified, it should read from and process ``stdin``.
452-
453-
.. seealso::
454-
:ref:`_wcargv_stdin.py <wcargv_stdin>`
455-
456-
* If a context manager is used in a script that reads and/or writes multiple
457-
files, which of the following approaches do you think would be best?
458-
459-
#. Put the entire script in a block managed by a ``with`` statement.
460-
#. Use one ``with`` statement for all reads and another for all writes.
461-
#. Use a ``with`` statement every time you read or write a file, that is, for
462-
every line.
463-
#. Use a ``with`` statement for each file you read or write.
464-
465-
Probably 4. is the best approach as part of the context manager’s job when
466-
accessing files is to ensure that a file is closed.
467-
468-
* Archive :file:`*.txt` files from the current directory in the :file:`archive`
469-
directory as :file:`*.zip` files with the current date as the file name.
470-
471-
* Which modules do you need for this?
472-
473-
:mod:`python3:datetime`, :mod:`python3:pathlib` and :mod:`python3:zipfile`.
474-
475-
* Write a possible solution.
476-
477-
.. code-block:: pycon
478-
:linenos:
479-
480-
>>> import datetime
481-
>>> import pathlib
482-
>>> import zipfile
483-
>>> file_pattern = "*.txt"
484-
>>> archive_path = "archive"
485-
>>> today = f"{datetime.date.today():%Y-%m-%d}"
486-
>>> cur_path = pathlib.Path(".")
487-
>>> paths = cur_path.glob(file_pattern)
488-
>>> zip_path = cur_path.joinpath(archive_path, today + ".zip")
489-
>>> zip_file = zipfile.ZipFile(str(zip_path), "w")
490-
>>> for path in paths:
491-
... zip_file.write(str(path))
492-
... path.unlink()
493-
...
494-
495-
Line 9
496-
creates the path to the ZIP file in the archive directory.
497-
Line 10
498-
opens the new ZIP file object for writing; :func:`str` is required to
499-
convert a path into a character string.
500-
Line 12
501-
writes the current file to the ZIP file.
502-
Line 13
503-
removes the current file from the working directory.
504-
505-
:doc:`/input`
506-
-------------
392+
:doc:`/types/strings/input`
393+
---------------------------
507394

508395
* How can you get string and integer values with the :func:`input` function?
509396

@@ -1083,3 +970,122 @@ Checks
1083970
.. seealso::
1084971
You can find a complete example at `github.com/veit/items
1085972
<https://github.com/veit/items/>`_.
973+
974+
:doc:`/save-data/files`
975+
-----------------------
976+
977+
* Uses the functions of the :mod:`python3:os` module to take a path to a file
978+
named :file:`example.log` and create a new file path in the same directory for
979+
a file named :file:`example.log1`.
980+
981+
.. code-block:: pycon
982+
983+
>>> import os
984+
>>> path = os.path.abspath("example.log")
985+
>>> print(path)
986+
/Users/veit/python-basics-tutorial-de/example.log
987+
>>> new_path = f"{path}2"
988+
>>> print(new_path)
989+
/Users/veit/python-basics-tutorial-de/example.log2
990+
991+
* What is the significance of adding ``b`` as a parameter to
992+
:func:`python3:open`?
993+
994+
This opens the file in binary mode, which means that bytes and not characters
995+
are read and written.
996+
997+
* Open a file :file:`my_file.txt` and insert additional text at the end of the
998+
file. Which command would you use to open :file:`my_file.txt`? Which command
999+
would you use to reopen the file and read it from the beginning?
1000+
1001+
.. code-block:: pycon
1002+
1003+
>>> with open("my_file", "a") as f:
1004+
... f.write("Hi, Pythinistas!\n")
1005+
...
1006+
17
1007+
>>> with open("my_file") as f:
1008+
... print(f.readlines())
1009+
...
1010+
['Hi, Pythinistas!\n', 'Hi, Pythinistas!\n']
1011+
1012+
* What use cases can you imagine in which the :mod:`python3:struct` module would
1013+
be useful for reading or writing binary data?
1014+
1015+
* when reading and writing a binary file
1016+
* when reading from an external interface, where the data should be stored
1017+
exactly as it was transmitted
1018+
1019+
* Why :doc:`pickle <python3:library/pickle>` may or may not be suitable for the
1020+
following use cases:
1021+
1022+
#. Saving some state variables from one run to the next ✅
1023+
#. Storing evaluation results ❌, as pickle is dependent on the respective
1024+
Python version
1025+
#. Saving user names and passwords ❌, as pickles are not secure
1026+
#. Saving a large dictionary with English terms ❌, as the entire pickle would
1027+
have to be loaded into memory
1028+
1029+
* If you look at the `man page for the wc utility
1030+
<https://linux.die.net/man/1/wc>`_, you will see two command line options:
1031+
1032+
``-c``
1033+
counts the bytes in the file
1034+
``-m``
1035+
counts the characters, which in the case of some Unicode characters can be
1036+
two or more bytes long
1037+
1038+
Also, if a file is specified, our module should read from and process that
1039+
file, but if no file is specified, it should read from and process ``stdin``.
1040+
1041+
.. seealso::
1042+
:ref:`_wcargv_stdin.py <wcargv_stdin>`
1043+
1044+
* If a context manager is used in a script that reads and/or writes multiple
1045+
files, which of the following approaches do you think would be best?
1046+
1047+
#. Put the entire script in a block managed by a ``with`` statement.
1048+
#. Use one ``with`` statement for all reads and another for all writes.
1049+
#. Use a ``with`` statement every time you read or write a file, that is, for
1050+
every line.
1051+
#. Use a ``with`` statement for each file you read or write.
1052+
1053+
Probably 4. is the best approach as part of the context manager’s job when
1054+
accessing files is to ensure that a file is closed.
1055+
1056+
* Archive :file:`*.txt` files from the current directory in the :file:`archive`
1057+
directory as :file:`*.zip` files with the current date as the file name.
1058+
1059+
* Which modules do you need for this?
1060+
1061+
:mod:`python3:datetime`, :mod:`python3:pathlib` and :mod:`python3:zipfile`.
1062+
1063+
* Write a possible solution.
1064+
1065+
.. code-block:: pycon
1066+
:linenos:
1067+
1068+
>>> import datetime
1069+
>>> import pathlib
1070+
>>> import zipfile
1071+
>>> file_pattern = "*.txt"
1072+
>>> archive_path = "archive"
1073+
>>> today = f"{datetime.date.today():%Y-%m-%d}"
1074+
>>> cur_path = pathlib.Path(".")
1075+
>>> paths = cur_path.glob(file_pattern)
1076+
>>> zip_path = cur_path.joinpath(archive_path, today + ".zip")
1077+
>>> zip_file = zipfile.ZipFile(str(zip_path), "w")
1078+
>>> for path in paths:
1079+
... zip_file.write(str(path))
1080+
... path.unlink()
1081+
...
1082+
1083+
Line 9
1084+
creates the path to the ZIP file in the archive directory.
1085+
Line 10
1086+
opens the new ZIP file object for writing; :func:`str` is required to
1087+
convert a path into a character string.
1088+
Line 12
1089+
writes the current file to the ZIP file.
1090+
Line 13
1091+
removes the current file from the working directory.

docs/control-flows/with.rst

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,82 @@
11
Context management with ``with``
22
================================
33

4-
A more rational way to encapsulate the ``try-except-finally`` pattern is to use
5-
the keyword ``with`` and a context manager. Python defines context managers for
6-
things like :doc:`file </types/files>` access and custom context managers. One
7-
advantage of context managers is that they can define default clean-up actions
8-
that are always executed, whether an exception occurs or not.
4+
A more rational way to encapsulate the ``try``-``except``-``finally`` pattern is
5+
to use the keyword ``with`` and a context manager. Python defines context
6+
managers for things like accessing :doc:`files </save-data/files>` and custom
7+
context managers. One advantage of context managers is that they can define
8+
cleanup actions that are always executed, regardless of whether an exception
9+
occurs or not.
910

10-
The following listing shows opening and reading a file using ``with`` and a
11+
.. seealso::
12+
:doc:`python3:library/contextlib`
13+
14+
Opening and closing files
15+
-------------------------
16+
17+
The following list shows the opening and reading of a file using ``with`` and a
1118
context manager.
1219

1320
.. literalinclude:: with.py
1421
:linenos:
1522

16-
A context manager is set up here that encloses the ``open`` function and the
17-
block that follows it. The predefined clean-up action of the context manager
18-
closes the file even if an exception occurs. As long as the expression in the
19-
first line is executed without throwing an exception, the file is always closed.
20-
This code is equivalent to this code:
23+
A context manager is set up here, which encloses the :func:`open` function and
24+
the subsequent block. The predefined clean-up action of the context manager
25+
closes the file, even if an exception occurs. As long as the expression in the
26+
first line is executed without triggering an exception, the file is always
27+
closed. This code is equivalent to this code:
2128

2229
.. literalinclude:: with_alt.py
2330
:linenos:
31+
32+
.. seealso::
33+
* :doc:`../save-data/files`
34+
35+
Locking
36+
-------
37+
38+
:class:`threading.Lock` can be used with ``try``-``finally``:
39+
40+
.. code-block:: Python
41+
42+
lock = threading.Lock()
43+
44+
try:
45+
print("a Job")
46+
print("another Job")
47+
finally:
48+
lock.release()
49+
50+
However, using the context manager is more elegant:
51+
52+
.. code-block:: Python
53+
54+
with lock:
55+
print("a Job")
56+
print("another Job")
57+
58+
.. seealso::
59+
`Careful threading with locks
60+
<https://www.python4data.science/en/latest/performance/threading-example.html#Careful-threading-with-locks>`_
61+
62+
Suppressing exceptions
63+
----------------------
64+
65+
Context managers can also be used to suppress the output of :doc:`exceptions`
66+
and continue execution.
67+
68+
.. code-block:: Python
69+
70+
try:
71+
os.remove("somefile.tmp")
72+
except FileNotFoundError:
73+
pass
74+
75+
This can be written more elegantly as:
76+
77+
.. code-block:: Python
78+
79+
from contextlib import suppress
80+
81+
with suppress(FileNotFoundError):
82+
os.remove("somefile.tmp")

docs/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ Follow us on…
124124
style
125125
variables-expressions
126126
types/index
127-
input
128127
control-flows/index
129128
functions/index
130129
modules/index

0 commit comments

Comments
 (0)