Skip to content

Commit 6e387ca

Browse files
committed
some minor improvements
1 parent ccab3e7 commit 6e387ca

File tree

3 files changed

+28
-10
lines changed

3 files changed

+28
-10
lines changed

text/main/basics/simpleDataTypesAndOperations/str/str.tex

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
\hsection{Text Strings}%
22
\label{sec:str}%
33
%
4-
The fourth and last important basic datatype in \python\ are text strings.
4+
The fourth important basic datatype in \python\ are text strings.
55
Text strings are sequences of characters of an arbitrary length.
66
In \python, they are represented by the datatype \pythonilIdx{str}.
77
Indeed, we have already used it before, even in our very first example program back that simply printed \pythonil{"Hello World"} in \cref{lst:very_first_program} in \cref{sec:ourFirstProgram}.
@@ -168,7 +168,7 @@
168168
\gitEvalPython{str_fstrings}{}{simple_datatypes/str_fstrings.py}%
169169
\listingBox{exec:str_fstrings}{\python\ \pglspl{fstring} in action.}{,style=python_console_style}%
170170

171-
\pythonIdx{str!f}\pythonIdx{f-string}Let us therefore discuss a very powerful and much more convenient gadget in \python's string processing toolbox: format strings, or \pglspl{fstring}\pythonIdx{f-string}\pythonIdx{str!f} for short~\cite{PSF:P3D:TPT:FSL,PEP498,M2017WAFSIPAHCIUT,B2023PFS}.
171+
\pythonIdx{str!f}\pythonIdx{f-string}Let us therefore discuss a very powerful and much more convenient gadget in \python's string processing toolbox: format strings, or \glspl{fstring}\pythonIdx{f-string}\pythonIdx{str!f} for short~\cite{PSF:P3D:TPT:FSL,PEP498,M2017WAFSIPAHCIUT,B2023PFS}.
172172
An \pgls{fstring} is like a normal string, except that it starts with \pythonil{f"}\pythonIdx{f\textquotedbl\idxdots\textquotedbl} instead of \pythonil{"}.
173173
And, most importantly, it can contain other data and even complete expressions inside curly braces~(\pythonil{\{...\}}\pythonIdx{\textbraceleft\idxdots\textbraceright!f-string}) which are then embedded into the string.%
174174
%
@@ -282,7 +282,25 @@
282282
One cool feature of this kind of expression-to-string conversation is that you can add the other format specifiers we discussed earlier after the \pythonil{=}.
283283
For example, you could write \pythonil{f"\{23\ *\ sin(2\ -\ 5)\ =\ :.2f\}"} and then the \pythonil{.2f} format would be applied to the result of the expression, i.e., you would get \pythonil{"23 * sin(2 - 5) = -3.25"} as the result of the extrapolation.
284284

285-
You are now able to convert the results of your computations to nice text.%
285+
We can also convert our last example of the \pythonil{str}\nobreakdashes-function, \pythonil{str(1 < 5) + " is True and " + str(1 + 5) + " = 6."}, to an \pgls{fstring} and get \pythonil{f"\{1 < 5\} is True and \{1 + 5\} = 6."}.
286+
This not just looks nicer, but it is also faster.
287+
288+
In the original example, \python\ needs to perform three string concatenation operations via the \pythonil{+}~operator.
289+
It first creates the result of \pythonil{str(1 < 5)}, which is a string.
290+
\pythonil{" is True and "} is also a string by definition.
291+
The two are concatenated, which results in a third string.
292+
Then \pythonil{str(1 + 5)} is evaluated, yielding the fourth string.
293+
The third string and this one are concatenated, resulting in a fifth string.
294+
And so on, resulting in the creation of seven separate string objects in total.
295+
All of them need to be explicitly created, because this is what we demanded with the command.
296+
297+
When using an \pgls{fstring}, there is no explicit need to create the intermediate concatenation results as objects.
298+
There might just be some text in a buffer somewhere under the hood that is finally returned as a string.
299+
Furthermore, \pglspl{fstring} are parsed when the code is loaded and evaluated during runtime, meaning that no runtime parsing is required~\cite{G2025MFIP}.
300+
There even exist specified \python\ bytecode for \pglspl{fstring}~\cite{PCPI:IFSIFO}.
301+
They also do not require an explicit or implicit function call and they can access the symbols of the current scope directly without needing them to be passed as arguments~\cite{G2025MFIP}.
302+
For all of these reasons, \Pglspl{fstring} therefore are fast and efficient~\cite{DEVC:WFAAPODSCMIP}.
303+
Having learned about them, you are now able to swiftly and elegantly convert the results of your computations to beautiful text.%
286304
\FloatBarrier%
287305
\endhsection%
288306
%

text/main/classes/dunder/dunder.tex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@
489489
\begin{itemize}%
490490
\item \dunder{eq} implements the functionality of~\pythonilIdx{==}, as we already discussed before.%
491491
%
492-
\item \dunder{ne} implements the functionality of~\pythonilIdx{!=}.%
492+
\item \dunder{ne} implements the functionality of~\pythonil{!=}\pythonIdx{"!=}.%
493493
%
494494
\item \dunder{lt} implements the functionality of~\pythonilIdx{<}.%
495495
%
@@ -503,7 +503,7 @@
503503
Implementing equality and inequality is rather easy, since our fractions are all normalized.
504504
For two fractions~\pythonil{x} and~\pythonil{y}, it holds only that~\pythonil{x == y} if \pythonil{x.a == y.a} and \pythonil{x.b == y.b}.
505505
\dunder{eq} is thus quickly implemented.
506-
\dunder{ne} is its complement for the \pythonilIdx{!=}~operator.
506+
\dunder{ne} is its complement for the \pythonil{!=}\pythonIdx{"!=}~operator.
507507
\pythonil{x != y} is \pythonil{True} if either \pythonil{x.a != y.a} or \pythonil{x.b != y.b}.
508508

509509
The other four comparison methods can be implemented by remembering how we used the common \pgls{denominator} for addition and subtraction.
@@ -1557,8 +1557,8 @@
15571557
.3 \dunder{rfloordiv}\DTcomment{right-integer-divide: \pythonil{a // b}\pythonIdx{//}~$\cong$~\pythonil{b.\_\_rfloordiv\_\_(a)}, if \pythonil{a.\_\_floordiv\_\_(b)} yields~\pythonilIdx{NotImplemented}}.
15581558
.3 \dunder{pow}\DTcomment{exponential: \pythonil{a ** b}\pythonIdx{**}~$\cong$~\pythonil{a.\_\_pow\_\_(b)}}.
15591559
.3 \dunder{rpow}\DTcomment{right-exponential: \pythonil{a ** b}\pythonIdx{**}~$\cong$~\pythonil{b.\_\_rpow\_\_(a)}, if \pythonil{a.\_\_pow\_\_(b)} yields~\pythonilIdx{NotImplemented}}.
1560-
.3 \dunder{matmul}\DTcomment{matrix-multiply: \pythonil{a @ b}\pythonIdx{@}~$\cong$~\pythonil{a.\_\_matmul\_\_(b)}}.
1561-
.3 \dunder{rmatmul}\DTcomment{right-ma, see \cref{sec:arithmeticsAndOrder}trix-multiply: \pythonil{a @ b}\pythonIdx{@}~$\cong$~\pythonil{b.\_\_rmatmul\_\_(a)}, if \pythonil{a.\_\_matmul\_\_(b)} yields~\pythonilIdx{NotImplemented}}.
1560+
.3 \dunder{matmul}\DTcomment{matrix-multiply: \pythonil{a @ b}\pythonIdx{"@}~$\cong$~\pythonil{a.\_\_matmul\_\_(b)}}.
1561+
.3 \dunder{rmatmul}\DTcomment{right-ma, see \cref{sec:arithmeticsAndOrder}trix-multiply: \pythonil{a @ b}\pythonIdx{"@}~$\cong$~\pythonil{b.\_\_rmatmul\_\_(a)}, if \pythonil{a.\_\_matmul\_\_(b)} yields~\pythonilIdx{NotImplemented}}.
15621562
.3 \dunder{divmod}\DTcomment{compute the result of an integer division as well as the remainder and return them as 2-tuple: \pythonil{divmod(a, b)}\pythonIdx{divmod}~$\cong$~\pythonil{a.\_\_divmod\_\_(b)}}.
15631563
.3 \dunder{rdivmod}\DTcomment{right-sided \pythonilIdx{divmod}: \pythonil{divmod(a, b)}\pythonIdx{divmod}~$\cong$~\pythonil{b.\_\_divmod\_\_(a)}, if \pythonil{a.\_\_divmod\_\_(b)} yields~\pythonilIdx{NotImplemented}}.
15641564
.3 \dunder{round}\DTcomment{round: \pythonil{round(a)}\pythonIdx{round}~$\cong$~\pythonil{a.\_\_round\_\_()}~\cite{PEP3141}}.
@@ -1573,7 +1573,7 @@
15731573
.3 \dunder{imod}\DTcomment{in-place modulo division: \pythonil{a \%= b}\pythonIdx{\%=}~$\cong$~\pythonil{a.\_\_imod\_\_(b)}, returns~\pythonilIdx{self}}.
15741574
.3 \dunder{ifloordiv}\DTcomment{in-place integer division: \pythonil{a //= b}\pythonIdx{//=}~$\cong$~\pythonil{a.\_\_ifloordiv\_\_(b)}, returns~\pythonilIdx{self}}.
15751575
.3 \dunder{ipow}\DTcomment{in-place exponentiation: \pythonil{a **= b}\pythonIdx{**=}~$\cong$~\pythonil{a.\_\_ipow\_\_(b)}, returns~\pythonilIdx{self}}.
1576-
.3 \dunder{imatmul}\DTcomment{in-place matrix multiplication: \pythonil{a @= b}\pythonIdx{@=}~$\cong$~\pythonil{a.\_\_imatmul\_\_(b)}, returns~\pythonilIdx{self}}.
1576+
.3 \dunder{imatmul}\DTcomment{in-place matrix multiplication: \pythonil{a @= b}\pythonIdx{"@=}~$\cong$~\pythonil{a.\_\_imatmul\_\_(b)}, returns~\pythonilIdx{self}}.
15771577
}%
15781578
%
15791579
\caption{An overview of the dunder\pythonIdx{dunder} methods in \python\ (Part~2).}%
@@ -1655,7 +1655,7 @@
16551655
16561656
While we implemented several arithmetic dunder methods for our \pythonil{Fractions} class in \cref{sec:arithmeticsAndOrder}, \cref{fig:pythonDunder:2} shows us that there are \emph{many} more.
16571657
The unary methods \dunder{abs}, \dunder{minus}, and \dunder{pos} allow us to implement the computation of the absolute value and the negated variant of a number, as well as the rather obscure unary plus.
1658-
There are dunder methods for basically all binary arithmetic operators, ranging from \pythonilIdx{+}, \pythonilIdx{-}, \pythonilIdx{*}, \pythonilIdx{/}, \pythonilIdx{//}, \pythonilIdx{\%}, to~\pythonilIdx{**} and even the matrix multiplication operator~\pythonilIdx{@}.
1658+
There are dunder methods for basically all binary arithmetic operators, ranging from \pythonilIdx{+}, \pythonilIdx{-}, \pythonilIdx{*}, \pythonilIdx{/}, \pythonilIdx{//}, \pythonilIdx{\%}, to~\pythonilIdx{**} and even the matrix multiplication operator~\pythonil{@}\pythonIdx{"@}.
16591659
Interestingly, these methods always exist in two variants, the plain one and one prefixed with~\inQuotes{\pythonil{r}.}
16601660
For example, when evaluating the expression~\pythonil{a + b}, \python\ will look whether \pythonil{a}~implements \dunder{add}.
16611661
If so, it will call \pythonil{a.\_\_add\_\_(b)}.

0 commit comments

Comments
 (0)