{ "cells": [ { "cell_type": "markdown", "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [] }, "source": [ "# Python basics\n", "\n", "The purpose of this tutorial is to introduce some basic Python syntax, which can help understand Ubermag simulations.\n", "\n", "## Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables (such as the object with name `a` in the examples below) are created through assignment of a value. We can check the type of the variable using the `type()` function:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "int" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 10\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "float" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 3.14 # decimal point present makes this a float type\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "str" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 'Python' # single or double quotes define a string\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tuple" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = (1, 2, 3) # tuple: round brackets\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "list" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = ['a', 2, 3.14] # list: square brackets\n", "type(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Large/small values, e.g. $a = 2.1 \\times 10^{6}$" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.1e-06" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 2.1e-6\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic arithmetic operations\n", "\n", "#### 1. Addition $c = a + b$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "a = 10\n", "b = 3\n", "c = a + b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To inspect an object, we can just type its name if it is in the last line of a notebook cell: " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "13" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `print()` function can be used to send information to the standard output (typically the display):" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The value of c is: 13\n" ] } ], "source": [ "print('The value of c is:', c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2. Subtraction: $a - b$" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a - b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3. Multiplication: $a \\times b$" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "30" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a * b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 4. Division: $a / b$" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.3333333333333335" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a / b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Python 3, if we divide two `int` variables, we are going to get `float`:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.5" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "5/2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 5. Power $a^{b}$" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "125" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 5\n", "b = 3\n", "a ** b # Common mistake to write a^b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 6. More complicated operations\n", "\n", "Other \"more complicated\" operations generally live in `math` or `numpy`. Before `math` can be used, it must be imported." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "import math" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All functions living in `math` or any other module, can be accessed using `.` operator." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "tags": [ "nbval-ignore-output" ] }, "outputs": [ { "data": { "text/plain": [ "2.65358979335273e-06" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "theta = 3.14159 # theta is approximately pi\n", "math.sin(theta)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-0.9999999999964793" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.cos(theta)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sin(math.pi/2)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 10\n", "math.log10(a)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.log(math.e) # natural log" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sequences: lists and tuples\n", "\n", "A collection of values can be represented using lists and tuples." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 51000.0]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = [1, 2, 3, 5.1e4] # list -> square bracket\n", "a" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3, 51000.0)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = (1, 2, 3, 5.1e4) # tuple -> round bracket\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Indexing" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0] # the first element" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 2, 3, 51000.0]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0] = 5\n", "a" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "51000.0" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b[3] # the last element" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively `-1` can be used as an index to get the last element" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "51000.0" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Length (the number of elements in a sequence)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(a)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What is the difference between list and tuple? Tuples are not mutable." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "TypeError", "evalue": "'tuple' object does not support item assignment", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[29], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mb\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m3\u001b[39m\n", "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" ] } ], "source": [ "b[2] = 3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Unpacking\n", "\n", "If we have a point which is defined as a tuple and want to unpack the values into x, y, and z, we can write:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x=-1, y=2, z=0\n" ] } ], "source": [ "point = (-1, 2, 0)\n", "x = point[0]\n", "y = point[1]\n", "z = point[2]\n", "print(f'x={x}, y={y}, z={z}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A more convenient way is:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x=-1, y=2, z=0\n" ] } ], "source": [ "x, y, z = point\n", "print(f'x={x}, y={y}, z={z}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding an element to the list:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 2, 3, 51000.0, 'new_element']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.append('new_element')\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sequences: numpy arrays\n", "\n", "Another sequence type that is used a lot in computational work is the `ndarray` type (n-dimensional array) from the `numpy` package. We can create a numpy array from other sequences, such as a list:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "import numpy as np # by convention `np` is used as the alias for numpy" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 5, 2, 10, 100])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = np.array([5, 2, 10, 100])\n", "c" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `ndarray` data type has been designed for numeric work. It is fast in execution and allows to carry out the same operation on all elements of the array at the same time:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 15, 6, 30, 300])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3*c" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 2.23606798, 1.41421356, 3.16227766, 10. ])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sqrt(c) # element-wise square root" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "117" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c.sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The Ubermag modules, such as `discretisedfield`, often return numpy arrays." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dictionaries\n", "\n", "Dictionaries map keys (such as `region1`) to values (such as `1e-12`):" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'region1': 1e-12, 'region797': 5e-11}" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = {'region1': 1e-12, 'region797': 5e-11}\n", "d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Accessing an element in a dictionary " ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1e-12" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d['region1'] # string in quotes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conditional execution\n", "\n", "All lines belonging to one execution branch must be indented." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I'm in!\n" ] }, { "data": { "text/plain": [ "6" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 5\n", "b = 4\n", "\n", "if a == 5 and b < 10:\n", " # indented lines\n", " print(\"I'm in!\") # single and double quotes\n", " a += 1 # a = a + 1\n", " \n", "a # output the value" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C\n" ] } ], "source": [ "if a == 10:\n", " print('A')\n", "elif a <= 4:\n", " print('B')\n", "else:\n", " print('C')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Iteration" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "5.1\n" ] } ], "source": [ "for i in [1, 2, 3, 5.1]:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 + 1 = 1\n", "5 + 1 = 6\n", "9 + 1 = 10\n", "4 + 1 = 5\n" ] } ], "source": [ "a = [0, 5, 9, 4]\n", "for i in range(len(a)):\n", " print(f'{a[i]} + 1 = {a[i] + 1}') # f-string" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 + 1 = 1\n", "5 + 1 = 6\n", "9 + 1 = 10\n", "4 + 1 = 5\n" ] } ], "source": [ "for i in a:\n", " print(f'{i} + 1 = {i + 1}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def area(a, b):\n", " # indented\n", " return a * b \n", "\n", "area(5, 2)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def sum_of_elements(a):\n", " s = 0\n", " for i in a:\n", " s = s + i\n", " \n", " return s\n", "\n", "sum_of_elements([1, 2, 3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Default values for arguments" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def volume(a, b, c):\n", " return a * b * c\n", "\n", "volume(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def volume(a, b=2, c=3):\n", " return a * b * c\n", "\n", "volume(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Accessing modules through `import`" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy\n", "\n", "numpy.pi" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Often we specify an alias" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "np.pi" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Common mistakes\n", "\n", "#### 1. No colon" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "raises-exception", "nbval-ignore-output" ] }, "outputs": [ { "ename": "SyntaxError", "evalue": "expected ':' (1951381238.py, line 1)", "output_type": "error", "traceback": [ "\u001b[0;36m Cell \u001b[0;32mIn[52], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m def speed(s, t)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m expected ':'\n" ] } ], "source": [ "def speed(s, t)\n", " return s/t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2. Lack of indentation" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "editable": true, "slideshow": { "slide_type": "" }, "tags": [ "raises-exception", "nbval-ignore-output" ] }, "outputs": [ { "ename": "IndentationError", "evalue": "expected an indented block after function definition on line 1 (3863715070.py, line 2)", "output_type": "error", "traceback": [ "\u001b[0;36m Cell \u001b[0;32mIn[53], line 2\u001b[0;36m\u001b[0m\n\u001b[0;31m return s/t\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block after function definition on line 1\n" ] } ], "source": [ "def speed(s, t):\n", "return s/t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3. Mixing incompatible types" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "TypeError", "evalue": "unsupported operand type(s) for +: 'int' and 'str'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[54], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m a \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m10\u001b[39m\n\u001b[1;32m 2\u001b[0m b \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m----> 3\u001b[0m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'" ] } ], "source": [ "a = 10\n", "b = 'a'\n", "a + b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 4. Using an undefined variable" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "NameError", "evalue": "name 'my_var' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[55], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mmy_var\u001b[49m \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m5\u001b[39m\n", "\u001b[0;31mNameError\u001b[0m: name 'my_var' is not defined" ] } ], "source": [ "my_var + 5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 5. Module is not imported" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "NameError", "evalue": "name 'scpy' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[56], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mscipy\u001b[39;00m \n\u001b[0;32m----> 2\u001b[0m \u001b[43mscpy\u001b[49m\u001b[38;5;241m.\u001b[39mfft\u001b[38;5;241m.\u001b[39mfft() \u001b[38;5;66;03m# typo: scpy instead of scipy\u001b[39;00m\n", "\u001b[0;31mNameError\u001b[0m: name 'scpy' is not defined" ] } ], "source": [ "import scipy \n", "scpy.fft.fft() # typo: scpy instead of scipy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object oriented programming basics\n", "\n", "In Python, everything is an object. Each object contains attributes and methods (functions). When we define an object, using `.` we can access its different methods. For instance, if we define a string:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "my_object = \"Ubermag\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can access some of its methods:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ubermag'" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_object.lower()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see all methods and attributes of an object using the `dir()` function:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting help\n", "\n", "In Jupyter notebooks, it is often enough to append a question mark to the function name:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "tags": [ "nbval-ignore-output" ] }, "outputs": [ { "data": { "text/plain": [ "\u001b[0;31mSignature:\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m/\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mDocstring:\u001b[0m Return the square root of x.\n", "\u001b[0;31mType:\u001b[0m builtin_function_or_method" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import math\n", "math.sqrt?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, use the `help()` function to get more information about an object or method:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on built-in function sqrt in module math:\n", "\n", "sqrt(x, /)\n", " Return the square root of x.\n", "\n" ] } ], "source": [ "help(math.sqrt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Further reading\n", "\n", "- A more detailed [Introduction to Python for scientists and engineers is available](https://github.com/fangohr/introduction-to-python-for-computational-science-and-engineering/blob/master/Readme.md)\n", "\n", "- More generic documentation and tutorials can be found on the Python home page at https://www.python.org/" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.12" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 4 }