Commit 04f898f4 authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'enh/virtual_mini_pytreat_intro_purple_monkey_dishwasher' into 'master'

virtual mini pytreat intro

See merge request fsl/pytreat-practicals-2020!23
parents c131e3e7 d1bb3f45
% The purpose of this comment is purely
% to make life difficult for you. Sorry
% about that. I'm not really sorry.
128.3 100.8 67.2 120.1 150.2 53.0 64.2 139.3 46.7 118.1 125.8 153.1 83.2 115.9 3.4 126.3 92.2 104.7 131.2 29.3
89.3 118.8 119.2 80.1 121.2 35.0 66.2 153.3 43.7 102.1 147.8 160.1 94.2 140.9 70.4 124.3 124.2 93.7 100.2 32.3
91.3 146.8 137.2 129.1 157.2 -22.0 75.2 90.3 33.7 86.1 74.8 90.1 114.2 81.9 72.4 135.3 85.2 102.7 58.2 55.3
75.3 87.8 84.2 112.1 131.2 57.0 150.2 73.3 41.7 110.1 78.8 102.1 116.2 134.9 34.4 74.3 150.2 52.7 89.2 21.3
79.3 83.8 78.2 103.1 96.2 26.0 151.2 122.3 46.7 113.1 143.8 80.1 61.2 136.9 8.4 94.3 76.2 123.7 150.2 10.3
93.3 157.8 154.2 79.1 155.2 8.0 63.2 120.3 12.7 130.1 105.8 111.1 66.2 99.9 54.4 120.3 113.2 128.7 110.2 46.3
111.3 126.8 65.2 90.1 101.2 36.0 116.2 139.3 36.7 91.1 88.8 94.1 90.2 92.9 -0.6 46.3 80.2 105.7 88.2 -11.7
149.3 119.8 134.2 124.1 89.2 21.0 133.2 113.3 28.7 139.1 136.8 82.1 141.2 90.9 11.4 97.3 109.2 137.7 120.2 32.3
141.3 149.8 115.2 115.1 105.2 51.0 77.2 130.3 -4.3 124.1 141.8 162.1 95.2 130.9 -10.6 114.3 132.2 134.7 79.2 69.3
141.3 77.8 135.2 167.1 103.2 55.0 153.2 68.3 33.7 136.1 125.8 85.1 148.2 114.9 76.4 57.3 147.2 125.7 153.2 45.3
13,7,3,18,15,3,12,11,9,9
13,1,7,17,16,13,18,9,18,6
9,19,16,3,18,3,19,12,9,6
2,11,6,12,2,11,15,9,3,9
2,12,1,7,4,3,6,6,2,4
10,8,14,1,17,19,8,19,2,9
18,14,2,11,17,14,6,16,14,18
6,8,13,16,11,17,16,5,16,15
6,5,4,18,6,14,19,8,4,15
15,17,12,10,17,12,5,9,18,6
Congratulations, you have read your first file from Python!
1 3
14 3
4 7
12 5
15 5
14 4
15 19
7 17
7 15
16 3
15 14
17 9
7 8
4 5
15 4
11 5
17 10
3 19
14 4
18 3
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Welcome to the WIN Virtual Mini PyTreat 2020!\n",
"\n",
"\n",
"This notebook is available at:\n",
"\n",
"\n",
"https://git.fmrib.ox.ac.uk/fsl/pytreat-practicals-2020/-/tree/master/talks%2Fvirtual_intro/intro.ipynb\n",
"\n",
"\n",
"If you have FSL installed and you'd like to follow along *interactively*,\n",
"follow the instructions for attendees in the `README.md` file of the above\n",
"repository, and then open the `talks/virtual_intro/intro.ipynb` notebook.\n",
"\n",
"\n",
"# Contents\n",
"\n",
"\n",
"* [Introduction](#introduction)\n",
" * [Python in a nutshell](#python-in-a-nutshell)\n",
" * [Different ways of running Python](#different-ways-of-running-python)\n",
"* [Variables and basic types](#variables-and-basic-types)\n",
" * [Integer and floating point scalars](#integer-and-floating-point-scalars)\n",
" * [Strings](#strings)\n",
" * [Lists and tuples](#lists-and-tuples)\n",
" * [Dictionaries](#dictionaries)\n",
" * [A note on mutablility](#a-note-on-mutablility)\n",
"* [Flow control](#flow-control)\n",
" * [List comprehensions](#list-comprehensions)\n",
"* [Reading and writing text files](#reading-and-writing-text-files)\n",
" * [Example: processing lesion counts](#example-processing-lesion-counts)\n",
"* [Functions](#functions)\n",
"* [Working with `numpy`](#working-with-numpy)\n",
" * [The Python list versus the `numpy` array](#the-python-list-versus-the-numpy-array)\n",
" * [Creating arrays](#creating-arrays)\n",
" * [Example: reading arrays from text files](#example-reading-arrays-from-text-files)\n",
"\n",
"\n",
"<a class=\"anchor\" id=\"introduction\"></a>\n",
"# Introduction\n",
"\n",
"\n",
"This talk is an attempt to give a whirlwind overview of the Python programming\n",
"language. It is assumed that you have experience with another programming\n",
"language (e.g. MATLAB).\n",
"\n",
"\n",
"This talk is presented as an interactive [Jupyter\n",
"Notebook](https://jupyter.org/) - you can run all of the code on your own\n",
"machine - click on a code block, and press **SHIFT+ENTER**. You can also \"run\"\n",
"the text sections, so you can just move down the document by pressing\n",
"**SHIFT+ENTER**.\n",
"\n",
"\n",
"It is also possible to *change* the contents of each code block (these pages\n",
"are completely interactive) so do experiment with the code you see and try\n",
"some variations!\n",
"\n",
"\n",
"You can get help on any Python object, function, or method by putting a `?`\n",
"before or after the thing you want help on:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 'hello!'\n",
"?a.upper"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And you can explore the available methods on a Python object by using the\n",
"**TAB** key:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Put the cursor after the dot, and press the TAB key...\n",
"a."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a class=\"anchor\" id=\"python-in-a-nutshell\"></a>\n",
"## Python in a nutshell\n",
"\n",
"\n",
"**Pros**\n",
"\n",
"\n",
"* _Flexible_ Feel free to use functions, classes, objects, modules and\n",
" packages. Or don't - it's up to you!\n",
"\n",
"* _Fast_ If you do things right (in other words, if you use `numpy`)\n",
"\n",
"* _Dynamically typed_ No need to declare your variables, or specify their\n",
" types.\n",
"\n",
"* _Intuitive syntax_ How do I run some code for each of the elements in my\n",
" list?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mylist = [1, 2, 3, 4, 5]\n",
"\n",
"for element in mylist:\n",
" print(element)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Cons**\n",
"\n",
"\n",
"* _Dynamically typed_ Easier to make mistakes, harder to catch them\n",
"\n",
"* _No compiler_ See above\n",
"\n",
"* _Slow_ if you don't do things the right way\n",
"\n",
"* _Python 2 is not the same as Python 3_ But there's an easy solution: Forget\n",
" that Python 2 exists.\n",
"\n",
"* _Hard to manage different versions of python_ But we have a solution for\n",
" you: `fslpython`.\n",
"\n",
"\n",
"Python is a widely used language, so you can get lots of help through google\n",
"and [stackoverflow](https://stackoverflow.com). But make sure that the\n",
"information you find is for **Python 3**, and **not** for **Python 2**!\n",
"Python 2 is obsolete, but is still used by many organisations, so you will\n",
"inevitably come across many Python 2 resources.\n",
"\n",
"\n",
"The differences between Python 2 and 3 are small, but important. The most\n",
"visible difference is in the `print` function: in Python 3, we write\n",
"`print('hello!')`, but in Python 2, we would write `print 'hello!'`.\n",
"\n",
"\n",
"FSL 5.0.10 and newer comes with its own version of Python, bundled with nearly\n",
"all of the scientific libraries that you are likely to need.\n",
"\n",
"\n",
"So if you use `fslpython` for all of your development, you can be sure that it\n",
"will work in FSL!\n",
"\n",
"\n",
"<a class=\"anchor\" id=\"different-ways-of-running-python\"></a>\n",
"## Different ways of running Python\n",
"\n",
"\n",
"Many of the Pytreat talks and practicals are presented as *Jupyter notebooks*,\n",
"which is a way of running python code in a web browser.\n",
"\n",
"\n",
"Jupyter notebooks are good for presentations and practicals, and some people\n",
"find them very useful for exploratory data analysis. But they're not the only\n",
"way of running Python code.\n",
"\n",
"\n",
"**Run Python from a file**\n",
"\n",
"\n",
"This works just like it does in MATLAB:\n",
"\n",
"\n",
"1. Put your code in a `.py` file (e.g. `mycode.py`).\n",
"2. Run `fslpython mycode.py` in a terminal.\n",
"3. ??\n",
"4. Profit.\n",
"\n",
"\n",
"**Run python in an interpreter**\n",
"\n",
"\n",
"Python is an [*interpreted\n",
"language*](https://en.wikipedia.org/wiki/Interpreted_language), like MATLAB.\n",
"So you can either write your code into a file, and then run that file, or you\n",
"can type code directly into a Python interpreter.\n",
"\n",
"\n",
"Python has a standard interpreter built-in - run `fslpython` in a terminal,\n",
"and see what happens (use CTRL+D to exit).\n",
"\n",
"\n",
"**But** there is another interpreter called [IPython](https://ipython.org/)\n",
"which is vastly superior to the standard Python interpreter. Use IPython\n",
"instead! It is already installed in `fslpython`, so if you want to do some\n",
"interactive work, you can use `fslipython` in a terminal.\n",
"\n",
"\n",
"<a class=\"anchor\" id=\"variables-and-basic-types\"></a>\n",
"# Variables and basic types\n",
"\n",
"\n",
"There are many different types of values in Python. Python *variables* do not\n",
"have a type though - a variable can refer to values of any type, and a\n",
"variable can be updated to refer to different values (of different\n",
"types). This is just like how things work in MATLAB.\n",
"\n",
"\n",
"<a class=\"anchor\" id=\"integer-and-floating-point-scalars\"></a>\n",
"## Integer and floating point scalars"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 7\n",
"b = 1 / 3\n",
"c = a + b\n",
"print('a: ', a)\n",
"print('b: ', b)\n",
"print('c: ', c)\n",
"print('b: {:0.4f}'.format(b))\n",
"print('a + b:', a + b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a class=\"anchor\" id=\"strings)\"></a>\n",
"## Strings"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 'Hello'\n",
"b = \"Kitty\"\n",
"c = '''\n",
"Magic\n",
"multi-line\n",
"strings!\n",
"'''\n",
"\n",
"print(a, b)\n",
"print(a + b)\n",
"print('{}, {}!'.format(a, b))\n",
"print(c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"String objects have a number of useful methods:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s = 'This is a Test String'\n",
"print(s.upper())\n",
"print(s.lower())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another useful method is:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s = 'This is a Test String'\n",
"s2 = s.replace('Test', 'Better')\n",
"print(s2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Two common and convenient string methods are `strip()` and `split()`. The\n",
"first will remove any whitespace at the beginning and end of a string:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s2 = ' A very spacy string '\n",
"print('*' + s2 + '*')\n",
"print('*' + s2.strip() + '*')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With `split()` we can tokenize a string (to turn it into a list of strings)\n",
"like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(s.split())\n",
"print(s2.split())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also use the `join` method to re-construct a new string. Imagine that\n",
"we need to reformat some data from being comma-separated to being\n",
"space-separated:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = ' 1,2,3,4,5,6,7 '"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`strip`, `split` and `join` makes this job trivial:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print('Original: {}'.format(data))\n",
"print('Strip, split, and join: {}'.format(' '.join(data.strip().split(','))))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a class=\"anchor\" id=\"lists-and-tuples\"></a>\n",
"## Lists and tuples\n",
"\n",
"\n",
"Both tuples and lists are built-in Python types and are like cell-arrays in\n",
"MATLAB. For numerical vectors and arrays it is much better to use *numpy*\n",
"arrays, which are covered later.\n",
"\n",
"\n",
"Tuples are defined using round brackets and lists are defined using square\n",
"brackets. For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"t = (3, 7.6, 'str')\n",
"l = [1, 'mj', -5.4]\n",
"print(t)\n",
"print(l)\n",
"\n",
"t2 = (t, l)\n",
"l2 = [t, l]\n",
"print('t2 is: ', t2)\n",
"print('l3 is: ', l2)\n",
"print(len(t2))\n",
"print(len(l2))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The key difference between lists and tuples is that tuples are *immutable*\n",
"(once created, they cannot be changed), whereas lists are *mutable*:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = [10, 20, 30]\n",
"a[2] = 999\n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Square brackets are used to index tuples, lists, strings, dictionaries, etc.\n",
"For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d = [10, 20, 30]\n",
"print(d[1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **MATLAB pitfall:** Python uses zero-based indexing, unlike MATLAB, where\n",
"> indices start from 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = [10, 20, 30, 40, 50, 60]\n",
"print(a[0])\n",
"print(a[2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A range of values for the indices can be specified to extract values from a\n",
"list or tuple using the `:` character. For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a[0:3])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **MATLAB pitfall:** Note that Python's slicing syntax is different from\n",
"> MATLAB in that the second number is *exclusive*, i.e. `a[0:3]` gives us the\n",
"> elements of `a` at positions `0`, `1` and `2` , but *not* at position `3`.\n",
"\n",
"\n",
"When slicing a list or tuple, you can leave the start and end values out -\n",
"when you do this, Python will assume that you want to start slicing from the\n",
"beginning or the end of the list. For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a[:3])\n",
"print(a[1:])\n",
"print(a[:])\n",
"print(a[:-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also change the step size, which is specified by the third value (not\n",
"the second one, as in MATLAB). For example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a[0:4:2])\n",
"print(a[::2])\n",
"print(a[::-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some methods are available on `list` objects for adding and removing items:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(d)\n",
"d.append(40)\n",
"print(d)\n",
"d.extend([50, 60])\n",
"print(d)\n",
"d = d + [70, 80]\n",
"print(d)\n",
"d.remove(20)\n",
"print(d)\n",
"d.pop(0)\n",
"print(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What will `d.append([50,60])` do, and how is it different from\n",
"`d.extend([50,60])`?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d.append([50, 60])\n",
"print(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a class=\"anchor\" id=\"dictionaries\"></a>\n",
"## Dictionaries\n",
"\n",
"\n",
"Dictionaries (or *dicts*) can be used to store key-value pairs. Almost\n",
"anything can used as a key, and anything can be stored as a value; it is\n",
"common to use strings as keys:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],