├── .gitignore ├── .readthedocs.yaml ├── 00-first-steps.ipynb ├── 01-python-basics.ipynb ├── 02-programs.ipynb ├── 03-loops-control-flow.ipynb ├── 04-basic-plotting.ipynb ├── 05-classes-oop.ipynb ├── 06-numpy-plotting.ipynb ├── 07-sympy.ipynb ├── 08-statistics.ipynb ├── 09-exceptions-testing.ipynb ├── 10-generators.ipynb ├── 11-more-classes.ipynb ├── CONTRIBUTORS.md ├── Exercises.ipynb ├── ExercisesSolutions.ipynb ├── FirstYearComputing_Master.tex ├── FirstYearComputing_Master_xelatex.tex ├── LICENSE ├── Makefile ├── README.md ├── _runipy └── Makefile ├── article-mod.tplx ├── breakpoints.py ├── chapter-base.tplx ├── chapter-ipython.tplx ├── conf.py ├── full-title.tpl ├── images ├── spyder-1.png ├── spyder-py3-reduced.png └── spyder-py3.png ├── index.ipynb ├── index.rst ├── lab1_basic.py ├── lab1_function.py ├── lab1_import.py ├── lab1_use_function.py ├── latex ├── BasicLatex.pdf ├── BasicLatex.tex ├── BasicLatexBibtex.tex ├── BasicLatexBibtex_pass1.pdf ├── BasicLatexBibtex_pass2.pdf ├── BasicLatexBibtex_pass3.pdf └── nummeth.bib ├── latex_chapter.tex ├── nbconvert_book.sty ├── pdf └── FirstYearComputing_Master.pdf ├── quadratic.py ├── requirements.txt ├── run_notebooks.py ├── southampton_precip.txt └── website-index.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | 0*tex 2 | 1*tex 3 | Exercises*tex 4 | *aux 5 | *out 6 | *toc 7 | *log 8 | *pdf 9 | 0*files 10 | Exercises*files 11 | .ipynb_checkpoints 12 | !latex/*pdf 13 | !pdf/*pdf 14 | __pycache__ 15 | _runipy 16 | _build 17 | A_numpy.txt 18 | simple_plot.png 19 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the OS, Python version and other tools you might need 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3" 12 | 13 | # Build documentation in the "docs/" directory with Sphinx 14 | sphinx: 15 | configuration: conf.py 16 | 17 | # Optionally build your docs in additional formats such as PDF and ePub 18 | # formats: 19 | # - pdf 20 | # - epub 21 | 22 | # Optional but recommended, declare the Python requirements required 23 | # to build your documentation 24 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 25 | python: 26 | install: 27 | - requirements: requirements.txt 28 | -------------------------------------------------------------------------------- /00-first-steps.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# First steps" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Programming is about getting the computer to do the calculation for you. This is needed when the calculation is long and has many repetitive steps. It does *not* mean that you can get the computer to understand things for you: usually you need to understand the steps before telling the computer what to do!" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Using a computer, particularly for mathematical or scientific purposes, involves a lot more than programming. There is also\n", 22 | "\n", 23 | "* *Algorithmic thinking*: understanding how to convert the solution to a problem into a sequence of steps that can be followed without further explanation.\n", 24 | "* *Efficient implementation* and *complexity*: there are many ways to solve a given problem, which will give equivalent answers in principle. In reality, some solutions will solve some problems to a reasonable accuracy in reasonable time, and it can be important to be able to check which solutions work in which cases.\n", 25 | "* *Effective implementation*: solving a problem on a computer *once* is great. Being able to re-use your solution on many problems is much better. Being able to give your code to anybody else, and it working for them, or saying *why* it won't work, without further input from you, is best.\n", 26 | "* *Reproducible science*: in principle, any scientific result should be able to be checked by somebody else. With complex scientific code, presenting and communicating its contents so that others can reproduce results is important and not always easy." 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "First, we will get the computer to do *something*, and later worry about doing it efficiently and effectively. Your time is more valuable than the computer's (literally: compare the [hourly cost of computer time through eg Amazon](https://aws.amazon.com/ec2/pricing/), typically *much* less than $5 per hour, against the minimum wage). We want the computer doing the work, and only when that wastes your time should you worry about the speed of the calculation." 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "# How to use these notes" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## The material" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "The four essential sections are on the basics, programs, loops and flow control, and basic plotting. You should work through the notes by typing in the commands as they appear, ensuring that you understand what's going on, and seeing where you make mistakes. At the end of each section, try the exercises that you think you can tackle. Also look back at previous exercises and see if you can solve them more straightforwardly with your additional knowledge.\n", 55 | "\n", 56 | "The section on classes should be read before reading the other sections: the details of creating your own classes won't be needed for later sections, but some understanding is important. The section on scientific Python is then the most important and should be explored in detail. At this point you should be able to tackle most of the exercises.\n", 57 | "\n", 58 | "The sections on symbolic Python and statistics should then be covered to get an overview of how Python can be used in these areas. The section on LaTeX is not directly related to programming but is essential for writing mathematical documents. Further sections are useful as your codes get more complex, but initially are less important." 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "## How to work when coding" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "When working on code it is often very useful to work in pairs, or groups. Talk about what you're doing, and why you're doing it. When something goes wrong, check with other people, or [explain to them what you're trying to do (rubber duck debugging)](https://en.wikipedia.org/wiki/Rubber_duck_debugging). When working on exercises, [use pair programming techniques](http://www.wikihow.com/Pair-Program). If there's more than one way of doing something, try them all and see which you think is best, and discuss why.\n", 73 | "\n", 74 | "There is no \"one right way\" to code, but well documented, easy to understand, clearly written code that someone else can follow as well is always a good start." 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "# Python" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "To introduce programming we will use the Python programming language. It's a good general purpose language with lots of tools and libraries available, and it's free. It's a solid choice for learning programming, and for testing new code. " 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "## Using Python on University machines" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "A number of Python tools are available on a standard university desktop machine. We will mostly be using Python through spyder, which allows us to write, run, test and debug python code in one place. To launch spyder, either type `spyder` in the search bar, or go to `Start`, then `All Programs`, then `Programming Languages`, then `Anaconda`, then choose `spyder`." 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "## Using Python on your own machine" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "As Python is free you can install and run it on any machine (or tablet, or phone) you like. In fact, many will have Python already installed, for the use of other software. However, for programming, it is best to have an installation that all works together, which you can easily experiment with, and which won't break other programs if you change something. For these reasons, we recommend you install the [anaconda distribution](http://docs.continuum.io/anaconda/)." 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "### Anaconda" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": {}, 129 | "source": [ 130 | "If you have enough bandwidth and time (you will be downloading about 1G of software) then you can use the [Anaconda graphical installer](https://www.continuum.io/downloads). There are two versions of Python: a Python `2.X` and a Python `3.X`. There are small differences between the two. Everything we show here will work on either version. We will be using the `3.X` version.\n", 131 | "\n", 132 | "The Anaconda package installs both the essential Python package and a large amount of useful Python software. It will put a launcher icon on your desktop. Clicking on the launcher will bring up a window listing a number of applications: we will be using `spyder` as seen below." 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "### miniconda" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "If you do not want to download all the Python packages, but only the essential ones, there is a smaller version of Anaconda, called miniconda. First, [download the miniconda package](http://conda.pydata.org/miniconda.html) for your computer. Again, we will be using the `3.X` version." 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "The miniconda package installs the basic Python and little else. There are a number of useful packages that we will use. You can install those using the `conda` app (either via the launcher, or via the command line). But before doing that, it is best to create an environment to install them in, which you can modify without causing problems." 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "### Environments" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "Packages may rely on other packages, and may rely on *specific versions* of other packages in order to work. This can lead to \"dependency hell\", when you need (for different purposes) package `A` and package `B` which rely on conflicting versions of package `C`.\n", 168 | "\n", 169 | "The answer to this is *environments*, which allow you to organize your different packages to minimize conflicts. Environments are like folders, and you have one for each project you are working on. That way, you ensure that updating or installing packages for one project does not cause problems for a different project.\n", 170 | "\n", 171 | "To get the most out of environments, we need to use the command line, or terminal.\n", 172 | "\n", 173 | "#### Terminals\n", 174 | "\n", 175 | "A *terminal*, or a [*command prompt window*](http://windows.microsoft.com/en-gb/windows-vista/open-a-command-prompt-window), is a window where commands can be typed in to directly run commands or affect files. On Windows you select the `Command Prompt` from the Accessories menu. On Mac or Linux system you open a terminal or an XTerm. Inside the terminal you can change directories using the `cd` command, and run commands associated with Anaconda or miniconda using the `conda` command.\n", 176 | "\n", 177 | "#### Creating the environment\n", 178 | "\n", 179 | "We will create a single environment called `labs`. If you are running on a Mac or on Linux, open a terminal. If on Windows, use a command prompt. Then type\n", 180 | "\n", 181 | "```bash\n", 182 | "conda create -n labs python=3\n", 183 | "```\n", 184 | "\n", 185 | "This creates the new environment, and installs the basic `python` package in the `python 3.X` flavour. It does not activate the environment. In order to work within this environment, if using Windows type\n", 186 | "\n", 187 | "```bash\n", 188 | "activate labs\n", 189 | "```\n", 190 | "\n", 191 | "If using Mac or Linux type\n", 192 | "\n", 193 | "```bash\n", 194 | "source activate labs\n", 195 | "```\n", 196 | "\n", 197 | "Then any command launched from the terminal or command prompt will use the packages in this environment." 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "### Packages" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | "After creating the environment, and activating it, the key packages that need installing (if using miniconda; they are all installed with the full Anaconda) are:\n", 212 | "\n", 213 | "* `ipython`\n", 214 | "* `numpy`\n", 215 | "* `matplotlib`\n", 216 | "* `scipy`\n", 217 | "* `spyder`\n", 218 | "* `spyder-app`\n", 219 | "* `sympy`\n", 220 | "\n", 221 | "Other packages that will be useful are\n", 222 | "\n", 223 | "* `jupyter`\n", 224 | "* `nose`\n", 225 | "* `numba`\n", 226 | "* `pandas`\n", 227 | "\n", 228 | "The command to install new packages is `conda install`. So, to install the packages above type (or copy and paste) first\n", 229 | "\n", 230 | "```bash\n", 231 | "activate labs\n", 232 | "```\n", 233 | "\n", 234 | "if on Windows, or \n", 235 | "\n", 236 | "```bash\n", 237 | "source activate labs\n", 238 | "```\n", 239 | "\n", 240 | "if on Mac or Linux, and then type\n", 241 | "\n", 242 | "```bash\n", 243 | "conda install ipython numpy matplotlib scipy spyder spyder-app sympy \\\n", 244 | " jupyter nose numba pandas\n", 245 | "```\n", 246 | "\n", 247 | "**Note**: the '`\\`' backslash character should continue an overly long line: if you are typing and not copying and pasting this should be unnecessary.\n", 248 | "\n", 249 | "This will download and install a lot of additional packages that are needed; just agree and continue." 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "# Spyder" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | "There are many ways of writing and running Python code. If you open a terminal (on Mac or Linux; on Windows, this would be a Command Prompt) you can type `python` or `ipython` to launch a very bare bones *console*. This allows you to enter code which it will then run.\n", 264 | "\n", 265 | "More helpful alternatives are *Integrated Development Environments* (IDEs) or the *notebook*. The [Jupyter notebook](https://jupyter.org/) (previously called the [IPython notebook](http://ipython.org/notebook.html)) is browser based and very powerful for exploratory computing. To run, type `jupyter notebook` in the terminal prompt.\n", 266 | "\n", 267 | "However, when just getting started, or when writing large codes, IDEs are a better alternative. A simple IDE is `spyder` which we will use here. To launch, either select `spyder` from the appropriate menu, or type `spyder` at the terminal prompt.\n", 268 | "\n", 269 | "You should then see a screen something like the figure (without the annotations).\n", 270 | "\n", 271 | "![The spyder editor, with the key areas outlined and coloured.](images/spyder-py3-reduced.png)" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "The four essential parts of the screen are outlined.\n", 279 | "\n", 280 | "1. The console (bottom right, marked in blue). You can work *interactively* here. Code run, either interactively or from the editor, will output any results here. Error messages will be reported here. There are two types of console: a Python console, and an IPython console. Both will run Python code, but the IPython console is easier to use.\n", 281 | "2. The editor (left, marked in red). You can write code to be saved to file or run here. This will suggest problems with syntax and has features to help debug and give additional information.\n", 282 | "3. The inspector (top right, marked in green). Can display detailed help on specific objects (or functions, or...) - the *Object inspector*, or can display detailed information on the variables that are currently defined - the *Variable inspector*. Extremely useful when debugging.\n", 283 | "4. The working directory (marked in yellow). When running a code this is the first place that `spyder` looks. You should ensure that the working directory is set to the location where the file is.\n", 284 | "\n", 285 | "For further information on using and setting up `spyder`, see [this tutorial](http://www.southampton.ac.uk/~fangohr/blog/spyder-the-python-ide.html)." 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "## Tab completion" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "A crucial feature of IPython and spyder that saves time and reduces errors is *tab completion*. When typing anything, try pressing the tab key. This will either automatically complete the name of the variable (or function, or class), or will present a list of options. This is one way of finding out what functions are available - press tab and it will list them all! By typing the first few characters and then pressing tab, you can rapidly narrow down the options." 300 | ] 301 | }, 302 | { 303 | "cell_type": "markdown", 304 | "metadata": {}, 305 | "source": [ 306 | "## Help" 307 | ] 308 | }, 309 | { 310 | "cell_type": "markdown", 311 | "metadata": {}, 312 | "source": [ 313 | "There are many ways of getting help. The most useful are:\n", 314 | "\n", 315 | "* Type `help()`. Works in the console.\n", 316 | "* Type `?` or `??`. Works in the console.\n", 317 | "* Type the name in the Object Inspector. Works in spyder only.\n", 318 | "* Google it. Pay particular attention to the online documentation and sites such as stackoverflow." 319 | ] 320 | }, 321 | { 322 | "cell_type": "markdown", 323 | "metadata": {}, 324 | "source": [ 325 | "# Reading list\n", 326 | "\n", 327 | "There's a lot of material related to Python online and in the library. None are essential, but lots may be useful. The particular books recommended as a first look are\n", 328 | "\n", 329 | "* Langtangen, *A Primer on Scientific Programming with Python*. Detailed, aimed more towards mathematicians than many others.\n", 330 | "* Newman, *Computational Physics*. Really aimed at teaching numerical algorithms rather than programming, but there's lots of useful examples at a good level.\n", 331 | "* Scopatz & Huff, *Effective Computation in Physics*. Covers a lot more material than just Python, not exactly aimed at mathematics, but essential background for computational research in the sciences.\n", 332 | "* Saha, *Doing Math with Python*. Covers more symbolic mathematics and assumes more Python background, but has lots of excellent exercises at the right level." 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": {}, 338 | "source": [ 339 | "# Versions" 340 | ] 341 | }, 342 | { 343 | "cell_type": "markdown", 344 | "metadata": {}, 345 | "source": [ 346 | "These notes have been constructed using the following versions of Python and related packages:" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 1, 352 | "metadata": { 353 | "collapsed": false 354 | }, 355 | "outputs": [ 356 | { 357 | "name": "stdout", 358 | "output_type": "stream", 359 | "text": [ 360 | "CPython 3.4.4\n", 361 | "IPython 4.1.1\n", 362 | "\n", 363 | "numpy 1.10.4\n", 364 | "scipy 0.17.0\n", 365 | "matplotlib 1.5.1\n", 366 | "sympy 0.7.6.1\n", 367 | "\n", 368 | "compiler : GCC 4.2.1 (Apple Inc. build 5577)\n", 369 | "system : Darwin\n", 370 | "release : 14.5.0\n", 371 | "machine : x86_64\n", 372 | "processor : i386\n", 373 | "CPU cores : 4\n", 374 | "interpreter: 64bit\n", 375 | "Git hash : c8886df0783a20e915cec64c793a4f8962b1c889\n" 376 | ] 377 | } 378 | ], 379 | "source": [ 380 | "%load_ext watermark\n", 381 | "%watermark -v -m -g -p numpy,scipy,matplotlib,sympy" 382 | ] 383 | } 384 | ], 385 | "metadata": { 386 | "kernelspec": { 387 | "display_name": "Python 3", 388 | "language": "python", 389 | "name": "python3" 390 | }, 391 | "language_info": { 392 | "codemirror_mode": { 393 | "name": "ipython", 394 | "version": 3 395 | }, 396 | "file_extension": ".py", 397 | "mimetype": "text/x-python", 398 | "name": "python", 399 | "nbconvert_exporter": "python", 400 | "pygments_lexer": "ipython3", 401 | "version": "3.4.4" 402 | }, 403 | "nbconvert": { 404 | "title": "First Steps" 405 | } 406 | }, 407 | "nbformat": 4, 408 | "nbformat_minor": 0 409 | } 410 | -------------------------------------------------------------------------------- /05-classes-oop.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Classes and Object Oriented Programming" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "We have looked at functions which take input and return output (or do things to the input). However, sometimes it is useful to think about *objects* first rather than the actions applied to them." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Think about a polynomial, such as the cubic\n", 22 | "\n", 23 | "$$ p(x) = 12 - 14 x + 2 x^3. $$\n", 24 | "\n", 25 | "This is one of the standard forms that we would expect to see for a polynomial. We could imagine representing this in Python using a container containing the coefficients, such as:" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": { 32 | "collapsed": true 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "p_normal = (12, -14, 0, 2)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "The order of the polynomial is given by the number of coefficients (minus one), which is given by `len(p_normal)-1`." 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "However, there are many other ways it could be written, which are useful in different contexts. For example, we are often interested in the roots of the polynomial, so would want to express it in the form\n", 51 | "\n", 52 | "$$ p(x) = 2 (x - 1)(x - 2)(x + 3). $$\n", 53 | "\n", 54 | "This allows us to read off the roots directly. We could imagine representing this in Python using a container containing the roots, such as:" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "p_roots = (1, 2, -3)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "combined with a single variable containing the leading term," 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 3, 78 | "metadata": { 79 | "collapsed": true 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "p_leading_term = 2" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "We see that the order of the polynomial is given by the number of roots (and hence by `len(p_roots)`). This form represents the same polynomial but requires two pieces of information (the roots and the leading coefficient)." 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "The different forms are useful for different things. For example, if we want to add two polynomials the standard form makes it straightforward, but the factored form does not. Conversely, multiplying polynomials in the factored form is easy, whilst in the standard form it is not." 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "But the key point is that the object - the polynomial - is the same: the representation may appear different, but it's the object itself that we really care about. So we want to represent the object in code, and work with that object." 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "## Classes" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "Python, and other languages that include *object oriented* concepts (which is most modern languages) allow you to define and manipulate your own objects. Here we will define a *polynomial* object step by step." 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 4, 124 | "metadata": { 125 | "collapsed": true 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "class Polynomial(object):\n", 130 | " explanation = \"I am a polynomial\"\n", 131 | " \n", 132 | " def explain(self):\n", 133 | " print(self.explanation)" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "We have defined a *class*, which is a single object that will represent a polynomial. We use the keyword `class` in the same way that we use the keyword `def` when defining a function. The definition line ends with a colon, and all the code defining the object is indented by four spaces.\n", 141 | "\n", 142 | "The name of the object - the general class, or type, of the thing that we're defining - is `Polynomial`. The convention is that class names start with capital letters, but this convention is frequently ignored.\n", 143 | "\n", 144 | "The type of object that we are building on appears in brackets after the name of the object. The most basic thing, which is used most often, is the `object` type as here." 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "Class variables are defined in the usual way, but are only visible inside the class. Variables that are set outside of functions, such as `explanation` above, will be common to all class variables.\n", 152 | "\n", 153 | "Functions are defined inside classes in the usual way (using the `def` keyword, indented by four additional spaces). They work in a special way: they are not called directly, but only when you have a member of the class. This is what the `self` keyword does: it takes the specific *instance* of the class and uses its data. Class functions are often called *methods*.\n", 154 | "\n", 155 | "Let's see how this works on a specific example:" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 5, 161 | "metadata": { 162 | "collapsed": false 163 | }, 164 | "outputs": [ 165 | { 166 | "name": "stdout", 167 | "output_type": "stream", 168 | "text": [ 169 | "I am a polynomial\n", 170 | "I am a polynomial\n", 171 | "I change the string\n" 172 | ] 173 | } 174 | ], 175 | "source": [ 176 | "p = Polynomial()\n", 177 | "print(p.explanation)\n", 178 | "p.explain()\n", 179 | "p.explanation = \"I change the string\"\n", 180 | "p.explain()" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "The first line, `p = Polynomial()`, creates an *instance* of the class. That is, it creates a specific `Polynomial`. It is assigned to the variable named `p`. We can access class variables using the \"dot\" notation, so the string can be printed via `p.explanation`. The method that prints the class variable also uses the \"dot\" notation, hence `p.explain()`. The `self` variable in the definition of the function is the instance itself, `p`. This is passed through automatically thanks to the dot notation.\n", 188 | "\n", 189 | "Note that we can change class variables in specific instances in the usual way (`p.explanation = ...` above). This only changes the variable for that instance. To check that, let us define two polynomials:" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": 6, 195 | "metadata": { 196 | "collapsed": false 197 | }, 198 | "outputs": [ 199 | { 200 | "name": "stdout", 201 | "output_type": "stream", 202 | "text": [ 203 | "Changed the string a third time\n", 204 | "I am a polynomial\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "p = Polynomial()\n", 210 | "p.explanation = \"Changed the string again\"\n", 211 | "q = Polynomial()\n", 212 | "p.explanation = \"Changed the string a third time\"\n", 213 | "p.explain()\n", 214 | "q.explain()" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "We can of course make the methods take additional variables. We modify the class (note that we have to completely re-define it each time):" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 7, 227 | "metadata": { 228 | "collapsed": true 229 | }, 230 | "outputs": [], 231 | "source": [ 232 | "class Polynomial(object):\n", 233 | " explanation = \"I am a polynomial\"\n", 234 | " \n", 235 | " def explain_to(self, caller):\n", 236 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))" 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "We then use this, remembering that the `self` variable is passed through automatically:" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 8, 249 | "metadata": { 250 | "collapsed": false 251 | }, 252 | "outputs": [ 253 | { 254 | "name": "stdout", 255 | "output_type": "stream", 256 | "text": [ 257 | "Hello, Alice. I am a polynomial.\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "r = Polynomial()\n", 263 | "r.explain_to(\"Alice\")" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "At the moment the class is not doing anything interesting. To do something interesting we need to store (and manipulate) relevant variables. The first thing to do is to add those variables when the instance is actually created. We do this by adding a special function (method) which changes how the variables of type `Polynomial` are created:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 9, 276 | "metadata": { 277 | "collapsed": true 278 | }, 279 | "outputs": [], 280 | "source": [ 281 | "class Polynomial(object):\n", 282 | " \"\"\"Representing a polynomial.\"\"\"\n", 283 | " explanation = \"I am a polynomial\"\n", 284 | " \n", 285 | " def __init__(self, roots, leading_term):\n", 286 | " self.roots = roots\n", 287 | " self.leading_term = leading_term\n", 288 | " self.order = len(roots)\n", 289 | " \n", 290 | " def explain_to(self, caller):\n", 291 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 292 | " print(\"My roots are {}.\".format(self.roots))" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "This `__init__` function is called when a variable is created. There are a number of special class functions, each of which has two underscores before and after the name. This is another Python *convention* that is effectively a rule: functions surrounded by two underscores have special effects, and will be called by other Python functions internally. So now we can create a variable that represents a specific polynomial by storing its roots and the leading term:" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 10, 305 | "metadata": { 306 | "collapsed": false 307 | }, 308 | "outputs": [ 309 | { 310 | "name": "stdout", 311 | "output_type": "stream", 312 | "text": [ 313 | "Hello, Alice. I am a polynomial.\n", 314 | "My roots are (1, 2, -3).\n", 315 | "Hello, Bob. I am a polynomial.\n", 316 | "My roots are (1, 1, 0, -2).\n" 317 | ] 318 | } 319 | ], 320 | "source": [ 321 | "p = Polynomial(p_roots, p_leading_term)\n", 322 | "p.explain_to(\"Alice\")\n", 323 | "q = Polynomial((1,1,0,-2), -1)\n", 324 | "q.explain_to(\"Bob\")" 325 | ] 326 | }, 327 | { 328 | "cell_type": "markdown", 329 | "metadata": {}, 330 | "source": [ 331 | "It is always useful to have a function that shows what the class represents, and in particular what this particular instance looks like. We can define another method that explicitly `display`s the `Polynomial`:" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 11, 337 | "metadata": { 338 | "collapsed": true 339 | }, 340 | "outputs": [], 341 | "source": [ 342 | "class Polynomial(object):\n", 343 | " \"\"\"Representing a polynomial.\"\"\"\n", 344 | " explanation = \"I am a polynomial\"\n", 345 | " \n", 346 | " def __init__(self, roots, leading_term):\n", 347 | " self.roots = roots\n", 348 | " self.leading_term = leading_term\n", 349 | " self.order = len(roots)\n", 350 | " \n", 351 | " def display(self):\n", 352 | " string = str(self.leading_term)\n", 353 | " for root in self.roots:\n", 354 | " if root == 0:\n", 355 | " string = string + \"x\"\n", 356 | " elif root > 0:\n", 357 | " string = string + \"(x - {})\".format(root)\n", 358 | " else:\n", 359 | " string = string + \"(x + {})\".format(-root)\n", 360 | " return string\n", 361 | " \n", 362 | " def explain_to(self, caller):\n", 363 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 364 | " print(\"My roots are {}.\".format(self.roots))" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": 13, 370 | "metadata": { 371 | "collapsed": false 372 | }, 373 | "outputs": [ 374 | { 375 | "name": "stdout", 376 | "output_type": "stream", 377 | "text": [ 378 | "2(x - 1)(x - 2)(x + 3)\n", 379 | "-1(x - 1)(x - 1)x(x + 2)\n" 380 | ] 381 | } 382 | ], 383 | "source": [ 384 | "p = Polynomial(p_roots, p_leading_term)\n", 385 | "print(p.display())\n", 386 | "q = Polynomial((1,1,0,-2), -1)\n", 387 | "print(q.display())" 388 | ] 389 | }, 390 | { 391 | "cell_type": "markdown", 392 | "metadata": {}, 393 | "source": [ 394 | "Where classes really come into their own is when we manipulate them as objects in their own right. For example, we can multiply together two polynomials to get another polynomial. We can create a method to do that:" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 14, 400 | "metadata": { 401 | "collapsed": true 402 | }, 403 | "outputs": [], 404 | "source": [ 405 | "class Polynomial(object):\n", 406 | " \"\"\"Representing a polynomial.\"\"\"\n", 407 | " explanation = \"I am a polynomial\"\n", 408 | " \n", 409 | " def __init__(self, roots, leading_term):\n", 410 | " self.roots = roots\n", 411 | " self.leading_term = leading_term\n", 412 | " self.order = len(roots)\n", 413 | " \n", 414 | " def display(self):\n", 415 | " string = str(self.leading_term)\n", 416 | " for root in self.roots:\n", 417 | " if root == 0:\n", 418 | " string = string + \"x\"\n", 419 | " elif root > 0:\n", 420 | " string = string + \"(x - {})\".format(root)\n", 421 | " else:\n", 422 | " string = string + \"(x + {})\".format(-root)\n", 423 | " return string\n", 424 | " \n", 425 | " def multiply(self, other):\n", 426 | " roots = self.roots + other.roots\n", 427 | " leading_term = self.leading_term * other.leading_term\n", 428 | " return Polynomial(roots, leading_term)\n", 429 | " \n", 430 | " def explain_to(self, caller):\n", 431 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 432 | " print(\"My roots are {}.\".format(self.roots))" 433 | ] 434 | }, 435 | { 436 | "cell_type": "code", 437 | "execution_count": 15, 438 | "metadata": { 439 | "collapsed": false 440 | }, 441 | "outputs": [ 442 | { 443 | "name": "stdout", 444 | "output_type": "stream", 445 | "text": [ 446 | "-2(x - 1)(x - 2)(x + 3)(x - 1)(x - 1)x(x + 2)\n" 447 | ] 448 | } 449 | ], 450 | "source": [ 451 | "p = Polynomial(p_roots, p_leading_term)\n", 452 | "q = Polynomial((1,1,0,-2), -1)\n", 453 | "r = p.multiply(q)\n", 454 | "print(r.display())" 455 | ] 456 | }, 457 | { 458 | "cell_type": "markdown", 459 | "metadata": {}, 460 | "source": [ 461 | "We now have a simple class that can represent polynomials and multiply them together, whilst printing out a simple string form representing itself. This can obviously be extended to be much more useful." 462 | ] 463 | }, 464 | { 465 | "cell_type": "markdown", 466 | "metadata": {}, 467 | "source": [ 468 | "# Exercise: Equivalence classes" 469 | ] 470 | }, 471 | { 472 | "cell_type": "markdown", 473 | "metadata": {}, 474 | "source": [ 475 | "An *equivalence class* is a relation that groups objects in a set into related subsets. For example, if we think of the integers modulo $7$, then $1$ is in the same equivalence class as $8$ (and $15$, and $22$, and so on), and $3$ is in the same equivalence class as $10$. We use the tilde $3 \\sim 10$ to denote two objects within the same equivalence class.\n", 476 | "\n", 477 | "Here, we are going to define the positive integers programmatically from equivalent sequences." 478 | ] 479 | }, 480 | { 481 | "cell_type": "markdown", 482 | "metadata": {}, 483 | "source": [ 484 | "## Exercise 1\n", 485 | "\n", 486 | "Define a Python class `Eqint`. This should be\n", 487 | "\n", 488 | "1. Initialized by a sequence;\n", 489 | "2. Store the sequence;\n", 490 | "3. Have a `display` method that returns a string showing the integer length of the sequence;\n", 491 | "4. Have an `equals` method that checks if two `Eqint`s are equal, which is `True` if, and only if, their sequences have the same length." 492 | ] 493 | }, 494 | { 495 | "cell_type": "markdown", 496 | "metadata": {}, 497 | "source": [ 498 | "## Exercise 2\n", 499 | "\n", 500 | "Define a `zero` object from the empty list, and three `one` objects, from a single object list, tuple, and string. For example\n", 501 | "\n", 502 | "```python\n", 503 | "one_list = Eqint([1])\n", 504 | "one_tuple = Eqint((1,))\n", 505 | "one_string = Eqint('1')\n", 506 | "```\n", 507 | "\n", 508 | "Check that none of the `one` objects equal the zero object, but all equal the other `one` objects. Display each object to check that the representation gives the integer length." 509 | ] 510 | }, 511 | { 512 | "cell_type": "markdown", 513 | "metadata": {}, 514 | "source": [ 515 | "## Exercise 3\n", 516 | "\n", 517 | "Redefine the class by including an `add` method that combines the two sequences. That is, if `a` and `b` are `Eqint`s then `a.add(b)` should return an `Eqint` defined from combining `a` and `b`s sequences.\n", 518 | "\n", 519 | "##### Note\n", 520 | "\n", 521 | "Adding two different *types* of sequences (eg, a list to a tuple) does not work, so it is better to either iterate over the sequences, or to convert to a uniform type before adding." 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "## Exercise 4\n", 529 | "\n", 530 | "Check your addition function by adding together all your previous `Eqint` objects (which will need re-defining, as the class has been redefined). Display the resulting object to check you get `3`, and also print its internal sequence." 531 | ] 532 | }, 533 | { 534 | "cell_type": "markdown", 535 | "metadata": {}, 536 | "source": [ 537 | "## Exercise 5\n", 538 | "\n", 539 | "We will sketch a construction of the positive integers from *nothing*.\n", 540 | "\n", 541 | "1. Define an empty list `positive_integers`.\n", 542 | "2. Define an `Eqint` called `zero` from the empty list. Append it to `positive_integers`.\n", 543 | "3. Define an `Eqint` called `next_integer` from the `Eqint` defined by *a copy of* `positive_integers` (ie, use `Eqint(list(positive_integers))`. Append it to `positive_integers`.\n", 544 | "4. Repeat step 3 as often as needed.\n", 545 | "\n", 546 | "Use this procedure to define the `Eqint` equivalent to $10$. Print it, and its internal sequence, to check." 547 | ] 548 | } 549 | ], 550 | "metadata": { 551 | "anaconda-cloud": {}, 552 | "kernelspec": { 553 | "display_name": "Python [default]", 554 | "language": "python", 555 | "name": "python3" 556 | }, 557 | "language_info": { 558 | "codemirror_mode": { 559 | "name": "ipython", 560 | "version": 3 561 | }, 562 | "file_extension": ".py", 563 | "mimetype": "text/x-python", 564 | "name": "python", 565 | "nbconvert_exporter": "python", 566 | "pygments_lexer": "ipython3", 567 | "version": "3.5.2" 568 | }, 569 | "nbconvert": { 570 | "title": "Classes and objects" 571 | } 572 | }, 573 | "nbformat": 4, 574 | "nbformat_minor": 0 575 | } 576 | -------------------------------------------------------------------------------- /10-generators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Iterators and Generators" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "In the section on loops we introduced the `range` function, and said that you should think about it as creating a list of numbers. In Python `2.X` this is exactly what it does. In Python `3.X` this is *not* what it does. Instead it creates the numbers one at a time. The difference in speed and memory usage is enormous for very large lists - examples are given [here](http://justindailey.blogspot.se/2011/09/python-range-vs-xrange.html) and [here](https://asmeurer.github.io/python3-presentation/slides.html#42).\n", 15 | "\n", 16 | "We can recreate one of the examples from [Meuer's slides](https://asmeurer.github.io/python3-presentation/slides.html#44) in detail:" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": { 23 | "collapsed": true 24 | }, 25 | "outputs": [], 26 | "source": [ 27 | "def naivesum_list(N):\n", 28 | " \"\"\"\n", 29 | " Naively sum the first N integers\n", 30 | " \"\"\"\n", 31 | " A = 0\n", 32 | " for i in list(range(N + 1)):\n", 33 | " A += i\n", 34 | " return A" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "We will now see how much memory this uses:" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": { 48 | "collapsed": false 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "%load_ext memory_profiler" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": { 59 | "collapsed": false 60 | }, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "peak memory: 32.38 MiB, increment: 0.50 MiB\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "%memit naivesum_list(10**4)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 4, 77 | "metadata": { 78 | "collapsed": false 79 | }, 80 | "outputs": [ 81 | { 82 | "name": "stdout", 83 | "output_type": "stream", 84 | "text": [ 85 | "peak memory: 35.95 MiB, increment: 3.57 MiB\n" 86 | ] 87 | } 88 | ], 89 | "source": [ 90 | "%memit naivesum_list(10**5)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 5, 96 | "metadata": { 97 | "collapsed": false 98 | }, 99 | "outputs": [ 100 | { 101 | "name": "stdout", 102 | "output_type": "stream", 103 | "text": [ 104 | "peak memory: 70.75 MiB, increment: 34.79 MiB\n" 105 | ] 106 | } 107 | ], 108 | "source": [ 109 | "%memit naivesum_list(10**6)" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 6, 115 | "metadata": { 116 | "collapsed": false 117 | }, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "peak memory: 426.25 MiB, increment: 382.75 MiB\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "%memit naivesum_list(10**7)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 7, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "name": "stdout", 140 | "output_type": "stream", 141 | "text": [ 142 | "peak memory: 3856.96 MiB, increment: 3744.59 MiB\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "%memit naivesum_list(10**8)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "We see that the memory usage is growing very rapidly - as the list gets large it's growing as $N$.\n", 155 | "\n", 156 | "Instead we can use the `range` function that yields one integer at a time:" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 8, 162 | "metadata": { 163 | "collapsed": false 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "def naivesum(N):\n", 168 | " \"\"\"\n", 169 | " Naively sum the first N integers\n", 170 | " \"\"\"\n", 171 | " A = 0\n", 172 | " for i in range(N + 1):\n", 173 | " A += i\n", 174 | " return A" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 9, 180 | "metadata": { 181 | "collapsed": false 182 | }, 183 | "outputs": [ 184 | { 185 | "name": "stdout", 186 | "output_type": "stream", 187 | "text": [ 188 | "peak memory: 34.35 MiB, increment: 0.13 MiB\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "%memit naivesum(10**4)" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 10, 199 | "metadata": { 200 | "collapsed": false 201 | }, 202 | "outputs": [ 203 | { 204 | "name": "stdout", 205 | "output_type": "stream", 206 | "text": [ 207 | "peak memory: 34.38 MiB, increment: 0.01 MiB\n" 208 | ] 209 | } 210 | ], 211 | "source": [ 212 | "%memit naivesum(10**5)" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 11, 218 | "metadata": { 219 | "collapsed": false 220 | }, 221 | "outputs": [ 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "peak memory: 34.40 MiB, increment: 0.01 MiB\n" 227 | ] 228 | } 229 | ], 230 | "source": [ 231 | "%memit naivesum(10**6)" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 12, 237 | "metadata": { 238 | "collapsed": false 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "peak memory: 34.41 MiB, increment: 0.00 MiB\n" 246 | ] 247 | } 248 | ], 249 | "source": [ 250 | "%memit naivesum(10**7)" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 13, 256 | "metadata": { 257 | "collapsed": false 258 | }, 259 | "outputs": [ 260 | { 261 | "name": "stdout", 262 | "output_type": "stream", 263 | "text": [ 264 | "peak memory: 34.41 MiB, increment: 0.00 MiB\n" 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "%memit naivesum(10**8)" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "We see that the *memory* usage is unchanged with $N$, making it practical to run much larger calculations. " 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "## Iterators" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "The `range` function is returning an [*iterator*](https://docs.python.org/3/glossary.html#term-iterator) here. This is an object - a general thing - that represents a stream, or a sequence, of data. The iterator knows how to create the first element of the stream, and it knows how to get the next element. It does not, in general, need to know all of the elements at once.\n", 291 | "\n", 292 | "As we've seen above this can save a lot of memory. It can also save time: the code does not need to construct all of the members of the sequence before starting, and it's quite possible you don't need all of them (think about the \"Shortest published mathematical paper\" exercise).\n", 293 | "\n", 294 | "An iterator such as `range` is very useful, and there's a lot more useful ways to work with iterators in the `itertools` module. These functions that return iterators, such as `range`, are called [*generators*](https://docs.python.org/3/glossary.html#term-generator), and it's useful to be able to make your own." 295 | ] 296 | }, 297 | { 298 | "cell_type": "markdown", 299 | "metadata": {}, 300 | "source": [ 301 | "## Making your own generators" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "Let's look at an example: finding all primes less than $N$ that can be written in the form $4 k - 1$, where $k$ is an integer.\n", 309 | "\n", 310 | "We're going to need to calculate all prime numbers less than or equal to $N$. We could write a function that returns all these numbers as a list. However, if $N$ gets large then this will be expensive, both in time and memory. As we only need one number at a time, we can use a generator." 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 14, 316 | "metadata": { 317 | "collapsed": true 318 | }, 319 | "outputs": [], 320 | "source": [ 321 | "def all_primes(N):\n", 322 | " \"\"\"\n", 323 | " Return all primes less than or equal to N.\n", 324 | " \n", 325 | " Parameters\n", 326 | " ----------\n", 327 | " \n", 328 | " N : int\n", 329 | " Maximum number\n", 330 | " \n", 331 | " Returns\n", 332 | " -------\n", 333 | " \n", 334 | " prime : generator\n", 335 | " Prime numbers\n", 336 | " \"\"\"\n", 337 | " \n", 338 | " primes = []\n", 339 | " for n in range(2, N+1):\n", 340 | " is_n_prime = True\n", 341 | " for p in primes:\n", 342 | " if n%p == 0:\n", 343 | " is_n_prime = False\n", 344 | " break\n", 345 | " if is_n_prime:\n", 346 | " primes.append(n)\n", 347 | " yield n" 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": {}, 353 | "source": [ 354 | "This code needs careful examination. First it defines the list of all prime numbers that it currently knows, `primes` (which is initially empty). Then it loops through all integers $n$ from $2$ to $N$ (ignoring $1$ as we know it's not prime).\n", 355 | "\n", 356 | "Inside this loop it initially assumes that $n$ is prime. It then checks if any of the known primes exactly divides $n$ (`n%p == 0` checks if $n \\bmod p = 0$). As soon as it finds such a prime divisor it knows that $n$ is not prime it resets the assumption with this new knowledge, then `break`s out of the loop. This statement stops the `for p in primes` loop early, as we don't need to look at later primes. \n", 357 | "\n", 358 | "If no known prime ever divides $n$ then at the end of the `for p in primes` loop we will still have `is_n_prime` being `True`. In this case we must have $n$ being prime, so we add it to the list of known primes and return it.\n", 359 | "\n", 360 | "It is precisely this point which makes the code above define a generator. We return the value of the prime number found \n", 361 | "\n", 362 | "1. using the `yield` keyword, not the `return` keyword, and\n", 363 | "2. we return the value as soon as it is known.\n", 364 | "\n", 365 | "It is the use of the `yield` keyword that makes this function a generator.\n", 366 | "\n", 367 | "This means that only the latest prime number is stored for return." 368 | ] 369 | }, 370 | { 371 | "cell_type": "markdown", 372 | "metadata": {}, 373 | "source": [ 374 | "To use the iterator within a loop, we code it in the same way as with the `range` function:" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 15, 380 | "metadata": { 381 | "collapsed": false 382 | }, 383 | "outputs": [ 384 | { 385 | "name": "stdout", 386 | "output_type": "stream", 387 | "text": [ 388 | "All prime numbers less than or equal to 20:\n", 389 | "2\n", 390 | "3\n", 391 | "5\n", 392 | "7\n", 393 | "11\n", 394 | "13\n", 395 | "17\n", 396 | "19\n" 397 | ] 398 | } 399 | ], 400 | "source": [ 401 | "print(\"All prime numbers less than or equal to 20:\")\n", 402 | "for p in all_primes(20):\n", 403 | " print(p)" 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": {}, 409 | "source": [ 410 | "To see what the generator is actually doing, we can step through it one call at a time using the built in `next` function:" 411 | ] 412 | }, 413 | { 414 | "cell_type": "code", 415 | "execution_count": 16, 416 | "metadata": { 417 | "collapsed": false 418 | }, 419 | "outputs": [], 420 | "source": [ 421 | "a = all_primes(10)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": 17, 427 | "metadata": { 428 | "collapsed": false 429 | }, 430 | "outputs": [ 431 | { 432 | "data": { 433 | "text/plain": [ 434 | "2" 435 | ] 436 | }, 437 | "execution_count": 17, 438 | "metadata": {}, 439 | "output_type": "execute_result" 440 | } 441 | ], 442 | "source": [ 443 | "next(a)" 444 | ] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "execution_count": 18, 449 | "metadata": { 450 | "collapsed": false 451 | }, 452 | "outputs": [ 453 | { 454 | "data": { 455 | "text/plain": [ 456 | "3" 457 | ] 458 | }, 459 | "execution_count": 18, 460 | "metadata": {}, 461 | "output_type": "execute_result" 462 | } 463 | ], 464 | "source": [ 465 | "next(a)" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": 19, 471 | "metadata": { 472 | "collapsed": false 473 | }, 474 | "outputs": [ 475 | { 476 | "data": { 477 | "text/plain": [ 478 | "5" 479 | ] 480 | }, 481 | "execution_count": 19, 482 | "metadata": {}, 483 | "output_type": "execute_result" 484 | } 485 | ], 486 | "source": [ 487 | "next(a)" 488 | ] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": 20, 493 | "metadata": { 494 | "collapsed": false 495 | }, 496 | "outputs": [ 497 | { 498 | "data": { 499 | "text/plain": [ 500 | "7" 501 | ] 502 | }, 503 | "execution_count": 20, 504 | "metadata": {}, 505 | "output_type": "execute_result" 506 | } 507 | ], 508 | "source": [ 509 | "next(a)" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": 21, 515 | "metadata": { 516 | "collapsed": false 517 | }, 518 | "outputs": [ 519 | { 520 | "ename": "StopIteration", 521 | "evalue": "", 522 | "output_type": "error", 523 | "traceback": [ 524 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 525 | "\u001b[0;31mStopIteration\u001b[0m Traceback (most recent call last)", 526 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 527 | "\u001b[0;31mStopIteration\u001b[0m: " 528 | ] 529 | } 530 | ], 531 | "source": [ 532 | "next(a)" 533 | ] 534 | }, 535 | { 536 | "cell_type": "markdown", 537 | "metadata": {}, 538 | "source": [ 539 | "So, when the generator gets to the end of its iteration it raises an exception. As seen in previous sections, we could surround the `next` call with a `try` block to capture the `StopIteration` so that we can continue after it finishes. This is effectively what the `for` loop is doing." 540 | ] 541 | }, 542 | { 543 | "cell_type": "markdown", 544 | "metadata": {}, 545 | "source": [ 546 | "We can now find all primes (less than or equal to 100, for example) that have the form $4 k - 1$ using" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": 22, 552 | "metadata": { 553 | "collapsed": false 554 | }, 555 | "outputs": [ 556 | { 557 | "name": "stdout", 558 | "output_type": "stream", 559 | "text": [ 560 | "The prime 3 is 4 * 1 - 1.\n", 561 | "The prime 7 is 4 * 2 - 1.\n", 562 | "The prime 11 is 4 * 3 - 1.\n", 563 | "The prime 19 is 4 * 5 - 1.\n", 564 | "The prime 23 is 4 * 6 - 1.\n", 565 | "The prime 31 is 4 * 8 - 1.\n", 566 | "The prime 43 is 4 * 11 - 1.\n", 567 | "The prime 47 is 4 * 12 - 1.\n", 568 | "The prime 59 is 4 * 15 - 1.\n", 569 | "The prime 67 is 4 * 17 - 1.\n", 570 | "The prime 71 is 4 * 18 - 1.\n", 571 | "The prime 79 is 4 * 20 - 1.\n", 572 | "The prime 83 is 4 * 21 - 1.\n" 573 | ] 574 | } 575 | ], 576 | "source": [ 577 | "for p in all_primes(100):\n", 578 | " if (1+p)%4 == 0:\n", 579 | " print(\"The prime {} is 4 * {} - 1.\".format(p, int((1+p)/4)))" 580 | ] 581 | }, 582 | { 583 | "cell_type": "markdown", 584 | "metadata": {}, 585 | "source": [ 586 | "# Exercise : twin primes" 587 | ] 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": {}, 592 | "source": [ 593 | "A *twin prime* is a pair $(p_1, p_2)$ such that both $p_1$ and $p_2$ are prime and $p_2 = p_1 + 2$." 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": {}, 599 | "source": [ 600 | "## Exercise 1\n", 601 | "\n", 602 | "Write a generator that returns twin primes. You can use the generators above, and may want to look at the [itertools](https://docs.python.org/3/library/itertools.html) module together with [its recipes](https://docs.python.org/3/library/itertools.html#itertools-recipes), particularly the `pairwise` recipe." 603 | ] 604 | }, 605 | { 606 | "cell_type": "markdown", 607 | "metadata": {}, 608 | "source": [ 609 | "## Exercise 2\n", 610 | "\n", 611 | "Find how many twin primes there are with $p_2 < 1000$." 612 | ] 613 | }, 614 | { 615 | "cell_type": "markdown", 616 | "metadata": {}, 617 | "source": [ 618 | "## Exercise 3\n", 619 | "\n", 620 | "Let $\\pi_N$ be the number of twin primes such that $p_2 < N$. Plot how $\\pi_N / N$ varies with $N$ for $N=2^k$ and $k = 4, 5, \\dots 16$. (You should use a logarithmic scale where appropriate!)" 621 | ] 622 | }, 623 | { 624 | "cell_type": "markdown", 625 | "metadata": {}, 626 | "source": [ 627 | "# Exercise : a basis for the polynomials" 628 | ] 629 | }, 630 | { 631 | "cell_type": "markdown", 632 | "metadata": {}, 633 | "source": [ 634 | "In the section on classes we defined a `Monomial` class to represent a polynomial with leading coefficient $1$. As the $N+1$ monomials $1, x, x^2, \\dots, x^N$ form a basis for the vector space of polynomials of order $N$, $\\mathbb{P}^N$, we can use the `Monomial` class to return this basis.\n", 635 | "\n", 636 | "## Exercise 1\n", 637 | "\n", 638 | "Define a generator that will iterate through this basis of $\\mathbb{P}^N$ and test it on $\\mathbb{P}^3$." 639 | ] 640 | }, 641 | { 642 | "cell_type": "markdown", 643 | "metadata": {}, 644 | "source": [ 645 | "## Exercise 2\n", 646 | "\n", 647 | "An alternative basis is given by the monomials\n", 648 | "\n", 649 | "$$ \\begin{aligned} p_0(x) &= 1, \\\\ p_1(x) &= 1-x, \\\\ p_2(x) &= (1-x)(2-x), \\\\ \\dots & \\quad \\dots, \\\\ p_N(x) &= \\prod_{n=1}^N (n-x). \\end{aligned} $$\n", 650 | "\n", 651 | "Define a generator that will iterate through this basis of $\\mathbb{P}^N$ and test it on $\\mathbb{P}^4$." 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "## Exercise 3\n", 659 | "\n", 660 | "Use these generators to write another generator that produces a basis of $\\mathbb{P}^3 \\times \\mathbb{P}^4$." 661 | ] 662 | } 663 | ], 664 | "metadata": { 665 | "anaconda-cloud": {}, 666 | "kernelspec": { 667 | "display_name": "Python [default]", 668 | "language": "python", 669 | "name": "python3" 670 | }, 671 | "language_info": { 672 | "codemirror_mode": { 673 | "name": "ipython", 674 | "version": 3 675 | }, 676 | "file_extension": ".py", 677 | "mimetype": "text/x-python", 678 | "name": "python", 679 | "nbconvert_exporter": "python", 680 | "pygments_lexer": "ipython3", 681 | "version": "3.5.2" 682 | }, 683 | "nbconvert": { 684 | "title": "Iterators and Generators" 685 | } 686 | }, 687 | "nbformat": 4, 688 | "nbformat_minor": 0 689 | } 690 | -------------------------------------------------------------------------------- /11-more-classes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Classes and Object Oriented Programming" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "In an earlier section we discussed *classes* as a way of representing an abstract object, such as a polynomial. The resulting code" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": { 21 | "collapsed": true 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "class Polynomial(object):\n", 26 | " \"\"\"Representing a polynomial.\"\"\"\n", 27 | " explanation = \"I am a polynomial\"\n", 28 | " \n", 29 | " def __init__(self, roots, leading_term):\n", 30 | " self.roots = roots\n", 31 | " self.leading_term = leading_term\n", 32 | " self.order = len(roots)\n", 33 | " \n", 34 | " def display(self):\n", 35 | " string = str(self.leading_term)\n", 36 | " for root in self.roots:\n", 37 | " if root == 0:\n", 38 | " string = string + \"x\"\n", 39 | " elif root > 0:\n", 40 | " string = string + \"(x - {})\".format(root)\n", 41 | " else:\n", 42 | " string = string + \"(x + {})\".format(-root)\n", 43 | " return string\n", 44 | " \n", 45 | " def multiply(self, other):\n", 46 | " roots = self.roots + other.roots\n", 47 | " leading_term = self.leading_term * other.leading_term\n", 48 | " return Polynomial(roots, leading_term)\n", 49 | " \n", 50 | " def explain_to(self, caller):\n", 51 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 52 | " print(\"My roots are {}.\".format(self.roots))" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "allowed polynomials to be created, displayed, and multiplied together. However, the language is a little cumbersome. We can take advantage of a number of useful features of Python, many of which carry over to other programming languages, to make it easier to use the results." 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "Remember that the `__init__` function is called when a variable is created. There are a number of special class functions, each of which has two underscores before and after the name. This is another Python *convention* that is effectively a rule: functions surrounded by two underscores have special effects, and will be called by other Python functions internally. So now we can create a variable that represents a specific polynomial by storing its roots and the leading term:" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "Hello, Alice. I am a polynomial.\n", 81 | "My roots are (1, 2, -3).\n", 82 | "Hello, Bob. I am a polynomial.\n", 83 | "My roots are (1, 1, 0, -2).\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "p_roots = (1, 2, -3)\n", 89 | "p_leading_term = 2\n", 90 | "p = Polynomial(p_roots, p_leading_term)\n", 91 | "p.explain_to(\"Alice\")\n", 92 | "q = Polynomial((1,1,0,-2), -1)\n", 93 | "q.explain_to(\"Bob\")" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "Another special function that is very useful is `__repr__`. This gives a *representation* of the class. In essence, if you ask Python to `print` a variable, it will print the *string* returned by the `__repr__` function. This was the role played by our `display` method, so we can just change the name of the function, making the `Polynomial` class easier to use. We can use this to create a simple string representation of the polynomial:" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 3, 106 | "metadata": { 107 | "collapsed": true 108 | }, 109 | "outputs": [], 110 | "source": [ 111 | "class Polynomial(object):\n", 112 | " \"\"\"Representing a polynomial.\"\"\"\n", 113 | " explanation = \"I am a polynomial\"\n", 114 | " \n", 115 | " def __init__(self, roots, leading_term):\n", 116 | " self.roots = roots\n", 117 | " self.leading_term = leading_term\n", 118 | " self.order = len(roots)\n", 119 | " \n", 120 | " def __repr__(self):\n", 121 | " string = str(self.leading_term)\n", 122 | " for root in self.roots:\n", 123 | " if root == 0:\n", 124 | " string = string + \"x\"\n", 125 | " elif root > 0:\n", 126 | " string = string + \"(x - {})\".format(root)\n", 127 | " else:\n", 128 | " string = string + \"(x + {})\".format(-root)\n", 129 | " return string\n", 130 | " \n", 131 | " def explain_to(self, caller):\n", 132 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 133 | " print(\"My roots are {}.\".format(self.roots))" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 4, 139 | "metadata": { 140 | "collapsed": false 141 | }, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "2(x - 1)(x - 2)(x + 3)\n", 148 | "-1(x - 1)(x - 1)x(x + 2)\n" 149 | ] 150 | } 151 | ], 152 | "source": [ 153 | "p = Polynomial(p_roots, p_leading_term)\n", 154 | "print(p)\n", 155 | "q = Polynomial((1,1,0,-2), -1)\n", 156 | "print(q)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "The final special function we'll look at (although there are [many more](https://docs.python.org/2/library/operator.html), many of which may be useful) is `__mul__`. This allows Python to *multiply* two variables together. We did this before using the `multiply` method, but by using the `__mul__` method we can multiply together two polynomials using the standard `*` operator. With this we can take the product of two polynomials:" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 5, 169 | "metadata": { 170 | "collapsed": true 171 | }, 172 | "outputs": [], 173 | "source": [ 174 | "class Polynomial(object):\n", 175 | " \"\"\"Representing a polynomial.\"\"\"\n", 176 | " explanation = \"I am a polynomial\"\n", 177 | " \n", 178 | " def __init__(self, roots, leading_term):\n", 179 | " self.roots = roots\n", 180 | " self.leading_term = leading_term\n", 181 | " self.order = len(roots)\n", 182 | " \n", 183 | " def __repr__(self):\n", 184 | " string = str(self.leading_term)\n", 185 | " for root in self.roots:\n", 186 | " if root == 0:\n", 187 | " string = string + \"x\"\n", 188 | " elif root > 0:\n", 189 | " string = string + \"(x - {})\".format(root)\n", 190 | " else:\n", 191 | " string = string + \"(x + {})\".format(-root)\n", 192 | " return string\n", 193 | " \n", 194 | " def __mul__(self, other):\n", 195 | " roots = self.roots + other.roots\n", 196 | " leading_term = self.leading_term * other.leading_term\n", 197 | " return Polynomial(roots, leading_term)\n", 198 | " \n", 199 | " def explain_to(self, caller):\n", 200 | " print(\"Hello, {}. {}.\".format(caller,self.explanation))\n", 201 | " print(\"My roots are {}.\".format(self.roots))" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 6, 207 | "metadata": { 208 | "collapsed": false 209 | }, 210 | "outputs": [ 211 | { 212 | "name": "stdout", 213 | "output_type": "stream", 214 | "text": [ 215 | "-2(x - 1)(x - 2)(x + 3)(x - 1)(x - 1)x(x + 2)\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "p = Polynomial(p_roots, p_leading_term)\n", 221 | "q = Polynomial((1,1,0,-2), -1)\n", 222 | "r = p*q\n", 223 | "print(r)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "We now have a simple class that can represent polynomials and multiply them together, whilst printing out a simple string form representing itself. This can obviously be extended to be much more useful." 231 | ] 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "metadata": {}, 236 | "source": [ 237 | "## Inheritance" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "As we can see above, building a complete class from scratch can be lengthy and tedious. If there is another class that does much of what we want, we can build on top of that. This is the idea behind *inheritance*. \n", 245 | "\n", 246 | "In the case of the `Polynomial` we declared that it started from the `object` class in the first line defining the class: `class Polynomial(object)`. But we can build on any class, by replacing `object` with something else. Here we will build on the `Polynomial` class that we've started with.\n", 247 | "\n", 248 | "A *monomial* is a polynomial whose leading term is simply 1. A monomial *is* a polynomial, and could be represented as such. However, we could build a class that knows that the leading term is always 1: there may be cases where we can take advantage of this additional simplicity.\n", 249 | "\n", 250 | "We build a new monomial class as follows:" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 7, 256 | "metadata": { 257 | "collapsed": true 258 | }, 259 | "outputs": [], 260 | "source": [ 261 | "class Monomial(Polynomial):\n", 262 | " \"\"\"Representing a monomial, which is a polynomial with leading term 1.\"\"\"\n", 263 | " \n", 264 | " def __init__(self, roots):\n", 265 | " self.roots = roots\n", 266 | " self.leading_term = 1\n", 267 | " self.order = len(roots)" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "Variables of the `Monomial` class *are* also variables of the `Polynomial` class, so can use all the methods and functions from the `Polynomial` class automatically:" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 8, 280 | "metadata": { 281 | "collapsed": false 282 | }, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "Hello, Caroline. I am a polynomial.\n", 289 | "My roots are (-1, 4, 9).\n", 290 | "1(x + 1)(x - 4)(x - 9)\n" 291 | ] 292 | } 293 | ], 294 | "source": [ 295 | "m = Monomial((-1, 4, 9))\n", 296 | "m.explain_to(\"Caroline\")\n", 297 | "print(m)" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": {}, 303 | "source": [ 304 | "We note that these functions, methods and variables may not be exactly right, as they are given for the general `Polynomial` class, not by the specific `Monomial` class. If we *redefine* these functions and variables inside the `Monomial` class, they will *override* those defined in the `Polynomial` class. We do not have to override all the functions and variables, just the parts we want to change:" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 9, 310 | "metadata": { 311 | "collapsed": true 312 | }, 313 | "outputs": [], 314 | "source": [ 315 | "class Monomial(Polynomial):\n", 316 | " \"\"\"Representing a monomial, which is a polynomial with leading term 1.\"\"\"\n", 317 | " explanation = \"I am a monomial\"\n", 318 | " \n", 319 | " def __init__(self, roots):\n", 320 | " self.roots = roots\n", 321 | " self.leading_term = 1\n", 322 | " self.order = len(roots)\n", 323 | " \n", 324 | " def __repr__(self):\n", 325 | " string = \"\"\n", 326 | " for root in self.roots:\n", 327 | " if root == 0:\n", 328 | " string = string + \"x\"\n", 329 | " elif root > 0:\n", 330 | " string = string + \"(x - {})\".format(root)\n", 331 | " else:\n", 332 | " string = string + \"(x + {})\".format(-root)\n", 333 | " return string" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 10, 339 | "metadata": { 340 | "collapsed": false 341 | }, 342 | "outputs": [ 343 | { 344 | "name": "stdout", 345 | "output_type": "stream", 346 | "text": [ 347 | "Hello, Caroline. I am a monomial.\n", 348 | "My roots are (-1, 4, 9).\n", 349 | "(x + 1)(x - 4)(x - 9)\n" 350 | ] 351 | } 352 | ], 353 | "source": [ 354 | "m = Monomial((-1, 4, 9))\n", 355 | "m.explain_to(\"Caroline\")\n", 356 | "print(m)" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": {}, 362 | "source": [ 363 | "This has had no effect on the original `Polynomial` class and variables, which can be used as before:" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 11, 369 | "metadata": { 370 | "collapsed": false 371 | }, 372 | "outputs": [ 373 | { 374 | "name": "stdout", 375 | "output_type": "stream", 376 | "text": [ 377 | "Hello, David. I am a polynomial.\n", 378 | "My roots are (2, 3).\n", 379 | "4(x - 2)(x - 3)\n" 380 | ] 381 | } 382 | ], 383 | "source": [ 384 | "s = Polynomial((2, 3), 4)\n", 385 | "s.explain_to(\"David\")\n", 386 | "print(s)" 387 | ] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": {}, 392 | "source": [ 393 | "And, as `Monomial` variables are `Polynomials`, we can multiply them together to get a `Polynomial`:" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 12, 399 | "metadata": { 400 | "collapsed": false 401 | }, 402 | "outputs": [ 403 | { 404 | "name": "stdout", 405 | "output_type": "stream", 406 | "text": [ 407 | "Hello, Erik. I am a polynomial.\n", 408 | "My roots are (-1, 4, 9, 2, 3).\n", 409 | "4(x + 1)(x - 4)(x - 9)(x - 2)(x - 3)\n" 410 | ] 411 | } 412 | ], 413 | "source": [ 414 | "t = m*s\n", 415 | "t.explain_to(\"Erik\")\n", 416 | "print(t)" 417 | ] 418 | }, 419 | { 420 | "cell_type": "markdown", 421 | "metadata": {}, 422 | "source": [ 423 | "In fact, we can be a bit smarter than this. Note that the `__init__` function of the `Monomial` class is identical to that of the `Polynomial` class, just with the `leading_term` set explicitly to `1`. Rather than duplicating the code and modifying a single value, we can *call* the `__init__` function of the `Polynomial` class directly. This is because the `Monomial` class is built on the `Polynomial` class, so knows about it. We regenerate the class, but only change the `__init__` function:" 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "execution_count": 13, 429 | "metadata": { 430 | "collapsed": true 431 | }, 432 | "outputs": [], 433 | "source": [ 434 | "class Monomial(Polynomial):\n", 435 | " \"\"\"Representing a monomial, which is a polynomial with leading term 1.\"\"\"\n", 436 | " explanation = \"I am a monomial\"\n", 437 | " \n", 438 | " def __init__(self, roots):\n", 439 | " Polynomial.__init__(self, roots, 1)\n", 440 | " \n", 441 | " def __repr__(self):\n", 442 | " string = \"\"\n", 443 | " for root in self.roots:\n", 444 | " if root == 0:\n", 445 | " string = string + \"x\"\n", 446 | " elif root > 0:\n", 447 | " string = string + \"(x - {})\".format(root)\n", 448 | " else:\n", 449 | " string = string + \"(x + {})\".format(-root)\n", 450 | " return string" 451 | ] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "execution_count": 14, 456 | "metadata": { 457 | "collapsed": false 458 | }, 459 | "outputs": [ 460 | { 461 | "name": "stdout", 462 | "output_type": "stream", 463 | "text": [ 464 | "Hello, Fred. I am a monomial.\n", 465 | "My roots are (2, -3).\n", 466 | "(x - 2)(x + 3)\n" 467 | ] 468 | } 469 | ], 470 | "source": [ 471 | "v = Monomial((2, -3))\n", 472 | "v.explain_to(\"Fred\")\n", 473 | "print(v)" 474 | ] 475 | }, 476 | { 477 | "cell_type": "markdown", 478 | "metadata": {}, 479 | "source": [ 480 | "We are now being very explicit in saying that a `Monomial` *really is* a `Polynomial` with `leading_term` being `1`. Note, that in this case we are calling the `__init__` function directly, so have to explicitly include the `self` argument." 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "By building on top of classes in this fashion, we can build classes that transparently represent the objects that we are interested in. \n", 488 | "\n", 489 | "Most modern programming languages include some object oriented features. Many (including Python) will have more complex features than are introduced above. However, the key points where\n", 490 | "\n", 491 | "* a single variable representing an object can be defined,\n", 492 | "* methods that are specific to those objects can be defined,\n", 493 | "* new classes of object that inherit from and extend other classes can be defined,\n", 494 | "\n", 495 | "are the essential steps that are common across nearly all." 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": {}, 501 | "source": [ 502 | "# Exercise: Equivalence classes" 503 | ] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": {}, 508 | "source": [ 509 | "This exercise repeats that from the earlier chapter on classes, but explicitly includes new class methods to make equivalence classes easier to work with.\n", 510 | "\n", 511 | "An *equivalence class* is a relation that groups objects in a set into related subsets. For example, if we think of the integers modulo $7$, then $1$ is in the same equivalence class as $8$ (and $15$, and $22$, and so on), and $3$ is in the same equivalence class as $10$. We use the tilde $3 \\sim 10$ to denote two objects within the same equivalence class.\n", 512 | "\n", 513 | "Here, we are going to define the positive integers programmatically from equivalent sequences." 514 | ] 515 | }, 516 | { 517 | "cell_type": "markdown", 518 | "metadata": {}, 519 | "source": [ 520 | "## Exercise 1\n", 521 | "\n", 522 | "Define a Python class `Eqint`. This should be\n", 523 | "\n", 524 | "1. Initialized by a sequence;\n", 525 | "2. Store the sequence;\n", 526 | "3. Define its representation (via the `__repr__` function) to be the integer length of the sequence;\n", 527 | "4. Redefine equality (via the `__eq__` function) so that two `Eqint`s are equal if their sequences have the same length." 528 | ] 529 | }, 530 | { 531 | "cell_type": "markdown", 532 | "metadata": {}, 533 | "source": [ 534 | "## Exercise 2\n", 535 | "\n", 536 | "Define a `zero` object from the empty list, and three `one` objects, from a single object list, tuple, and string. For example\n", 537 | "\n", 538 | "```python\n", 539 | "one_list = Eqint([1])\n", 540 | "one_tuple = Eqint((1,))\n", 541 | "one_string = Eqint('1')\n", 542 | "```\n", 543 | "\n", 544 | "Check that none of the `one` objects equal the zero object, but all equal the other `one` objects. Print each object to check that the representation gives the integer length." 545 | ] 546 | }, 547 | { 548 | "cell_type": "markdown", 549 | "metadata": {}, 550 | "source": [ 551 | "## Exercise 3\n", 552 | "\n", 553 | "Redefine the class by including an `__add__` method that combines the two sequences. That is, if `a` and `b` are `Eqint`s then `a+b` should return an `Eqint` defined from combining `a` and `b`s sequences.\n", 554 | "\n", 555 | "##### Note\n", 556 | "\n", 557 | "Adding two different *types* of sequences (eg, a list to a tuple) does not work, so it is better to either iterate over the sequences, or to convert to a uniform type before adding." 558 | ] 559 | }, 560 | { 561 | "cell_type": "markdown", 562 | "metadata": {}, 563 | "source": [ 564 | "## Exercise 4\n", 565 | "\n", 566 | "Check your addition function by adding together all your previous `Eqint` objects (which will need re-defining, as the class has been redefined). Print the resulting object to check you get `3`, and also print its internal sequence." 567 | ] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "metadata": {}, 572 | "source": [ 573 | "## Exercise 5\n", 574 | "\n", 575 | "We will sketch a construction of the positive integers from *nothing*.\n", 576 | "\n", 577 | "1. Define an empty list `positive_integers`.\n", 578 | "2. Define an `Eqint` called `zero` from the empty list. Append it to `positive_integers`.\n", 579 | "3. Define an `Eqint` called `next_integer` from the `Eqint` defined by *a copy of* `positive_integers` (ie, use `Eqint(list(positive_integers))`. Append it to `positive_integers`.\n", 580 | "4. Repeat step 3 as often as needed.\n", 581 | "\n", 582 | "Use this procedure to define the `Eqint` equivalent to $10$. Print it, and its internal sequence, to check." 583 | ] 584 | }, 585 | { 586 | "cell_type": "markdown", 587 | "metadata": {}, 588 | "source": [ 589 | "# Exercise: Rational numbers" 590 | ] 591 | }, 592 | { 593 | "cell_type": "markdown", 594 | "metadata": {}, 595 | "source": [ 596 | "Instead of working with floating point numbers, which are not \"exact\", we could work with the rational numbers $\\mathbb{Q}$. A rational number $q \\in \\mathbb{Q}$ is defined by the *numerator* $n$ and *denominator* $d$ as $q = \\frac{n}{d}$, where $n$ and $d$ are *coprime* (ie, have no common divisor other than $1$)." 597 | ] 598 | }, 599 | { 600 | "cell_type": "markdown", 601 | "metadata": {}, 602 | "source": [ 603 | "## Exercise 1\n", 604 | "\n", 605 | "Find a Python function that finds the greatest common divisor (`gcd`) of two numbers. Use this to write a function `normal_form` that takes a numerator and divisor and returns the coprime $n$ and $d$. Test this function on $q = \\frac{3}{2}$, $q = \\frac{15}{3}$, and $q = \\frac{20}{42}$." 606 | ] 607 | }, 608 | { 609 | "cell_type": "markdown", 610 | "metadata": {}, 611 | "source": [ 612 | "## Exercise 2\n", 613 | "\n", 614 | "Define a class `Rational` that uses the `normal_form` function to store the rational number in the appropriate form. Define a `__repr__` function that prints a string that *looks like* $\\frac{n}{d}$ (**hint**: use `len(str(number))` to find the number of digits of an integer, and use `\\n` to start a new line). Test it on the cases above." 615 | ] 616 | }, 617 | { 618 | "cell_type": "markdown", 619 | "metadata": {}, 620 | "source": [ 621 | "## Exercise 3\n", 622 | "\n", 623 | "Overload the `__add__` function so that you can add two rational numbers. Test it on $\\frac{1}{2} + \\frac{1}{3} + \\frac{1}{6} = 1$." 624 | ] 625 | }, 626 | { 627 | "cell_type": "markdown", 628 | "metadata": {}, 629 | "source": [ 630 | "## Exercise 4\n", 631 | "\n", 632 | "Overload the `__mul__` function so that you can multiply two rational numbers. Test it on $\\frac{1}{3} \\times \\frac{15}{2} \\times \\frac{2}{5} = 1$." 633 | ] 634 | }, 635 | { 636 | "cell_type": "markdown", 637 | "metadata": {}, 638 | "source": [ 639 | "## Exercise 5\n", 640 | "\n", 641 | "Overload the [`__rmul__`](https://docs.python.org/2/reference/datamodel.html?highlight=rmul#object.__rmul__) function so that you can multiply a rational by an *integer*. Check that $\\frac{1}{2} \\times 2 = 1$ and $\\frac{1}{2} + (-1) \\times \\frac{1}{2} = 0$. Also overload the `__sub__` function (using previous functions!) so that you can subtract rational numbers and check that $\\frac{1}{2} - \\frac{1}{2} = 0$." 642 | ] 643 | }, 644 | { 645 | "cell_type": "markdown", 646 | "metadata": {}, 647 | "source": [ 648 | "## Exercise 6\n", 649 | "\n", 650 | "Overload the `__float__` function so that `float(q)` returns the floating point approximation to the rational number `q`. Test this on $\\frac{1}{2}, \\frac{1}{3}$, and $\\frac{1}{11}$." 651 | ] 652 | }, 653 | { 654 | "cell_type": "markdown", 655 | "metadata": {}, 656 | "source": [ 657 | "## Exercise 7\n", 658 | "\n", 659 | "Overload the `__lt__` function to compare two rational numbers. Create a list of rational numbers where the denominator is $n = 2, \\dots, 11$ and the numerator is the floored integer $n/2$, ie `n//2`. Use the `sorted` function on that list (which relies on the `__lt__` function)." 660 | ] 661 | }, 662 | { 663 | "cell_type": "markdown", 664 | "metadata": {}, 665 | "source": [ 666 | "## Exercise 8\n", 667 | "\n", 668 | "The [Wallis formula for π](http://mathworld.wolfram.com/WallisFormula.html) is\n", 669 | "\n", 670 | "$$ \\pi = 2 \\prod_{n=1}^{\\infty} \\frac{ (2 n)^2 }{(2 n - 1) (2 n + 1)}. $$\n", 671 | "\n", 672 | "We can define a partial product $\\pi_N$ as\n", 673 | "\n", 674 | "$$ \\pi_N = 2 \\prod_{n=1}^{N} \\frac{ (2 n)^2 }{(2 n - 1) (2 n + 1)}, $$\n", 675 | "\n", 676 | "each of which are rational numbers.\n", 677 | "\n", 678 | "Construct a list of the first 20 rational number approximations to $\\pi$ and print them out. Print the sorted list to show that the approximations are always increasing. Then convert them to floating point numbers, construct a `numpy` array, and subtract this array from $\\pi$ to see how accurate they are." 679 | ] 680 | } 681 | ], 682 | "metadata": { 683 | "kernelspec": { 684 | "display_name": "Python [default]", 685 | "language": "python", 686 | "name": "python3" 687 | }, 688 | "language_info": { 689 | "codemirror_mode": { 690 | "name": "ipython", 691 | "version": 3 692 | }, 693 | "file_extension": ".py", 694 | "mimetype": "text/x-python", 695 | "name": "python", 696 | "nbconvert_exporter": "python", 697 | "pygments_lexer": "ipython3", 698 | "version": "3.5.2" 699 | }, 700 | "nbconvert": { 701 | "title": "Classes and objects" 702 | } 703 | }, 704 | "nbformat": 4, 705 | "nbformat_minor": 0 706 | } 707 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Sources and contributors 2 | 3 | ## Sources 4 | 5 | The material and presentation style have been strongly influenced by 6 | 7 | * [Software Carpentry](http://software-carpentry.org/), particularly the [novice Python lesson](https://github.com/swcarpentry/python-novice-inflammation); 8 | * [Hans Fangohr's](http://www.southampton.ac.uk/~fangohr/) [Python courses](http://www.southampton.ac.uk/~fangohr/training/python/); 9 | * [Johansson's Scientific Python lectures](https://github.com/jrjohansson/scientific-python-lectures); 10 | * [Newman's *Computational Physics with Python* book](http://www-personal.umich.edu/~mejn/computational-physics/); 11 | * [Scopatz & Huff's *Effective Computation in Physics*](http://physics.codes/); 12 | * [Vedran Sego's course at Manchester](http://www.maths.manchester.ac.uk/~vsego/teaching.php); 13 | * [Lorena Barba's work](http://lorenabarba.com/), particularly with [the Practical Numerical Methods with Python MOOC](https://github.com/numerical-mooc/numerical-mooc) 14 | 15 | ## Contributors 16 | 17 | People that have directly contributed code, bugfixes, comments and ideas include 18 | 19 | * Ian Hawke 20 | * Wynn Ho 21 | * Sujit Sahu 22 | * Hans Fangohr 23 | * Vedran Sego 24 | * Sarah Mount 25 | * Nick (@python33r) 26 | * Greg Wilson 27 | * Giampaolo d'Alessandro 28 | * Sam Mugel 29 | * Greg Ashton 30 | * Vanessa Graber 31 | * Yafet Sanchez Sanchez 32 | * Ruth Walton 33 | * Will Woodhead (@lux01) 34 | -------------------------------------------------------------------------------- /FirstYearComputing_Master.tex: -------------------------------------------------------------------------------- 1 | 2 | \date{} 3 | \author{Southampton Mathematics} 4 | \documentclass{book} 5 | 6 | \usepackage{nbconvert_book} 7 | 8 | %%%%% 9 | % User-defined commands for the LaTeX chapter 10 | % New commands; see section 1.1 11 | \newcommand{\pda}[2]{\frac{\partial {#1}}{\partial {#2}}} 12 | \newcommand{\uos}{\textsc{University of Southampton}} 13 | % Renewed commands; see section 1.2 14 | \renewcommand{\vec}[1]{\mathbf{#1}} 15 | 16 | % New environments; see section 2 17 | \newenvironment{solution}[1]{% 18 | \begin{center} 19 | \rule{#1}{.1pt} 20 | \end{center} 21 | }{% 22 | \begin{center} 23 | \rule{0.9\textwidth}{.1pt} 24 | \end{center} 25 | } 26 | %%%%% 27 | 28 | \title{Mathematics with Python} 29 | 30 | \begin{document} 31 | 32 | 33 | \maketitle 34 | 35 | \tableofcontents 36 | 37 | \addtocounter{chapter}{-1} 38 | 39 | \include{00-first-steps} 40 | \include{01-python-basics} 41 | \include{02-programs} 42 | \include{03-loops-control-flow} 43 | \include{04-basic-plotting} 44 | \include{05-classes-oop} 45 | \include{06-numpy-plotting} 46 | \include{07-sympy} 47 | \include{08-statistics} 48 | 49 | \include{latex_chapter} 50 | 51 | \appendix 52 | 53 | \include{09-exceptions-testing} 54 | \include{10-generators} 55 | \include{11-more-classes} 56 | 57 | \end{document} 58 | -------------------------------------------------------------------------------- /FirstYearComputing_Master_xelatex.tex: -------------------------------------------------------------------------------- 1 | 2 | \date{} 3 | \author{Southampton Mathematics} 4 | \documentclass{book} 5 | 6 | \usepackage{nbconvert_book} 7 | 8 | % enable system font access 9 | \usepackage{fontspec} 10 | 11 | % styling: Palatino (main text), Helvetica (stress), Code2000 (exotic text) and Asana Math (for math things) 12 | \setmainfont{Lucida Grande} 13 | \setmonofont{Monaco} % Monaco 14 | \newfontfamily{\maintext}{Lucida Grande} 15 | %\newfontfamily{\code}{DejaVu Sans Mono} 16 | %\newfontfamily{\math}{Arial} 17 | 18 | %%%%% 19 | % User-defined commands for the LaTeX chapter 20 | % New commands; see section 1.1 21 | \newcommand{\pda}[2]{\frac{\partial {#1}}{\partial {#2}}} 22 | \newcommand{\uos}{\textsc{University of Southampton}} 23 | % Renewed commands; see section 1.2 24 | \renewcommand{\vec}[1]{\mathbf{#1}} 25 | 26 | % New environments; see section 2 27 | \newenvironment{solution}[1]{% 28 | \begin{center} 29 | \rule{#1}{.1pt} 30 | \end{center} 31 | }{% 32 | \begin{center} 33 | \rule{0.9\textwidth}{.1pt} 34 | \end{center} 35 | } 36 | %%%%% 37 | 38 | \title{Mathematics with Python} 39 | 40 | \begin{document} 41 | 42 | 43 | \maketitle 44 | 45 | \tableofcontents 46 | 47 | \addtocounter{chapter}{-1} 48 | 49 | \include{00-first-steps} 50 | \include{01-python-basics} 51 | \include{02-programs} 52 | \include{03-loops-control-flow} 53 | \include{04-basic-plotting} 54 | \include{05-classes-oop} 55 | \include{06-numpy-plotting} 56 | \include{07-sympy} 57 | \include{08-statistics} 58 | 59 | \include{latex_chapter} 60 | 61 | \appendix 62 | 63 | \include{09-exceptions-testing} 64 | \include{10-generators} 65 | \include{11-more-classes} 66 | 67 | \end{document} 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ian Hawke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | runipy_pdf: 2 | cp *.tplx nbconvert_book.sty _runipy/ 3 | cp -r images _runipy/ 4 | cp latex_chapter.tex FirstYearComputing_Master.tex _runipy/ 5 | python run_notebooks.py 6 | make -C _runipy FirstYearComputing_Master.pdf 7 | 8 | FirstYearComputing_Master.pdf: FirstYearComputing_Master.tex \ 9 | 00-first-steps.tex 01-python-basics.tex 02-programs.tex \ 10 | 03-loops-control-flow.tex 04-basic-plotting.tex \ 11 | 05-classes-oop.tex 06-numpy-plotting.tex \ 12 | 07-sympy.tex 08-statistics.tex 09-exceptions-testing.tex \ 13 | 10-generators.tex 11-more-classes.tex latex_chapter.tex 14 | pdflatex $< 15 | pdflatex $< 16 | 17 | FirstYearComputing_Master_xelatex.pdf: FirstYearComputing_Master_xelatex.tex \ 18 | 00-first-steps.tex 01-python-basics.tex 02-programs.tex \ 19 | 03-loops-control-flow.tex 04-basic-plotting.tex \ 20 | 05-classes-oop.tex 06-numpy-plotting.tex \ 21 | 07-sympy.tex 08-statistics.tex 09-exceptions-testing.tex \ 22 | 10-generators.tex 11-more-classes.tex latex_chapter.tex 23 | xelatex $< 24 | xelatex $< 25 | 26 | all_html: index.html \ 27 | 00-first-steps.html 01-python-basics.html 02-programs.html \ 28 | 03-loops-control-flow.html 04-basic-plotting.html \ 29 | 05-classes-oop.html 06-numpy-plotting.html \ 30 | 07-sympy.html 08-statistics.html 09-exceptions-testing.html \ 31 | 10-generators.html 11-more-classes.html 32 | 33 | web_html: website-index.html \ 34 | 00-first-steps.html 01-python-basics.html 02-programs.html \ 35 | 03-loops-control-flow.html 04-basic-plotting.html \ 36 | 05-classes-oop.html 06-numpy-plotting.html \ 37 | 07-sympy.html 08-statistics.html 09-exceptions-testing.html \ 38 | 10-generators.html 11-more-classes.html \ 39 | ExercisesSolutions.html 40 | 41 | %.pdf: %.tex %.ipynb 42 | pdflatex $< 43 | pdflatex $< 44 | 45 | %.tex: %.ipynb chapter-base.tplx 46 | jupyter nbconvert --to latex --template=chapter-ipython.tplx $< 47 | 48 | %.html: %.ipynb full-title.tpl 49 | jupyter nbconvert --to html --template=full-title.tpl $< 50 | 51 | Exercises.tex: Exercises.ipynb 52 | jupyter nbconvert --to latex $< 53 | ExercisesSolutions.tex: ExercisesSolutions.ipynb 54 | jupyter nbconvert --to latex $< 55 | 56 | webpages: web_html 57 | mkdir -p webpages 58 | cp [01]*html ExercisesSolutions.html webpages/ 59 | cp website-index.html webpages/index.html 60 | cp -r images webpages/ 61 | ghp-import -m "Generate website" -b gh-pages webpages 62 | git push origin gh-pages 63 | 64 | # Makefile for Sphinx documentation 65 | # 66 | 67 | # You can set these variables from the command line. 68 | SPHINXOPTS = 69 | SPHINXBUILD = sphinx-build 70 | PAPER = 71 | BUILDDIR = _build 72 | 73 | # User-friendly check for sphinx-build 74 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 75 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 76 | endif 77 | 78 | # Internal variables. 79 | PAPEROPT_a4 = -D latex_paper_size=a4 80 | PAPEROPT_letter = -D latex_paper_size=letter 81 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 82 | # the i18n builder cannot share the environment and doctrees with the others 83 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 84 | 85 | html: 86 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 87 | @echo 88 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 89 | 90 | epub: 91 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 92 | @echo 93 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 94 | 95 | 96 | clean: 97 | rm -f *.{out,log,aux,toc} 98 | rm -rf auto 99 | rm -f [01]*tex 100 | rm -rf [01]*files 101 | rm -f Exercises*tex 102 | rm -rf Exercises*files 103 | rm -rf __pycache__ 104 | rm -f *.html 105 | rm -rf webpages 106 | rm -rf $(BUILDDIR)/* 107 | rm -f _runipy/*.{ipynb,tex,out,log,aux,toc} 108 | rm -rf _runipy/*_files _runipy/images _runipy/.ipynb_checkpoints 109 | rm -f _runipy/*.{tplx,sty} 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maths with Python 2 | 3 | [![Binder](http://mybinder.org/badge.svg)](http://mybinder.org/repo/IanHawke/maths-with-python) 4 | [![Documentation Status](https://readthedocs.org/projects/maths-with-python/badge/?version=latest)](http://maths-with-python.readthedocs.org/en/latest/?badge=latest) 5 | 6 | 7 | Gathering some material for a Python class aimed at first year undergraduate mathematicians at Southampton. To be covered in ten hours of labs. 8 | 9 | To build these notes you will need 10 | 11 | * python (3.3+) 12 | * ipython (3+) 13 | * ipython-notebook or jupyter (the notes recommend jupyter, but that's for forwards compatibility: it should work on ipython-notebook 3+) 14 | * scipy stack (scipy, sympy, numpy, matplotlib) 15 | * latex 16 | * nose 17 | * watermark line magic (see https://github.com/rasbt/watermark) 18 | * memory profiler line magic (see https://pypi.python.org/pypi/memory_profiler) 19 | -------------------------------------------------------------------------------- /_runipy/Makefile: -------------------------------------------------------------------------------- 1 | FirstYearComputing_Master.pdf: FirstYearComputing_Master.tex \ 2 | 00-first-steps.tex 01-python-basics.tex 02-programs.tex \ 3 | 03-loops-control-flow.tex 04-basic-plotting.tex \ 4 | 05-classes-oop.tex 06-numpy-plotting.tex \ 5 | 07-sympy.tex 08-statistics.tex 09-exceptions-testing.tex \ 6 | 10-generators.tex 11-more-classes.tex latex_chapter.tex 7 | pdflatex $< 8 | pdflatex $< 9 | 10 | %.pdf: %.tex %.ipynb 11 | pdflatex $< 12 | pdflatex $< 13 | 14 | %.tex: %.ipynb chapter-base.tplx 15 | jupyter nbconvert --to latex --template=chapter-ipython.tplx $< 16 | -------------------------------------------------------------------------------- /article-mod.tplx: -------------------------------------------------------------------------------- 1 | 2 | % Default to the notebook output style 3 | ((* if not cell_style is defined *)) 4 | ((* set cell_style = 'style_ipython.tplx' *)) 5 | ((* endif *)) 6 | 7 | % Inherit from the specified cell style. 8 | ((* extends cell_style *)) 9 | 10 | 11 | %=============================================================================== 12 | % Latex Article 13 | %=============================================================================== 14 | 15 | ((* block docclass *)) 16 | \date{} 17 | \author{Southampton Mathematics} 18 | \documentclass{article} 19 | ((* endblock docclass *)) 20 | -------------------------------------------------------------------------------- /breakpoints.py: -------------------------------------------------------------------------------- 1 | def test_sequence(N): 2 | """ 3 | Compute the infinite sum of 2^{-n} starting from n = 0, truncating 4 | at n = N, returning the value of 2^{-n} and the truncated sum. 5 | 6 | Parameters 7 | ---------- 8 | 9 | N : int 10 | Positive integer, giving the number of terms in the sum 11 | 12 | Returns 13 | ------- 14 | 15 | limit : float 16 | The value of 2^{-N} 17 | partial_sum : float 18 | The value of the truncated sum 19 | 20 | Notes 21 | ----- 22 | 23 | The limiting value should be zero, and the value of the sum should 24 | converge to 2. 25 | """ 26 | 27 | # Start sum from zero, so give zeroth term 28 | limit = 1.0 29 | partial_sum = 1.0 30 | 31 | # At each step, increment sum and change summand 32 | for n in range(1, N+1): 33 | partial_sum += limit 34 | limit /= 2.0 35 | 36 | return limit, partial_sum 37 | 38 | if __name__ == '__main__': 39 | print(test_sequence(50)) 40 | -------------------------------------------------------------------------------- /chapter-base.tplx: -------------------------------------------------------------------------------- 1 | ((= Latex chapter base template (must inherit) 2 | This templatex, mostly copied from base.tplx, converts a notebook to a chapter. 3 | The result, after conversion, must be LaTeX included in a master document. 4 | =)) 5 | 6 | ((*- extends 'display_priority.tplx' -*)) 7 | 8 | %=============================================================================== 9 | % Abstract overrides 10 | %=============================================================================== 11 | 12 | ((* block header *)) 13 | ((* endblock header *)) 14 | 15 | ((* block body *)) 16 | \begin{chapter}{((( nb.metadata.get('nbconvert', {}).get('title', resources.metadata.name) | ascii_only | escape_latex )))} 17 | 18 | ((* block predoc *)) 19 | ((* endblock predoc *)) 20 | 21 | ((( super() ))) 22 | 23 | \end{chapter} 24 | ((* endblock body *)) 25 | 26 | %=============================================================================== 27 | % Support blocks 28 | %=============================================================================== 29 | 30 | % Displaying simple data text 31 | ((* block data_text *)) 32 | \begin{verbatim} 33 | ((( output.data['text/plain'] ))) 34 | \end{verbatim} 35 | ((* endblock data_text *)) 36 | 37 | % Display python error text as-is 38 | ((* block error *)) 39 | \begin{Verbatim}[commandchars=\\\{\}] 40 | ((( super() ))) 41 | \end{Verbatim} 42 | ((* endblock error *)) 43 | ((* block traceback_line *)) 44 | ((( line | indent | strip_ansi | escape_latex ))) 45 | ((* endblock traceback_line *)) 46 | 47 | % Display stream ouput with coloring 48 | ((* block stream *)) 49 | \begin{Verbatim}[commandchars=\\\{\}] 50 | ((( output.text | escape_latex | ansi2latex ))) 51 | \end{Verbatim} 52 | ((* endblock stream *)) 53 | 54 | % Display latex 55 | ((* block data_latex -*)) 56 | ((*- if output.data['text/latex'].startswith('$'): -*)) 57 | ((= Replace $ symbols with more explicit, equation block. =)) 58 | \begin{equation*}\adjustbox{max width=\hsize}{$ 59 | ((( output.data['text/latex'] | strip_dollars ))) 60 | $}\end{equation*} 61 | ((*- else -*)) 62 | ((( output.data['text/latex'] ))) 63 | ((*- endif *)) 64 | ((* endblock data_latex *)) 65 | 66 | % Default mechanism for rendering figures 67 | ((*- block data_png -*))((( draw_figure(output.metadata.filenames['image/png']) )))((*- endblock -*)) 68 | ((*- block data_jpg -*))((( draw_figure(output.metadata.filenames['image/jpeg']) )))((*- endblock -*)) 69 | ((*- block data_svg -*))((( draw_figure(output.metadata.filenames['image/svg+xml']) )))((*- endblock -*)) 70 | ((*- block data_pdf -*))((( draw_figure(output.metadata.filenames['application/pdf']) )))((*- endblock -*)) 71 | 72 | % Draw a figure using the graphicx package. 73 | ((* macro draw_figure(filename) -*)) 74 | ((* set filename = filename | posix_path *)) 75 | ((*- block figure scoped -*)) 76 | \begin{center} 77 | \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))} 78 | \end{center} 79 | { \hspace*{\fill} \\} 80 | ((*- endblock figure -*)) 81 | ((*- endmacro *)) 82 | 83 | % Redirect execute_result to display data priority. 84 | ((* block execute_result scoped *)) 85 | ((* block data_priority scoped *)) 86 | ((( super() ))) 87 | ((* endblock *)) 88 | ((* endblock execute_result *)) 89 | 90 | % Render markdown 91 | ((* block markdowncell scoped *)) 92 | ((( cell.source | citation2latex | strip_files_prefix | markdown2latex ))) 93 | ((* endblock markdowncell *)) 94 | 95 | % Don't display unknown types 96 | ((* block unknowncell scoped *)) 97 | ((* endblock unknowncell *)) 98 | -------------------------------------------------------------------------------- /chapter-ipython.tplx: -------------------------------------------------------------------------------- 1 | ((= IPython input/output style =)) 2 | 3 | ((*- extends 'chapter-base.tplx' -*)) 4 | 5 | % Custom definitions 6 | ((* block definitions *)) 7 | ((( super() ))) 8 | 9 | % Pygments definitions 10 | ((( resources.latex.pygments_definitions ))) 11 | 12 | % Exact colors from NB 13 | \definecolor{incolor}{rgb}{0.0, 0.0, 0.5} 14 | \definecolor{outcolor}{rgb}{0.545, 0.0, 0.0} 15 | 16 | ((* endblock definitions *)) 17 | 18 | %=============================================================================== 19 | % Input 20 | %=============================================================================== 21 | 22 | ((* block input scoped *)) 23 | ((( add_prompt(cell.source | highlight_code(strip_verbatim=True), cell, 'In ', 'incolor') ))) 24 | ((* endblock input *)) 25 | 26 | %=============================================================================== 27 | % Hide output (taken from jupyter/ngcm-tutorial/Day-2/nbconvert_templates) 28 | %=============================================================================== 29 | 30 | ((* block input_group *)) 31 | ((*- if not cell.metadata.get('nbconvert', {}).get('hide_code', False) -*)) 32 | ((( super() ))) 33 | ((*- endif -*)) 34 | ((* endblock input_group *)) 35 | 36 | %=============================================================================== 37 | % Output 38 | %=============================================================================== 39 | 40 | ((* block execute_result scoped *)) 41 | ((*- for type in output.data | filter_data_type -*)) 42 | ((*- if type in ['text/plain']*)) 43 | ((( add_prompt(output.data['text/plain'] | escape_latex, cell, 'Out', 'outcolor') ))) 44 | ((* else -*)) 45 | \texttt{\color{outcolor}Out[{\color{outcolor}((( cell.execution_count )))}]:}((( super() ))) 46 | ((*- endif -*)) 47 | ((*- endfor -*)) 48 | ((* endblock execute_result *)) 49 | 50 | 51 | %============================================================================== 52 | % Support Macros 53 | %============================================================================== 54 | 55 | % Name: draw_prompt 56 | % Purpose: Renders an output/input prompt 57 | ((* macro add_prompt(text, cell, prompt, prompt_color) -*)) 58 | ((*- if cell.execution_count is defined -*)) 59 | ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*)) 60 | ((*- else -*)) 61 | ((*- set execution_count = " " -*)) 62 | ((*- endif -*)) 63 | ((*- set indention = " " * (execution_count | length + 7) -*)) 64 | \begin{Verbatim}[commandchars=\\\{\}] 65 | ((( text | add_prompts(first='{\color{' ~ prompt_color ~ '}' ~ prompt ~ '[{\\color{' ~ prompt_color ~ '}' ~ execution_count ~ '}]:} ', cont=indention) ))) 66 | \end{Verbatim} 67 | ((*- endmacro *)) 68 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Maths with Python documentation build configuration file, created by 5 | # sphinx-quickstart on Tue Mar 8 10:22:01 2016. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | 19 | # If extensions (or modules to document with autodoc) are in another directory, 20 | # add these directories to sys.path here. If the directory is relative to the 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. 22 | #sys.path.insert(0, os.path.abspath('.')) 23 | 24 | # -- General configuration ------------------------------------------------ 25 | 26 | # If your documentation needs a minimal Sphinx version, state it here. 27 | #needs_sphinx = '1.0' 28 | 29 | # Add any Sphinx extension module names here, as strings. They can be 30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 31 | # ones. 32 | extensions = [ 33 | 'sphinx.ext.imgmath', 34 | 'nbsphinx', 35 | 'IPython.sphinxext.ipython_console_highlighting', 36 | ] 37 | 38 | # Add any paths that contain templates here, relative to this directory. 39 | templates_path = ['_templates'] 40 | 41 | # The suffix(es) of source filenames. 42 | # You can specify multiple suffix as a list of string: 43 | # source_suffix = ['.rst', '.md'] 44 | source_suffix = '.rst' 45 | 46 | # The encoding of source files. 47 | #source_encoding = 'utf-8-sig' 48 | 49 | # The master toctree document. 50 | master_doc = 'index' 51 | 52 | # General information about the project. 53 | project = 'Maths with Python' 54 | copyright = '2016, Mathematical Sciences, University of Southampton' 55 | author = 'Mathematical Sciences, University of Southampton' 56 | 57 | # The version info for the project you're documenting, acts as replacement for 58 | # |version| and |release|, also used in various other places throughout the 59 | # built documents. 60 | # 61 | # The short X.Y version. 62 | version = '1.0' 63 | # The full version, including alpha/beta/rc tags. 64 | release = '1.0' 65 | 66 | # The language for content autogenerated by Sphinx. Refer to documentation 67 | # for a list of supported languages. 68 | # 69 | # This is also used if you do content translation via gettext catalogs. 70 | # Usually you set "language" from the command line for these cases. 71 | language = None 72 | 73 | # There are two options for replacing |today|: either, you set today to some 74 | # non-false value, then it is used: 75 | #today = '' 76 | # Else, today_fmt is used as the format for a strftime call. 77 | #today_fmt = '%B %d, %Y' 78 | 79 | # List of patterns, relative to source directory, that match files and 80 | # directories to ignore when looking for source files. 81 | exclude_patterns = ['_build'] 82 | 83 | # The reST default role (used for this markup: `text`) to use for all 84 | # documents. 85 | #default_role = None 86 | 87 | # If true, '()' will be appended to :func: etc. cross-reference text. 88 | #add_function_parentheses = True 89 | 90 | # If true, the current module name will be prepended to all description 91 | # unit titles (such as .. function::). 92 | #add_module_names = True 93 | 94 | # If true, sectionauthor and moduleauthor directives will be shown in the 95 | # output. They are ignored by default. 96 | #show_authors = False 97 | 98 | # The name of the Pygments (syntax highlighting) style to use. 99 | pygments_style = 'sphinx' 100 | 101 | # A list of ignored prefixes for module index sorting. 102 | #modindex_common_prefix = [] 103 | 104 | # If true, keep warnings as "system message" paragraphs in the built documents. 105 | #keep_warnings = False 106 | 107 | # If true, `todo` and `todoList` produce output, else they produce nothing. 108 | todo_include_todos = False 109 | 110 | 111 | # -- Options for HTML output ---------------------------------------------- 112 | 113 | # The theme to use for HTML and HTML Help pages. See the documentation for 114 | # a list of builtin themes. 115 | html_theme = 'alabaster' 116 | 117 | # Theme options are theme-specific and customize the look and feel of a theme 118 | # further. For a list of options available for each theme, see the 119 | # documentation. 120 | #html_theme_options = {} 121 | 122 | # Add any paths that contain custom themes here, relative to this directory. 123 | #html_theme_path = [] 124 | 125 | # The name for this set of Sphinx documents. If None, it defaults to 126 | # " v documentation". 127 | #html_title = None 128 | 129 | # A shorter title for the navigation bar. Default is the same as html_title. 130 | #html_short_title = None 131 | 132 | # The name of an image file (relative to this directory) to place at the top 133 | # of the sidebar. 134 | #html_logo = None 135 | 136 | # The name of an image file (within the static path) to use as favicon of the 137 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 138 | # pixels large. 139 | #html_favicon = None 140 | 141 | # Add any paths that contain custom static files (such as style sheets) here, 142 | # relative to this directory. They are copied after the builtin static files, 143 | # so a file named "default.css" will overwrite the builtin "default.css". 144 | html_static_path = ['_static'] 145 | 146 | # Add any extra paths that contain custom files (such as robots.txt or 147 | # .htaccess) here, relative to this directory. These files are copied 148 | # directly to the root of the documentation. 149 | #html_extra_path = [] 150 | 151 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 152 | # using the given strftime format. 153 | #html_last_updated_fmt = '%b %d, %Y' 154 | 155 | # If true, SmartyPants will be used to convert quotes and dashes to 156 | # typographically correct entities. 157 | #html_use_smartypants = True 158 | 159 | # Custom sidebar templates, maps document names to template names. 160 | #html_sidebars = {} 161 | 162 | # Additional templates that should be rendered to pages, maps page names to 163 | # template names. 164 | #html_additional_pages = {} 165 | 166 | # If false, no module index is generated. 167 | #html_domain_indices = True 168 | 169 | # If false, no index is generated. 170 | #html_use_index = True 171 | 172 | # If true, the index is split into individual pages for each letter. 173 | #html_split_index = False 174 | 175 | # If true, links to the reST sources are added to the pages. 176 | #html_show_sourcelink = True 177 | 178 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 179 | #html_show_sphinx = True 180 | 181 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 182 | #html_show_copyright = True 183 | 184 | # If true, an OpenSearch description file will be output, and all pages will 185 | # contain a tag referring to it. The value of this option must be the 186 | # base URL from which the finished HTML is served. 187 | #html_use_opensearch = '' 188 | 189 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 190 | #html_file_suffix = None 191 | 192 | # Language to be used for generating the HTML full-text search index. 193 | # Sphinx supports the following languages: 194 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' 195 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' 196 | #html_search_language = 'en' 197 | 198 | # A dictionary with options for the search language support, empty by default. 199 | # Now only 'ja' uses this config value 200 | #html_search_options = {'type': 'default'} 201 | 202 | # The name of a javascript file (relative to the configuration directory) that 203 | # implements a search results scorer. If empty, the default will be used. 204 | #html_search_scorer = 'scorer.js' 205 | 206 | # Output file base name for HTML help builder. 207 | htmlhelp_basename = 'MathswithPythondoc' 208 | 209 | # -- Options for LaTeX output --------------------------------------------- 210 | 211 | latex_elements = { 212 | # The paper size ('letterpaper' or 'a4paper'). 213 | #'papersize': 'letterpaper', 214 | 215 | # The font size ('10pt', '11pt' or '12pt'). 216 | #'pointsize': '10pt', 217 | 218 | # Additional stuff for the LaTeX preamble. 219 | #'preamble': '', 220 | 221 | # Latex figure (float) alignment 222 | #'figure_align': 'htbp', 223 | } 224 | 225 | # Grouping the document tree into LaTeX files. List of tuples 226 | # (source start file, target name, title, 227 | # author, documentclass [howto, manual, or own class]). 228 | latex_documents = [ 229 | (master_doc, 'MathswithPython.tex', 'Maths with Python Documentation', 230 | 'Mathematical Sciences, University of Southampton', 'manual'), 231 | ] 232 | 233 | # The name of an image file (relative to this directory) to place at the top of 234 | # the title page. 235 | #latex_logo = None 236 | 237 | # For "manual" documents, if this is true, then toplevel headings are parts, 238 | # not chapters. 239 | #latex_use_parts = False 240 | 241 | # If true, show page references after internal links. 242 | #latex_show_pagerefs = False 243 | 244 | # If true, show URL addresses after external links. 245 | #latex_show_urls = False 246 | 247 | # Documents to append as an appendix to all manuals. 248 | #latex_appendices = [] 249 | 250 | # If false, no module index is generated. 251 | #latex_domain_indices = True 252 | 253 | 254 | # -- Options for manual page output --------------------------------------- 255 | 256 | # One entry per manual page. List of tuples 257 | # (source start file, name, description, authors, manual section). 258 | man_pages = [ 259 | (master_doc, 'mathswithpython', 'Maths with Python Documentation', 260 | [author], 1) 261 | ] 262 | 263 | # If true, show URL addresses after external links. 264 | #man_show_urls = False 265 | 266 | 267 | # -- Options for Texinfo output ------------------------------------------- 268 | 269 | # Grouping the document tree into Texinfo files. List of tuples 270 | # (source start file, target name, title, author, 271 | # dir menu entry, description, category) 272 | texinfo_documents = [ 273 | (master_doc, 'MathswithPython', 'Maths with Python Documentation', 274 | author, 'MathswithPython', 'One line description of project.', 275 | 'Miscellaneous'), 276 | ] 277 | 278 | # Documents to append as an appendix to all manuals. 279 | #texinfo_appendices = [] 280 | 281 | # If false, no module index is generated. 282 | #texinfo_domain_indices = True 283 | 284 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 285 | #texinfo_show_urls = 'footnote' 286 | 287 | # If true, do not generate a @detailmenu in the "Top" node's menu. 288 | #texinfo_no_detailmenu = False 289 | 290 | 291 | # -- Options for Epub output ---------------------------------------------- 292 | 293 | # Bibliographic Dublin Core info. 294 | epub_title = project 295 | epub_author = author 296 | epub_publisher = author 297 | epub_copyright = copyright 298 | 299 | # The basename for the epub file. It defaults to the project name. 300 | #epub_basename = project 301 | 302 | # The HTML theme for the epub output. Since the default themes are not 303 | # optimized for small screen space, using the same theme for HTML and epub 304 | # output is usually not wise. This defaults to 'epub', a theme designed to save 305 | # visual space. 306 | #epub_theme = 'epub' 307 | 308 | # The language of the text. It defaults to the language option 309 | # or 'en' if the language is not set. 310 | #epub_language = '' 311 | 312 | # The scheme of the identifier. Typical schemes are ISBN or URL. 313 | #epub_scheme = '' 314 | 315 | # The unique identifier of the text. This can be a ISBN number 316 | # or the project homepage. 317 | #epub_identifier = '' 318 | 319 | # A unique identification for the text. 320 | #epub_uid = '' 321 | 322 | # A tuple containing the cover image and cover page html template filenames. 323 | #epub_cover = () 324 | 325 | # A sequence of (type, uri, title) tuples for the guide element of content.opf. 326 | #epub_guide = () 327 | 328 | # HTML files that should be inserted before the pages created by sphinx. 329 | # The format is a list of tuples containing the path and title. 330 | #epub_pre_files = [] 331 | 332 | # HTML files that should be inserted after the pages created by sphinx. 333 | # The format is a list of tuples containing the path and title. 334 | #epub_post_files = [] 335 | 336 | # A list of files that should not be packed into the epub file. 337 | epub_exclude_files = ['search.html'] 338 | 339 | # The depth of the table of contents in toc.ncx. 340 | #epub_tocdepth = 3 341 | 342 | # Allow duplicate toc entries. 343 | #epub_tocdup = True 344 | 345 | # Choose between 'default' and 'includehidden'. 346 | #epub_tocscope = 'default' 347 | 348 | # Fix unsupported image types using the Pillow. 349 | #epub_fix_images = False 350 | 351 | # Scale large images. 352 | #epub_max_image_width = 0 353 | 354 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 355 | #epub_show_urls = 'inline' 356 | 357 | # If false, no index is generated. 358 | #epub_use_index = True 359 | -------------------------------------------------------------------------------- /full-title.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'basic.tpl' -%} 2 | {% from 'mathjax.tpl' import mathjax %} 3 | 4 | 5 | {%- block header -%} 6 | 7 | 8 | 9 | {%- block html_head -%} 10 | 11 | {{nb.metadata.get('nbconvert', {}).get('title', resources.metadata.name)}} 12 | 13 | 14 | 15 | 16 | {% for css in resources.inlining.css -%} 17 | 20 | {% endfor %} 21 | 22 | 49 | 50 | 51 | 52 | 53 | 54 | {{ mathjax() }} 55 | {%- endblock html_head -%} 56 | 57 | {%- endblock header -%} 58 | 59 | {% block body %} 60 | 61 |
62 |
63 | {{ super() }} 64 |
65 |
66 | 67 | {%- endblock body %} 68 | 69 | {% block footer %} 70 | 71 | {% endblock footer %} 72 | -------------------------------------------------------------------------------- /images/spyder-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/images/spyder-1.png -------------------------------------------------------------------------------- /images/spyder-py3-reduced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/images/spyder-py3-reduced.png -------------------------------------------------------------------------------- /images/spyder-py3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/images/spyder-py3.png -------------------------------------------------------------------------------- /index.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Python for mathematicians" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This repository is for a course at Southampton University given in the first year, first semester, to introduce mathematics undergraduate students to programming using Python. The expected audience affects the presentation and particularly the exercises.\n", 15 | "\n", 16 | "The [opening notebook](00-first-steps.ipynb), mostly introduces how to install the software, and how to think about the course.\n", 17 | "\n", 18 | "The essential sections of the course are on\n", 19 | "\n", 20 | "* [the basics](01-python-basics.ipynb)\n", 21 | "* [functions and programs](02-programs.ipynb)\n", 22 | "* [loops and control flow](03-loops-control-flow.ipynb)\n", 23 | "* [basic plotting](04-basic-plotting.ipynb).\n", 24 | "\n", 25 | "The [next notebook introduces classes](05-classes-oop.ipynb), which should at least be started to get the most out of the rest. We then have three important sections on\n", 26 | "\n", 27 | "* [scientific Python](06-numpy-plotting.ipynb)\n", 28 | "* [symbolic Python](07-sympy.ipynb)\n", 29 | "* [statistics](08-statistics.ipynb).\n", 30 | "\n", 31 | "Finally, there are three \"appendices\" on\n", 32 | "\n", 33 | "* [testing](09-exceptions-testing.ipynb)\n", 34 | "* [generators](10-generators.ipynb)\n", 35 | "* [more details on classes, including inheritance](11-more-classes.ipynb)." 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "For issues or modifications, please raise them on [the github repository](https://github.com/IanHawke/maths-with-python)." 43 | ] 44 | } 45 | ], 46 | "metadata": { 47 | "kernelspec": { 48 | "display_name": "Python 3", 49 | "language": "python", 50 | "name": "python3" 51 | }, 52 | "language_info": { 53 | "codemirror_mode": { 54 | "name": "ipython", 55 | "version": 3 56 | }, 57 | "file_extension": ".py", 58 | "mimetype": "text/x-python", 59 | "name": "python", 60 | "nbconvert_exporter": "python", 61 | "pygments_lexer": "ipython3", 62 | "version": "3.4.4" 63 | } 64 | }, 65 | "nbformat": 4, 66 | "nbformat_minor": 0 67 | } 68 | -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | .. Maths with Python documentation master file, created by 2 | sphinx-quickstart on Tue Mar 8 10:22:01 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Maths with Python 7 | ================= 8 | 9 | This is material for an introductory Python course for first year undergraduate Mathematics students at the University of Southampton. 10 | 11 | First Steps 12 | =========== 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | 00-first-steps 18 | 19 | Python Basics 20 | ============= 21 | 22 | .. toctree:: 23 | :maxdepth: 2 24 | 25 | 01-python-basics 26 | 27 | Programs 28 | ======== 29 | 30 | .. toctree:: 31 | :maxdepth: 2 32 | 33 | 02-programs 34 | 35 | Loops - how to repeat yourself 36 | ============================== 37 | 38 | .. toctree:: 39 | :maxdepth: 2 40 | 41 | 03-loops-control-flow 42 | 43 | Basic Plotting 44 | ============== 45 | 46 | .. toctree:: 47 | :maxdepth: 2 48 | 49 | 04-basic-plotting 50 | 51 | Classes and objects 52 | =================== 53 | 54 | .. toctree:: 55 | :maxdepth: 2 56 | 57 | 05-classes-oop 58 | 59 | Scientific Python 60 | ================= 61 | 62 | .. toctree:: 63 | :maxdepth: 2 64 | 65 | 06-numpy-plotting 66 | 67 | Symbolic Python 68 | =============== 69 | 70 | .. toctree:: 71 | :maxdepth: 2 72 | 73 | 07-sympy 74 | 75 | Statistics 76 | ========== 77 | 78 | .. toctree:: 79 | :maxdepth: 2 80 | 81 | 08-statistics 82 | 83 | Exceptions and Testing 84 | ====================== 85 | 86 | .. toctree:: 87 | :maxdepth: 2 88 | 89 | 09-exceptions-testing 90 | 91 | Iterators and Generators 92 | ======================== 93 | 94 | .. toctree:: 95 | :maxdepth: 2 96 | 97 | 10-generators 98 | 99 | Classes and OOP 100 | =============== 101 | 102 | .. toctree:: 103 | :maxdepth: 2 104 | 105 | 11-more-classes 106 | 107 | Indices and tables 108 | ================== 109 | 110 | * :ref:`search` 111 | -------------------------------------------------------------------------------- /lab1_basic.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 09:12:34 2015 4 | 5 | @author: ih3 6 | """ 7 | 8 | import math 9 | x = math.sin(1.2) 10 | -------------------------------------------------------------------------------- /lab1_function.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 11:12:44 2015 4 | 5 | @author: ih3 6 | """ 7 | 8 | from math import pi 9 | 10 | def degrees_to_radians(theta_d): 11 | """ 12 | Convert an angle from degrees to radians. 13 | 14 | Parameters 15 | ---------- 16 | 17 | theta_d : float 18 | The angle in degrees. 19 | 20 | Returns 21 | ------- 22 | 23 | theta_r : float 24 | The angle in radians. 25 | """ 26 | theta_r = pi / 180.0 * theta_d 27 | return theta_r 28 | -------------------------------------------------------------------------------- /lab1_import.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 09:18:43 2015 4 | 5 | @author: ih3 6 | """ 7 | 8 | import lab1_basic 9 | print(lab1_basic.x) -------------------------------------------------------------------------------- /lab1_use_function.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 11:15:58 2015 4 | 5 | @author: ih3 6 | """ 7 | 8 | from lab1_function import degrees_to_radians 9 | 10 | print(degrees_to_radians(15.0)) 11 | print(degrees_to_radians(30.0)) 12 | print(degrees_to_radians(45.0)) 13 | print(degrees_to_radians(60.0)) 14 | print(degrees_to_radians(75.0)) 15 | print(degrees_to_radians(90.0)) 16 | -------------------------------------------------------------------------------- /latex/BasicLatex.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/latex/BasicLatex.pdf -------------------------------------------------------------------------------- /latex/BasicLatex.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper]{article} 2 | 3 | \begin{document} 4 | 5 | This is a basic document. 6 | 7 | See 8 | how 9 | the 10 | effect of different spacings 11 | 12 | works; or not? 13 | 14 | \textbf{Note the use} of \textit{different} \texttt{styles} of 15 | text. Use them \textsc{as little} as possible. 16 | 17 | Note also 18 | \begin{itemize} 19 | \item how anything ``special'' starts ``\verb|\|'', 20 | \item how quote characters behave (compare with ''this''), 21 | \item how curly braces \verb|{| and \verb|}| are used without 22 | appearing, 23 | \item and how \emph{environments} always \verb|\begin| and 24 | \verb|\end|. 25 | \end{itemize} 26 | 27 | 28 | \section{Sections split up your document} 29 | \label{sec:TopSection} 30 | 31 | 32 | \subsection{Subsections are also useful} 33 | \label{sec:SubSection} 34 | 35 | Note that different \LaTeX\ classes (\texttt{article}, \texttt{book}, 36 | etc.) allow for different sectioning commands. 37 | 38 | 39 | \end{document} 40 | -------------------------------------------------------------------------------- /latex/BasicLatexBibtex.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper]{article} 2 | 3 | \begin{document} 4 | 5 | 6 | \section{Sections split up your document} 7 | \label{sec:TopSection} 8 | 9 | 10 | \subsection{Subsections are also useful} 11 | \label{sec:SubSection} 12 | 13 | Note that different \LaTeX\ classes (\texttt{article}, \texttt{book}, 14 | etc.) allow for different sectioning commands. 15 | 16 | 17 | \subsection{Another subsection} 18 | \label{sec:SubSection2} 19 | 20 | \LaTeX is very good at cross-referencing; the ``discussion'' of 21 | different sectioning commands occurred in section~\ref{sec:SubSection} 22 | on page~\pageref{sec:SubSection}. 23 | 24 | 25 | \section{Mathematics} 26 | \label{sec:Maths} 27 | 28 | Mathematics can be included inline, as in $x = y$, or in displayed 29 | equations such as 30 | % 31 | \begin{equation} 32 | \label{eq:TaylorThm} 33 | f(x) = f(c) + f'(c) (x - c) + \frac{f''(c)}{2!} (x - c)^2 + \ldots + 34 | \frac{f^{(n)}(c)}{n!} (x - c)^n + \ldots 35 | \end{equation} 36 | % 37 | The advantage of the displayed equation is that it can be 38 | cross-referenced; that was equation~\ref{eq:TaylorThm}. 39 | 40 | \subsection{Bibliographies} 41 | \label{sec:BibTeX} 42 | 43 | 44 | Nearly everybody wants to cite other work, such as~\cite{godunov}. 45 | 46 | \bibliographystyle{plain} 47 | \bibliography{nummeth} 48 | 49 | \end{document} 50 | 51 | 52 | %%% Local Variables: 53 | %%% mode: latex 54 | %%% TeX-master: t 55 | %%% End: 56 | -------------------------------------------------------------------------------- /latex/BasicLatexBibtex_pass1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/latex/BasicLatexBibtex_pass1.pdf -------------------------------------------------------------------------------- /latex/BasicLatexBibtex_pass2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/latex/BasicLatexBibtex_pass2.pdf -------------------------------------------------------------------------------- /latex/BasicLatexBibtex_pass3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/latex/BasicLatexBibtex_pass3.pdf -------------------------------------------------------------------------------- /latex/nummeth.bib: -------------------------------------------------------------------------------- 1 | @string{ JCP = {J. Comput. Phys.}} 2 | @string{ JFM = {J. Fluid Mech.}} 3 | @string{ CMP = {Comm. Math. Phys.}} 4 | @string{ ApJ = {Astrophysical Journal}} 5 | @string{ PR = {Phys. Rev.}} 6 | @string{ CQG = {Classical Quantum Gravity}} 7 | @string{ SSciCom = {SIAM J. Sci. Comput.}} 8 | 9 | @Book{artvis3, 10 | author = {J.D.~Anderson}, 11 | title = {{C}omputational {F}luid {D}ynamics - the {B}asics with {A}pplications}, 12 | publisher = {{M}c{G}raw-{H}ill}, 13 | year = {1995}, 14 | OPTkey = {}, 15 | OPTeditor = {}, 16 | OPTvolume = {}, 17 | OPTnumber = {}, 18 | OPTseries = {}, 19 | OPTaddress = {}, 20 | OPTedition = {}, 21 | OPTmonth = {}, 22 | OPTnote = {}, 23 | OPTannote = {} 24 | } 25 | 26 | 27 | @Article{semico, 28 | author = {A.M.~Anile and N.~Nikiforakis and R.M.~Pidatella}, 29 | title = {Assessment of a high resolution centred scheme for 30 | the solution of hydrodynamical semiconductor equations.}, 31 | journal = SSciCom, 32 | year = {2000}, 33 | OPTkey = {}, 34 | volume = {{\bf 22}}, 35 | number = {5}, 36 | OPTmonth = {}, 37 | pages = {1533-1548}, 38 | OPTnote = {}, 39 | OPTannote = {} 40 | } 41 | 42 | 43 | @Unpublished{hern, 44 | author = {S.D.~Hern and A.M.~Anile and N.~Nikiforakis}, 45 | title = {A mesh refinement approach for hydrodynamical 46 | semiconductor simulations}, 47 | note = {(submitted to JCP)}, 48 | OPTkey = {}, 49 | OPTyear = {}, 50 | OPTmonth = {}, 51 | OPTannote = {} 52 | } 53 | 54 | @Article{benartzi, 55 | author = {M.~Ben-Artzi}, 56 | title = {{A}pplication of the {G}eneralised {R}iemann {P}roblem {M}ethod to 1-{D} compressible flows with {I}nterfaces}, 57 | journal = JCP, 58 | year = {1986}, 59 | OPTkey = {}, 60 | volume = {{\bf 65}}, 61 | OPTnumber = {}, 62 | OPTmonth = {}, 63 | pages = {170}, 64 | OPTnote = {}, 65 | OPTannote = {} 66 | } 67 | 68 | @Book{artvis3, 69 | author = {J.D.~Anderson}, 70 | title = {{C}omputational {F}luid {D}ynamics - 71 | the {B}asics with {A}pplications}, 72 | publisher = {{M}c{G}raw-{H}ill}, 73 | year = {1995}, 74 | OPTkey = {}, 75 | OPTeditor = {}, 76 | OPTvolume = {}, 77 | OPTnumber = {}, 78 | OPTseries = {}, 79 | OPTaddress = {}, 80 | OPTedition = {}, 81 | OPTmonth = {}, 82 | OPTnote = {}, 83 | OPTannote = {} 84 | } 85 | 86 | 87 | @Article{benartzi, 88 | author = {M.~Ben-Artzi}, 89 | title = {{A}pplication of the {G}eneralised 90 | {R}iemann {P}roblem {M}ethod to 1-{D} compressible flows with {I}nterfaces}, 91 | journal = JCP, 92 | year = {1986}, 93 | OPTkey = {}, 94 | volume = {{\bf 65}}, 95 | OPTnumber = {}, 96 | OPTmonth = {}, 97 | pages = {170}, 98 | OPTnote = {}, 99 | OPTannote = {} 100 | } 101 | 102 | @Article{bergol, 103 | author = {M.J.~Berger and J.~Oliger}, 104 | title = {{A}daptive {M}esh {R}efinement for {H}yperbolic {P}artial 105 | {D}ifferential {E}quations}, 106 | journal = JCP, 107 | year = {1984}, 108 | OPTkey = {}, 109 | volume = {{\bf 53}}, 110 | OPTnumber = {}, 111 | OPTmonth = {}, 112 | pages = {484--512}, 113 | OPTnote = {}, 114 | OPTannote = {} 115 | } 116 | 117 | @Article{ppm, 118 | author = {P.~Colella and P.R.~Woodward}, 119 | title = {{T}he {P}iecewise-{P}arabolic 120 | {M}ethod ({PPM}) for {G}as-{D}ynamics}, 121 | journal = JCP, 122 | year = {1984}, 123 | OPTkey = {}, 124 | volume = {{\bf 54}}, 125 | OPTnumber = {}, 126 | OPTmonth = {}, 127 | pages = {174}, 128 | OPTnote = {}, 129 | OPTannote = {} 130 | } 131 | 132 | @Article{godunov, 133 | author = {S.~Godunov}, 134 | title = {{F}inite {D}ifference {M}ethod for {N}umerical 135 | {C}omputation of {D}iscontinuous {S}olutions of the {E}quations of {F}luid 136 | {D}ynamics}, 137 | journal = {Mat.~Sbornik}, 138 | year = {1959}, 139 | OPTkey = {}, 140 | volume = {{\bf 47}}, 141 | OPTnumber = {89}, 142 | OPTmonth = {}, 143 | pages = {3--271}, 144 | OPTnote = {}, 145 | OPTannote = {} 146 | } 147 | 148 | @Article{eno, 149 | author = {A.~Harten and S.~Osher}, 150 | title = {{U}niformly {H}igh-{O}rder {A}ccurate 151 | {N}onoscillatory {S}chemes {I}}, 152 | journal = {{SIAM} Journal of Numerical Analysis}, 153 | year = {1987}, 154 | OPTkey = {}, 155 | volume = {{\bf 24}}, 156 | OPTnumber = {}, 157 | OPTmonth = {}, 158 | pages = {279}, 159 | OPTnote = {}, 160 | OPTannote = {} 161 | } 162 | 163 | @Article{clawpack, 164 | author = {R.J.~LeVeque}, 165 | title = {Wave propagation algorithms for 166 | multi-dimensional hyperbolic systems}, 167 | journal = JCP, 168 | year = {1997}, 169 | OPTkey = {}, 170 | volume = {{\bf 131}}, 171 | OPTnumber = {}, 172 | OPTmonth = {}, 173 | pages = {327--353}, 174 | OPTnote = {}, 175 | OPTannote = {} 176 | } 177 | 178 | @InCollection{leveque1, 179 | author = {R.J.~LeVeque}, 180 | title = {{N}onlinear {C}onservation {L}aws and 181 | {F}inite {V}olume {M}ethods for {A}strophysical {F}luid {F}low}, 182 | booktitle = {{C}omputational {M}ethods for {A}strophysical 183 | {F}luid {F}low}, 184 | OPTcrossref = {}, 185 | OPTkey = {}, 186 | publisher = {Springer-Verlag}, 187 | year = {1998}, 188 | editor = {O.~Steiner and A.~Gautschy}, 189 | OPTvolume = {}, 190 | OPTnumber = {}, 191 | OPTseries = {}, 192 | OPTchapter = {}, 193 | OPTtype = {}, 194 | OPTaddress = {}, 195 | OPTedition = {}, 196 | OPTmonth = {}, 197 | OPTpages = {}, 198 | OPTnote = {}, 199 | OPTannote = {} 200 | } 201 | 202 | @Article{srcbal, 203 | author = {R.J.~LeVeque}, 204 | title = {{B}alancing {S}ource {T}erms and {F}lux 205 | {G}radients in {H}igh-{R}esolution {G}odunov {M}ethods: {T}he 206 | {Q}uasi-{S}teady {W}ave-{P}ropagation {A}lgorithm}, 207 | journal = JCP, 208 | year = {1998}, 209 | OPTkey = {}, 210 | volume = {{\bf 146}}, 211 | OPTnumber = {}, 212 | OPTmonth = {}, 213 | pages = {346--365}, 214 | OPTnote = {}, 215 | OPTannote = {} 216 | } 217 | 218 | @Article{sph, 219 | author = {J.~Monaghan}, 220 | title = {{S}moothed {P}article {H}ydrodynamics}, 221 | journal = {{A}nnual {R}eview of {A}stronomy and {A}strophysics}, 222 | year = {1992}, 223 | OPTkey = {}, 224 | volume = {{\bf 30}}, 225 | OPTnumber = {}, 226 | OPTmonth = {}, 227 | pages = {543}, 228 | OPTnote = {}, 229 | OPTannote = {} 230 | } 231 | 232 | @Article{artvis1, 233 | author = {J.~von~Neumann and R.D.~Richtmyer}, 234 | title = {??}, 235 | journal = {Journal of Applied Physics}, 236 | year = {1950}, 237 | OPTkey = {}, 238 | volume = {{\bf 21}}, 239 | OPTnumber = {}, 240 | OPTmonth = {}, 241 | pages = {232}, 242 | OPTnote = {}, 243 | OPTannote = {} 244 | } 245 | 246 | @Book{numrec, 247 | author = {W.H.~Press and S.A.~Teukolsky and W.T.~Vetterling and B.P.~Flannery}, 248 | title = {{N}umerical {R}ecipes in {F}ortran 77: {T}he {A}rt of 249 | {S}cientific {C}omputing}, 250 | publisher = {Cambridge {U}niversity {P}ress}, 251 | year = {1986}, 252 | OPTkey = {}, 253 | OPTeditor = {}, 254 | OPTvolume = {}, 255 | OPTnumber = {}, 256 | OPTseries = {}, 257 | OPTaddress = {}, 258 | OPTedition = {}, 259 | OPTmonth = {}, 260 | OPTnote = {}, 261 | OPTannote = {} 262 | } 263 | 264 | @Book{artvis2, 265 | author = {R.D.~Richtmyer and K.W.~Morton}, 266 | title = {{D}ifference {M}ethods for initial value problems}, 267 | publisher = {Interscience}, 268 | year = {1967}, 269 | OPTkey = {}, 270 | OPTeditor = {}, 271 | OPTvolume = {}, 272 | OPTnumber = {}, 273 | OPTseries = {}, 274 | OPTaddress = {}, 275 | OPTedition = {}, 276 | OPTmonth = {}, 277 | OPTnote = {}, 278 | OPTannote = {} 279 | } 280 | 281 | @InCollection{toro2, 282 | author = {E.F.~Toro}, 283 | title = {{P}rimitive, {C}onservative and {A}daptive 284 | {S}chemes for {H}yperbolic {C}onservation {L}aws}, 285 | booktitle = {{N}umerical {M}ethods 286 | for {W}ave {P}ropagation}, 287 | OPTcrossref = {}, 288 | OPTkey = {}, 289 | publisher = {Kluwer}, 290 | year = {1998}, 291 | editor = {E.F.~Toro and C.~Clarke}, 292 | OPTvolume = {}, 293 | OPTnumber = {}, 294 | OPTseries = {}, 295 | OPTchapter = {}, 296 | OPTtype = {}, 297 | OPTaddress = {}, 298 | OPTedition = {}, 299 | OPTmonth = {}, 300 | OPTpages = {}, 301 | OPTnote = {}, 302 | OPTannote = {} 303 | } 304 | 305 | @TechReport{toroprim, 306 | author = {E.F.~Toro}, 307 | title = {Defects of {C}onservative {M}ethods and 308 | {A}daptive {P}rimitive-{C}onservative {S}chemes for {C}omputing 309 | {S}olutions to {H}yperbolic {C}onservation {L}aws}, 310 | institution = {Manchester Metropolitan University}, 311 | year = {1994}, 312 | OPTkey = {}, 313 | OPTtype = {}, 314 | number = {MMU-9401}, 315 | OPTaddress = {}, 316 | OPTmonth = {}, 317 | OPTnote = {}, 318 | OPTannote = {} 319 | } 320 | 321 | @Article{blastwave, 322 | author = {P.~Woodward and P.~Colella}, 323 | title = {The numerical 324 | simulation of two-dimensional flow with strong shock waves}, 325 | journal = JCP, 326 | year = {1984}, 327 | OPTkey = {}, 328 | volume = {{\bf 54}}, 329 | OPTnumber = {}, 330 | OPTmonth = {}, 331 | pages = {115--173}, 332 | OPTnote = {}, 333 | OPTannote = {} 334 | } 335 | 336 | @Book{Korn, 337 | author = {T.W.~K{\"{o}}rner}, 338 | title = {The Pleasures of Counting}, 339 | publisher = {Cambridge University Press}, 340 | year = {1996}, 341 | OPTkey = {}, 342 | OPTeditor = {}, 343 | OPTvolume = {}, 344 | OPTnumber = {}, 345 | OPTseries = {}, 346 | OPTaddress = {}, 347 | OPTedition = {}, 348 | OPTmonth = {}, 349 | OPTnote = {}, 350 | OPTannote = {} 351 | } 352 | 353 | @Unpublished{primslic, 354 | author = {I.~Hawke and N.~Nikiforakis}, 355 | title = {A generalisation of 356 | {T}oro's {S}lope {L}imited {C}entred {S}cheme}, 357 | note = {in preparation}, 358 | OPTkey = {}, 359 | OPTyear = {}, 360 | OPTmonth = {}, 361 | OPTannote = {} 362 | } 363 | 364 | @Article{sod, 365 | author = {G.A.~Sod}, 366 | title = {A {S}urvey of {S}everal {F}inite--{D}ifference {M}ethods 367 | for {S}ystems of {N}onlinear {H}yperbolic {C}onservation {L}aws}, 368 | journal = JCP, 369 | year = {1978}, 370 | OPTkey = {}, 371 | volume = {{\bf 27}}, 372 | OPTnumber = {}, 373 | OPTmonth = {}, 374 | pages = {1--31}, 375 | OPTnote = {}, 376 | OPTannote = {} 377 | } 378 | 379 | @Article{tslic, 380 | author = {E.F. Toro and S.J. Billet}, 381 | title = {Centred {TVD} schemes for hyperbolic conservation laws}, 382 | journal = {IMA J. Numer. Anal.}, 383 | year = {2000}, 384 | OPTkey = {}, 385 | volume = {{\bf 20}}, 386 | OPTnumber = {}, 387 | OPTmonth = {}, 388 | pages = {47--79}, 389 | OPTnote = {}, 390 | OPTannote = {} 391 | } 392 | 393 | -------------------------------------------------------------------------------- /latex_chapter.tex: -------------------------------------------------------------------------------- 1 | \begin{chapter}{\LaTeX} 2 | 3 | Producing high quality mathematical documents that show equations, figures and references clearly is very difficult in standard word processing packages. Instead the standard is to use \LaTeX, a ``document prepartion language''. Most notes, such as these, and mathematical papers, use \LaTeX. 4 | 5 | \section{What is \LaTeX} 6 | 7 | \LaTeX\ takes a plain text file and converts it into a document, often in PDF format, containing all the equations, figures and cross-references. In this sense it's similar to Python: you start from a plain text file and \emph{build} it to produce a result. 8 | 9 | \LaTeX\ documents are often complex, but many are available online. A standard technique is to find a \LaTeX document that does what you want online, and take the key commands from that. 10 | 11 | \section{Installing or finding} 12 | \label{sec:installing} 13 | 14 | \LaTeX\ is free software and there's lots of available implementations. As with Python, a \LaTeX\ document is plain text and can be written using any text editor. However, specific \LaTeX\ editors can help in rapidly writing documents with fewer errors. 15 | 16 | \subsection{University machines} 17 | 18 | Use the search function to look for \texttt{TeXnicCentre}. When first running, choose all the default options. Some of the instructions below on building a document are specific to TeXnicCentre, as it's provided on the university machines, but similar methods should work in all editors. 19 | 20 | \subsection{Personal machines} 21 | 22 | If using a Linux or Mac, \LaTeX\ should be installed automatically. There are many editors you can use -- \href{http://www.xm1math.net/texmaker/}{TeXMaker} is one example -- and you can experiment with which you prefer. If using a Windows machine, you can freely download \href{http://www.texniccenter.org/}{TeXnicCentre} which will install \LaTeX\ for you, or use TeXMaker as above. 23 | 24 | \subsection{Online} 25 | 26 | There are browser-based \LaTeX\ editors which can be used, such as \href{https://www.overleaf.com/}{Overleaf} and \href{https://www.sharelatex.com/}{ShareLaTeX}. There are obvious advantages -- there's no need to install anything, it's backed up externally, and it builds the document for you. The balancing disadvantages are also there -- needs a network connection, the online editor isn't as full featured as special desktop versions, and keeping your work private requires paying. 27 | 28 | Overleaf also \href{https://www.overleaf.com/latex/learn/free-online-introduction-to-latex-part-1}{hosts an online tutorial on \LaTeX} that works through the essential points. 29 | 30 | \subsection{\LaTeX\ in other formats} 31 | 32 | A full \LaTeX\ document can be very complex as it controls \emph{every} aspect of the document appearance. Many simpler document formats have been written, often based around \href{http://daringfireball.net/projects/markdown/}{Markdown} (see also \href{https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet}{this cheatsheet}). To typeset mathematics within these document formats, \LaTeX\ \emph{syntax} is used: one particular example is \href{https://www.authorea.com}{Authorea} where a simple Markdown-based document format can be mixed with \LaTeX\ syntax to create documents both for online and offline use. We have already seen how \LaTeX\ syntax can be used within, e.g., \texttt{matplotlib}. 33 | 34 | \section{Getting Started} 35 | 36 | \subsection{A basic document} 37 | 38 | Download a simple \LaTeX\ document \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/BasicLatex.tex}{from this link}. Open it in whichever editor you are using, and build it so you can see the output (which should look like \href{https://github.com/IanHawke/maths-with-python/raw/master/latex/BasicLatex.pdf}{this pdf file}). If using TeXnicCentre on the University machines, you should be able to do this by running ``Build and View'' from the ``Build'' menu. 39 | 40 | You should compare the document with the built PDF file. In particular note, as stated in the document, 41 | % 42 | \begin{itemize} 43 | \item that anything before the ``\verb|\begin{document}|'' (the \emph{preamble}) doesn't show explicitly, but changes global properties of the document, 44 | \item how whitespace works, 45 | \item how anything ``special'' starts ``\verb|\|'', 46 | \item how quote characters behave (compare with ''this''), 47 | \item how curly braces \verb|{| and \verb|}| are used without 48 | appearing, 49 | \item how \emph{environments} always \verb|\begin| and 50 | \verb|\end|, 51 | \item and how the \verb|\section| command works. 52 | \end{itemize} 53 | % 54 | You should edit and re-build the document so that you can see the effects of adding standard text, new sections (or subsections), and so on. 55 | 56 | \subsection{Mathematics and references} 57 | 58 | Now download \emph{both} \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/BasicLatexBibtex.tex}{this \LaTeX\ document} and \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/nummeth.bib}{this bibliography file}. The bibliography file must be saved in the same directory as the \LaTeX\ document, must have a \texttt{.bib} extension, and (in this case) should be called \texttt{nummeth.bib}. Again, build this document and view the results. 59 | 60 | \subsubsection{The build process} 61 | 62 | Some editors will (or will let you) build the document one step at a time. In this case you may have perform multiple build steps. For example, the first build step will produce a document that \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/BasicLatexBibtex_pass1.pdf}{looks like this}. At this point none of the cross-references are correct, but appear as ``\textbf{?}'', and there is no bibliography. The second build step will create the bibliography, but will not change the document. The third build step will produce a document that \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/BasicLatexBibtex_pass2.pdf}{looks like this}. At this point cross-references to sections and equations are correct, and the bibliography is included. However, the cross-references to the bibliography are not correct. A fourth build step will produce a document that \href{https://raw.githubusercontent.com/IanHawke/maths-with-python/master/latex/BasicLatexBibtex_pass3.pdf}{looks like this}, with all references correct. 63 | 64 | \subsubsection{Mathematics} 65 | 66 | To include mathematical notation inline, commands should be placed between dollar signs, \verb|$...$|, so that \verb|$\pi$| gives $\pi$. To create a \emph{displayed} equation, use the \texttt{equation} environment, as in 67 | % 68 | \begin{verbatim} 69 | \begin{equation} 70 | \label{eq:label_example} 71 | x = y + z. 72 | \end{equation} 73 | \end{verbatim} 74 | % 75 | which gives 76 | % 77 | \begin{equation} 78 | \label{eq:label_example} 79 | x = y + z. 80 | \end{equation} 81 | % 82 | Note that the ``\verb|\label{...}|'' command allows the equation to be cross-referenced using the ``\verb|\ref{...}|'' command, giving equation \ref{eq:label_example}. 83 | 84 | As seen above, Greek characters in mathematics are the letter preceded by the backslash, so \verb|$\theta$| gives $\theta$. To produce subscripts, use the underscore \verb|_|, and for superscripts the caret \verb|^|. So \verb|$x_1^2$| gives $x_1^2$. To group characters together, use the curly braces \verb|{}|. You need to do this, for example, if you want more than one character to appear in sub- or superscripts. Hence \verb|$F_n-2$| gives $F_n-2$, but \verb|$F_{n-2}$| gives $F_{n-2}$. 85 | 86 | Standard mathematical commands and symbols are also preceded by backslashes, such as \verb|$\int$| ($\int$), \verb|$\sum$| ($\sum$), and \verb|$\infty$| ($\infty$). A more complete list \href{https://en.wikibooks.org/wiki/LaTeX/Mathematics}{can be found online}, and for more obscure symbols the online \href{http://detexify.kirelabs.org/classify.html}{handwriting recognition trick} is very useful. 87 | 88 | \subsection{Cross-referencing and bibliographies} 89 | 90 | We saw above how the \texttt{equation} environment could include a \verb|\label| which allowed it to be cross-referenced using the \verb|\ref| command. This can be done for any environment which takes a number; for example, the section on installing \LaTeX\ above has the label \verb|\label{sec:installing}|, and can be cross-referenced using \verb|\ref{sec:installing}|, giving section~\ref{sec:installing}. 91 | 92 | For citing references -- books, papers, websites etc.\ -- we instead use the \verb|\cite| command. This looks for the article within the \emph{Bibtex} file that has the specific \emph{key}. In the document here, the command \verb|\cite{godunov}| tells \LaTeX\ that the key is ``\verb|godunov|'', and the command \verb|\bibliography{nummeth}| tells it that the Bibtex file is in \texttt{nummeth.bib}. 93 | 94 | The structure of the Bibtex file can look complex. There are many shortcuts -- for example, by searching for the reference on Google Scholar, and then clicking on the ``Cite'' link, it will give the Bibtex entry that you can simply copy and paste into your file. For alternatives, see section~\ref{sec:Citations}. 95 | 96 | 97 | \LaTeX\ is most useful for creating long documents (journal articles, theses, etc.) containing substantial mathematics. Sectioning, cross-referencing and bibliographies we have already seen. There are a number of additional features to make the creation of long documents easier. 98 | 99 | These are gathered in a logical order below, but for most purposes the discussion of commands (section~\ref{sec:commands}), provided packages (section~\ref{sec:packages_provided}), and modularity (section~\ref{sec:modularity}) will be of most use. 100 | 101 | \section{Commands} 102 | \label{sec:commands} 103 | 104 | \subsection{Defining commands} 105 | \label{sec:commands_defn} 106 | 107 | Firstly, user-defined commands can replace long sequences with a short, or more memorable, version. For example, a simple partial derivative 108 | % 109 | \begin{equation} 110 | \label{eq:example_pd_1} 111 | \frac{\partial y}{\partial x} 112 | \end{equation} 113 | % 114 | can be written \verb|\frac{\partial y}{\partial x}|. The equivalent shorthand 115 | % 116 | \begin{equation} 117 | \label{eq:example_pd_2} 118 | \pda{y}{x} 119 | \end{equation} 120 | % 121 | can be written, for example, \verb|\pda{y}{x}|. This is both clearer and shorter. 122 | 123 | The command \verb|\pda| is defined in the \emph{document preamble}: after the \verb|\documentclass| command but before the \verb|\begin{document}| statement. The definition used here is 124 | % 125 | \begin{center} 126 | \verb|\newcommand{\pda}[2]{\frac{\partial {#1}}{\partial {#2}}}| 127 | \end{center} 128 | % 129 | which requires some explanation: 130 | \begin{itemize} 131 | \item Obviously \verb|\newcommand{\pda}| defines the new command 132 | \verb|\pda|. 133 | \item The statement \verb|[2]| says that the command has two arguments 134 | (in the example \verb|\pda{y}{x}| the arguments are \verb|y| and 135 | \verb|x| respectively). For commands that take no arguments (e.g.\ 136 | where you are just defining a shorthand, such as the command 137 | \verb|\uos| defined at the start of this document which expands to 138 | \uos) this part is absent. 139 | \item The rest of the line defines the command, and is enclosed in 140 | braces \verb|{...}| for safety. The arguments are referred to by the 141 | \verb|#| statements; e.g., in the example above \verb|#1| 142 | corresponds to \verb|y| and \verb|#2| to \verb|x|. Again, the 143 | arguments are typically enclosed in braces \verb|{...}| for safety. 144 | \end{itemize} 145 | 146 | \subsection{Redefining commands} 147 | \label{sec:commands_redefn} 148 | 149 | Sometimes a command already exists with the shorthand name that you want to use, but does not do what you expect or want. In this case it can be redefined using the command \verb|\renewcommand|. This works in exactly the same way as \verb|\newcommand|, except the command must already exist (note that if the command already exists then trying to (re)define it with \verb|\newcommand| will give an error). 150 | 151 | The classic example is typesetting vectors using the \LaTeX\ command \verb|\vec|. By default this puts an arrow above the argument, similar to (but smaller than) the command \verb|\overrightarrow| which produces, e.g., $\overrightarrow{AB}$. Many people typeset vectors use bold fonts, which can be done using e.g.\ 152 | % 153 | \begin{center} 154 | \verb|\renewcommand{\vec}[1]{\mathbf{#1}}| 155 | \end{center} 156 | % 157 | which produces the output $\vec{a}$. 158 | 159 | \section{Environments} 160 | \label{sec:environments} 161 | 162 | As we have seen, commands are not the only things that \LaTeX\ provides. It also provides \emph{environments} which are enclosed within \verb|\begin{...}| and \verb|\end{...}| statements. Standard environments are \verb|equation| and \verb|document|. 163 | 164 | Just as with commands it is possible to define new environments (using the \verb|\newenvironment| command in the document preamble) or redefine old ones (using the \verb|\renewenvironment| command). The usage is similar to that of \verb|\newcommand| as well: the main difference is that instead of defining what the command does, you define what should happen before entering and after exiting the environment. 165 | 166 | A simple example is 167 | % 168 | \begin{verbatim} 169 | \newenvironment{solution}[1]{% 170 | \begin{center} 171 | \rule{#1}{.1pt} 172 | \end{center} 173 | }{% 174 | \begin{center} 175 | \rule{0.9\textwidth}{.1pt} 176 | \end{center} 177 | } 178 | \end{verbatim} 179 | % 180 | which defines a \verb|solution| environment. 181 | 182 | The explanation of each piece is as follows: 183 | \begin{itemize} 184 | \item \verb|\newenvironment{solution}|: the definition of the name of the new environment. 185 | \item \verb|[1]|: the number of arguments pass in (here 1). 186 | \item \verb|{\begin{center} \rule{#1}{.1pt} \end{center} }|: in the definition these are spaced using carriage returns and comment markers for clarity, but by matching the curly braces this can be seen to be just one argument. These are the commands issued before entering the environment. \verb|#1| is the first argument passed in. 187 | \item \verb|{\begin{center} \rule{\rule{0.9\textwidth}{.1pt} \end{center} }|: again this was spaced for clarity in the definition. These are the commands issued after exiting the environment. No arguments can be used at this point. 188 | \end{itemize} 189 | 190 | This environment, used as 191 | % 192 | \begin{verbatim} 193 | \begin{solution}{0.9\textwidth} 194 | This is the solution. 195 | \end{solution} 196 | \end{verbatim} 197 | % 198 | produces the output 199 | % 200 | \begin{solution}{0.9\textwidth} 201 | This is the solution. 202 | \end{solution} 203 | % 204 | 205 | \section{Packages} 206 | \label{sec:packages} 207 | 208 | In essence a package is just a file containing a number of useful commands and environments, as explained in sections~\ref{sec:commands} and \ref{sec:environments}. So, rather than hand-defining a large number of commands you can import them all by including code such as 209 | % 210 | \begin{verbatim} 211 | \usepackage{amsmath} 212 | \end{verbatim} 213 | % 214 | in the document preamble. 215 | 216 | This is particularly important when producing journal articles. Many journals require (or strongly encourange) you to submit articles fitting in with their in-house style. Many scientific journals will therefore provide a \LaTeX\ package to use in the production of your article. 217 | 218 | \subsection{Useful packages} 219 | \label{sec:packages_provided} 220 | 221 | Most \LaTeX\ distributions will include the following packages which are extremely useful: 222 | \begin{itemize} 223 | \item \texttt{graphicx} or \texttt{graphics}: commands to import and manipulate graphics files. 224 | \item \texttt{amsmath} (and \texttt{amssymb} and \texttt{amsthm}): The American Mathematical Society \LaTeX\ package. A large number of useful commands, especially for aligning equations (see \verb|\align| and related). 225 | \item \texttt{fancyhdr}, \texttt{enumerate}, \texttt{caption}, \texttt{geometry}: control the document layout and appearance in a more transparent fashion. \texttt{fancyhdr} in particular is useful for producing headers for theses. 226 | \item \texttt{babel}: if you want to typeset anything in a language other than English, this package provides a lot of support. 227 | \item \texttt{hyperref}: transforms citations and cross-references into hyperlinks. Particularly useful when compiling direct to PDF. 228 | \item \texttt{natbib} or \texttt{biblatex}: most will find the default citation styles sufficient (or, for articles, journals will frequently provide their own). If you require something more controllable then these packages give you that power (\texttt{natbib} is much older and practically obsolete, but has lots of examples and is in widespread use. \texttt{biblatex} is much newer and very powerful but with far fewer examples and requires a modern \LaTeX\ distribution). 229 | \end{itemize} 230 | 231 | \subsection{Creating packages} 232 | \label{sec:packages_creating} 233 | 234 | At its heart a package just contains the commands you would have placed in the document preamble. However, there are a few additional commands and points to be careful of. 235 | 236 | \begin{itemize} 237 | \item \verb|\ProvidesPackage{}[]|: this command defines the name of the package \verb|| (which should match its filename) and an optional description \verb||. 238 | \item \verb|\RequirePackage{}|: instead of putting \verb|\usepackage{}| inside a package, this command allows \LaTeX\ to check if \verb|| has already been loaded, and if not, does so. 239 | \item \verb|\DeclareOption|, \verb|ExecuteOptions|, \verb|\ProcessOptions|: allows you to pass options to the package (and hence options to commands in the package). 240 | \end{itemize} 241 | 242 | Package files should have a \verb|.sty| extension. 243 | 244 | \section{Modularity} 245 | \label{sec:modularity} 246 | 247 | Long documents are typically composed of many chapters and sections using a variety of data. Working on a single long document is inefficient and confusing. It is better to split the document into multiple chunks corresponding to the structure of the document. \LaTeX\ has two ways of doing this. 248 | 249 | \subsection{Input} 250 | \label{sec:modularity_input} 251 | 252 | The command \verb|\input| simply imports a file, as if it were ``cut and paste'' into the current document. This could be done right here, with a file imported into the middle of a paragraph. The \verb|\input| command takes the name of the file to be imported without the \texttt{.tex} extension. Once the file is imported the document continues as normal. 253 | 254 | The \verb|\input| command is somewhat inflexible. My personal viewpoint is that its main use is for importing data produced by or stored in external formats. For example, if you have a code that produces a table with 50 entries, it will be safer to make your code output the results directly into a \LaTeX\ table format which can then be \verb|\input| into a document, rather than trying to copy all the data by hand. 255 | 256 | \subsection{Include} 257 | \label{sec:modularity_include} 258 | 259 | The alternative to the \verb|\input| command is the \verb|\include| command. Its use is exactly the same as the \verb|\input| command -- the only argument is the name of the file to be included, without the \texttt{.tex} extension. There are two main differences. 260 | 261 | The first difference, as is clear from this document, is that the text imported via the \verb|\include| command always starts on a new page, and there will be a new page inserted (via a page break) after the included content as well. For this reason the \verb|\include| statement is typically used in long documents -- reports or theses -- where each included file contains a full chapter. 262 | 263 | The second difference is the main advantage of the \verb|\include| command. You can selectively include only certain files whilst leaving all the \verb|\include| statements in place. For example, consider an outline document 264 | % 265 | \begin{verbatim} 266 | \documentclass{book} 267 | 268 | \includeonly{chapter2} 269 | 270 | \begin{document} 271 | 272 | \include{chapter1} 273 | \include{chapter2} 274 | \include{chapter3} 275 | 276 | \end{document} 277 | \end{verbatim} 278 | % 279 | This document should consist of three chapters. If we are working just on chapter 2 then we can concentrate solely on that by using the \verb|\includeonly| command to produce only the output for that chapter. However, all cross-references to the other chapters will still be correctly resolved (provided that they have been compiled at least once). 280 | 281 | \section[Additional commands]{Additional commands for long documents} 282 | \label{sec:additional} 283 | 284 | This contains a list of commands that are often useful for long reports and theses. 285 | % 286 | \begin{itemize} 287 | \item \verb|\maketitle|: Produces a title page based on the \verb|\author|, \verb|\title| and \verb|\date| (which must be set after the \verb|\begin{document}| but before the \verb|\maketitle|). 288 | \item \verb|\appendix|: as just used here, this converts the section or chapter numbering to use letters instead of numbers. 289 | \item \verb|\tableofcontents|: inserts a table of contents containing the titles of chapters, sections, subsections (there are parameters to control the depth). 290 | 291 | Note that if a title is extremely long it may not fit in the table of contents (or in the headers). All sectioning commands provide an option for a short title to be used in headers, table of contents and similar circumstances. An example is the title for this appendix where a short title of ``Additional commands'' can be produced using 292 | \begin{verbatim} 293 | \section[Additional commands]{Additional commands for long documents} 294 | \end{verbatim} 295 | \item \verb|\listoffigures|, \verb|\listoftables|: inserts the appropriate lists based on the captions of figures and tables. Here you will almost certainly want to use the optional short form for the captions. 296 | \item \verb|\frontmatter|, \verb|\mainmatter|, \verb|\backmatter|: only avaiable for \verb|book| class, this explicitly changes the page numbering to Roman letters or Arabic numerals respectively. 297 | \end{itemize} 298 | 299 | \section{Citations and bibliographies} 300 | \label{sec:Citations} 301 | 302 | One of \LaTeX's strengths is its cross-referencing. However, the mechanism for including and organizing the bibliography is out-dated, so requires a little work to use in the best fashion. 303 | 304 | The command to reference a bibliography citation is \verb|\cite|. Some 305 | additional packages (such as \verb|natbib|) introduce additional 306 | citation commands which allow for more control of the appearance of 307 | the reference within the text. The \verb|\cite| command takes at least 308 | one argument, which is the \emph{key} to the article in the 309 | bibliography. 310 | 311 | This section introduces the two most basic ways of building a bibliography in \LaTeX. Only the \verb|Bibtex| method of section~\ref{sec:bibtex} is recommended, and it is best to look at tools mentioned later for ease. Later sections will mainly focus on tools to build, maintain and control bibliographies using the underlying \verb|Bibtex| technology. 312 | 313 | Note that when using \LaTeX\ to build a document containing a bibliography it is usually necessary to build the document at least twice, and usually three times. On the first pass it looks in the document and finds which citations are needed. On the second pass it looks in the database and extracts the citations, putting them in the appropriate form. The third pass finalizes the document. 314 | 315 | \subsection{Direct inclusion} 316 | \label{sec:Direct} 317 | 318 | The bibliography can be written directly into the \LaTeX\ document using the commands (for example) 319 | % 320 | \begin{verbatim} 321 | \begin{thebibliography}{99} 322 | 323 | \bibitem{Duncan98} R. C. Duncan, Astrophys. J. {\bf 498}, L45 (1998). 324 | 325 | \end{thebibliography} 326 | \end{verbatim} 327 | % 328 | In this case there is only one item in the bibliography. The \verb|{99}| at the beginning gives the maximum number of entries in the bibliography -- this could be increased if needed. The article key is here \verb|Duncan98|, and would be cross-referenced in the text using \verb|\cite{Duncan98}|. 329 | 330 | The advantages of this citation method are 331 | \begin{enumerate} 332 | \item speed; you can directly and rapidly change the document, 333 | \item control; you can control exactly how it appears. 334 | \end{enumerate} 335 | 336 | The disadvantages are numerous. 337 | \begin{enumerate} 338 | \item Reuse; for every document you need to copy the reference without error. 339 | \item Modification; for every different use you need to manually change the appearance of the reference, and do it consistently. 340 | \item Completeness; there is no simple way to store all additional information about the reference that is not explicitly required (e.g.\ the abstract). 341 | \item Errors; if you delete the reference from the text you must consistently remove it from the bibliography. If an unpublished article is published, you must consistently update the reference in all documents. 342 | \item Etc... 343 | \end{enumerate} 344 | 345 | \subsection{Bibtex} 346 | \label{sec:bibtex} 347 | 348 | \verb|Bibtex| was the original solution for the \LaTeX referencing issues outlined above. An example of using \verb|Bibtex| is given in the \verb|BasicLatexBibtex| document, combined with the \verb|nummeth.bib| database file. 349 | 350 | In brief, the \verb|Bibtex| file is a database. Written as a plain-text file, each entry is a single reference. An example entry would be 351 | % 352 | \begin{verbatim} 353 | @article{Pareschi2005, 354 | author = {Pareschi, Lorenzo and Russo, Giovanni}, 355 | doi = {10.1007/s10915-004-4636-4}, 356 | issn = {0885-7474}, 357 | journal = {Journal of Scientific Computing}, 358 | keywords = {65c20,82d25,ams subject classification,high order shock capturing, 359 | hyperbolic systems with relaxation,kutta methods,runge,schemes,stiff,systems}, 360 | month = oct, 361 | number = {1}, 362 | pages = {129--155}, 363 | title = {{Implicit-Explicit Runge-Kutta Schemes and Applications to 364 | Hyperbolic Systems with Relaxation}}, 365 | url = {http://www.springerlink.com/index/10.1007/s10915-004-4636-4}, 366 | volume = {25}, 367 | year = {2005} 368 | } 369 | \end{verbatim} 370 | % 371 | The \emph{document type} is \verb|article|, as denoted by the \verb|@article|. There are many other possible, including books, reports, theses, unpublished, and many more. The \emph{key} is \verb|Pareschi2005|, to be cited \verb|\cite{Pareschi2005}| in the \LaTeX\ file. Some of the information included is required, but precisely what depends on the document type. For articles the minimum is the key, the author, the journal and the year. All other information \emph{may} be used (if available). 372 | 373 | Inside the \LaTeX\ document only two lines are required. For example, in \verb|BasicLatexBibtex| the two lines are 374 | % 375 | \begin{verbatim} 376 | \bibliographystyle{plain} 377 | \bibliography{nummeth} 378 | \end{verbatim} 379 | % 380 | The first controls the appearance of the bibliography; what order the references appear (e.g.\ alphabetical or in citation order), what information is included, and so on. It also controls how the citations appear in the text (e.g.\ author-date or numerical). The second line says that the references are stored in the \verb|nummeth.bib| file. Multiple \verb|bibtex| files can be referenced, separated by commas (e.g. \verb|\bibliography{file1,file2,file3}|). 381 | 382 | The advantages of the \verb|bibtex| database are clear. 383 | % 384 | \begin{enumerate} 385 | \item Reuse across multiple documents is easy. 386 | \item Additional information is stored with the reference. 387 | \item Changing styles is simple. 388 | \item Errors can be corrected in a single place. 389 | \end{enumerate} 390 | % 391 | 392 | Some disadvantages remain. 393 | % 394 | \begin{enumerate} 395 | \item The \verb|bibtex| database format is difficult to maintain by hand. 396 | \item Control over the appearance of the reference is less straightforward. 397 | \item Producing a database from scratch is a lengthy and tedious process. 398 | \end{enumerate} 399 | 400 | \subsection{Constructing and maintaining a database} 401 | \label{sec:maintaining} 402 | 403 | When starting you will build your own database from everything you read, and also inherit a database from your supervisor, group and office-mates. Merging disparate databases by hand, and typing all the details of references into a plain-text database, is a recipe for mistakes and a huge waste of time. Better tools include the following. 404 | 405 | \subsubsection{Journal websites} 406 | \label{sec:journals} 407 | 408 | Most published papers have a webpage through the journal, and many of these will export all of the reference information in a standard format. For \verb|bibtex| this typically means the website sends you a plain text file which you can copy and paste into your database. 409 | 410 | It is often the case that a little tweaking of the entry will be required -- frequently the article key is not memorable, and the appearance of special characters can be problematic. But this approach can save considerable time, as well as giving you information (DOI, URLs) that other \LaTeX\ tools can use. 411 | 412 | \subsubsection{Endnote and similar} 413 | \label{sec:endnote} 414 | 415 | Many people and groups use software such as \href{http://www.endnote.com/}{Endnote} to maintain their bibliographical database. There are free tools to convert between database formats -- see, for example, the \href{http://dret.net/bibconvert/}{ShaRef} service at \verb|http://dret.net/bibconvert/|. 416 | 417 | The advantages of packages like Endnote are their wide use (in certain fields), their tools for maintaining the database, and their tools for use with other word-processing packages such as Word. The conversion process will often require a little tweaking, as above. 418 | 419 | \subsubsection{Cloud and social reference managers} 420 | \label{sec:cloud} 421 | 422 | Online reference managers are available and are, for basic services, often free. These services include the basic functions of desktop packages such as Endnote, but have two major additional advantages. Firstly, the database is stored online and so available to you anywhere, on any device. Secondly, the tools are frequently well integrated with journal websites. This means that saving a reference to the database is just a single button click. 423 | 424 | Examples include 425 | % 426 | \begin{enumerate} 427 | \item \href{http://www.citeulike.org/}{CiteULike} at \verb|http://www.citeulike.org/| 428 | \item \href{http://www.mendeley.com/}{Mendeley} at \verb|http://www.mendeley.com/| 429 | \item \href{http://www.zotero.org/}{Zotero} at \verb|http://www.zotero.org/| 430 | \end{enumerate} 431 | % 432 | Each has their own internal database format and will export to other formats, such as \verb|bibtex|, on demand. 433 | 434 | The advantages of online reference managers for groups of collaborators and for web integration are obvious; it is definitely worth investigating such tools, and finding out which are standard in your field and group. 435 | 436 | \subsection{Controlling the appearance} 437 | \label{sec:appearance} 438 | 439 | Usually when writing a document there is a template to follow, and often that template will be prescriptive. For example, many journals provide \LaTeX\ style files to use, combined with \verb|bibtex| style files as well. In these cases there is no need to control how the references appear. 440 | 441 | However, in certain cases (such as your thesis) you may wish for more control. There are three basic methods: using the original \verb|bibtex| styles, using the \verb|natbib| package, or using the \verb|biblatex| package. 442 | 443 | \subsubsection{Bibtex styles} 444 | \label{sec:bibtex_styles} 445 | 446 | The original \verb|bibtex| package came with a small selection of styles, and a number of additional styles have been made publically available. Many can be found online -- \href{http://www.cs.stir.ac.uk/~kjt/software/latex/showbst.html}{a sample list} can be found at \verb|http://www.cs.stir.ac.uk/~kjt/software/latex/showbst.html|, and many others exist. 447 | 448 | If you are interested in the style being approximately correct, this is usually sufficient. 449 | 450 | \subsubsection{Natbib} 451 | \label{sec:natbib_styles} 452 | 453 | The \verb|natbib| package contains additional citation commands, and additional software to build a style file that does exactly what you want. I would say it is now out of date, and \verb|biblatex| is a better package, but it is still widely used. 454 | 455 | A few examples of the \href{http://merkel.zoneo.net/Latex/natbib.php}{citation commands provided} include 456 | % 457 | \begin{enumerate} 458 | \item \verb|\citet{Jones90}|, producing ``Jones et al.\ (1990)'' 459 | \item \verb|\citet[chap. 2]{Jones90}|, producing ``Jones et al.\ (1990, chap.\ 2)'' 460 | \item \verb|\citep{Jones90}|, producing ``(Jones et al.\ 1990)'' 461 | \end{enumerate} 462 | % 463 | The distinction is between \emph{textual} (\verb|\citet|) and \emph{parenthetical} (\verb|citep|) citations. 464 | 465 | In addition, \verb|natbib| has tools for sorting and compressing multiple citations in a single cross-reference, for modifying the appearance of parentheses, for aliasing a citation (i.e.\ replacing a key reference by ``Paper I'' throughout), and much more. 466 | 467 | \subsubsection{Biblatex} 468 | \label{sec:biblatex_styles} 469 | 470 | All of the features mentioned above, and more, have been implemented in the \verb|biblatex| package. This allows the use of standard \LaTeX\ macros and commands for controlling the layout and appearance of citations and the bibliography. The \href{http://ctan.org/pkg/biblatex}{package description} can be found at \verb|http://ctan.org/pkg/biblatex|, with \href{http://mirror.ctan.org/macros/latex/contrib/biblatex/doc/biblatex.pdf}{full documentation} at 471 | \verb|http://mirror.ctan.org/macros/latex/contrib/biblatex/doc/biblatex.pdf|. 472 | 473 | There are changes that can be made at the detail level when updating the \verb|biblatex|; see, for example, the \href{http://tex.stackexchange.com/questions/5091/what-to-do-to-switch-to-biblatex}{comments at StackExchange} at \\ \verb|http://tex.stackexchange.com/questions/5091/what-to-do-to-switch-to-biblatex|. This allows you to take advantage of the full features of \verb|biblatex|. 474 | 475 | \end{chapter} 476 | -------------------------------------------------------------------------------- /nbconvert_book.sty: -------------------------------------------------------------------------------- 1 | \NeedsTeXFormat{LaTeX2e} 2 | 3 | \ProvidesPackage{nbconvert_book} 4 | \ProvidesFile{nbconvert_book.sty} 5 | 6 | \RequirePackage{graphicx} % Used to insert images 7 | \RequirePackage{adjustbox} % Used to constrain images to a maximum size 8 | \RequirePackage{color} % Allow colors to be defined 9 | \RequirePackage{enumerate} % Needed for markdown enumerations to work 10 | \RequirePackage{geometry} % Used to adjust the document margins 11 | \RequirePackage{amsmath} % Equations 12 | \RequirePackage{amssymb} % Equations 13 | \RequirePackage{eurosym} % defines \euro 14 | \RequirePackage[mathletters]{ucs} % Extended unicode (utf-8) support 15 | \RequirePackage[utf8x]{inputenc} % Allow utf-8 characters in the tex document 16 | \RequirePackage{fancyvrb} % verbatim replacement that allows latex 17 | \RequirePackage{grffile} % extends the file name processing of package graphics 18 | % to support a larger range 19 | % The hyperref package gives us a pdf with properly built 20 | % internal navigation ('pdf bookmarks' for the table of contents, 21 | % internal cross-reference links, web links for URLs, etc.) 22 | \RequirePackage{hyperref} 23 | \RequirePackage{longtable} % longtable support required by pandoc >1.10 24 | \RequirePackage{booktabs} % table support for pandoc > 1.12.2 25 | \RequirePackage{textcomp} % Required for \textquotesingle, pandoc > 1.15? 26 | 27 | 28 | 29 | 30 | \definecolor{orange}{cmyk}{0,0.4,0.8,0.2} 31 | \definecolor{darkorange}{rgb}{.71,0.21,0.01} 32 | \definecolor{darkgreen}{rgb}{.12,.54,.11} 33 | \definecolor{myteal}{rgb}{.26, .44, .56} 34 | \definecolor{gray}{gray}{0.45} 35 | \definecolor{lightgray}{gray}{.95} 36 | \definecolor{mediumgray}{gray}{.8} 37 | \definecolor{inputbackground}{rgb}{.95, .95, .85} 38 | \definecolor{outputbackground}{rgb}{.95, .95, .95} 39 | \definecolor{traceback}{rgb}{1, .95, .95} 40 | % ansi colors 41 | \definecolor{red}{rgb}{.6,0,0} 42 | \definecolor{green}{rgb}{0,.65,0} 43 | \definecolor{brown}{rgb}{0.6,0.6,0} 44 | \definecolor{blue}{rgb}{0,.145,.698} 45 | \definecolor{purple}{rgb}{.698,.145,.698} 46 | \definecolor{cyan}{rgb}{0,.698,.698} 47 | \definecolor{lightgray}{gray}{0.5} 48 | 49 | % bright ansi colors 50 | \definecolor{darkgray}{gray}{0.25} 51 | \definecolor{lightred}{rgb}{1.0,0.39,0.28} 52 | \definecolor{lightgreen}{rgb}{0.48,0.99,0.0} 53 | \definecolor{lightblue}{rgb}{0.53,0.81,0.92} 54 | \definecolor{lightpurple}{rgb}{0.87,0.63,0.87} 55 | \definecolor{lightcyan}{rgb}{0.5,1.0,0.83} 56 | 57 | % commands and environments needed by pandoc snippets 58 | % extracted from the output of `pandoc -s` 59 | \providecommand{\tightlist}{% 60 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 61 | \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} 62 | % Add ',fontsize=\small' for more characters per line 63 | \newenvironment{Shaded}{}{} 64 | \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} 65 | \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} 66 | \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 67 | \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 68 | \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} 69 | \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 70 | \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 71 | \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} 72 | \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} 73 | \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} 74 | \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} 75 | \newcommand{\RegionMarkerTok}[1]{{#1}} 76 | \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} 77 | \newcommand{\NormalTok}[1]{{#1}} 78 | 79 | % Additional commands for more recent versions of Pandoc 80 | \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}} 81 | \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 82 | \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} 83 | \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}} 84 | \newcommand{\ImportTok}[1]{{#1}} 85 | \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}} 86 | \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} 87 | \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} 88 | \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}} 89 | \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} 90 | \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}} 91 | \newcommand{\BuiltInTok}[1]{{#1}} 92 | \newcommand{\ExtensionTok}[1]{{#1}} 93 | \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}} 94 | \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}} 95 | \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} 96 | \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} 97 | 98 | % Define a nice break command that doesn't care if a line doesn't already 99 | % exist. 100 | \def\br{\hspace*{\fill} \\* } 101 | % Math Jax compatability definitions 102 | \def\gt{>} 103 | \def\lt{<} 104 | 105 | 106 | 107 | 108 | % Pygments definitions 109 | 110 | \makeatletter 111 | \def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax% 112 | \let\PY@ul=\relax \let\PY@tc=\relax% 113 | \let\PY@bc=\relax \let\PY@ff=\relax} 114 | \def\PY@tok#1{\csname PY@tok@#1\endcsname} 115 | \def\PY@toks#1+{\ifx\relax#1\empty\else% 116 | \PY@tok{#1}\expandafter\PY@toks\fi} 117 | \def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{% 118 | \PY@it{\PY@bf{\PY@ff{#1}}}}}}} 119 | \def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}} 120 | 121 | \expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 122 | \expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 123 | \expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 124 | \expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 125 | \expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} 126 | \expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 127 | \expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 128 | \expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}} 129 | \expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 130 | \expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}} 131 | \expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 132 | \expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}} 133 | \expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 134 | \expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}} 135 | \expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 136 | \expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}} 137 | \expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 138 | \expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 139 | \expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}} 140 | \expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 141 | \expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 142 | \expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}} 143 | \expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 144 | \expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}} 145 | \expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} 146 | \expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 147 | \expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}} 148 | \expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}} 149 | \expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 150 | \expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 151 | \expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}} 152 | \expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} 153 | \expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 154 | \expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 155 | \expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}} 156 | \expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 157 | \expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}} 158 | \expandafter\def\csname PY@tok@mb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 159 | \expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}} 160 | \expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf} 161 | \expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit} 162 | \expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 163 | \expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 164 | \expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} 165 | \expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 166 | \expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}} 167 | \expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 168 | \expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 169 | \expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}} 170 | \expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 171 | \expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} 172 | \expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 173 | \expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 174 | \expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 175 | \expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 176 | \expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 177 | \expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 178 | \expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}} 179 | \expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 180 | \expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} 181 | \expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} 182 | 183 | \def\PYZbs{\char`\\} 184 | \def\PYZus{\char`\_} 185 | \def\PYZob{\char`\{} 186 | \def\PYZcb{\char`\}} 187 | \def\PYZca{\char`\^} 188 | \def\PYZam{\char`\&} 189 | \def\PYZlt{\char`\<} 190 | \def\PYZgt{\char`\>} 191 | \def\PYZsh{\char`\#} 192 | \def\PYZpc{\char`\%} 193 | \def\PYZdl{\char`\$} 194 | \def\PYZhy{\char`\-} 195 | \def\PYZsq{\char`\'} 196 | \def\PYZdq{\char`\"} 197 | \def\PYZti{\char`\~} 198 | % for compatibility with earlier versions 199 | \def\PYZat{@} 200 | \def\PYZlb{[} 201 | \def\PYZrb{]} 202 | \makeatother 203 | 204 | 205 | % Exact colors from NB 206 | \definecolor{incolor}{rgb}{0.0, 0.0, 0.5} 207 | \definecolor{outcolor}{rgb}{0.545, 0.0, 0.0} 208 | 209 | 210 | 211 | 212 | % Prevent overflowing lines due to hard-to-break entities 213 | \sloppy 214 | % Setup hyperref package 215 | \hypersetup{ 216 | breaklinks=true, % so long urls are correctly broken across lines 217 | colorlinks=true, 218 | urlcolor=blue, 219 | linkcolor=darkorange, 220 | citecolor=darkgreen, 221 | } 222 | % Slightly bigger margins than the latex defaults 223 | 224 | \geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in} 225 | -------------------------------------------------------------------------------- /pdf/FirstYearComputing_Master.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IanHawke/maths-with-python/25ab7bddc6b131fac7a12696010fd1187f723b69/pdf/FirstYearComputing_Master.pdf -------------------------------------------------------------------------------- /quadratic.py: -------------------------------------------------------------------------------- 1 | 2 | from math import sqrt 3 | from numpy.testing import assert_equal, assert_allclose 4 | 5 | def real_quadratic_roots(a, b, c): 6 | """ 7 | Find the real roots of the quadratic equation a x^2 + b x + c = 0, if they exist. 8 | 9 | Parameters 10 | ---------- 11 | 12 | a : float 13 | Coefficient of x^2 14 | b : float 15 | Coefficient of x^1 16 | c : float 17 | Coefficient of x^0 18 | 19 | Returns 20 | ------- 21 | 22 | roots : tuple or float or None 23 | The root(s) (two if a genuine quadratic, one if linear, None otherwise) 24 | 25 | Raises 26 | ------ 27 | 28 | NotImplementedError 29 | If the equation has trivial a and b coefficients, so isn't solvable. 30 | """ 31 | 32 | discriminant = b**2 - 4.0*a*c 33 | if discriminant < 0.0: 34 | return None 35 | 36 | if a == 0: 37 | if b == 0: 38 | raise NotImplementedError("Cannot solve quadratic with both a" 39 | " and b coefficients equal to 0.") 40 | else: 41 | return -c / b 42 | 43 | x_plus = (-b + sqrt(discriminant)) / (2.0*a) 44 | x_minus = (-b - sqrt(discriminant)) / (2.0*a) 45 | 46 | return x_plus, x_minus 47 | 48 | def test_no_roots(): 49 | """ 50 | Test that the roots of x^2 + 1 = 0 are not real. 51 | """ 52 | 53 | roots = None 54 | assert_equal(real_quadratic_roots(1, 0, 1), roots, 55 | err_msg="Testing x^2+1=0; no real roots.") 56 | 57 | def test_zero_roots(): 58 | """ 59 | Test that the roots of x^2 = 0 are both zero. 60 | """ 61 | 62 | roots = (0, 0) 63 | assert_equal(real_quadratic_roots(1, 0, 0), roots, 64 | err_msg="Testing x^2=0; should both be zero.") 65 | 66 | def test_real_distinct(): 67 | """ 68 | Test that the roots of x^2 - 1 = 0 are \pm 1. 69 | """ 70 | 71 | roots = (1.0, -1.0) 72 | assert_equal(real_quadratic_roots(1, 0, -1), roots, 73 | err_msg="Testing x^2-1=0; roots should be 1 and -1.") 74 | 75 | def test_real_distinct_irrational(): 76 | """ 77 | Test that the roots of x^2 - 2 x + (1 - 10**(-10)) = 0 are 1 \pm 1e-5. 78 | """ 79 | 80 | roots = (1 + 1e-5, 1 - 1e-5) 81 | assert_allclose(real_quadratic_roots(1, -2.0, 1.0 - 1e-10), roots, 82 | err_msg="Testing x^2-2x+(1-1e-10)=0; roots should be 1 +- 1e-5.") 83 | 84 | def test_real_linear_degeneracy(): 85 | """ 86 | Test that the root of x + 1 = 0 is -1. 87 | """ 88 | 89 | root = -1.0 90 | assert_equal(real_quadratic_roots(0, 1, 1), root, 91 | err_msg="Testing x+1=0; root should be -1.") 92 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=1.4 2 | nbsphinx 3 | ipykernel 4 | -------------------------------------------------------------------------------- /run_notebooks.py: -------------------------------------------------------------------------------- 1 | from runipy.notebook_runner import NotebookRunner 2 | from IPython.nbformat.current import read 3 | from glob import glob 4 | 5 | files = glob("./[01]*ipynb") 6 | 7 | for file in files: 8 | print("Doing file {}".format(file)) 9 | notebook = read(open(file), 'json') 10 | r = NotebookRunner(notebook) 11 | r.run_notebook(skip_exceptions=True) 12 | from IPython.nbformat.current import write 13 | write(r.nb, open("_runipy/"+file, 'w'), 'json') 14 | print("Done file {}".format(file)) 15 | -------------------------------------------------------------------------------- /southampton_precip.txt: -------------------------------------------------------------------------------- 1 | #Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 2 | 1855 85.6 54.3 61.3 10.1 60.0 43.9 101.0 47.9 88.4 187.5 28.2 55.4 3 | 1856 93.5 50.6 36.3 127.3 55.7 40.3 16.5 64.7 67.6 74.5 38.7 87.1 4 | 1857 72.3 10.6 54.4 60.7 19.0 38.2 43.7 66.3 93.6 191.4 57.1 25.0 5 | 1858 27.0 33.1 22.9 94.1 65.7 14.1 69.6 55.5 75.2 66.2 50.1 116.6 6 | 1859 59.6 78.3 49.7 92.4 36.8 45.7 66.6 58.3 135.3 119.8 125.1 127.1 7 | 1860 129.2 29.3 59.3 47.6 88.7 205.0 84.7 115.0 99.2 53.2 80.2 127.7 8 | 1861 20.7 60.2 76.4 10.2 41.3 100.8 103.5 22.2 78.0 27.7 164.3 53.2 9 | 1862 104.0 20.1 124.2 57.5 123.9 53.8 52.8 36.3 29.7 171.8 22.4 72.7 10 | 1863 129.4 32.4 38.7 20.5 55.2 94.6 26.4 63.9 98.7 115.3 60.7 64.4 11 | 1864 72.6 53.6 84.2 62.6 39.4 35.9 8.0 20.6 61.7 36.1 108.3 58.8 12 | 1865 128.2 103.6 27.8 21.8 74.0 65.2 103.3 128.5 3.4 221.8 122.5 84.4 13 | 1866 169.4 163.7 73.4 62.2 40.6 41.2 41.5 66.3 168.1 40.6 48.1 51.0 14 | 1867 136.3 60.5 73.0 47.2 37.7 31.8 128.7 53.1 85.4 78.3 7.3 45.2 15 | 1868 110.9 23.8 73.5 82.7 41.3 14.9 17.2 119.7 93.8 70.7 40.6 215.4 16 | 1869 87.1 79.8 48.6 26.5 106.5 41.4 25.2 19.4 104.4 72.6 37.4 98.8 17 | 1870 56.2 66.9 45.4 9.7 36.8 7.9 13.3 69.7 55.9 96.3 51.9 85.1 18 | 1871 74.1 40.4 35.4 106.6 10.9 61.8 125.4 32.9 116.7 65.8 19.9 64.2 19 | 1872 175.2 60.3 75.1 36.6 60.7 76.0 82.3 35.0 47.6 160.1 115.4 142.0 20 | 1873 130.1 73.3 78.5 27.3 31.8 57.3 58.3 66.2 69.3 75.9 72.0 14.3 21 | 1874 53.3 52.9 11.7 73.9 47.1 49.9 32.6 60.2 81.2 131.3 78.7 118.6 22 | 1875 118.4 74.7 25.6 35.0 44.7 72.2 115.5 43.3 39.8 124.0 118.7 31.0 23 | 1876 26.4 71.4 94.7 59.2 13.4 37.3 16.2 99.8 117.2 73.5 105.0 202.4 24 | 1877 157.7 42.4 58.6 73.5 60.5 20.8 82.1 77.0 49.3 61.5 158.5 47.8 25 | 1878 34.5 59.7 39.8 85.8 114.0 44.0 41.4 174.7 37.5 90.8 63.2 39.3 26 | 1879 109.5 105.6 12.4 76.7 71.0 133.4 105.0 163.1 95.5 20.9 12.9 19.1 27 | 1880 21.1 90.0 21.3 45.4 9.8 54.8 133.4 24.0 147.2 116.7 63.9 107.2 28 | 1881 38.8 86.0 69.3 21.5 27.4 57.5 44.0 110.8 48.7 38.4 129.6 75.8 29 | 1882 45.3 48.1 15.1 91.0 47.2 77.9 72.3 54.0 57.1 173.5 109.5 73.6 30 | 1883 87.4 112.8 23.1 26.4 65.1 34.8 79.9 28.6 109.2 70.0 113.1 20.8 31 | 1884 87.4 63.5 60.7 42.4 26.6 55.3 55.6 32.2 51.3 22.1 39.2 94.3 32 | 1885 72.1 86.7 53.7 40.0 98.3 39.8 7.3 17.1 128.7 100.1 76.9 46.5 33 | 1886 101.6 17.8 65.4 68.3 97.9 16.7 62.5 33.5 67.2 135.5 92.7 179.8 34 | 1887 79.0 24.0 44.0 33.6 28.5 25.0 20.2 73.6 72.6 33.8 104.9 52.1 35 | 1888 29.5 29.4 87.5 60.2 55.7 71.2 157.1 64.2 27.4 42.4 130.2 54.1 36 | 1889 20.7 48.4 68.3 53.2 69.0 10.5 67.9 54.1 26.7 136.3 38.4 52.0 37 | 1890 100.4 18.5 29.7 67.4 42.9 69.5 50.1 92.5 34.2 23.4 49.3 41.7 38 | 1891 78.8 0.8 68.3 25.5 63.7 45.8 62.4 139.4 33.9 249.3 92.1 126.4 39 | 1892 21.3 28.2 27.8 18.7 20.9 36.2 60.7 89.9 78.9 113.8 69.4 43.4 40 | 1893 43.6 95.0 6.6 1.7 21.3 26.0 101.9 32.9 42.4 87.3 59.9 78.8 41 | 1894 103.6 56.8 47.7 44.3 31.7 52.2 132.7 50.6 44.8 132.7 124.6 65.2 42 | 1895 89.6 3.0 52.0 66.7 8.0 49.0 98.0 68.4 7.2 78.6 52.5 64.4 43 | 1896 28.1 9.5 90.2 13.7 8.5 45.6 17.5 65.1 170.2 77.6 21.6 121.2 44 | 1897 69.1 95.9 133.5 53.4 36.6 50.8 28.6 111.8 67.9 21.6 32.9 125.3 45 | 1898 14.1 57.4 17.3 42.1 113.8 24.8 14.8 31.3 24.9 126.8 117.6 91.9 46 | 1899 101.7 79.6 22.4 73.7 30.0 34.9 33.8 14.6 80.5 55.6 134.7 40.2 47 | 1900 94.8 140.8 29.9 35.2 42.4 72.7 27.3 88.7 26.8 60.4 83.6 99.6 48 | 1901 36.1 41.8 59.1 71.2 42.3 27.8 90.5 74.6 57.7 73.0 15.1 128.9 49 | 1902 27.1 42.4 62.2 43.9 73.2 96.7 44.0 84.7 33.4 59.5 83.1 47.3 50 | 1903 66.1 48.6 86.7 70.4 73.1 102.4 66.8 106.9 67.1 280.7 45.7 83.1 51 | 1904 123.3 96.7 37.9 38.9 92.4 26.9 40.0 79.9 63.6 61.9 27.0 99.2 52 | 1905 27.0 22.1 123.5 41.3 17.4 101.3 10.1 83.5 50.6 57.9 110.3 20.1 53 | 1906 207.3 87.9 36.0 22.5 53.8 45.6 17.3 38.9 23.1 150.5 110.4 47.2 54 | 1907 25.6 41.1 18.1 110.2 76.8 47.8 37.3 42.0 11.4 186.2 74.2 112.0 55 | 1908 48.5 40.1 84.5 81.1 57.4 12.9 42.9 124.8 44.0 42.9 31.7 96.6 56 | 1909 23.5 10.9 91.0 33.1 33.5 138.4 68.9 53.7 98.1 238.5 15.1 112.3 57 | 1910 90.6 105.1 25.5 59.9 34.6 86.9 63.9 47.3 3.5 105.2 96.4 135.5 58 | 1911 36.8 47.2 55.1 47.3 47.7 38.2 3.4 18.4 35.3 108.8 112.7 221.7 59 | 1912 96.4 68.1 107.9 1.7 33.9 111.3 81.6 157.0 61.3 93.5 40.6 94.2 60 | 1913 133.6 31.7 87.7 77.1 82.2 17.8 24.6 53.0 54.2 108.1 93.9 48.7 61 | 1914 16.6 120.6 124.1 38.2 34.7 9.6 75.2 70.6 39.1 64.1 95.8 250.9 62 | 1915 107.5 144.0 19.5 33.0 91.9 33.9 112.2 39.3 92.7 96.4 82.5 205.1 63 | 1916 34.7 141.4 97.1 214.7 37.9 41.8 32.9 82.1 46.7 140.1 123.2 103.9 64 | 1917 31.6 28.9 91.2 62.6 55.4 66.4 84.5 129.1 38.9 123.3 18.2 33.0 65 | 1918 107.1 39.0 27.6 59.8 41.9 27.6 133.9 55.8 145.1 36.9 74.2 66.4 66 | 1919 125.0 80.1 129.9 64.5 8.8 17.8 40.4 74.2 175.5 20.1 64.6 156.7 67 | 1920 104.7 15.2 53.3 87.0 43.4 55.5 133.7 41.9 52.5 77.8 57.3 80.3 68 | 1921 91.0 8.9 31.6 24.7 236.3 3.5 16.3 54.6 19.7 176.4 54.8 43.3 69 | 1922 122.7 80.6 58.2 85.9 19.7 50.9 108.7 77.5 48.1 31.6 57.1 133.3 70 | 1923 42.8 150.6 106.2 77.9 44.0 9.6 23.3 58.2 52.5 101.0 44.6 80.8 71 | 1924 76.4 10.1 38.2 84.1 106.5 68.5 90.1 75.7 133.6 77.4 76.1 155.5 72 | 1925 108.1 116.9 12.0 66.9 95.3 0.0 68.7 109.7 78.2 101.6 73.0 93.0 73 | 1926 134.6 48.0 16.3 83.6 38.1 71.5 43.8 27.7 12.4 62.6 190.8 9.9 74 | 1927 60.4 107.5 92.9 49.7 19.3 61.7 70.5 108.2 153.2 51.2 79.3 103.8 75 | 1928 143.7 65.0 84.6 51.9 28.7 59.3 40.7 72.9 29.6 184.5 75.1 74.9 76 | 1929 40.2 30.5 4.4 27.8 50.1 35.5 51.8 44.9 10.7 126.8 230.2 188.8 77 | 1930 127.5 31.6 42.5 132.4 52.8 18.5 51.2 117.1 80.4 58.7 145.2 106.0 78 | 1931 57.9 57.2 25.1 73.8 77.3 80.9 90.5 142.6 51.9 17.0 101.3 17.8 79 | 1932 82.7 3.5 32.1 79.0 144.8 50.6 77.4 30.0 94.2 153.3 48.5 38.6 80 | 1933 54.6 94.2 95.9 29.0 47.8 45.3 43.7 23.6 80.9 47.5 17.5 20.1 81 | 1934 75.9 2.7 81.2 52.1 21.2 38.2 24.8 90.0 66.7 45.1 62.7 36.5 82 | 1935 20.6 94.3 25.6 85.9 37.3 106.1 60.2 71.7 100.1 146.1 199.7 99.5 83 | 1936 146.6 82.5 62.5 53.7 13.8 80.6 100.4 10.4 93.8 109.9 96.2 91.5 84 | 1937 171.8 143.0 98.7 55.7 75.2 36.4 28.7 31.5 46.5 93.0 55.6 147.6 85 | 1938 95.3 17.3 8.6 0.8 51.3 19.6 63.3 63.0 42.9 92.7 134.9 100.8 86 | 1939 150.4 33.6 33.3 54.6 33.0 48.8 119.6 51.8 56.4 103.1 160.8 46.7 87 | 1940 67.6 74.9 81.3 31.0 7.9 5.3 98.3 0.0 41.4 115.8 216.4 62.2 88 | 1941 91.5 79.5 106.7 44.9 43.9 41.4 47.2 88.6 34.3 25.4 69.1 54.1 89 | 1942 90.0 9.4 67.8 49.5 70.6 11.2 45.0 89.2 56.6 102.6 40.1 97.5 90 | 1943 149.9 31.1 15.7 21.3 88.9 32.8 53.6 35.1 48.8 94.0 38.3 51.3 91 | 1944 63.5 10.9 5.3 38.2 14.7 53.1 68.8 55.2 44.2 104.5 139.0 69.6 92 | 1945 47.0 54.0 20.6 27.7 69.9 99.3 56.1 47.2 49.3 83.3 8.1 105.4 93 | 1946 69.3 76.7 23.4 69.1 108.2 96.5 24.6 110.0 93.5 35.8 139.4 84.3 94 | 1947 75.4 45.0 170.4 54.8 27.9 34.3 22.9 24.6 28.2 29.7 34.0 70.9 95 | 1948 142.0 30.0 23.1 44.7 96.3 59.2 21.1 92.2 86.1 46.7 43.2 122.2 96 | 1949 20.1 36.3 37.1 46.2 63.5 11.9 8.1 24.4 85.6 217.2 95.8 35.6 97 | 1950 20.1 127.0 39.4 62.0 32.2 43.4 110.7 102.9 87.4 13.5 151.6 40.4 98 | 1951 102.4 153.7 109.1 207.5 69.7 29.3 53.8 125.9 86.1 28.3 234.7 70.2 99 | 1952 59.8 17.2 65.5 51.0 77.1 30.5 7.9 103.2 99.8 127.7 94.3 61.0 100 | 1953 23.6 36.2 13.8 45.9 67.5 68.8 111.3 47.4 87.8 143.8 34.0 20.3 101 | 1954 36.9 81.0 83.6 6.1 53.1 90.0 66.2 96.1 77.8 81.4 139.3 74.4 102 | 1955 91.0 52.2 29.9 9.4 108.1 69.3 33.8 24.4 42.8 118.6 70.5 107.0 103 | 1956 122.7 2.6 17.4 51.6 7.3 52.0 57.5 88.9 111.3 123.5 21.0 140.5 104 | 1957 74.6 104.0 52.5 2.3 39.8 42.9 109.2 88.5 67.3 61.0 67.0 53.3 105 | 1958 117.9 72.2 38.7 15.0 54.8 87.4 45.3 111.0 123.7 81.3 58.4 115.7 106 | 1959 85.9 4.4 84.9 69.1 17.2 24.7 42.0 39.6 2.0 78.5 97.0 164.2 107 | 1960 102.5 75.6 53.9 31.6 36.7 62.0 113.3 152.4 123.3 89.0 135.4 99.8 108 | 1961 126.4 61.4 3.1 105.1 33.5 18.6 29.7 23.5 92.8 97.7 62.1 86.1 109 | 1962 131.6 13.7 33.2 38.2 62.8 9.0 40.7 82.2 106.7 138.7 77.3 70.7 110 | 1963 14.8 34.0 114.4 125.1 42.3 62.6 31.0 87.3 66.6 43.9 151.5 35.8 111 | 1964 10.9 28.4 111.8 129.2 66.8 61.1 19.4 22.3 18.6 129.8 62.8 87.2 112 | 1965 95.3 3.7 92.1 29.1 47.9 53.9 80.9 63.5 106.7 14.5 106.5 131.6 113 | 1966 52.7 142.0 26.1 97.0 60.4 69.2 56.0 75.4 49.7 150.1 49.7 67.1 114 | 1967 102.5 90.7 58.1 46.3 108.8 36.2 26.5 65.0 105.7 179.6 54.0 75.4 115 | 1968 67.8 55.2 24.0 63.2 66.9 108.3 58.5 42.0 175.9 107.3 45.1 85.4 116 | 1969 130.3 44.9 75.9 22.0 82.9 29.3 49.4 67.9 35.5 2.8 130.1 94.6 117 | 1970 115.4 63.3 49.5 42.1 30.5 36.2 56.0 61.3 68.7 13.2 221.4 26.6 118 | 1971 110.6 26.8 72.3 52.1 30.5 129.8 40.2 54.9 8.9 61.9 55.0 29.4 119 | 1972 85.7 88.0 62.6 64.4 71.1 43.3 41.9 36.1 26.8 38.4 77.5 125.7 120 | 1973 36.9 23.1 19.1 50.4 72.1 34.3 30.3 35.5 43.8 36.8 25.4 64.5 121 | 1974 141.2 118.5 26.1 16.0 42.0 93.6 48.0 80.2 160.5 50.4 166.3 44.5 122 | 1975 129.5 25.3 98.2 31.7 41.3 17.0 24.9 36.4 163.6 31.1 58.8 33.2 123 | 1976 12.2 31.1 16.5 9.9 32.1 10.5 16.9 29.4 138.0 132.5 154.6 94.9 124 | 1977 76.1 122.7 74.0 25.0 62.8 55.7 10.6 102.5 19.6 50.6 85.7 113.1 125 | 1978 90.3 75.7 67.4 65.4 43.1 29.5 81.4 50.7 24.2 6.4 21.3 198.6 126 | 1979 90.6 61.7 92.7 50.3 117.8 44.1 29.7 79.7 16.3 60.2 48.0 111.4 127 | 1980 45.0 61.8 87.6 16.7 20.7 136.7 48.7 57.8 49.9 86.6 47.7 46.4 128 | 1981 28.9 36.4 140.7 49.0 86.5 31.7 52.1 10.7 165.6 80.6 37.7 92.3 129 | 1982 39.8 46.6 82.4 16.6 64.6 79.6 30.3 56.4 56.8 167.6 123.3 97.4 130 | 1983 76.3 33.8 34.1 74.9 66.0 46.3 9.1 39.9 81.7 55.1 40.6 94.4 131 | 1984 125.5 32.3 80.0 2.0 92.8 19.8 29.5 22.7 62.5 95.7 132.4 109.0 132 | 1985 70.7 35.8 56.6 41.7 35.3 59.0 57.0 91.9 23.3 18.3 51.6 108.4 133 | 1986 116.3 7.6 57.9 53.2 67.7 22.3 53.0 103.9 31.3 74.4 116.7 112.0 134 | 1987 9.7 55.4 96.8 73.5 29.9 65.9 47.2 16.7 38.4 192.8 79.4 43.5 135 | 1988 148.8 49.5 69.7 43.0 24.4 25.6 60.3 60.9 30.4 83.6 18.1 18.9 136 | 1989 25.3 80.3 80.0 73.7 4.1 36.5 16.3 27.5 26.9 93.6 52.1 159.0 137 | 1990 120.5 168.4 4.3 36.1 19.0 53.6 8.9 19.5 38.5 91.9 42.6 57.9 138 | 1991 104.2 29.5 79.4 40.1 11.1 111.0 70.0 11.7 43.8 77.0 55.8 28.0 139 | 1992 20.7 37.8 37.0 90.9 16.2 48.7 47.6 94.6 50.3 59.3 135.1 91.9 140 | 1993 99.9 7.5 47.9 86.1 57.0 59.7 54.7 34.0 124.9 174.5 76.7 155.8 141 | 1994 127.8 81.4 63.7 61.7 95.4 25.7 16.1 50.3 93.1 107.6 71.3 122.2 142 | 1995 146.0 127.3 45.0 22.6 21.1 11.2 19.7 4.6 151.4 47.4 126.7 83.9 143 | 1996 64.7 84.9 38.1 37.3 44.0 21.0 43.8 72.6 36.7 55.5 140.7 23.5 144 | 1997 16.4 112.2 23.4 12.5 40.7 105.2 10.6 72.1 7.5 64.5 151.4 100.5 145 | 1998 118.5 9.5 78.5 89.3 18.9 109.0 37.4 18.3 99.6 135.1 59.0 87.3 146 | 1999 129.4 28.8 32.2 57.2 17.2 75.3 11.8 119.5 111.9 66.8 49.6 138.8 147 | -------------------------------------------------------------------------------- /website-index.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Maths with Python\n", 8 | "\n", 9 | "The following pages outline an introduction to Python aimed at mathematicians. In particular, it should form the basis for a self-paced course for first year undergraduates in [Mathematical Sciences](http://www.southampton.ac.uk/maths) at the [University of Southampton](http://www.southampton.ac.uk/)." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "The [opening page](00-first-steps.html), mostly introduces how to install the software, and how to think about the course.\n", 17 | "\n", 18 | "The essential sections of the course are on\n", 19 | "\n", 20 | "* [the basics](01-python-basics.html)\n", 21 | "* [functions and programs](02-programs.html)\n", 22 | "* [loops and control flow](03-loops-control-flow.html)\n", 23 | "* [basic plotting](04-basic-plotting.html).\n", 24 | "\n", 25 | "The [next page introduces classes](05-classes-oop.html), which should at least be started to get the most out of the rest. We then have three important sections on\n", 26 | "\n", 27 | "* [scientific Python](06-numpy-plotting.html)\n", 28 | "* [symbolic Python](07-sympy.html)\n", 29 | "* [statistics](08-statistics.html).\n", 30 | "\n", 31 | "Finally, there are three \"appendices\" on\n", 32 | "\n", 33 | "* [testing](09-exceptions-testing.html)\n", 34 | "* [generators](10-generators.html)\n", 35 | "* [more details on classes, including inheritance](11-more-classes.html)." 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "The [PDF notes](https://github.com/IanHawke/maths-with-python/tree/master/pdf) also contain a section introducing $\\LaTeX$." 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "This material is [hosted on GitHub](https://github.com/IanHawke/maths-with-python)." 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "There are [solutions to all the exercises available](ExercisesSolutions.html)." 57 | ] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.4.4" 77 | }, 78 | "nbconvert": { 79 | "title": "Maths with Python" 80 | } 81 | }, 82 | "nbformat": 4, 83 | "nbformat_minor": 0 84 | } 85 | --------------------------------------------------------------------------------