Finished first draft of Python-part.

This commit is contained in:
Oliver Rümpelein 2016-04-25 16:20:31 +02:00
parent 4110c30cc6
commit e59dac99bf
4 changed files with 193 additions and 79 deletions

View file

@ -19,22 +19,22 @@ html header: <link rel="stylesheet"
+ currying => just convenience
+ code example: Pythagoraian triangles, bubble sort
* Phuncy: The pythonic way is functional!
- Not strictly functional
- recursion, fafco
- lambda syntax
+ Not strictly functional
- recursion
+ fafco
- map, fold => example (sum of squares?)
- python lambda syntax: lambda a,b: a+b
- fold with reduce
- don't return lists, but iterators!
- Note: 2: map, filter, reduce, list comprehension
+ python lambda syntax: lambda a,b: a+b
+ don't return lists, but iterators!
+ fold with reduce
+ Note: 2: map, filter, reduce, list comprehension
3: map, filter, functools.reduce(), list comprehension
- The python2 to 3 page states:
+ The python2 to 3 page states:
“Removed `reduce()`. Use `functools.reduce()` if you really need it;
however, 99 percent of the time an explicit `for` loop is more
readable.”
- Why use it? => Multi-processing, WTF Count.
+ Why use it? => Multi-processing, WTF Count.
```python
a = list(range(10))
@ -50,7 +50,7 @@ html header: <link rel="stylesheet"
from functools import reduce
print(reduce(lambda x,y: x+y,map(lambda x: x**2,range(10))))
```
- currying: not really, but binding via lambdas or functools.partial() or
+ currying: not really, but binding via lambdas or functools.partial() or
https://mtomassoli.wordpress.com/2012/03/18/currying-in-python/
- decorators!
- still FP has advantages and is heavily used, i.e. in genomics (works on

View file

@ -39,9 +39,22 @@
fontsize=\small,
}
\newminted[pycode]{python}%
{
linenos=true,
autogobble=true,
breaklines=true,
showspaces=false,
showtabs=false,
tabsize=2,
frame=single,
fontsize=\small,
}
\newmintinline[ccmd]{c}{}
\newmintinline[cppcmd]{cpp}{}
\newmintinline[haskellcmd]{haskell}{}
\newmintinline[pycmd]{python}{}
%%% Local Variables:
%%% mode: latex

View file

@ -2,4 +2,10 @@
title={Foldr Foldl Foldl' - HaskellWiki},
urldate={2016-04-21},
url={https://wiki.haskell.org/Foldr_Foldl_Foldl%27},
}
@online{decorators,
title={simeonfranklin.com - Understanding Python Decorators in 12 Easy Steps!},
urldate={2016-04-25},
url={http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/},
}

View file

@ -3,7 +3,7 @@
\usepackage{babel}
\usepackage{csquotes}
\usepackage{tabularx}
\usepackage[backend=biber, style=numeric,]{biblatex}
\usepackage[backend=biber,]{biblatex}
\bibliography{wtf}
\usepackage{fontspec}
@ -39,18 +39,18 @@
\end{frame}
\begin{frame}[fragile]{Example}
%ToDo: C-code call by value, call by reference.
\begin{cppcode}
int f(int x) { return ++x;}
int g(int& x) { return ++x;}
int main() {
int x = 2;
f(x);
assert(x==2); // f is “functional”
g(x);
assert(x!=2); // g is not!
}
\end{cppcode}
% ToDo: C-code call by value, call by reference.
\begin{cppcode}
int f(int x) { return ++x;}
int g(int& x) { return ++x;}
int main() {
int x = 2;
f(x);
assert(x==2); // f is “functional”
g(x);
assert(x!=2); // g is not!
}
\end{cppcode}
\end{frame}
\begin{frame}{Pros and Cons}
@ -83,19 +83,19 @@
\begin{frame}[fragile]{Syntax Functions}
Function constraints, definition and calls:
\begin{haskell}
mysum :: Num a => a -> a -> a -> a
mysum x y z = x + y + z
-- b == 6
b = mysum 1 2 3
\end{haskell}
\begin{haskell}
mysum :: Num a => a -> a -> a -> a
mysum x y z = x + y + z
-- b == 6
b = mysum 1 2 3
\end{haskell}
\pause
Functions always get evaluated left to right, thus the following works (\emph{Currying}):
\begin{haskell}
mysum2 = mysum 2
-- c == 12
c = mysum2 4 6
\end{haskell}
\begin{haskell}
mysum2 = mysum 2
-- c == 12
c = mysum2 4 6
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Syntax Lists (1)}
@ -117,26 +117,26 @@
\item Two lists can be concatenated using the \haskellcmd{++} operator:
\haskellcmd{[1,2,3] ++ [4..7]}
\item Single objects get pushed to the front using
\enquote{\haskellcmd{:}}: \haskellcmd{1:[2..7]}.
\enquote{\haskellcmd{:}}: \haskellcmd{1:[2..7]}.
\item This can also be used vice versa to extract single values from lists:
\begin{haskell}
extract (x:xs) = x
-- a = 1
a = extract [1..5]
\end{haskell}
\begin{haskell}
extract (x:xs) = x
-- a = 1
a = extract [1..5]
\end{haskell}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Syntax Recursion}
Example: Add a value to every entry in an array
\begin{haskell}
addto :: (Num a) => [a] -> a -> [a]
addto [] _ = [] -- edge case (list empty)
addto (x:xs) y = (x+y) : addto xs y
b = [1..4]
-- c == [5,6,7,8]
c = addto b 4
\end{haskell}
\begin{haskell}
addto :: (Num a) => [a] -> a -> [a]
addto [] _ = [] -- edge case (list empty)
addto (x:xs) y = (x+y) : addto xs y
b = [1..4]
-- c == [5,6,7,8]
c = addto b 4
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Lambdas}
@ -169,52 +169,147 @@
\end{frame}
\begin{frame}[fragile]{Folds (2)}
\uncover<+-> Example: Self written Right fold and sum:
\begin{haskell}
mfold f z [] = z
mfold f z (x:xs) = f x (mfold f z xs)
msum = mfold (+) 0
-- g == 5050
g = msum [1..100]
\end{haskell}
\uncover<+-> Example: Self written Right fold and sum:
\begin{haskell}
mfold f z [] = z
mfold f z (x:xs) = f x (mfold f z xs)
msum = mfold (+) 0
-- g == 5050
g = msum [1..100]
\end{haskell}
\uncover<+->{Note that this gets pretty resource hungry with large
lists, better use left-folds for this (see~\cite{whichfold})}
\end{frame}
\begin{frame}[fragile]{Example: Pythagorean triangles}
Get all Pythagorean triangles with a hypotenuse off length at most 15:
\begin{haskell}
> [(a,b,c) | a <- [1..15],
b <- [1..a],
c <- [1..b],
a^2 == b^2 + c^2]
[(5,4,3),(10,8,6),(13,12,5),(15,12,9)]
\end{haskell}
\end{frame}
\begin{haskell}
> [(a,b,c) | a <- [1..15],
b <- [1..a],
c <- [1..b],
a^2 == b^2 + c^2]
[(5,4,3),(10,8,6),(13,12,5),(15,12,9)]
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Example: Bubble-sort}
Recursive, functional bubble-sort algorithm:
\begin{haskell}
bsort f [] = []
bsort f (x:xs) = (bsort f a) ++ [x] ++ (bsort f b)
where a = [ y | y <- xs, not (f x y) ]
b = [ y | y <- xs, (f x y) ]
mbsort = bsort (\x y -> (x > y))
\end{haskell}
\begin{haskell}
bsort f [] = []
bsort f (x:xs) = (bsort f a) ++ [x] ++ (bsort f b)
where a = [ y | y <- xs, not (f x y) ]
b = [ y | y <- xs, (f x y) ]
mbsort = bsort (\x y -> (x > y))
\end{haskell}
\pause Result:
\begin{haskell}
λ> h = [1, 20, -10, 5]
λ> mbsort h
[-10,1,5,29]
\end{haskell}
\begin{haskell}
λ> h = [1, 20, -10, 5]
λ> mbsort h
[-10,1,5,29]
\end{haskell}
\end{frame}
\section{Phuncy!}
\subsection{Overview}
\begin{frame}{Functional programming in Python}
\begin{itemize}[<+->]
\item Obviously, python is not strictly functional…
\item …but has functions as first class objects!
\item Some other stuff is widely used, but with another syntax…
\item …, although there are ways to get the \enquote{real} functional
style.
\item I use python3 here, python2 differs in some points.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Lambdas, Maps}
\begin{itemize}[<+->]
\item Lambda-syntax: \pycmd{lambda a,b: a+b}
\item Maps are done by \pycmd{map}
\item \emph{Note:} Most functional list-functions return iterators in
python, not lists!
\item Use \pycmd{list()} to cast Iterators, but this is usually not
necessary.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Filters}
\begin{itemize}[<+->]
\item Can be done using \pycmd{filter(func, iter)}:
\begin{pycode}
a = range(1,7)
b = filter(lambda x: x%2, a)
print(list(b))
# [1,3,5]
\end{pycode}
\item Alternatively, use List Comprehension:
\begin{pycode}
a = range(1,7)
b = [x for x in a if x%2]
print(b)
\end{pycode}
\item Pro: Maybe easier readable, returns list
\item Con: Returns list (slower when iterating afterwards)
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Fold}
\begin{itemize}[<+->]
\item From the python2 to python3 Changelog:
\begin{quote}
Removed `reduce()`. Use `functools.reduce()` if you really need it;
however, 99 percent of the time an explicit `for` loop is more
readable.
\end{quote}
\item I disagree Old-style is more explicit and still available from \pycmd{functools}
\item Example sum of squares
\begin{pycode}
from functools import reduce
a = range(10)
mapped = map(lambda x: x**2, a)
reduced = reduce(lambda x,y: x+y, mapped)
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Currying}
\begin{itemize}[<+->]
\item No real currying, but several workarounds
\item Lambdas: \pycmd{g=lambda x: foo(2,x)}
\item \pycmd{functools.partial}:
\begin{pycode}
def foo(x,y):
return x+y
bar=partial(foo, 2)
bar(3) # 5
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Decorators}
\begin{itemize}[<+->]
\item Often used to modify functions in Frameworks
\item Encapsulates other functions. More infos at \cite{decorators}
\begin{pycode}
def debug(func):
def inner(*args, **kwargs):
sys.stderr.write("F: {}, args: {}, kwargs {}".format(func.__name__, args,
kwargs))
return func(*args, **args)
return inner
@debug
def foo(x):
print(x)
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[plain]{References}
\printbibliography
\end{frame}
\end{frame}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% ispell-dictionary: en
%%% ispell-local-dictionary: "en_GB"
%%% End: