|
|
\usepackage{fontspec}
|
\usepackage{polyglossia}
|
\setdefaultlanguage[
|
spelling=new
|
,variant=german
|
]{german}
|
|
\usetheme{default}
|
|
\usepackage{minted}
|
\setminted{
|
%fontsize=\small,
|
style=default
|
}
|
|
\title{Python typing}
|
\author{Hong-Phuc Bui}
|
\institute{HTW Saar}
|
|
\begin{document}
|
\begin{frame}[plain]
|
\maketitle
|
\end{frame}
|
|
|
\begin{frame}[plain]
|
\tableofcontents
|
\end{frame}
|
|
\section{Primitiven Typen}
|
\begin{frame}[fragile]
|
\frametitle{Einfache Nutzung}
|
\begin{minted}{python}
|
# filename: developer.py
|
# integer
|
staff: int = 123_456
|
|
# float
|
developer_quote: float = 0.7
|
|
# string
|
team: str = "DevOp"
|
|
developer: int = developer_quote * staff
|
|
# Bug!
|
print(f"Es gibt {developer} Entwickler in Team „{team}“!")
|
\end{minted}
|
\pause
|
\begin{minted}{python}
|
# → Es gib 86419.2 Entwickler in Team „DevOp“!
|
\end{minted}
|
Wir wollen keine ein-fünftel Entwickler!
|
\end{frame}
|
|
\begin{frame}[fragile]
|
% \frametitle{Bugfix}
|
Eine Variante ist explizite Konvertierung.
|
|
\begin{minted}{python}
|
# Bugfix:
|
developer: int = int(developer_quote * staff)
|
|
# Bugfixed
|
print(f"Es gibt etwa {developer} Entwickler in Team „{team}“!")
|
\end{minted}
|
|
\end{frame}
|
|
|
\begin{frame}[fragile]
|
\frametitle{Konstante}
|
\begin{minted}{python}
|
# filename: light-speed.py
|
from typing import Final
|
|
LIGHT_SPEED: Final[int] = 299_792_458 # Exact value [m/s]
|
|
LIGHT_SPEED = 299_792.458 # [km/s]
|
\end{minted}
|
\pause
|
|
Keine Fehlermeldung!
|
\end{frame}
|
|
\subsection{Typen Überprüfen}
|
\begin{frame}[fragile]
|
\frametitle{Run Type-check}
|
{\footnotesize
|
\begin{minted}{text}
|
$ python3 -m pip install mypy
|
$ mypy light-speed.py
|
light-speed.py:5: error: Cannot assign to final name "LIGHT_SPEED" [misc]
|
light-speed.py:5: error: Incompatible types in assignment
|
(expression has type "float", variable has type "int") [assignment]
|
Found 2 errors in 1 file (checked 1 source file)
|
\end{minted}
|
}
|
|
\end{frame}
|
|
|
\section{Zusammengesetzten Typen}
|
\begin{frame}[fragile]
|
\frametitle{Zusammengesetzten Typen}
|
\begin{minted}{python}
|
# list of prof
|
prof: list[str] = ["D. Knuth", "R. Sedgwick", "E. Gamma"]
|
|
# grade is a tuple of student and his note
|
grade: tuple[str, float] = ("Tommy", 12.5)
|
|
# set of all possible notes
|
notes: set[str] = {"A", "B", "C", "D", "E"}
|
|
# dictionary
|
german_articles: dict[str, str] = {
|
"der": "the", "des": "the", "dem": "the", "den": "the",
|
"die": "the",
|
"das": "the",
|
}
|
\end{minted}
|
\end{frame}
|
|
\subsection{Union und Generic}
|
\begin{frame}[fragile]
|
\frametitle{Union}
|
\begin{minted}{python}
|
measurement: list[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
|
\end{minted}
|
\pause
|
|
Wozu ist das gut?
|
\end{frame}
|
|
|
\begin{frame}[fragile]
|
\frametitle{Generic}
|
|
\begin{minted}{python}
|
def avg(values: Sequence[int | float]) -> float:
|
return sum(values) / len(values)
|
\end{minted}
|
\vspace{5ex}
|
\pause
|
\begin{minted}{python}
|
from typing import Sequence, Callable
|
|
avg: Callable[[Sequence[int | float]], float] = \
|
lambda values: sum(values) / len(values)
|
\end{minted}
|
\end{frame}
|
|
\begin{frame}[fragile]
|
\frametitle{Aufruf}
|
\begin{minted}{python}
|
# List Ok
|
length: list[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
|
length_avg = avg(length)
|
|
# Tupel Ok
|
count_member: tuple[int, int, int, int, int] = (12, 15, 16, 11, 10)
|
member_avg = avg(count_member)
|
\end{minted}
|
\end{frame}
|
|
\begin{frame}[fragile]
|
\frametitle{Pitfall}
|
\begin{minted}{python}
|
# Set is not a Sequence
|
my_set: set[int] = {2, 3, 5, 7, 11} #
|
prime_avg = avg(prime_set)
|
|
|
# mypy:
|
# ...incompatible type "Set[int]"; expected "Sequence[Union[int, float]]"
|
\end{minted}
|
\end{frame}
|
|
\subsection{TypeAlias}
|
\begin{frame}[fragile]
|
\frametitle{TypeAlias}
|
\begin{minted}{python}
|
from typing import Sequence, Callable, TypeAlias
|
|
|
Scale: TypeAlias = Sequence[int | float]
|
|
avg: Callable[[Scale], float] = \
|
lambda values: sum(values) / len(values)
|
|
# noch besser:
|
avg: Callable[[Scale], float] = \
|
lambda v: sum(v) / len(v) if len(v) > 0 else 0.0
|
\end{minted}
|
\end{frame}
|
|
\section{Referenz}
|
\begin{frame}[fragile]
|
\frametitle{Referenz}
|
\begin{enumerate}
|
\item \url{https://mypy.readthedocs.io/}
|
\item \url{https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html}
|
\end{enumerate}
|
|
\vfill
|
Weiter lesen: Was ist der Unterschied zwischen Iterable und Sequence?
|
|
\end{frame}
|
|
\end{document}
|
|