{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "The Python syntax is uncomplicated whenever possible. Python is arguably one of the most syntactically natural programming languages.\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Comments\n", "\n", "Comments are used throughout this course, let's show a few examples." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'Multiple line comments do not exist in Python,\\nunlike /* */ in C++ or Java. One can use multiline\\nstrings, which are simply not assigned to any variable\\nand thus thrown away immediately. Docstring use this\\napproach as well, see below.'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# - This is a comment\n", "# - It always begins by \"#\" (hash)\n", "# - This is more or less quivalent to // in C++\n", "\n", "a = 1 + 2 # A comment on a line with a code\n", "\n", "\"\"\"Multiple line comments do not exist in Python,\n", "unlike /* */ in C++ or Java. One can use multiline\n", "strings, which are simply not assigned to any variable\n", "and thus thrown away immediately. Docstring use this\n", "approach as well, see below.\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Plain commands\n", "Simply try the following commands and their modifications." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "data": { "text/plain": [ "1.55" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1 + 1.1 / 2 # the result of a simple calculation is assigned to a variable\n", "print(type(a)) # print output (stdout)\n", "a # IPython displays the last command result" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello world!\n", "type(a) = , len(a) = 12\n" ] } ], "source": [ "a = \"Hello\" + \" world!\" # a simple string manipulation\n", "print(a)\n", "print(\"type(a) = %s, len(a) = %i\" % (type(a), len(a))) # a formated output" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 0.707\n" ] } ], "source": [ "import math # importing a module\n", "a = math.cos(math.pi / 4) # using the cos function and the pi constant\n", "print('a = %.3g' % a)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 0.707\n" ] } ], "source": [ "from math import sin, pi # importing selected symbols from a module\n", "a = sin(pi / 4)\n", "print('a = %.3g' % a)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "ename": "NameError", "evalue": "name 'cos' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcos\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpi\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# this should not work --> an exception is thrown\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mNameError\u001b[0m: name 'cos' is not defined" ] } ], "source": [ "a = cos(pi / 2) # this should not work --> an exception is thrown" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# A few important builtin functions\n", "There is not too many [built-in functions](http://docs.python.org/2/library/functions.html) in Python. Let us mention some of them (which we might have already encountered).\n", "\n", "* `dir` -- list symbols (functions, variables, methods) in a given context\n", "* `eval` -- evaluates a string as a code and returs the result\n", "* `help` -- helps us (displays the 'docstring')\n", "* `len` -- the lengths of something (a string, a list, etc.)\n", "* `open` -- opens a file\n", "* `print` -- prints out a string\n", "* `raw_input` -- reads input from keyboard\n", "* `str`, `repr` -- returns a text reprezentation of an object\n", "* `type` -- returns the type of the argument\n", "\n", "We shall get introduced to these and other built-in functions soon." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['In', 'Out', '_', '_1', '_2', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_i', '_i1', '_i2', '_i3', '_i4', '_i5', '_i6', '_i7', '_ih', '_ii', '_iii', '_oh', '_sh', 'a', 'exit', 'get_ipython', 'math', 'pi', 'quit', 'sin']\n", "\n", "['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']\n" ] } ], "source": [ "print(str(dir()) + \"\\n\") # display the current context (variables etc)\n", "print(repr(dir(\"a\"))) # display the symbols of a string object (attributes, methods)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can demonstrate the `raw_input` and the `eval` power on a simple \"calculator\"." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 2\n", "Enter an expression that contains a: a * 2 + a**2\n", "a * 2 + a**2 = 8\n" ] } ], "source": [ "a = 2\n", "e = input(\"a = {}\\nEnter an expression that contains a: \".format(a))\n", "print(\"{} = {}\".format(e, eval(e)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Python operators\n", "\n", " + - * ** / // %\n", " << >> & | ^ ~\n", " < > <= >= == != <>\n", " or and not\n", " is is not in not in\n", "\n", "# Keywords\n", "\n", " and del from not while\n", " as elif global or with\n", " assert else if pass yield\n", " break except import print\n", " class exec in raise\n", " continue finally is return\n", " def for lambda try" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conditions and other blocks in Python\n", "Code blocks (or [compound statements](http://docs.python.org/2/reference/compound_stmts.html)) \n", "consist of one or more ‘clauses.’ A clause consists of a header and a ‘suite.’ The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header’s colon, or it can be one or more indented statements on subsequent lines. Only the latter form of suite can contain nested compound statements; the following is illegal, mostly because it wouldn’t be clear to which if clause a following else clause would belong:\n", "\n", "The indentation is arbitrary but it must be consistent across a single file. Strongly recommended are **four spaces**, as noticed in [PEP 8 -- Style Guide for Python Code](http://www.python.org/dev/peps/pep-0008/#indentation). This document contains important *conventions*, such as the name conventions for variables, functions, classes etc.\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "It's true that 2 > 1\n", "It's true that 2 > 1 and not true that 1 > 2\n" ] } ], "source": [ "# this is an example of nested if statements\n", "if 2 > 1:\n", " print(\"It's true that 2 > 1\")\n", " if 1 > 2:\n", " print(\"It's true that 2 > 1 and 1 > 2\")\n", " else:\n", " print(\"It's true that 2 > 1 and not true that 1 > 2\")\n", "else:\n", " print(\"It's not true that 2 > 1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For conditional statements we have `if` - `elif` - `else`. There is nothing like switch / case (as it can be easily substituted by multiple elif statements)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This I can count with fingers on single hand\n" ] } ], "source": [ "a = 5\n", "if a > 10:\n", " print(\"Cannot count this with fingers\")\n", "elif a > 5:\n", " print(\"We need both hands' fingers to count this\")\n", "elif a >= 0:\n", " print(\"This I can count with fingers on single hand\")\n", "else:\n", " print(\"Cannot do negative numbers\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`while` blocks use the same indentation rules:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "a = 0\n", "while a < 5:\n", " print(a)\n", " a += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`while` blocks (as well as `for` but we'll explain `for` later) can have an `else` part, which is executed when the condition is false." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The end, a = 1\n" ] } ], "source": [ "a = 10\n", "while a < 5:\n", " print(\"a = %i\" % a)\n", " a += 1\n", "else:\n", " a = 1\n", "print(\"The end, a = %i\" % a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`break` interrupts a cycle, `continue` makes a new iteration, i.e. skips the commands below." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 1\n", "a = 3\n", "a = 5\n" ] } ], "source": [ "a = 0\n", "while a < 5:\n", " a += 1\n", " # even number are not printed\n", " if a % 2 == 0:\n", " continue\n", " print(\"a = %i\" % a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's find the largest three-digit number divisible by 19." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The answer is: 988\n" ] } ], "source": [ "a = 999\n", "while a > 0:\n", " if a % 19 == 0:\n", " print(\"The answer is: %i\" % a)\n", " break\n", " a -= 1\n", "else:\n", " # break nespustí else část\n", " print(\"We have not found the answer\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Multiline expressions\n", "We can split long lines using \\\\." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'this is just an abudantly long text, that does not have any meaning ...'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a_long_variable_name = \"this is just an abudantly long text, \" + \\\n", " \"that does not have any meaning ...\"\n", "a_long_variable_name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can (and should) often ommit \\\\ in expressions inside parenthesis." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-9431767748815581066" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a_long_variable_name = (10000000000000 + 2222222222222222 + 9999999999999999 + 3987493874 +\n", " 444444444444444 + 23987342978 + 9874 + 555555555555555555 +\n", " 987349987 - 9999999999999999999)\n", "a_long_variable_name" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One should not create lines longer than 80 characters (see [PEP8](http://www.python.org/dev/peps/pep-0008/#maximum-line-length)), although this convention is often not very convenient." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Function definition\n", "Functions are defined using the `def` keyword." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Python!\n" ] } ], "source": [ "# a simple function with any return value\n", "def hello():\n", " print(\"Hello Python!\")\n", "# now call our function\n", "hello()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function is not very useful as usually we need inputs and/or outputs." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Prague!\n" ] } ], "source": [ "# subj is an argument of the hello function\n", "def hello(subj):\n", " phrase = \"Hello %s!\" % subj\n", " # return stops the function execution and returns a value\n", " return phrase\n", "print(hello(\"Prague\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can distinguish *positional* and *keyword* (named) arguments. Arguments can have *implicit values*, which makes such arguments *optional*." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Prague!\n", "Nazdar Praho!\n", "Nazdar Praho!\n" ] } ], "source": [ "# greet is an argument with an implicit value\n", "def hello(subj, greet=\"Hello\"):\n", " phrase = \"%s %s!\" % (greet, subj)\n", " return phrase\n", "# we don't specify the optional freet argument\n", "print(hello(\"Prague\"))\n", "# we use greet as a keyword argument\n", "# positional arguments must come first\n", "print(hello(\"Praho\", greet=\"Nazdar\"))\n", "# we can use both subj and greet as keyword arguments\n", "print(hello(greet=\"Nazdar\", subj=\"Praho\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Functions can have variable arguments but we'll explain this later when we learn about containers." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Side effects of functions\n", "\n", "Funtions can have side efects, i.e. they can change the input arguments, if these arguments are so called *mutable*. What mutable and immutable means will be explained later. Nonetheless, it's *strongly recommended to avoid creating functions with side effects* unless it has a good reason and the name of the function indicates this behaviour. Let us show an example of a function with side effects." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "the original list\n", "['in my list']\n", "l inside my_function\n", "l = ['in my list', \"I'm here\"]\n", "x after calling my_function\n", "['in my list', \"I'm here\"]\n" ] } ], "source": [ "def my_function(l):\n", " # l should be a list\n", " l.append(\"I'm here\")\n", " print(\"l inside my_function\")\n", " print('l = {}'.format(l))\n", "print(\"the original list\")\n", "x = [\"in my list\"]\n", "print(x)\n", "my_function(x)\n", "print(\"x after calling my_function\")\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "An unpleasant surprise appears when an argument's implicit value is mutable." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['appended']\n", "['appended']\n", "['appended']\n", "['appended', 'appended']\n" ] } ], "source": [ "def foo(l=[]):\n", " # this is changing l\n", " l.append(\"appended\")\n", " print(l)\n", "# first call with an explicit input parameter\n", "foo([])\n", "# now using the implicit value - the result should be identical\n", "foo()\n", "# now repeat the previous calls again\n", "# we expect the results are indetical but they aren't\n", "foo([])\n", "foo()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can avoid side effect by copying (either using the `copy` module or by copy methods). It is usually better to assing results to new variables, e.g." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['appended']\n", "['appended']\n", "['appended']\n", "['appended']\n" ] } ], "source": [ "def foo(l=[]):\n", " p = l + [\"appended\"]\n", " print(p)\n", "# first call with an explicit input parameter\n", "foo([])\n", "# now using the implicit value - the result should be identical\n", "foo()\n", "# now repeat the previous calls again\n", "# we expect the results are indetical\n", "foo([])\n", "foo()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Using modules\n", "Complex codes are usually contained in modules. We can think about modules as simple containers with reusable functions, variables or classes. We will show how to create modules later; nevertheless using modules is basically unavoidable. The standard (built-in) Python library is in fact a collection of modules." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0\n" ] } ], "source": [ "# import (i.e. read and use) the math module \n", "import math\n", "# cos is a function from the math module\n", "print(math.cos(0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apart from importing whole modules we can import only certain symbols. To import the `cos` function:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0\n" ] } ], "source": [ "from math import cos\n", "# cos can be now called without math.\n", "print(cos(0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also import everything from a module by using `from ... import *`. We have to be careful if symbols from the module do not collide with other symbols as they would be overwritten." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0\n" ] } ], "source": [ "from math import *\n", "print(sin(pi/2))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }