Skip to content

Commit 4ffb24a

Browse files
committed
several textual improvements
1 parent 7962dad commit 4ffb24a

File tree

15 files changed

+248
-158
lines changed

15 files changed

+248
-158
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ Die Slides zum Kurs in deutscher Sprache können unter <https://thomasweise.gith
3636
11. [Der Datentyp `str`](https://thomasweise.github.io/programmingWithPythonSlidesDE/11_str.pdf)
3737
12. [`None`](https://thomasweise.github.io/programmingWithPythonSlidesDE/12_none.pdf)
3838
13. [Variablen: Wertzuweisung](https://thomasweise.github.io/programmingWithPythonSlidesDE/13_variablen_wertzuweisung.pdf)
39-
14. [Fehler im Kode mit Exceptions und IDE finden](https://thomasweise.github.io/programmingWithPythonSlidesDE/14_fehler_im_kode_mit_exceptions_und_ide_finden.pdf)
40-
15. [Variablentypen und Type Hints](https://thomasweise.github.io/programmingWithPythonSlidesDE/15_variablentypen_und_type_hints.pdf)
39+
14. [Zwischenspiel: Fehler im Kode mit Exceptions und IDE finden](https://thomasweise.github.io/programmingWithPythonSlidesDE/14_fehler_im_kode_mit_exceptions_und_ide_finden.pdf)
40+
15. [Variablen: Typen und Type Hints](https://thomasweise.github.io/programmingWithPythonSlidesDE/15_variablen_typen_und_type_hints.pdf)
41+
16. [Gleichheit und Identität](https://thomasweise.github.io/programmingWithPythonSlidesDE/16_gleichheit_und_identität.pdf)
42+
17. [Listen](https://thomasweise.github.io/programmingWithPythonSlidesDE/17_listen.pdf)
43+
18. [Zwischenspiel: Der Linter Ruff](https://thomasweise.github.io/programmingWithPythonSlidesDE/18_ruff.pdf)
44+
19. [Tuples](https://thomasweise.github.io/programmingWithPythonSlidesDE/19_tuples.pdf)
45+
20. [Mengen](https://thomasweise.github.io/programmingWithPythonSlidesDE/20_mengen.pdf)
46+
21. [Dictionaries oder Hash Maps](https://thomasweise.github.io/programmingWithPythonSlidesDE/21_dictionaries.pdf)
47+
4148

4249
### 2.3. The Slides in English
4350
The slides for the course are available at <https://thomasweise.github.io/programmingWithPythonSlides> and also listed below.

text/main/basics/collections/collections.tex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
\label{sec:collections}%
33
%
44
We already learned about simple datatypes, like integer and floating point numbers, strings, and Boolean values.
5-
We also learned how we can use variables to store instances (objects) of such datatypes.
5+
We also learned how we can use a variable to store one instance (object) of such a datatype.
66
However, in many cases, we do not just want to store a single object.
77
Often, we want to store and process \emph{collections} of objects~\cite{PSF:P3D:TPSL:BIT,PSF:P3D:TPLR:DM,PSF:P3D:TPSL:CAABCFC}.
88
\python\ offers us four basic types of collections:
99

1010
The first one, \emph{lists}, are mutable sequences of objects.
11-
We can create a list \pythonil{my_list} composed of the three strings \pythonil{"a"}, \pythonil{"b"}, and~\pythonil{"c"} by writing \pythonil{my_list = ["a", "b", "c"]}.
11+
We can create a list variable~\pythonil{my_list} composed of the three strings~\pythonil{"ax"}, \pythonil{"by"}, and~\pythonil{"cz"} by writing~\pythonil{my_list = ["ax", "by", "cz"]}.
1212
Like the characters in strings, we can access the elements of lists using square brackets.
13-
For instance, \pythonil{my_list[0]} would return the first element of \pythonil{my_list}, namely~\pythonil{"a"}.
13+
For instance, \pythonil{my_list[0]} would return the first element of \pythonil{my_list}, namely~\pythonil{"ax"}.
1414
In \cref{sec:lists} we learn more about lists and we also get to know a new static code analysis tool that can help us to detect programming issues.
1515

1616
The second type of collections is formed by \emph{tuples}.
@@ -37,6 +37,7 @@
3737
%
3838
%
3939
\hinput{lists}{lists.tex}%
40+
\hinput{ruff}{ruff.tex}%
4041
\hinput{tuples}{tuples.tex}%
4142
\hinput{sets}{sets.tex}%
4243
\hinput{dictionaries}{dictionaries.tex}%
Lines changed: 15 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
\hsection{Lists}%
22
\label{sec:lists}%
33
%
4-
A \pythonilIdx{list} is a mutable sequence of objects which can be accessed via their index~\cite{PSF:P3D:TPLR:S}.
5-
They work very similar to the strings we already discussed in \cref{sec:str}, but instead of characters, they can contain any kind of objects and they can be modified.%
6-
%
7-
\hsection{Basic Functionality and Examples}%
8-
\label{sec:lists:basicFunctions}%
9-
%
104
\gitLoadAndExecPython{lists:lists_1}{}{collections}{lists_1.py}{}%
115
\listingPythonAndOutput{lists:lists_1}{%
126
A first example for using lists in \python:~creating, indexing, printing of and appending elements and other lists to lists.}{}%
@@ -19,6 +13,9 @@
1913
\listingPythonAndOutput{lists:lists_3}{%
2014
A third example of using lists in \python: slicing, adding, and multiplying lists.}{}%
2115
%
16+
A \pythonilIdx{list} is a mutable sequence of objects which can be accessed via their index~\cite{PSF:P3D:TPLR:S}.
17+
They work very similar to the strings we already discussed in \cref{sec:str}, but instead of (only) characters, they can contain any kind of objects and they can be modified.
18+
2219
In \cref{lst:lists:lists_1}, we provide some first examples for using lists.
2320
A list can be defined by simply writing its contents, separated by~\pythonilIdx{,} inside square brackets~\pythonil{[...]}\pythonIdx{[\idxdots]}.
2421
\pythonil{["apple", "pear", "orange"]} creates a list with three elements, namely the strings \pythonil{"apple"}, \pythonil{"pear"}, and~\pythonil{"orange"}.
@@ -117,134 +114,30 @@
117114
If~\pythonil{i} is omitted, i.e., if \pythonil{:j:k} is provided, then \pythonil{i=0} is assumed.
118115
If~\pythonil{j} is omitted, i.e., if \pythonil{i::k} is provided, then \pythonil{j=len(l)} is assumed.
119116

120-
If you have a list \pythonil{l4 = [5, 6, 7, 5, 6, 7, 5, 6, 7]}, then the slice~\pythonil{l4[2:-2]} will return a new list which contains all the elements of~\pythonil{l4} starting from index~\pythonil{2} and up to (excluding) the second-to-last element.
121-
The slice~\pythonil{l4[1::2]} starts at index~\pythonil{1}, continues until the end of the list, and adds every second element.
117+
If you have a list \pythonil{lst4 = [5, 6, 7, 5, 6, 7, 5, 6, 7]}, then the slice~\pythonil{lst4[2:-2]} will return a new list which contains all the elements of~\pythonil{lst4} starting from index~\pythonil{2} and up to (excluding) the second-to-last element.
118+
The slice~\pythonil{lst4[1::2]} starts at index~\pythonil{1}, continues until the end of the list, and adds every second element.
122119
This results in~\pythonil{[6, 5, 7, 6]}.
123-
As final example, consider the slice~\pythonil{l4[-1:3:-2]}.
120+
As final example, consider the slice~\pythonil{lst4[-1:3:-2]}.
124121
It will begin creating the new list at the last element.
125122
The step-length is~\pythonil{-2}, so it will move backwards and add every second element to the new list.
126123
It stops adding elements before reaching index~\pythonil{3}.
127-
Therefore, the result will be the new list~\pythonil{l7 = [7, 5, 6]}.
124+
Therefore, the result will be the new list~\pythonil{lst7 = [7, 5, 6]}.
128125

129126
Notice that the slices\pythonIdx{slice} we create are independent copies of ranges of the original lists.
130-
The list~\pythonil{l7} is a slice from the list~\pythonil{l4}.
131-
If we modify it, e.g., set \pythonil{l7[1] = 12}, then we set the second element of~\pythonil{l7} to~\pythonil{12}.
132-
\pythonil{l7}~becomes~\pythonil{[7, 12, 6]}.
133-
Now, the second element of~\pythonil{l7} originally is the seventh element of~\pythonil{l4}, namely the \pythonil{5} located at index~\pythonil{6}, which is equivalent to index~\pythonil{-3}.
127+
The list~\pythonil{lst7} is a slice from the list~\pythonil{lst4}.
128+
If we modify it, e.g., set \pythonil{lst7[1] = 12}, then we set the second element of~\pythonil{lst7} to~\pythonil{12}.
129+
\pythonil{lst7}~becomes~\pythonil{[7, 12, 6]}.
130+
Now, the second element of~\pythonil{lst7} originally is the seventh element of~\pythonil{lst4}, namely the \pythonil{5} located at index~\pythonil{6}, which is equivalent to index~\pythonil{-3}.
134131
You may wonder whether this element now also has changed.
135132
It did not.
136-
\pythonil{l4} remains unchanged by any operation on the independent copied slice~\pythonil{l7}.
133+
\pythonil{lst4} remains unchanged by any operation on the independent copied slice~\pythonil{lst7}.
137134

138135
An interesting functionality is also list unpacking\pythonIdx{list!unpacking}\pythonIdx{unpacking}.
139-
In \cref{sec:strBasicOperations}, the list~\pythonil{l2} contains the three elements~\pythonil{[5, 6, 7]}.
136+
In \cref{sec:strBasicOperations}, the list~\pythonil{lst2} contains the three elements~\pythonil{[5, 6, 7]}.
140137
If we know the number of elements in the list in our program, then we can assign them to exactly the same number of variables.
141-
\pythonil{a, b, c = l2} creates and assigns values to three variables \pythonil{a=5}, \pythonil{b=6}, and \pythonil{c=7} by unpacking the list~\pythonil{l2}.%
142-
%
143-
\FloatBarrier%
144-
\endhsection%
145-
%
146-
\hsection{An Example of Errors and a new Tool}%
147-
\label{sec:listExampleForErrorsAndRuff}%
148-
%
149-
\gitLoadAndExecPython{lists:lists_error}{}{collections}{lists_error.py}{}%
150-
\listingPythonAndOutput{lists:lists_error}{%
151-
A program processing lists which exhibits some subtle errors and inefficiencies.}{}%
152-
%
153-
Now, in the previous chapter, we learned that static code analysis tools can help us to discover subtle problems in our programs.
154-
Obviously, when dealing with more complex datastructures like lists, there are also more potential problems, more mistakes that one could make.
155-
Let us look at the very short example \cref{lst:lists:lists_error}.
156-
The program consists of only two lines, \pythonil{my_list: list[str] = list([1, 2, 3])} and \pythonil{print(my_list)}.
157-
It does not have any \emph{error} in the strict sense.
158-
We can execute it just fine and it will produce the output \textil{[1, 2, 3]} as shown in \cref{exec:lists:lists_error}.
159-
160-
\gitExec{exec:lists:lists_error:mypy}{\programmingWithPythonCodeRepo}{.}{_scripts_/mypy.sh collections lists_error.py}%
161-
\listingToolOutput{lists:lists_error:mypy}{%
162-
The results of static type checking with \mypy\ of the program given in \cref{lst:lists:lists_error}.}
163-
164-
However, upon closer inspection, we discover some issues.
165-
In a first step, we would apply \mypy~(as~\cref{ut:mypy}) to check for problems with the types of variables.
166-
And indeed, \cref{exec:lists:lists_error:mypy} shows us \emph{three} errors!
167-
We defined \pythonil{my_list} as a list of strings by using the \pgls{typeHint} \pythonil{list[str]}.
168-
However, we then set its value to be a list of three integer numbers (hence, three errors).
169-
As promised in the title of this section, we will also use another tool to analyze this program:~\ruff.
170-
171-
\begin{figure}%
172-
\centering%
173-
\includegraphics[width=0.7\linewidth]{\currentDir/pipInstallRuff}%
174-
\caption{Installing \ruff\ in a \ubuntu\ \pgls{terminal} via \pip~(see \cref{sec:pipAndVenv} for a discussion of how packages can be installed).}%
175-
\label{fig:pipInstallRuff}%
176-
\end{figure}%
138+
\pythonil{a, b, c = lst2} creates and assigns values to three variables \pythonil{a=5}, \pythonil{b=6}, and \pythonil{c=7} by unpacking the list~\pythonil{lst2}.
139+
Of course, this only works if list~\pythonil{lst2} has exactly length~3.%
177140
%
178141
\FloatBarrier%
179-
%
180-
\usefulTool{ruff}{%
181-
\ruff\ is a very fast \python\ \pgls{linter} that checks the code for all kinds of problems, ranging from formatting and style issues over missing documentation to performance problems and potential errors~\cite{M2022RAEFPLACFWIR}. %
182-
It can be installed via \bashil{pip install ruff} as shown in \cref{fig:pipInstallRuff} on \cpageref{fig:pipInstallRuff}. %
183-
You can then apply \ruff\ using the command \bashil{ruff check fileToScan.py}. %
184-
We provide a script for using \ruff\ with a reasonable default configuration in \cref{lst:bash:ruff} on \cpageref{lst:bash:ruff}.%
185-
}%
186-
%
187-
\gitExec{exec:lists:lists_error:ruff}{\programmingWithPythonCodeRepo}{.}{_scripts_/ruff.sh collections lists_error.py}%
188-
\listingToolOutput{lists:lists_error:ruff}{%
189-
The results of linting with \ruff\ of the program given in \cref{lst:lists:lists_error}. (We used the script given in \cref{lst:bash:ruff} on \cpageref{lst:bash:ruff} to apply \ruff.)}%
190-
%
191-
Let us apply \ruff\ to the program \textil{lists_error.py} given in \cref{lst:lists:lists_error}, which produces the output \cref{exec:lists:lists_error:ruff}.
192-
\ruff\ finds two errors in this file:
193-
First, it complains that any python file should start with multi-line string specifying the purpose of the file.
194-
The use of such \pglspl{docstring} makes it easier for other programmers to understand what is done by which file in projects that are composed of multiple \python\ scripts.%
195-
%
196-
\bestPractice{module:docstrings}{
197-
Each \python\ file should start with a string describing its purpose~\cite{PEP257}. %
198-
This can either be a single line, like a headline, or a longer text. %
199-
In the second case, the first line must be a headline, followed by an empty line, followed by the rest of the text. %
200-
Either way, it must be a string delimited by~\pythonil{"""..."""}\pythonIdx{\textquotedbl\textquotedbl\textquotedbl\idxdots\textquotedbl\textquotedbl\textquotedbl}~\cite{PEP257,PEP8}.%
201-
\pythonIdx{str!doc}%
202-
}%
203-
%
204-
Additionally, \ruff\ finds that writing \pythonil{list([1, 2, 3])} is actually useless waste of speed and memory:
205-
It basically creates a list via \pythonil{[1, 2, 3]} and then immediately makes a copy of it via the \pythonilIdx{list} function wrapped around the list specification.
206-
We can leave this outer call to \pythonil{list} away.
207-
208-
\gitLoadAndExecPython{lists:lists_fixed}{}{collections}{lists_fixed.py}{}%
209-
\listingPythonAndOutput{lists:lists_fixed}{%
210-
The corrected version of~\cref{lst:lists:lists_error}, taking into account the information given by \mypy\ in \cref{exec:lists:lists_error:mypy} and \ruff\ in \cref{exec:lists:lists_error:ruff}.}{}%
211-
%
212-
%
213-
In \cref{lst:lists:lists_fixed} we implement the three recommendations from the two tools.
214-
We change the \pgls{typeHint} of the list to \pythonil{list[int]}, which solves the type confusion that \mypy\ discovered.
215-
We remove the useless copying of the list as \ruff\ recommended.
216-
Finally, we add a proper \pgls{docstring} at the top of the file, in which we even document the changes we applied.
217-
The output \cref{exec:lists:lists_fixed} of the new program remains the same.
218-
But now, both tools are satisfied, as shown in \cref{exec:lists:lists_fixed:mypy,exec:lists:lists_fixed:ruff}.
219-
And our program is much clearer and faster.%
220-
%
221-
\bestPractice{manyCodeAnalysisTools}{%
222-
Use many static code analysis tools and use them always. %
223-
They can discover a wide variety of issues, problems, or potential improvements. %
224-
They can help you to keep your code clean and to enforce a good programming style. %
225-
Do not just apply them, but also \emph{implement} their suggestions where possible.%
226-
}%
227-
%
228-
\FloatBarrier%
229-
%
230-
\gitExec{exec:lists:lists_fixed:mypy}{\programmingWithPythonCodeRepo}{.}{_scripts_/mypy.sh collections lists_fixed.py}%
231-
\listingToolOutput{lists:lists_fixed:mypy}{%
232-
The results of static type checking with \mypy\ of the program given in \cref{lst:lists:lists_fixed}.}%
233-
%
234-
\gitExec{exec:lists:lists_fixed:ruff}{\programmingWithPythonCodeRepo}{.}{_scripts_/ruff.sh collections lists_fixed.py}%
235-
\listingToolOutput{lists:lists_fixed:ruff}{%
236-
The results of static type checking with \ruff\ of the program given in \cref{lst:lists:lists_fixed}.}
237-
238-
Well, this was only a two-line program.
239-
But ask yourself:
240-
Did you spot the incorrect \pgls{typeHint} when you read the program?
241-
Did you see that we actually created a list and then copied it instead of using it directly?
242-
(The \pgls{docstring} I give you, no chance of seeing that as we did not mention it before.)
243-
Imagine that your job would be to work on a program with thousands of lines that was developed by a colleague.
244-
Wouldn't you love it if that colleague had thoroughly documented and type-hinted and checked their code?
245-
Be that colleague.%
246-
%
247-
\FloatBarrier%
248-
\endhsection%
249142
\endhsection%
250143
%
File renamed without changes.

0 commit comments

Comments
 (0)