From ab548036699852e806ed9bb92260664e72d7c1c5 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Mon, 15 Oct 2018 15:52:30 +0200 Subject: [PATCH 01/19] 01_Fundamentals.ipynb --- 01_Fundamentals.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index 0955d74..73b9534 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -654,14 +654,14 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.4" + "pygments_lexer": "ipython2", + "version": "2.7.15rc1" } }, "nbformat": 4, From c92a53d25264fb798383b69d01a8349737badb61 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Tue, 16 Oct 2018 14:48:50 +0200 Subject: [PATCH 02/19] ok --- 01_Fundamentals.ipynb | 91 ++++++++++++++++++++++++++++++++--------- 01ex_Fundamentals.ipynb | 6 +-- 2 files changed, 75 insertions(+), 22 deletions(-) diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index 07435ca..eeea15e 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -429,9 +429,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], "source": [ "def fib1(n):\n", " \"\"\"Fib with recursion.\"\"\"\n", @@ -449,9 +457,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], "source": [ "# In Python, a more efficient version that does not use recursion is\n", "\n", @@ -467,9 +483,18 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 loops, best of 3: 6.67 ms per loop\n", + "100000 loops, best of 3: 4.2 µs per loop\n" + ] + } + ], "source": [ "# check indeed the timing:\n", "\n", @@ -578,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -597,9 +622,19 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Something is happening before the function is called.\n", + "Whee!\n", + "Something is happening after the function is called.\n" + ] + } + ], "source": [ "say_whee()" ] @@ -617,9 +652,18 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('buddy', 12)\n", + "6.0\n" + ] + } + ], "source": [ "class Pet:\n", " # the \"constructor\"\n", @@ -641,9 +685,18 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tobia\n", + "70\n" + ] + } + ], "source": [ "# ineritance is straightforward\n", "class Dog(Pet):\n", diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb index 5852179..135dff2 100644 --- a/01ex_Fundamentals.ipynb +++ b/01ex_Fundamentals.ipynb @@ -153,14 +153,14 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.4" + "pygments_lexer": "ipython2", + "version": "2.7.15rc1" } }, "nbformat": 4, From 83ad8fdee03c54dd92fd9a613c2f157926d4e584 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Wed, 17 Oct 2018 15:30:55 +0200 Subject: [PATCH 03/19] yes --- 01_Fundamentals.ipynb | 49 +++++++++---------------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index b65478b..5d8aad7 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -457,15 +457,8 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 10, -======= - "execution_count": 80, ->>>>>>> upstream/master -======= + "execution_count": null, ->>>>>>> upstream/master "metadata": {}, "outputs": [], "source": [ @@ -483,33 +476,23 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 11, -======= + "execution_count": 81, ->>>>>>> upstream/master + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ -<<<<<<< HEAD - "100 loops, best of 3: 6.67 ms per loop\n", - "100000 loops, best of 3: 4.2 µs per loop\n" -======= + "7.27 ms ± 90.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "4.47 µs ± 108 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ->>>>>>> upstream/master + ] } ], -======= - "execution_count": null, - "metadata": {}, - "outputs": [], ->>>>>>> upstream/master + "source": [ "# check indeed the timing:\n", "\n", @@ -618,15 +601,9 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 4, -======= - "execution_count": 85, ->>>>>>> upstream/master -======= + "execution_count": null, ->>>>>>> upstream/master + "metadata": {}, "outputs": [], "source": [ @@ -651,15 +628,9 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 5, -======= - "execution_count": 86, ->>>>>>> upstream/master -======= + "execution_count": null, ->>>>>>> upstream/master + "metadata": {}, "outputs": [], "source": [ From 3cde8da28b518ad5e95c1535f87c876d6fb53704 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Wed, 17 Oct 2018 15:33:48 +0200 Subject: [PATCH 04/19] yes --- 01_Fundamentals.ipynb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index 5d8aad7..e1551d1 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -429,15 +429,8 @@ }, { "cell_type": "code", -<<<<<<< HEAD -<<<<<<< HEAD - "execution_count": 9, -======= - "execution_count": 79, ->>>>>>> upstream/master -======= + "execution_count": null, ->>>>>>> upstream/master "metadata": {}, "outputs": [], "source": [ From a9ddca8490bdb699c161b292670e82501b20b7e2 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Mon, 22 Oct 2018 14:21:06 +0200 Subject: [PATCH 05/19] yes --- 01_Fundamentals.ipynb | 177 +++++++++++++++++++++++++++++++++--------- 1 file changed, 140 insertions(+), 37 deletions(-) diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index e1551d1..d71b75e 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -87,9 +87,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "8\n", + "('cube', 8)\n", + "('square', 4)\n" + ] + } + ], "source": [ "def square(x):\n", " \"\"\"Square of x.\"\"\"\n", @@ -229,9 +240,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 4, 9, 16]\n", + "0\n", + "1\n", + "4\n", + "9\n", + "16\n" + ] + } + ], "source": [ "x = list(map(square, range(5)))\n", "print (x)\n", @@ -282,9 +306,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "15" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from functools import reduce\n", "\n", @@ -306,9 +341,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 10, 'a')\n", + "(2, 20, 'b')\n", + "(3, 30, 'c')\n", + "(4, 40, 'd')\n" + ] + } + ], "source": [ "xs = [1, 2, 3, 4]\n", "ys = [10, 20, 30, 40]\n", @@ -327,9 +373,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "TypeError", + "evalue": "() takes exactly 2 arguments (1 given)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcube\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mcustom_sum\u001b[0;34m(xs, transform)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Returns the sum of xs after a user specified transform.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mxs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: () takes exactly 2 arguments (1 given)" + ] + } + ], "source": [ "def custom_sum(xs, transform):\n", " \"\"\"Returns the sum of xs after a user specified transform.\"\"\"\n", @@ -391,9 +450,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "7" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "sum = lambda x,y: x+y\n", "sum(3,4)" @@ -401,18 +471,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "5\n", + "11\n", + "19\n", + "29\n" + ] + } + ], "source": [ "for i in map(lambda x: x*x+3*x+1, range(5)): print (i)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "285\n" + ] + } + ], "source": [ "# what does this function do?\n", "from functools import reduce\n", @@ -429,10 +519,17 @@ }, { "cell_type": "code", - - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], "source": [ "def fib1(n):\n", " \"\"\"Fib with recursion.\"\"\"\n", @@ -450,10 +547,17 @@ }, { "cell_type": "code", - - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], "source": [ "# In Python, a more efficient version that does not use recursion is\n", "\n", @@ -469,23 +573,18 @@ }, { "cell_type": "code", - - "execution_count": 81, - + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - - "7.27 ms ± 90.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", - "4.47 µs ± 108 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" - + "100 loops, best of 3: 4.66 ms per loop\n", + "100000 loops, best of 3: 3.41 µs per loop\n" ] } ], - "source": [ "# check indeed the timing:\n", "\n", @@ -594,9 +693,7 @@ }, { "cell_type": "code", - - "execution_count": null, - + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -621,11 +718,17 @@ }, { "cell_type": "code", - - "execution_count": null, - + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Whee!\n" + ] + } + ], "source": [ "say_whee()" ] From 4370904cf73f8121c088062d0b784007b94f9ff1 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Tue, 30 Oct 2018 22:07:52 +0100 Subject: [PATCH 06/19] exercises --- .../01_Fundamentls-checkpoint.ipynb | 6 - .../02_NumberRepresentation-checkpoint.ipynb | 6 - 01_Fundamentals.ipynb | 53 +- 01ex_Fundamentals.ipynb | 2 +- 02_NumberRepresentation.ipynb | 528 +++++++++++++++++- 02ex_NumberRepresentation.ipynb | 119 ++++ 02ex_NumberRepresentation_andrea.ipynb | 436 +++++++++++++++ README.md | 42 +- 8 files changed, 1113 insertions(+), 79 deletions(-) delete mode 100644 .ipynb_checkpoints/01_Fundamentls-checkpoint.ipynb delete mode 100644 .ipynb_checkpoints/02_NumberRepresentation-checkpoint.ipynb create mode 100644 02ex_NumberRepresentation.ipynb create mode 100644 02ex_NumberRepresentation_andrea.ipynb diff --git a/.ipynb_checkpoints/01_Fundamentls-checkpoint.ipynb b/.ipynb_checkpoints/01_Fundamentls-checkpoint.ipynb deleted file mode 100644 index 2fd6442..0000000 --- a/.ipynb_checkpoints/01_Fundamentls-checkpoint.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/.ipynb_checkpoints/02_NumberRepresentation-checkpoint.ipynb b/.ipynb_checkpoints/02_NumberRepresentation-checkpoint.ipynb deleted file mode 100644 index 2fd6442..0000000 --- a/.ipynb_checkpoints/02_NumberRepresentation-checkpoint.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb index d71b75e..9a6ef3a 100644 --- a/01_Fundamentals.ipynb +++ b/01_Fundamentals.ipynb @@ -37,11 +37,11 @@ "print (m.pi)\n", "\n", "# alternatively you can import only a given \"thing\" from the library\n", - "from math import pi\n", + "from math import pi #se ci metto una virgola e altre cose, le importa\n", "print (pi)\n", "\n", "# or just get everything (very dangerous!!!)\n", - "from math import *\n", + "from math import * #scomodo perché magari importa roba con un nome specifico che non posso più usare, ma non conoscendole non me ne accorgo\n", "print (sqrt(7))" ] }, @@ -170,6 +170,13 @@ "print (x)\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La prima funzione riassegna al \"\"\"\"\"puntatore\"\"\"\"\" a x[0] un numero nuovo, che quindi è cambiato per sempre. !! se provassi a farlo con una variabile semplice (un numero) non funzionerebbe" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -257,7 +264,7 @@ } ], "source": [ - "x = list(map(square, range(5)))\n", + "x = list(map(square, range(5))) \n", "print (x)\n", "\n", "# Note the difference w.r.t python 2. In python 3 map retuns an iterator so you can do stuff like:\n", @@ -419,7 +426,7 @@ " f.write(data + '\\n')\n", " return logger\n", "\n", - "foo_logger = make_logger('foo.txt')\n", + "foo_logger = make_logger('foo.txt') #foo.txt verrà creato se non esiste già\n", "foo_logger('Hello')\n", "foo_logger('World')" ] @@ -430,7 +437,7 @@ "metadata": {}, "outputs": [], "source": [ - "! cat 'foo.txt'" + "! type 'foo.txt'" ] }, { @@ -487,7 +494,7 @@ } ], "source": [ - "for i in map(lambda x: x*x+3*x+1, range(5)): print (i)" + "for i in map(lambda x: x*x, range(5)): print (i)" ] }, { @@ -506,7 +513,7 @@ "source": [ "# what does this function do?\n", "from functools import reduce\n", - "s1 = reduce(lambda x, y: x+y, map(lambda x: x**2, range(1,10)))\n", + "s1 = reduce(lambda x, y: x+y, map(lambda x: x**2, range(1,10))) #reduce serve a sommare tutte le coppie\n", "print(s1)\n" ] }, @@ -704,16 +711,10 @@ " print(\"Something is happening after the function is called.\")\n", " return wrapper\n", "\n", - "@my_decorator\n", "def say_whee():\n", - " print(\"Whee!\")\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "@my_decorator is just an easier way of saying say_whee = my_decorator(say_whee). It’s how you apply a decorator to a function." + " print(\"Whee!\")\n", + "\n", + "say_whee = my_decorator(say_whee)" ] }, { @@ -761,10 +762,10 @@ "source": [ "class Pet:\n", " # the \"constructor\"\n", - " def __init__(self, name, age):\n", + " def __init__(self, name, age): #inizializza gli elementi delle classe Pet\n", " self.name=name\n", " self.age=age\n", - " # class functions take the \"self\" parameter \n", + " # class functions take the \"self\" parameter !!!\n", " def set_name(self,name):\n", " self.name=name\n", " def convert_age(self,factor):\n", @@ -772,7 +773,7 @@ "\n", "buddy=Pet(\"buddy\",12)\n", "print (buddy.name, buddy.age)\n", - "buddy.convert_age(0.5)\n", + "buddy.age=3\n", "print (buddy.age)\n", "\n" ] @@ -809,6 +810,20 @@ "\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "! tenere le def delle funzioni dentro la classe mi permette di riferirmi alle proprietà della classe" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "! sono come struct, ma che prima definisci e poi riempi" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb index 2bfeee7..79a07fe 100644 --- a/01ex_Fundamentals.ipynb +++ b/01ex_Fundamentals.ipynb @@ -42,7 +42,7 @@ "x = 5\n", "def f(alist):\n", " for i in range(x):\n", - " alist.append(i)\n", + " alist.append(i)\n", " return alist\n", "\n", "alist = [1,2,3]\n", diff --git a/02_NumberRepresentation.ipynb b/02_NumberRepresentation.ipynb index 3d916ac..8e36862 100644 --- a/02_NumberRepresentation.ipynb +++ b/02_NumberRepresentation.ipynb @@ -4,25 +4,65 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Binary and Hexadecimal representations" + "# Integers\n", + "\n", + "Integrers number are represented by N bits words. Python 3 allows you to store integers with practically unlimited precision, the only limitation comes from the (contiguos) space available in memory.\n", + "In python 2, N depends on the PC architercture, N=64 in modern computers.\n", + "\n", + "Typically 1 bit is dedicated to specifying the sign fo the number, thus the conversion between binary and decimal representation is:\n", + "\n", + "$d = (-1)^j\\sum_{i=0}^{N-1} \\alpha_i ~ 2^i$\n", + "\n", + "where $\\alpha_i$ are either $0$ or $i$ and the $b=\\alpha_{N-1}\\alpha_{N-2}..\\alpha_0$ is the binary representation of the number." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Binary representation of 18 : 0b10010\n", - "Hexadecimal representation of 18 : 0x12\n", - "Decimal representation of 0b10010 : 18\n", - "Decimal representation of 0x12 : 18\n" - ] - } - ], + "outputs": [], + "source": [ + "import sys\n", + "print (sys.maxsize)\n", + "\n", + "# check \n", + "print (2**63-1 == sys.maxsize)\n", + "\n", + "# python 3 doesn't have a limit for integers\n", + "print (sys.maxsize+1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "incidentally note that python 3 recast int to floats when dividing them with `/`. To keep the old functionality of `/`, use instead `//`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print (2/3)\n", + "print (2//3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Binary and Hexadecimal representations\n", + "\n", + "numbers values (in python as all the other languages) are assumed to be expressed as decimal. Built-in functions allows explicitly to convert from one representation to another. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# an integer in decimal representation\n", "a=18\n", @@ -57,7 +97,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -65,14 +105,13 @@ "b = 13 # 13 = 0000 1101 \n", "\n", "c = a & b; # 12 = 0000 1100\n", - "print \"Logical AND \", c\n", + "print (\"Logical AND \", c)\n", "\n", "c = a | b; # 61 = 0011 1101 \n", - "print \"Logical OR \", c\n", + "print (\"Logical OR \", c)\n", "\n", "c = a ^ b; # 49 = 0011 0001\n", - "print \"Logical XOR \", c\n", - "\n" + "print (\"Logical XOR \", c)" ] }, { @@ -89,8 +128,7 @@ "outputs": [], "source": [ "c = ~a; # -61 = 1100 0011\n", - "print \"Negation of a \", c\n", - "\n" + "print (\"Negation of a \", c)" ] }, { @@ -107,12 +145,454 @@ "outputs": [], "source": [ "c = a << 2; # 240 = 1111 0000\n", - "print \"Left shift (towards most significant) of two positions \", c\n", + "print (\"Left shift (towards most significant) of two positions \", c)\n", "\n", "c = a >> 2; # 15 = 0000 1111\n", - "print \"Right shift (towards least significant) of two positions \", c\n", - "\n" + "print (\"Right shift (towards least significant) of two positions \", c)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Floating point numbers\n", + "\n", + "non-integer number cannot be represent with infinite precision on a computer. Single (also known as *float*) and double precision numbers are assigned 32 and 64 bits respectively. \n", + "Note that all floating point numbers in python are double precision (64 bits).\n", + "A standard has been developed by IEEE such that the relative precision (see later) is the same in the whole validity range.\n", + "\n", + "The 32 or 64 bits are divided among 3 quantities uniquely characterizing the number:\n", + "\n", + "$x_{float} = (-1)^s \\times 1.f \\times 2^{e-bias}$\n", + "\n", + "where *s* is the sign, *f* the fractional part of the mantissa and *e* the exponent. In order to get numbers smaller than 1, a constant *bias* term is added to the exponent, such *bias* is typically equal to half of the max value of *e*.\n", + "The mantissa is defined as:\n", + "\n", + "${\\rm mantissa}=1.f=1+m_{n-1}2^{-1}+m_{n-2}2^{-2}+..+m_{0}2^{-n}$\n", + "\n", + "where $n$ is the number of bits dedicated to *f* (see below) and $m_i$ are the binary coefficients. \n", + "\n", + "Numbers exceeding the maximum allowed value are *overflows* and the calculations involving them provide incorrect answers. Numbers smaller in absolute value than the minimum allowed value are *underflows* and simply set to zero, also in this case incorrect results are yielded. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Single\n", + "\n", + "For single precision floating point numbers, $0\\le e \\le 255$ and $bias=127$. Bits are arranged as follows:\n", + "\n", + "| | *s* | *e* | *f* |\n", + "|---|---|---|---|\n", + "| Bit position | 31 | 30-23 | 22-0 |\n", + "\n", + "Special values are also possibiles. N.B.: those are not numbers that can be used in the mathematical sense!\n", + "\n", + "| | conditions | value |\n", + "|---|---|---|\n", + "| $+\\infty$ | s=0, e=255, f=0 | +INF |\n", + "| $-\\infty$ | s=1, e=255, f=0 | +INF |\n", + "| not a number | e=255, f>0 | NaN |\n", + "\n", + "The largest value is obtained for $f\\sim 2$ and $e=254$, i.e. $2\\times2^{127}\\sim 3.4\\times2^{38}$.\n", + "\n", + "The value closest to zero is obtained instead for $f=2^{-23}$ and $e=0$, i.e. $2^{-149}\\sim 1.4\\times2^{45}$.\n", + "\n", + "An example is given below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Image\n", + "Image(url='http://www.dspguide.com/graphics/F_4_2.gif')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Double\n", + "\n", + "For double precision floating point numbers, $0\\le e \\le 2047$ and $bias=1023$. Bits are arranged as follows:\n", + "\n", + "| | *s* | *e* | *f* |\n", + "|---|---|---|---|\n", + "| Bit position | 63 | 62-52 | 51-0 |\n", + "\n", + "Special values are also possibiles. N.B.: those are not numbers that can be used in the mathematical sense!\n", + "\n", + "| | conditions | value |\n", + "|---|---|---|\n", + "| $+\\infty$ | s=0, e=2047, f=0 | +INF |\n", + "| $-\\infty$ | s=1, e=2047, f=0 | +INF |\n", + "| not a number | e=2047, f>0 | NaN |\n", + "\n", + "The validity range for double numbers is $2.2^{-308} - 1.8^{308}$\n", + "\n", + "Serious scientific calculations almost always requires at least double precision floating point numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Floating point numbers on your system\n", + "\n", + "Information about the floating point reresentation on your system can be obtained from sys.float_info. Definitions of the stored values are given on the python doc [page](https://docs.python.org/2/library/sys.html#sys.float_info)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "print (sys.float_info)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Accuracy and the perils of calculations with floats\n", + "\n", + "\n", + "Floats can only have a limited number of meaningful decimal places, on the basis of how many bits are allocated for the fractional part of the mantissa: 6-7 decimal places for singles, 15-16 for doubles. In particular this means that calculations involving numbers with more than those decimal places involved do not yield the correct result, simply because the binary representation of those numbers could not store them properly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for e in [14,15,16]: print (7+1.0*10**-e)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It should never been forgotten that computers store numbers in binary format. In the same way it is not possible to express the fraction 1/3 with a finite decimal places, analogously fraction well represented in the decimal base cannot be represented in binary, e.g. 1/10 is the infinitely repeating number:\n", + "\n", + "$0.0001100110011001100110011001100110011001100110011...$\n", + "\n", + "corresponding to $3602879701896397/2^{55}$ which is close to but not exactly equal to the true value of 1/10 (even though it is even printed to be like that!!.\n", + "Similarly 0.1 is not 1/10, and making calculations assuming that exactly typically yield to wrong results:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# is 1/10 the same of 0.1?\n", + "print (1/10)\n", + "\n", + "# but then whatch out!!\n", + "0.1 + 0.1 + 0.1 == 0.3\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A lesson of paramount importance is that you must never compare floating point numbers with the \"==\" operator as **what is printed is not what is stored**!!\n", + "\n", + "The function ```float.hex()``` yield the exact value stored for a floating point number:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "x=math.pi\n", + "print (x)\n", + "print (x.hex())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are ways to print floats (e.g. filling data into an output file) controlling the number of decimals:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print (format(math.pi, '.13f')) # give 13 significant digits\n", + "\n", + "print ('%.17f' % (0.1 * 0.1 * 100)) # give 15 significant digits\n", + "\n", + "# now repeat trying with >15 digits!\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is no bug here, this is simply due to the fact that the mantissa is represented by a limited amount of bits, therefore calculations can only make sense if a corresponding number of decimal digits are concerned:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 23 bits are used for f in single precision floating points \n", + "print (2**-23)\n", + "\n", + "# 53 bits are used for f in single precision floating points \n", + "print (2**-53)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A typical case is subtraction of numbers very close by in value (e.g. when dealing with spectral frequencies). The same happens with functions evaluated near critical points (see later)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 + 6.022e23 - 6.022e23" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Associative law does not necessarily hold:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print (6.022e23 - 6.022e23 + 1)\n", + "print (1 + 6.022e23 - 6.022e23)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Distributive law does not hold" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "a = math.exp(1);\n", + "b = math.pi;\n", + "c = math.sin(1);\n", + "a*(b+c) == a*b+a*c" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# (we'll see numpy soon, bear with me for the moment)\n", + "\n", + "# loss of precision can be a problem when calculating likelihoods\n", + "import numpy as np\n", + "probs = np.random.random(1000)\n", + "print (np.prod(probs))\n", + "\n", + "# when multiplying lots of small numbers, work in log space\n", + "print (np.sum(np.log(probs)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## From numbers to Functions: Stability and conditioning\n", + "\n", + "Suppose we have a computer algorithm $g(x)$ that represents the mathematical function $f(x)$. $g(x)$ is stable if for some small perturbation $\\epsilon$, $g(x+\\epsilon)\\simeq f(x)$\n", + "\n", + "A mathematical function $f(x)$ is well-conditioned if $f(x+\\epsilon)\\simeq f(x)$ for all small perturbations $\\epsilon$.\n", + "\n", + "That is, the functionf(x) is **well-conditioned** if the solution varies gradually as problem varies. For a well-conditinoed function, all small perutbations have small effects. However, a poorly-conditioned problem only needs some small perturbations to have large effects. For example, inverting a nearly singluar matrix is a poorly conditioned problem.\n", + "\n", + "A numerical algorithm $g(x)$ is numerically-stable if $g(x)\\simeq f(x′)$ for some $x′\\simeq x$. Note that stability is a property that relates the algorithm $g(x)$ to the problem $f(x)$.\n", + "\n", + "That is, the algorithm $g(x)$ is **numerically stable** if it gives nearly the right answer to nearly the right question. Numerically unstable algorithms tend to amplify approximation errors due to computer arithmetic over time. If we used an infitinte precision numerical system, stable and unstable alorithms would have the same accuracy. However, as we have seen (e.g. variance calculation), when using floating point numbers, algebrically equivaelent algorithms can give different results.\n", + "\n", + "In general, we need both a well-conditinoed problem and nuerical stabilty of the algorihtm to reliably accurate answers. In this case, we can be sure that $g(x)\\simeq f(x)$.\n", + "\n", + "In most of the cases, the solution to stability issues is properly redefying the function as in the example above with the likelihood. More examples follow " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The tangent function is poorly conditioned\n", + "\n", + "import math\n", + "x1 = 1.57078\n", + "x2 = 1.57079\n", + "t1 = math.tan(x1)\n", + "t2 = math.tan(x2)\n", + "\n", + "print ('t1 =', t1)\n", + "print ('t2 =', t2)\n", + "print ('% change in x =', 100.0*(x2-x1)/x1)\n", + "print ('% change in tan(x) =', (100.0*(t2-t1)/t1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Catastrophic cancellation occurs when subtracitng\n", + "# two numbers that are very close to one another\n", + "# Here is another example\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "% matplotlib inline\n", + "\n", + "def f(x):\n", + " return (1 - np.cos(x))/(x*x)\n", + "\n", + "x = np.linspace(-4e-8, 4e-8, 100)\n", + "plt.plot(x,f(x));\n", + "plt.axvline(1.1e-8, color='red')\n", + "plt.xlim([-4e-8, 4e-8]);\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# We know from L'Hopital's rule that the answer is 0.5 at 0\n", + "# and should be very close to 0.5 throughout this tiny interval\n", + "# but errors arisee due to catastrophic cancellation\n", + "\n", + "print ('%.30f' % np.cos(1.1e-8))\n", + "print ('%.30f' % (1 - np.cos(1.1e-8))) # exact answer is 6.05e-17\n", + "print ('%2f' % ((1 - np.cos(1.1e-8))/(1.1e-8*1.1e-8)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Numerically stable version of funtion using simple trignometry\n", + "\n", + "def f1(x):\n", + " return 2*np.sin(x/2)**2/(x*x)\n", + "\n", + "x = np.linspace(-4e-8, 4e-8, 100)\n", + "plt.plot(x,f1(x));\n", + "plt.axvline(1.1e-8, color='red')\n", + "plt.xlim([-4e-8, 4e-8]);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Stable and unstable version of the variance:\n", + "\n", + "$s^2 = \\frac{1}{n-1} \\sum (x-\\bar{x})^2$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# sum of squares method (vectorized version)\n", + "# watch out! big number minus big number!\n", + "def sum_of_squers_var(x):\n", + " n = len(x)\n", + " return (1.0/(n*(n-1))*(n*np.sum(x**2) - (np.sum(x))**2))\n", + "\n", + "# direct method\n", + "# squaring occuring after subtraction\n", + "def direct_var(x):\n", + " n = len(x)\n", + " xbar = np.mean(x)\n", + " return 1.0/(n-1)*np.sum((x - xbar)**2)\n", + "\n", + "\n", + "# Welford's method\n", + "# an optimized method\n", + "def welford_var(x):\n", + " s = 0\n", + " m = x[0]\n", + " for i in range(1, len(x)):\n", + " m += (x[i]-m)/i\n", + " s += (x[i]-m)**2\n", + " return s/(len(x) -1 )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# check the performances with an array \n", + "# of randomly distributed data around 1e12\n", + "\n", + "x_ = np.random.uniform(0,1,int(1e3))\n", + "x = 1e12 + x_\n", + "\n", + "# correct answer\n", + "print (np.var(x_))\n", + "\n", + "print (sum_of_squers_var(x))\n", + "print (direct_var(x))\n", + "print (welford_var(x))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/02ex_NumberRepresentation.ipynb b/02ex_NumberRepresentation.ipynb new file mode 100644 index 0000000..1bd815f --- /dev/null +++ b/02ex_NumberRepresentation.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1\\. Write a function that converts number representation (bin<->dec<->hex)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2\\. Write a function that converts a 32 bit word into a single precision floating point (i.e. interprets the various bits as sign, mantissa and exponent)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3\\. Write a program to determine the underflow and overflow limits (within a factor of 2) for python on your computer. \n", + "\n", + "**Tips**: define two variables inizialized to 1 and halve/double them enough time to exceed the under/over-flow limits " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4\\. Write a program to determine the machine precision\n", + "\n", + "**Tips**: define a new variable by adding a smaller and smaller value (proceeding similarly to prob. 2) to an original variable and check the point where the two are the same " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5\\. Write a function that takes in input three parameters $a$, $b$ and $c$ and prints out the two solutions to the quadratic equation $ax^2+bx+c=0$ using the standard formula:\n", + "$$\n", + "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}\n", + "$$\n", + "\n", + "(a) use the program to compute the solution for $a=0.001$, $b=1000$ and $c=0.001$\n", + "\n", + "(b) re-express the standard solution formula by multiplying top and bottom by $-b\\mp\\sqrt{b^2-4ac}$ and again find the solution for $a=0.001$, $b=1000$ and $c=0.001$. How does it compare with what previously obtained? Why?\n", + "\n", + "(c) write a function that compute the roots of a quadratic equation accurately in all cases" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "6\\. Write a program that implements the function $f(x)=x(x−1)$\n", + "\n", + "(a) Calculate the derivative of the function at the point $x = 1$ using the derivative definition:\n", + "\n", + "$$\n", + "\\frac{{\\rm d}f}{{\\rm d}x} = \\lim_{\\delta\\to0} \\frac{f(x+\\delta)-f(x)}{\\delta}\n", + "$$\n", + "\n", + "with $\\delta = 10^{−2}$. Calculate the true value of the same derivative analytically and compare with the answer your program gives. The two will not agree perfectly. Why not?\n", + "\n", + "(b) Repeat the calculation for $\\delta = 10^{−4}, 10^{−6}, 10^{−8}, 10^{−10}, 10^{−12}$ and $10^{−14}$. How does the accuracy scales with $\\delta$?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "7\\. Consider the integral of the semicircle of radius 1:\n", + "$$\n", + "I=\\int_{-1}^{1} \\sqrt(1-x^2) {\\rm d}x\n", + "$$\n", + "which it's known to be $I=\\frac{\\pi}{2}=1.57079632679...$.\n", + "Alternatively we can use the Riemann definition of the integral:\n", + "$$\n", + "I=\\lim_{N\\to\\infty} \\sum_{k=1}^{N} h y_k \n", + "$$\n", + "\n", + "with $h=2/N$ the width of each of the $N$ slices the domain is divided into and where\n", + "$y_k$ is the value of the function at the $k-$th slice.\n", + "\n", + "(a) Write a programe to compute the integral with $N=100$. How does the result compares to the true value?\n", + "\n", + "(b) How much can $N$ be increased if the computation needs to be run in less than a second? What is the gain in running it for 1 minute? \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/02ex_NumberRepresentation_andrea.ipynb b/02ex_NumberRepresentation_andrea.ipynb new file mode 100644 index 0000000..dff935b --- /dev/null +++ b/02ex_NumberRepresentation_andrea.ipynb @@ -0,0 +1,436 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "La rappresentazione decimale del numero inserito è 678\n", + "La rappresentazione esadecimale del numero inserito è 0x2a6\n", + "0b1010100110\n", + "0x2a6\n", + "La rappresentazione decimale del numero inserito è 678\n", + "La rappresentazione binaria del numero inserito è 0b1010100110\n", + "La rappresentazione binaria del numero inserito è 0b1010100110\n", + "La rappresentazione esadecimale del numero inserito è 0x2a6\n" + ] + } + ], + "source": [ + "#1\n", + "def convert(a):\n", + " hexa = {\"0\": 0, \"1\" : 1, \"2\" : 2, \"3\" : 3, \"4\" : 4, \"5\":5, \"6\":6, \"7\":7, \"8\":8, \"9\":9, \"a\":10, \"b\":11, \"c\":12, \"d\":13,\"e\":14,\"f\":15}\n", + " hexainv = {hexa[i]: i for i in hexa}\n", + " if type(a) != int:\n", + " alist = [i for i in a]\n", + " if alist[1] == \"b\": \n", + " adec = 0\n", + " atemp1 = 0\n", + " atemp2 = 0\n", + " ahex = \"\"\n", + " k = 0\n", + " e = 0\n", + " for j in range(2,len(alist)):\n", + " adec = adec + int(alist[len(alist)-j+1])*2**(j - 2)\n", + " k = k + 1\n", + " if k == 4 or j == (len(alist) - 1) :\n", + " #print(adec)\n", + " atemp1 = (adec - atemp2)\n", + " #print(atemp1)\n", + " ahex = hexainv[(atemp1/(16**e))] + ahex\n", + " #print(ahex)\n", + " atemp2 = atemp1+atemp2\n", + " k = 0\n", + " e = e + 1\n", + " print(\"La rappresentazione decimale del numero inserito è %d\" %adec)\n", + " print(\"La rappresentazione esadecimale del numero inserito è 0x%s\" %ahex)\n", + " elif alist[1] == \"x\":\n", + " adec = 0\n", + " abin = \"\"\n", + " for j in range(2,len(alist)):\n", + " adec = adec + hexa[alist[len(alist)-j+1]]*16**(j - 2)\n", + " print(\"La rappresentazione decimale del numero inserito è %d\" %adec)\n", + " while adec != 0:\n", + " abin = str(adec%2) + abin\n", + " adec = int(adec/2)\n", + " print(\"La rappresentazione binaria del numero inserito è 0b%s\" %abin)\n", + " #print(alist)\n", + " elif type(a) == int:\n", + " ahex = \"\"\n", + " abin = \"\"\n", + " adec = a\n", + " while adec != 0:\n", + " abin = str(adec%2) + abin\n", + " adec = int(adec/2)\n", + " print(\"La rappresentazione binaria del numero inserito è 0b%s\" %abin)\n", + " alist = [i for i in abin]\n", + " alist.reverse()\n", + " k = 0\n", + " e = 0\n", + " atemp = 0\n", + " atemp2 = 0\n", + " atemp1 = 0\n", + " for i in range(len(alist)):\n", + " atemp = atemp + int(alist[i])*2**i\n", + " k = k + 1\n", + " if k == 4 or i == (len(alist) - 1) :\n", + " atemp1 = (atemp - atemp2)\n", + " #print(atemp1)\n", + " ahex = hexainv[(atemp1/(16**e))] + ahex\n", + " #print(ahex)\n", + " atemp2 = atemp1+atemp2\n", + " k = 0\n", + " e = e + 1\n", + " print(\"La rappresentazione esadecimale del numero inserito è 0x%s\" %ahex) \n", + "\n", + "A = 678\n", + "convert(bin(A))\n", + "print(bin(A))\n", + "print(hex(A))\n", + "convert(hex(A))\n", + "convert(A)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1\\. Write a function that converts number representation (bin<->dec<->hex)" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "# 2\\. Write a function that converts a 32 bit word into a single precision floating point (i.e. interprets the various bits as sign, mantissa and exponent)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0b10000000110000000000000000000000\n", + "-1.7632415262334313e-38\n", + "Spiacente, la funzione accetta solo interi entro i 32 bit!\n", + "1.7632415262334313e-38\n" + ] + } + ], + "source": [ + "#2\n", + "def singlefloat(a):\n", + " if a >= 2**32 or type(a) != int:\n", + " print(\"Spiacente, la funzione accetta solo interi entro i 32 bit!\")\n", + " afloat = 1.\n", + " e = 0\n", + " bias = 127\n", + " for i in range(0,23):\n", + " afloat = afloat + (a & 2**i)*2**(-23)\n", + " #print(afloat)\n", + " for i in range(23,31):\n", + " e = e + ((a & 2**i)/2**i)*2**(i-23)\n", + " e = e - 127\n", + " #print(e)\n", + " afloat = afloat*2**e\n", + " if a & 2**31 == 0:\n", + " afloat = afloat\n", + " elif a & 2**31 == 2**31: \n", + " afloat = -afloat \n", + " return(afloat)\n", + "\n", + "A = 2**31+2**23+2**22\n", + "print(bin(A))\n", + "print(singlefloat(A))\n", + "#singlefloat(2**34)\n", + "print(1.5*2**-126)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3\\. Write a program to determine the underflow and overflow limits (within a factor of 2) for python on your computer. \n", + "\n", + "**Tips**: define two variables inizialized to 1 and halve/double them enough time to exceed the under/over-flow limits " + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5e-324 is the underflow limit within a factor of 2\n", + "8.98846567431158e+307 is the overflow limit within a factor of 2\n" + ] + } + ], + "source": [ + "#3\n", + "under = 1.\n", + "over = 1.\n", + "temp1 = 0.\n", + "temp2 = 0.\n", + "k = 1.\n", + "while under > 0:\n", + " temp1 = under\n", + " under = under/2\n", + "print(temp1, \"is the underflow limit within a factor of 2\")\n", + "\n", + "while (over*2./over) == 2. :\n", + " over = over*2\n", + " temp2 = over\n", + "print(temp2, \"is the overflow limit within a factor of 2\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4\\. Write a program to determine the machine precision\n", + "\n", + "**Tips**: define a new variable by adding a smaller and smaller value (proceeding similarly to prob. 2) to an original variable and check the point where the two are the same " + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.000000000000001 è la massima precisione raggiungibile dal sistema\n" + ] + } + ], + "source": [ + "#4\n", + "aref = 1.\n", + "a = aref + 0.1\n", + "k = 1\n", + "temp = 0.\n", + "while (a-aref) > 0.:\n", + " k = k+1\n", + " temp = a\n", + " a = aref\n", + " a = a+10**(-k)\n", + "print(temp, \"è la massima precisione raggiungibile dal sistema\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5\\. Write a function that takes in input three parameters $a$, $b$ and $c$ and prints out the two solutions to the quadratic equation $ax^2+bx+c=0$ using the standard formula:\n", + "$$\n", + "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}\n", + "$$\n", + "\n", + "(a) use the program to compute the solution for $a=0.001$, $b=1000$ and $c=0.001$\n", + "\n", + "(b) re-express the standard solution formula by multiplying top and bottom by $-b\\mp\\sqrt{b^2-4ac}$ and again find the solution for $a=0.001$, $b=1000$ and $c=0.001$. How does it compare with what previously obtained? Why?\n", + "\n", + "(c) write a function that compute the roots of a quadratic equation accurately in all cases" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.999999\n", + "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.9999990001\n" + ] + } + ], + "source": [ + "#5.a\n", + "import math as m\n", + "def quadroot(a,b,c):\n", + " xplus = (-b + m.sqrt(b*b - 4*a*c))/(2*a)\n", + " xminus = (-b - m.sqrt(b*b - 4*a*c))/(2*a)\n", + " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(xplus,xminus))\n", + " \n", + "quadroot(0.001,1000,0.001)\n", + "\n", + "#5.b\n", + "def requadroot(a,b,c):\n", + " x1 = ((-b + m.sqrt(b*b - 4*a*c))*(-b - m.sqrt(b*b - 4*a*c)))/((2*a)*(-b - m.sqrt(b*b - 4*a*c)))\n", + " x2 = ((-b - m.sqrt(b*b - 4*a*c))*(-b + m.sqrt(b*b - 4*a*c)))/((2*a)*(-b + m.sqrt(b*b - 4*a*c)))\n", + " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(x1,x2))\n", + "\n", + "requadroot(0.001,1000,0.001)\n", + "\n", + "#5.c" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "6\\. Write a program that implements the function $f(x)=x(x−1)$\n", + "\n", + "(a) Calculate the derivative of the function at the point $x = 1$ using the derivative definition:\n", + "\n", + "$$\n", + "\\frac{{\\rm d}f}{{\\rm d}x} = \\lim_{\\delta\\to0} \\frac{f(x+\\delta)-f(x)}{\\delta}\n", + "$$\n", + "\n", + "with $\\delta = 10^{−2}$. Calculate the true value of the same derivative analytically and compare with the answer your program gives. The two will not agree perfectly. Why not?\n", + "\n", + "(b) Repeat the calculation for $\\delta = 10^{−4}, 10^{−6}, 10^{−8}, 10^{−10}, 10^{−12}$ and $10^{−14}$. How does the accuracy scales with $\\delta$?" + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.010000000000001\n", + "1.0000999999998899\n", + "1.0000009999177333\n", + "1.0000000039225287\n", + "1.000000082840371\n", + "1.0000889005833413\n", + "0.9992007221626509\n" + ] + } + ], + "source": [ + "#6.a\n", + "def f(x):\n", + " return x*(x-1)\n", + "\n", + "#calcolo della derivata\n", + "def fder(y, delta):\n", + " d = (f(y + delta) - f(y))/delta\n", + " return d\n", + "\n", + "acc = 0.01\n", + "fder(1, acc)\n", + "\n", + "#6.b\n", + "for i in range(2,16,2):\n", + " print(fder(1,10**-i))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "7\\. Consider the integral of the semicircle of radius 1:\n", + "$$\n", + "I=\\int_{-1}^{1} \\sqrt(1-x^2) {\\rm d}x\n", + "$$\n", + "which it's known to be $I=\\frac{\\pi}{2}=1.57079632679...$.\n", + "Alternatively we can use the Riemann definition of the integral:\n", + "$$\n", + "I=\\lim_{N\\to\\infty} \\sum_{k=1}^{N} h y_k \n", + "$$\n", + "\n", + "with $h=2/N$ the width of each of the $N$ slices the domain is divided into and where\n", + "$y_k$ is the value of the function at the $k-$th slice.\n", + "\n", + "(a) Write a programe to compute the integral with $N=100$. How does the result compares to the true value?\n", + "\n", + "(b) How much can $N$ be increased if the computation needs to be run in less than a second? What is the gain in running it for 1 minute? \n" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000000 0.8560192584991455 1.5707963267423612\n" + ] + } + ], + "source": [ + "#7.a\n", + "import math as m\n", + "import time as t\n", + "def f(x):\n", + " res = m.sqrt(1-x*x)\n", + " return res\n", + "\n", + "def integralf(a,b,N): \n", + " h = (abs(b-a)/N)\n", + " val = 0.\n", + " for i in range(1, N+1):\n", + " val = val + h*f(a+i*h)\n", + " return val\n", + "\n", + "N = 100\n", + "timetot = 0.\n", + "res = 0.\n", + "ttemp = 0.\n", + "Ntemp = 0\n", + "while timetot < 1.: #<61.\n", + " ttemp = timetot\n", + " Ntemp = N\n", + " start = t.time()\n", + " res = integralf(-1,1,N)\n", + " end = t.time()\n", + " N = N*10\n", + " timetot = end - start\n", + "print(Ntemp, ttemp, res)\n", + "#in 0.82 s il programma risulta accurato fino alla decima cifra decimale\n", + "#in 36.6 s il programma risulta accurato fino all'undicesima cifra decimale\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/README.md b/README.md index f526428..d5e63f2 100644 --- a/README.md +++ b/README.md @@ -46,18 +46,17 @@ In particular, if you are working in a location where such repo already exist, w `git fetch upstream` - * The default branch is `master`, you should now create your how development branch where to play and exercise with the code: + * The default branch is `master`, you should now create your development branch where to play and exercise with the code. Note that however you have a branch corresponding to you (name_surname) in the upstream repository (`upstream/name_surname`): that is the branch you should point the pull request to. In order to set up a proper development cycle, you must create a branch (in the example below called TRACKING_BRANCH_NAME) that *tracks* `upstream/name_surname`: -`git branch` +`git branch -vv` -`git checkout -b DEV_BRANCH_NAME` - -Now you `master` and `DEV_BRANCH_NAME` are the identical, work on the latter will tracked and later committed. +`git checkout -b TRACKING_BRANCH_NAME upstream/name_surname` +Note that the case you decide do make your development in a branch that does NOT track `upstream/name_surname`, you'll eventually need to merge your changes into the branch tracking `upstream/name_surname` which is the one you'll make the pull request for (see later). ### Standard development cycle - * Before starting with the development you could check whether the orginal repository (mzanetti79's one) have been updated with respect to your forked version (that's likely to be the case prior to every lab class). If it had, then merge the chances into your master: + * Before starting with the development you could check whether the orginal repository (mzanetti79's one) have been updated with respect to your forked version (that's likely to be the case prior to every lab class). If it had, then merge the chances into your master. `git fetch upstream` @@ -65,34 +64,31 @@ Now you `master` and `DEV_BRANCH_NAME` are the identical, work on the latter wil `git merge upstream/master` -this will update your local version, not the one on github. To update the latter you need to push the local version (see later) + The idea is that your master always reflects `upstream/master`, i.e. it keeps a local copy of the reference code as a starting point for your developments (i.e. solving the assigned problems). + Note that in order to update your repository on github, you need to push the local version (see later). + + * In the case a pull request of yours to mzanetti79 has been recently approved, you also need to synch your development branch: + + `git checkout TRACKING_BRANCH_NAME` - * From within your local repository choose your development branch and check it out (i.e. switch to it). : + `git merge upstream/name_surname` -`git checkout DEV_BRANCH_NAME` + * You may also need to get the updates from the master, i.e. need to merge the master: + + `git merge master` * Now do the real stuff, i.e. developing some code. Image you create a NEW_FILE. Add the file to your local repository and stages it for commit (To unstage a file, use 'git reset HEAD NEW_FILE)' -`git add NEW_FILE` + `git add NEW_FILE` * Commits the (tracked) changes you made to the file and prepares them to be pushed to your remote repository on github -`git commit -m "Add existing file"` + `git commit -m "Add existing file"` (what follows after `-m` is a comment to later remind what was that commit about) * Now you want to propagate (push) your local changes to your remote repository on github (`origin`) - `git push origin DEV_BRANCH_NAME` - - * Finally you may want to propagate your development also to the repo you originally forked from, i.e. mzanetti79's one (this is likely to happen anytime you'll be asked to deliver your homework!). For that you need to go for a "pull request", which is done from github itself. - - * To close a development loop is a good habit to clean up, i.e. get rid of the development branch. Prior to that you may want to merge the `master` branch - - `git checkout master` - - `git merge DEV_BRANCH_NAME` - - `git push origin master` + `git push origin TRACKING_BRANCH_NAME` - `git commit -d DEV_BRANCH_NAME` + * Finally you may want to propagate your development also to the repo you originally forked from, i.e. mzanetti79's one (this is likely to happen anytime you'll be asked to deliver your homework!). For that you need to go for a "pull request", which is done from github itself. Be carefull to point your pull request to `mzanetti79/name_surname` From 5f44a6e0057bab68d0126249447e3e0153f47cd2 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Tue, 6 Nov 2018 14:56:33 +0100 Subject: [PATCH 07/19] exercise 2 --- 02ex_NumberRepresentation_andrea.ipynb | 36 +++++++++++++++++++------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/02ex_NumberRepresentation_andrea.ipynb b/02ex_NumberRepresentation_andrea.ipynb index dff935b..06cbbe2 100644 --- a/02ex_NumberRepresentation_andrea.ipynb +++ b/02ex_NumberRepresentation_andrea.ipynb @@ -111,7 +111,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -120,8 +120,7 @@ "text": [ "0b10000000110000000000000000000000\n", "-1.7632415262334313e-38\n", - "Spiacente, la funzione accetta solo interi entro i 32 bit!\n", - "1.7632415262334313e-38\n" + "-1.7632415262334313e-38\n" ] } ], @@ -151,7 +150,7 @@ "print(bin(A))\n", "print(singlefloat(A))\n", "#singlefloat(2**34)\n", - "print(1.5*2**-126)" + "print(-1.5*2**-126)" ] }, { @@ -249,7 +248,7 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -257,19 +256,26 @@ "output_type": "stream", "text": [ "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.999999\n", - "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.9999990001\n" + "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.9999990001\n", + "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993352e-07 e x2 = -999999.9999989993\n" ] } ], "source": [ "#5.a\n", "import math as m\n", + "import numpy as n\n", + "\n", + "A = 0.001\n", + "B = 1000\n", + "C = 0.001\n", + "\n", "def quadroot(a,b,c):\n", " xplus = (-b + m.sqrt(b*b - 4*a*c))/(2*a)\n", " xminus = (-b - m.sqrt(b*b - 4*a*c))/(2*a)\n", " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(xplus,xminus))\n", " \n", - "quadroot(0.001,1000,0.001)\n", + "quadroot(A,B,C)\n", "\n", "#5.b\n", "def requadroot(a,b,c):\n", @@ -277,9 +283,18 @@ " x2 = ((-b - m.sqrt(b*b - 4*a*c))*(-b + m.sqrt(b*b - 4*a*c)))/((2*a)*(-b + m.sqrt(b*b - 4*a*c)))\n", " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(x1,x2))\n", "\n", - "requadroot(0.001,1000,0.001)\n", + "requadroot(A,B,C)\n", "\n", - "#5.c" + "#5.c\n", + "\n", + "def accquadroot(a,b,c):\n", + " #xp = (-m.exp(m.log(b)-m.log(2)-m.log(a)))+m.exp(0.5*m.log(b*b - 4*a*c)-m.log(2)-m.log(a))\n", + " xp = m.log(abs(-b+m.sqrt(b*b-4*a*c))) - m.log(2) - m.log(abs(a))\n", + " xp = n.sign(a)*n.sign(-b+m.sqrt(b*b-4*a*c))*m.exp(xp)\n", + " xm = (-m.exp(m.log(b)-m.log(2)-m.log(a)))-m.exp(0.5*m.log(b*b - 4*a*c)-m.log(2)-m.log(a))\n", + " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(xp,xm))\n", + " \n", + "accquadroot(A,B,C)" ] }, { @@ -333,7 +348,8 @@ "\n", "#6.b\n", "for i in range(2,16,2):\n", - " print(fder(1,10**-i))" + " print(fder(1,10**-i))\n", + " " ] }, { From e8b0b4d095407807dd013720c97dd2dd8540de11 Mon Sep 17 00:00:00 2001 From: andreadeans Date: Wed, 7 Nov 2018 10:58:57 +0100 Subject: [PATCH 08/19] exercise 2 --- 02ex_NumberRepresentation_andrea.ipynb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/02ex_NumberRepresentation_andrea.ipynb b/02ex_NumberRepresentation_andrea.ipynb index 06cbbe2..c08ba94 100644 --- a/02ex_NumberRepresentation_andrea.ipynb +++ b/02ex_NumberRepresentation_andrea.ipynb @@ -248,16 +248,16 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.999999\n", - "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993346e-07 e x2 = -999999.9999990001\n", - "Le soluzioni dell'equazione quadratica sono x1 = -9.999894245993352e-07 e x2 = -999999.9999989993\n" + "Le soluzioni dell'equazione quadratica sono x1 = -9.094947017729282e-09 e x2 = -100000000.0\n", + "Le soluzioni dell'equazione quadratica sono x1 = -9.094947017729282e-09 e x2 = -100000000.0\n", + "Le soluzioni dell'equazione quadratica sono x1 = -9.09494701772929e-09 e x2 = -99999999.99999982\n" ] } ], @@ -266,9 +266,9 @@ "import math as m\n", "import numpy as n\n", "\n", - "A = 0.001\n", - "B = 1000\n", - "C = 0.001\n", + "A = 0.0001\n", + "B = 10000\n", + "C = 0.0001\n", "\n", "def quadroot(a,b,c):\n", " xplus = (-b + m.sqrt(b*b - 4*a*c))/(2*a)\n", @@ -291,7 +291,8 @@ " #xp = (-m.exp(m.log(b)-m.log(2)-m.log(a)))+m.exp(0.5*m.log(b*b - 4*a*c)-m.log(2)-m.log(a))\n", " xp = m.log(abs(-b+m.sqrt(b*b-4*a*c))) - m.log(2) - m.log(abs(a))\n", " xp = n.sign(a)*n.sign(-b+m.sqrt(b*b-4*a*c))*m.exp(xp)\n", - " xm = (-m.exp(m.log(b)-m.log(2)-m.log(a)))-m.exp(0.5*m.log(b*b - 4*a*c)-m.log(2)-m.log(a))\n", + " xm = m.log(abs(-b-m.sqrt(b*b-4*a*c))) - m.log(2) - m.log(abs(a))\n", + " xm = n.sign(a)*n.sign(-b-m.sqrt(b*b-4*a*c))*m.exp(xm)\n", " print(\"Le soluzioni dell'equazione quadratica sono x1 = {} e x2 = {}\" .format(xp,xm))\n", " \n", "accquadroot(A,B,C)" From 2bb44c8774afeecc055d2ca19271fdf8ccbc26d4 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 14:51:40 +0100 Subject: [PATCH 09/19] Delete 01ex_Fundamentals.ipynb --- 01ex_Fundamentals.ipynb | 166 ---------------------------------------- 1 file changed, 166 deletions(-) delete mode 100644 01ex_Fundamentals.ipynb diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb deleted file mode 100644 index 79a07fe..0000000 --- a/01ex_Fundamentals.ipynb +++ /dev/null @@ -1,166 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1\\. Write the following as a list comprehension" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1\n", - "ans = []\n", - "for i in range(3):\n", - " for j in range(4):\n", - " ans.append((i, j))\n", - "print (ans)\n", - "\n", - "# 2\n", - "ans = map(lambda x: x*x, filter(lambda x: x%2 == 0, range(5)))\n", - "print (list(ans))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2\\. Convert the following function into a pure function with no global variables or side effects" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 5\n", - "def f(alist):\n", - " for i in range(x):\n", - " alist.append(i)\n", - " return alist\n", - "\n", - "alist = [1,2,3]\n", - "ans = f(alist)\n", - "print (ans)\n", - "print (alist) # alist has been changed!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3\\. Write a `decorator` hello that makes every wrapped function print “Hello!”, i.e. something like:\n", - "\n", - "```python\n", - "@hello\n", - "def square(x):\n", - " return x*x\n", - "```\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4\\. Write the factorial function so that it a) does and b) does not use recursion." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "5\\. Use HOFs (zip in particular) to compute the weight of a circle, a disk and a sphere, assuming different radii and different densities:\n", - "\n", - "```python\n", - "densities = {\"Al\":[0.5,1,2],\"Fe\":[3,4,5],\"Pb\": [15,20,30]}\n", - "radii = [1,2,3]\n", - "```\n", - "\n", - "where the entries of the dictionary's values are the linear, superficial and volumetric densities of the materials respectively.\n", - "\n", - "In particular define a list of three lambda functions using a comprehension that computes the circumference, the area and the volume for a given radius.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "6\\. Edit the class defintion to add an instance attribute of is_hungry = True to the Dog class. Then add a method called eat() which changes the value of is_hungry to False when called. Figure out the best way to feed each dog and then output “My dogs are hungry.” if all are hungry or “My dogs are not hungry.” if all are not hungry. The final output should look like this:\n", - "\n", - "`I have 3 dogs. \n", - "Tom is 6. \n", - "Fletcher is 7. \n", - "Larry is 9. \n", - "And they're all mammals, of course. \n", - "My dogs are not hungry.\n", - "`\n", - "\n", - "```python\n", - "# Parent class\n", - "class Dog:\n", - "\n", - " # Class attribute\n", - " species = 'mammal'\n", - "\n", - " # Initializer / Instance attributes\n", - " def __init__(self, name, age):\n", - " self.name = name\n", - " self.age = age\n", - "\n", - " # instance method\n", - " def description(self):\n", - " return \"{} is {} years old\".format(self.name, self.age)\n", - "\n", - " # instance method\n", - " def speak(self, sound):\n", - " return \"{} says {}\".format(self.name, sound)\n", - "\n", - "# Child class (inherits from Dog class)\n", - "class RussellTerrier(Dog):\n", - " def run(self, speed):\n", - " return \"{} runs {}\".format(self.name, speed)\n", - "\n", - "# Child class (inherits from Dog class)\n", - "class Bulldog(Dog):\n", - " def run(self, speed):\n", - " return \"{} runs {}\".format(self.name, speed)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.15rc1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From bcc10dd5aeb6643f6e216a8c1ecb9bd2046b7cae Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 14:53:40 +0100 Subject: [PATCH 10/19] Delete 02ex_NumberRepresentation.ipynb --- 02ex_NumberRepresentation.ipynb | 119 -------------------------------- 1 file changed, 119 deletions(-) delete mode 100644 02ex_NumberRepresentation.ipynb diff --git a/02ex_NumberRepresentation.ipynb b/02ex_NumberRepresentation.ipynb deleted file mode 100644 index 1bd815f..0000000 --- a/02ex_NumberRepresentation.ipynb +++ /dev/null @@ -1,119 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1\\. Write a function that converts number representation (bin<->dec<->hex)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2\\. Write a function that converts a 32 bit word into a single precision floating point (i.e. interprets the various bits as sign, mantissa and exponent)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3\\. Write a program to determine the underflow and overflow limits (within a factor of 2) for python on your computer. \n", - "\n", - "**Tips**: define two variables inizialized to 1 and halve/double them enough time to exceed the under/over-flow limits " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4\\. Write a program to determine the machine precision\n", - "\n", - "**Tips**: define a new variable by adding a smaller and smaller value (proceeding similarly to prob. 2) to an original variable and check the point where the two are the same " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "5\\. Write a function that takes in input three parameters $a$, $b$ and $c$ and prints out the two solutions to the quadratic equation $ax^2+bx+c=0$ using the standard formula:\n", - "$$\n", - "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}\n", - "$$\n", - "\n", - "(a) use the program to compute the solution for $a=0.001$, $b=1000$ and $c=0.001$\n", - "\n", - "(b) re-express the standard solution formula by multiplying top and bottom by $-b\\mp\\sqrt{b^2-4ac}$ and again find the solution for $a=0.001$, $b=1000$ and $c=0.001$. How does it compare with what previously obtained? Why?\n", - "\n", - "(c) write a function that compute the roots of a quadratic equation accurately in all cases" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "6\\. Write a program that implements the function $f(x)=x(x−1)$\n", - "\n", - "(a) Calculate the derivative of the function at the point $x = 1$ using the derivative definition:\n", - "\n", - "$$\n", - "\\frac{{\\rm d}f}{{\\rm d}x} = \\lim_{\\delta\\to0} \\frac{f(x+\\delta)-f(x)}{\\delta}\n", - "$$\n", - "\n", - "with $\\delta = 10^{−2}$. Calculate the true value of the same derivative analytically and compare with the answer your program gives. The two will not agree perfectly. Why not?\n", - "\n", - "(b) Repeat the calculation for $\\delta = 10^{−4}, 10^{−6}, 10^{−8}, 10^{−10}, 10^{−12}$ and $10^{−14}$. How does the accuracy scales with $\\delta$?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "7\\. Consider the integral of the semicircle of radius 1:\n", - "$$\n", - "I=\\int_{-1}^{1} \\sqrt(1-x^2) {\\rm d}x\n", - "$$\n", - "which it's known to be $I=\\frac{\\pi}{2}=1.57079632679...$.\n", - "Alternatively we can use the Riemann definition of the integral:\n", - "$$\n", - "I=\\lim_{N\\to\\infty} \\sum_{k=1}^{N} h y_k \n", - "$$\n", - "\n", - "with $h=2/N$ the width of each of the $N$ slices the domain is divided into and where\n", - "$y_k$ is the value of the function at the $k-$th slice.\n", - "\n", - "(a) Write a programe to compute the integral with $N=100$. How does the result compares to the true value?\n", - "\n", - "(b) How much can $N$ be increased if the computation needs to be run in less than a second? What is the gain in running it for 1 minute? \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.5.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From a3e8adb384ca366306238537a62cdbe582a3f558 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:00:54 +0100 Subject: [PATCH 11/19] upload - solving conflicts --- 01ex_Fundamentals.ipynb | 166 ++++++++++++++++++++++++++++++++ 02ex_NumberRepresentation.ipynb | 119 +++++++++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 01ex_Fundamentals.ipynb create mode 100644 02ex_NumberRepresentation.ipynb diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb new file mode 100644 index 0000000..79a07fe --- /dev/null +++ b/01ex_Fundamentals.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1\\. Write the following as a list comprehension" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 1\n", + "ans = []\n", + "for i in range(3):\n", + " for j in range(4):\n", + " ans.append((i, j))\n", + "print (ans)\n", + "\n", + "# 2\n", + "ans = map(lambda x: x*x, filter(lambda x: x%2 == 0, range(5)))\n", + "print (list(ans))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2\\. Convert the following function into a pure function with no global variables or side effects" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5\n", + "def f(alist):\n", + " for i in range(x):\n", + " alist.append(i)\n", + " return alist\n", + "\n", + "alist = [1,2,3]\n", + "ans = f(alist)\n", + "print (ans)\n", + "print (alist) # alist has been changed!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3\\. Write a `decorator` hello that makes every wrapped function print “Hello!”, i.e. something like:\n", + "\n", + "```python\n", + "@hello\n", + "def square(x):\n", + " return x*x\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4\\. Write the factorial function so that it a) does and b) does not use recursion." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5\\. Use HOFs (zip in particular) to compute the weight of a circle, a disk and a sphere, assuming different radii and different densities:\n", + "\n", + "```python\n", + "densities = {\"Al\":[0.5,1,2],\"Fe\":[3,4,5],\"Pb\": [15,20,30]}\n", + "radii = [1,2,3]\n", + "```\n", + "\n", + "where the entries of the dictionary's values are the linear, superficial and volumetric densities of the materials respectively.\n", + "\n", + "In particular define a list of three lambda functions using a comprehension that computes the circumference, the area and the volume for a given radius.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "6\\. Edit the class defintion to add an instance attribute of is_hungry = True to the Dog class. Then add a method called eat() which changes the value of is_hungry to False when called. Figure out the best way to feed each dog and then output “My dogs are hungry.” if all are hungry or “My dogs are not hungry.” if all are not hungry. The final output should look like this:\n", + "\n", + "`I have 3 dogs. \n", + "Tom is 6. \n", + "Fletcher is 7. \n", + "Larry is 9. \n", + "And they're all mammals, of course. \n", + "My dogs are not hungry.\n", + "`\n", + "\n", + "```python\n", + "# Parent class\n", + "class Dog:\n", + "\n", + " # Class attribute\n", + " species = 'mammal'\n", + "\n", + " # Initializer / Instance attributes\n", + " def __init__(self, name, age):\n", + " self.name = name\n", + " self.age = age\n", + "\n", + " # instance method\n", + " def description(self):\n", + " return \"{} is {} years old\".format(self.name, self.age)\n", + "\n", + " # instance method\n", + " def speak(self, sound):\n", + " return \"{} says {}\".format(self.name, sound)\n", + "\n", + "# Child class (inherits from Dog class)\n", + "class RussellTerrier(Dog):\n", + " def run(self, speed):\n", + " return \"{} runs {}\".format(self.name, speed)\n", + "\n", + "# Child class (inherits from Dog class)\n", + "class Bulldog(Dog):\n", + " def run(self, speed):\n", + " return \"{} runs {}\".format(self.name, speed)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15rc1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/02ex_NumberRepresentation.ipynb b/02ex_NumberRepresentation.ipynb new file mode 100644 index 0000000..1bd815f --- /dev/null +++ b/02ex_NumberRepresentation.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1\\. Write a function that converts number representation (bin<->dec<->hex)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2\\. Write a function that converts a 32 bit word into a single precision floating point (i.e. interprets the various bits as sign, mantissa and exponent)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3\\. Write a program to determine the underflow and overflow limits (within a factor of 2) for python on your computer. \n", + "\n", + "**Tips**: define two variables inizialized to 1 and halve/double them enough time to exceed the under/over-flow limits " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4\\. Write a program to determine the machine precision\n", + "\n", + "**Tips**: define a new variable by adding a smaller and smaller value (proceeding similarly to prob. 2) to an original variable and check the point where the two are the same " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5\\. Write a function that takes in input three parameters $a$, $b$ and $c$ and prints out the two solutions to the quadratic equation $ax^2+bx+c=0$ using the standard formula:\n", + "$$\n", + "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}\n", + "$$\n", + "\n", + "(a) use the program to compute the solution for $a=0.001$, $b=1000$ and $c=0.001$\n", + "\n", + "(b) re-express the standard solution formula by multiplying top and bottom by $-b\\mp\\sqrt{b^2-4ac}$ and again find the solution for $a=0.001$, $b=1000$ and $c=0.001$. How does it compare with what previously obtained? Why?\n", + "\n", + "(c) write a function that compute the roots of a quadratic equation accurately in all cases" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "6\\. Write a program that implements the function $f(x)=x(x−1)$\n", + "\n", + "(a) Calculate the derivative of the function at the point $x = 1$ using the derivative definition:\n", + "\n", + "$$\n", + "\\frac{{\\rm d}f}{{\\rm d}x} = \\lim_{\\delta\\to0} \\frac{f(x+\\delta)-f(x)}{\\delta}\n", + "$$\n", + "\n", + "with $\\delta = 10^{−2}$. Calculate the true value of the same derivative analytically and compare with the answer your program gives. The two will not agree perfectly. Why not?\n", + "\n", + "(b) Repeat the calculation for $\\delta = 10^{−4}, 10^{−6}, 10^{−8}, 10^{−10}, 10^{−12}$ and $10^{−14}$. How does the accuracy scales with $\\delta$?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "7\\. Consider the integral of the semicircle of radius 1:\n", + "$$\n", + "I=\\int_{-1}^{1} \\sqrt(1-x^2) {\\rm d}x\n", + "$$\n", + "which it's known to be $I=\\frac{\\pi}{2}=1.57079632679...$.\n", + "Alternatively we can use the Riemann definition of the integral:\n", + "$$\n", + "I=\\lim_{N\\to\\infty} \\sum_{k=1}^{N} h y_k \n", + "$$\n", + "\n", + "with $h=2/N$ the width of each of the $N$ slices the domain is divided into and where\n", + "$y_k$ is the value of the function at the $k-$th slice.\n", + "\n", + "(a) Write a programe to compute the integral with $N=100$. How does the result compares to the true value?\n", + "\n", + "(b) How much can $N$ be increased if the computation needs to be run in less than a second? What is the gain in running it for 1 minute? \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From a0dca7ef6388cfe772368599a7c9781af37d7be0 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:11:56 +0100 Subject: [PATCH 12/19] Delete 01ex_Fundamentals.ipynb --- 01ex_Fundamentals.ipynb | 166 ---------------------------------------- 1 file changed, 166 deletions(-) delete mode 100644 01ex_Fundamentals.ipynb diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb deleted file mode 100644 index 79a07fe..0000000 --- a/01ex_Fundamentals.ipynb +++ /dev/null @@ -1,166 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "1\\. Write the following as a list comprehension" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 1\n", - "ans = []\n", - "for i in range(3):\n", - " for j in range(4):\n", - " ans.append((i, j))\n", - "print (ans)\n", - "\n", - "# 2\n", - "ans = map(lambda x: x*x, filter(lambda x: x%2 == 0, range(5)))\n", - "print (list(ans))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "2\\. Convert the following function into a pure function with no global variables or side effects" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "x = 5\n", - "def f(alist):\n", - " for i in range(x):\n", - " alist.append(i)\n", - " return alist\n", - "\n", - "alist = [1,2,3]\n", - "ans = f(alist)\n", - "print (ans)\n", - "print (alist) # alist has been changed!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "3\\. Write a `decorator` hello that makes every wrapped function print “Hello!”, i.e. something like:\n", - "\n", - "```python\n", - "@hello\n", - "def square(x):\n", - " return x*x\n", - "```\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "4\\. Write the factorial function so that it a) does and b) does not use recursion." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "5\\. Use HOFs (zip in particular) to compute the weight of a circle, a disk and a sphere, assuming different radii and different densities:\n", - "\n", - "```python\n", - "densities = {\"Al\":[0.5,1,2],\"Fe\":[3,4,5],\"Pb\": [15,20,30]}\n", - "radii = [1,2,3]\n", - "```\n", - "\n", - "where the entries of the dictionary's values are the linear, superficial and volumetric densities of the materials respectively.\n", - "\n", - "In particular define a list of three lambda functions using a comprehension that computes the circumference, the area and the volume for a given radius.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "6\\. Edit the class defintion to add an instance attribute of is_hungry = True to the Dog class. Then add a method called eat() which changes the value of is_hungry to False when called. Figure out the best way to feed each dog and then output “My dogs are hungry.” if all are hungry or “My dogs are not hungry.” if all are not hungry. The final output should look like this:\n", - "\n", - "`I have 3 dogs. \n", - "Tom is 6. \n", - "Fletcher is 7. \n", - "Larry is 9. \n", - "And they're all mammals, of course. \n", - "My dogs are not hungry.\n", - "`\n", - "\n", - "```python\n", - "# Parent class\n", - "class Dog:\n", - "\n", - " # Class attribute\n", - " species = 'mammal'\n", - "\n", - " # Initializer / Instance attributes\n", - " def __init__(self, name, age):\n", - " self.name = name\n", - " self.age = age\n", - "\n", - " # instance method\n", - " def description(self):\n", - " return \"{} is {} years old\".format(self.name, self.age)\n", - "\n", - " # instance method\n", - " def speak(self, sound):\n", - " return \"{} says {}\".format(self.name, sound)\n", - "\n", - "# Child class (inherits from Dog class)\n", - "class RussellTerrier(Dog):\n", - " def run(self, speed):\n", - " return \"{} runs {}\".format(self.name, speed)\n", - "\n", - "# Child class (inherits from Dog class)\n", - "class Bulldog(Dog):\n", - " def run(self, speed):\n", - " return \"{} runs {}\".format(self.name, speed)\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.15rc1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 10a84ac48757b7322041adfa1c0803e034496c60 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:12:20 +0100 Subject: [PATCH 13/19] 01ex --- 01ex_Fundamentals.ipynb | 168 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 01ex_Fundamentals.ipynb diff --git a/01ex_Fundamentals.ipynb b/01ex_Fundamentals.ipynb new file mode 100644 index 0000000..5852179 --- /dev/null +++ b/01ex_Fundamentals.ipynb @@ -0,0 +1,168 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1\\. Write the following as a list comprehension" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]\n", + "[0, 4, 16]\n" + ] + } + ], + "source": [ + "# 1\n", + "ans = []\n", + "for i in range(3):\n", + " for j in range(4):\n", + " ans.append((i, j))\n", + "print (ans)\n", + "\n", + "# 2\n", + "ans = map(lambda x: x*x, filter(lambda x: x%2 == 0, range(5)))\n", + "print (list(ans))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2\\. Converte the following function into a pure function with no global variables or side effects" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2, 3, 0, 1, 2, 3, 4]\n", + "[1, 2, 3, 0, 1, 2, 3, 4]\n" + ] + } + ], + "source": [ + "x = 5\n", + "def f(alist):\n", + " for i in range(x):\n", + " alist.append(i)\n", + " return alist\n", + "\n", + "alist = [1,2,3]\n", + "ans = f(alist)\n", + "print (ans)\n", + "print (alist) # alist has been changed!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "3\\. Write a `decorator` hello that makes every wrapped function print “Hello!”, i.e. something like:\n", + "\n", + "```python\n", + "@hello\n", + "def square(x):\n", + " return x*x\n", + "```\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "4\\. Write the factorial function so that it a) does and b) does not use recursion." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "5\\. Edit the class defintion to add an instance attribute of is_hungry = True to the Dog class. Then add a method called eat() which changes the value of is_hungry to False when called. Figure out the best way to feed each dog and then output “My dogs are hungry.” if all are hungry or “My dogs are not hungry.” if all are not hungry. The final output should look like this:\n", + "\n", + "`I have 3 dogs. \n", + "Tom is 6. \n", + "Fletcher is 7. \n", + "Larry is 9. \n", + "And they're all mammals, of course. \n", + "My dogs are not hungry.\n", + "`\n", + "\n", + "```python\n", + "# Parent class\n", + "class Dog:\n", + "\n", + " # Class attribute\n", + " species = 'mammal'\n", + "\n", + " # Initializer / Instance attributes\n", + " def __init__(self, name, age):\n", + " self.name = name\n", + " self.age = age\n", + "\n", + " # instance method\n", + " def description(self):\n", + " return \"{} is {} years old\".format(self.name, self.age)\n", + "\n", + " # instance method\n", + " def speak(self, sound):\n", + " return \"{} says {}\".format(self.name, sound)\n", + "\n", + "# Child class (inherits from Dog class)\n", + "class RussellTerrier(Dog):\n", + " def run(self, speed):\n", + " return \"{} runs {}\".format(self.name, speed)\n", + "\n", + "# Child class (inherits from Dog class)\n", + "class Bulldog(Dog):\n", + " def run(self, speed):\n", + " return \"{} runs {}\".format(self.name, speed)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 8c23e51c9b2319318824ba1a8fb6119a8bd5439a Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:22:34 +0100 Subject: [PATCH 14/19] Delete README.md --- README.md | 94 ------------------------------------------------------- 1 file changed, 94 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index d5e63f2..0000000 --- a/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# LaboratoryOfComputationalPhysics - -Notebooks guiding students through the world of data analysis with python. - -This repo should be forked by each individual student. Exercises should be committed to the student's repo and notified to the professor by a pull request. -Such pull request should be made on this remote repo under the corresponding student branch (Dedicated branches will indeed be created in due time). - -## IPython notebooks instructions and tips -Notebooks are extremely powerful tools, you may find useful to discover some of their functionalities on this tutorial [page](https://nbviewer.jupyter.org/github/ipython/ipython/blob/3.x/examples/Notebook/Index.ipynb) or on this by checking this [list](https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/) of tips - -## Git Instructions - -To start with, you need to have a github account. If you don't have one, go to [github](github.com) and follow instructions on how to create it. - -Suggestion: use a reasonable username that resembles your actual name. - -Once you have your github, as first thing fork this repository, i.e. go [there](https://github.com/mzanetti79/LaboratoryOfComputationalPhysics) and click on the top-right button *fork* - -### Setting up a local repository - -What follows needs to be done any time a new local repository is created. -In particular, if you are working in a location where such repo already exist, what follows doesn't need to be repeated. - * Clone your (forked) repository (i.e. create a local repository cloned from the remote one) - -`git clone https://github.com/YOUR_GIT_ACCOUNT/LaboratoryOfComputationalPhysics.git` - - where YOUR_GIT_ACCOUNT it your account on github. Now you can get to your local working folder: - - `cd LaboratoryOfComputationalPhysics/` - - * Configure your username and email: - -`git config --global user.name "YOUR_GIT_ACCOUNT"` - -`git config --global user.email "YOUR_EMAIL_ADDRESS"` - -(you must have understood what capital-letters-words stand for). Your git configuration is stored in `.gitconfig`, a file that you can alwasy edit by hand or via the `git config ..` commands. - -* Define mzanetti79's repo as the upstream repository (you may need to set the url too), check that actually succeeded and get (fetch) the updates that have been done on the remote repository: - -`git remote add upstream https://github.com/mzanetti79/LaboratoryOfComputationalPhysics.git` - -`git remote set-url origin https://YOUR_GIT_ACCOUNT@github.com/YOUR_GIT_ACCOUNT/LaboratoryOfComputationalPhysics.git` - -`git remote -v` - -`git fetch upstream` - - * The default branch is `master`, you should now create your development branch where to play and exercise with the code. Note that however you have a branch corresponding to you (name_surname) in the upstream repository (`upstream/name_surname`): that is the branch you should point the pull request to. In order to set up a proper development cycle, you must create a branch (in the example below called TRACKING_BRANCH_NAME) that *tracks* `upstream/name_surname`: - -`git branch -vv` - -`git checkout -b TRACKING_BRANCH_NAME upstream/name_surname` - -Note that the case you decide do make your development in a branch that does NOT track `upstream/name_surname`, you'll eventually need to merge your changes into the branch tracking `upstream/name_surname` which is the one you'll make the pull request for (see later). - -### Standard development cycle - - * Before starting with the development you could check whether the orginal repository (mzanetti79's one) have been updated with respect to your forked version (that's likely to be the case prior to every lab class). If it had, then merge the chances into your master. - - `git fetch upstream` - - `git checkout master` - - `git merge upstream/master` - - The idea is that your master always reflects `upstream/master`, i.e. it keeps a local copy of the reference code as a starting point for your developments (i.e. solving the assigned problems). - Note that in order to update your repository on github, you need to push the local version (see later). - - * In the case a pull request of yours to mzanetti79 has been recently approved, you also need to synch your development branch: - - `git checkout TRACKING_BRANCH_NAME` - - `git merge upstream/name_surname` - - * You may also need to get the updates from the master, i.e. need to merge the master: - - `git merge master` - - * Now do the real stuff, i.e. developing some code. Image you create a NEW_FILE. Add the file to your local repository and stages it for commit (To unstage a file, use 'git reset HEAD NEW_FILE)' - - `git add NEW_FILE` - - * Commits the (tracked) changes you made to the file and prepares them to be pushed to your remote repository on github - - `git commit -m "Add existing file"` - -(what follows after `-m` is a comment to later remind what was that commit about) - - * Now you want to propagate (push) your local changes to your remote repository on github (`origin`) - - `git push origin TRACKING_BRANCH_NAME` - - * Finally you may want to propagate your development also to the repo you originally forked from, i.e. mzanetti79's one (this is likely to happen anytime you'll be asked to deliver your homework!). For that you need to go for a "pull request", which is done from github itself. Be carefull to point your pull request to `mzanetti79/name_surname` From b2d3f67640979fdea1d9fdd0f5c4ff893fdaea51 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:23:13 +0100 Subject: [PATCH 15/19] upload --- README.md | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f526428 --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# LaboratoryOfComputationalPhysics + +Notebooks guiding students through the world of data analysis with python. + +This repo should be forked by each individual student. Exercises should be committed to the student's repo and notified to the professor by a pull request. +Such pull request should be made on this remote repo under the corresponding student branch (Dedicated branches will indeed be created in due time). + +## IPython notebooks instructions and tips +Notebooks are extremely powerful tools, you may find useful to discover some of their functionalities on this tutorial [page](https://nbviewer.jupyter.org/github/ipython/ipython/blob/3.x/examples/Notebook/Index.ipynb) or on this by checking this [list](https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/) of tips + +## Git Instructions + +To start with, you need to have a github account. If you don't have one, go to [github](github.com) and follow instructions on how to create it. + +Suggestion: use a reasonable username that resembles your actual name. + +Once you have your github, as first thing fork this repository, i.e. go [there](https://github.com/mzanetti79/LaboratoryOfComputationalPhysics) and click on the top-right button *fork* + +### Setting up a local repository + +What follows needs to be done any time a new local repository is created. +In particular, if you are working in a location where such repo already exist, what follows doesn't need to be repeated. + * Clone your (forked) repository (i.e. create a local repository cloned from the remote one) + +`git clone https://github.com/YOUR_GIT_ACCOUNT/LaboratoryOfComputationalPhysics.git` + + where YOUR_GIT_ACCOUNT it your account on github. Now you can get to your local working folder: + + `cd LaboratoryOfComputationalPhysics/` + + * Configure your username and email: + +`git config --global user.name "YOUR_GIT_ACCOUNT"` + +`git config --global user.email "YOUR_EMAIL_ADDRESS"` + +(you must have understood what capital-letters-words stand for). Your git configuration is stored in `.gitconfig`, a file that you can alwasy edit by hand or via the `git config ..` commands. + +* Define mzanetti79's repo as the upstream repository (you may need to set the url too), check that actually succeeded and get (fetch) the updates that have been done on the remote repository: + +`git remote add upstream https://github.com/mzanetti79/LaboratoryOfComputationalPhysics.git` + +`git remote set-url origin https://YOUR_GIT_ACCOUNT@github.com/YOUR_GIT_ACCOUNT/LaboratoryOfComputationalPhysics.git` + +`git remote -v` + +`git fetch upstream` + + * The default branch is `master`, you should now create your how development branch where to play and exercise with the code: + +`git branch` + +`git checkout -b DEV_BRANCH_NAME` + +Now you `master` and `DEV_BRANCH_NAME` are the identical, work on the latter will tracked and later committed. + + +### Standard development cycle + + * Before starting with the development you could check whether the orginal repository (mzanetti79's one) have been updated with respect to your forked version (that's likely to be the case prior to every lab class). If it had, then merge the chances into your master: + + `git fetch upstream` + + `git checkout master` + + `git merge upstream/master` + +this will update your local version, not the one on github. To update the latter you need to push the local version (see later) + + * From within your local repository choose your development branch and check it out (i.e. switch to it). : + +`git checkout DEV_BRANCH_NAME` + + * Now do the real stuff, i.e. developing some code. Image you create a NEW_FILE. Add the file to your local repository and stages it for commit (To unstage a file, use 'git reset HEAD NEW_FILE)' + +`git add NEW_FILE` + + * Commits the (tracked) changes you made to the file and prepares them to be pushed to your remote repository on github + +`git commit -m "Add existing file"` + +(what follows after `-m` is a comment to later remind what was that commit about) + + * Now you want to propagate (push) your local changes to your remote repository on github (`origin`) + + `git push origin DEV_BRANCH_NAME` + + * Finally you may want to propagate your development also to the repo you originally forked from, i.e. mzanetti79's one (this is likely to happen anytime you'll be asked to deliver your homework!). For that you need to go for a "pull request", which is done from github itself. + + * To close a development loop is a good habit to clean up, i.e. get rid of the development branch. Prior to that you may want to merge the `master` branch + + `git checkout master` + + `git merge DEV_BRANCH_NAME` + + `git push origin master` + + `git commit -d DEV_BRANCH_NAME` From d23c628f050ed8d65df05f77e34191de2cb3ab54 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:28:04 +0100 Subject: [PATCH 16/19] Delete 02_NumberRepresentation.ipynb --- 02_NumberRepresentation.ipynb | 619 ---------------------------------- 1 file changed, 619 deletions(-) delete mode 100644 02_NumberRepresentation.ipynb diff --git a/02_NumberRepresentation.ipynb b/02_NumberRepresentation.ipynb deleted file mode 100644 index 8e36862..0000000 --- a/02_NumberRepresentation.ipynb +++ /dev/null @@ -1,619 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Integers\n", - "\n", - "Integrers number are represented by N bits words. Python 3 allows you to store integers with practically unlimited precision, the only limitation comes from the (contiguos) space available in memory.\n", - "In python 2, N depends on the PC architercture, N=64 in modern computers.\n", - "\n", - "Typically 1 bit is dedicated to specifying the sign fo the number, thus the conversion between binary and decimal representation is:\n", - "\n", - "$d = (-1)^j\\sum_{i=0}^{N-1} \\alpha_i ~ 2^i$\n", - "\n", - "where $\\alpha_i$ are either $0$ or $i$ and the $b=\\alpha_{N-1}\\alpha_{N-2}..\\alpha_0$ is the binary representation of the number." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "print (sys.maxsize)\n", - "\n", - "# check \n", - "print (2**63-1 == sys.maxsize)\n", - "\n", - "# python 3 doesn't have a limit for integers\n", - "print (sys.maxsize+1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "incidentally note that python 3 recast int to floats when dividing them with `/`. To keep the old functionality of `/`, use instead `//`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (2/3)\n", - "print (2//3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Binary and Hexadecimal representations\n", - "\n", - "numbers values (in python as all the other languages) are assumed to be expressed as decimal. Built-in functions allows explicitly to convert from one representation to another. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# an integer in decimal representation\n", - "a=18\n", - "\n", - "# its binary representation\n", - "a_bin = bin(a)\n", - "print('Binary representation of',a,':', a_bin)\n", - "\n", - "# its hexadecimal representation\n", - "a_hex = hex(a)\n", - "print('Hexadecimal representation of',a,':', a_hex)\n", - "\n", - "# converting back to integer\n", - "print('Decimal representation of',a_bin,':', int(a_bin,2))\n", - "print('Decimal representation of',a_hex,':', int(a_hex,16))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Bitwise operators" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Logical operators" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "a = 60 # 60 = 0011 1100 \n", - "b = 13 # 13 = 0000 1101 \n", - "\n", - "c = a & b; # 12 = 0000 1100\n", - "print (\"Logical AND \", c)\n", - "\n", - "c = a | b; # 61 = 0011 1101 \n", - "print (\"Logical OR \", c)\n", - "\n", - "c = a ^ b; # 49 = 0011 0001\n", - "print (\"Logical XOR \", c)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Unary operators" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = ~a; # -61 = 1100 0011\n", - "print (\"Negation of a \", c)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Masks and shifts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "c = a << 2; # 240 = 1111 0000\n", - "print (\"Left shift (towards most significant) of two positions \", c)\n", - "\n", - "c = a >> 2; # 15 = 0000 1111\n", - "print (\"Right shift (towards least significant) of two positions \", c)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Floating point numbers\n", - "\n", - "non-integer number cannot be represent with infinite precision on a computer. Single (also known as *float*) and double precision numbers are assigned 32 and 64 bits respectively. \n", - "Note that all floating point numbers in python are double precision (64 bits).\n", - "A standard has been developed by IEEE such that the relative precision (see later) is the same in the whole validity range.\n", - "\n", - "The 32 or 64 bits are divided among 3 quantities uniquely characterizing the number:\n", - "\n", - "$x_{float} = (-1)^s \\times 1.f \\times 2^{e-bias}$\n", - "\n", - "where *s* is the sign, *f* the fractional part of the mantissa and *e* the exponent. In order to get numbers smaller than 1, a constant *bias* term is added to the exponent, such *bias* is typically equal to half of the max value of *e*.\n", - "The mantissa is defined as:\n", - "\n", - "${\\rm mantissa}=1.f=1+m_{n-1}2^{-1}+m_{n-2}2^{-2}+..+m_{0}2^{-n}$\n", - "\n", - "where $n$ is the number of bits dedicated to *f* (see below) and $m_i$ are the binary coefficients. \n", - "\n", - "Numbers exceeding the maximum allowed value are *overflows* and the calculations involving them provide incorrect answers. Numbers smaller in absolute value than the minimum allowed value are *underflows* and simply set to zero, also in this case incorrect results are yielded. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Single\n", - "\n", - "For single precision floating point numbers, $0\\le e \\le 255$ and $bias=127$. Bits are arranged as follows:\n", - "\n", - "| | *s* | *e* | *f* |\n", - "|---|---|---|---|\n", - "| Bit position | 31 | 30-23 | 22-0 |\n", - "\n", - "Special values are also possibiles. N.B.: those are not numbers that can be used in the mathematical sense!\n", - "\n", - "| | conditions | value |\n", - "|---|---|---|\n", - "| $+\\infty$ | s=0, e=255, f=0 | +INF |\n", - "| $-\\infty$ | s=1, e=255, f=0 | +INF |\n", - "| not a number | e=255, f>0 | NaN |\n", - "\n", - "The largest value is obtained for $f\\sim 2$ and $e=254$, i.e. $2\\times2^{127}\\sim 3.4\\times2^{38}$.\n", - "\n", - "The value closest to zero is obtained instead for $f=2^{-23}$ and $e=0$, i.e. $2^{-149}\\sim 1.4\\times2^{45}$.\n", - "\n", - "An example is given below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from IPython.display import Image\n", - "Image(url='http://www.dspguide.com/graphics/F_4_2.gif')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Double\n", - "\n", - "For double precision floating point numbers, $0\\le e \\le 2047$ and $bias=1023$. Bits are arranged as follows:\n", - "\n", - "| | *s* | *e* | *f* |\n", - "|---|---|---|---|\n", - "| Bit position | 63 | 62-52 | 51-0 |\n", - "\n", - "Special values are also possibiles. N.B.: those are not numbers that can be used in the mathematical sense!\n", - "\n", - "| | conditions | value |\n", - "|---|---|---|\n", - "| $+\\infty$ | s=0, e=2047, f=0 | +INF |\n", - "| $-\\infty$ | s=1, e=2047, f=0 | +INF |\n", - "| not a number | e=2047, f>0 | NaN |\n", - "\n", - "The validity range for double numbers is $2.2^{-308} - 1.8^{308}$\n", - "\n", - "Serious scientific calculations almost always requires at least double precision floating point numbers" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Floating point numbers on your system\n", - "\n", - "Information about the floating point reresentation on your system can be obtained from sys.float_info. Definitions of the stored values are given on the python doc [page](https://docs.python.org/2/library/sys.html#sys.float_info)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "print (sys.float_info)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Accuracy and the perils of calculations with floats\n", - "\n", - "\n", - "Floats can only have a limited number of meaningful decimal places, on the basis of how many bits are allocated for the fractional part of the mantissa: 6-7 decimal places for singles, 15-16 for doubles. In particular this means that calculations involving numbers with more than those decimal places involved do not yield the correct result, simply because the binary representation of those numbers could not store them properly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for e in [14,15,16]: print (7+1.0*10**-e)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It should never been forgotten that computers store numbers in binary format. In the same way it is not possible to express the fraction 1/3 with a finite decimal places, analogously fraction well represented in the decimal base cannot be represented in binary, e.g. 1/10 is the infinitely repeating number:\n", - "\n", - "$0.0001100110011001100110011001100110011001100110011...$\n", - "\n", - "corresponding to $3602879701896397/2^{55}$ which is close to but not exactly equal to the true value of 1/10 (even though it is even printed to be like that!!.\n", - "Similarly 0.1 is not 1/10, and making calculations assuming that exactly typically yield to wrong results:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# is 1/10 the same of 0.1?\n", - "print (1/10)\n", - "\n", - "# but then whatch out!!\n", - "0.1 + 0.1 + 0.1 == 0.3\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A lesson of paramount importance is that you must never compare floating point numbers with the \"==\" operator as **what is printed is not what is stored**!!\n", - "\n", - "The function ```float.hex()``` yield the exact value stored for a floating point number:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "x=math.pi\n", - "print (x)\n", - "print (x.hex())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are ways to print floats (e.g. filling data into an output file) controlling the number of decimals:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (format(math.pi, '.13f')) # give 13 significant digits\n", - "\n", - "print ('%.17f' % (0.1 * 0.1 * 100)) # give 15 significant digits\n", - "\n", - "# now repeat trying with >15 digits!\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There is no bug here, this is simply due to the fact that the mantissa is represented by a limited amount of bits, therefore calculations can only make sense if a corresponding number of decimal digits are concerned:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 23 bits are used for f in single precision floating points \n", - "print (2**-23)\n", - "\n", - "# 53 bits are used for f in single precision floating points \n", - "print (2**-53)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A typical case is subtraction of numbers very close by in value (e.g. when dealing with spectral frequencies). The same happens with functions evaluated near critical points (see later)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "1 + 6.022e23 - 6.022e23" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Associative law does not necessarily hold:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (6.022e23 - 6.022e23 + 1)\n", - "print (1 + 6.022e23 - 6.022e23)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Distributive law does not hold" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "a = math.exp(1);\n", - "b = math.pi;\n", - "c = math.sin(1);\n", - "a*(b+c) == a*b+a*c" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# (we'll see numpy soon, bear with me for the moment)\n", - "\n", - "# loss of precision can be a problem when calculating likelihoods\n", - "import numpy as np\n", - "probs = np.random.random(1000)\n", - "print (np.prod(probs))\n", - "\n", - "# when multiplying lots of small numbers, work in log space\n", - "print (np.sum(np.log(probs)))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## From numbers to Functions: Stability and conditioning\n", - "\n", - "Suppose we have a computer algorithm $g(x)$ that represents the mathematical function $f(x)$. $g(x)$ is stable if for some small perturbation $\\epsilon$, $g(x+\\epsilon)\\simeq f(x)$\n", - "\n", - "A mathematical function $f(x)$ is well-conditioned if $f(x+\\epsilon)\\simeq f(x)$ for all small perturbations $\\epsilon$.\n", - "\n", - "That is, the functionf(x) is **well-conditioned** if the solution varies gradually as problem varies. For a well-conditinoed function, all small perutbations have small effects. However, a poorly-conditioned problem only needs some small perturbations to have large effects. For example, inverting a nearly singluar matrix is a poorly conditioned problem.\n", - "\n", - "A numerical algorithm $g(x)$ is numerically-stable if $g(x)\\simeq f(x′)$ for some $x′\\simeq x$. Note that stability is a property that relates the algorithm $g(x)$ to the problem $f(x)$.\n", - "\n", - "That is, the algorithm $g(x)$ is **numerically stable** if it gives nearly the right answer to nearly the right question. Numerically unstable algorithms tend to amplify approximation errors due to computer arithmetic over time. If we used an infitinte precision numerical system, stable and unstable alorithms would have the same accuracy. However, as we have seen (e.g. variance calculation), when using floating point numbers, algebrically equivaelent algorithms can give different results.\n", - "\n", - "In general, we need both a well-conditinoed problem and nuerical stabilty of the algorihtm to reliably accurate answers. In this case, we can be sure that $g(x)\\simeq f(x)$.\n", - "\n", - "In most of the cases, the solution to stability issues is properly redefying the function as in the example above with the likelihood. More examples follow " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# The tangent function is poorly conditioned\n", - "\n", - "import math\n", - "x1 = 1.57078\n", - "x2 = 1.57079\n", - "t1 = math.tan(x1)\n", - "t2 = math.tan(x2)\n", - "\n", - "print ('t1 =', t1)\n", - "print ('t2 =', t2)\n", - "print ('% change in x =', 100.0*(x2-x1)/x1)\n", - "print ('% change in tan(x) =', (100.0*(t2-t1)/t1))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Catastrophic cancellation occurs when subtracitng\n", - "# two numbers that are very close to one another\n", - "# Here is another example\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "% matplotlib inline\n", - "\n", - "def f(x):\n", - " return (1 - np.cos(x))/(x*x)\n", - "\n", - "x = np.linspace(-4e-8, 4e-8, 100)\n", - "plt.plot(x,f(x));\n", - "plt.axvline(1.1e-8, color='red')\n", - "plt.xlim([-4e-8, 4e-8]);\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# We know from L'Hopital's rule that the answer is 0.5 at 0\n", - "# and should be very close to 0.5 throughout this tiny interval\n", - "# but errors arisee due to catastrophic cancellation\n", - "\n", - "print ('%.30f' % np.cos(1.1e-8))\n", - "print ('%.30f' % (1 - np.cos(1.1e-8))) # exact answer is 6.05e-17\n", - "print ('%2f' % ((1 - np.cos(1.1e-8))/(1.1e-8*1.1e-8)))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Numerically stable version of funtion using simple trignometry\n", - "\n", - "def f1(x):\n", - " return 2*np.sin(x/2)**2/(x*x)\n", - "\n", - "x = np.linspace(-4e-8, 4e-8, 100)\n", - "plt.plot(x,f1(x));\n", - "plt.axvline(1.1e-8, color='red')\n", - "plt.xlim([-4e-8, 4e-8]);" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Stable and unstable version of the variance:\n", - "\n", - "$s^2 = \\frac{1}{n-1} \\sum (x-\\bar{x})^2$" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# sum of squares method (vectorized version)\n", - "# watch out! big number minus big number!\n", - "def sum_of_squers_var(x):\n", - " n = len(x)\n", - " return (1.0/(n*(n-1))*(n*np.sum(x**2) - (np.sum(x))**2))\n", - "\n", - "# direct method\n", - "# squaring occuring after subtraction\n", - "def direct_var(x):\n", - " n = len(x)\n", - " xbar = np.mean(x)\n", - " return 1.0/(n-1)*np.sum((x - xbar)**2)\n", - "\n", - "\n", - "# Welford's method\n", - "# an optimized method\n", - "def welford_var(x):\n", - " s = 0\n", - " m = x[0]\n", - " for i in range(1, len(x)):\n", - " m += (x[i]-m)/i\n", - " s += (x[i]-m)**2\n", - " return s/(len(x) -1 )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# check the performances with an array \n", - "# of randomly distributed data around 1e12\n", - "\n", - "x_ = np.random.uniform(0,1,int(1e3))\n", - "x = 1e12 + x_\n", - "\n", - "# correct answer\n", - "print (np.var(x_))\n", - "\n", - "print (sum_of_squers_var(x))\n", - "print (direct_var(x))\n", - "print (welford_var(x))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.5.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 09363a8d070cc4549bda01da4dbb586cbce7378c Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:28:21 +0100 Subject: [PATCH 17/19] Add files via upload --- 02_NumberRepresentation.ipynb | 139 ++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 02_NumberRepresentation.ipynb diff --git a/02_NumberRepresentation.ipynb b/02_NumberRepresentation.ipynb new file mode 100644 index 0000000..3d916ac --- /dev/null +++ b/02_NumberRepresentation.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Binary and Hexadecimal representations" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Binary representation of 18 : 0b10010\n", + "Hexadecimal representation of 18 : 0x12\n", + "Decimal representation of 0b10010 : 18\n", + "Decimal representation of 0x12 : 18\n" + ] + } + ], + "source": [ + "# an integer in decimal representation\n", + "a=18\n", + "\n", + "# its binary representation\n", + "a_bin = bin(a)\n", + "print('Binary representation of',a,':', a_bin)\n", + "\n", + "# its hexadecimal representation\n", + "a_hex = hex(a)\n", + "print('Hexadecimal representation of',a,':', a_hex)\n", + "\n", + "# converting back to integer\n", + "print('Decimal representation of',a_bin,':', int(a_bin,2))\n", + "print('Decimal representation of',a_hex,':', int(a_hex,16))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bitwise operators" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Logical operators" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "a = 60 # 60 = 0011 1100 \n", + "b = 13 # 13 = 0000 1101 \n", + "\n", + "c = a & b; # 12 = 0000 1100\n", + "print \"Logical AND \", c\n", + "\n", + "c = a | b; # 61 = 0011 1101 \n", + "print \"Logical OR \", c\n", + "\n", + "c = a ^ b; # 49 = 0011 0001\n", + "print \"Logical XOR \", c\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Unary operators" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = ~a; # -61 = 1100 0011\n", + "print \"Negation of a \", c\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Masks and shifts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a << 2; # 240 = 1111 0000\n", + "print \"Left shift (towards most significant) of two positions \", c\n", + "\n", + "c = a >> 2; # 15 = 0000 1111\n", + "print \"Right shift (towards least significant) of two positions \", c\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.5.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 67b3c844494cb72d0ffdd944ffdb157837437da5 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:31:50 +0100 Subject: [PATCH 18/19] Delete 01_Fundamentals.ipynb --- 01_Fundamentals.ipynb | 856 ------------------------------------------ 1 file changed, 856 deletions(-) delete mode 100644 01_Fundamentals.ipynb diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb deleted file mode 100644 index 9a6ef3a..0000000 --- a/01_Fundamentals.ipynb +++ /dev/null @@ -1,856 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Modules/packages/libraries\n", - "\n", - "Definitions:\n", - "\n", - " * Modules:\n", - " A module is a file which contains python functions, global variables etc. It is nothing but .py file which has python executable code / statement.\n", - "\n", - " * Packages:\n", - " A package is namespace which contains multiple package/modules. It is a directory which contains a special file `__init__.py`\n", - " \n", - " * Libraries:\n", - " A library is a collection of various packages. There is no difference between package and python library conceptually.\n", - " \n", - "Modules/packages/libraries can be easily \"imported\" and made functional in your python code. A set of libriaries comes with every python installation. Others can be installed locally and then imported. Your own code sitting somewhere else in your local computer can be imported too.\n", - "\n", - "Further details (very important!) on packages and how to create them can be found online. We may find the need of creating our own during the course." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "###### all the \"stuff\" that is in the math library can be used\n", - "import math\n", - "print(math.pi)\n", - "\n", - "# you can give math a label for convenience\n", - "import math as m\n", - "print (m.pi)\n", - "\n", - "# alternatively you can import only a given \"thing\" from the library\n", - "from math import pi #se ci metto una virgola e altre cose, le importa\n", - "print (pi)\n", - "\n", - "# or just get everything (very dangerous!!!)\n", - "from math import * #scomodo perché magari importa roba con un nome specifico che non posso più usare, ma non conoscendole non me ne accorgo\n", - "print (sqrt(7))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To know which modules are there for you to use just type:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print (help('modules') )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`pip` is a special package. It is used from the command line to install properly (e.g. matching the version of the local packages) new packages. It can also be used from within python to check i.e. the set installed packages and their versions. N.B.: only the installed packages on top of the default ones will be listed " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import pip\n", - "sorted([\"%s==%s\" % (i.key, i.version) for i in pip.get_installed_distributions()])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Functions" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "4\n", - "8\n", - "('cube', 8)\n", - "('square', 4)\n" - ] - } - ], - "source": [ - "def square(x):\n", - " \"\"\"Square of x.\"\"\"\n", - " return x*x\n", - "\n", - "def cube(x):\n", - " \"\"\"Cube of x.\"\"\"\n", - " return x*x*x\n", - "\n", - "# create a dictionary of functions\n", - "funcs = {\n", - " 'square': square,\n", - " 'cube': cube,\n", - "}\n", - "\n", - "x = 2\n", - "print(square(x))\n", - "print(cube(x))\n", - "\n", - "for func in sorted(funcs):\n", - " print (func, funcs[func](x))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Functions arguments" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "what is passsed to a function is a copy of the input. Imagine we have a list *x =[1, 2, 3]*. If within the function the content of *x* is directly changed (e.g. *x[0] = 999*), then *x* chanes outside the funciton as well. However, if *x* is reassigned within the function to a new object (e.g. another list), then the copy of the name *x* now points to the new object, but *x* outside the function is unhcanged." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def modify(x):\n", - " x[0] = 999\n", - " return x\n", - "\n", - "x = [1,2,3]\n", - "print (x)\n", - "print (modify(x))\n", - "print (x)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def no_modify(x):\n", - " x = [4,5,6]\n", - " return x\n", - "\n", - "x = [1,2,3]\n", - "print (x)\n", - "print (no_modify(x))\n", - "print (x)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "La prima funzione riassegna al \"\"\"\"\"puntatore\"\"\"\"\" a x[0] un numero nuovo, che quindi è cambiato per sempre. !! se provassi a farlo con una variabile semplice (un numero) non funzionerebbe" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Binding of default arguments occurs at function definition:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(x = []):\n", - " x.append(1)\n", - " return x\n", - "\n", - "print (f())\n", - "print (f())\n", - "print (f(x = [9,9,9]))\n", - "print (f())\n", - "print (f())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Try to aviod that!!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def f(x = None):\n", - " if x is None:\n", - " x = []\n", - " x.append(1)\n", - " return x\n", - "\n", - "print (f())\n", - "print (f())\n", - "print (f(x = [9,9,9]))\n", - "print (f())\n", - "print (f())" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Higher order functions\n", - "\n", - "A function that uses another function as an input argument or returns a function (HOF) is known as a higher-order function. The most familiar examples are `map` and `filter`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### map\n", - "\n", - "The map function applies a function to each member of a collection" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 1, 4, 9, 16]\n", - "0\n", - "1\n", - "4\n", - "9\n", - "16\n" - ] - } - ], - "source": [ - "x = list(map(square, range(5))) \n", - "print (x)\n", - "\n", - "# Note the difference w.r.t python 2. In python 3 map retuns an iterator so you can do stuff like:\n", - "for i in map(square,range(5)): print(i)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### filter\n", - "\n", - "The filter function applies a predicate to each memmber of a collection, retaining only those members where the predicate is True" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def is_even(x):\n", - " return x%2 == 0\n", - "\n", - "print (list(filter(is_even, range(5))))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "list(map(square, filter(is_even, range(5))))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### reduce\n", - "\n", - "The reduce function reduces a collection using a binary operator to combine items two at a time. More often than not reduce can be substituted with a more efficient for loop. It is worth mentioning it for its key role in big-data applications together with map (the map-reduce paradigm). \n", - "N.B.: it no loger exist in python 3, it is now part of the `functools` library" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "15" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from functools import reduce\n", - "\n", - "def my_add(x, y):\n", - " return x + y\n", - "\n", - "# another implementation of the sum function\n", - "reduce(my_add, [1,2,3,4,5])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### zip\n", - "\n", - "zip is useful when you need to iterate over matched elements of multiple lists" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1, 10, 'a')\n", - "(2, 20, 'b')\n", - "(3, 30, 'c')\n", - "(4, 40, 'd')\n" - ] - } - ], - "source": [ - "xs = [1, 2, 3, 4]\n", - "ys = [10, 20, 30, 40]\n", - "zs = ['a', 'b', 'c', 'd', 'e']\n", - "\n", - "for x, y, z in zip(xs, ys, zs):\n", - " print (x, y, z)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Custom HOF" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "() takes exactly 2 arguments (1 given)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcube\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m\u001b[0m in \u001b[0;36mcustom_sum\u001b[0;34m(xs, transform)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcustom_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Returns the sum of xs after a user specified transform.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mxs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mxs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mTypeError\u001b[0m: () takes exactly 2 arguments (1 given)" - ] - } - ], - "source": [ - "def custom_sum(xs, transform):\n", - " \"\"\"Returns the sum of xs after a user specified transform.\"\"\"\n", - " return sum(map(transform, xs))\n", - "\n", - "xs = range(5)\n", - "print (custom_sum(xs, square))\n", - "print (custom_sum(xs, cube))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Returning a function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def make_logger(target):\n", - " def logger(data):\n", - " with open(target, 'a') as f:\n", - " f.write(data + '\\n')\n", - " return logger\n", - "\n", - "foo_logger = make_logger('foo.txt') #foo.txt verrà creato se non esiste già\n", - "foo_logger('Hello')\n", - "foo_logger('World')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "! type 'foo.txt'" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Anonimous functions (lambda)\n", - "\n", - "When using functional style, there is often the need to create small specific functions that perform a limited task as input to a HOF such as map or filter. In such cases, these functions are often written as anonymous or lambda functions. \n", - "The syntax is as follows:\n", - "\n", - "lambda *arguments* : *expression*\n", - "\n", - "\n", - "If you find it hard to understand what a lambda function is doing, it should probably be rewritten as a regular function." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sum = lambda x,y: x+y\n", - "sum(3,4)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1\n", - "5\n", - "11\n", - "19\n", - "29\n" - ] - } - ], - "source": [ - "for i in map(lambda x: x*x, range(5)): print (i)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "285\n" - ] - } - ], - "source": [ - "# what does this function do?\n", - "from functools import reduce\n", - "s1 = reduce(lambda x, y: x+y, map(lambda x: x**2, range(1,10))) #reduce serve a sommare tutte le coppie\n", - "print(s1)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Recursive functions " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" - ] - } - ], - "source": [ - "def fib1(n):\n", - " \"\"\"Fib with recursion.\"\"\"\n", - "\n", - " # base case\n", - " if n==0 or n==1:\n", - " return 1\n", - " # recurssive case\n", - " else:\n", - " return fib1(n-1) + fib1(n-2)\n", - "\n", - " \n", - "print ([fib1(i) for i in range(10)])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" - ] - } - ], - "source": [ - "# In Python, a more efficient version that does not use recursion is\n", - "\n", - "def fib2(n):\n", - " \"\"\"Fib without recursion.\"\"\"\n", - " a, b = 0, 1\n", - " for i in range(1, n+1):\n", - " a, b = b, a+b\n", - " return b\n", - "\n", - "print ([fib2(i) for i in range(10)])" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100 loops, best of 3: 4.66 ms per loop\n", - "100000 loops, best of 3: 3.41 µs per loop\n" - ] - } - ], - "source": [ - "# check indeed the timing:\n", - "\n", - "%timeit fib1(20)\n", - "%timeit fib2(20)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Iterators\n", - "\n", - "Iterators represent streams of values. Because only one value is consumed at a time, they use very little memory. Use of iterators is very helpful for working with data sets too large to fit into RAM." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Iterators can be created from sequences with the built-in function iter()\n", - "\n", - "xs = [1,2,3]\n", - "x_iter = iter(xs)\n", - "\n", - "print (next(x_iter))\n", - "print (next(x_iter))\n", - "print (next(x_iter))\n", - "print (next(x_iter))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Most commonly, iterators are used (automatically) within a for loop\n", - "# which terminates when it encouters a StopIteration exception\n", - "\n", - "x_iter = iter(xs)\n", - "for x in x_iter:\n", - " print (x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## More on comprehensions" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# A generator expression\n", - "\n", - "print ((x for x in range(10)))\n", - "\n", - "# A list comprehesnnion\n", - "\n", - "print ([x for x in range(10)])\n", - "\n", - "# A set comprehension\n", - "\n", - "print ({x for x in range(10)})\n", - "\n", - "# A dictionary comprehension\n", - "\n", - "print ({x: x for x in range(10)})" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Useful Modules\n", - "\n", - "You may want to have a look at the content of the following modules for further usage of (HO) functions:\n", - " - [operator](https://docs.python.org/3/library/operator.html)\n", - " - [functools](https://docs.python.org/3/library/functools.html)\n", - " - [itertools](https://docs.python.org/3/library/itertools.html)\n", - " - [toolz](https://pypi.org/project/toolz/)\n", - " - [funcy](https://pypi.org/project/funcy/)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Decorators\n", - "\n", - "Decorators are a type of HOF that take a function and return a wrapped function that provides additional useful properties.\n", - "\n", - "Examples:\n", - "\n", - " - logging\n", - " - profiling\n", - " - Just-In-Time (JIT) compilation" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "def my_decorator(func):\n", - " def wrapper():\n", - " print(\"Something is happening before the function is called.\")\n", - " func()\n", - " print(\"Something is happening after the function is called.\")\n", - " return wrapper\n", - "\n", - "def say_whee():\n", - " print(\"Whee!\")\n", - "\n", - "say_whee = my_decorator(say_whee)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Whee!\n" - ] - } - ], - "source": [ - "say_whee()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Classes and Objects\n", - "\n", - "Old school object-oriented programming is possible and often used in python. Classes are defined similarly to standard object-oriented languages, with similar functionalities.\n", - "\n", - "The main python doc [page](https://docs.python.org/3.6/tutorial/classes.html) is worth reading through " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "('buddy', 12)\n", - "6.0\n" - ] - } - ], - "source": [ - "class Pet:\n", - " # the \"constructor\"\n", - " def __init__(self, name, age): #inizializza gli elementi delle classe Pet\n", - " self.name=name\n", - " self.age=age\n", - " # class functions take the \"self\" parameter !!!\n", - " def set_name(self,name):\n", - " self.name=name\n", - " def convert_age(self,factor):\n", - " self.age*=factor\n", - "\n", - "buddy=Pet(\"buddy\",12)\n", - "print (buddy.name, buddy.age)\n", - "buddy.age=3\n", - "print (buddy.age)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "tobia\n", - "70\n" - ] - } - ], - "source": [ - "# ineritance is straightforward\n", - "class Dog(Pet):\n", - " # the following variables is \"global\", i.e. holds for all \"Dog\" objects\n", - " species = \"mammal\"\n", - " # functions can be redefined as usual\n", - " def convert_age(self):\n", - " self.age*=7\n", - " def set_species(self, species):\n", - " self.species = species\n", - " \n", - "puppy=Dog(\"tobia\",10)\n", - "print(puppy.name)\n", - "puppy.convert_age()\n", - "print(puppy.age)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "! tenere le def delle funzioni dentro la classe mi permette di riferirmi alle proprietà della classe" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "! sono come struct, ma che prima definisci e poi riempi" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.15rc1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 4bc5967e8161dedbb8ddd76c99e942d383b6e577 Mon Sep 17 00:00:00 2001 From: andreadeans <43958933+andreadeans@users.noreply.github.com> Date: Mon, 12 Nov 2018 15:32:10 +0100 Subject: [PATCH 19/19] upload --- 01_Fundamentals.ipynb | 748 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 748 insertions(+) create mode 100644 01_Fundamentals.ipynb diff --git a/01_Fundamentals.ipynb b/01_Fundamentals.ipynb new file mode 100644 index 0000000..613cb85 --- /dev/null +++ b/01_Fundamentals.ipynb @@ -0,0 +1,748 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Modules/packages/libraries\n", + "\n", + "Definitions:\n", + "\n", + " * Modules:\n", + " A module is a file which contains python functions, global variables etc. It is nothing but .py file which has python executable code / statement.\n", + "\n", + " * Packages:\n", + " A package is namespace which contains multiple package/modules. It is a directory which contains a special file `__init__.py`\n", + " \n", + " * Libraries:\n", + " A library is a collection of various packages. There is no difference between package and python library conceptually.\n", + " \n", + "Modules/packages/libraries can be easily \"imported\" and made functional in your python code. A set of libriaries comes with every python installation. Others can be installed locally and then imported. Your own code sitting somewhere else in your local computer can be imported too.\n", + "\n", + "Further details (very important!) on packages and how to create them can be found online. We may find the need of creating our own during the course." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "###### all the \"stuff\" that is in the math library can be used\n", + "import math\n", + "print(math.pi)\n", + "\n", + "# you can give math a label for convenience\n", + "import math as m\n", + "print (m.pi)\n", + "\n", + "# alternatively you can import only a given \"thing\" from the library\n", + "from math import pi\n", + "print (pi)\n", + "\n", + "# or just get everything (very dangerous!!!)\n", + "from math import *\n", + "print (sqrt(7))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To know which modules are there for you to use just type:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print (help('modules') )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`pip` is a special package. It is used from the command line to install properly (e.g. matching the version of the local packages) new packages. It can also be used from within python to check i.e. the set installed packages and their versions. N.B.: only the installed packages on top of the default ones will be listed " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pip\n", + "sorted([\"%s==%s\" % (i.key, i.version) for i in pip.get_installed_distributions()])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Functions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def square(x):\n", + " \"\"\"Square of x.\"\"\"\n", + " return x*x\n", + "\n", + "def cube(x):\n", + " \"\"\"Cube of x.\"\"\"\n", + " return x*x*x\n", + "\n", + "# create a dictionary of functions\n", + "funcs = {\n", + " 'square': square,\n", + " 'cube': cube,\n", + "}\n", + "\n", + "x = 2\n", + "print(square(x))\n", + "print(cube(x))\n", + "\n", + "for func in sorted(funcs):\n", + " print (func, funcs[func](x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Functions arguments" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "what is passsed to a function is a copy of the input. Imagine we have a list *x =[1, 2, 3]*. If within the function the content of *x* is directly changed (e.g. *x[0] = 999*), then *x* chanes outside the funciton as well. However, if *x* is reassigned within the function to a new object (e.g. another list), then the copy of the name *x* now points to the new object, but *x* outside the function is unhcanged." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def modify(x):\n", + " x[0] = 999\n", + " return x\n", + "\n", + "x = [1,2,3]\n", + "print (x)\n", + "print (modify(x))\n", + "print (x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def no_modify(x):\n", + " x = [4,5,6]\n", + " return x\n", + "\n", + "x = [1,2,3]\n", + "print (x)\n", + "print (no_modify(x))\n", + "print (x)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Binding of default arguments occurs at function definition:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1]\n", + "[1, 1]\n", + "[9, 9, 9, 1]\n", + "[1, 1, 1]\n", + "[1, 1, 1, 1]\n" + ] + } + ], + "source": [ + "def f(x = []):\n", + " x.append(1)\n", + " return x\n", + "\n", + "print (f())\n", + "print (f())\n", + "print (f(x = [9,9,9]))\n", + "print (f())\n", + "print (f())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Try to aviod that!!" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1]\n", + "[1]\n", + "[9, 9, 9, 1]\n", + "[1]\n", + "[1]\n" + ] + } + ], + "source": [ + "def f(x = None):\n", + " if x is None:\n", + " x = []\n", + " x.append(1)\n", + " return x\n", + "\n", + "print (f())\n", + "print (f())\n", + "print (f(x = [9,9,9]))\n", + "print (f())\n", + "print (f())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Higher order functions\n", + "\n", + "A function that uses another function as an input argument or returns a function (HOF) is known as a higher-order function. The most familiar examples are `map` and `filter`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### map\n", + "\n", + "The map function applies a function to each member of a collection" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = list(map(square, range(5)))\n", + "print (x)\n", + "\n", + "# Note the difference w.r.t python 2. In python 3 map retuns an iterator so you can do stuff like:\n", + "for i in map(square,range(5)): print(i)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### filter\n", + "\n", + "The filter function applies a predicate to each memmber of a collection, retaining only those members where the predicate is True" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def is_even(x):\n", + " return x%2 == 0\n", + "\n", + "print (list(filter(is_even, range(5))))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list(map(square, filter(is_even, range(5))))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### reduce\n", + "\n", + "The reduce function reduces a collection using a binary operator to combine items two at a time. More often than not reduce can be substituted with a more efficient for loop. It is worth mentioning it for its key role in big-data applications together with map (the map-reduce paradigm). \n", + "N.B.: it no loger exist in python 3, it is now part of the `functools` library" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from functools import reduce\n", + "\n", + "def my_add(x, y):\n", + " return x + y\n", + "\n", + "# another implementation of the sum function\n", + "reduce(my_add, [1,2,3,4,5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### zip\n", + "\n", + "zip is useful when you need to iterate over matched elements of multiple lists" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "xs = [1, 2, 3, 4]\n", + "ys = [10, 20, 30, 40]\n", + "zs = ['a', 'b', 'c', 'd', 'e']\n", + "\n", + "for x, y, z in zip(xs, ys, zs):\n", + " print (x, y, z)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Custom HOF" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def custom_sum(xs, transform):\n", + " \"\"\"Returns the sum of xs after a user specified transform.\"\"\"\n", + " return sum(map(transform, xs))\n", + "\n", + "xs = range(5)\n", + "print (custom_sum(xs, square))\n", + "print (custom_sum(xs, cube))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Returning a function" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def make_logger(target):\n", + " def logger(data):\n", + " with open(target, 'a') as f:\n", + " f.write(data + '\\n')\n", + " return logger\n", + "\n", + "foo_logger = make_logger('foo.txt')\n", + "foo_logger('Hello')\n", + "foo_logger('World')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello\r\n", + "World\r\n" + ] + } + ], + "source": [ + "! cat 'foo.txt'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Anonimous functions (lambda)\n", + "\n", + "When using functional style, there is often the need to create small specific functions that perform a limited task as input to a HOF such as map or filter. In such cases, these functions are often written as anonymous or lambda functions. \n", + "The syntax is as follows:\n", + "\n", + "lambda *arguments* : *expression*\n", + "\n", + "\n", + "If you find it hard to understand what a lambda function is doing, it should probably be rewritten as a regular function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sum = lambda x,y: x+y\n", + "sum(3,4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for i in map(lambda x: x*x, range(5)): print (i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# what does this function do?\n", + "from functools import reduce\n", + "s1 = reduce(lambda x, y: x+y, map(lambda x: x**2, range(1,10)))\n", + "print(s1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Recursive functions " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def fib1(n):\n", + " \"\"\"Fib with recursion.\"\"\"\n", + "\n", + " # base case\n", + " if n==0 or n==1:\n", + " return 1\n", + " # recurssive caae\n", + " else:\n", + " return fib1(n-1) + fib1(n-2)\n", + "\n", + " \n", + "print ([fib1(i) for i in range(10)])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# In Python, a more efficient version that does not use recursion is\n", + "\n", + "def fib2(n):\n", + " \"\"\"Fib without recursion.\"\"\"\n", + " a, b = 0, 1\n", + " for i in range(1, n+1):\n", + " a, b = b, a+b\n", + " return b\n", + "\n", + "print ([fib2(i) for i in range(10)])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# check indeed the timing:\n", + "\n", + "%timeit fib1(20)\n", + "%timeit fib2(20)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Iterators\n", + "\n", + "Iterators represent streams of values. Because only one value is consumed at a time, they use very little memory. Use of iterators is very helpful for working with data sets too large to fit into RAM." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Iterators can be created from sequences with the built-in function iter()\n", + "\n", + "xs = [1,2,3]\n", + "x_iter = iter(xs)\n", + "\n", + "print (next(x_iter))\n", + "print (next(x_iter))\n", + "print (next(x_iter))\n", + "print (next(x_iter))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Most commonly, iterators are used (automatically) within a for loop\n", + "# which terminates when it encouters a StopIteration exception\n", + "\n", + "x_iter = iter(xs)\n", + "for x in x_iter:\n", + " print (x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## More on comprehensions" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " at 0x7fa83048c6e0>\n", + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", + "set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n", + "{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}\n" + ] + } + ], + "source": [ + "# A generator expression\n", + "\n", + "print ((x for x in range(10)))\n", + "\n", + "# A list comprehesnnion\n", + "\n", + "print ([x for x in range(10)])\n", + "\n", + "# A set comprehension\n", + "\n", + "print ({x for x in range(10)})\n", + "\n", + "# A dictionary comprehension\n", + "\n", + "print ({x: x for x in range(10)})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Useful Modules\n", + "\n", + "You may want to have a look at the content of the following modules for further usage of (HO) functions:\n", + " - [operator](https://docs.python.org/3/library/operator.html)\n", + " - [functools](https://docs.python.org/3/library/functools.html)\n", + " - [itertools](https://docs.python.org/3/library/itertools.html)\n", + " - [toolz](https://pypi.org/project/toolz/)\n", + " - [funcy](https://pypi.org/project/funcy/)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Decorators\n", + "\n", + "Decorators are a type of HOF that take a function and return a wrapped function that provides additional useful properties.\n", + "\n", + "Examples:\n", + "\n", + " - logging\n", + " - profiling\n", + " - Just-In-Time (JIT) compilation" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def my_decorator(func):\n", + " def wrapper():\n", + " print(\"Something is happening before the function is called.\")\n", + " func()\n", + " print(\"Something is happening after the function is called.\")\n", + " return wrapper\n", + "\n", + "def say_whee():\n", + " print(\"Whee!\")\n", + "\n", + "say_whee = my_decorator(say_whee)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Something is happening before the function is called.\n", + "Whee!\n", + "Something is happening after the function is called.\n" + ] + } + ], + "source": [ + "say_whee()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Classes and Objects\n", + "\n", + "Old school object-oriented programming is possible and often used in python. Classes are defined similarly to standard object-oriented languages, with similar functionalities.\n", + "\n", + "The main python doc [page](https://docs.python.org/3.6/tutorial/classes.html) is worth reading through " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Pet:\n", + " # the \"constructor\"\n", + " def __init__(self, name, age):\n", + " self.name=name\n", + " self.age=age\n", + " # class functions take the \"self\" parameter \n", + " def set_name(self,name):\n", + " self.name=name\n", + " def convert_age(self,factor):\n", + " self.age*=factor\n", + "\n", + "buddy=Pet(\"buddy\",12)\n", + "print (buddy.name, buddy.age)\n", + "buddy.convert_age(0.5)\n", + "print (buddy.age)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ineritance is straightforward\n", + "class Dog(Pet):\n", + " # the following variables is \"global\", i.e. holds for all \"Dog\" objects\n", + " species = \"mammal\"\n", + " # functions can be redefined as usual\n", + " def convert_age(self):\n", + " self.age*=7\n", + " def set_species(self, species):\n", + " self.species = species\n", + " \n", + "puppy=Dog(\"tobia\",10)\n", + "print(puppy.name)\n", + "puppy.convert_age()\n", + "print(puppy.age)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15rc1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}