{ "cells": [ { "cell_type": "markdown", "id": "a398cc49", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Week I - Key Python Features for Coding Numerical Simulations" ] }, { "cell_type": "markdown", "id": "3b25ff85", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "\n", "## Dynamic typing\n", "\n", "Python is dynamically typed (opposed to static language such as C, C++, Fortran), hence:\n", "\n", "* Types are set on the values, not on the names, of the variables.\n", "* Types do not need to be known before variables are actually used: variable types are checked at run time!\n", "* Variable names can change types if their values are changed\n", "\n", "### Example" ] }, { "cell_type": "code", "execution_count": null, "id": "31e48d1a", "metadata": { "scrolled": true }, "outputs": [], "source": [ "def inspect(x):\n", " print('This object is: {}'.format(type(x)))\n", " print('x = {}'.format(x))\n", " return type(x)\n", "\n", "x = 2 \n", "inspect(x)\n", "\n", "x = 3.2\n", "inspect(x)\n", "\n", "x = 'Hello!'\n", "inspect(x)\n" ] }, { "cell_type": "markdown", "id": "5d367e84", "metadata": {}, "source": [ "\n", "## Shared references\n", "\n", "Python is *reference counted*, so variables names are just references to the underlying values. How many times a reference is used and what are its related names is counted internally.\n", "Notably, multiple names can reference to the same object: **shared references**\n", "\n", "### Examples\n" ] }, { "cell_type": "code", "execution_count": null, "id": "bec4246d", "metadata": {}, "outputs": [], "source": [ "x = 5\n", "y = x\n", "print(id(x))\n", "print(id(y))" ] }, { "cell_type": "code", "execution_count": null, "id": "200cf2c6", "metadata": {}, "outputs": [], "source": [ "help(id)" ] }, { "cell_type": "code", "execution_count": null, "id": "7c3cf0da", "metadata": {}, "outputs": [], "source": [ "x = 3\n", "print(id(x))\n", "print(id(y))" ] }, { "cell_type": "code", "execution_count": null, "id": "70780769", "metadata": {}, "outputs": [], "source": [ "y = 4\n", "print(id(x))\n", "print(id(y))" ] }, { "cell_type": "code", "execution_count": null, "id": "7e674fbb", "metadata": {}, "outputs": [], "source": [ "x = ['a','b','c']\n", "y = x\n", "print(id(x))\n", "print(id(y))" ] }, { "cell_type": "code", "execution_count": null, "id": "ebe8fe75", "metadata": {}, "outputs": [], "source": [ "x[1] = 'w'\n", "print(x)\n", "print(y)\n", "print(id(x),id(y))" ] }, { "cell_type": "markdown", "id": "2e3fbef4", "metadata": {}, "source": [ "## Mutability\n", "\n", "In Python, data types can be either mutable or immutable:\n", "\n", "* **mutable** types allow values to change after creation, such as *lists, dictionaries, sets*\n", "* **immutable** types are static and cannot change values, such as *int, float, bool, str, tuples*\n", "\n", "### Examples" ] }, { "cell_type": "code", "execution_count": null, "id": "e9e2d5e7", "metadata": {}, "outputs": [], "source": [ "lis = ['a','b','c']\n", "tup = ('a','b','c')\n", "print(lis)\n", "print(id(lis),id(tup))\n", "lis[2] = 'zz'\n", "print(lis)\n", "print(id(lis))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "eba371b0", "metadata": {}, "outputs": [], "source": [ "try:\n", " tup[2] = 'zz'\n", "except TypeError as err:\n", " print('Forbidden!',err)" ] }, { "cell_type": "markdown", "id": "4ad9adbc", "metadata": {}, "source": [ "\n", "## Integers and Floats in Python\n", "\n", "Several numerical datatypes are available in Python, such as:\n", "* *int*: integers, with unlimited precision!\n", "* *float*: floating points, (usually) implemented with 'double' in C (check with sys.float_info)\n", "* *complex*: two floats (get with z.real and z.imag)\n", "\n", "Other relevant numeric datatypes:\n", "* *fractions.Fraction*, rational number arithmetics \n", "* *decimal.Decimal*, floats with user-definable precision\n", "\n", "Numpy has its own datatypes, here some of the most relevant:\n", "* np.half, np.single, np.double, np.longdouble (depends on platform!)\n", "* np.float16 (alias of np.half), np.float32 (alias of np.single), np.float64 (alias of np.double), np.float128 (alias np.longdouble - existence depends on the platform!)\n", "\n", "For more details on extended precision, beyond 64 bits, check out https://numpy.org/doc/stable/user/basics.types.html#extended-precision" ] }, { "cell_type": "markdown", "id": "e620a8e6", "metadata": {}, "source": [ "-------------" ] }, { "cell_type": "markdown", "id": "ec8f18da", "metadata": {}, "source": [ "\n", "### Week 1, Exercise - Underflow, overflow and machine precision\n" ] }, { "cell_type": "code", "execution_count": null, "id": "330ee8d6", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "def check_underflow_limit(float_type):\n", " '''\n", " Returns the underflow limit\n", " '''\n", " a = float_type(1.0)\n", " while a>float_type(0.0):\n", " under = a\n", " a = a/float_type(2.0)\n", " print('The calculated underflow limit is:{}'.format(under))\n", "\n", "def check_overflow_limit(float_type):\n", " '''\n", " Returns the overflow limit\n", " '''\n", " a = float_type(1.0)\n", " while a!=float_type('Inf'):\n", " over = a\n", " a = a*float_type(2.0)\n", " print('The calculated overflow limit is:{}'.format(over))\n", "\n", "def check_machine_precision(float_type):\n", " '''\n", " Returns machine precision\n", " '''\n", " eps = float_type(1.0)\n", " while (float_type(1.0)+eps!=float_type(1.0)):\n", " eps = eps/float_type(2.0)\n", " print('The calcuated machine precision is:{}'.format(float_type(2)*eps))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "121931e7", "metadata": {}, "outputs": [], "source": [ "for ft in [float,np.float16,np.float32,np.float64,np.longdouble]:\n", " print(str(ft))\n", " check_underflow_limit(ft)\n", " check_overflow_limit(ft)\n", " check_machine_precision(ft)\n", " print('---------------')\n", " #Compare with numpy results\n", " print(np.finfo(ft))" ] } ], "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.11.1" } }, "nbformat": 4, "nbformat_minor": 5 }