{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Python\n", "***\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following is a short introduction to Jupyter notebooks (formerly known as IPython notebooks) and Python. It is loosely based on more comprehensive tutorials [IPython Notebook Tutorial](http://cs231n.github.io/ipython-tutorial/) and [Python / Numpy Tutorial](http://cs231n.github.io/python-numpy-tutorial/). For a full Python documentation see [Python documentation](https://docs.python.org/3.7/)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Jupyter notebook\n", "\n", "---\n", "In this course, we will be using Jupyter notebooks. A Jupyter notebook lets you write and execute Python code in your web browser. Jupyter notebooks make it very easy to tinker with code and execute it in bits and pieces; for this reason Jupyter notebooks are widely used in scientific computing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Installation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Ubuntu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On Ubuntu install the web application Jupyter Notebook by typing the following three commands in the console" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ sudo apt update" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ sudo apt install python3-pip python3-dev" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ sudo pip3 install jupyter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Windows" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On Windows follow the instructions given for example in [A Beginner’s Guide to Installing Jupyter Notebook Using Anaconda Distribution](https://medium.com/@neuralnets/beginners-quick-guide-for-handling-issues-launching-jupyter-notebook-for-python-using-anaconda-8be3d57a209b). Note that the Anaconda distribution also includes installation of Python language." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running Jupyter notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you have `jupyter` installed, start the notebook with the command" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ jupyter notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If everything worked correctly, your web browser should pop up and you should see a screen like this, showing all available Jupyter notebooks in the current directory" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![caption](figures/file-browser.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, there is a Jupyter notebook file called `IPython tutorial.ipynb` in our working directory. If you clicked through to the notebook file, you would see a screen like this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![caption](figures/notebook-1.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A Jupyter notebook is made up of a number of cells. Each cell can contain Python code. You can execute a cell by clicking on it and pressing `Shift-Enter`. When you do so, the code in the cell will run, and the output of the cell will be displayed beneath the cell. For example, after running the first cell the notebook looks like this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![caption](figures/notebook-2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Global variables are shared between cells. Executing the second cell thus gives the following result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![caption](figures/notebook-3.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By convention, Jupyter notebooks are expected to be run from top to bottom. Failing to execute some cells or executing cells out of order can result in errors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![caption](figures/notebook-error.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This has only been a brief introduction to Jupyter notebooks, but it should be enough to get you up and running on this course." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python\n", "\n", "---\n", "Python is a high-level, dynamically typed programming language. Python code is often said to be almost like pseudocode, since it allows you to express very powerful ideas in very few lines of code while being very readable.\n", "\n", "There are currently two different supported versions of Python, 2.7 (run by `python` command) and 3.7 (run by `python3` command). Somewhat confusingly, Python 3.0 introduced many backwards-incompatible changes to the language, so code written for 2.7 may not work under 3.7 and vice versa. For this course all code will use Python 3.7.\n", "\n", "On most Unix systems (Linux distributions, macOS), both versions of Python are pre-installed so you don't need to worry about the installation. You can check your Python 3 version at the command line by running `python3 --version`.\n", "\n", "In case you are using a Windows system, install Python through Anaconda distribution as mentioned above by following the instructions given for example in [A Beginner’s Guide to Installing Jupyter Notebook Using Anaconda Distribution](https://medium.com/@neuralnets/beginners-quick-guide-for-handling-issues-launching-jupyter-notebook-for-python-using-anaconda-8be3d57a209b)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Imports" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modules are Python `.py` files that consist of Python code and can define functions, classes, and variables that you can reference in other Python `.py` files. Typically for this course, we will be using the `fenics` module. Modules are accessed by using the `import` statement as follows" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [], "source": [ "import fenics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now access everything from the `fenics` module via the statement `fenics.\"something\"`, e.g. the function `IntervalMesh` is accessed in the following way" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [], "source": [ "mesh = fenics.IntervalMesh(20, 0.0, 2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When the module name is ubiquitous in your code, it is a good practice to use" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [], "source": [ "import fenics as fe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "to shorten your code. This way we can call `IntervalMesh` just by writing" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [], "source": [ "mesh = fe.IntervalMesh(20, 0.0, 2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If one wants to access an object from a Python module directly, one can use the syntax" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from fenics import IntervalMesh" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and then access the function `IntervalMesh` as follows" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "mesh = IntervalMesh(20, 0.0, 2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another possibility for importing objects from a module represents the so called wildcard import written as" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from fenics import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above code imports *everything* from the module `fenics`. This practice is generally not recommended as the import statements should be as specific as possible and should only import what they need." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python functions are defined using the `def` keyword. For example" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [], "source": [ "def sign(x):\n", " if x > 0:\n", " return 'positive'\n", " elif x < 0:\n", " return 'negative'\n", " else:\n", " return 'zero'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "defines a function `sign` which takes one argument (a number) and returns a string which says whether the given number is positive, negative, or zero. Let's try it out" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "negative\n", "zero\n", "positive\n" ] } ], "source": [ "for x in [-1, 0, 1]:\n", " print(sign(x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Classes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python is an object oriented programming language. Almost eveything in Python is an object which has its properties and methods. A `class` keyword initiates an object constructor. Let us create a class called `Greeter` with property `name` and method `greet()`" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [], "source": [ "class Greeter(object):\n", "\n", " # Constructor\n", " def __init__(self, name):\n", " self.name = name\n", "\n", " # Instance method\n", " def greet(self, loud=False):\n", " if loud:\n", " print('HELLO, {}!'.format(self.name.upper()))\n", " else:\n", " print('Hello, {}'.format(self.name))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Conventionally, the name of an object constructor starts with a capital letter (that's why \"`Greeter`\"). We can now create an object (an instance of the class `Greeter`) via" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [], "source": [ "greeter_1 = Greeter('Fred')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The variable `greeter_1` now holds an instance of the class `Greeter` initialized with a name `'Fred'`. Let us verify that" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fred\n" ] } ], "source": [ "print(greeter_1.name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also access the instance's method `greet()`" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Fred\n", "HELLO, FRED!\n" ] } ], "source": [ "greeter_1.greet()\n", "greeter_1.greet(loud=True)" ] } ], "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.6.9" } }, "nbformat": 4, "nbformat_minor": 2 }