\documentclass[a4paper]{article}
\usepackage{natbib,unatbib}
\usepackage[hide,twocolumn]{ulecnot}

\usepackage{imakeidx}

\usepackage{tikz-qtree}

\usepackage{uprog}
\usepackage{xcolor}
\usepackage{hyperref}
\hypersetup{colorlinks=true,linkbordercolor=red,linkcolor=magenta,pdfborderstyle={/S/U/W 1}}

\makeindex

\pagestyle{fancy}
\lhead{METU Cognitive Science}
\chead{Introduction to Programming (with Python)}
\rhead{Last updated \it \today}
\lfoot{Umut \"Ozge -- \href{mailto:umozge@metu.edu.tr}{\nolinkurl{umozge@metu.edu.tr}}}
\cfoot{}
\rfoot{Page \thepage/\pageref{LastPage}}
\setlength{\headheight}{13.6pt}

\begin{document}

\tableofcontents
\newpage
\section{The Python interpreter}

\begin{itemize}
\item The first step into learning programming in Python is to have a working
Python interpreter.

\item The course will be based on Python 3, i.e.\ we will assume that you are
running your programs on an interpreter with a version number starting with
3.\footnote{Please check \url{https://docs.python.org/3.0/whatsnew/3.0.html}
for what is new in Python 3.}

\item Please visit \url{https://docs.python.org/2/using/index.html} for
installing Python on the platform of your choice.

\item You can interact with the interpreter, you can have it run a stored
program, or you can do both.

\item The previous item may not mean much at the moment, don't worry.

\item When you invoke the Python interpreter on its own, you will enter into the
\uterm{interactive mode}\index{interactive mode} of the interpreter.

\begin{ucodeframe}
\input{code/console1.txt}
\end{ucodeframe}

\item You can see the version you are running by checking the number in the
first line, following `\Verb+Python+'.
\item The Python \uterm{prompt} `\Verb+>>>+' indicates that the interpreter is ready
to receive input from the \uterm{user}.
\item From now on, I will call the interface by which you interact with the
interpreter the \uterm{Python console},\index{console} or simply the \uterm{console}.
\item There are two ways to \uterm{exit} the console. You can either type
\Verb+exit()+ followed by hitting \Verb+enter+, or you can hold down the control key and
press \Verb+D+.

\end{itemize}

\section{Arithmetic}

\begin{itemize}
\item A fundamental distinction you need to learn well is
\uterm{expressions}\index{expression} and \uterm{statements}.\index{statement} Here we start with expressions. The
statements will come later.

\item An expression is a piece of code that can be read by the interpreter. The
interpreter deciphers this code -- or understands it, if you like -- and
computes the \uterm{value} of this expression, and finally returns (a string
representation of) the value.

\item To fix the terminology, interpreter evaluates an expression and computes a
result. This computed result is the value of the expression.

\item You can type an expression on the Python console and hit \Verb+enter+ for the
interpreter to \uterm{evaluate} the expression and \uterm{print} the result on the
screen. The simplest kind of expression you can provide to the interpreter is a
number. Simply type it on the console and hit \Verb+return+.

\begin{ucodeframe}
\begin{pyconsole}
4
\end{pyconsole}
\end{ucodeframe}

\item Interpreter sees nothing to further evaluate given an integer, therefore
it gives you the integer back as the result of the evaluation.

\item Arithmetic expressions are so fundamental to computing that almost all
programming languages have \uterm{constructs} to perform arithmetic. You can
actually use the Python interpreter as a calculator; type an arithmetic
expression to the interpreter and hit \Verb+enter+ to let the interpreter evaluate
the expression and return the result:

\begin{ucodeframe}
\begin{pyconsole}
4 + 7
\end{pyconsole}
\end{ucodeframe}

\item Now try something more complicated:

\begin{ucodeframe}
\begin{pyconsole}
4 + 7 * 8
\end{pyconsole}
\end{ucodeframe}

\item This could be a little surprise for you, if you were expecting the result
to be 88 rather than 60. Actually 88 would be the result for an interpreter that
evaluates arithmetic expressions from left to right, without caring about
the kind of the arithmetic operator it is interpreting. The Python interpreter,
like other interpreters, has some grouping rules concerning algebraic
expressions like arithmetic operations. For instance, we have just discovered
that it gives \uterm{precedence}\index{operator precedence} to multiplication with respect to addition. If
you want to compute first the sum of 4 and 7 and then multiply the result by 8,
you should type:

\begin{ucodeframe}
\begin{pyconsole}
(4 + 7) * 8
\end{pyconsole}
\end{ucodeframe}

\item Some common operations that are available in the Python console
are:\footnote{Note that in Python 2, `\Verb+/+' performs floor division, if
the operands are integer; more on types below.}

\begin{tabular}{llp{180pt}}
Operator & Name & Example \\
\pyv{+},\pyv{-}, * & add., subt., mult.\ & \\
\pyv{/} & division & `\pyv{8/5}' gives `\pycon{8/5}'\\
\pyv{//} & floor division & `\pyv{8//5}' gives `\pycon{8//5}', round the result to the greatest lower integer\\
\pyv{%} & modulo & `\pyv{8%3}' gives `\pycon{8%3}', the remainder of division\\
** & exponentiation & `\pyv{8**3}' gives `\pycon{8**3}'
	\end{tabular}

\hrulefill
\begin{uexercise}
Open up a Python console, and by trying various expressions, figure out the
grouping rules regulating the precedence of the operators given in the above
table.
\end{uexercise}
\hrulefill
\end{itemize}

\section{Data types}

\begin{itemize}

\item With some idealization, you can think of computation as some actions
operating on data and generating new data. The data can be integers, floating
point numbers (floats), characters, strings, lists, matrices, and so
on.\footnote{We will not cover the numerical type \pyv{complex}.}

\item All the types of data mentioned above have their specific instances. As we
will see shortly, the expression \pyv{4} is an instance of the type integer. We
will call these instances \uterm{objects}.\index{object} We will have more to say about these
matters later, but let us fix the terminology from the beginning: Every
\uterm{object} is an instance of a \uterm{class},\index{class} which names the object's
\uterm{type}.\index{type} This much will do for the moment.

\item Every programming language comes with a collection of \uterm{built-in data
types}. What we mean by being built-in is that the language has some basic
expressions to represent the type of data in question.\footnote{Some analogy: In
Turkish you have a built-in expression to ask the place of an item in an ordered
sequence, namely \emph{ka\c c\i{}nc\i{}}. English lacks such a built-in
expression, it needs to construct complex expressions to ask the same question.}

\end{itemize}

\subsection{Integer}

\begin{itemize}
\item So far we have seen only one of the built-in data types of Python, namely
integers.

\item You can ask the type of the value of an expression -- which is an object
-- on the Python console, by using a \uterm{built-in
function}\index{function!built-in} called `\pyv{type}'.

\begin{ucodeframe}
\begin{pyconsole}
type(4)
\end{pyconsole}
\end{ucodeframe}

\item What \pyv{type}\index{type} does is to first let the interpreter evaluate the
expression in the parentheses, and then checks the type of the result of this
evaluation:

\begin{ucodeframe}
\begin{pyconsole}
type(4*2**3)
\end{pyconsole}
\end{ucodeframe}

\end{itemize}

\subsection{Float}
\begin{itemize}
\item Another numerical type is that of floating point numbers, or simply
\uterm{float}.\index{float}

\begin{ucodeframe}
\begin{pyconsole}
type(4.4)
\end{pyconsole}
\end{ucodeframe}

\begin{ucodeframe}
\begin{pyconsole}
type(8/5)
\end{pyconsole}
\end{ucodeframe}

\item Here are some more built-in functions that operate on numbers.

\begin{ucodeframe}
\begin{pyconsole}
abs(-4.2)
pow(3, 2)
divmod(8, 3)
\end{pyconsole}
\end{ucodeframe}

\item If what \pyv{divmod} does is not clear, try to figure it out by giving it
other arguments.

\item A handy function to be used with float objects is
\pyv{round}:

\begin{ucodeframe}
\begin{pyconsole}
round(44.6)
round(44.5)
round(3.141592653589793,4)
\end{pyconsole}
\end{ucodeframe}

\item Here we observe that there are two functions with the name \pyv{round}.
One rounds the floating number to the nearest integer, and takes only the
floating number to be rounded as argument. The other \pyv{round} takes two
arguments. The first is the float, the second is the number of digits to be kept
after the floating point.\footnote{Actually it is slightly more complicated than
this. Strictly speaking there is one \pyv{round} and it has two arguments. What
happens when you call \pyv{round} with a single argument is that the second
argument is looked up from the function specification, which is set to
0 by default. More on this in Section~\ref{sec:functions}.}

\end{itemize}

\subsection{String}

\begin{itemize}

\item Deep down, computers operate via numerical representations. However,
computers are used in many tasks that are not numerical -- at least from the
perspective of the user, take a text editor, web-browser, or a library
management system for instance; programming itself is performed by mainly words.

\item A string is an ordered sequence of \emph{zero
or more} characters.\footnote{In Python, there is no basic data type for
characters; they are treated simply as unary strings.} The type of such objects
is \uterm{str} in Python. There are two ways to
represent strings: either with matching single quotes `\pyv{'}', or by matching
double quotes `\pyv{"}'.  All the following are
strings:

\begin{ucodeframe}
\begin{pyconsole}
type('abracadabra')
type("a")
type(' ')
type('')
\end{pyconsole}
\end{ucodeframe}

\item Just like numbers, strings can be added by `\Verb|+|', the
\uterm{concatenation}\index{concatenation!string} operator, and you can ``multiply'' a string by an integer:

\begin{ucodeframe}
\begin{pyconsole}
'abra' + 'cad' + 'abra'
'cad' * 3
3 * 'cad'
\end{pyconsole}
\end{ucodeframe}

\item As we observed above, the built-in function \pyv{type} is evoked by
providing its argument within parentheses. Python has another kind of built-in
function which is called a \uterm{method}\index{method}. These functions operate relative to certain types of objects. For
instance a string object supports the method \pyv{upper()},
which, like other methods, is evoked by the following syntax:

\begin{ucodeframe}
\begin{pyconsole}
"abracadabra".upper()
\end{pyconsole}
\end{ucodeframe}

\item You can check all the methods available for strings in Python by typing
\pyv{help(str)} in the console. You can leave the help screen by pressing
\pyv{q}.

% \item Python provides fast access to the any substring of a string by a
% mechanism called \uterm{indexing}\index{indexing!string}.

\end{itemize}

\subsection{Boolean}

\begin{itemize}

\item We have seen above that arithmetical expressions evaluate to number
objects and
string concatenation or multiplication evaluate to string objects. Some expressions are
like yes-no questions, they evaluate to true or false. Python has two designated
objects that stand for these truth-values: \pyv{True} and \pyv{False}. Their
type is \uterm{bool} (shortened from `boolean').

\begin{ucodeframe}
\begin{pyconsole}
type(True)
type(False)
\end{pyconsole}
\end{ucodeframe}

\item Yes-no questions are asked by \uterm{comparison operators}. All but the
two\footnote{We will discuss object comparison operators later.} are:

\begin{tabular}{ll}
\Verb+<+&	strictly less than\\
\Verb+<=+&	less than or equal\\
\Verb+>+&	strictly greater than\\
\Verb+>=+&	greater than or equal\\
\Verb+==+&	equal\\
\Verb+!=+&	not equal
\end{tabular}

\item Comparison operators can be used to compare both numbers and strings. For
strings alphabetical order determines the result of the comparison. Try

\begin{ucodeframe}
\begin{pyconsole}
'abra' < 'cad'
8 != 7
8 == 7
\end{pyconsole}
\end{ucodeframe}

\item Now let us combine some of the concepts we have encountered so far:

\begin{ucodeframe}
\begin{pyconsole}
type(3 + 7 < 7)
\end{pyconsole}
\end{ucodeframe}

\item Here, as in arithmetic, Python interpreter observes the precedence
relation among operators. It first \uterm{evaluates} the addition operator since
comparison operators has lower precedence than arithmetic operators; then the
comparison is performed -- giving \pyv{False}, and finally the built-in type
detecting function is applied to \pyv{False}, giving the type expression for
boolean, namely \pycon{type(True)}. The evaluation order can be pictured as a tree.

\begin{tikzpicture}[sibling distance=40pt]
\Tree [.\pyv{type} [.\pyv{<} [.\pyv{+} [.3 ] [.7 ] ] [.7 ] ] ]
\end{tikzpicture}

\item Boolean values can be combined with boolean operators \pyv{and}, \pyv{or},
and \pyv{not} as in symbolic logic (more on this below).

\end{itemize}

\subsection{Type conversion (manual)}

\begin{itemize}

\item You can convert between types using \uterm{type constructors}, which are
built-in Python functions. The constructors for the data types we have seen so
far are \pyv{str}, \pyv{int}, \pyv{float} and
\pyv{bool}. They take their arguments in parentheses. Some sample conversions
are:

\begin{ucodeframe}
\begin{pyconsole}
str(3.4)
float(3)
int(3.7)
\end{pyconsole}
\end{ucodeframe}

\end{itemize}

\section{Variables, identifiers, assignment statements}

\begin{itemize}

\item  A \uterm{variable} is a location where data -- Python objects in our case
-- is stored. The content of a variable may change, hence the name ``variable''.

\item It is useful to have names for things, and variables are no exception. We
can name (or point to) variables by \uterm{identifiers}. Python allows as
identifier any sequence of letters, numbers and the underscore character
(`\Verb+_+'), provided that the first character in the sequence is not a number
or the sequence is not a special expression reserved for a designated use in
Python, like \Verb+print+ for instance; such expressions are called
\uterm{keywords}.

\item By using the identifier you can have access to the information (what we
have been calling object or value) stored in the variable. We simply say that an
identifier points to an object, or refers to an object, skipping the detail
about the variable that mediates this relation.  You can make an identifier
point to an object by an \uterm{assignment statement}:

\begin{ucodeframe}
\begin{pyconsole}
a_word = "I am not a word, I am a sentence."
\end{pyconsole}
\end{ucodeframe}

\item From there on, you can use \Verb+a_word+ everywhere you want to use the
string assigned to it. You can go on entering code into console as:

\begin{ucodeframe}
\begin{pyconsole}
len(a_word)
a_word.isalpha()
a_word.startswith("I am")
\end{pyconsole}
\end{ucodeframe}

\item We encounter some new concepts here. First, you can get the length of
a string by the built-in function \pyv{len}. Second the method
\pyv{isalpha}\footnote{You can check what it does by \pyv{help(str.isalpha)}.} returns
a \pyv{Bool} type value -- the method applies to some type and returns a value of
another type. Third, methods, being functions, can take arguments:
\pyv{startswith} takes a string as an argument and checks whether that string is
a prefix of the string that the method is run on.

\item It is very important to learn the meaning of `\Verb+=+' in programming, as
it is quite different from what we normally understand from equality in
mathematics.\footnote{Some programming languages use `\Verb+<-+' instead.}

\item Let's assume you made this:

\begin{ucodeframe}
\begin{pyconsole}
my_number = 5
your_number = my_number
\end{pyconsole}
\end{ucodeframe}

\item Now the following tests should succeed:

\begin{ucodeframe}
\begin{pyconsole}
your_number == 5
your_number == my_number
my_number == your_number
\end{pyconsole}
\end{ucodeframe}

\item Now modify \Verb+my_number+:

\begin{ucodeframe}
\begin{pyconsole}
my_number = 7
\end{pyconsole}
\end{ucodeframe}

\item What do you expect as the value of \Verb+your_number+ when you modified
the value of \Verb+my_number+? 5 or 7? Think a little before you try it on the
console. (Get the habit of thinking before trying, this is very important in
learning programming.)

\item You will discover that modifying \Verb+my_number+ has no effect on
\Verb+your_number+. This is because what is designated by `\Verb+=+' is not
equality but the relation of ``pointing to''. When you say:\footnote{Here is a
useful convention: Enclosing names between angle brackets forms a meta variable
over the type of thing designated by the name. E.g.\ ``\Verb+<identifier>+''
means ``take an arbitrary identifier'', likewise ``\Verb+value+'' stands for an
arbitrary value.}

\begin{pygments}[frame=single]{python}
<identifier> = <value>
\end{pygments}

you mean that the name \Verb+<identifier>+ points to the object \Verb+value+.
After that whenever you use the name \Verb+<identifier>+ in an expression, it
gets evaluated to the object/value it points to. On the other hand, when you
say:

\begin{pygments}[frame=single]{python}
<identifier1> = <identifier2>
\end{pygments}

you mean that the name \Verb+<identifier1>+ points to the same object/value that
the name \Verb+<identifier2>+ points to. You do not establish a direct
connection between the two identifiers; therefore manipulating one, does not
effect the other.\footnote{Take the sentence `John goes shopping on the same
day as Mary'. The two possible readings of this sentence are:
\begin{itemize}
\item[](R1) Mary goes to shopping on a certain day (say Monday), and that day is
also the day for John to go shopping.
\item[](R2) Whichever day Mary goes shopping, John does too on that day; John
follows Mary's shopping schedule day-to-day.
\end{itemize}
The relation between identifiers we are concerned here is of type R1 rather than R2. This relates to
the issue of extension versus intension.
}

\item Another important point about assignment statements is the order in which
the Python interpreter handles them. First the expression on the right hand side
is evaluated, \emph{then} the identifier on the left hand side is made pointing
to that value. One nice corollary of this is the possibility of statements like
the following:

\begin{ucodeframe}
\begin{pyconsole}
my_number = 8*(5-3)
my_number
my_number = my_number + 4
my_number
\end{pyconsole}
\end{ucodeframe}

\item It works exactly the same with other operations and other data types.

\begin{ucodeframe}
\begin{pyconsole}
my_word = 'abra'
my_word
my_word = my_word * 4
my_word
\end{pyconsole}
\end{ucodeframe}

\item We have seen some assignment statements;  pieces of
code that put the `\Verb+=+' sign in between other things. It is important to
notice how such statements differ from expressions. Take the following code:

\begin{ucodeframe}
\begin{pyconsole}
my_number = 8*(5-3)
\end{pyconsole}
\end{ucodeframe}

when you enter this into console you get an empty prompt; in other words the
console does not return anything. There is still an expression,
\Verb+8*(5-3)+, as part of the
statement and it gets evaluated; but the assignment statement itself
does not return any value; it simply makes \Verb+my_number+ point to the value
computed by evaluating \Verb+8*(5-3)+.

\item In general, a statement is a piece of code that has a side effect; it does
something beyond evaluation of expressions. Statements are executed, expressions
are evaluated. You can think of a statement as an imperative sentence. The distinction will get clarified as we go along, just keep an
eye on the distinction.

\end{itemize}

\section{Simple input/output}

\begin{itemize}

\item Some computer programs interact with their users. A basic interaction is
to ask for an input from the user and to display an output for the user. The
simplest way is using an \Verb+input()+ and \Verb+print()+ statement,
respectively:

\begin{ucodeframe}
\begin{pygments}[frame=none]{python}
>>> my_number = input()
'8'
>>> print(my_number)
'8'
>>>
\end{pygments}
\end{ucodeframe}

\item You could use \Verb+input()+ on its own as a statement -- try it. In that
case it still asks for an input to be entered, but the entered input is
inaccessible afterwards. What we did above is to store the value entered by the
user in a variable named \Verb+my_number+. This enabled us to use the value for
some other purpose later on.

\item You can make \Verb+input()+ and \Verb+print()+ more ``communicative'' by
providing them string \uterm{arguments}:

\begin{ucodeframe}
\begin{pygments}[frame=none]{python}
>>> my_number = input('Give me a number: ')
Give me a number: 8
>>> print('My favorite number is ',my_number)
My favorite number is  8
>>>
\end{pygments}
\end{ucodeframe}

\item As you might have noticed, \pyv{input} returns a string even the user has
entered an integer. Python3's \pyv{input} takes every input as a string. If you
want \pyv{input} to read what is provided by the user as if the input is entered
to the console, you \uterm{wrap} the function \pyv{eval} around \pyv{input}:

\begin{ucodeframe}
\begin{pygments}[frame=none]{python}
>>> my_number = eval(input())
8
>>> print(my_number)
8
>>> type(my_number)
<class 'int'>
>>>
\end{pygments}
\end{ucodeframe}
\end{itemize}

\section{Programs}

\begin{itemize} \item In languages like Python, a program is a sequence of
statements (and as we see later function and class definitions).\footnote{Some
people like to use the word ``script'' instead of ``program'' for Python
programs. The distinction is not important for us.} Although it is possible to
enter your program line-by-line to the console, it is much more convenient to
have it stored in a file and then run by the Python interpreter. Store your
python programs in text files with the extension \Verb+.py+, and run it by
either entering \Verb+python3 <your program>.py+ replacing \Verb+<your program>+
with the actual name of your program file, or click the appropriate menu item,
if you are using a graphical environment.

\begin{uexercise}

\begin{enumerate}
\item[]
\item Write a program that asks for your name and prints the number of letters
in it.
\item Write a program that asks for your surname and prints its 2nd and 5th
letters. (We maintain that no surname has less than 5 letters by filling the
empty slots with 'x' when entering the input string.)
\item Write a program that asks for two integers and prints their product.
\item Write a program that asks for a word, and prints a version of it where the
first letter is changed to 'C'. (Type \pyv{help(str)} in the console to see some
useful string methods.)
\item Write a program that asks for a word, and prints a version of it where the
first and the last letter is in upper-case.
\item Write a program that asks for a string and prints 0 if it has an even
length and 1 if it has an odd length. Do not use \pyv{if},  use \pyv{%}.
\item Write a program that asks for a string and prints \Verb+True+ if its
2nd and 4th symbols are equal. Do not use \Verb+if+.
\end{enumerate}

\end{uexercise}

\end{itemize}

\section{Containers}

\subsection{Lists}

\begin{itemize}
\item A Python \uterm{list} is a comma separated sequence of objects enclosed in
square brackets.

\begin{ucodeframe}
\begin{pyconsole}
a = [1,2,3]
type(a)
b = list('abcd')
b
\end{pyconsole}
\end{ucodeframe}

\item String indexing \index{indexing!list} works for lists as well -- make sure you fully understand
how all the expressions below are evaluated.

\begin{ucodeframe}
\begin{pyconsole}
things =  [2,3,'x',7,'yz',13]
things[5]
things[2:5:2]
things[2:5:2][1]
things[2:5:2][1][1]
\end{pyconsole}
\end{ucodeframe}

\item In contrast to strings, lists are mutable\index{mutable}; you can change any element of a
list by using the corresponding index; but you cannot add an element to a list in
this way -- try.

\begin{ucodeframe}
\begin{pyconsole}
things =  [2,3,'x',7,'yz',13]
things[5]= ['u',8]
things
\end{pyconsole}
\end{ucodeframe}

\item Note that a list can contain any type of object, including lists.

\item The concatenation\index{concatenation!list} operator `\Verb-+-' used for stings is applicable also
to lists.

\begin{ucodeframe}
\begin{pyconsole}
things =  [2,3,'x',7,'yz',13]
more_things = ['u',8]
things + more_things
\end{pyconsole}
\end{ucodeframe}

\item The concatenation operator `\Verb-+-' returns the result of concatenation
of its operands, without changing the operands themselves. After the
concatenation above, the lists \Verb+things+ and \Verb+more_things+ stay the
same as before. If you want to change a list by concatenating another list to
it, you have two options:

\item[] Option 1:
\begin{ucodeframe}
\begin{pyconsole}
things =  [2,3,'x',7,'yz',13]
more_things = ['u',8]
things = things + more_things
things
\end{pyconsole}
\end{ucodeframe}

\item[] Option 2:
\begin{ucodeframe}
\begin{pyconsole}
things =  [2,3,'x',7,'yz',13]
more_things = ['u',8]
things.extend(more_things)
things
\end{pyconsole}
\end{ucodeframe}

\item The \Verb+extend()+ method is easy to confuse with \Verb+append()+. The
latter adds its argument to the list it runs on:

\begin{ucodeframe}
\begin{pyconsole}
w =  [2,3,7]
w.append('x')
w
w.append(['x'])
w
w.extend(['x'])
w
\end{pyconsole}
\end{ucodeframe}

\item[] therefore extending a list $L$ with some list $[a]$ is
equivalent to appending $a$ to $L$.

\item Lists allow for multiple assignments:

\begin{ucodeframe}
\begin{pyconsole}
w = [8,0]
x, y = w
print(x,y)
\end{pyconsole}
\end{ucodeframe}

\item The test for membership is done as follows:

\begin{ucodeframe}
\begin{pyconsole}
w = [8,0]
7 in w
8 in w
v = 3
v in [1,2,3]
\end{pyconsole}
\end{ucodeframe}

\item A useful method for string to list conversion is \Verb+split()+:

\begin{ucodeframe}
\begin{pyconsole}
s = '1;2;3;4'
s.split(';')
t= '1 2 3 4'
t.split(' ')
\end{pyconsole}
\end{ucodeframe}

\item The dual of \Verb+split()+ is \Verb+join()+:

\begin{ucodeframe}
\begin{pyconsole}
t= ['a','b','c','d']
'-'.join(t)
\end{pyconsole}
\end{ucodeframe}
Note that \Verb+join+ works only with lists of strings.
\end{itemize}

\subsection{Tuples}

\begin{itemize}
\item A Python \uterm{tuple} is an immutable list.

\begin{ucodeframe}
\begin{pyconsole}
w = 1,4,2
type(w)
w
u = tuple([1,4,2])
u
v = tuple('abcde')
v
\end{pyconsole}
\end{ucodeframe}

\item Except methods and operations that are aimed to change the object,
whatever you can do with a list applies for a tuple as well.

\item Advice: Use tuples instead of lists, (only) when there is a risk of accidentally
altering the contents and/or size of the container.
\end{itemize}

\subsection{Dictionaries}

\begin{itemize}
\item A Python \uterm{dict} is a set of key-value pairs:

\begin{ucodeframe}
\begin{pyconsole}
employer32 = {'Name':'J. Smith', 'Department':'Pretty Things'}
employer32['Department']
\end{pyconsole}
\end{ucodeframe}

\end{itemize}

\subsection{Sets}
\begin{itemize}

\item Python has a \uterm{set} data type that
implements the mathematical concept of sets. Use \Verb+help(set)+ to see how
this data type works.

\item Use sets instead of lists, if repetitions and order is not important for
the task at hand.

\end{itemize}

\section{Flow of control}

\begin{itemize}

\item We will cover 3 basic ways to control the flow of execution:
	\begin{enumerate}
	\item sequencing;
	\item conditional branching;
	\item looping, which takes the two forms:
		\begin{enumerate}
		\item bounded looping;
		\item conditional looping.
		\end{enumerate}
	\end{enumerate}

\end{itemize}

\subsection{Sequencing}

\begin{itemize}

\item This is the most basic control structure, and it is also simple to state:
in the absence of other control structures statements are executed in the order
they are encountered going from top to bottom.

\end{itemize}

\subsection{Conditional branching}

\begin{itemize}

\item A simple conditional statement is of the form
\item[]
\uterm{if} $<$\emph{boolean
expression}$>$ \uterm{then} $<$\emph{statements}$>$

where
$<$\emph{statements}$>$ are executed if $<$\emph{boolean expression}$>$ gets
evaluated as \Verb+True+, and skipped otherwise. The syntax of the expression requires some care:

\begin{ucodeframe}
\inputpygments{python}{code/simple-if.py}
\end{ucodeframe}

\item The above code tells the interpreter what to do when the provided boolean
test returns \Verb+True+; you can specify what to do for the \Verb+False+ case
as well.

\begin{ucodeframe}
\inputpygments{python}{code/else-if.py}
\end{ucodeframe}

\end{itemize}

\subsection{Looping}

\begin{itemize}

\item  Looping allows for repeating an action with different parameters at every
repetition.

\end{itemize}

\subsubsection{Bounded loops}

\begin{itemize}

\item The maximum number of repetitions is fixed. Python uses the \Verb+for+
structure for this.

\begin{ucodeframe}
\inputpygments{python}{code/for-example.py}
\end{ucodeframe}

\end{itemize}

\subsubsection{Conditional loops}

\begin{itemize}

\item The second type of looping does not have an upper bound for the number of
repetitions. The loop runs as long as a condition is met. Python has the
\Verb+while+ construct for this purpose:

\item The program in Code~\ref{while-example} illustrates a typical use of a
\pyv{while} loop.

\begin{uexample}[While loop.]\label{while-example}
\item[]
\begin{ucodeframe}
\inputpygments{python}{code/while-example.py}
\end{ucodeframe}
\end{uexample}

\begin{uexercise}\label{excontainers}
\begin{enumerate}
\item Write a program (\Verb+flip+) that takes a string as input and gives
another string which has the same characters as the input except
the case of every cased character (i.e.\ letters) is altered.
It would turn
\Verb+'abRaCadABra'+
 to
\Verb+'ABrAcADabRA'+,
\Verb+'Aa++aA' to \Verb+'aA++Aa', and so on.

You may traverse a string letter by letter by using a \Verb+for+ loop, exactly
like how we do for lists. Each iteration gives a one character string from the
original string in the order of their appearance.

You may use the built-in string functions \Verb+isupper()+, \Verb+islower()+,
\Verb+upper()+, \Verb+lower()+ in your program.

\item
Write a program (\Verb+acro+) that takes a string and returns an acronym.
For instance it should return \Verb+'LSD'+ for
\Verb+'Lucy in the Sky with Diamonds+'.

But be careful, it should NOT return \Verb+'ISIS'+ for \\ \Verb+'mIddle eaSt technIcal univerSity'+, \\ but print \Verb+'Sorry, no acronym for that.'+
instead. You may use the built-in functions mentioned in the previous question.

\item
Write a program (\Verb+zipp+) that takes two lists and returns a list formed by
taking one element from the first, then one from the second, then from the
first, and so on. The program should be able to handle cases where one list is
shorter than the other. Example outputs would be
\Verb+[1, 5, 2, 6, 3, 7, 4, 8]+
for input lists \Verb+[1,2,3,4]+ and \Verb+[5,6,7,8]+, or for example
\Verb+[1, 5, 2, 6, 7, 8]+ for input lists \Verb+[1,2]+ and \Verb+[5,6,7,8]+.

\item
Write a program (\Verb+flat+) that takes a possibly nested list (= a list
with at least one element which is itself a list) and returns a non-nested list.
It gives \Verb+[1,2,3,4,5]+ for \Verb+[[1,2],3,[4],5]+, or \Verb+[1,2,3]+ for
\Verb+[[1],[[2]], [[[3]]]]+, and so on.

You can check whether the value of a variable, say \Verb+mylist+, is a list or
not by the python expression \Verb+type(mylist) is list+; this evaluates to
\Verb+True+ if \Verb+mylist+ holds a list, and \Verb+False+ otherwise. Therefore
you can write a conditional statement which controls the behavior of your
program according to whether a certain object is a list or not.

\item \label{excartesian}
Write a program that takes two sets from the user and prints the Cartesian
product of the give sets in the form of a set of 2-tuples. You can use Python lists or
sets to represent sets.
\href{https://github.com/umutozge/prog-book/blob/master/code/cartesian-product.py}{[solution]}

\end{enumerate}
\end{uexercise}

\end{itemize}

\section{Functions}
\label{sec:functions}

\begin{itemize}

\item A Python function is a subprogram that can be called within other programs, including itself.

\item For instance, assume you have the task of deciding whether two lists of numbers have the same arithmetic mean. Here is a first attempt:

\begin{ucodeframe}
\inputpygments{python}{code/comp-mean-long.py}
\end{ucodeframe}

\item The above program can be improved by putting the lists
themselves in a for loop, thereby writing the code for mean
calculation only once.

\begin{ucodeframe}
\inputpygments{python}{code/comp-mean-middle.py}
\end{ucodeframe}

\item We will now separate the calculation of the mean from the main
program by defining a function that computes the mean of a given list
of numbers. First, the function definition in the Python way:

\begin{ucodeframe}
\inputpygments{python}{code/comp-mean-func.py}
\end{ucodeframe}

\item Now the complete program:

\begin{ucodeframe}
\inputpygments{python}{code/comp-mean.py}
\end{ucodeframe}

\item Organizing your programs into functions is good because:
	\begin{itemize}
	\item it makes the program easy to write/understand;
	\item the function can be re-used within the same program or by other programs.
	\end{itemize}

\item Python functions come in three types:
\begin{itemize}
\item functions that return a value, as above;
\item functions that has a side effect without returning anything;
\item functions that do both.
\end{itemize}

\item A function \uterm{terminates} (or \uterm{halts}) when:
	\begin{enumerate}
	\item a \Verb+return+ statement is executed;
	\item an exception that sends the control to outside of the function
	occurs;\footnote{This will get clarified when we cover errors and
	exceptions.}
	\item the last statement in the function definition is executed.
	\end{enumerate}
\end{itemize}

\begin{itemize}
\item Names internal to a function are invisible to and irrelevant for the users
of that function. The case is exactly like in mathematics. Take the function
that sums the squares of two numbers:
$$f(x,y) = x^2 + y^2$$
The function may well have been defined as:
$$f(s,t) = s^2 + t^2$$
Which way it is defined is totally irrelevant for its use.

\item This brings us to the notion of \uterm{scope} of a variable. Take the
following simple functions:

\begin{ucodeframe}
\begin{pygments}[frame=none]{python}

def g(y,x):
	return y - x

def f(x,y):
	return g(x,y) / (x + y)

\end{pygments}
\end{ucodeframe}

\item[] What would be the result of \pyv{f(4,6)}?
\item[] When the function \pyv{f} is called with these \uterm{parameters}, the
following assignments are made:

\begin{align*}
\pyv{x}\leftarrow 4\\
\pyv{y}\leftarrow 6
\end{align*}

\item[] When \pyv{g} is called with the parameters \pyv{x} and \pyv{y} from
within \pyv{f}, what happens is that the identifier \pyv{y} in the definition of
\pyv{g} is made to point to the value that was being pointed to by the
identifier \pyv{x} of \pyv{f}.\footnote{Strictly speaking, these identifiers are
created afresh every time the function is invoked.} Pretty confusing.  In order
not to get confused, in referring to an identifier, let us indicate the owner
function as a subscript.  When \pyv{f(4,6)} is invoked we have:

\begin{align*}
\pyv{x}_{\pyv{f}} \leftarrow 4\\
\pyv{y}_{\pyv{f}}\leftarrow 6
\end{align*}

\item As \pyv{g(x,y)} is invoked, the variable assignments become like this:

\begin{align*}
\pyv{x}_{\pyv{f}} \leftarrow 4\\
\pyv{y}_{\pyv{f}}\leftarrow 6\\
\pyv{x}_{\pyv{g}} \leftarrow 6\\
\pyv{y}_{\pyv{g}}\leftarrow 4
\end{align*}

\item This shows that the naming of the variables in \pyv{g} is totally
independent of those of \pyv{f}. In invoking a function what is important is the
position of the parameters. The first identifier in the function definition is
made to point to the value of the first parameter in the function call, the
second identifier points to the value of the second parameter, and so on.

\item A functional parameter or any identifier that is created within the body
of a function does not exist outside the body of that function.

\item You can think of each identifier as having an owner. This could be the
main program, a function within the program, or a construct like a \pyv{for}
loop. The rule to keep in mind is that an identifier always belongs to the
closest owner.

% Here is an example, work out the value of \pyv{a(1,2)}:
%
% \begin{ucodeframe}
% {\small
% \inputpygments{python}{code/scope-example-for-loop.py}
% }
% \end{ucodeframe}
%

% \item You may leave a variable \uterm{free} in a function; but then it needs to
% refer to a value that is outside the scope of the function, otherwise you get an
% error.

\begin{uexercise}

\begin{enumerate}
\item[]
\item Write a Python function \pyv{no_111} that takes a string argument and
returns \pyv{True} if the provided string is in the following language and
\pyv{False} otherwise:

\begin{align*}
\setabs{w\in \crbr{0,1}^*}{w \text{ has no substring }111}
\end{align*}

Your function should NOT use built-in string methods that search for a certain
substring in a given string. Use a counter instead. \href{https://github.com/umutozge/prog-book/blob/master/code/cartesian-product.py}{[solution]}

Note that although the question asks for a function rather than a program, you
need to test your function for correctness. The easiest way to do it is to have
a program that has your function definition and uses it. Below is an example
that tests a string for whether it starts with a capital letter or not. There
are lines starting with \pyv{#}. These comments are ignored by the Python
interpreter. They are written for other programmers to help them understand your
programs.
\href{https://github.com/umutozge/prog-book/blob/master/code/func-prog-ex.py?dl=0}{Download
the program to your computer}, and run to observe its behavior.

\begin{ucodeframe}
\footnotesize
\inputpygments{python}{code/func-prog-ex.py}
\end{ucodeframe}

\item Assume that exam grades are kept as a list of tuples. Each tuple pairs
a student with her/his grade, e.g.\ \pyv{[('John',85),('Mary',90),('Maya',54)]}.
Write a function that takes the student-grade list as input and returns the
class average. Your function should work for any class size.

\item Write a python program that takes two lists of integers from the user
and returns the number of elements that occur at the same position in both of
the lists. {\bf Do not use a function definition}. Note that, your program
should be able to handle the case where the two lists are not equal in size.
In reading a list from the user, put your \pyv{input()} function inside
\pyv{eval()}; this way the user can directly type a list. Observe the following
sample interaction:

\begin{ucodeframe}
\footnotesize
\begin{Verbatim}
Python 3.4.2 (default, Oct  8 2014, 13:14:40)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> my_list = eval(input('A list please: '))
A list please: [1,2,3]
>>> my_list
[1, 2, 3]
>>> type(my_list)
<class 'list'>
>>>
\end{Verbatim}
\end{ucodeframe}

Some example sessions of your program
would look like the following.

\begin{ucodeframe}
\begin{Verbatim}
A list please: [1,[2,3],3,5,4]
A list please: [2,3,3,4,[3,4]]
the number of corresponding elements is:  1

A list please: [1,2,3,4,5,6,7]
A list please: [1,2,3]
the number of corresponding elements is:  3
\end{Verbatim}
\end{ucodeframe}

\item

Modify your program so that the number of corresponding elements is returned by a function.

\item

Write a python program that takes a list as input, prints each member to the
screen, together with the information whether the member has been encountered
before or not. A sample session would be like the following.

\begin{ucodeframe}
\begin{Verbatim}
A list please: [1,3,1,4,2,3]
1 new to me
3 new to me
1 seen before
4 new to me
2 new to me
3 seen before
\end{Verbatim}
\end{ucodeframe}
\end{enumerate}
\end{uexercise}

\end{itemize}

\section{Taking notes on your code}

\begin{itemize}

\item Good computer code is usually self-explanatory. Using meaningful identifier
names and having a neat and clear structure are good programming practices.

\item However as programs get complicated, it becomes necessary to add some text
to your  code that is meant for a programmer -- you, in the first place. The
usual name for such devices is \uterm{comment}.\index{comments}

\item Single-line comments are written after `\pyv{#}' character.
Anything that comes after `\pyv{#}' it until a line break is ignored by the interpreter.

\begin{ucodeframe}
\inputpygments{python}{code/hash-comment.py}
\end{ucodeframe}

\item If you need to use line breaks in your comment, Python provides a block
comment structure. A block comment starts and ends with three consecutive
double quotes and can include line breaks. Block comments can appear in anywhere
in your code; but those immediately following a function definition appear on
the help of that function (TODO: more on this later).

\begin{uexample}
Here is the solution to
Exercise \ref{excontainers}.\ref{excartesian} put into function form:
\begin{ucodeframe}
\inputpygments{python}{code/cartesian-product-func.py}
\end{ucodeframe}

\qed
\end{uexample}

\end{itemize}

\section{Some basic programming techniques} {

\subsection{Counters}

\begin{itemize}

\item Counting is perhaps the first thing that comes to mind about computing.
Keeping a variable that is incremented or decremented according to certain
conditions checked within a loop is a ubiquitous programming technique.

\item A simple example would be a function that takes a list and an object,
returning the number of times the object occurs in the list.

\begin{uexample}[Count occurrences]
\item[]
\vspace{-10pt}
\begin{ucodeframe}
\inputpygments{python}{code/occurs-count.py}
\end{ucodeframe}
\qed
\end{uexample}

\item Note the way the \pyv{count} variable is incremented. It is a short
form that we have been avoiding till now. It is equivalent to the statement `\pyv{count = count
+ 1}'.

\end{itemize}

\subsection{Accumulators}

\begin{itemize}

\item Assume you do not have multiplication as a primitive operator, i.e.\ no
`\Verb+*+'.  Given two non-negative integers $m$ and $n$, you can think of their
multiplication as adding $m$ to 0 for $n$ times. Here is a program that
\uterm{implements} this idea.

\item At any given point of this computation we need to have access to two values.
One is how many more $m$'s we need to add; the other the value of $m$'s added so far.
We use a counter -- $n$ itself -- for the first and an \uterm{accumulator},
\pyv{product}, for the second.

\begin{uexample}[Multiplication]
A program that multiplies two integers without using a multiplication
operator.\footnote{If you wonder how would this roundabout way of implementing multiplication
compares with Python's multiplication operator `\pyv{*}' speed-wise, try
multiplying 12 with 6666666666 (twelve 6's in a row), first directly on the
Python interpreter, then by the program.}

\begin{ucodeframe}
\inputpygments{python}{code/multiadd.py}
\end{ucodeframe}
\qed
\end{uexample}

\end{itemize}

\subsection{Flags}

\begin{itemize}

\item Counters and accumulators are devices that are incremented or decremented
as the computation advances. Their size depend on the input. Some programming
tasks call for keeping track of the state of a variable, called
 a \uterm{flag}\index{flags},  which can be in one of
a fixed number of states. If
the number of states is 2, then a boolean type variable is used to store the
state, like an on/off switch. Here is an example:

\begin{uexample}

Below is a function that takes a string and returns
\pyv{True}
 if the input string consists of zero or more \pyv{'a'}s and \pyv{'b}'s
without more than 3 consecutive
\pyv{a}'s, and returns \pyv{False} otherwise.\footnote{This is not the optimum way
to solve this problem; the function loops through the input string till the end
even in cases a reject decision becomes inevitable at a non-final iteration. The
purpose of the code is to illustrate the use of a flag.}

\begin{ucodeframe}
\inputpygments{python}{code/flag-example.py}
\end{ucodeframe}

\qed
\end{uexample}

\end{itemize}

\subsection{Windows}

\begin{itemize}

\item In all the examples so far, the decision of how to manipulate our counters
and/or accumulators were based on the current item in a loop. In some programming
tasks you need to check a number of items coming from consecutive iterations of
a loop. An example:

\begin{uexample}

Now we have a slightly different string recognition task.
Here we need to accept strings of zero or more \pyv{a}'s and \pyv{b}'s that do \emph{not}
contain the substring \pyv{'abab'}.

\begin{ucodeframe}
\inputpygments{python}{code/window-example.py}
\end{ucodeframe}

\qed
\end{uexample}
\end{itemize}

\begin{uexercise}
\begin{enumerate}
\item[]
\item Write a function named \pyv{myJoin} that takes a string type separator and a list of strings
and returns a string where the strings in the list are joined by the separator.
%\href{https://github.com/umutozge/prog-book/blob/master/code/my_join.py}{[solution]}
\item Write a function named \pyv{compare} that takes two integers, returns
\pyv{"GT"}, \pyv{"LT"} or \pyv{"EQ"}.
%\href{https://github.com/umutozge/prog-book/blob/master/code/.py}{[solution]}
\item Write a function that takes a list and returns a list obtained by removing
	the first element of the input list. If the list is empty the function should
return back the empty list.
\href{https://github.com/umutozge/prog-book/blob/master/code/remove_head.py}{[solution]}
\item Write a function that takes an input list and removes its first element.
The input list needs to be one element less after the function is applied.
\href{https://github.com/umutozge/prog-book/blob/master/code/remove_head_in_place.py}{[solution]}
\item Write a function that takes a list of integers and an integer and removes
all occurrences of the integer from the list and returns the modified
list.
\href{https://github.com/umutozge/prog-book/blob/master/code/remove_all.py}{[solution]}
\item Write a function that takes a list of integers and an integer and removes
only the first occurrence of the integer from the list and returns the modified
list. \href{https://github.com/umutozge/prog-book/blob/master/code/remove_first.py}{[solution]}
\item Take a third argument \pyv{n} and remove at most \pyv{n} occurrences.
\href{https://github.com/umutozge/prog-book/blob/master/code/remove_n.py}{[solution]}
\item Remove the last occurrence of an item from a list; do NOT reverse the list
or traverse it from backwards.
\item Input: a list; Output: a palindrome of the list (e.g.\ given [1,2,3],
returns [1,2,3,3,2,1]). Do not use builtin reverse function.
%\href{https://github.com/umutozge/prog-book/blob/master/code/list-palind.py}{[solution]}
\item A program that takes a string as input and prints a horizontal histogram of the
characters like below, for instance for the input \pyv{"abracadabra"}

\begin{Verbatim}
a *****
b **
c *
d *
r **
\end{Verbatim}
\href{https://github.com/umutozge/prog-book/blob/master/code/char_histo.py}{[solution]}

\item Make a vertical histogram.
\href{https://github.com/umutozge/prog-book/blob/master/code/char_histo_vert.py}{[solution]}
\end{enumerate}
\end{uexercise}

\begin{uexercise}
\begin{enumerate}
\item[]
\item
Write a program \pyv{fact} that gives the factorial of a given non-negative integer.
(Factorial of 0 is 1, factorial of $n$ is $1\times 2 \times\ldots
n$.)\href{https://github.com/umutozge/prog-book/blob/master/code/fact-iter-for.py}{[solution1]}
 \href{https://github.com/umutozge/prog-book/blob/master/code/fact-iter-while.py}{[solution2]}

\item
Write a function that takes a list as input and returns its reverse. Use
an accumulator in your solution. Also write functions that works for strings and
works for both.  \href{https://github.com/umutozge/prog-book/blob/master/code/reverse.py}{[solution]}

\item Write a function \pyv{flip} that takes a string and returns another
string where the case of each character is flipped from upper to lower or vice
versa. Check the string methods \pyv{isupper()}, \pyv{upper()}, \pyv{islower()},
and \pyv{upper()}--do not use \pyv{swap()}.
\href{https://github.com/umutozge/prog-book/blob/master/code/flip.py}{[solution]}

\item Write a  function \pyv{seclarge} that takes a list of integers
as input and returns the second largest element of the list. You need to write a
function that applies to a list of integers of any length and there is no
requirement that the elements of the lists be distinct. Make a list of all
exceptional cases (empty list, lists with repeated elements, and the like),
decide what to do in these cases, and make your function handle all these cases
smoothly. \href{https://github.com/umutozge/prog-book/blob/master/code/seclarge.py}{[solution]}

\item
Write a function \pyv{swap} that takes a list and two indices as arguments
and swaps the elements at the given indices. Your function should return the
modified list, if swap is successful; otherwise -- for instance if one or both
of the indices is beyond the size of the list -- your function should return the
special python expression \Verb+None+.
\href{https://github.com/umutozge/prog-book/blob/master/code/swap.py}{[solution]}

\item
Write a function (\Verb+maincon+) that takes a propositional logic formula as a
string and returns its main connective. Assume that input formulae
are totally parenthesized -- no parenthesis omission by convention. Use
\Verb+-+, \Verb+>+, \Verb+A+,\Verb+V+, for logical connectives $-$, $\imp$,
$\land$, $\lor$, respectively. Use lower case letters for proposition symbols.
\href{https://github.com/umutozge/prog-book/blob/master/code/maincon.py}{[solution]}

\end{enumerate}
\end{uexercise}

\section{Working with files}

\begin{itemize}
\item To handle a file you need a
\uterm{stream}\index{file handling!input streams} object:

\begin{ucodeframe}
\pyv{f = open("textfile.txt","r")}
\end{ucodeframe}

The file `textfile.txt' needs to be in the directory you run the program or invoke
the console.

\item The second argument to the function \pyv{open()} is the \uterm{mode} of
the stream object,\footnote{Strictly speaking, it is a \pyv{TextIOWrapper} object.}
 and the most common ones are \pyv{"r"} for read, \pyv{"w"} for write,
and \pyv{"a"} for append; combinations are possible.  Check
\href{https://docs.python.org/3/library/functions.html#open}{here} for
additional modes.

\item Once you have a stream object in read mode, the method \pyv{readlines()}
returns the list of lines in the file. If you want to read lines one at a time,
you need to use \pyv{readline()}. You can use the help function of the console
to inspect other methods on streams.

\begin{uexample}\label{filei} Let us read a
\href{https://github.com/umutozge/prog-book/blob/master/code/tr-word-list.txt}{list}
of Turkish words and compute the average word length.

\begin{ucodeframe}
\inputpygments{python}{code/mean-word-length.py}
\end{ucodeframe}

\end{uexample}

\item In order to write to a file, open a stream with
\pyv{"w"} or \pyv{"a"} mode. The latter adds output to an already existing file,
while the former creates a new file or overwrites what was already there. The
basic writing method is \pyv{.write()}, you can also write a list of strings as
lines by \pyv{.writelines()}.

\begin{uexercise}
\begin{enumerate}
\item[]
\item[] Read words as in Example\ref{filei}. Write palindromes to a separate file,
word per line.
\end{enumerate}
\end{uexercise}

\end{itemize}

\section{Importing modules}

\begin{itemize}

\item By default, only a small number of basic functions and classes\footnote{A
class is a program that defines types of objects together with various methods
of those objects.} are available for the Python interpreter. For instance there
is no means to generate random numbers by default. Python 3 provides the
\uterm{module} named \pyv{random} for this and related functionality. In order
to be able to use functions in a Python module, you need to import the module:

\begin{ucodeframe}
\begin{pyconsole}
import random
\end{pyconsole}
\end{ucodeframe}

\item Now you can use functions from the module by prefixing their names by
\pyv{random.}. Here is how to generate a random integer from a certain range,
including the end points:

\begin{ucodeframe}
\begin{pyconsole}
random.randint(0,9)
\end{pyconsole}
\end{ucodeframe}

\item Other useful functions are \pyv{choice()}, \pyv{sample()} and
\pyv{shuffle()}.

\begin{ucodeframe}
\begin{pyconsole}
random.choice(["Alpha","Bravo","Charlie","Delta","Echo"])
random.sample(range(1,1000),10)
list = [1,2,3,4,5]
random.shuffle(list)
list
\end{pyconsole}
\end{ucodeframe}

\item Be careful that \pyv{shuffle()} does not return a value, it shuffles its
list argument \emph{in-place}.

\begin{uexercise} \begin{enumerate} \item[] \item Read in the word list file as
in \ref{filei}. Import the module \pyv{statistics}.  After importing the module
you can check the contents by \pyv{help(statistics)} in the console or visit
\href{https://docs.python.org/3/library/statistics.html}{here}. Find out how to
compute mean and standard deviation. Use this methods to calculate the mean word
length and standard deviation. Write in a separate file all the words that are
longer than mean + 2 times standard deviation. This will give you "unusually
long" words of Turkish language.

\item
Read in the word list; randomly pick a word; shuffle it, ask the user to guess
the original, unshuffled word.

\item
Modify your solution to the previous item, such that a correct answer need
not be the original word, any word in the word list would do.

\item Write a function that takes a set of integers (you can take it as a list
and eliminate repetitions) and generates a random binary relation as a set of
ordered tuples.
\item Write functions that check functionhood, reflexivity, symmetry and
transitivity of binary relations.

\end{enumerate}
\end{uexercise}

\end{itemize}

\section{Higher order functions}

\begin{itemize}
\item Higher order functions are functions that receive and/or deliver
functions.

\begin{uexample}
The following function takes a function and a list, and applies the
function to all the items in the list and returns the results, again in a list
in the same order.

\begin{ucodeframe}
\inputpygments{python}{code/lapply.py}
\end{ucodeframe}

\qed
\end{uexample}

\begin{uexample}
Now a function which takes a function \pyv{f}, a value \pyv{k} and the number \pyv{n}  of
times \pyv{f} is to be applied.
\begin{ucodeframe}
\inputpygments{python}{code/mapply.py}
\end{ucodeframe}

\qed
\end{uexample}

\begin{uexample}
Now a function whose return value is a function; taking two function arguments
and returning their composition:

\begin{ucodeframe}
\inputpygments{python}{code/compose.py}
\end{ucodeframe}

Save this function definition in a file \pyv{ftools.py} (for ``function
tools''); you can load the definitions in a python file by importing it either
in another program or in the console. For now, the file should be in the same
directory with the importing program or where you invoked the console. And you
need to prefix whatever you call from the loaded module with the module name.

\begin{ucodeframe}

\begin{pyconsole}
import ftools
smax = ftools.compose(str,max)
smax([100,102,1002])
s2max = ftools.compose(len,smax)
s2max([100,102,1002])
\end{pyconsole}
\end{ucodeframe}

\qed
\end{uexample}

\end{itemize}

\section{Lambda abstraction}

\begin{itemize}
\item In its most ordinary use \pyv{lambda}'s provide a concise way of defining
functions. Here is a function that duplicates a string or a number:

\begin{ucodeframe}
\begin{pyconsole}
f = lambda x : 2*x
f(4)
f("vah")
f(f("vah"))
\end{pyconsole}
\end{ucodeframe}

\item The \pyv{lambda} keyword is followed by the argument and the body of the
function comes after the \pyv{:}.

\item You do not need to name \pyv{lambda} functions in order to use them; you
may directly use the definition itself, do not forget the parenthesis around the
function and the argument:

\begin{ucodeframe}
\begin{pyconsole}
(lambda x: 3*x**2 + 5*x + 2)(8)
\end{pyconsole}
\end{ucodeframe}

\item You may have as many arguments as you like:

\begin{ucodeframe}
\begin{pyconsole}
(lambda x, y : (x+y)/(x*y))(2,4)
\end{pyconsole}
\end{ucodeframe}

\item The above function would give a division-by-zero error, if any of its
arguments is zero. Therefore, it would be good to check for this and return
\pyv{None} if this is the case:

\begin{ucodeframe}
\begin{pyconsole}
k = lambda x, y : (x+y)/(x*y) if x*y != 0 else None
k(2,4)
type(k(0,4))
\end{pyconsole}
\end{ucodeframe}

\item Given a function with more than one arguments, you can abstract over any
argument you like via \pyv{lambda}. Here is an example. Python's math module
provides a logarithm function whose default base is
$e=2.78281828\ldots$.\footnote{Logarithm function $\log_b a$ gives the exponent
$x$ such that $a=b^x$.} In order to use it in another base you need to specify
the base as a second argument:

\begin{ucodeframe}
\begin{pyconsole}
import math
math.log(8)
math.log(8,2)
\end{pyconsole}
\end{ucodeframe}

\item[] Assume you need to use the logarithm function in base 2 frequently. You
can define your own logarithm function as:

\begin{ucodeframe}
\begin{pyconsole}
import math
log = lambda x : math.log(x,2)
log(8)
\end{pyconsole}
\end{ucodeframe}

\item You can also abstract over the base argument. The following function takes
one argument and returns the logarithm of 8 taking the argument as the base:

\begin{ucodeframe}
\begin{pyconsole}
import math
f = lambda x : math.log(8,x)
f(2)
f(10)
\end{pyconsole}
\end{ucodeframe}

\item Let us now go higher order and define a function that takes a two-place
function and abstracts over the first argument of this function, specifying its second argument.

\begin{ucodeframe}
\begin{pyconsole}
abstract1 = lambda f, x : lambda y : f(y,x)
\end{pyconsole}
\end{ucodeframe}

\item[]Note that the return value of the function \pyv{abstract1} is itself a
function -- the part coming after the first `:'. If you want to turn the
Python's built-in logarithm function to a function operating at base 2, all you
need is:

\begin{ucodeframe}
\begin{pyconsole}
import math
log2 = abstract1(math.log,2)
log2(16)
\end{pyconsole}
\end{ucodeframe}

\item Here is a similar function that abstracts over the second argument,
specifying the first argument:

\begin{ucodeframe}
\begin{pyconsole}
abstract2 = lambda f, x : lambda y : f(x,y)
\end{pyconsole}
\end{ucodeframe}

\item Let us use \pyv{abstract2} on the binary function \pyv{math.pow} giving the
result of raising its first argument to the power of its second argument.

\begin{ucodeframe}
\begin{pyconsole}
import math
math.pow(2,3)
pow2 = abstract2(math.pow,2)
pow2(3) == math.pow(2,3)
\end{pyconsole}
\end{ucodeframe}

\item Generalizing one step further, we arrive at a function \pyv{abstract} that
takes which argument -- first or second -- to abstract over as a parameter (1
for the first and 2 for the second):

\begin{ucodeframe}
\begin{pyconsole}
abstract = lambda f, x, n :\
lambda y : f(x,y) if n==2 else lambda y : f(y,x)
import math
abstract(math.pow,10,2)(3)
\end{pyconsole}
\end{ucodeframe}
Note the use of the backslash  character `$\backslash$` to break lines

\end{itemize}

\section{List comprehensions}

\begin{itemize}
\item It is a highly common programming task to map a list of items to another
list. For instance, you have a set of integers and you want the set of squares
of these integers. One way to do it is to initialize an accumulator and
collect all the squared integers in this accumulator through a for loop
iterating over the original list. Python provides a concise way of realizing
such processes.

\begin{ucodeframe}
\begin{pyconsole}
import math
k = [1,2,3,4,5]
[math.pow(x,2) for x in k]
\end{pyconsole}
\end{ucodeframe}

\item You can apply a filter to a list comprehension. For instance, if you want
only the squares of even numbers in a list, you do:

\begin{ucodeframe}
\begin{pyconsole}
import math
k = [1,2,3,4,5]
[math.pow(x,2) for x in k if x%2 == 0]
\end{pyconsole}
\end{ucodeframe}

\hrulefill
\begin{uexercise}
Write a function \pyv{closest} that takes 3 arguments:
\begin{itemize}
\item[] \pyv{x}: an integer;
\item[] \pyv{y}: an integer;
\item[] \pyv{k}: a list of unary functions on integers.
\end{itemize}

The function \pyv{closest} should return the value closest to \pyv{y} obtained by applying one
of the functions in \pyv{k} to \pyv{x} once.

\end{uexercise}
\begin{uexercise}
Collatz Conjecture states that starting from any positive integer, one
eventually arrives at 1, repeatedly applying the following function:

$$C(n) =
\begin{cases}
n/2, &\text{ if }$n$\text{ is even}\\
3n+1, &\text{ otherwise.} $$
\end{cases}
$$
	For instance, the Collatz series for 6 would be, 6,3,10,5,16,8,4,2,1.

\begin{enumerate}
\item Write a function that computes the Collatz series for a given integer.
\item Write a function that takes an integer \pyv{n} and a list of integers
\pyv{k}, and filters out elements in \pyv{k} which are NOT in the Collatz series
of \pyv{n}.
\item Write a function that maps a list of integers to the list of number of
steps required to reduce them to 1.
\item Write a function that takes two integers \pyv{x} and \pyv{y}, and
returns the number of integers less than or equal to \pyv{x} that can be reduced
to 1 in \pyv{y} or fewer steps.
\end{enumerate}
\end{uexercise}

\end{itemize}
\hrulefill

\section{Recursion}

\begin{itemize}

\item A recursive function/procedure includes a call to itself.

\begin{uexample}

Let us first examine an \uterm{iterative} algorithm for the factorial function:

\begin{ucodeframe}
\vspace{1em}
\begin{algorithmic}
\Function{Factorial}{$n$}
\State $result \gets 1$
\State $count \gets 0$
	\While{$count < n$}
		\State $count \gets count + 1$
		\State $result \gets result \times count$
	\EndWhile
\State \Return $result$
\EndFunction
\end{algorithmic}
\end{ucodeframe}

Now a recursive algorithm for computing the same function.

\begin{ucodeframe}
\vspace{1em}
\begin{algorithmic}
\Function{Factorial}{$n$}
\If{$n = 0$}
\State \Return 1
\Else
\State \Return $n*$ \Call{Factorial}{$n-1$}
\EndIf
\EndFunction
\end{algorithmic}

\end{ucodeframe}

\end{uexample}

\item Note that the recursive algorithm for factorial is easier to understand.

\hrulefill
\begin{uexercise}
\begin{enumerate}
\item[]
\item Write Python code that implements the iterative algorithm for
the factorial; write two versions, one with \Verb+while+ and the other with
\Verb+for+.

\begin{hide}
\begin{usolution}
\begin{ucodeframe}
\inputpygments{python}{code/fact-iter-while.py}
\end{ucodeframe}

\begin{ucodeframe}
\inputpygments{python}{code/fact-iter-for.py}
\end{ucodeframe}
\end{usolution}
\end{hide}

\item Write Python code implementing the recursive algorithm.
\begin{hide}
\begin{usolution}
\begin{ucodeframe}
\inputpygments{python}{code/fact-rec.py}
\end{ucodeframe}
\end{usolution}
\end{hide}
\end{enumerate}
\end{uexercise}
\hrulefill

\begin{uexample}
A more advanced example of recursion is the solution to the ancient
game \href{https://en.wikipedia.org/wiki/Tower_of_Hanoi}{\uterm{Towers of Hanoi}}.

The game involves a number of disks with holes in the middle, by which
they can be fitted into pegs (or sticks). There are three pegs in total, call
them $A$, $B$ and $C$. Initially all the disks are fitted to one of the disks in
an order of decreasing size -- smallest on top. You can move one disk at a time
from peg to peg. In no state of the game a larger disk can sit on top of a
smaller one. The aim of the game is to transfer the stack of disks from its
initial peg to another peg.

Two questions that immediately arise about the game: Given $n$ disks:
	\begin{itemize}
	\item[i.] What is the minimum number of moves to transfer the disks to
	another peg;
	\item[ii.] What are the specific moves for the same task.
	\end{itemize}

Work out the problem by hand for $n=3$ and $n=4$. This might reveal a recursive
solution to the problem. Give yourself some time to work on the solution before
reading on.

Once you work out the solution for $n=3$, the solution for $n=4$ is simply
running the solution for $n=3$ once,  moving the 3 disks to another location;
then moving the 4th disk to the location which is empty, and finally running the
solution for $n=3$ once more to bring the 3 disks on top of the 4th. Therefore,
the number of moves you have in total is two times the number of moves for
moving 3 disks plus 1. If this works for 4 disks, why should not it work for 5
disks: first move the top 4 to another location, then the 5th, then the 4 on top
of the 5th. You can also use the same method to compute the result for 3 disks:
2 times the number of moves for 2 disks plus 1. It is not hard to see that the
method works for an arbitrary integer $n$ greater than 1, no matter how large it
is. The only case you need to dictate the result rather than use the method is
$n=1$, where the number of moves is simply 1. Here is an algorithm to compute
the number of moves for any $n$:

\begin{ucodeframe}
\hspace{1em}
\begin{algorithmic}
\Function{Number-of-Moves}{$n$} \Comment compute number of moves for $n$ disks
\If{$n=1$}
\State\Return 1
\Else
\State\Return ($2\times$ \Call{Number-of-Moves}{$n-1$}) $+1$
	\EndIf
\EndFunction
\end{algorithmic}
\end{ucodeframe}

\end{uexample}

\begin{uexample}
Constructing a function that gives you the specific moves in Towers of Hanoi is a harder task.
As a hint to the solution, think of a function with 4 parameters:
move $n$ disks from $A$ to $B$ by using $C$. Try for some time, before reading
on.

\begin{ualgorithmic}
\Function{Move}{$n,X,Y,Z$} \Comment move $n$ disks from $X$ to $Y$ using $Z$
	\If{$n=1$}
		\State\Print `Move from $X$ to $Y$'
	\Else
		\State\Call{Move}{$n-1,X,Z,Y$} \Comment move $n-1$ disks from $X$ to $Z$ using $Y$
		\State\Print `Move from $X$ to $Y$'
		\State\Call{Move}{$n-1,Z,Y,X$} \Comment move $n-1$ disks from $Z$ to $Y$ using $X$
	\EndIf
\EndFunction
\end{ualgorithmic}
\end{uexample}

\hrulefill
\begin{uexercise}
\begin{itemize}
\item[]
\item[a.] Implement the recursive algorithm for computing the number of moves for Towers of Hanoi in Python. How does your counting
program behave as the number of disks gets larger?

\item[b.] Implement the recursive algorithm for computing the moves for Towers
of Hanoi in Python. A sample interaction with such a program would look like:

\begin{ucodeframe}
\begin{Verbatim}
[code]$ python -i hanoi_moves_rec.py
>>> moves(3,'A','B','C')
Move A to B
Move A to C
Move B to C
Move A to B
Move C to A
Move C to B
Move A to B
>>>
\end{Verbatim}
\end{ucodeframe}

\end{itemize}
\end{uexercise}
\hrulefill

\begin{hide}
\begin{usolution}
\begin{ucodeframe}
\inputpygments{python}{code/hanoi_count_rec.py}
\end{ucodeframe}
\begin{ucodeframe}
\inputpygments{python}{code/hanoi_moves_rec.py}
\end{ucodeframe}
\end{usolution}
\end{hide}

\item As you might have realized thinking of the solution and
implementing it is easier than actually understanding how it works.

\item In order to better understand how the algorithm works, you can either
trace the computation by pencil and paper, or use a visual debugger.
TODO: Debugger section.

\end{itemize}

\subsection{Tail recursion}

Take the rather simple task of reversing a list. An iterative procedure with a \Verb+for+ or \Verb+while+ loop should be easy to construct by now. A recursive procedure would not be much harder to think of.

\begin{ualgorithmic}
\Function{Reverse}{$l$}
	\If{$l$ is empty}
		\State\Return $l$
	\Else
		\State\Return \Call{Reverse}{all but first of $l$} + [first of $l$]
	\EndIf
\EndFunction
\end{ualgorithmic}

Python implementation is straightforward:

\begin{ucodeframe}
\inputpygments{python}{code/recursive-reverse.py}
\end{ucodeframe}

The following is the trace of the computation of this algorithm applied to \Verb+[1,2,3,4,5]+:

\begin{ucodeframe}
\footnotesize
\begin{Verbatim}
reverse([1,2,3,4,5])
  reverse([2,3,4,5]) + [1]
    reverse([3,4,5]) + [2]
      reverse([4,5]) + [3]
        reverse([5]) + [4]
          reverse([]) + [5]
            []
          [5]
        [5,4]
      [5,4,3]
    [5,4,3,2]
  [5,4,3,2,1]
\end{Verbatim}
\end{ucodeframe}

In the above diagram each level of indentation stands for a call of the
function \Verb+reverse(l)+.  What is striking here is that in every recursive
call of the function, some partial results have to be kept aside to be merged
again after the series of recursive calls hits the basis case of an empty list. From start to end all the calls should be kept active in the memory.

Now we see a slightly different approach which still has a recursive function call, but nevertheless looks more tidy in its computation. Our function will have an optional argument, which will be used as an accumulator for the result, just like we have been doing in iterative procedures we saw earlier. We directly give the python code (you are encouraged to write the pseudocode as an exercise):

\begin{ucodeframe}
\inputpygments{python}{code/tail-recursive-reverse.py}
\end{ucodeframe}

\begin{ucodeframe}
\footnotesize
\begin{Verbatim}
reverse([1,2,3,4,5], [])
  reverse([2,3,4,5], [1])
    reverse([3,4,5], [2,1])
      reverse([4,5], [3,2,1])
        reverse([5], [4,3,2,1])
          reverse([], [5,4,3,2,1])
          [5,4,3,2,1]
\end{Verbatim}
\end{ucodeframe}

As can be observed through the trace of computation, given any level in the stack of recursive function calls, how the computation will proceed is entirely determined by the information present in that step; you do not need to care about previous steps, as you will not need to return to them anymore. An interpreter made aware of this fact will optimize the computation by getting rid of the unnecessary information, freeing up space. The technical name is Tail Call Optimization and recursive procedures that are suitable for such optimization are called tail-recursive.\footnote{Python3 does not do such optimization. Each function call in the tail-recursive version of the reversing function will be kept in memory until the end of the procedure. As in each call the entire input list is kept, the tail-recursive program takes longer to execute.}

\newpage
\printindex
\end{document}

\section{Procedure versus Process}

\begin{itemize}
\item explain this over factorial as in scip -- perhaps do this after recursion.
\end{itemize}

\section{Paradigm functions}

\begin{itemize}
\item Primitive recursive functions: power, greatest common divisor,
$n^{th}$ prime.
\item Computable but not primitive recursive: Ackermann's function.

$$
A(x,y) =
\begin{cases}
y + 1, & \text{if }x = 1\\
A(x-1,1), & \text{if }y = 0\\
A(x-1,A(x,y-1), & \text{otherwise.}
\end{cases}
$$

\item Tree recursion -- the paradigm example is the computation of Fibonacci
numbers:

$$
Fib(n) =
\begin{cases}
0, & \text{if }n = 0\\
1, & \text{if }n = 1\\
Fib(n-1) + Fib(n-2), & \text{otherwise.}
\end{cases}
$$

\item The following is perhaps the conceptually most straightforward way of
computing the $n^{th}$ Fibonacci number.

{
\small
\begin{pygments}[frame=single]{python}
def fib(n):
	if n == 1:
		return 1
	elif n == 0:
		return 0
	else:
		return fib(n-1) + fib(n-2)
\end{pygments}
}

\item However, this is a very costly way of computing Fibonacci numbers. The
reason becomes obvious when you draw a tree that traces the computation of, say,
$Fib(5)$.

\item Fortunately, it is possible to compute Fibonacci numbers with an iterative function as
follows:

{
\small
\begin{pygments}[frame=single]{python}
def fibit(n):
	if n <= 1:
		return n

	first, second = 1, 0

	for i in range(n-1):
		swap = first + second
		second = first
		first = swap

	return first
\end{pygments}
}

\end{itemize}
\renewcommand{\bibsep}{0pt}
\renewcommand{\bibfont}{\small}
\bibliography{ozge}
\bibliographystyle{natgig}
\end{document}