{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Crush just enough Python\n", "\n", "This is a brief introduction to programming in Python to help you hit the ground running with the CFD step-by-step.\n", "\n", "**Installation**: Download and install a Python distribution on your computer. One option is the free [Anaconda Scientific Python](https://www.anaconda.com/download) distribution. Choose *Miniconda* if your computer is running out of storage.\n", "\n", "Here are some suggestions:\n", "- For best results, prepare your own code for every class, either as a Python script or in a clean Jupyter notebook.\n", "- To write and execute Python code, I recommend using Visual Studio Code.\n", "- For easy management of various Python environment, I recommend creating an isolated environment for this course. Open Anaconda Prompt and type the following command:\n", "```Prompt\n", "conda create --name cfd2025 python=3.12\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Libraries\n", "\n", "Python is a high-level, interpreted language that supports procedural, functional and object-oriented programming.\n", "\n", "- Python is inhabited by many `packages` or `libraries` that provide useful things like *array operations*, *plotting*, and much more.\n", "\n", "- We can `import` libraries of functions to expand the capabilities of Python in our programs.\n", "\n", "Let's start by importing a few libraries to help us out.\n", "\n", "- `NumPy`: providing a bunch of useful array operations (similar to MATLAB).\n", "\n", "- `Matplotlib`: a 2D plotting library which we will use to visualize our results.\n", "\n", "Before the actual import, it is necessary to install the corresponding libraries. Type the following command to install `Matplotlib` and its dependencies:\n", "\n", "```Prompt\n", "conda install matplotlib\n", "```\n", "\n", "```{note}\n", "If you are a proficient MATLAB user, there is a wiki page that should prove helpful to you: [NumPy for Matlab Users](http://wiki.scipy.org/NumPy_for_Matlab_Users).\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import and use libraries\n", "\n", "Standing on the shoulders of giants. The following code will be at the top of most of our programs, so execute the code in this cell first!" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# <-- comments in Python are denoted by the pound sign, like this one\n", "import numpy # we import the array library\n", "from matplotlib import pyplot # import plotting library" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are importing one library named `numpy` and we are importing a module called `pyplot` of a big library called `matplotlib`.\n", "\n", "To use a function belonging to one of these libraries, we have to tell Python where to look for it. For that, each function name is written following the library name, with a **dot** in between.\n", "\n", "So if we want to use the NumPy function [linspace()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html), we call it by writing:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "myarray = numpy.linspace(0, 5, 6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can visualize the resulting array by printing it:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0. 1. 2. 3. 4. 5.]\n" ] } ], "source": [ "print(myarray)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{admonition} Exercise\n", "The function `linspace()` is very useful. Try to change the input parameters and observe the different outputs. What are the meanings of the three input parameters?\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import styles\n", "\n", "You will often see code snippets that use the following lines" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from matplotlib import pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Question**: What's all of this import-as business?\n", "\n", "*It's a way of creating `shortcuts` to the NumPy library and the pyplot module. You will see them frequently as it is in common usage.*\n", "\n", "```{note}\n", "Sometimes, you'll see people importing a whole library without assigning a shortcut for it (like `from numpy import *`). This way is **NOT** recommended.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables\n", "\n", "Python does not require explicitly declared variable types like some compiled languages, such as C." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "a = 5 # a is an integer 5\n", "b = 'five' # b is a string of the word 'five'\n", "c = 5.0 # c is a floating point 5" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " \n" ] } ], "source": [ "print(type(a), type(b), type(c))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{warning}\n", "If you divide an integer by an integer that yields a *remainder*, the result will be converted to a *float*. (This is different from the behavior in Python 2.7!)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loops in Python\n", "\n", "Python uses `indents` and `whitespace` to group statements together.\n", "\n", "To write a short loop in C, you might use:\n", "```C\n", "for (i = 0, i < 5, i++){\n", " printf(\"Hi! \\n\");\n", "}\n", "```\n", "\n", "Python does not use curly braces like C, so the same program as above is written in Python as follows:\n", "```Python\n", "for i in range(5):\n", " print('Hi!')\n", "```\n", "\n", "```{admonition} Exercise\n", "Write a Python program that calculates the sum of integers from 1 to 10 and print the result. Note the use of the `range()` function.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you have nested for-loops, there is a further indent for the inner loop." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "for i in range(3):\n", " for j in range(3):\n", " pass # do nothing\n", " \n", " # This statement is within the i-loop, but not the j-loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Slicing arrays\n", "\n", "In `NumPy`, you can look at portions of arrays in the same way as in MATLAB. Let's take an array of values from 1 to 5." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 3 4 5]\n" ] } ], "source": [ "myvals = numpy.array([1, 2, 3, 4, 5])\n", "print(myvals)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python uses a **zero-based** index, so let's look at the *first* and *last* element in the array `myvals`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 5\n" ] } ], "source": [ "print(myvals[0], myvals[4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are 5 elements in the array `myvals`, but if we try to look at `myvals[5]`, Python will throw an error, as `myvals[5]` is actually calling the non-existant 6th element of the array." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "IndexError", "evalue": "index 5 is out of bounds for axis 0 with size 5", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mIndexError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[10], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mmyvals\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m5\u001b[39;49m\u001b[43m]\u001b[49m)\n", "\u001b[1;31mIndexError\u001b[0m: index 5 is out of bounds for axis 0 with size 5" ] } ], "source": [ "print(myvals[5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Arrays can also be sliced, grabbing a range of values. Let's look at the first three elements." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 3]\n" ] } ], "source": [ "print(myvals[0:3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "Slicing is *inclusive* on the left and *exclusive* on the right, so the above command gives us the values of `myvals[0]`, `myvals[1]` and `myvals[2]`, but not `myvals[3]`.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Assigning array variables\n", "\n", "One of the strange little features in Python that often confuses people comes up when assigning and comparing arrays of values. Here is a quick example. Let us start by defining a 1D array called $a$:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1. 2. 3. 4. 5.]\n" ] } ], "source": [ "a = numpy.linspace(1, 5, 5)\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, so we have an array $a$, with the values 1 to 5. If we want to make a copy of that array, called $b$, we may try the following:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1. 2. 3. 4. 5.]\n" ] } ], "source": [ "b = a\n", "print(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Great! So $a$ has the values 1 to 5 and now so does $b$. Now we have a backup of $a$, we can change its values without worrying about losing data (or so we may think!)." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 2. 17. 4. 5.]\n" ] } ], "source": [ "a[2] = 17\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, the 3rd element of $a$ has been changed to 17. Now let's check on $b$." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 2. 17. 4. 5.]\n" ] } ], "source": [ "print(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "When you use a statement like $b = a$, rather than copying all the values of $a$ into a new array called $b$, Python just creates an `alias` (or a pointer) called $b$ and tells it to route us to $a$. So if we change a value in $a$, then $b$ will reflect that change (technically, this is called *assignment by reference*). This default behavior may result in a more efficient code and potentially saves memory, but can also lead to hidden errors that are difficult to debug!\n", "```\n", "\n", "If you want to make a true copy of the array, you have to tell Python *explicitly* to copy every element of $a$ into a new array. Let us call it $c$." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 1. 2. 17. 4. 5.]\n" ] } ], "source": [ "c = a.copy()\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can try again to change a value in $a$ and see if the changes are also seen in $c$." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1. 2. 3. 4. 5.]\n", "[ 1. 2. 17. 4. 5.]\n" ] } ], "source": [ "a[2] = 3\n", "print(a)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Array operations with NumPy\n", "\n", "For more computationally intensive programs, the use of built-in `NumPy` functions can provide an increase in execution speed many-times over. As a simple example, consider the following equation:\n", "\n", "$$u^{n+1}_i = u^n_i-u^n_{i-1}$$\n", "\n", "Now, given a vector $u^n = [0, 1, 2, 3, 4, 5]$ we can calculate the values of $u^{n+1}$ by iterating over the values of $u^n$ with a for loop." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "1\n", "1\n", "1\n", "1\n" ] } ], "source": [ "un = numpy.array([0, 1, 2, 3, 4, 5])\n", "\n", "for i in range(1, len(un)):\n", " print(un[i] - un[i-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the expected result and the execution time was very short. If we perform the same operation as an array operation, then rather than calculate $u^n_i-u^n_{i-1}\\ $ 5 separate times, we can `slice` the $u$ array and calculate each operation with one command:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 1, 1, 1, 1])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "un[1:] - un[0:-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What this command says is subtract the 0th, 1st, 2nd, 3rd, 4th and 5th elements of $u$ from the 1st, 2nd, 3rd, 4th, 5th and 6th elements of $u^n$.\n", "\n", "**Question**: If we can use raw Python (for-loop) to conduct the calculations, why do we still need array operation?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Speed comparison\n", "\n", "For a 6-element array, the benefits of array operations are pretty slim. There will be no appreciable difference in execution time because there are so few calculations taking place.\n", "\n", "Therefore, we need to make a larger array to test the calculation speed. The iPython **magic** function `%%timeit` will help us evaluate the performance of our code. \n", "\n", "```{note}\n", "The `%%timeit` magic function will run the code multiple times and then give an average execution time as a result.\n", "The execution times below will vary from machine to machine. Don't expect your times to match these results, but you *should* expect to see the same general trend in decreasing execution time as we switch to array operations.\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "526 ms ± 11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%%timeit\n", "un = numpy.arange(1000000)\n", "\n", "for i in range(1, len(un)):\n", " diff = un[i] - un[i-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's compare that with the performance of the same code implemented with array operations:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.44 μs ± 174 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n" ] } ], "source": [ "%%timeit\n", "diff = un[1:] - un[0:-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, the speed difference is **huge**! Several handreds of miliseconds is not a huge amount of time to wait, but these speed gains will increase exponentially with the size and complexity of the problem being evaluated." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Defining functions in Python\n", "\n", "Next, we are going to introduce *function definitions*, which will allow us more flexibility in reusing and also in organizing our code.\n", "\n", "We will begin with a trivial example: a function which adds two numbers. To create a function in Python, we start with the following:\n", "\n", "```Python\n", "def simpleadd(a, b):\n", "```\n", "\n", "This statement creates a function called `simpleadd` which takes two inputs, $a$ and $b$. Let us execute this function definition code." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "def simpleadd(a, b):\n", " return a + b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `return` statement tells Python what data to return in response to being called. Now we can try calling our `simpleadd` function:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "simpleadd(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, there can be much more happening between the `def` line and the `return` line. In this way, one can build code in a *modular* way.\n", "\n", "```{admonition} Exercise\n", "Write a function named `fibonacci` that returns the n-th (zero-indexed) number in the Fibonacci sequence. Print the 7-th number (13) by calling the function.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once defined, the function `fibonacci` can be called like any of the built-in Python functions that we have already used. For exmaple, we might want to print the first 10 numbers in the Fibonacci sequence:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for n in range(10):\n", " print(fibonacci(n))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will use the capability of defining our own functions in Python to help us build codes that are easier to *reuse*, easier to *maintain*, easier to *share*!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic plotting\n", "\n", "On a system with `Matplotlib` installed, we can import the `pyplot` module for plotting all kinds of figures to visualize our data." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "from matplotlib import pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The simplest (x, y) line plot is achieved by calling `plt.plot()` with two iterable objects of the same length (typically lists of numbers or `NumPy` arrays). For example," ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure()\n", "x = [0., 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]\n", "y = [0.0, 0.25, 1.0, 2.25, 4.0, 6.25, 9.0]\n", "plt.plot(x,y)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To plot (x, y) points as a *scatter* plot rather than as a *line* plot, call `plt.scatter()` instead:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "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jdXr0jnWUv+MyLe+9S396le/It+bArvHubi4WH/5y1/U1NQ08FVbW6uvfOUrampq0qxZs5wauuek85meM2eO3nvvPX300UcDj7399tvKy8vThAkTcjper0rnOH/yySfKy4u9bOXn50v67M4dmXPlepiz0liXRZeMbd682WpubrZWrFhhjR492vrb3/5mWZZlrV692rrpppsGnh9dynT33Xdbzc3N1ubNm1namyK7x/pXv/qVVVBQYD366KNWW1vbwNeHH37o1lvwBLvHeTBW06TO7rHu7u62JkyYYP3rv/6r9de//tV6/fXXrQsuuMC67bbb3HoLnmD3OD/55JNWQUGBtWHDBqulpcXavXu3NWPGDGvmzJluvQVP6O7utg4ePGgdPHjQkmQ98MAD1sGDBweWUJtwPfRtMGJZlvXoo49aEydOtEaOHGlNnz7dev311wf+7+abb7Yuu+yymOf/4Q9/sC655BJr5MiR1vnnn29t3LjR4RF7l51jfdlll1mShnzdfPPNzg/cY+x+pj+PYMQeu8f68OHD1uWXX26dddZZ1oQJE6yVK1dan3zyicOj9h67x/nhhx+2KioqrLPOOssqKyuzvvGNb1jvvvuuw6P2lt///vfDnnNNuB6GLIu5LQAA4B5f1owAAADvIBgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACuIhgBAACu+n8iQGgFul53UQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import random\n", "\n", "x, y = [], []\n", "for i in range(100):\n", " x.append(random.random())\n", " y.append(random.random())\n", "\n", "plt.figure()\n", "plt.scatter(x, y)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Homework 1\n", "\n", "Learn more about the Python language. Get yourself familiar with the following contents:\n", "\n", "- Data types (integer, float, string, etc)\n", "- Data container (tuple, list, dictionary, etc)\n", "- Conditions and loops\n", "- Array operation using NumPy\n", "- Plotting figures using Matplotlib (size, labels, legends, formats, subplots, contours, etc)\n", "\n", "**Let us code and have fun!!!**" ] } ], "metadata": { "kernelspec": { "display_name": "cfd2025", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.9" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }