diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..b1abdf6 --- /dev/null +++ b/Gemfile @@ -0,0 +1 @@ +gem "github-pages", group: :jekyll_plugins diff --git a/README.md b/README.md new file mode 100644 index 0000000..284b79f --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# Lunch Time Python + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/ssciwr/lunch-time-python/ci.yml?branch=main)](https://github.com/ssciwr/lunch-time-python/actions/workflows/ci.yml) +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/ssciwr/lunch-time-python/main) +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main) + +Welcome to Lunch Time Python - an event series organized by the [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de) at Heidelberg University. + +## What it is + +Python is a very popular - maybe even *the* most popular - programming language among scientific software developers. One of the reasons for this success story is the rich standard library and the rich ecosystem of available (scientific) libraries. To fully leverage this ecosystem, developers need to stay up to date and explore new libraries. *Lunch Time Python* aims at providing a communication platform between Pythonistas to learn about new libraries in an informal setting. Sessions take roughly 30 minutes, one library is presented per session and the code will be made available afterwards. Come by, enjoy your lunch with us and step up your Python game! + +## Sessions + +Next installment of Lunch Time Python: tba + +Here is a list of past sessions which you can reproduce in a Cloud environment by clicking the [Binder](https://mybinder.org) or [Colab](https://colab.research.google.com/) (requires a Google account) links below: + +* Dash: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime12/lunchtime12.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime12%2Flunchtime12.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime12/lunchtime12.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime12/lunchtime12.ipynb) (Session 12, May 25th 2022, 12:00pm) + +* spaCy: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime11/lunchtime11.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime11%2Flunchtime11.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime11/lunchtime11.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime11/lunchtime11.ipynb) (Session 11, November 25th 2022, 11:30am) + +* pytorch: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime10/lunchtime10.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime10%2Flunchtime10.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime10/lunchtime10.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime10/lunchtime10.ipynb) (Session 10, October 30th 2022, 12pm) + +* mypy: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime9/lunchtime9.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime9%2Flunchtime9.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime9/lunchtime9.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime9/lunchtime9.ipynb) (Session 9, September 30th 2022, 12pm) + +* ipywidgets: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime8/lunchtime8.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime8%2Flunchtime8.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime8/lunchtime8.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime8/lunchtime8.ipynb) (Session 8, July 29th 2022, 12pm) + +* matplotlib: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime7/lunchtime7.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime7%2Flunchtime7.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime7/lunchtime7.ipynb), [notebook](https://ssciwr.github.io/lunch-time-python/lunchtime7/lunchtime7.ipynb) (Session 7, June 24th 2022, 12pm) + +* numba: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime6/lunchtime6.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime6%2Flunchtime6.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime6/lunchtime6.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime6/lunchtime6.ipynb) (Session 6, April 29th 2022, 12pm) + +* pillow: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime5/lunchtime5.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime5%2Flunchtime5.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime5/lunchtime5.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime5/lunchtime5.ipynb) (Session 5, March 25th 2022, 12pm) + +* pytest: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime4/lunchtime4.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime4%2Flunchtime4.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime4/lunchtime4.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime4/lunchtime4.ipynb) (Session 4, February 25th 2022, 12pm) + +* Click: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime3/lunchtime3.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime3%2Flunchtime3.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime3/lunchtime3.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime3/lunchtime3.ipynb) (Session 3, January 28th 2022, 12pm) + +* SymPy: [slides](https://ssciwr.github.io/lunch-time-python/lunchtime2/lunchtime2.slides.html), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime2%2Flunchtime2.ipynb), [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime2/lunchtime2.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime2/lunchtime2.ipynb) (Session 2, November 26th 2021, 12pm) + +* requests: [colab](https://colab.research.google.com/github/ssciwr/lunch-time-python/blob/main/lunchtime1/lunchtime1.ipynb), [binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime1%2Flunchtime1.ipynb), [noteboook](https://ssciwr.github.io/lunch-time-python/lunchtime1/lunchtime1.ipynb) (Session 1, October 29th 2021, 12 pm) + +## Registration + +Registration for Lunch Time Python sessions is not required. You can still register using [this form](https://ssc.iwr.uni-heidelberg.de/form/lunch-time-python-registration) to + +* give us a better idea about the potential audience and what libraries we should present. +* make us send you a reminder the day before the session + +Suggestions for libraries to present are very welcome as a [github issue](https://github.com/ssciwr/lunch-time-python/issues/new/choose) or as an [email to the SSC developers](mailto:ssc@iwr.uni-heidelberg.de) + +## Licensing + +The example codes are [available on GitHub](https://github.com/ssciwr/lunch-time-python) and are provided under the permissive MIT license giving you a lot of freedom to reuse and redistribute the code in your projects! diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..f980e76 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..5dfb179 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,75 @@ + + + + + + + + + +{% seo %} + + + + + +
+
+ {% if site.github.is_project_page %} + View on GitHub + {% endif %} + +

+ + + + + + + + + + + + SSC Lunch Time Python +

+
+
+ + +
+
+ {{ content }} +
+
+ + + + + + diff --git a/assets/css/style.scss b/assets/css/style.scss new file mode 100644 index 0000000..ff0c121 --- /dev/null +++ b/assets/css/style.scss @@ -0,0 +1,29 @@ +--- +--- + +@import "{{ site.theme }}"; + +#navigation ul { + margin: 0; + padding: 0; + border: 0; + font-size: 20px; +} + +#navigation ul li { + list-style-type: none; + display: inline; +} + +#navigation li a { + display: block; + float: left; + padding: 0px 10px; + color: #fff; + text-decoration: none; + border-right: 1px solid #fff; +} + +#navigation li a:hover { + background-color: #3a9ebf; +} \ No newline at end of file diff --git a/assets/images/favicon.ico b/assets/images/favicon.ico new file mode 100644 index 0000000..af97f26 Binary files /dev/null and b/assets/images/favicon.ico differ diff --git a/assets/images/ssc-logo.svg b/assets/images/ssc-logo.svg new file mode 100644 index 0000000..af8fa23 --- /dev/null +++ b/assets/images/ssc-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/lunchtime1/README.md b/lunchtime1/README.md new file mode 100644 index 0000000..dd06831 --- /dev/null +++ b/lunchtime1/README.md @@ -0,0 +1,3 @@ +# Lunchtime #1: requests library (Oct. 21) + +The [requests library](https://docs.python-requests.org/en/latest/) provides an elegant and simple way to send HTTP requests. Connect to the server of your choice, and download websites, stream data or upload content. Requests is [one of the most downloaded python packages](https://pypi.org/project/requests/) with about 14 Million downloads per week, and half a million of repositories that depend on requests. \ No newline at end of file diff --git a/lunchtime1/lunchtime1.ipynb b/lunchtime1/lunchtime1.ipynb new file mode 100644 index 0000000..55f62b7 --- /dev/null +++ b/lunchtime1/lunchtime1.ipynb @@ -0,0 +1,627 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": {}, + "source": [ + "# Lunch Time Python\n", + "## Lunch 1: Requests\n", + "*Scientific Software Center, Heidelberg University* \n", + "*October 2021* \n", + "*Visit on [GitHub](https://github.com/ssciwr/lunch-time-python)* \n", + "\n", + "Welcome to Lunch Time Python! This is the notebook for [session 1](https://ssciwr.github.io/lunch-time-python/lunchtime1/) - the [requests](https://docs.python-requests.org/en/latest/) library.\n", + "\n", + "The requests library provides an elegant and simple way to send HTTP requests. Connect to the server of your choice, and download websites, stream data or upload content. Requests is [one of the most downloaded python packages](https://pypi.org/project/requests/) with about 14 Million downloads per week, and half a million of repositories that depend on requests as of October 2021." + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "# Requests: HTTP for humans\n", + "\n", + "Carry out HTTP/1.1 requests using python! An HTTP request is made by a client to a server. For example, when you open a web page in your browser, your device sends a GET request to the web server hosting the page.\n", + "\n", + "The HTTP request contains three elements in the start line: An HTTP method; the request target; and the HTTP version.\n", + "\n", + "For example, when you open the page [ssc.iwr.uni-heidelberg.de](https://ssc.iwr.uni-heidelberg.de/), this is the message that is sent from the client to the server:\n", + "\n", + "GET https://ssc.iwr.uni-heidelberg.de/ HTTP/1.1\n", + "\n", + "The above request contains the request method, GET, the URI of the target, https://ssc.iwr.uni-heidelberg.de/, and the protocol version, HTTP/1.1.\n", + "\n", + "**These are the [main methods](https://www.tutorialspoint.com/http/http_methods.htm) for HTTP/1.1:**\n", + "1. GET \n", + "The GET method is used to retrieve information from the given server using a given URI. Requests using GET should only retrieve data and should have no other effect on the data.\n", + "\n", + "1. HEAD \n", + "Same as GET, but transfers the status line and header section only.\n", + "\n", + "1. POST \n", + "A POST request is used to send data to the server, for example, customer information, file upload, etc. using HTML forms.\n", + "\n", + "1. PUT \n", + "Replaces all current representations of the target resource with the uploaded content.\n", + "\n", + "1. DELETE \n", + "Removes all current representations of the target resource given by a URI.\n", + "\n", + "1. CONNECT \n", + "Establishes a tunnel to the server identified by a given URI.\n", + "\n", + "1. OPTIONS \n", + "Describes the communication options for the target resource.\n", + "\n", + "1. TRACE \n", + "Performs a message loop-back test along the path to the target resource.\n", + "\n", + "*Let's start requesting! \n", + "To install requests on your local machine, simply use* `python -m pip install requests`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "import requests as rq\n", + "import json # to pretty-print JSON responses" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": {}, + "source": [ + "We will start with the above example - \n", + "GET https://ssc.iwr.uni-heidelberg.de/ HTTP/1.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "targetURI = \"https://ssc.iwr.uni-heidelberg.de/\"\n", + "r = rq.get(url=targetURI)" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": {}, + "source": [ + "This did something! Let's check the object that we obtained." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "r.status_code" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, + "source": [ + "There are a couple of status codes that are important. You are probably familiar with 404 Not Found; status codes starting with 2 stand for successful requests; status codes starting with 3 stand for redirections; codes starting with 4 stand for client-side errors." + ] + }, + { + "cell_type": "raw", + "id": "8", + "metadata": {}, + "source": [ + "# Tell me some sites that you would like to GET!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "targetURI = \"https://en.wikipedia.org/wiki/Monty_Python\"\n", + "r = rq.get(url=targetURI)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": {}, + "outputs": [], + "source": [ + "r.text" + ] + }, + { + "cell_type": "markdown", + "id": "12", + "metadata": {}, + "source": [ + "## The HTTP response\n", + "The response that you receive from the server contains the status line (as per `r.status_code`), the HTTP headers and a body. \n", + "\n", + "### The response header" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": {}, + "outputs": [], + "source": [ + "r.headers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": {}, + "outputs": [], + "source": [ + "r.headers[\"content-type\"] # the dictionary is case-insensitive!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": {}, + "outputs": [], + "source": [ + "r.encoding # the type of compression that is used" + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": {}, + "source": [ + "The headers contain information in the response headers (like host), the general headers (i.e. information about the connection), and representation headers (ie. content length).\n", + "You can also see what cookies were sent back, and how much time elapsed for the processing of the request." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [ + "r.cookies # the cookies that the server sent back" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": {}, + "outputs": [], + "source": [ + "r.elapsed # time between request send and receiving the response" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": {}, + "source": [ + "### The response body\n", + "Not all requests come with a body (the payload) - if for example you PUT data on a server, the response does not necessarily entail a body. You can look at the request's body using `r.text` (this one looks at textual data) or `r.content` (automatically detects the encoding also for non-text response content)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": {}, + "outputs": [], + "source": [ + "r.text" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21", + "metadata": {}, + "outputs": [], + "source": [ + "r.content" + ] + }, + { + "cell_type": "markdown", + "id": "22", + "metadata": {}, + "source": [ + "### Side note\n", + "This doesn't look too pretty - you can use BeautifulSoup (`pip install beautifulsoup4`) to improve it's appearance, but that library can fill up a whole other lunch time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": {}, + "outputs": [], + "source": [ + "from bs4 import BeautifulSoup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": {}, + "outputs": [], + "source": [ + "soup = BeautifulSoup(r.content, \"html.parser\")\n", + "print(soup.prettify())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "print(soup.text)" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": {}, + "source": [ + "### Back to requests\n", + "Requests also has a built-in JSON decoder." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": {}, + "outputs": [], + "source": [ + "r = rq.get(\"https://api.github.com/events\")\n", + "r.json()" + ] + }, + { + "cell_type": "markdown", + "id": "28", + "metadata": {}, + "source": [ + "# GET request with parameters\n", + "Now let's try to get something useful using requests (apart from that you can use it to crawl the web and download pages!). Let's find out the geographic position of Heidelberg University using [google's geocoding API](https://developers.google.com/maps/documentation/geocoding/overview?_gl=1*oagjnc*_ga*MTk0NjcwNTg2Ni4xNjM1MTUzNjc5*_ga_NRWSTWS78N*MTYzNTE1MzY3OC4xLjAuMTYzNTE1MzY3OC4w). For this, you can generate a trial account on google's website to obtain an API key." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": {}, + "outputs": [], + "source": [ + "# api-endpoint\n", + "URI = \"https://maps.googleapis.com/maps/api/geocode/json\"\n", + "# API key\n", + "key = \"XXXXXXXXXXXXXXXXXXX\"" + ] + }, + { + "cell_type": "markdown", + "id": "30", + "metadata": {}, + "source": [ + "The better practice is to store the key securely outside of the notebook (and adding the configuration file to .gitignore)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": {}, + "outputs": [], + "source": [ + "import yaml\n", + "\n", + "with open(\"config.yml\", \"r\") as ymlfile:\n", + " cfg = yaml.safe_load(ymlfile)\n", + "key = cfg[\"google_api\"][\"secret_code\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": {}, + "outputs": [], + "source": [ + "# location to geocode\n", + "location = \"university of heidelberg\"\n", + "country = \"germany\"\n", + "# defining a params dict for the parameters to be sent to the API\n", + "parameters = {\"key\": key, \"address\": location, \"country\": country}\n", + "# sending get request and saving the response as response object\n", + "r = rq.get(url=URI, params=parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33", + "metadata": {}, + "outputs": [], + "source": [ + "r.status_code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": {}, + "outputs": [], + "source": [ + "# extracting data in json format\n", + "data = r.json()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35", + "metadata": {}, + "outputs": [], + "source": [ + "print(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": {}, + "outputs": [], + "source": [ + "# print this a little prettier\n", + "print(json.dumps(data, indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": {}, + "outputs": [], + "source": [ + "address_out = data[\"results\"][0][\"formatted_address\"]\n", + "# printing the output\n", + "print(\"Address is {}.\".format(address_out))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38", + "metadata": {}, + "outputs": [], + "source": [ + "latitude = data[\"results\"][0][\"geometry\"][\"location\"][\"lat\"]\n", + "longitude = data[\"results\"][0][\"geometry\"][\"location\"][\"lng\"]\n", + "# printing the output\n", + "print(\"Latitude is {} and longitude {}.\".format(latitude, longitude))" + ] + }, + { + "cell_type": "markdown", + "id": "39", + "metadata": {}, + "source": [ + "# Making a POST request\n", + "Again we need an account for this example. This time, we are using the service [pastebin](https://pastebin.com/). You can send text to this address and it will be publicly visible. It serves as a storage for textual data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40", + "metadata": {}, + "outputs": [], + "source": [ + "# defining the api-endpoint\n", + "api_endpoint = \"https://pastebin.com/api/api_post.php\"\n", + "# API key\n", + "key = \"XXXXXXXXXXXXXXXXXXXXXXXXXXXX\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "41", + "metadata": {}, + "outputs": [], + "source": [ + "key = cfg[\"pastebin_api\"][\"secret_code\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": {}, + "outputs": [], + "source": [ + "# the API option\n", + "option = \"paste\"\n", + "# name/title of your paste\n", + "api_paste_name = \"lunch time python\"\n", + "# syntax highlighting\n", + "api_format = \"python\"\n", + "# this makes a paste public, unlisted or private, public = 0, unlisted = 1, private = 2\n", + "private = 0\n", + "# the text you want to paste, for example, a code snippet in python\n", + "text = \"\"\"\n", + "print(\"Hello, lunch time!\")\n", + "x = 'my lunch'\n", + "y = 'your lunch'\n", + "print('{} {}'.format(x, y))\n", + "\"\"\"\n", + "# data dictionary, to be sent to api\n", + "data = {\n", + " \"api_dev_key\": key,\n", + " \"api_option\": option,\n", + " \"api_paste_code\": text,\n", + " \"api_paste_format\": api_format,\n", + " \"api_paste_private\": private,\n", + "}\n", + "\n", + "# sending post request and saving response as response object\n", + "r = rq.post(url=api_endpoint, data=data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43", + "metadata": {}, + "outputs": [], + "source": [ + "r.status_code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44", + "metadata": {}, + "outputs": [], + "source": [ + "# extracting response text\n", + "pastebin_url = r.text\n", + "print(\"The pastebin URL is {}\".format(pastebin_url))" + ] + }, + { + "cell_type": "markdown", + "id": "45", + "metadata": {}, + "source": [ + "# Making a PUT request\n", + "A PUT request is similar to a POST request, but it is *idempotent*. This means, that in a PUT request the target is replaced. In a POST request, the target appears multiple times. In the above example from pastebin, a POST request generates a new paste, while a PUT request would replace/alter a paste. For the differences between HTTP methods, see [here](https://www.w3schools.com/tags/ref_httpmethods.asp).\n", + "\n", + "For the PUT example, we will use [httpbin](https://httpbin.org/). This is an open service that allows you to test API calls and authetication methods." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46", + "metadata": {}, + "outputs": [], + "source": [ + "# the api-endpoint\n", + "api_endpoint = \"https://httpbin.org/put\"\n", + "# the data to send - we want to receive a JSON response\n", + "data_type = \"application/json\"\n", + "# storing in a dictionary\n", + "data = {\"accept\": data_type}\n", + "# Making a PUT request\n", + "r = rq.put(url=api_endpoint, data=data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47", + "metadata": {}, + "outputs": [], + "source": [ + "# check status code for response received\n", + "print(r)\n", + "print(\"*************************\")\n", + "print(r.status_code)\n", + "print(\"*************************\")\n", + "# print content of request\n", + "print(r.content)\n", + "print(\"*************************\")\n", + "# print recognizing the json response of the request\n", + "print(r.json())\n", + "print(\"*************************\")\n", + "# print this a little prettier\n", + "print(json.dumps(r.json(), indent=4, sort_keys=True))" + ] + }, + { + "cell_type": "markdown", + "id": "48", + "metadata": {}, + "source": [ + "# Advanced topics\n", + "There is so much more you can do with requests - for example:\n", + "- [sessioning](https://docs.python-requests.org/en/latest/user/advanced/#session-objects) which allows you to re-use the connection to the server (through session pooling, leading to faster requests); \n", + "- [SSL certificate verification](https://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification) which allows you to validate the requests;\n", + "- [streaming](https://docs.python-requests.org/en/latest/user/advanced/#streaming-requests); \n", + "- and [much more](https://docs.python-requests.org/en/latest/user/advanced/)!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49", + "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.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime10/README.md b/lunchtime10/README.md new file mode 100644 index 0000000..56d8cd4 --- /dev/null +++ b/lunchtime10/README.md @@ -0,0 +1,5 @@ +# Lunchtime 10: PyTorch (October 28th) + +[PyTorch](https://pytorch.org/) is a free and open-source machine learning framework that was originally developed by engineers at Facebook, but is now part of the Linux foundation. +The two main features of PyTorch are its tensor computations framework (similar to numpy) with great support for GPU acceleration and their support for neural networks via autograd. + diff --git a/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte b/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte new file mode 100644 index 0000000..1170b2c Binary files /dev/null and b/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte differ diff --git a/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte.gz b/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte.gz new file mode 100644 index 0000000..5ace8ea Binary files /dev/null and b/lunchtime10/data/MNIST/raw/t10k-images-idx3-ubyte.gz differ diff --git a/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte b/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte new file mode 100644 index 0000000..d1c3a97 Binary files /dev/null and b/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte differ diff --git a/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte.gz b/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte.gz new file mode 100644 index 0000000..a7e1415 Binary files /dev/null and b/lunchtime10/data/MNIST/raw/t10k-labels-idx1-ubyte.gz differ diff --git a/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte b/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte new file mode 100644 index 0000000..bbce276 Binary files /dev/null and b/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte differ diff --git a/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte.gz b/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte.gz new file mode 100644 index 0000000..b50e4b6 Binary files /dev/null and b/lunchtime10/data/MNIST/raw/train-images-idx3-ubyte.gz differ diff --git a/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte b/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte new file mode 100644 index 0000000..d6b4c5d Binary files /dev/null and b/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte differ diff --git a/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte.gz b/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte.gz new file mode 100644 index 0000000..707a576 Binary files /dev/null and b/lunchtime10/data/MNIST/raw/train-labels-idx1-ubyte.gz differ diff --git a/lunchtime10/lunchtime10.ipynb b/lunchtime10/lunchtime10.ipynb new file mode 100644 index 0000000..fee436b --- /dev/null +++ b/lunchtime10/lunchtime10.ipynb @@ -0,0 +1,922 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "SEOtINgnsNVw", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## 28.10.2022: PyTorch\n", + "\n", + "\n", + "[PyTorch](https://pytorch.org/) is a free and open-source machine learning framework that was originally developed by engineers at Facebook, but is now part of the Linux foundation. \n", + "The two main features of PyTorch are its tensor computations framework (similar to numpy) with great support for GPU acceleration and their support for neural networks via autograd.\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 0 Why use PyTorch? " + ] + }, + { + "attachments": { + "image.png": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABaAAAAMWCAYAAAAH4yGaAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAABaCgAwAEAAAAAQAAAxYAAAAASD0W4QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAQABJREFUeAHsvQecXGd5xf1Mn9mZ7b2o92ZL7g0b27jggg3GYENCsQm9OB+d5PtCDaRgSAgEEkIIJKETMNU22MYFG9xt9V5Wq9X2XqZ+57yzdzW7WsmytGtL4rz27J3b3nvf/72z+u25Z85jpiYCIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACM0DAhz5zM9DvjHS5YPFSq6istubdO2zf3uYZOYY6FQEREAEREAEREAEREAEREAEREAEREAEREAEREIEXg0BNXb3NnrfAeru7bcvGdS/GKUz7Mf3T3qM6FAEREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEQkACt20AEREAEREAEREAEREAEREAEREAEREAEREAEREAERGBGCEiAnhGs6lQEREAEREAEREAEREAEREAEREAEREAEREAEREAEREACtO4BERABERABERABERABERABERABERABERABERABERCBGSEgAXpGsKpTERABERABERABERABERABERABERABERABERABERABCdC6B0RABERABERABERABERABERABERABERABERABERABGaEgAToGcGqTkVABERABERABERABERABERABERABERABERABERABCRA6x4QAREQAREQAREQAREQAREQAREQAREQAREQAREQARGYEQISoGcEqzoVAREQAREQAREQAREQAREQAREQAREQAREQAREQARGQAK17QAREQAREQAREQAREQAREQAREQAREQAREQAREQAREYEYISICeEazqVAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAK07gEREAEREAEREAEREAEREAEREAEREAEREAEREAEREIEZISABekawqlMREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJ0LoHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEZoSABOgZwapORUAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJEDrHhABERABERABERABERABERABERABERABERABERABEZgRAhKgZwSrOhUBERABERABERABERABERABERABERABERABERABEZAArXtABERABERABERABERABERABERABERABERABERABERgRghIgJ4RrOpUBERABERABERABERABERABERABERABERABERABERAArTuAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQgRkhIAF6RrCqUxEQAREQAREQAREQAREQAREQAREQAREQAREQAREQAQnQugdEQAREQAREQAREQAREQAREQAREQAREQAREQAREQARmhIAE6BnBqk5FQAREQAREQAREQAREQAREQAREQAREQAREQAREQAQkQOseEAEREAEREAEREAEREAEREAEREAEREAEREAEREAERmBECEqBnBKs6FQEREAEREAEREAEREAEREAEREAEREAEREAEREAERkACte0AEREAEREAEREAEREAEREAEREAEREAEREAEREAERGBGCEiAnhGs6lQEREAEREAEREAEREAEREAEREAEREAEREAEREAEREACtO4BERABERABERABERABERABERABERABERABERABERCBGSEgAXpGsKpTERABERABERABERABERABERABERABERABERABERABCdC6B0RABERABERABERABERABERABERABERABERABERABGaEgAToGcGqTkVABERABERABERABERABERABERABERABERABERABCRA6x4QAREQAREQAREQAREQAREQAREQAREQAREQAREQARGYEQISoGcEqzoVAREQAREQAREQAREQAREQAREQAREQAREQAREQARGQAK17QAREQAREQAREQAREQAREQAREQAREQAREQAREQAREYEYISICeEazqVAREQAREQAREQAREQAREQAREQAREQAREQAREQAREQAK07gEREAEREAEREAEREAEREAEREAEREAEREAEREAEREIEZISABekawqlMREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJ0LoHREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEZoSABOgZwapORUAEREAEREAEREAEREAEREAEREAEREAEREAEREAEJEDrHhABERABERABERABERABERABERABERABERABERABEZgRAhKgZwSrOhUBERABERABERABERABERABERABERABERABERABEZAArXtABERABERABERABERABERABERABERABERABERABERgRghIgJ4RrOpUBERABERABERABERABERABERABERABERABERABEQgKAR/egRisZglEgkrKioyvg9HohYKBi3IVyhofn8AL7/5fGa5XMYyGe+VtVQqbaOjI3iN2vDwiA0NDVlfT69lc9k/PZAasQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwGEJSIA+LJ4Tf6U/ELBEPG5RCM3RSMQSxcW2YsUKW7Rokc2ePccaGhqtsrrGSkpLrSQRtzjWhyMUpSFG+7KWSVNoHrIhiM0jEJ37+gZs//791tbeYS17W2zXzl227tlnrXnPHhseGROmIUpTmFYTAREQAREQAREQAREQAREQAREQAREQAREQARH40yYgAfokvP50MgcgPEdjUVuwYKFdfMkldtrpp9uKVSts7pw55sN/8DdbJpt3NOdyZv4gXM9chpnh4UGDydkyqWHzQ4SmGzocClk4HLbi4hJraGrE8gC2zcIl7YdzOmT9/f22fdtWe/aZZ+yRhx+2391zn/V0d8MxnbJ0Om1ZHEtNBERABERABERABERABERABERABERABERABETgT4uABOiT7Hon4GK++NJL7cqrrrKzzzvXZs+a7SI0fMjTYKTGaHLUspmsBSFQcxmUZAtARPZjSqE4CcE4BxGakRwhiNKZdMbFbfgQyxEKhR2tdCaNfTNwSUfQX9JtUwSxe+nSpTZ//ny7/vrrIWWbPf30U/bA7x6wO376U9u8ebPb7iTDreGIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAgchoAE6MPAOZFWvRQu52uuvcYuuuRiq6yqdK7kEFzLOfxHnRlpzk5Y9mFqjNag7TmLZRlMc3lxmnEd4SDc0V4GNFbFihIQnkOWhDg9ODhsPgjVpYjpSCILemBoGM7osHE/z+HMbemk9gf8znW9HHEfb33722zduvV2169/bT+/42e2c+fOEwmtzlUEREAEREAEREAEREAEREAEREAEREAEREAEROAoCUiAPkpwL9ZudC3TocxGB/JNr7vZLr/iClu+YrmVl5cj47kEEnPWbeN322Y5ZzlEYNDlzP2DEJgDeM+WgZM5AzHZDxd0NAwBGjEbdEKPDA9bGm7oAawLIIIjFI64Prmsly5p9FNeWoZlZgODiOxAPnQ4HLIiZE1T8R5BbrQPK8tKSiBaB+yMM8+AQ3qJ3XDjjfboH/9gd/zkDnvwgQfcOeiHCIiACIiACIiACIiACIiACIiACIiACIiACIjAyUlAAvQJdl0pPlfXVNu1177CXgq38ymnnmr19Q0WjoZd1AZznbOIyIBm7JzMzv6MfbLQmwMQhilK439LIuTZ5URDxA5EIS4jliOTSdlQ37ANQVAegoDctr8dbuVd1tnZZSlGcSBug4UIA3A9NzU12TnnnmdVKGDIqI4wCh3y3JKjSUyRDc3/IGqnsA/s0M5FXVVdDXd2lc2dNxeC9Fn26B/+aHfe+Wu75ze/PcGugk5XBERABERABERABERABERABERABERABERABETgSAhIgD4SSsfJNlUQb8+/4Hw4nq+0Cy680ObMneOcyyz0l0qm3FkyYiNIoRlzdCDnELMBZdmJz0EIwsjdQBZzymIUnqFSZ1JJ52DuaGuzvc17rK211fr6+pyYvbel1drbu+CIztgwhOf2jg4bwXHiiQSiOYrsoYd+b5ddfrmtWXMaRPB6xH4EsG+v2764OGEBzA8PDSLiAwI4hXG86MAugSv69DNOt2XLl9ma09fYGXj/29/cY48//rjb9jjBrdMQAREQAREQAREQAREQAREQAREQAREQAREQARE4RgISoI8R4Au1+xlnnWnXXXedXYXiggsXLXa5y4y98OI4UEaQ6c7wHSNqY0yAZsYz4zRyEKAZoRFBYcFsLmM+zKdHktbc2mKbN260rVs2W0tzMxzP+6yvpwdCctBKS8shOietp3cAedHQsCEeD/QPmA95z4zs2LVjJwoLboFA3WHNu5vtpRe/1JYsWWzFiWIbRnwHixdSDA+4Y7rk6XFUGRyfL+ZFn3veebZq1So7+9xz7ac/+Slyou+01n37xrfVGxEQAREQAREQAREQAREQAREQAREQAREQAREQgROXgATo4/zaNTY22lnnnG23vOUtdv75F7ic5SSE5xRczDAWu6KATmhG7Abdxaj9ZyEnEidteHAIQnDagq6IIFzMEJAHB/qts6PTNm3aaBvXr7P169ba9m3bLDkyaAnkN5eVllp1dZVFQ7w1/NY22mmtbe1wL+csjPVFiNoYGkK+M9aWl5Xbk088aS0t+6ytvc0uveQSW3nKSrecIjQFcgrQXqMwzvwPiuY8V07ZVwi501dfc42tOuUUW75suf34Rz+ydWvXough3NNqIiACIiACIiACIiACIiACIiACIiACIiACIiACJyyBA+rgCTuEk/fEFy9ZYm++5RZ7y1+8BQUHo8aoDWYz+xnwjMZig8FACFM4muFWDgRDFvYHXZ5zF0Tj9v37Xc5zOBy1/RCIt23dZnv3NmO61TbC+dyPuIwA+vEhszkeiVldTa01NTZYBOJzCpnQg/39LjaD2dHDI8MQvdPuHPr6hxDDUWRpbBPEMdtxrF/84pe2YcMGu+iiC51Tm5Ec5gvbyMgIzpJCecCJ5RTNKTwHEAfCjOg0hXMUROzvG7Dqqhp772232UUvvci+8uUv20//7ycuDoRjVRMBERABERABERABERABERABERABERABERABETjxCEiAPk6v2erT1tjffu5z9pKXXAQn8YglWczPNbiIIeAy2znLwoGWdz7Hi+LOSZyFSL190ybbvG6dJZHvTAfyjh074Cheb48++pj19va6iI4oBG1XiBDicnE8hvcpJyRncZwcYjoqKqts/vxFNmde0No7O2337j22CxnRaeZHxyI4JzisEeMRixVZVU0NIkH8tnXrFmvGNv0Qrl9x3SusEWJ2GO5mnq8rjogpndOMCknjzKE74/xQoBAidiaddXEhjAxZsXKVffpvP2srVqywj//N37jChsyPVhMBERABERABERABERABERABERABERABERABETixCNAA+/ET5ZQpisYgtPb19iCPuO9EOe3ndZ7FJcX25294g/3DF263ZUuXw3HsCc/5blyMBd562c9cyjxlCr1ZiLcsJHjP3XfZEAoJ0rl877332ne+8x3bvn0H3NDIgIaQm4LIzH1YXDCHeb6SyVFkNw/ZEGIvkhCXc1mfjSLruRec+xHd0d3Tba3721CwcAj8++BM7reS0hI4pdO2c9dOJx4vgWO7srISQvej9sgjDzshug5O6BLEetApzfgNH9zbAbihqURns8iJxjJ4oQ8aTwRFEhnJQTf000895WJDCsecp6GfIiACIiACIiACIiACIiACIiACIiACIiACInDyEIijvlppeYWNIlWgq6P9pBiYBOjj6DLOmjXLPvyxj9p7//I2FAEsxZnlHcPQaKndOscwT5d5zFRwgxBzKd5mEaERQO5zd1eXPfz731vLnj0uWmMtXND3P/iglVdUWH1Do4vQ6B8YtOKSUtdzSXGJRZHrTBE5UVxs5eXlcD5X2DLkMBdB6N+5a49t37nTWlr3WVd3N2JAIuinwR17EGI14zWGhkac85pCeR9E70Rxwmpra23r9q123333Whn6nDd/vitOiCHkBWecN4VniuFuSmc0heixcXKsHHsArur6unq76uqr4Kzea9uQVS0nNNmoiYAIiIAIiIAIiIAIiIAIiIAIiIAIiIAInIwEJEC/yFf1ZHZAr1y50v7mk5+wV736BotEo440ZWY6hfOCrHsLWTYfvcFVQYjOPoi0dEX7EWXRtr/dHnzgAeuDWExBeOfundYNt3INXMiDQ6M2gIJ/UHXhTB5EAEbOSsrKLBQJuz4pHFMs5hOWqupq64cTmsIztW5mTmchEpN/06wmJ3ZHohCuEceRgkvaKzSYRPyHy4lOpuCwTtvAwAAyq4cRpbHSamrr3AAolnMMPGf2yTFQRHeaMwc1qVFYL4Y4ftFFF8GhPWwbkF1NB7eaCIiACIiACIiACIiACIiACIiACIiACIiACJxsBE5GAVoZ0MfBXXr66afbhz7yEbv40ostAkfygbzn/Mnl/c75934U7nP2Zgq5EHDZOM0hD5r7DUFkpujb3TlgPYzhCIdsH4oR9qDIH93PzGwuQsxHMAThGZEc4VjUEiUlFg4FLFwUMz+iPJr37YebudfS6LcE6yg2w6vssp5jRUVYv88CKFQYDoVQRBCCOKI0GOfBPOd+RHYwszqEfuii3rFzh4voWL58BQTvEneOGWzrD+YlZyc94603lvwoD/z0ltfAVf3+D34QESxF9s1v/Kd1d3c517S3/sAeeicCIiACIiACIiACIiACIiACIiACIiACIiACInC8EJAA/SJfidVrVttHPgrx+ZJLLBxFcb/ncPf6kVPh8wVcRjOMxE64ZYE/CrmMsSiGYLx7xzZra22B4AzReWjYWtvaIQhHbAQO5dHMAOIwIATnUtYHsToRL7IyZDkHUjkbhaO5fzhk3ciXoTzsD4YtCCGZYnIcLmRGa9C1zBgMFhrsQkHDMIoZMrqDRQgHR4ZsEOL3INzTYbi4q6sqeIqIzthuHZ3tVl5ZjizooKXhmvYxbwN1BemIpjU6L0cf+mKMjo469/U73vFOuKf99s3//IZ1ojii2gtLgPdYPJHgjecOzHuB2eFjs9NyMjzGifBggRy8+5bny0gaZqsfS4vHE/jGgc99vtjPicLiWMasfUVABERABERABERABERABERABERABE5uAhKgX8Tru2z5cvsInM+XXXa5i9JIIroC2psTbSefVl7uQ8FBJzbn4ziQXWH+nA/FBhHDAdEqDvf0HORIP/3kY9ba3u4iMPoHhpwoFoTQiyQN7JhDFEe/i9VIQZAewvuBvm7kSfsshjiOMATikaFBC6LPEOIvLINYDTiaUxCA0zi/AFzPIYjN5RCtKSL7sF1jY70TqlvhtKZz2o8igzxPFh/k+40bN9hOZEnPnzffSc08VwrRFOsyyPhwhRUxbop53jgnj5/zdHfPmTfP/uJtb3PC9X98/esoiNg71abH9bJ4PG7LEUuydNlSy8K5zkb3+JbNW2zd2mddlvbxOICamhrkcV9tS5YsxXVDAUn8F8L98F0UuXzyiSdw7Q539Y58RBRzZ8+ZYxdeeFG+z2PolgIu77Nm5KI/8MD9R34Sh9kyiocr11x7rZ166ql48ILPCM6PRUDvQ8HPX/3ql0eVU56AmH35lVfaGaef4Qp1tuzdi2Kef7RHHn74MGeiVSIgAiIgAiIgAiIgAiIgAiIgAiIgAiJw/BOQAP0iXaN5EFLf//732zXXXGuMpHCuYKfAUtSlpjVJzoNwDL3PCZbcjAX6KNy6xRTAIOgWRUIQpHM2jLzn/v5hiLMDEN9SVhqPORHOB9dzGNEb6cyoRYIRiyTibr8wBGHuH4WYFg2GLFpeaj4IyMyJZkZ0AOJaMpWxvvZ9NgKH9iiE6FIUNpzVsMj6EOvBnObkKHKZsU8RIjJKS+mIDkCArqDFGW7sNtu9fYcNnNaHGA70zf8gnAcRAZLC2Omi5XhyHPiE5imPnJKLD6J6v81fMN/+4q1vheN02P7j379+UGTJhC6Ow5la5GHz/K++5hpEl6TdGUbhJP/Rj35k//TF249bAbqurs7e9OY32znnnIf7KX/eRXDtb9261dZCOJ8cHXMs6FevXm2fv/12G8GDj2NpdMun4ey/7777pk2AjuFBz00332yXX36Fe5BCwZwcKEyz8Ca/AfB825Uvf7l98tOfcQ9p+OnnffGDH/zAHn/sMeSsp55vd9peBERABERABERABERABERABERABERABI4bAhKgX4RLUY+igLe85S32hje8wYlVFLDy0it+jomwnGe5PuePpcrsGqZwMTsBF+uQwwFBOgcHNLZNjVrzzu322B8etl07diMHGm7lAHKYkdUcgxgcDqHUXxhF/5C9XBQtdgUHa2trrK6m1spLSg3StYVxHvFw1IohUjNSIwdB2wfxOQsRbxjCc0dXt23Zvt3Wbthk/R37LYa+/RCYu9q6rW8Q2dMQppktnYjnLIHIjoGBUSuFszMIF/TuXbtsH1yd5WXlFvIHIVbC7Q1LNosQphlbgGNQYD7QCsY8Roc5D9yiHy7rhQsX2Lve9W7rQLwIhboTqTFXe8mSJRYBW46fLQKhv7q60gn4x+tY6CRmYUm63L2oiVyu2LnRWahyOlskEnHRLt0oqHksjfdUDDnn1VVVx9LNhH35eaXI3IeMdTr5OW+Wzzfnw5ijabfceis+G2XW09Pt+qPIvXjxYrvgJS+xe++552i61D4iIAIiIAIiIAIiIAIiIAIiIAIiIAIicFwQkAD9Al8GftX+mmuvsdtue58T8w46vKe7UmnFe2qy+UV5TzTFLpiHnWibgTMyDKE4CNF426bN9r3vfsf++MdHrbuvx5JwqAbhLI5BRK4rS1hlImYlsZBVoxBgSWnC5sydY7V19S4zOgb3LYXkAEToOETROOchpGUhrvkhhIVRhDAQCCEjOmP7OzrsiWeetXvvf9AefeppS6bhkkbxQkZ4BHCiGeQ79/X02G5EHlAcP+30Nc4t24rChRSh582f7woJDkCwHsX5M0c3GkUxQ5xrXsibTGQMBBZTeGejqEgBcO68ufaRj33UtmzdYk89+ZRbdyL8YO41Ha50fvPFxilF3akZHOejcgLs9J4jOZDJoXgcajnvjcnN62vy8pmY9z6+z7dvFvrkAxkM2O3KsTPWg7nraiIgAiIgAiIgAiIgAiIgAiIgAiIgAiJwIhOQAP0CX72zzz7bPvThD7vYjSM+NDWpMV2NWcFs4XDQAnCJDkOIpSv1jp/93J566hk4KHtd5EAul8Y2AassK7bZtdXWCBG6FrnNjSgMWFVRajVwPzNGI1IcNz/6YRlDHiSKKAEKXz64llGFEEI03NCYUiYNQSArqay0ulmzraahyWqRN/37R/5o+9o6nDiNIGsLYJtkchiRHgFL4NjFKHI4kE1C7K61hqYGi8Yiztcdg2gdSAZcvIATEyFgH7oxsuPgtRRs58yda5/527+1a6++ZlzMPXhLLTnRCPCe4PX1nNaF50+R+UiFZm7nifuFfRxv7397993WgG9GVOLzxTEzO30nctN/+MMfHm+nqvMRAREQAREQAREQAREQAREQAREQAREQgedFQAL088J1bBtfcMEF9iEUHayD89jluh7k1pxahOVST39lXjQUNUvDnRxEATiKVX94+BEI0He4IoHO7ZlOIgs6Ywk4o+vKS2xOXbU1FBdZJcTf2kTUyqKIfkBkR2aw13JBxFrAeOlHnIYPfWYDWUtaGukeyGbGsWCwxnFwAhCWOc/ihFXV1XbueedaPQRony9odyMiYA8czugAmdE5S+GcokUJqyovR8xEyDpHhhABEkQsR8KNYwiieawoDjE6aqPIjk7jWJCucYyJ4y8UnSeuyV8HCossgnfa6afb579wu334gx+a1hziY7va2vtYCGzcsNH+4e//Hk5/3IsFDmt+bs4551xbs2aNiyvhPUCRmZ+DzZs32/33/w731Oi4QM1oEGZTr1+3/lhOZ8b3/dxnP4tvDGTsVTfe6ETo+353n/37176GbHjlP884fB1ABERABERABERABERABERABERABERgRglIgJ5RvAc6X7Bwof05Mp/PO+88F79wYM2RvcuLsT4nxjF3lmLVEOIuUnjdB9GtB7EXzFoeRrQFKgZaFMJdMcKhq1FosL602CoiQYtDSA75Ef2QHsArDdEOkRnpEKIzQi5CgyI06gJCkEbMR85vGTiaqU77ISKH4ZLOIFIjieMNDg1ZCOfQgKJ0119/ncuL/vmvfm27mvdaKjkK43TQRiEKdnftt2gEwR4Qlvvg0u7s7LS5c+cj7zhqQzjPAMRjFm7LsoAhWqHg7Obd0oLlUKE9IX5slXO3Mi/3Na99rT326KP2YxTyGx4e8VZreoIS2Lx5k93++c/j7Cdecbr9P/DBD9ry5cuNcTaFAvT9v/udfeUrX3bfCKAT32sUsI/3Qn5ZPIS5/fbP29f+7WuuqOfI8PBRFTP0xqypCIiACIiACIiACIiACIiACIiACIiACBwvBCRAv0BX4tWvfjWyn691Ryt0dD7X4Qvdz9yWRc4o/lIpTsHpuW9fq23ZssW5oUcg6oYhFudSKB6YzFkJCgKWI+qiFE7jqB8u4xyE3iyczylkDWchZmfDcJiOmB/b04AcgGDtY6Y0xGMf8qApPCczPhseGYVLGRnROGYGjtPUyDCOF3ZRHfOQJf3nf/ZnKKBXY//5X9+2DbubrT5RZCPJIWvZ3WMrly1BcUKI0hChs2NO1hCE7gwEtxQc1RQGDxRy82iw2GDe80xRGqfjGrOvD9WKUfTwgx/6EETox2zTpk2H2uyEX371NdfYmWeeaVUoqsfcYDpku1G4bjuKQ/7Pt78N8X34iMZ4JqJgzj33XGtsaLSSMhShhM19CA8WelD079m1z9oPvve98X7oMD7cPcv1IyN50f+88863l1x0ocv6TuLBQkvLXvv1L3+JeJh8Rvdz9eUdlPdFKtXrzU6Ycow55GhPbswF5/nTAX0k7corX25nn3MOHP1VeBAClngow/0ZffHf3/7WuAB8pOfMlHYyZLviyivtrLPOslmIqxnF/d/W1mb/+z//Y9u2bnXrJ/fJB1SrVq3CtwJi7uESY3Cam5vtvnvvddvzRzwet5dddpmVoVghPz+8Zrt377bf/uY3bpvly1fYK199g4vy4Lre3l7bsGEDihj+1nbs2OFc4Ye7juMH0hsREAEREAEREAEREAEREAEREAEREAERmEYCEqCnEeahurr0ZS+zq666yiqQuXx4gXDM7Qmhddz3OSbAevMU3lJ0OMNFnA2krXlPs7Xtb3euX7pBi4uKzA9hl3EZEQjGMQjFEQi+/mwKgjNfKC6YgXiXQxYzYjqymRRc0PiafzrohOsAhGpGaRjEaLyBARrRG3A+p2GX9qO/cCQMFzSF4zTmIRTjmLXIlb7qistc3MYdP/+Fbd221cIQvufPnm1lJQlr294G93TaieejyREIYX4Xv+F3Dm6MBcUReU4UqPMaMwHkRWhIn2PL3CKe0pSNY1+yZIndcust9o//8I/W3t4+5XYn6sK3vu1tdsqpp0KkPMXqkRVchOvsnPAYN+8pOuAvOP8C27Ztm/3zP33RiY9TjfWCl7zErrjiSjv9jDOsqanJKNxH4G5n0UmKvnTeXgqx9Epss3btWvvmN/8TTvauqboaX9aF9Vde9XJ7xbXX2YKFC5zoWo74FcZi9PX32UUXXmS/+MXP7Qff/4Ht3986vt/RvmGsxlQ3ApfzAc1ztVtufYuL8KDg29DYOIElhXSy5DcVtkHU//KX/tk595+rTwq7HO8ll1xiN910sxPgGxsbrKSk1C2nOH7mGWfanXfdaXf89Ke2B8JxYbv66qvtFddfb6Wl2B6fXbr6H3nkEXv8scesv7/fbbpk6VK75ZZbbdbsWYgVSbltHnroQWttbXUPt85FNMnS5cusOFGMBz5+J8TzWweXvuxS+78f/9h++IMfFB5S70VABERABERABERABERABERABETgRSYA+yOMkPyW/5E3HzyZAfztnD6iXdw3+vF3NnUptRePgAToGWZP0fkNb3yDrVi1Mp9P7ATUg1VULil0J7p579ycCJ1fkoUTmd7PLIRomkBZrKy3t89lKSdQ8I/rmMGcySKeA68cLMQ+uI99sA+zB8Ys+2krhnDp4wecYjT+53pOcxCbeQw6NCl0+1DsMBSBqxrb8cNKQZp9pNE33/soiMMRXVVeZlddeZk1NdbZo489DqGxDc7pYevv6bLhocGx2JEsRFO/k5QZOUBncxDieAoZvRTM0JsbMY3SfOe93MIj+JHCL5+bX/96exQu6J/+5CdOUD2C3Y7rTcjlve+7DcL6rTZ37lxcLuR/Qyim4M5GwZUiMl2xS5YstZ7eHqusqrQvIL5i165d42MLwhG75rQ19v984AN2IQRhuugpOHv9cEPmdUfgvGUhPGYstyDXu76hwb76r1+x7RC23QUb7zH/hn2cd/75TnB92csuwz2JDHFcT/bLc6+uqrbZcAHPX7DAPRT43ne/O6mHF3b23e95r936lrfYApwPz7GQAVky1qOkpMQW42EGHcQ1yDv/AqIxKOwfrtF1fdppp7toEHIY4bcG8GDH48DfA3QvL1+xwiogzn/tq191rmivz/nz59viRYvdsSlkFyEjncIyz8cToKvAkhx5H5AxXdJ0bVOw5rcreAyPPfvlQwqOhWOtQ1zOrp278Nn4o3dITUVABERABERABERABERABERABETgRSFAExz/xm1oaLIyaBDUhfbva4HJcjf+np76m9385n19Y5OVV1Q6faqjvc327tmDv5n7DhoDRe2ysgr032hVNbVu/f7WfcZXV2fHQdtrwcwTkAA9w4xffeOr4aY83319nu5KCruHbZ7VGRsd2JI+4PwK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CIiACIiACIiACIiACIiACIiACIiACIjALAQkQM8C6F4cHYfoyz+WkaE+6+1stmP73oA7OtMy4GqurKmz8spaKywus4KiEssvLEPec4FlBDNdjMbqtevtSmOTjSCqIzaWsPz8fPPD3TzY02Fd7S3WBqH50sULNtLXar09ndbSeNkG0EFiLBK2SHjERoeHLAbxWUUEREAEREAEREAEREAEREAEREAEREAEREAEROCjTUAC9H2+/Rl5MTI04P7Sq9qCPObsnDzLDGVZAKJzMBhCPnQQjukMTOKxAERqdlAYhauZnQ6yo8Lx8YSNQWCOxSJwWQ/bMERmP3KlI5ERGx7oT1etVxEQAREQAREQAREQAREQAREQAREQAREQAREQARGYICABegLFR+cNOy/sx5+KCIiACIiACIiACIiACIiACIiACIiACIiACIiACCwkAfRKpyICIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACd56ABOg7z1Q1ioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIgIAEaO0GIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACC0JAAvSCYFWlIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACEqC1D4iACIiACIiACIiACIiACIiACIiACIiACIiACIiACCwIAQnQC4JVlYqACIiACIiACIiACIiACIiACIiACIiACIiACIiACEiA1j4gAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiKwIAQkQC8IVlUqAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAVr7gAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwIIQkAC9IFhVqQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgARo7QMiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAILQkAC9IJgVaUiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAISoLUPiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAILAgBCdALglWVioAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAISIDWPiACIiACIiACIiACIiACIiACIiACIiACIiACIiACIrAgBCRALwhWVSoCIiACIiAC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vXmX/CBrMb667n9aQnO16tWscqXK1sp9JLdt09bkO7pps6bWrFnz4EM6WbSVNbXSr1mzZh4BeqUvbDjks08txxd6rOpW0goSjau5yH7yKafYQQcfbB8NHuzsPwkL/8lHtwTeFT5LsNAnDVRnyWXanNu836ZOmRL8dF9y8SWJHRK0ZQHe2vNvQxKbwxdZR+++++5Wz92yRHcwsuKeP3++FWWVnRzTj24NT4AABCAAAQhAAAIQgAAEIAABCEAAAhCAAAI0bcAtbafYiy+8YBdeeKH7PHb/x5ssbuVTuEGDBna6W8uec+65waevLHfnzZ9n09zf8bixY+3111+zGdNn2PIVy4MwKv/JJRGysmpamzZt8oisq1attN/+7ndhob/NNsaFpybXyxJ1ZXks6+IoqGqbylWQa4wYm/w465gMF5z3339/d1lxvO22224uMjcLPrMlGktolggcP+P3aH0c4/JMJL7GL+L0zTffBN/NhxxyiLtAqRziUhwSmrWo4OlnnGHnnnde8CG90gX/+eLu7lKGDxtmn37yickqXfUxe/bsGG2Bn3N8/xivq46e/yhaq4733Xe/YNE8RRMLm4Jcbfzil79yi/jMxLFyhyL3G28PGhQP4xMCEIAABCAAAQhAAAIQgAAEIAABCEAAAikRQIBOCVP5PkiuFe69+65gddvcBVaJkAoSUiWu6k+iqIJE3EYNG1njRo1tn332scuvuMLdWCzzxefesCcef9yGDRuax21GOGkb/sl0AbRJU18EL0m8VdoSXLclRPF587mSp/W3ZZDribPOPtvF3/Ote48ellGtumXnZAdBVvlZsXx54qT88SbnNxzkSWwpP+eeLjcaV/3mSus/4GXbddddw0J/2lMod2feuHGTwP03V11ly5evsHffedtuveUfwcdyXGgwN/bN/86aNdP69uljt91+e0JUVn0e736+v/zyC0sWoLXQ44Fufa02EMVqWUCP/HZkEL43x8o3CEAAAhCAAAQgAAEIQAACEIAABCAAAQgUTWDzCm9FH8sR5ZiAFok7/NBD7L133w0L720hpG4qu7ZHS19ZFq9wVxJVqlS2U087zZ5wkfO63/+hRCjJ37PccOyokFu+LaVhCa9333uv3fjXm8ICgXJ9sWr1qiCqq9z5uWhb8l/+/VvLv47VIoBHHv4T++CD9/O46Mh/no5N5i4hXtxPPOkke/Ptd+zCiy4OPrLzn6ffy5Yts0FvvRnqNe7XpEJrtzCXyB+DxPQWLVpYffe/XcldjCioHqa7hfvM6TPjYXxCAAIQgAAEIAABCEAAAhCAAAQgAAEIQCBlAlhAp4yq/B+40v0L/+bKX1vjJk3svPPPd7cTxwU/zPK3LJcNWxNa5VJCi/qd4W4j5J+4z5NPbBcwuQKRuJ3p7h9ikEC6dNlS90G91n0wF2y9HI/d2qdE5i+//NJmz5qV57DaderYww8/YgcedJDJ7YTKG4NcZEiM1acE6QULFppcW0yZMtkm/PCDDRkyxGS1fbH7Wj7OLYu10F+qQZbLl11yibNubz89+RQ74cQTrYP7aFZ8ycz1Pb/ALSFZgvF1v/+9DRs+zEa6Ww9tyx/kgmSw+5Q+/PDDg6W14lmXk2MHH3Swfel5H+ZuPeq7y5Ff/urXm1yV5IrzGRmZ9snHH/m5H+aPkt8QgAAEIAABCEAAAhCAAAQgAAEIQAACECiSAAJ0kYgq1gGyrJVP6Af/8x97yi2atSieXFLs1rGjHXDAAdalazfbxd1FtPSF96q4GCtXDlEYjVa1519wwXYL0GvWrA4CbxMXtaOgKr/M11x9lbudeMdq+fdtDRKy5UZDlsEx1Ktf337285/bIYceGoTmKPRKcJZgPf678fbUU33sww8/sBwXbmUZLdFdVuD6U1wHHHigL0bYLOFDO8adyqdE6O+++85mzpxpT/d9yvNQzbnXcN5d3Vfzvta5S9fAvVUrca8SuEcuyqvY3HHHnXbOWWf5gpJzt0hysS8Y+c/bb7Of/OQnQWDWOUpzr733DoK7BOgs93d95FFHJfYrkspuZf3tqG9t4oQJW8TJBghAAAIQgAAEIAABCEAAAhCAAAQgAAEIFEUAAbooQhV0/1JfgFB/MUyaNMmGfv211XEr4ayatdxCuLodfPAh7vrhorAwn8RMiZqV3V9w8+bNbfdevWzUt99uYbEb4yvqc5VbY0+bOtV23333PIdKDF60aFH4y7NjO380dVcU55xzbhCbo7Bb2d1QSGR+7LFH7Un3bz1//gJnsqTQlLRwoIT5ZMvpQg8uYIf45ef+448/2hdffGF1XGCu6S5JZPh93HEnhAUKW7duncddSs+ePV24rlJAzBbyNGnixLBgYatWrYLIrHI2cWt3ueJQkH9pLbIogV1BFt86Z9qUqeE3/0AAAhCAAAQgAAEIQAACEIAABCAAAQhAoLgEEKCLS2wnHC8r3B0VJGrK3cMuu+wSxNP69RvY2DFj7N133zG55IhBAvMsd1mhvxjGjR1nWrROC/bJd7CEyw0uamrb/vvvb2NGj05YL8dzUv1c7u43Jkyc4ELp5rLL0vjIo462b4YPtzGex1RDzVo1g1heo0aWDXx5QIGnRSvvHE8jhhpugfzggw/YvffcbQtcfC4syKJa4rHEcQm6Eq0TQdt9EcPKbrWcHDKqZ1jXbt2snXOXYC/hV9bVX3/1VZ6FFmVhPsutojdTN3f5MSGkd/Gll1jNrJoJwVuLBSqe5DpKTlP5eqFfP3ez8atgMS0BWmJ5x46d3If36dapU6cgTMdz5ALk9ddft29GfBM38QkBCEAAAhCAAAQgAAEIQAACEIAABCAAgWIRQIAuFq4df3D+ZfEkbso3cbIQW1K5kFB81NFH2wXnXxD8Pku8rOv+hH8YP94+++zTPAJ0QWnKGvjpp/taT7dSbteuXRCgJcTKclZuOpT3bQ1L3GXEqJHfuphd1ePNFYUlQB9ySO5CicURoFu1bGV/uv764LpCIqv8Nn/22Wc20xdeVH4VJPJLFE4WoKt4OT7+6KMgPkeRuaDyKI4mTZravvvtH0ToaEGsYxW7FlNUOWJo2LChnfR//2fHHnd8EP0lWjdt2sw6durovqUXBOE+Hpv/U/mQlfTgjwbboYcdZnvuuWdi8UKJyRK05cpDPp/zBwnOzz37jMlFSh231vbZgWBBvavX1cXug7pOndp5xHMd/6VbX0sAL26Q726VXRMXBAhAAAIQgAAEIAABCEAAAhCAAAQgAIGKS2CzKlZxGZSqkktEXL8hdxE5CZsSHGVdvDHIeSWbVcXZs0dPO/WUk23xkmUhXaXfvUcP28f9Dr/5xhtFJrh27RoXLXPyiM3Ks0To7QkScSe6BbQWHIxBeWvUqJGd6Iv0jR41ykaOHBF3FfrZ0I8/211r7LP3PkGU3WuvvWzO3Ll226232EsvvGBLlmxyqeGsN27cvOigIhR/WQHH7+FLIf+ccNKJdsqpp24puHoctWpLgK6WOLO6i7Odu3SxU045JSy0qHJlZ68N4vre7pNZluOFhSiYa1FIMRLr5CAXKIUFnSvr6PHff2/iUt3zpLTlOqSr+5pWnem3gqypv/fj5syZXVh0W2yXiN/K3YKoDJrMUHozXOQf7v6ltTClBG0CBCAAAQhAAAIQgAAEIAABCEAAAhCAQMUisNm/QcUqd6ktbU52jouY2XmERYmFe7sgnLFJDC2pzK/LWResZWfMnmM5LiLLRYMESAmb1/z2t/aTww8vMqlTTj3NOnXunLDClQip8+XGI4qlRUZSyAGLFy+xD99/P7CIQutyXzzw2OOOs6uuvjq4DpHrjIKCBFQtCHjBz35u1/72d8FqWBbUEpwbuQVyi+YtEuKyzl+/fsOWFt8uoMq6u36DBgUlEbbJhckee+xpR7lrkDYuvuZxv+FHiEGWu8mQNXUMs10Efv6554L4rDzpHImztWrVtmOOPdbdhRycp/7jecmf8vfcsWPHLdKb7D6jC7J+Tj6333PPhoUKJTgrfxLHxVEuRGLQtoEvv2xT3Q93qqGtW8Ff9/vf23P9XrA77rzL7rzrbuv3Yn+76ppr3L9041Sj4TgIQAACEIAABCAAAQhAAAIQgAAEIACBckQAAbqUVabEw5Xu/zgKrsreBhcoH33kUbdUPjVYQzdq1Nh2bd/eurgVbWECbKrFmjjhB/vs00/yiI8SQ/fea2+74S832vEnnBBcSMhKVmKr0pNLkAYuyh7mLiAuvPDCIARLNF4BNwAAQABJREFUSFWQAC2R+EW3Lt5ei9d58+baDTdcv4WgumrVKjvtjDPshZf628luRSyXFo1c4FSe9L2euxE54MAD7d5//9v+dvPNtmbNZncUyt/UaVNtwICXglVu5CRXETPd1UQy9xVeD9dc81v3mfzrUG65rZA7DS3EWL9+/WA5fO5551kfd0NygltlL1u2LEaX57NmzZpWLUmA1k65GJElcnJ6K1estBNPOsluuPFGd41yTIg/cPfzs/yvti9EqPTPOPNMO/Oss4M1eDLjZcuXFer/OTlDrwwcaNOmTQt1pe0SoeNfPG6DW4MPHPiyzZ83L24q8vOYY46xyy67whb7IpFiob+lSxbbNdf+1nr0zLuYZJGRcQAEIAABCEAAAhCAAAQgAAEIQAACEIBAuSCw2SyzXBSn7Bdi9uzZ7qN4ShCXozsE+dKVRep9//mPbXCxUE4XZK06111JPPHE43bHP/+5zQUfMWKE9XvueTv22OPyxCEhvHv37vZU32dcrJxq33zzTRAtV/nChHKzsM8+e9uuu7YPIubqVbkCr8RUCdGz3W2DxNuSCLIWfu+99zx/x1qGu66ITJSPli1bush8n631NBfMn++uNeZYjcwaYVE/idDKz2oXq5ODtt180002aeKk5M0uli61oV9/ba29bBJjFfQpFyPXujX42eecY199+UUQqWWRLr/S7Tu0DyJwlUpVTPmJ5yWLytqm4/Nbr8vX8yMP/c9uu/2fwd1FONcrdvmy5cGiuu/TTweBfOjQr22aWyHLFYkWKzzgwIOsTZs27s+6ckKYV3oSoj/79DPLTnJZkqeA+X6MHT3GunfrHkTuZBE7HjZmzNiEVXvctrXPat4eVU65MYkc4vFrVq+xXr1298Ujh9nChQvjZj4hAAEIQAACEIAABCAAAQhAAAIQgAAEKgABBOhSVsnvvD3I2rkrg3vuvXezf+JNeYxCoeRRuW2Qm4n69Qt3D5Fq0QYPHmx/dNcJd9x9dx7BVkKi/DtL+DzO3V7ot/4keCpthSgI67v8JY8eM8r+cN11+lkiQUL4NVf9xj79fIi1bds2kQdFHvMj62L5HG7atKl55qyy/8V9MRPKs6yf+/Z9yj784IOEeBv3y/r59ttutSN9UcZabm2cHNa5SxG57TjOFw3MLb+SqRw4VPLpAFkLy52FJg8khHfp1k2ZC1GIzy67tAvWy8lxrnTBekD//l6mdnbZ5ZeHCYXIMn5qccLcNCXqKs1c7pqAiMcoTm1f7oL/b6+5OmWB9/HHHwsTDIcfcUQe1yOKS399fGKjONbPEv71Jz5bBndDUtP9YCe5+NjyGLZAAAIQgAAEIAABCEAAAhCAAAQgAAEIlEcCuODYAbUqcXJbg4TFcWPHuG/mcVt1rxGFPomF2xtk/dt/QH+74fo/B1cPsjROjlffJbDKClv79Jm8X8JuXbc4/m78eLfGvsPzP3Z7s5TnfLncOOrII+y5Z58xicE1atTIs18/lB+J4rIMTg7aruMli95++20uMt9WqEirBfN+fv55VsnjkMVychn1PTKoWrVaSCvuV/zK42OPPmo33/y3wCfmQfXUpElTF+e3zLOsxP/tEw19n3oqWDDLvUnlpLazOc3qpoUL83NXeeXeY4FbFZ971pkmq+pUg3xFT546xbKdZyxHPFeTG++9+26xrNjVhua6BXqyH+kYn/iMGPGNzXGBngABCEAAAhCAAAQgAAEIQAACEIAABCBQsQjIjPVvZaXIDRo2shq+oNuypUtshfu7LY2hhouI+x+wvx1yyKFBdKxRIzOIhBKWP/3kE3dDMLzIbMu1xpjRo4N7hD336h2ER4mNEnolgkrkiyLsDz/8YIPeeqvIOIs6QJbGP7hP4nfeedv9FVe3Dh13C76UlV5MW0Kl8qDfUYyWP+Q5c+bYA/ffb7f8/e828tuRQSQuKr3i7lf+5AZkjC9uqMUFu3Tt6ha3mYGH8qS86S85bxJn16xZY++8/bbd+Jcb7O1Bg2zRVlxASCye5S4/Pnz/g+BLejdnoPJJFFYasewxDdWB+AwZMsTuvvNO69PnSV9sr4lddsUVVtPbgSzC9VenVk178cUXbcKECVsUW76nx7q7i3fffSfE1b5Dh5C20tBfTFeieNVN3BWnyiar7Uceftj+dtNfbfSoUVvEXdSGtm3aWqdOnUI9q32Kn6zsv/12lD3jLkCys9cWFUWe/Tq3RauW1muPXm4Bnus2ppb7rX7j9dfCoouL3Dc0AQIQgAAEIAABCEAAAhCAAAQgAAEIQKBwAjVr1ba67vFgrWtaixbML/zAMrRH5rMFvTNfKovQvmNna9Cwsc2YNtlmz5xRKvMoC+FOnTtb506dHWwuWllEy5ewROVJk/L6Hi6sEBIDu7orB/lhbt2qjXXs1NHauAsKhYULF9jsWbNt4sQJ9tVXX9kIF2ZLMuzWsWNYWLDDbh1t1112Cb6Wm7h7Cy0+KB/DEk3nuJ/nmTNm2vffj7fJkyfbyBEjbf781Bes29b8SvjevVev4I5Di/J17NjJ2XSy1u4XOatGVrDaXbBgns2bO8/GuRW5rLGnug/l4lpli73iFf/dnEOLFi19AcBcQVvC8Hx3tSEx/Ltx44JwL4t1ieSNfTHEQw49LAjH8dJSnj9yNycSt7cWdtttN/cr7X/td/VydbTmLVoEQVvpSgRf5os7ys/1jOnTQzv63i3Olb4mALYl/PZ319kVv/hFWLwxunRRGa5ylyeD3nyzWD6glX6mC/JdfWLgsMN+Ej5lXS1r/k8//dTGf/ddaDfbkk/OgQAEIAABCEAAAhCAAAQgAAEIQAACFYVAk2bNrc0u7W3p4sU2YXzJehnYWQwRoNNMXsJydJ+RatJZbvXdpm0b93Pc3K1ULfiGln9eWUrnuMi3o0K16tWC8CpfxA0aNAhWt0pPCw3K3cP8efPDAoU7Kv1U4m3m/qnlG1o+oDMyMl0EXmWL/QKVta3cTEhQ3Z6gxQwl/MuyOSurRhBRJUArjYkTJwafzzH+ouq2qP0xHlk9q0yNXMyWj2+lq3PlN3rhwkUurs+x6S5Cb2948H8P2Tm+uKLqU21S5VK97t17zzx+oYubjnw97+aW3DnuymOSM0r2V13cuDgeAhCAAAQgAAEIQAACEIAABCAAAQhUJALlUYBmEcI0t+Diis/K3qpVK4MFqaxI0xlysnNs6pQp4S+d6RYnLfkV3pG+hZcsWbLFYpCF5a+oui1qf4xXgq2syvW3o8Khhx3mVspdgqW28iXRW36sP/n44+0Sn5XfHBe0x7llNgECEIAABCAAAQhAAAIQgAAEIAABCEAAAnlXbIMHBCBQ7gloscPLL7/C/T93TrjFkPWzXLv898EHgrV1uYdAASEAAQhAAAIQgAAEIAABCEAAAhCAAATSQgAL6LRgJhEI7HwCVatW8wUH69pFF19se/buHRazlEsVWT/Lr/f3vgjlqG1YzHDnl4wcQAACEIAABCAAAQhAAAIQgAAEIAABCJRWAgjQpbVmyBcEtpNA1apVTQsgysWGPnv12tP+8Oc/Wm8Xn6tUrpLwH659EyZMsCefeHI7U+R0CEAAAhCAAAQgAAEIQAACEIAABCAAAQjkJYAAnZcHvyBQbghccumlduNfb0osAqiFDOVqo5L/FxcGlPWzFmocPmyYvffuO+Wm7BQEAhCAAAQgAAEIQAACEIAABCAAAQhAoHQQwAd06agHcgGBEidQs2Yta9CggWVmZlpGRkZwuSHBOQYJ0llZNW3gwIF27TVXx818QgACEIAABCAAAQhAAAIQgAAEIAABCECgxAhgAV1iKIkIAqWPgNxvrF+/Pk/GJDwHQTqjuvV58kn71+23Jyyi8xzIDwhAAAIQgAAEIAABCEAAAhCAAAQgAAEIbCcBBOjtBMjpECitBGT5nJWZ4eJybXPN2Sq59bMsoLXw4McffWSvvvqKvTNokE2fPr20FoF8QQACEIAABCAAAQhAAAIQgAAEIAABCJRxAgjQZbwCyT4ECiPw0eDBduddd1tWzSxb436eV61aZfPmzbecdTk2etQo++rLL7ewji4sLrZDAAIQgAAEIAABCEAAAhCAAAQgAAEIQGBbCCBAbws1zoFAGSAwZMjnNmLEN9aocSMXn1fbyhUrbM2aNWUg52QRAhCAAAQgAAEIQAACEIAABCAAAQhAoLwQQIAuLzVJOSBQAIHVbvk8fRouNgpAwyYIQAACEIAABCAAAQhAAAIQgAAEIACBNBConIY0SAICEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQqIAEE6ApY6RQZAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEA6CCBAp4MyaUAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQqIAEEKArYKVTZAhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAAC6SCAAJ0OyqQBAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQKACEkCAroCVTpEhAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCKSDAAJ0OiiTBgQgAAEIQAACEIAABCAAAQhAAAIQgAAEIACBCkgAAboCVjpFhgAEIAABCEAAAhCAAAQgAAEIQAACEIAABCCQDgII0OmgTBoQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCogAQToCljpFBkCEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAQDoIIECngzJpQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCogAQQoCtgpVNkCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAALpIIAAnQ7KpAEBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAoAISQICugJVOkSEAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIpIMAAnQ6KJMGBCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAIEKSAABugJWOkWGAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIJAOAgjQ6aBMGhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEKiABBOgKWOkUGQIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAOgggQKeDMmlAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEKiABBCgK2ClU2QIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAukggACdDsqkAQEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgAhJAgK6AlU6RIQABCEAAAhCAAAQgAAEIQAACEIAABCAAAQikgwACdDookwYEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAgQpIAAG6AlY6RYYABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgkA4CCNDpoEwaEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQqIAEE6ApY6RQZAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEA6CCBAp4MyaUAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQqIAEEKArYKVTZAhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAAC6SCAAJ0OyqQBAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQKACEkCAroCVTpEhAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCKSDAAJ0OiiTBgQgAAEIQAACEIAABCAAAQhAAAIQgAAEIACBCkgAAboCVjpFhgAEIAABCEAAAhCAAAQgAAEIQAACEIAABCCQDgII0OmgTBoQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCogAQToCljpFBkCEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAQDoIIECngzJpQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCogAQQoCtgpVNkCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAALpIIAAnQ7KpAEBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAoAISQICugJVOkSEAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIpIMAAnQ6KJMGBCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAIEKSAABugJWOkWGAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIJAOAgjQ6aBMGhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEKiABBOgKWOkUGQIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAOgggQKeDMmlAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEKiABBCgK2ClU2QIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAukggACdDsqkAQEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgAhJAgK6AlU6RIQABCEAAAhCAAAQgAAEIQAACEIAABCAAAQikgwACdDookwYEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAgQpIAAG6AlY6RYYABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgkA4CCNDpoEwaEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQqIAEE6ApY6RQZAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgEA6CCBAp4MyaUAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQqIAEEKArYKVTZAhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAAC6SCAAJ0OyqQBAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQKACEkCAroCVTpEhAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCKSDAAJ0OiiTBgQgAAEIQAACEIAABCAAAQhAAAIQgAAEIACBCkgAAboCVjpFhgAEIAABCEAAAhCAAAQgAAEIQAACEIAABCCQDgII0OmgTBoQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCogAQToCljpFBkCEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAQDoIIECngzJpQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCogAQQoCtgpVNkCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAALpIIAAnQ7KpAEBCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAoAISQICugJVOkSEAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIpIMAAnQ6KJMGBCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAIEKSAABugJWOkWGAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIJAOAgjQ6aBMGhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEKiABBOgKWOkUGQIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIBAOgggQKeDMmlAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEKiABBCgK2ClU2QIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAukggACdDsqkAQEIQAACEIAABCAAAQhAAAIQgAAEIAABCECgAhJAgK6AlU6RIQABCEAAAhCAAAQgAAEIQAACEIAABCAAAQikgwACdDookwYEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAgQpIAAG6AlY6RYYABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgkA4CCNDpoEwaEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQqIAEE6ApY6RQZApFAlSpVrFatWpaRkRE38QkBCEAAAhCAAAQgAAEIQAACEIAABCAAgRIjULXEYiKiUkmgevXqIV/Z2dmlMn+lNVMSZqtVq2Zr1661jRs3ltZsFjtflSpVsmbNmgXBuXLlyrbLrrta69atbfGiRTZx4kRbvny5TZs2rdjxcgIEIJA+AjVq1LD69etbpn9u3LDBzK/rDf45Z/bs0GelLyekBAEIQAACEIAABCAAAQhAAAIQKJoAAnTRjMrkEVWrVg3CYucuXWzdunU25PPPTSJ0Tk5OmSxPujItUTYzM9N69OhhrVq1trFjx9rkyT8GhuvXr09XNnZIOhkZmbZr+13t3/ff7+XrGcrp6noQ2CVMS3SfO3eudenU0cp6WXcIQCKFQCkhcMABB9of/vQnO/Cgg2z16tXh2tXk0ak/PdlGjvyG67eU1BPZgAAEIAABCEAAAhCAAAQgAIFcAgjQ5bAl1KlTx2686Sa78KKLLCc7x43jKtnyFcvt9ltvs+eefQYLuULqvJKLz+07dLCXB75iDRs2DEdVz6huHw3+yO65+64g4hdyaqnfXLt2bbvm2t/aJZddahnVc91trF2zJk++JUC7HJ1nGz8gAIHSR6Ba9WqhX8/xScV1PqkoK+j1PtFYtbrf0r2/J0AAAhCAAAQgAAEIQAACEIAABEoTAXxAl6baKKG8nH/Bz+yYY461ypUqmyx6JazWrVPXrr/heqtZs2YJpVL+oqlXt6795ca/WoMGDYJFoditX7fejjjiCDvttNPLbIEz3A3LQW4pefkVV1imW0G7QlVmy0LGIQABCEAAAhCAAAQgAAEIQAACEIAABMoWAQToslVfKeW2e4/u1qZNm+BuQ/6LZR2nz7p16/kr2wdbhruYIGxJQK43Dj3ssCDay5+qmOlTlsEdO3a0nj133/KkMrBFfp5v/vs/gsuNXH/WuW435ONaltF169Wz2m41L5+ysp4nQAACEIAABCAAAQhAAAIQgAAEIAABCECgpAjggqOkSJaieGpk1TC5jpBv0PwhJ9sX1XNRlbAlAVk813FBVgsP5g/r3P9zdk7ZW8hR4nl39/fcpWtXW7FiRaJYWVlZ9u2339qA/v1t9OhRpsUq5Te8ijOQ6E6AAAQgAAEIQAACEIAABCAAAQhAAAIQgEBJEECALgmKpSyO5cuWBxFVgqIWIJQPaImra9zn7/fffx8WIyxlWS4V2dHCe/Pmz7OGDRqGRbxkLSxu+ps7d46NH/9dqchncTLRtGlTt9zuaeuTRGWVZ+bMGfZUnz72zNN9aQ/FAcqxEIAABCAAAQhAAAIQgAAEIAABCEAAAsUigAuOYuEqGwe/PGCAffD++2E5uVpu0ZuVVdMXIVxhTz31lM2aNatsFGIn5HLZsmV2/3332ezZs92CPCO4p5BbjqFDh9pbb71lZXF9vkaNG1unzp3DAmURqVxvvPrqq/b6668F8VkTFAQIQAACEIAABCAAAQhAAAIQgAAEIAABCOwIAlhA7wiqOzFOiYkfDR4chMWZLjbLmneDW/ZOnjLF7rrjjgLdS+zE7JaqpFetWmX/feABq1a1mrut6OHCfY3A65WBA+2N118vVXlNNTPy8dyiZcs8bjUkQL89aJDNnzcvRJPrFzrVGDkOAhCAAAQgAAEIQAACEIAABCAAAQhAAAKpE0CATp1VmThSYqJE6CGffx7+ykSmS1km7/v3vaUsR9ueHblhyczMCAsqJmLx9rFs6dLET75AAAIQgAAEIAABCEAAAhCAAAQgAAEIQGBHEcAFx44iuxPj3aEWrS5e4rJhJ1ZuMZNWW8jfHjZu9EUGvR7LU9hZbXJ7093e81Otw3Slo/ykM62dkV5kvl3l3EnX33blORa8FH9ua/m29bxSjIKsQQACEIAABCAAAQhAAAIQKFUEEKBLVXWU7szImrZJkybWum1bq169eunObCnKnZg1atSoVDEracGlVq1aoW3oM51B5VCabbxNVqlSJZ1Jh/pUulk1axY7XV1LahNaJHJHhxo1aljz5s2DT/MdnVadevWsmadV0u2roHxXcYYNnWHrNm1CGyjomB2xTe1MddeqVauwQGlx06iRlRWulXr16xf31O06Xn7tWzmrHV03ujc0dt/z6vfSGXRNtW3XzrTuQXHKWNOvX12H9dNcH+lkQ1oQgAAEIAABCEAAAhCAAAR2NgFccOzsGthB6Z919tl2xpln25o1q4NIsmrlSrvjjn/ZxAkT8vgD3lryp51xpp1++unWzh/qs1w0kbBQuXLunIWsarOzs23hwoU2ffo0e+bpp+3dd97ZWnS2//77e57OsuYtWuQuiheMcCvZ8OHDrM+TT9riRYu2er52Kg8XX3KpHXX00bbafTaH4CKk8nP/v++zkSO/sZycnNzt2/CvRIz7H3jQ6tSp42dvtIyMTPvqyy+t/0sv2hT3o11U6NK1q/3il7+0PXvvZQ0a1LfKlSpvZrZhg61bt87WrF0bFjp8zRcCfPSRh4uKslj7r7r6attjzz2dU0bgIDGwRQv3Ae1+wGNYu2at3fz3fwTeCdHWGa73Y378cZL94+abi2wj559/vp159jnW0v1La6FGxSPRR/WgeNZ6GefNn2cvPN/P+j7VJ2yL6Rf1edTRx9h5Hr98VSuonT326CP29VdfhTJJUL38iiv8mAuspovP1bzOVOcvvNDP7rrzTlNb35YgX9k3/vUmF2pdRN9oXvcZNsAX9Hzn7UG2ePHiYDV++OGHh2MkfCpdlf19X/Dznrvvsu/GjSs02QMOPMjOOOMM23uffaxBw4beLvxNAh29ifuq1atDfcydO8f6PPFEiLPQyLayo6ozu+zyy+3YY49zMa5tKINSinWzwdug6ma1p/fFF1+4z/P/2KRJk7YSY+G76rnYfOVvfmOHHHqYi87NQn3FtEI6Xm9LliyxeXPn2ocffmD9nn/elojjNob/++lP7dxzzwuTDRL9q1evZv/P3nkARlV0bfgIhN4F6RJ6bwIKIgqIHVQQlY69YkcUK/aOFREVRfT3swtSRFHpoNJEepGO9N6r/3lmM8vNZpNsIi145vuWu3vv1HfOTLzvnHkncya1O83voNrdvoT5aNny5WpzH8noUSNjngsaNz5but55Zzi+7huQe+6+W9Yn6KSfqsTtDTfeJC21DsxB9D223rFDe5k6ZUqK9t3lmmvloosvkvIVKkounUfpC98fjJVdu3crTptk4oSJ8qra0cYY5sEUIdR6EWrWriU33HCjNFLbY8wwd1MufePK1L4YM3q0fPjhB7I0hrktuTKbNz9PWuvfiTp16gg24dtHfNq3Xcfjpo0bdM5b7ezt999/Ty6rRPcrV6ni+rtCxYphfH//7Vf5eMCA0HjU2M2aN5fu3R9QnfvikjUuqyt75d8rpXOHDrJixYpE+fEDDG7W+fmCCy6UeP27xhgP15e5S7HZq3PJ9m3b9G/JNHnh+edl+bJlSfKxG4aAIWAIGAKGgCFgCBgChoAhYAgYAmlDwAjotOGVIWJDyp3RoIE0a9ZUtm/fri/YmRwRPXfuXHnrzTf0++4U29Gpc2dpdUUbqVihgiNiPfHMi3owQMDg6Va2bFmpq4TrhAkT5L2+feX3338LRgt/L3hyIalbr75UqlTRkWA+v7POOktmz5olP40YESYawokivtx2++1yvZIqBQsWlP1KbigL5EiFzFkyy+uvvZYqcRqRXZKfELbnnnuu4BUHUYPXIGT0nDmzZUkUkoY2gEONmjUd8dyoUSONn0/wcswSxSMXaugfzbdo0aJSrlw5ade+vRJPE+SpJ59w/eLzS1KxGG+0uPRSqVa1msORemXSOmRW0iVESYUygQSHLKJ9ahzuJv9CztSsWUOefvLJRKX5OoFJh06dpKN+ChYo6MgmSGK/KBFMRN54FZa6v5QjRL9UAv8jXWSAXPP5BeMHv1eoUF4uvvgSZ7PEhVxevHiRjB83Tlpq+6659jqpVauW8+ilbD6QqnhCEz+9IW+evHLJJZeEk2P323dsVy31cVJA7a1bt/uVbD1HTlYC2RPuxMmbN4+wcBEtlCtfXh555FFXXzxek7ML8CqutlepUiWpXec0Ga9lMpYmT5oULduo9yCDW11xhZTQBQewoG7R8MAuKK9okaJyjraHeWFA//7y448/pNg3vt9o++NPPCnNmjaVIkWL6FjJ7dofWRblFFEv2HI6P9BfrVtfIa+/+qoMHTokav2DN4Nltbz0ch3z1wskMF6qtIs+j1ZeIZ2Pyrj56DRd2JrqymOBy+cXLCP4vWq1anL+BRfItq1b3W3iMz4hoK+/4Qbp3OUaKVWqVNjGfH7Yf7Ae/j4YXdaqldxyyy26SFNS8qiNZNNFIeodGXzfx5eOl+ZKqA4dMkQ+6v+hLuwtT7XeifJK6FdI35df6SVNdbGEeZLFw8hy6Rv6Pz4+Xhrp/Psa/TJkcJrK46BWFmwqKkEM8QzJTbsjA+OlhC46Vq5cRU7TxbGff/5Z3u37jluw8XhFpuH3qaVOVeL+Yl1A0wVL5noN9MHnn3/uML1LFwhatGwp+bRsFgR8Xjt27nDznkuQ8A9zVyu1vxtvvklOKXyKmztSHB86d5VQUvt0XTBavnyFzs9Pyh/TpgaztO+GgCFgCBgChoAhYAgYAoaAIWAIGAJpQCA6a5KGDCzq8YcAL9aQAXhnQt6FyId/ErzTkhIgwRY8rx6keHlChpCOF3/ICk8AeLKFewR+U04e3fZ8sZIFENL9+r0vg9W7NzKMVC/IylUqS08lr3w+xIHEefjRR2WleqzNnDkzTCREpofwOF+9Y0sqCbFXCUdIP+pIG0coeb1YvXd9PSPTxvKbOmXVuoAdnnEQQ3gSQ17QxmgBHM5V0giv5wYNGjqCivqQFqKXPPk4vDSuJ4KpO1hBREOsQXJDQq9VwiscP1qBqdzLoyRqjhw5FZO9Libl+r4KJo0kzngGic/29WDwdSlTpox6u94p5194oZRUT+H9+w8o1vtdO2lrtAAZxTZ8PItvvvkWKV++gvR5u7fMnDEjxTbGqSdjzlw5td4HXTz6mD6BbMLz+YwzGoT7nbKp436ti+v7BLuMVp/U7lEOfU2/Eeh72sBizmmn1ZXLlVDEDvDI9nYWHCPB/LnfQD3+ezz0sCPdSEeaSLsgje8j0mB3xZU8vuiii6W8EqBDhw6VXi+/HMw6yXfq3P3BB+Xyy1s5WQjKoCxfR/Dx/ehtgd+51dM7v3rpIyUBUZy/QH75Qsm9aMGnP0WJuedfeEHOOquxk7/As96XBfV/kraB4NtEOj8fQR4/8dRTUu/0+vK/Tz+V+fPmubiR//iyIE+vve46adcOr+dT0zwfnXtuAbcI0uftt2Xgt99EFhP+TXnZFfcc2XO4eYXffPbs2i03qDf59brjomLFStp3B8K24evo8SQzf69gwZN1l8b10rZdO4kvE68LTiHCn37hEy3Q98wBBU8u6OYF0r337rtu90W0+FHvaZ3xsO7T91318L3AzffYsre7yDSZMp3k5m0WBx7r2dNh9YHO3akF5o5zmjSVB3v0kGpK3PMbz2EW1oJzHvl4O2AcMefRxssvv1yqVq0iX37xhe5seC/Z4siXhRTGhLdl5ieI86vbtZV26n2eWxc/WHzyz8nMfQ/MA8yz7Tt0VA/2G92ODZ77D/HpN/2Hyrr6+ns5c+bSOSu/lNa/ha/q4ubTTz8lP+vfGd/PxLNgCBgChoAhYAgYAoaAIWAIGAKGgCEQGwJGQMeGU4aKxUu/Jzs84cE19JLuKdDETeJFH7KlXbv2jsTwxAWxIAIgAXhJ94Q2pBJb3vGmJm9IAO7hAXzwnwNJCGhe2neqZMbnn30m8fFllNS5XrZs2eIqQdratetIpy5dVEbjNVm5cmXiyiX8Ygt8terVZX8Cwctt8l2vMiAv6lZp5ED+bYjEDhIU4ukgB/dFCRBTkGRNlJChLt67HMwgTcGR7e54IufIAYmtcZTY2r9/n3vGc7wH2cK+ZesW9QzsK8uWLo1SUmy36IPsWk7mzCEikD6HMA0SZXyHEIX0CgY0dbNlS5A1SXhA3EqVK8utt93mPFhZaPBtJAqkEm3lA8l04MBBR37TLmyFKx+IaIgn6tdbZR/+mDYtWHSi764PtN5c/SdfvnxO7qF6teoOZ/Im0AbKBXvy5pr+EFpo8WMGgh0yvLV6FWOfjAFslUA5lE2ZeMnjZR4MpVUb+pFHH9NFiQau/fQBgTz47FNMdujuBAJjDxwZH2BFGRCidevWV2/rQkrUzpchg79zcSP/oT8gnjt37uLIRF8OdfOer0i+kC/1JF/y5+NJOPCrrR7xt9x6m2zduk2Gfz8sshjXD+hd33X3PXLppZe53ywCEag7tk5fIbfA+HSLNmqH2Dp1or/ADDkFPIr37dsvzyqhFy2QD2T1lVdd5eakYkWLOZsLzV+h+Si0IHSSyiXsDff9AW0jGPr5CJs888xGsnrVKhkzZrRsTGZ+oDzGtxvnOpcRqOvZTc6Rq1QyCE9oxiv5KjWtJPtJzua87fk2kA922vqK1nKjkp1FdHEJqRMfmAOoE4tcYE6gXxhPXH1/QLy3aNFSkMpZtnSZSlf87bNI9krdyBu5D+Ql4uKyONy5hx1QHstfkOGU5+cEyqWt7JpooxIxo0aOdDI8yRakD6qqzNDDjzziFlZ2af/6sUifMB7Im37QjCWP2jZl71C7oH2Ujb03bHim85xftGiR/KIe0dECeDKf0DY+BGSX7rrnHl0UOsPZmJ+L/HikT6gHv31ArokFQjypXb30Ac+xUerI3zHqFqd154P9ki9lMk7Is27dutKjx0NunKcmNeXLtashYAgYAoaAIWAIGAKGgCFgCBgChsAhBIyAPoTFf/pbFdXbvOOOu9QLMOQ17cHgZZ6t4MhrLF68WEmmg+6FPEvmLEpa1XZev5BPvKhDZkB41KhR03mLfvfdINUeDhEHkAmEFZoXXna80FdQiQ/SEPA2bNPmSpW6mOM0cN3NwD/nqUcfnsZ51INuj5IDBMgOSOe3e78ls9Rz+liEjipX0rBhI4cJxIsnPlatXi0jVBN73fp1SkLtdsQFHsZllcw6SzVZ2UruyRAInGzaFrb5o3P8bwjoUSN/cXqukCeQKmx/L68yEPSj7wMIQ8rZrAsAaOi6oHwNusSbt2wOx+M+ZBsELEQcxKknfHgGsYXOKiTSgvnzVV5jg5LpBVTrtoIj7Wgj8SkX+yB9ixYtZIvqAuMF7fuevJILpIUAggCmHQSHl+bFffKHuF+zeo3MmjU7pjyTKyvyPvhho5ChfCgL7DzJhrzNau3nmX/OdFrHPj2YX6cka+PGjR0hqwC4ujJOpk+frvIa4x0Z6rHJlTuXFFKiGXkRJCQ8IbZnz27nlYqu94gff1QMk0rnYE83qlc4xCcYEyD8+D527FiZ8ed0VwfaQr2pA3rHNVUyBlulD3hGGrxZIeqiEdDki1QO8jzetrgHiff33387jecli5c48hGyNruWk1fJ8SZNm0l1Fo0SykGfO3++/G63xFjVHx47dgzZJAlI9bDgVLzYIdKQSNjcMtXkHadtW6KSOH45LaeWV7ZcWblQPcfxxPV13Lt3j2qi11Wpmw7SW+WHYg3YXTv1YC5ZspSzX/IDP3Ci35GS2bB+vazXD96/PiBtA8Fe1NX7kBY5to+8xywdK8xxq1evUtmIOKdnfeaZZ7oFmt1KODO/+rECcbp8xXJ5/tlnffbJXqkvtnmB7lCAeqVv+cxTL/M//vhDVmkfMZaRzsGjH6kXxhHtIu2uXTudrV9z7bXy2KOPJFsOeKDBf8YZZ4QXEBmH2NWvqpU/efIk1XvepDr3u109cufOE1p80t0DEM/YAR/Khdhn0SM5AjpaJbBz5hACixu0mb85yDFtU91mNManqlSGJ/7r1z/dEevx8fFON9rjwmLAD8OHy+zZs9yii59nIP9Pq3uaSm+cESbpqStz9Zm6uMqiCGOR+BYMAUPAEDAEDAFDwBAwBAwBQ8AQMARiR8AI6NixOmFj4p2KtELhwoWcp5pvaDYlLafoAVufqdfyoIEDZd3aNf6Ru9Y5Tb2WO3VR0uciRzJAaEAu5NKty926d3fyAQcPhDw/gwnnzpkrb77xhuqUvuKIOZ4hoYBm8GWXXa7k5EzVvj10UBX6uw+plEEhJfa81yVEECQDJNs7usX+WAU8XE8udLLzzIPcIPyth2C9p1vL++kHUjoYIBg7qYZyi5aXOl1cMCNwPUWfVapUWUmVoQ7HYLpYv7/91luSV0kadL8hlfAAhcCEuINoJGTNllX6q8YsZCjEdDgop8KhlRAuPnCYHR6VkEd4MRJoJ8TPb3og2PDvhzsyG91v2goZdbpKZNSvX18PwrvQHboHWUOetBF5kHOaNHFaxV8mI/fgy/ZXygsuVkB2QXxPV2JtmR6AyQGBK5avkNGjRifB2+eRnit1Rh6F+kMKQkBCRE1QApmD+zZu2qgH7K11vzlgzQf0hCHpICoJ1J9xMWbMGLWLd2XQt9/6qOEreuEc5olUAN7TpKF87JzFIbxqv/7qqyTto371FGtIfR/AGZ1lbOHPP//0t8PXi1TnmsNF8dpHEoG6eYIaUhBP0VXqNRwk2agDh81B9EL0EbABSMeffhrhPPejHTB4RZvpznP+LCXj6TfKAUPKwZMVG4ocI7SdcVWrdm1H8vqKQzSycDJEtYoHcBCdksDBgN72Gu0P2gYxTlnkXVrlO5AHek91hyPLCqaP/F5BDw0EGwJtXbR4kUxTz/21utixfsN6lQxaKUt1twKEN4Ex0vy8891iCYcv+oDdEA+N+5G6QDRBD3/cnFD3MmXLuINZWaxA5oVy6HcWJ4qpJjiLEl99+aU7PNbnl9KVRSTGILtLIOkHDx7sCF4Whwj0QavWrZ3XPEQ045/yaCdzE2MTWQu0z6MFDtFsq7r1WxO0somDvTEPI3Xys9pCZKBMDiSFvMWbHS9yygSXWroQcqnO+YN1sTJob5F5+N/8rSItcan7VrXFWaqTDqkP5mvUbqcpAe3xb64kPnMg9cWu/FgcqGMJHeo/dQ6MDJwBwAGrSP6ws4Gy+PC3p0yZstJMn//800+Ryey3IWAIGAKGgCFgCBgChoAhYAgYAoZACggYAZ0COP+VRxwieNWVV4W9xmg3xBfenc8+83SyHmrTpk4TPhCaHTt2ciQGL+qQKHi/csWbMzJAjEI4NDu3mbRUIpZAOoit8847z3nrTf9jmiM2qEfHjh3dQWZ89yQqchGzlQyCRDhWAVIUQs4TUJ74GTZsmPTp3TtJtSA/1q9bJ6/26iVTp06VD/p/5OROuE9a2ub0htU7HKItPQFiNBic526CZ6y/T1kz1AOZgx9TCxCidevVk+0JpCN1pZ6Q1z0e6O7aEcwDcujXiRPc5+eff5LnXnhR6urBY5CHPKPvObQML9FYCWjy90QgNvDXwoVKoPcXDmrzZGiwDofzu7c3PCbxtv/hh+Hyqi6csBsgWihRooQj3pEe8IQ92/rHq7RB927dlLheGC2Z8+DkEM01qgF+n8YrV7acI70pn3H02OOPy/fff5+IQEV+o0yZMrrLILSwQMbgM2PGn/LCc88lW8fvVVd6rEpS9H3vfWl+7nkuDWmxC0hUDiB95+3e4bHGs0vU6/TSyy4Lk+rc27R5kzzU48HwQYnYBuM4GCDNOXTu88+/UM/Suo4AJA4ewdhBEyU8f1SP0mDgoEc8bHdsP+RBzPNt27bKY4896g7t5HdkedjF/ffdq57y5dzODP8cDAuqBzserEhMxBogVskD0hovfxYPPlHiO7lwpe4SACPf7z7eWl2469unj3z44QeuT/19rosXLXbyQSzwvav9gWcyZRIgoU8ueLIuSnSQJ3v2dPdS+wdsaS8k/TOqt42mfDCwaPfp//2fjPzlF/lUFxarV6/hxiVxsKN8uiDRrPm58l0UDX8IfuZs5jy/uIJtQsberYtc63W3R7RAmc8+/bRbKLpVPZ4ZI2AKvhwg+Kj2KQcg+rEWLQ9/jzmEwHzC3ycWPz54v596eUeX9MFjml0zW5WQB1XwWb1mjXS97VaXT7R/sFc+3wwc5OyQsgikxWab698oI6CjIWf3DAFDwBAwBAwBQ8AQMAQMAUPAEEgegUzJP7In/xUEeEFHNoEACcUHj9k3X389JiIUIhOdUsgvAi/qaI3i0ZtcgMDoqrrC6D0TP0i6NGnaVLVm73ZJ8QLsrtqb6Nd6ggLSY50SK8NV4uI39cA8VqGGeu/lVE9LT4pkicviPEd//CGpFyB1pJ0+TP9juvxPiSBIGDxC2cqPlySEalgWw0f+F1ewSuCzEuXiSZVENyN+oNNaXPFHW9cHbAOP4/Z6CBgkekoBu+ioMga0i3r4QD8WUKkOvC3TErAv7OU2lYl4S+UUjjT57OtGucgnsNhxZ9euyRK7xMeL9cabbnZ96tNDtj3x+GPJks8+HtfP9HA+yEgWWPyY4MrBdnEBDInLjoGgZzj3qOv3w4arB+xWfiYbtm/bLl9+9rnMUQkC7BePWaQ0OAhUlRoSBeQ6WISANPZjFbuFyAxK3wTtO5gBntFDhw11Y8PbAQsKkN0t1fs1MiC3UkMPxkOD281HCfPKkCFDtL6zw9GTK496YSfexmlfDp3PypcPzXHhDGL4Qn3x7r/zjq4pks/MT6efcbrOo+XdmCZr+o2y39B5NBr5HCx+3ty5wq4ESFWPEeMEghY5iFgDZeKljWxHJPkczAMP97FjxjopEV8edWXXi/9bEIzP96Yqp8IZAUGCfYfOXd27358s+RzMg0W50aNHucNO8YKm/+hfZEH8345g/OS+Z9LdHWiov/TSi248Jkc+k56DFsPjSMvCbmforgBsOaVAmnvvuduNiX3797nxAWYrVix3EiMppbVnhoAhYAgYAoaAIWAIGAKGgCFgCBgCSRE4xAolfWZ30oGAf9lNR9JEBGV60v+bNEhgeA1Z2pBFvb7+RD82QUYgpbxnqv7y/AULdMt48bCnKsQC0gAQKj7fyDwgoe679x7p805fKVSokEsLQVC8eAnBC3KMasTedMutkkXz8gFuDLIHz8peL7/kbx+Ta4BPDpWv/DJkTu7cOVOtz2b1Hu31ysvugD+IWiQTOJgvLRIBqRbyLyOg/RyvHra+TvQpXployqJ/G0vAa3W6Ej7F1esxl3pOopdLHxfRrfQd1Lt69KhRsWTj4uCF3PX22xwhGHOiwxAxe/Yc8pYenPjKyy+nmhtyLHgmewkAiLWPPx6QIhkYmemsmbOcdzrkMlgRIOtKqtwGXtgQhaF76rV6aE0j4d4/zv6yqN54amHgwG+ldJl4qau67D8M/169SX9SLe1DUiI+PfI8aOl6XV3mByQN8Mr1dfFxk7tyuCi673hs0ybaA0FcTA/qiwxxWeOcHjm2Rv7YHXMFUhRB8jMynf9NvGv0MD7ww3YpCwK6dHy8jxLTlXI3KnlOvyP3klK44PwLpLLK53BwYDAgZfGReusnNwcG437Yr5/uCGmZCCNkKpBGiiXQL3yeeqJnTPbGIk6t2rUEKRbwBSfKY/dKtFBIbRtpE2ybckjz0Uf9w4dpRksTeY8dM40aneWkbbxta2ZSSmVnFunuDb+bJDJd8HeOnDnkueeeTXLQbTBOou/aLgLtI6C3T/1TCsRdorschuu4QNP9V5VNwVOfAy0tGAKGgCFgCBgChoAhYAgYAoaAIWAIpB0BI6DTjlmyKU5RMqWybqHmxTwtAaIDaQYO18Ib9miHX3Q7dgmte5DL4vXcE06p1Yd6r9Vtzd6LjZd3XvArVqykJNPwZMkXPPwgIIertABb1yHuuMdhaxyI9vqbb0rJBDLEkwd4HA9Tb8pvvv0mtWod8eeT1DMSgpX+I0B2IWeCB+wwlTlILeBJ3KljB7f1HZuJlcxLLd/D9Rw5ADww9yeQoBCGS/Tgt8dTOKQsWtkvKFlUTrVuz1BtaGyKdtKPaCXHGtC0HjdurPNIjDXN4YhHm2fPnum8JlPLr5hqJ7NFPzj+GQeDB30n63R8xxqWLVvqyC90l8MknSauU+c0WaCHyvlFoZUrV6gH8oywxyz5Uzb2N+LHETGRkG+/1VvHbYjgZexFC8gYQDz6cU0ZHEyaGokXmdeOHTtde0hHXlmyxElhXYiIDJDV6AkzBzEnuavGh5BOro7BPMjbLZokkIzYW7ZsWXWBLCnZHUwX+R0yFimSueqdnFoodWopQave1485gbn88/995uRVUkvvn29Yv8H1IbIteKWvVK/06dOT6nj7+MEr7aRfWAz09Qg+j/yOh/S2rduEhR0CuGHvRYokxSk+Pt4R+N62fR8O/PqbNO1EWLhwgfNOZ570CxH83airOwdW6N+R1Ih6ygWXieMnuF0jkW2K/L1//4HwIZG0jz5tcGZDnXuqytQpKe/gIK+nn3wSV3aHZ3AnSGQ59tsQMAQMAUPAEDAEDAFDwBAwBAwBQyBlBIyAThmfmJ8WVQK3yzXXqLbtjTETt8HMkbzodu+9MmjQwODto/KdF2tPasVSYH7VU62k5HLp+NJSomRJKatejTVq1ExEHkAUcMCW396dXL6QAj0efEAqK9nGVnOIE4iUHHqQYenS8Y7cJQ7BeSTq4V1DBg+RKXrw1LEOHIS3V8nZSOIdT89fRo12HtyQ5cnpOdOu3UrIHq8hu3osczie1/GmF7Zt3+YO4EtLnZcqab1x46ZEhCWkF4eTxRogSSElkYg4moE6DtXFBDRhUwvMAXjZepLOx1+qhDJ2za6C1AJk//p1651cRdCuSFetalWHmR+rELLYIBrsEjoX0JGIyAu8+/77MnnyZPlRNatH6OF3yXms79uHFm/KteJQUWxhj5bHuIY4pFzfnpMSFmBSyoV2YesQjIxjxjjt4xDEyAB57AjkyAfJ/EbKg8WM+PgyUrJkCfVYLeQOOfQHljriMS6rkzFJJouot6njSNWM3qhe56mFInq4Hm0hDYE20j+ff64EdGoABzJHU/sZ1UuGdUeTGbtJjZQlOf1C3IWqg+3HayDbZL8iZeHrDE7M1wWVSI8MpdT7nsMpKcMH0i1ZusT99Lbgn0W7gsOqv1e5xdYw6a0Rwap69epOBzq1tmIz6D6z+BJLcDaXYLe0j08O3dHwwYcfucMKWagZMvi7RIcqBvNNrT7BuPbdEDAEDAFDwBAwBAwBQ8AQMAQMAUMgeQSMgE4emzQ94QWcF3e2L8eyTTwy8wIF8jsPusj7x/I3XmpnNW4sFdSrE684CJas2s7sObJL7ly53bZ2CLrs2bOph2H2RMQbhAj3uKYWIGp6PvaYvKCanmjN4pVHOogtCAMf8MZ9Vr1pv/nma3/rmF8nT5rsDozDexvikfpCAKKbC2HTtFkzJV83KPm2W7aqt/Qa9RTn4LEpUybLn3qQ3/EcIH19cASXtm+nerGmJ+D5DD7kA0ZYBcQThFckYRstf9IgVZIWYjJaPmm9hw2iYc0hZqkFZGSQofGEHvEh7N7u806YeE0tD9rJGMN2IncgxJeJd/IzwTyQuJk8eYpU0APiPI6Uz0Fv+XW8YIcsjG1VTejdurMArXHI43lz5znZjSChGMw3+B1JDOoEmcdoxEu2QYMG8tXXXyeMz9THOHrOZcuW0/hKrCaQtNgCHqmxhtIq09BYpXkqqdRFkaJFJE/uPE5OAUkexh+LeMxHjD8OyvN4kD9lpbYYFlmPTSo1EavOON7PePWjfe/LY2Fv7pw54fZG5h/tN57yafGWP5RHSG+axZ5Y+tSnQ9+Y+OBD4OoXPnwcrkWVYC9c+JRw3vQheA74+BPXPp8+mCbye2huROLj1EMLb2oQzAOxLFaSH3Wb9PvvToomMv9ov38YPlxq16kj559/fqK+5O80f69r1qzlDrllYY3xhsTNihUrdXzMUfmN4YkO+KSNtMGCIWAIGAKGgCFgCBgChoAhYAgYAoZA2hEwAjrtmEVPoS+m+/VFfu/efc5DMHqk5O+SLrThPPk4R+MJHs0tW14qpyrZU758OeeFDLGGlyHEDmQBL+EQEKEPXmWh7//m5fy3336VTz/9VImkvFpm6fD2bN9myI5vlPAa/N13SoLu8LeP+RUdVWQXLlSdXLbcQ3p5bNAO5aA4SBPuQQBy+BvSG3/rIWkLdKs82+CHDhkss5RcJRwvJEe8erWzgEC9fcB9xAUAAEAASURBVL3wfGX7e3rCdiV4dqv3Kx7V2Akf+pRFDnBIzXZ2aVrv0Zqe8tOThr6A8MbzN5ZQQHcGICnhMSMN7WrYsGF43KSaDySXYg7WfILEHgQr4y8YZuuhfK+92kvefe99F5c0BOrNeC2j/YgWslqW5rfX2Sh9CBHdqlUrtyAySXcT/KxepXhWR9of5bHYFO4fbQ/38PY+Vb1iYw3kizdpJCmcGnXN3NPmyqucnVAedllYDzc90vMR7UIPO1YyN7eSz+DtbQWacp/+PYg1faw4JhdP4XV299dfC9NUJrYa1F12/ax9HBkKKeYchBm0bezg7LPP1qj0YtI0kXmocbmysE3sILFt50r0O0nahBvMpVOmTHGHJyYXJ3ifvyvfDxsm9XRhEykZL3Hlx0d8fLz+nSvvkjB2eB4aH+vk8stbyfoN651UxzDV6Pdpg/nbd0PAEDAEDAFDwBAwBAwBQ8AQMAQMgdgQMAI6NpxSjYWnZPbs2SWvHkAX9BxNNWFChOzqZYhn4bEMp6l0xPXX3yBNmjZ12svQCryUQ6JAPOCpDGnAB/IBMiAuLrP7DrnEJ0gqpLUtED6QYOQdGcDmyy8+dzqhkc+O5W8kIXq98oojxZs2baZe7AWcJx0Ei//4+oENXuQQlZDW5zZv7jzuatSs4XSwBw0cGJUE9OmP5rWketDinRomHrVwtutzqFp6wg5Nt3fvHolTOQcC+YIHXqNcg+VEy99JlWi8ox2w6QMHQiR8amXn0kUavI6DJB1pyCM9gfEVDJkzZ1Gq7xAG4AYugwcNkmfjy0jbq6+W8ko2M14Zt9QDoo0PgfiQpMWKFVOpipIqeXO6qxuLH3hKDxk82MkSBMssV668a1MkkYptR7YzmC6578GxzXcvxRAtfjWVZbhFDyFtdm5zJ61B/VObj7JkUa96nStYpHLSF5rmUIiBJE2ITFmbNm2UWHV/8RBncWV3AnkLqZsW6Y1DdUzfN+pLfyxeEpJ7SV8uyafKly+vLg7mTtLn/E1IT/C2Tb2xg7R4p69dszZNRSKDhId8myuvlNq16+jfsdBujNTHxxlu0WyeaoDXqFFDPv2//5N581LXA09T5SyyIWAIGAKGgCFgCBgChoAhYAgYAv8RBIyAPkwdvUOJ08nqSfh/n/4vXYQTRByeoMciQO4ifXHHnXfJpZde6ojmXeoJBikIOcBziCJIKDz88ASDKN6sW9Q5PJFrRT2wrqpq1EIQpSdkV13ORmc1dt7PkFuRgbJr6yFsY0aPUdJ2PWwaLGZktKP+GwJlvB6Ot2H9Oqe/Wqt2LSlbrpyTLHEaxxBDWnfqD56QHnz3pCBxWrVqrR569R123ymZmF5S53A2fo+SliFS+BCBl0nbAsmWnpA5ky5U6EGCPnjCDImD1Mhnnju8jnJ/U0dPePp6p3SlfaSJDOyMiMlDNDJhwm9POiO3ERxf4EJ5SAe8+Pxzsk696fG2Rk8diYG86vFJf3mb40oa8uDjF5QgnzlwErt95KGHEunr+rEfWTXmhX/TLt+mqF6lCuFpp9V181H7Dh2c/AltpO5+PoLAZBzRhuB8hF7z33pwX2P1zIVoJ056w/btO8IH2KWWBzNRcDaiX6LZQmr5/Kvnig+HotLPhztwCCiLrJHh39gAeTFmmO9XrVoVU71174T+LUpaj8h6+d/0AYuEvd96S5aoPMklLS5Rj+cKbnwg6RTL+OAwUDTGsaeXXnzhmP2d9m2yqyFgCBgChoAhYAgYAoaAIWAIGAIZEQEjoA9Tr23Uw/H+pxISfDJaqFS5snR/4AHVybwgkU4m5NN29SRcvHix89RF23qzykegUbpKSZ5FixfJn3/+qYd0bZQHe/Rw25zTK9FwlXpvNlePYLZJewIW8gDSiQABee9996l+8iL5eMBH/4pYOpz940nAueol90TPx6W4eg5fccUVUkfJcnRhc6hXfL78+Zy0SC5dZOAwN3D1pCAEGSQs5MbtXe+Q1atWy5gxow9nFdOV119//eX6IVOmEKFKO/GIzp8vf7ryy6vp2CGQiByDMFO971gCB6t5W4gl/uGKgxfrwYOxkZiMj61bt0ohlV7xAcL0x+HfO5I0JW9fHz/a1VPa3w/7XvNPLIESxOTDD/oJnxa6iHSOaiWfemppweZy5crpvJhzqZRGDpXxyK5e0ARsj/QQuNhkkyZN5M677pIHut8frsZffy10Y/5Q3XVBRSV31q9dI7/++muoP3WcpjX4FBCPkQFd3gce7KESCJcnOgCQOoLxEp2PNqp3MuNmy+YtOh+tVUkb5qPFqt07Vw/JXCj/+/wLt5gVqaMdWVZKv0mbyF5TiAyJCp60ixmLucsdDplCmsP+SMvE3rTww571NrVrFh3z6/xMoH20d9j3w/SKnEbspHCwcixqcZDr0O8Gh+f94PPI70F7j3wW7bePv0flj775+iv3QWIKLfH4+HinGY6cC393uCJzwy4B2kefkp6/Ryx4tNJ5ncXW7vd3i1aU3TMEDAFDwBAwBAwBQ8AQMAQMAUPAEEgBASOgUwDnv/AIQqqJSke0aNHSkcy+zRAZa5VoHj9unGoz/5+M/Pln/yjJ9bS69QQSO+idmSRSCjdKqrfmzbfc4nRePWHEiz/kDy/+nkRAbuDue+5REmCTDPz22xRyPLqPfP0oFW3nN994I1wBSLMG6pVaV+VNKurhaaWV9EAXOp9KcSDH4Qku2k286rrV+3ggoPEkRXMZIoZAG+OUgM6TN0+4bWn5ArEDge3lKBzBowTWWiUyYwmQXcciOJI24WC51MpHsgEv5CKqA+3ri/1279bNaS2nlv5wPR+iOul8fIBoa3TWWYKkRZmy5Zz8RgH1/kQuBOkD+paxi8f0hRddJD0ffyx8ACL9xeGZ3g5YkNi7e5/8rgfB3Xj99b6Iw3rt1LmLtFQSnUW9YOAAT3aZfPzxAPlZ56OgdnEwHt/RZHZkbKIHIVtOdCuFHxzQFxzbKUR1JCWEpQLFYHFR8frnoLvIdqSUD2OERQPqDvHJx9tSSumO9LP169e5xYCTtT3UxxO0t+u87XdzHOk6kL875DEB3/SWN3jwd8LHB8YEOweqqZdzOdWD5hwEiHY0/L3d0+acSkyzW4C4EydO9MntaggYAoaAIWAIGAKGgCFgCBgChoAhEAMCRkDHANKJHOWMMxqox24b57np28lLN8TL9ddeIxMnTPC3k72WKRMvxYsXU4+xxCShf3lPNqE+IE6/D/s78tl7PkO+4EmKd2Q5lQXwRBIED78vvewymT9vnnAA27EM1Itt6Xjx+bZCVAQJI4i9sWPGuI+vaz71Br7uhhvk/vvvD6fjGfImVapWUZKwrPP09vGP1fWAerqy5d2HzNrWbOrFnJ6QLXvWRIsJ2Fdo+356cjt6aXy/xlIiB/v9/fdKR1L5+LSzabNmgrRKVLkJHzHiSrmQ1wRHbEY85ydxnA0mXLnHggb2FyROkR7gEwxnn9NEej7xhNO29fkjFZNVtejRgP9h+PDw4sj+fapnrnZMeeTLokpZ1YaGvPZpg3mn9J02UWfSBevo01RXkjxeCfPgYhblQoTfcMP1MnH8eB812SuLYblV8zc4Dl1kzSctIS2x0ZxmwcYT+vQDZHKTJk3lu+8GxYzT6WecIdded50u9OSV8WPHyujRo2WG7jJJ0pa0NOQwxF2tczGe5ki1+EA/Nj//fPlpxIg0HRBKOj70/5FsV7TxQZlB26Itixf95T6+XVxr1qwt7/V730l1+LqSjsXSho0aGQEdBMu+GwKGgCFgCBgChoAhYAgYAoaAIRADAunbNxtDxhYlYyDAoXklShYPk03UGhLljddfl4UxalLj1Vu8REklExJrN2dVjzFIgOQC5Tz8yKNSQcks/5JPXPSgp0yeLB3at5NxSsIEA1vwWyth3k61YY91aHjmmapTe6f06fuu/DxqtHyr28ivuurqVKu1Zctm+fij/tKnTx8X12MEGRMfX0alE05NNY+jEQFplT27D3lBQxoWKXyK3HTTTWkqvlOXLlK+XIUw8UN7IXPwsj6RAhrNS/UQOE8c0zaIyKvbtpNT1Os9LaGGelo+/dxzcr9K43j7iEyP3MtVbdvKMxrvi6++lnETf5Vnn3/Bed1Gxo38PWb0KOn18ssyc8ZMJ43Cc8i5rFmzqXxMHTcefRrGHItD1IM4jNsSJYpLfj1MM63htttvl5de6SVVqlSNmtRr7frD/ygTD9uxOg/8MW1a1DSRNyH88V4NkpssFMVpvY9UWLhwgXrzrw33Pf2O1/+tXW93hH2s5bIYeG7z86Sx6uF3u7+7fD/8Bxk1JvEcGGtehzPesuXLncwJfU/ADpizO3ToKHlUuiItgXnzhZdekttu75qWZGmOe2rp0u7gwWefe16+/Pobh2Pfd9+LKZ+ZM/+U1pdf5nYu+DbTpxxmWKx48ZjysEiGgCFgCBgChoAhYAgYAoaAIWAIGAKHEDAC+hAW/8lv2bNlV+3LPI5Q8ABAoP3226+yIWILvH8evJbU7cqnqd6x35odfJZT9Y6TI88oA5Ktc+fOklM1anm5J3Ao34wZf8rnn38my5ctc3qbaIT6fLwH29VXt3UETbC8o/WdunDo4osvvSx33323nHfeec4z+/T69eWcJk1iqgbYDhs6JFFcMMiXLyTNkejBMfoxftxYgVT1BAyEXkEl9jpon6UltGlzpZN98J6H9D1aqiNH/pKWbI77uBx2Nk898/F89YE+bdy4sVSvXiMRqeufJ3c9vf7pcsP1N6jX743ym8pOvPd+PylfoUI4D/RqO3bsJC+//IpcdeVVTn+9lI7FK6+80mnYJpdv8P7IUSNl8ZJFYYLUk4qFVUJEB1w4KrsRIKH9GKRNkKu9337bXcMRU/ly3XXXS5cu10ibNm3ksy++kK+/+VYXk1onSlVYFzggNP18QJmQ0QsWzHfXRJGT+dFG8ShStGgir2Py8XacTLJ/dftrXQCAIEfnnACW2HmlipWkgvabxy61Qk4tfaogj0J87AjZG49FammP5PNFqgmPFz3e7wRvK03VW75y5apa39j/UwJ9cuzgLp07J/72m7zx5ltO9iJWjGJtZ4+HHnaLHVdedZWTQKIf6px2WkwLJ2C+UuWUdunCiw+0mT7JnTOXv2VXQ8AQMAQMAUPAEDAEDAFDwBAwBAyBGBGI/a0xxgwtWsZCgK3tO3ZsT0SQ8PKNFnEsnm03qQYo+rKeXAy3XgkUyORIUsH/Ruf0lVdf0wP6Dh1qh0cdnpajR40KazwvUxK6x4MPOC9ITyAhB4CHY4uWLaS5kr9HO0BELFUyJqe2IW/efI50QoYDwql2ndpyScuWqVYpmxIZtdXTNBjAZs+evbqdfW/w9jH7/tGAAbJIt6fjkU6g3dSxtB5ud596Z8YSbu/aVQmqyo44JT0BEgdv0ffei80bMZZyjpc4tGuTHtTp7dzX65FHH5XTTz/D/0zyPPxAv7RWEvn2O+5wmOFxidzFBRde6A4JhXgmcCDctu3b3IJALr3H2KBMpBsYkxyqRoish7uZ8E/lKpXlFCV8gzIa9NGunbvo7HDUIUMGuwWpnAnEG3HQN27U6Czh8NCUyvCZ1K5dxx3iFl+mjOv/4upFyrxx622JvWA3bFjvDj5lLvAhs7YtPr5M0jnGRwhcH338cSmrZUCfe3tDRYbxmSVLSNIkEP2wfUXLfJUu1hxCLZQ1hO3z6u17cqFCqZbV88mnVBKlppvrqDu4btGFmqlTp6aa9mhEoI1bdDEi2N+079nnn5OKFSuEqxB8Hr6Z8OXGm2+RDrpwQv+igV9RCXp0x889t3nMCyeReSb3e+fOHa7PGUOMDzDl78YLL76YXJIk9/GaD7bngP5tDI6XJAnshiFgCBgChoAhYAgYAoaAIWAIGAKGQFQEDr3lR31sN090BDapJ+7K5SvCnpW0lxfsa6651nkoJ9f+ouph+PCjj6k345VuW3LwpdyRJ5owmgQHz/CiffChh6R2rVrOu497fCDNvtPD0/q+0ydMHnF/4DffOC1UyGlIXgLlQV7ccOONjshwN4/iPxD3kydPCmtnU8+9e1UjtGQp5xV98SWXpFib0/RQQg5eJJCWkC1bNpk6ZbL88UdsUgMu0RH8Z7uSTbNmzlJCdWMYdxYnkGm49tprnQc45Ge0AOHzxFNPy4033ezsw8sh0H/btm2TWbNmykbVTD7RAv337rt99SC5Q7iwOIP35dPPPqt43ORIMN/nwfYXLVbUEc/33ddNkA/AxsCNBRc8YbE3PJF9wCt1zpzZjiAjPz7Ebdeuvdxx111unEUrh/QsAOGRXL1mDbfowT36hjGGXnXQ63b2rFlKQP+mhxFuSTRPsJBw2223yyu9XlXZmNJkETXggfp4z55OG5t8aRP1oi3jxo5JlObP6X+6gzz9YhPxITnru90FTRPFDf7IqzsHnn7mWWnfvoNb+PL2Rhx0zCERIbKPZEDWZNLvv4W9wj32dfWQ1t5v9xH0naMF2nrX3feoVEtbnQPzhwlO5oM1Svp+8vHH0ZId9Xsc/Pi/Tz9149kXzjzM4ZavvPqqI5ZZIPHt9nG4llZ77qZyMrfceqvwt8PbNv2UWRcGwO1wH2Y4aOBAmaH2hP1QJ8ri+wUXXKj2+IQbA8E6Rn7vpQukhXThwP9tY3xwyOhsHXMWDAFDwBAwBAwBQ8AQMAQMAUPAEDAE0obAkX0jT1tdLPYxQGDp0iUyXQ+5qqdb/r0XM6QPh/3deeddTg92oRJdWzZvccROnjy5hS36tWvXlssvb+VIU0gvPNp4yQ+SD7l0mz7aq8GQNVtW9eQ8Xzp16pyIcMBbeop6+n3+2WeC13MwcHjbKy+/5Eg8iDyIBOoIAcYhinffe688qQTX0Q4fvv++1K9XXwqoFi51/EcP7aNOeDF263a/I2aWLFmspMU62bplqyM/0AKuUKG8NGx4piPQd2k6HzIpwTF//nynO+rvHevrxx8PUOmH8tKy5WVKHG911VEuz5FInVXbGVIPG6J9u3btUhvJ7hYSihYtJmg/Z1OyGm1wbxdO33vKFHmnz9vHumlHpHwOzhw86DtHhOLhiZ0SINfOaNBATjmlsLOP+Sopgafxdt19kENlG/DSrFylivMELaI2AhFMgPQijwEf9ZdpOj6CxCq/h+iCzYM9HpINCXra4Fy4cGFHQhfTPoC0RkZl48ZNWoc9zlbRGEcS5Lzzztdy84YPkIOkpQ+R3/H95Sqh/wwdMkTQZ+7UqZObC7hPXSpUrCilNL+8ung0c8YMl367emaTnt0Bp+hcceFFF6rNV3RZMccwV/BZtmyp2kEfd9//M3v2LFmrh91x2OUO9fJW5tiRx7Tp3vvuUymF05R0nyPbdRED2wNjCM1KlasIsjxxcVlcvSB1wc3jT9uyZD6yf+5G/vKLwxVsaZ8v+x+txyW6IEXdJqu2PfMBizDMF+hoQ85eoQt5+RVD7hH8YsDcOXNVD3+Sh+eYXpcsXizfDxum8/7l7m+Bb98+te0mTZtpXxdRiYs6sljjMa/t0A8yTNgBh0ueq7tV8ul37JAAGcy82f/DD12fHu7GjdadNCyQnqUSOPS/t2n+1nDQY/78arO6wLZ69SrhANF9uoCYv0B+1Tcv4ebm9nrOAOloJ2nZAfDXXwvdAs3hrqvlZwgYAoaAIWAIGAKGgCFgCBgChsCJjsCRfSM/0dE7Adq3ZOlSQesXLdascYf0Rtnif9HFF8tZZzfWl+6/ZP26DeoxllNf2vMr4VNMiaz8jjyAUILsQSsTIhptWF7WeXHnZZ6t78FQR/Wir1XPSwg3yC4CccnnE5V8mDhxQjB6+Dv6qv37fyhdVZqgRPESjqAjDR531157nYwdM0YggI5mmDBhgnzz9VfSWb3FCxYsqAf27XbkF+1BXuN0Jcc5nOzvv/92sgyQ06VOLSVl4uMlh5IZO7ZBsIVqjEcqbZil3qbHS6Ad81XTGA9MZCCqKkGKXRA8kXiLenHzHQIUj1b6n23ueL9DEu7fvy/cHLyC0Rz+v08+ETxdyd+TQuFIJ8CXhQsXqrzIu9JDiWG8J70HJR7lxdV2Ib8gb9HBRl8ZzLCfLErIYUNB8hk4pqntv6mHgvp8PERr1qxR+/tapSwaS9169RzpxzO8SyF+u6iX+qV6kFpo/K53eSMFwSIOhC7xKI9+wDa3bNkigwcPitonHEj69ZdfSjM94A/ZDohDAnWFbL1apTjw4CWPrfqhXyFX0TNmnGMj3CMu5PISlbD5qH//qIstU6dMlcXnLnJtoI6k43O2agc3UBJ//vx5Op42O0K3QIGCegBqCTcv7VT7A1cIRvR70WNmXJGWgJwCXsXkeSQC+eI9zkICXt+7td2evIRwRmbivPMvcBix84R6sRsEjMDT9y/9gS38rl7nAxSj4ylM/+MP+eSTj+Wuu+52fe/rvG3rFrdoWaVqVdfXm1WGhsWVXDrP0cbM2u/YCuQzvZFV20dfTZw4Ufr07n3Emjho0EDXH3ifYx8E+oQxd/Mtt6oU0DpZvmKZrFm1WvYokc74YH4uVaqUWyTwJDt2s04XRiaMHy9ovVswBAwBQ8AQMAQMAUPAEDAEDAFDwBBIGwJGQKcNrxMu9kElAcaPGydf6aFgHTt3cQQRpAIkCGQjWq9Vq1SVTNVCHs68kEMc8AwyCaIRT8xNSqZBbEEI85yA5xtebj4ULVZMD0m7SjiECp1cH3i5R3pj+PDvwySBfxa8vqOHnlWqVMl5OkJ6Uw4fCK3nVdeznZJgyBIciaB+mFGzfbVXLy0/h+AtBzm/V0koMHLknn7Hmw6PU7CCcKK++/cfSPDuVG1avY+8wgolNV577VVHOkUt6Bjc9MTdDz/84A6qvK9bNyWiywk2Qxv5QKBiKywo4I1KGtruSVSqjTcnn7/Ue/Dtt3vLF1987lrj84/etEi8I39HT/Vv79KWJCHKrSRxAjc2b94kb7/1lkrM1HaHnrGN3+MFEcuHcnLkyBkmSPGQ9sQozxg33MNjto9ihn1EC3/q7oXHH3vUHbZWUccf5YRsbL9s075hUalGgkcu+fKc8c1iAcGNYbW/3Xt2y88//yS99FDD5MIMLQuysK1KfJQtW9aV49vFfABMkLyQ2wSeQUj7wJhlRwSetO+//57zfPXPgtfBOhfEx8c7iRqIcS/NgFctbaii8xFXgm8vix2+LbNnz3akPd64FdXz2pPfzBMcQvfbr0k9vIPlp/c7dYIcf/mlFwUv9jq6CEWZHKKIrXvSHozw2iZQf8aQD2DEWJmrXt7vvfuujNKDIsk3yVhJaL9Pd9iu5JtC3ngLY9tVlWjGrgrowgn2pM1z/URfUV/+DjAnuPlAiWdff56hfw8WEyaMd7aN93HUkHJVoiYJ3sRCfhoxwhHeTz/zjP7tqOz6wv/dwDbZscHft+rVqrt60x+0x9st9fU2OEgXFwYPHhwswr4bAoaAIWAIGAKGgCFgCBgChoAhYAjEiEBifYQYE1m0EwcBXrDxFnxW9WknTZrkPFm5BwniSVMIHMgxyAVe3gk8g2TE2/OhHg9K/w/6OfLJEyhc8XLD+80HdKXRwHXEdgIpSTwObnuy5+OyeNEiHzXZ6ycqCTFRPY8hvklLPSB0yquHLnq0eN/+20DbfTv4DmnmCZTIvPFs7KXyIP0//MB5OuPtSRqPH3iBG1iBIeSGwht+DhGIh+ozTz8tbBmHADmcwfdlsD2uTWkoBM/2zz/7n0qy3CHz5s5xhBlejL6NZOWJQF9/+sWVo42FHFy48C95UA+TfK9v37DkQ3JVCOETSu/rzb0jH05y9kS9+VA2+KUnYOPt27V13t70L2MIyYggZsgtYB8hzA6VzW8WaEaOHOnI5WFDhyZbBeLildm9232qTTtHpTZCnrXBcvz4DXmg7nW2TP/QPspft26dDBo4yJHPQTI0slDkRXq98oora5ZKZUAi+n5GPsaPE/Lkw5jxz8GRsbJAPalfeP556f3mm5HZh39z2N3XurNg2LChrj3ehsmLQHsYU3wYT4RMmUPz0aLFi+R+xWLEjz84O4M89FjgDX3mmWe6OrlEgX88Hr7ffZq09L6fIyCPO3fsoOTxKFmrXupgEc5PcSBeNIyoA17xEOgv6MF+X3/1pauhzzdQXbcIhGn68UH+fMhXCwhGTfE7C4zeLn0eqZk8OzpaqwzHV+oRv1R30Bw4GGqfbyMFYpfUhSv95+1gv97DRunbx/XAyFFq48kF1wxNG6xfJq2vm0CTSxS471H4WUno+1W+hd0c7NQAz2BdkxsfHk92GiBB80G/frJAJZLSOycEqmZfDQFDwBAwBAwBQ8AQMAQMAUPAEPjPIWAe0P+5Lk/cYE9ucLjSJRde4A6N43A8JAEgDfgEX7g9sbB79y4ZN268I8j+VgL7fD3Y6W8lqCB5QrILIRKb7fF/Tp/utkHjvQzhyidEcoSIiccffdTp1CauWfRfUyZPkaFDhzjtWbzsDir54YKyDa3btHEetl4PN3oOKd+lfZBwkBLknS1bdtm4YaOS5iGP0WipKe8JJVM4oOuee+6VZs2bO/I9Gn7gTRmQj2ikjvhxhPR4oHtYjiRa/v/mHgQdxN8WJbYgitD82O2I8ATc0pD5r0r8n686rnfffbdcpvrfkP0QYLST4O3EtxECCiIVAvWNN153B3jFUtyOHTtlnXpFHlD5Dkgo8FqlnpeOXIslg3TGASsWQ7zXPu3iEDj6Kb3h6aeedDItPZ96Sk5T+RlvE/4KZh4vf4WwRhf30//7xLU9tbLBB/mWxmc2lNtu7+q88YsXLx4oCxqVPgpJWfhycFmeM3uOvNrrFflRvdxjDRCrTVT24031hkYWA2keiEFP6vk2+XKoH3bAoXD9+r0vK5YvT7UoJHduvflmuaxVK7m/+wNSUHcXQHJH2hp5H2Qs6ZyCZMWD3bs7WY+6esjnBh23jGXmKupHnOQOzdyze0+CJAoe2yHaGYKd/NMTaG/H9u1U2qiN3KCLbuXLlXPyH2Dj20C+YOSJWsrro7s8WGTzHrjJlc2ctGbNWm3fFjd30D7GOfabljpTJnMD8x11Y+5eqwsSsYQeuvD4pZLkTz/7nFQoXz7c/94OyCNoA9Rr7ty5Tvf7O5XGSC0gmbFa/6agI42OPOGkkzI5L+bU0kY+Hzd2rJzT+Cxpq4dU3qT9gYe6n7syZaK/Q31OOmdT2JV+Fi36S+f2njI2cFgmbbJgCBgChoAhYAgYAoaAIWAIGAKGgCGQNgR468owb1PlKlZWj9rCsmLZYlm1MvqW9LQ1/8SMjfbqM+rR3KXLNY6UgPDA+xFS6/nnnk2R7PTkyJl6SB46xhw8liMnBEDogD1eyCGU8QjDA9EZj76Qe2KFazBArvDCntxz4vo4wXQpfaeO5BdZVnryiiwnVE/15gw0w5MoqREPvj7oi9ZRAoxt3WXLlXWHjEGcoLfLAWsL5i+QmSpnMGnypASiO30kV2Tdo/0OtSfxIsK/xcnjz8FiDRs1ksqVKzvdXSQl8DjFU/Yv1b7GU32GHkwHuZUadsG6k7+3Q3+f9EeagHZY4cnrC9VrrH0fSJLkq+8D6l+yZElp0LChO/QTyRr0iiEN8SRdsniRkwxYrgSt8yZWAiytAdwgzirqYk8tlQCpWKmixMeXcYsFeOdD6v2l5SyYO8/1DwQ78dPSP75O3g5oQ7369dW7uJHOF1W1rEKOGKUdyG0g8QPxyBxESGtZaDnXqlVLda7r68Ge1Vwe+fMX0HofcLhNnjRZye1vnc14G/GYc/WBcn1/+nv+Gs3mPBHp46TnSvl8kB8655wmUrNmTSmhNsDiGV7yeHuj+z5VpVbmqYcuuyRiwSe59h3AZrSdsYZo7aZ8j2Nq+fh6EB9ZljMaYNv1nR40CzkcgLl06RK3u2X48OFuEYo06W0j9aGsWNJHqztlQ5BzcGbduvWcpFOZsmWcXBR5QuL/9ddC5y2NPjULs/vwsk8DptHKtXuGgCFgCBgChoAhYAgYAoaAIWAIpAWBU/TstVPLlJMt6ty0YO6stCQ9buPydh772+oxboYR0LF1QCE9gOzpp5+Rjh07ppmA9iXgHcZBWMhbhAgDvM9CL/8QipDPFpJHwOEHhvqB8CBAcEBq4WnrP8nncPw/gbyCcKaN2Ij/QBDxwUa4WjiEABhBzKH7nQWyW39jE+CEPAEa4ukl1w6VEpLI8TboPVLJl48rS23wcI5hyvK2gF34cg6XHdCGONWzjosLbdoBNwL5Z5T5CK17Px9QfzCi7yE49+lY4XtGDrQJG8C+kc2ghyDE6SN0sL3G+fHQRupKPUP9wS6OkD0dZHwkzM+Hc3wcD222OhgChoAhYAgYAoaAIWAIGAKGQMZB4EQkoE2CI+PYX8w1LaDb1dkWHyQ0IDvS8kLtCdKQz2LMRVvEBAQ8ficyINiX92o9kdt5ONvmx2FaxmJ6yqdvKONIl+PrdqTt3ZGYB3apvfkSM94VAvZ4ImEPN4LYdkZp49Eah4cbY8vPEDAEDAFDwBAwBAwBQ8AQMAQMgYyKgB1CmFF7LoV6lypVSgoXKuw8z3y0f5SQWrFihd7L2F52vj12NQQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDIHjHwEjoI//PkpzDRueeaaUV31ZtqYT2G7MVugZqjvsD3NKc6aWwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMgTQiYBIcaQTseIvOYVaXtGgpWbNllX8O/iO5cueSCy+6SAoWLBje7u30RrXi8+fPS+QVfby1xepjCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAicWAkZAZ/D+LFSokPR++23Jlj27a0lmPQBs586dTpsX4pkP+qwrVX5j+/btGby1Vn1DwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQyEgIGAGdkXorSl0hmLNkySLbt21L9JT7hCxxcbJu7Vr55OMBiZ7bD0PAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBI40AkZAH2mEj0L+//zzj/N0jlbUrl27ZNq0afL+e+9Fe2z3DAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQOGII2CGERwzao5PxP1oMBHTkJ5NKcWzevFn69O4t7dtefXQqY6UYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCEQQMA8oANgZMSvq1atkssuu1QqVqgoJxc6WbYo6bxi+UqZO3eOrFm7Rvbv25cRm2V1NgQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDIETAAEjoDN4J+7ZvVsmjh8v06ZMkcyZM8uBAwdkn5LOe/bsyeAts+obAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGQEZHwAjojN6DWv/9+/fL9u3bT4CWWBMMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFD4ERCwDSgT6TetLYYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFwHCFgBPRx1BlWFUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBE4kBIyAPpF609piCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAobAcYSAEdDHUWdYVQwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDiREDAC+kTqTWuLIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgCxxECRkAfR51hVTEEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ+BEQsAI6BOpN60thoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIHEcIGAF9HHWGVcUQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDIETCQEjoE+k3rS2GAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhcBwhYAT0cdQZVhVDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAROJASMgD6RetPaYggcZgROOumkw5yjZXe4EMiZM6ecUqSI5NCrBUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEjlcEshyvFbN6GQKGwLFH4J9//pHKlStL5SpV5KB+F/6v1y1btsiECeNl/759x76SETWAmI2Li3N1jHiUoX/my5dPatWuLXn1mkvbWKxYMclfoIBs2rRJlixeLJs3b5bx48bJ/v37M3Q7rfLHDwL58ueXvXv2yK5du1ylWJBi/FswBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBNKCgBHQaUHL4hoC/0EErm7bVh597HHZs3eva/2BAwdk1qzZckHzc2Xrvi3HBSIQYxCzp5YuLXXr1lWCNpcsXrxIZsyYIX+vXCnUOSOH8hUqyHnnnSe33Ha7lCtXTjJlyiT/HDwoB/WTKVNmEXVUnzVzpjRrco5s3749IzfV6n6MEcC2SpYqJcVLlJB6Opa2bt3mxtKc2bNl/fr1x7h2VrwhYAgYAoaAIWAIGAKGgCFgCBgChkBGRMAI6IzYa1ZnQ+AoInDgwEHZuXOXfna4UiE9lf3U78ePJ2TmzJmlbdt28ljPnpI3b145qIRz9uzZZciQIfLYo484cvYoQnZYiypevIS80/ddqVOnjiOct23dmih/yHf65KDrk0SP7IchkGYEcufOLc8+97y0aNHCLXQ4r2fNpdfLL8kTOr7MAzrNkFoCQ8AQMAQMAUPAEDAEDAFDwBAwBP7zCJgG9H/eBE4cADIpCQlZYuHwIvCPI5oTk83HGwmVPUcOufueeySzem9u37ZNyfKdTpqiSZMm7v7hReTo5XbKKafI40r6Va9eXfap3ElK8hqhfjp6dbOSTkwEihcvLueff77s3r1bduzY4TzqkeG48uq2csedd52YjbZWGQKGgCFgCBgChoAhYAgYAoaAIWAIHFEEjIA+ovBa5kcTgUsvvdzJE2TJYo79RxP3Y10Wes/16tWTPHnyJKoKJHnWrFmdHEeiBxnoR1mV22h1xRXO6zRI+iOTQLv5ZInL4toZlyVOpThsASYDde9xV9UiRYvKnXff7Tzqg/bGwkfhQoWk1Kmljrs6W4UMAUPAEDAEDAFDwBAwBAwBQ8AQMASOfwSMqTv++8hqmAwCZcuXly5duqjmbz0pUqSIFNAD2d5+u7cM6N/ftEqTwexEvQ3tGtX7HUI2g5KypePj5ZprrpVMWv+ggnWuXLnkq6++lHffeUcWLVrkSGgI6Uy68LJTPVYtGALpRQA7ypEjZ5LkjC101PftswMuk4BjNwwBQ8AQMAQMAUPAEDAEDAFDwBAwBFJFwAjoVCGyCMcjAkgTtG7dWrpcc41ky5rNeYDi+Yx+KVIcFv47CCBNMVsPSDtJybPMmbPIAfXWRI4C7+f169bL/HnzMiQY+fRQxarVqiU6QDGHSo189tln0kcXWqZNnZoh22WVPv4QcDrPumNg08aN8t2ggdKmTRvZtWtX2PZy5cot48aNkR+Gf3/8Vd5qZAgYAoaAIWAIGAKGgCFgCBgChoAhcNwjYAT0cd9FVsFoCHDAXJFTiui28MKyTTV/9+7dqzIF4g6fc1+iJbJ7JywC69atk4d79JB777tXypYtJ5l1MQK7GDJksHzQ7/0M2W7I5mLFiyU69I3FFUhAI58zZJce80pfdvnlUqVKVcmfP7+OkcyydctWGfjtNzJjxgxXN3Sfx4weLX37vCPtOrSXk08+2SnAL126RAYOHChjx4455m2wChgChoAhYAgYAoaAIWAIGAKGgCFgCGQ8BIyAznh9ZjVWBA4q27xvf+hQtqBWqYHz30Tg4MGD8vGAj/QAwq1SrEQJ9YTO7A5P+3XCBFm2bFmGBAWP/jx58opfUMFLlcPgINstGAJpQaDUqafKDTfeJGefc7bEl44P7xTZpwt38+fPCxPQ5LlhwwZ5443XZfacWYIXPsePrlyxQibqWDp44GBairW4hoAhYAgYAoaAIWAIGAKGgCFgCBgChoBDwAhoMwRDwBA4IRDgoLQvv/wySVu8vECSB8f5DeoNkb5fJUZ8QBbBgiGQFgROVfL53vu6yS233io7d+6S/bpwh54ziza5VLKI3SSRYdmypbpzoF/kbaezbgt+SWCxG4aAIWAIGAKGgCFgCBgChoAhYAgYAqkgYAR0KgDZ4+MTAXR/I73xlK+TA0qq8OxEChwMBlmU7gAw6JP8R0NGJcwg1Km79p7zQqX7uIfX6okUjvYCAVrh//yb8ZTBwG956WVy8y23yObNm0P2pPMBcwq4Z8qEdfGJLWTUsRRb6zJ2rHSPo//434eM3etWe0PAEDAEDAFDwBAwBAwBQyDjIGAEdMbpq5hrmjNnTsmVK5fTwYV4hDTYrVv3tygB4QOH9eXNm1eyxMVJnG71xxMOb8uNeggV8SG52IqNtnJyIa9uz86h3nO8+BK47lXyd/OmTeHDq5JLG3kfuYG8efNJtmxZXfk8P3jwH/XY2+GkFGiTO2AwU2YtY6+UUJkF6h8kRPieVyULiuuzTBovLs6b90ma1wHXHjz/UgscXpe/QAGtSzbJpG3KrBhRVpwecLdmzWrXTgjhnTt3hvFKLU//nLzz5MkjcXrVyrvbu1R3ddvWrWGSGe3fggULCpjEadnFipeQNWvXyOK//kqRXKf/0HYlPd+1om4LfU61hVV//+3Ko95gQD+j9/rvwiHiytmT2gO2hP5yHrWnk07K5EivAwf2uzI3qV0cSQ9e2p1H+4k+I1D+DrWfrVu2xNRMPEGRHKDfISnJpWixYq7OkHf0lxsbauNbNE/6/3CGggVPlqxq/5RD3hy0SQguHVCvwqp9jj0yJnygXjvVO3q76l4Hx4R/HrxiIxwql0U1gInLb9q+QW0Cb2vXRiW6Gcdp7S/6IJ/mRxt8QDLEjztvo8xPzD3582nZObLLtGnTZNdhxpPywYh5KquWFTqkMrMbT2t1HO/ds1elfELjYc/uPTrPbJM9Ok/GEpjr6J9Dc18m2abpd2zfHsY/R46cUqBgATcmwLRI0aKyR8fcFh3rEOD79x/QPtvpcI6lzGhxcutcgs1CKGfWD+OQeQP98+07dkjlypWl4ZlnJmjkh/qEBTrGPnPBZrXjHTu2J8qaNjEX0y9+hFP/7dq2HZpntEAdsmvfu/ianoNAiR+0nwI6p9Hv1BV74zt/X7BZ6sLiyrr16xN5/EcrK6V71J1ycibMgbTYz+Xr1qxx0k0Hdf7br5+d2pat2hf/JjCfu7Zre1wf6LyL/WPba1at0qwVC/3bAx7MGUE8UiqXPqRv+fsK9gTw4W+y/w2G+fMX0MNW4xyehdUe6feZqucNntEC9kG+1Ju+itO5Dp1v6rVZxz/4kZZ+4W/EibaYGw0Tu2cIGAKGgCFgCBgChoAhYAgYAkcHAc/QHZ3SrJSjgsD5518gV159tRQvXtwRP5Aqv//2qzzRs6d7Seal85rrrpeOnTpJuXJlQ2TlIb7IkdULFsyX5555RsaMGSO79eU02gstXnVnn32OI3kgmHipXaQk6csvvSizZ89OU1srVaost3ftKtWqV3ckEEQV5MDAb7+Vj/p/KK1atZLWba50L9z7lICGaCyqhE6QROUF/ZKWLaVBw4buBdqTQ7zM8zJ9f7f7ZMnixeEX+MgKQiBAWJ3Z6CzpekdXqV6jppLFIWI+yAJCskNWjRw5Ul59+WVZuHChIweiYRRZBu276eZbHDFEfSETJk4YL6+/9pqrI4fMtW7TRrrdf78j2eOyxDnsl69YLi0uvlhWLF8emaX7DdlVtWo15+nYqPFZckrhwo6I8mQFkfZpeZA9a9eulV69XpGff/pJNikuwThRM0/2ZshoIMs7du4snTt3kfgy8UoAZwqnwC62K8G1fu066fXKy/LNN9/ETPKFM4nhC/bSpGlTlRm4zZFwB1SrNleunPKtloc9phYKK17nNGkiXa65TmrWqim5E4iyMDbK1tBfu1TCAE3pDz/oJ1+p3AdEMW0Mx0utoBSe93ziCS27liN9yBNiSzMOp6AMFiQe1MMWb7v9djeWeYjdMsZ/+eUXeeuN16Piy1jwix/d7u8uF6ktQYiSnyMNyUi/YMO7du2WpXroXJ/evWXEjz/KeiUFY7FtsgDDhx5+JFwHpeyli9rGqpUreSy1atdxNnrpZZe5siFNybtli0t0jvrNYewi/st/PNF9uc4bHXSeq1ihouRUezhJ/weO4AEJCUm6Yf0GmT79D/n666/k+6FDY+pLFpHe/+BDR/zRQ5CpH6pkxScfD3BzUiE9HPVixbjrXXdJqVKlJJvOjQTKpb0sFqxe9beMGjVKHn34YTdfxYqxz6eYLo5c3batzuXXqa2wqKCLjoonAY18yGIW3uhj7JSysZNp06bKpN9+l426wLBY58MpUya7NP4fFhHuuvtuR1wzdzqs1Pb7vf++fPnF5z5aouvtd9wpTbTvPQm7evVq+b9PPpYhgwe78lkUvPe+++TCCy+SQoUKuTx9BoyrLVu3yN+6SPaIYvHbr786rXP/PNYr9S5durTcdc890rhxYzmlSBEl/+MS9eceJVZZCFut5PBPP43QOn4iS5csibWIcDww4W8F5P51198gp59+ulvIwe6CcwG4b9i4QdasXqNzxgfy04gfY9JwL1O2rHTu0kXHU1O3aIFtrFy5Qm7Tv7n+b96ll12uY+lWqVGzhlvkoE5bdX6vWK5sOE64wmr3JUuWcH9bWrVqLZUqVQottGmaYAj9bdsu8+fNc/PmpEmTQnakY8WCIWAIGAKGgCFgCBgChoAhYAgYAv8GASOg/w16x2naqtWrSYMGDRwRx4srH7xSCS2UoH3s8ceFQ6mQsNi/b7/7BJvCK2mF8hXkowGfyKxZM+SlF1+Q74d9H4zivlevXkNqKWEGseXK0JdvyBZeurvefluS+Cnd6Ni5k5ynxHm+fHkdCcWLPN5cHJBFaKmEVf369cNlcY8X7uDLPt8LK7lRSD26ggESBdLhtNPqynIlDyE8IgMeyU2bNZPXXn9DvajzOCLFES9R8CFtrpy55JKLL1HirKXMmDlTnnnqKRk18pfIbJP8xnMbcgTCE5KRkE+9rfv06SPVqlWXx5WEbKb1wPPsgHpI8iHgkRZsq7uZ8E8RJaL6vf+BI06DhFG0dkKaQNK8+eZbSmisVOL7VUcUQdimNUBmtW3fXu5Rwqds2XIO1317k8qfZM+WXUqqXbzZ+225UDF76YXnZaZidjgD9lK9Rg2prgQ/Xn5gy3X+/PnOixnCKblwSYsWOiZ6OlywY/odvKMFbL1cuXLy1NPPyMOPPCr9+r0v777zjiNpo8WP9R6LRbVq15IauujhCSbSehvx+eDdHR8f73+6K/Wl3njb9u3zdpj8DUYi/1defU3OOuussG3jhcuhhpEhi2JZtkxZeenlV9yixYsvvOAWgVi8SC1UqFBB6tatp96emx2O1K2skmkQ0I889phce+114XmJXRb7E+pO/Q9nuFUJ+ut0kY3xBobUAy/nyJBdF+NKlCjuyLlzzz1Xxo8fJ3doWhaskgvkVbJkSW1n3fAcBCFdrnw5YQGpns5TH/Tvr3NR4dC6lc5LjJVgAOOSJUtJ+/YdpHnz8+R6xWX69GlJ+juYJvj9lttulZtuuiXcPp7hvR6c2fD6Vh9XlwxieO9eXYj8/Tdpe9VVzl5oB3NK5LwCYd347LOlSpUqocVJzYH2pTS/1dBxV69ePddOxmIRJX+n//GHI6Cf1LFy5ZVXun6nrGhjK7d65LNI8PXX38hHH/WX3m+95RYLXeVj+IfFlJdf6SVNlASnfNoWnD+DWRRQD+X8urhD+zp06ChPPfmEfPH5Z4rJocWeYPxo3yupZ3mfd/oK9g62lMecHekxTF1OKXyKs4XXXteDHXVh9omejyuWI6NlG76H3dauXVuqV6vm5gO898uVL+/KYrfSe+/3c38nwBPvaj6hPk46b0HMd+zUWR548EG3SEEa6hutH6hALv0bQdkDPv7Eecj3fOxRGaYLM/xdt2AIGAKGgCFgCBgChoAhYAgYAoZAehEIuUulN7WlOy4R4OWSDy+kEFa8cLJd9/Y77nDEGSRx0KM3WiNITyRI0Z49n5QuXa5JEm2AEgWQmE6yIKEcvDZr6ctrWkPlKlV1K3DBMDECIQxp/Ka+tBOQ1PDt8tfkyvDPg1dw4He0ABl87733yTt9+0pBJYMhccEuteCJB0iCN9Vb9Cb1RkstUAefzl9JE186Xro/+IA0VS/eSNKR/ksu4O094qefpXad2o6cj6XeHhdIyedeeFFJ7yeTyz7qferD58EeD0m3bt0kPr6M67eokQM3adeFF14oTz/7rHqZNwo8OTxffbsOXUPEkHZ8sgXgMf36G28q+Xxq2L585EP5JE7PfYglPE5vv72r3Ie3uhKS/yaEygrVN7lyff7B58HvyfX96boY9fXAQY58hlxMLp7Pnyv5Eg+CtsdDPZTce8V52AfjRH4HpVC60FjzdYO4fvq55xzZCpGZkj1H5pme3336vit33nmX2wFCeurhg29X8J5/xhx5zjlN5IcRI6R9x45uPPln0a7gg8yLb+fOHTvVg/4a5xldRGVS3P1oCQP3sCN2cnz+5RdSp06dRHUNREv0tbcueDzwYA8ppumCWPq2hep1qM0kJl5cXFZnp4xDfkP6B9OHC0noe59PqH0JYykcKfEXj4G/UgZSGMyLV+tuHPo9lkB9OilZ+sijj+niZsp/RyiLwK6Bb9W+mTtZIKLewUA83xZ/39eT3RsvvvSy9H3vfZ1D6/jHKV6bNT9XBn73nVSsWDHJ3wqfr6+bz8j/xvP4gw/769/hp52Mjn8e7Uoa6u0+Cd9366LNe/0+kCZNmsRkK9mz51DP8/vliSefdAsAvn6+PP/b1y94n7+DyHP0eu11aduuvZN28s/taggYAoaAIWAIGAKGgCFgCBgChkBaEUj8ppbW1Bb/+ERA+Upe5N0noYZse75VyTbIDn3kAi/reIlCGqMpCwEDIeKD90osqx6f115/vbRRL7ZgQMJh5d+hrfXc92Xy0nr+hRckIQKCaYPfIayLeL1brRwvw3jzIRWxYsUKFxUvLrx3/YffvCBHBu5FxiVNDv3Q3sgALp2VXL/1ttucfrRvA1de/CHXIU/QyUXbE9KRewTigBH1Laoef3fqdvt7lJBNKYA96Qj+ulf1WCHo8DpEssDjTr70B/Wmbw5pG4eIl3r1T3dexcXVA5p2k5/PE6Ixp3ppo3+LBqrvX080+HqjMYoX5gMq6xBLIH/yAIt26v1cokRJVyZYgTPlgFVIZzik9+rzpUzinXFGA+mksgxHKngMFOEUi+isZOF1ateQUEpThvuS/s2rnvjouCJbog12GumMFT8+PNb0TceOneRalUEopoR+egOY0sfevtHt9nYWmSf3eR6OmzAusHvfv/7a/Lzz5E31Ji1bpoyTQqAPPD4hG8npxj/95W0k2Ebi48F+qR5khyxD2bLlIqsT/u3R9vl7jK5SAvLii0LSC758pDCwBeyW9vgyw5ml88szzz0v52mbaQ/B2xzYMM/hSYq0DwQpWrjgSNl4v1JfMCkdHy/3d3/AzY0pVSPUzlCr8Vpv0qyp0NaS6r3qMaBccHXjUOuEDVGGD8Sjr7DBHio/we6ElEK37t3l3Gbnqsa6ErqazrfPzQ+qUY/eNlIWSCmgyezL8vUpoXry76pUSIp4a5OI79OErr53U6pdKJ2zGbVldse00B0izJnco6/57rFANgQb9rZKzj7eJZdcIs3UI50QfO7ayMg4AABAAElEQVRuJPxDvU7XueTpZ551ZDBtJT33KQvcyR/ZDaRW2AWUN7/qgQfmb7IiDnIWra9oE8w+0Xdfh7N098prr73hPJrBkLL4YMPIQjEfYAtIrIA/NkddCNQNm8c2IXSRYkopaLbh/ElLHfC6Ru6DPLlH4D51of3YQTDwd+2GG29w9fN1JT52if2zsIsUDemxTbDwEkrE1wq4ew898kiK+ATLtO+GgCFgCBgChoAhYAgYAoaAIWAIREMgKYMXLZbdy7AI8BLJSy8vwngzIsvASyr6oFOnTpEJ48fLgvkLnD4qBOjpp58haIuylZgXXP+SW7VaVSWgr1Ld268Ui0NkxJTJk9VLuprKXhRyeROfF9lOnbrIL+qZ69OnBOBVV7d1khReMoKXYcjnsWNGh5P973+fqhzILPciTby8efO4LdRV1HPap6OdCxYskBl6CBMkk9dD5YWbLfWjRo1M4l18tnqS3XjTTQ6foPQBL+h4YIPR+HHjXL6QDDVq1tTtyXWcXAcHilE2GENoQe5c0foKma4aq7/8/Eu47ql9YVEAsoSAJApEAh7g9AH6u8hHjBs31pEoxKE8NFXbXNnGYcABhj7QVvD/888/Fb8xMkulLtavX+f0UJuonuhlrS53Zfh6Iw0A+XWFki8LFyyUr7/60meV7JUysCd0belfiJd5qhk6UtuMli4HNYJfnTqnyfU33ODszZfHNZsSmmzxRqpgsmqMHquA9AFb6MEATLE7wpixY2WA6o4jAUP7aC99guRCO92yD8Hot6PTHhYoWrVurbIiM2TgN9+mqzkQh19+8YXq3/6m/b7XEd+Uc27z5q5uPlNItB9++EGWLV0aJhe1giqnc0C1qZeGt9XTnqpVqzqiv6qOEcY79wi0hz4De/R2GS8b9XAzZFKQ7mmgurYsqHhcsENsH91oDol7RD2iYw2UeZnK5xTQRRCw5HeILM2k+uObZP2G9aprvsItNEGE/ZvAzo7W2g+MJcriA+EJ+ThYPVaZQ5gjkB5w2up6AOEFF1yoxNoVTqbFHwR60j8nSSn1aMfD/9lnn4npkEAwwpYg1pkLssRlcdcvv/hSJk4c7+YzSG404Kkj5CyH0hHAhDqdffY5UlE9ZJdE0SSmz8qVKy9Xqg4+49XPz2BJPl+oNvO3anvIbNDuzEpG16tfT9q2bSdV1A68fIrrR9Vhps3oM8d6KF5a+oXyGf94CIM/eLCgM23qNBkzerTM0LkJXWQWsRqprXVS7Xji8CHQNtJB9o5QzWQO1UsuNFR7PVv/bmGrlEug/5G66Pf+e06Ch3s8y6KY5C+QX3fzXCtnnxNKQ5mUR30vuOACrdt0Nw5JEwz00am6OMAibHmVwvB95+ZCbcf3w4bJoIEDnUY/B1tqdCWj46SAHhL44EMPuYUF32fUtZDuumFsk27WrNjkiJBUYQcJV+qNLVNvxs16nT/W6kG1s2bNDuNYvUZ1VwaLrIwBAmmYQ5hrhg0bqoff6qGlCX/PGaONzzlH2qiNZVNv+X37Q3JKSOXgbY9u+5w5s2XqlClBaOy7IWAIGAKGgCFgCBgChoAhYAgYAjEhYAR0TDBl7EiOQNOXTsgyXlghyr7+6islRibKX3qAHuRX5syZ3CFgECDtlWRrpBIJeFmRhpf3rFmySk0lX2+6+WZ5t+87YUA+1UOcIBohpyA5XFwlq+qqHigkKulTC2cqCQEh5gkESBIOevv444/DSSFLxo0Z60jCvUrQnaoa1h10m3zNmrXCZfByPen33+UTPfxq1d+rHAmErzC0G+RypA7waVpHvHghriCsfQCjSZMnuUPmyA9S25O845Sc5ICokar33LXrHY7sgAwIkUh7pEyZMkpo36wan6PC7fH5Jnf1sgRo8uKVtnrVavnxxx/0cMIJrt6bN22URXpYGISoDw0aNJTL9TCpXQFdTvoZD7y+2j8QG/PmzpXlCYcW8myyLhaMHj1Kt2R3k1PU49zjDTECuQKesRDQ1CFObYN2U9/vBg2UL/VAvsm/T3IkqK/jr2pfEEH3qVc4/UUdwGm/EhtFixSVa6699pgR0Gc1PtuRQr5O2M7OnTtkgmL+hsq+UPfIwL3ly1fo+GjvbJ72EyDxKqh+bflyFSKTxPwbUopD29gyD4FFvzZWQvK8888PE0rUFTKIgxVZTMFbkeBsXHFl/AV1XSGMmjZt5uoH7i6u5oFO8Wuv9nILRGhkL1++zD3DdljoYLHpqqvaOq1ySHnaSb4QexepJ/Ovv06UIUroxhqKaF8zD5AXn1+V9B48ZLBsVDIbm96g5Ddeu461izXTiHiM2a533Om8S2krn1y5cynpOdXZ5k8qq8F4iAzcmzNnjlypusjoY7OwQFrGBHPDsKFDdMyMdvci00b+zqqkHX2ELTF/cbDoJD1YkTIOJJCjLGb9oQtU7XTXwRVKAvuFDPIC/xYtL9WFoAWyaNGiRNmDG/r9HKznbZb4a9as0fE3SPq83VuWRBDXU6dMdnMeh+TV190Su3aFNHxJx+GMzGVHgoCm4vztYNEG26FvPh4wwNXzj2nTQn2d0Drwmav43HX3PWGvdR4xHvh7Qz2TI6DRyr9Y9dvBg7mMa+YsmeWDD/q5wzOZA+nHyLBKbW3qtCnu0FQW67BN/j4wr7dt106Gf/99ornW491ID6e9RD26WczxgbH0gu5eGap2wt+KaGGn4s4uCeSSWDCgruzwqaw60tffeKPce/dd0ZIluYddZVdcSc/Y36J/s77TcThaD7Kk/uiuM478vHRJi0ud/jpYErAh/s4NGPCR/m37QmYrWR0ZOHTwL12IRK6LsxB8oM0sGDZseKYR0B4UuxoChoAhYAgYAoaAIWAIGAKGQJoQMAI6TXBl3MiQKrxIQ4b0efttd+jSPvW29YFD6DgYjg+6zplUY5RDpSCDeeGF+ArJVXRJREAvVU/MuUrgsF3av6hDiPHy2ky3io9QIjVIivnyuBIfYhJShUO5IAu4R/ylS5fIygT5DeJuVS8/Pj7wAr9ZPZSJ7wMv6KvUW3iBkmqbN2/2t5O9tlDy4v/ZOwt4qYr3jQ8Nl+6UlBIFBBtsxW6xu//Gz+5uRbEAW2wFFQxspS0URVSQFOmU7vL/fOcyy7l7d/fuLcr39bPs3nPmTDwTx3nmnWf2FckXvMOIi7L++usIT0L2E7ETb7NmzXJ8IIeXa1L+vyuv8rIm5J1nIVvQLj1A3m39RXqBe04WwnC4FCQGiwOffPyxxyDRsxwg2UneemC3KFJOyJCXe/Z0D8prE8/pqJEGRE4mmVNEJPS1WTzdqWe8qvE8jBIs0Tiiv4kPIovDqTikDqIv3sCpd6+3vXf9VZJv4NA16haChLLiSb65rEPHDr49B4KqePESIvPmuEe7dJHXe/aykE884l+VZ/QCLQh07/G0J5MgdSDbymeU8QfTQQxFScXclM+TsJEHPDGsNl1EeIVWBH54P88R8ZjK0MXda68OrorkcMLiSWjfz0lDmINFQ7sP8RA3HvN8Jk+eor7lPHEZSDNILrSuL5HWeW4I6EA+Q35Ber4kCYghWggpSGPh7NTTT/dR0g+LSVqAMaBv3z6uR7du/jrlD32NC/zNWPfKyz11fb3XYGYMCWEg3DvJQ3qcCOEZCpeThT4xYcJ44dsloSctJOFXX37pPWg5MLNhw4YxwhCiEBKcRaBEBPS+0jgOpC55oe1BGLJgMn36tGzZox+//dZbntjdSQd0hvKTzx112CUSEYVlAUOW/97TeNbloYeylYm0Ic2f1QGsZcuW0wLCFTGPacYI3jd4Gycy6unQww6XBMfunkQPbXvShEmu66OPxg4wDGWOxvGtdv2M0AGJu4mU37lduxguvIOaNG7iF3369ukTe4SyoJe/n/DncEDG3JAeXsRddKhqqj6P9z1SUuHQQvoZfQKP4z21+EofZQdCOkbbpj8yjn/19Vee2GcROZE1bdbU63AHQpo8837s+sgjScf4yaqPbk896ct3q2Q3wJkP7a6KzmioXad2oqTsmiFgCBgChoAhYAgYAoaAIWAIGAI5ImAa0DlCtG0EYPKJPd2ju+v19tsiezeSz/ElZFv+Y10f9d6skIwYBBgTUSbNTMZDfNz7RR59oyWPEQurCTv30Z+EWEhmTGrZfp2hCXWYJHMNUhtpj1SGdzWEa9SUrMjATM3k6PVEv0kHvVU84JjUY+SZ7cyP68C1RORzfDzP69DCQRu8z8AGg9AkznPl3buRhIl/MvvfkJiU+/HHuvo6miwCPopx9Am2gXeSZ2zYVs890po4caK7/bZbs5HP0Wf5/XLPl7w3NCRISIPnWTTAkz1ci38u/m+ef/D++xOSz9GwL4twZGGDeEPc4MVW8s1l1atV90ROqCM8J1nQSEY+R/P5pSQwBg0c6AlOCLQhkjp5T17J48aP8x7h0bD5+U0bVcXGyGcflzD013OI+Jhjj/XSC8FDHtzpY3/+Odrdecft2cjn+Oh+1BjQRSQqBG1ID6yoszp16/jDyeKfSfU3WrOff/6Zu+3WWwqcfEbOAAmUjAihWrJU5uLIZ598GstWqOtwIfo3pGS/fh/5BbdwH0K4Q8e9/QJTuJbqmza9YsVKedB+npB8jj7LQiDEd8CWe+QnUyopq44v96i/xvLQRT6BcKS1VATzbyNHevI59CvCxhsSK3gZM8YEQ/Ynmna4XpDf5GmxJB6o83hCPT6dJ5943C/sheu+jBrfkRJJZPvL+5lDA8Mhu+ABCfyMDj2ERA0WreNwjW8WD197/bUs7ZvxDH1qdg3EG57RHHK4bIOUBfeRdXpYB6qm40XOAt3QoUP8wgMLBxjpocG/9z57+7/T+ScT08V+l8s9d9/ldzAlq3sWQ9mpAgaE4T23ePGipORzSJ/w1Ae7I9idwPfXOu+hj+S3knmjh2ft2xAwBAwBQ8AQMAQMAUPAEDAEDIFkCBgBnQyZPFxnYsmkDw+lXH2YKIrYSTaRzENWsj3C5HOayKTevXvHyN5sgSIX8FT8449RmiSvi+WLOCjf2eec6w9oC8HZsjxEes1RAhpCoJ00c9HcTGYcCAbhWUp4BaKAOJjk4jVWmHasCLrmzVv4rcukA/YQdEhWfJjA8zlZXt7p3ct7gIeygxEaxztJGiRcS/Zs9DqEend5ag7o3z92OWASu7DhBxrd1WtUj9VjZt7XZvFMj38m/u8hIs7xuKU+qSuIc3Rr0QFPtx0i1zBr1sz4qBP+/bfI9UUiP0gLIw0O+dtctlLkIvUdyor8SRl5MVf2BxKmzhXEUVct0OCp/tSTT7jzzzvXdZacwtM67C8nz+TUMRfc3WbNmsuDVG1EecXAHY/nZ+RtGiUiU6UICT1q9CjvtR4OJqPs5bSodNbZZ8fqMlUc3GNcnDhxgnv26Wd8/wqY5/RcuverQ0BLjoa8YcTPjo4P3n/fy+ekEw+yF69o90C0TdL/qlWv5sfydOJgF8HPPw93LFDkZGgIs4gRpDkIT3rI8UCexxtlYmErHEQKpnjNQoJiycYK7hHmr78m+nrgbwziM912kPlE7v6lveExj6TNnFmpvfWJmbpjAY1nwhhBWZMtUh1w4EFewiLIS1B+pKRee/XVlFhES/H2m2+6CfIeDjgQB2N29Q0H4kbDIs+B9y/5JH94MY8U+Y98Syrso3H0fPFFr5Uf3gs8x/8nNG/eMhos5W/q/d1333Gf6Z27Xm0cS5b+Or27eR9FDYkfxvycjP8fgYRGYuthea+fdsrJ7uSTOvvF64Luvznlxe4bAoaAIWAIGAKGgCFgCBgChsC2gUBi96Jto2ybtBR44zbUJLWdvLJSeRcnylTRopmH5PnDmdLcipsonmTXmDDjCfnqyy8nC5Lw+jfy7GyrrfxNmzXzE24ms0yeObjvcWnIBnXNldLAZSK/UNvL/eFeGya9eF/tLa3duTpQMH67Pwki91C/QX1PjBA3E9vVIkIniixBvqEwbXdpKKP9HEgrMEKq4A3pY0JIhOs55YFDtTgcEX1M8g8ZoC9XVmRmfW2v/0u4xJMA8XHyHMQl5FWqrdzhOQ7TwqM0akuWLHWvi3xJN9+ffvap31JeVdu//xFBxbbyyfK6HjpkaFJCI6QXyvnQAw950idcT/VN+ZYqj+XLlffELziBcz1JOuBlm4xESRVnfu6N06GJSEJQfgxCqVGjxu75F150555zttdohZQPnvnRtMB4pLbw89kSjS39lXUwGuNKkO4gn/PmzXXv6fCx3Bja6y0kb9Gq1Y6xg96QGTno4E7aqv9Ujm2btCCzkP2ZNClT17ig65p2hIZ8iJe+PGPmDL+okpuy0nGRrQjtm/iqakECYjkdIx/ohLMwk47xzsAjtYxIQYz0ygjbRJ7J1ONqLZr8q/vBCB/nHx9uZfkmXPwYxDUkJwrLIEqRQHnowQfSyiP5YEGMfggpi5Fn8EgkUVFO+t7UCwtHgRCepsXD3NoKEd7081DnYF+tWuaYEI0LSZewCENYiHIO8aScicaI6LPhN2Q170LaCUb5KEMjnRuQrlHfjz/2mI8np2c4MHS53s3sDCCP4IRs06WXXeZefOEFXwaktdarLcQbmHBQYSKj7ZgZAoaAIWAIGAKGgCFgCBgChoAhkFsEjIDOLWJJwuOVet6553kdy3Q0dOOjqSTC6PzzzvWanfH38vs3E+Y1Is0GDOjvJ/jpxsdBZ4fq0LFW0iqFGMCYxFaRDIfEFLJEAxk3WF61hx9+hJ/YcpNJ7/kXXOCG6dCysSL8ooan37nCi0l9mNAy+feHgungusK2ipUqSgM180Ao0qJcTNb7iXBLl1AIeZz3zzxPtkDM8SzlgSBuo0O0pmg7eMAuhI//Zpv5V9KLnjt3TvytbH+jS0tbgXjBqFsI0b+VDmRIugT0bBH855x9Vrb4Q11kuxF3gXATJoxLGysOS+PAOTRUMZ6HiOHwPoindNONy0ae/+SANraXB41ZyCDyw+Gbw3SYIl79eLf/qnYdvCzznNgmfrBVq1b+wMBAOtK2KcO0adNznZPB8tI9qfNJXq874EA7q5KGp3hIDDILWZ9Ei1AhTH6+yQ/yMaSD0SfmyRuWfpWhRa50PD6RUfD65/IS5xujTZbTgkkiQtgHiPwDxkv0bDpyDOGxtZJBWrhgocuokxFr/xwGS/6zmfIyR2VCooO0GGeqSiO5Ro2a2YLGX6ghD3HaeXRc46DLVRvG9PjwBfE3ZaC9MJ6na9OnTfUkeyg/7bds2QwvlRSvkUwdQd5CBPMuou4hXCGrw/M5pct7et3aNX58pg2FMaCs6jxqpUuX8m0iELXEz5jOmEt6oZ9Fn0n0mwUvdpmE8LQv2lYYExM9E71G+LFjxsbG/ui9RL8nyaMcWaFywoq654MXPYfQHq8dG4xxb0uOCw3pTT3+JsqvXTMEDAFDwBAwBAwBQ8AQMAQMgW0bASOgC6h+oQyYmPKBIMit8Uypkul52uU2bvK0XpNPyIAw+U0nDg5OmiOPLSbnGJPUIiKMmfwryiyGxuXHH/XzW+EhBTDCJzvsionwMccd6/EKk1+Iov46WIkD+ArbOICLg+fwAMPACPI2L150HE63dOmyGHHl45P3KYcFxutU+8Ti/oF0+uXnn7VVfkHcnex/7iBysaYObQxEM/mGWIBQDjhmfyrxldyGj8YCuZSb5xf8M9974ZPfYPwuqrJvDkOTerwOiws6slFyCXIVne2jjj5aOK/xur6Q1RwK+Mfvf0gm5Wu//X5z5DudNOvWrSfSNSPW18EZgo42klvDixXiLIxp1DnSORkiBtM1POzXCMfCMloUXrOBgKZvNG3a1D0tuRGuRdtcsjxQLshAxqBou0ZTPp3nCbNMCyy5IdnXrlvrFi9Z7Orov2CQqfwXb4zb48ePcw2lW09Z+ZvFqFY77OBqSs85Vd02btxE7bydY6dKsJUr1X8VR2EZGOa08Baf9rx5//iF0ijeHo3ImBGeoa5YMCKdf/9d5zE54ogjvE5zCJPTN89mvssy9ZEJT9rxnuF4/6MzHuRsaF+MEV10mF8Yh3NKi/ukx3svusuFMlROIVMV4iVfPM9Oo3Rx7dG9m5fBoi+EvkF8vM/Z7cHi8BlnnuXvQcazwDFFu2BYdPv8k8/c1GlTQvL2bQgYAoaAIWAIGAKGgCFgCBgChkC+ETACOt8QbozAb4jW7lQmirm1vDyTbhrEjbRFbibLIe7Va7Ju0YULgLxNZNNnTPeaq3iDB2+7YiJiIfIgSKKyGhDZzZs1z0KSLV++wh/EF52gJ0qnIK6VkpQIRMPqDXUFRniJ58Xmzp6jw6UWeo1QgezrH8/u7baTvEgaixGQexy6iARIToYnY1VtEQ/4Ep7fk6dMyVO7yym9RPfBCm/P3LRZtG4DyZsozs1x7ZGHH3Y1qtdwxx53nNfTjZYHkg8yMhA/tOlmkqLp0KGjO/W007zHO56DD9x/n9c13hz5T5YmWrV494fyUAYWDKZOy71EAWlAlEbrjvhys1hG31+r8acwjL6DjMv69VnHXIg9vIXJa7oGXtF+le5zhCMf8xfMV7vIeREpGm+6C4KE++7b79z+++3v0+LvVVro21cH4912xx3u+muvEcGcufAXjf+MM850V159tcc/tAfusyslLzt1onEn+w3mvGsYI3JjlCmax2TP4tGLDnkUO9Kkz7ILJTdGfcenGd9kmojA5fDd+PRy277IV6L0kh20GF8O8jl+3Ni0CWjCI6PBOwOJKGSWMK7TXlmkCocEUzb60Y5a4NxPbYzdXAsUnp1N9917T6G1lfgy2t+GgCFgCBgChoAhYAgYAoaAIbDtImAEdAHVLRO6DE3oKpTLkE5y7g9XK61nEh0+VRDZY8KJByKTdH7nxggefYY4vEd0/CxdkY6SV+nrr73m7rjzztiEFW+to48+xg3sPyBGQFcQMXTEUUd6D7bgzYVH28/yAh6vw8A2hVFflCUYZcwrSYaHKKR5OCCMOIkbWQCI9nRs6bL0yJoqVap64iDUCelAHkAuhGvppJfXMCG95fKYy01L2oh0XlMu+Ocmawv9bbfc7GZKL/jMs84WqVrSSyhAnkXJJlLOJGzKeI9JDr0Dh+bSRm7YqJE/mOujDz9weMJvCVahfAXvzRvaA3mlTHnNnz/MTEQd8fg46SsipdM1FmfySuzmlAZyNE2abK/6WpclKPmkDslzbox6jhrkYDpx0M/ROM8tqZtO3OSHw2A/eL+vu/DCC/1BhTwHpuj7Hn7Y4ZJFquJ+libxuHHj3CotGkImtm3b1nXsuLeXeAgesJSvpKQrukpHGFmcwjLyxrkDubV0agvZHjS/4/to/N/ppA2O0Trg3Ybec9Tq1K7jPZfj46eNhT4WDZ/qdzS98JuzEtI1FnFzs5A8aOAAx1h90SWXuBNOPNFLnLAYRf1QnmiZKDsEPl7aLLhxD+/pFi1buh46IHewzjtYo7ZlZggYAoaAIWAIGAKGgCFgCBgChkBeEEh/5pOX2P9Dz7DNvG+f96SzOjXLdtd0IShVqrT7/rvv0g2eq3BMdMN25Vw9qMDwN+HwJZ71xI4mr4nYR2QKvv32G7dSE9xgTHQh6mppm3iwOnXquM4nnZRlIl1Gh/b16/eR+/HHH0OwQv3GYzJKHmRilJV4SDcDZcuVlfedDsQSIRGM32zH/1daqzkZnvNR8jpVeDRmkYUgvxjpQCrhoReupXq+oO5Rr0q8oKLbbPFA2HV99FHHAaA77dTa7SUN6EYilSFiwBayxxPSKi9e3FHyB4/Ljh07eoJvoUjWD99/f7OVI5rwsuXLNuRzYxuBXKpYoWI0WNq/i2gXA59o+063rRHOa+0Ku8Iw6oM+EZ8fygtJDnmu3OctaT0GeR7I21SR0B3pE75fpAqY53v/ei/9G66/zj3U5RE/piIfRPmR4jhMWv0Qzt7bXPlgPEACqKQW9iAcMd4B2BtaJBymwxKjbdnfKKB/Ql0UFhbLVyyPyWGELJMm42BY0AzXc/WtOsTTf9GiRVkeg3SNX+AgQDrtIktEcX/Qp4hj8pTJcXeS/8kiUpQ0Th4y8w59Y/DgQf4AUnTY2+/S3u3SfhdXRwsUpbUQQR3RDkLbJW7+5gOmLPAcdPDBXnJk+Y03uu+++9Zfj44FOeXB7hsChoAhYAgYAoaAIWAIGAKGgCEAAkZAF1A7WCaycejQof5TQFEWWDRMJEuWKOm9InM7aS4tYhxyJWqZGs+JyceZM2dqq/g3bs8994pNlCGDdt9zDx3uNsxrLHMAYds2O2vSm+lFSf7wHoQEzIvXXDRv6f5GWgRCkbSZTPNdXGRNXqy6ZBwqVqwUK2+Ic/r06bFrqeL9FzI8VYDIPTS50ZsmjWDgW2+7elmuhXvJvkMek93P6Xo0/ZzCbun3p0ye7F584QVJpmzn9vy2g2vYUDq78iytqgPGtqu3naRV6rhqOvCtkkg9SBvaPwQNZA2LDGxxP+fcc90stX1Ins1teEmSx6IiuDDaNwe20UbyYuxOiPcKXb8ufUJ5haQhckOa5SaP7D6YMHGCJx/DcxCRc+fN1SFrn2pHxQRPwoZ7ufpmbFDfnJDmroxIl8xVMrkJzPgIlht7P97RmQRijRo1HIt7mCcSRW5CPtNXqX8OHfzyi8/d4491jWnf5ybtdMMGcrKwxgh2yVDvjHsY6fBemyBN9759+2Ze8//m8p8NFTgnzjN8irTfozrotC/6/eeff+YP1/Xvj1wmRXC01FlE+Ouvv9J6mnSQNclLXxo1apTjs5MOxm3Xrp3aSV2/U6tWrdpaqNhOC8S1/XiHrAgLFRDXvg2pbS2Vtvkee+zhpYf+lkb0DL3XzAwBQ8AQMAQMAUPAEDAEDAFDwBDILQJGQOcWsa00PJNmtmX/LdmBQBDkVJRa2oZbWYctBU82Jvp4iCE3kYwwxQPvNXnYsfU7TJSZzB52+OEipr/1BDRbejPk8bxEE1uMCS/k/T/z5uWUpQK7j34qnsRRK67t9lVEOs6XN7tAit5K+RtvQ7Yth/ISmN8cWhewSxWBr480k5s9e5YnBKhPjGchYmprm3i69Rqew9O3qohVtKdni9heuIVISPiCbYZ/pk6d6qb27hVLGRJ6xx139N6m9XX4G4c/sjWdQ8kg+0Ld4jF50EEHuyGDBm0RBDQEUdQrmHZRUvIiNWtu3IUQK2QOPyAuy2aUjbUtPwaobedGp90vNOWiP+WQpWy352nciPY98rh40WL3xutvOA5HLQgjztz0r4JIMz6OPffay9173/2usfothCv9nrGTvPGJeujzdwktOkJyrlq90k2cONF7wr7Ss2fahGd8+lvK39Q1XtBhyPRllycvxHS3J58s8GyOGf2n3k3/xAhvxl6I/aFDhnj5nQJPMEWEeHjnpx2yyMsnWOUqlTXG7eSaSt++vs4sqF6juqstMnqXXXdT+9n4v4cQ8HhCjxw5Uot1z4fH7dsQMAQMAUPAEDAEDAFDwBAwBAyBtBHYOMNI+xELuLUhwIQdL0YmkK++8kra25R3l9dTw4YNs2w1xvMRqQ3NghPC4Lf8DhzoSVw8nTE89Bo1auy9rnbQIUcndu7sPTRDBJAo7737jjzYJoRLaX1HvQAzH8j0ZM7iHpgkpoXSTObQLgg2JvRgVEaSCocccojr3atXlkPXkkQRu4x3bJSAhhAhvnFjx8ZIyljgZD+yFyZhyEmTJvnDzoL3H3nPJKBruwwdzhUOmkr4cNzF886/wHU69BAdbDXeE6c/DPvBzZoxY4s7VC8u2wXyZ1lhVVaLBhw0iJQGhNJMlT3IFZDISi2cDJeuLp9gELnXXX+Du/Dii+QNXTpcdui4EteWYMiKLF26JEaY0Ubo/8jgQJ7RNtM1JEnqauEqunMCohPJofQtzcadfoTZQjLuBKN8yE+wKDPC5Y6ABqd68nqfO5edBht12fND+oV85ee7mnTHX3jxJb8IwsIHYwwLH3jd4xVbqlRJPwZxqBx1TH3RlpE/mSGN80/69XNvvflmfrKwRT27epXkR1RGcKBuGMe3lzZ0XozFJN5B7C7hXRVvENu888KYS/tComff/fbPNQHN+MHOCjS9aWO5NcqbjtEGGN84sLF06TKulCSi0IKeosNqo7Zg/gJPpEOmB6uiReeHH+3qDjv00FiZaXO0QbAyMwQMAUPAEDAEDAFDwBAwBAwBQyAvCBgBnRfUtrJnwgT97HPOde+9955bnSZ5dOQRR7qW8lYOuppMftHDRKc5eH8mgoJJ/CeffOw6dz7JT+xJ/19N2jnQCJIO+Y3oRJ8D+DiAMEoiJYo3yzXi1CfeiJ+Dw3KyP37/3e2zzz6uceMmvnyUp5wI8wt0yNcH0vJNNy8N5Y3YuEkTT2JGDyBbuXKFGzFiRE7ZyPV9PMxniCiNkuyQDZDgHffe2331xRex+koVeRPluU3bNt6bt4kwOOqoo1Xm5a7Pe++6Ky6/PFckZap0tsR7EECdDjnMscDSvEVz10ztkm3wd995h/vmm29SZpm+8MQTj7t20lLdc489PUFDO1wLQVOtuqRYKmbTkE0ZYSHcnCZP7nksEm0w8gfBhvd2u112cT8P/8lLS4T7qb47n3Sya9GiRaxN0dZWicj6SXI6ifpfqrgK6946jTeQsWBPnvhUrlxJ/bKxJ96j5HmqPFC2XYTPgw93ca9poe6zzz5TvFqo0m6J3JD2qdLIyz088Tt16uR1nckH5WOcQ27i/nvv9ecOEC95b7/Lrp4cnT1ntryeJ7jffh2Z9liWl7xtrmeWaIGFeoEUBpPM9l3Lj8WT1JfTbZsQydffcKPjYNGeL72k99Bw35fZIRM10hLb7S+RHotWu+++u9ffxjs4XdtZ8hcXXHChYwH0xRdfcNOnTfMLBem20XTT2V5j2v77H6D2sItr1qypf8/9pPf2Cccfl2MU7AC65MIL3Mg/RrmqIqOx0OZKl9m46JZjRBbAEDAEDAFDwBAwBAwBQ8AQMAQMgQgCmfv4Ixfs57aHAJNHyBW0atuI/MXLLydDKxJiFY+tMJlnsg/J+vJLL2TxiIyPCzLokS5dfJjgscUEHsLvyKOO8vIbIU7uDxk0xKGhnRuDIF68eIn3gAvPEWeDhg0d3q05We9evd1vv/3uPecIy7OQGE23b+YlF4K3W07xXHPtta7tzm1jHt2eoJPn4Z9/jsmSt5ziyc396dOmy/NxVsw7DUKEdG+/407vXZdOXKedcYaIieZecxvyA2IVKYOB8l4PdZNOPFtjmPMuuMDddfdd7owzTnc76+A2PPWbaQv6aaefnlZxOJRzjOoX3IOxwMICBjrRW4L9PenvLF6bLLBQzrvvuVee2+l5ateTJjbkc9S7n34BefbcM89mKf/mLPMqecP6RZlIJpZJJ/2KK/7nTjr55MjV1D+RW+nyyKNuhx12EAn9sPt+2DAveYE39ea0MvJg3Wff/XwW6JuMmYynLCRMmzY1lrXhw4e75559xms8v/XGGzpo8IdtknymwHPnzPUSTox7GO27QvkK7tnnn/Pt1V9M458bRD4fe+xx7qijj3bvaHH2i6++dqecckq2J1cIbzzKw/tMP0RaV3NXX3NNrtI759zz3PEnnOg14/sPGOjefLuXzkvYM1t6+b1wjxYm7rjzTpXtWC2yIXmV4Zro/c8CazoGwT5bWtiMcaHMfKd7WG46aVgYQ8AQMAQMAUPAEDAEDAFDwBD4byFgBPR/pL4hLvh069HdNZDXbiorqe3M90hrFCLGe35tCIz+M9u9J4ncyomkZMvyJOlN4+nMxJXvBtLRhegL3s9ch9Dq3qNbNgIpVf64R/wcDlZMpHEwSIjddpNXmoiInGz58mV+yzXka5hgM9kuLt3LZ557Pi0i8YCDDpIX3B6uvLY6kzZGefCIw5O4sGzYD9+7kb/+GiPPSYcyNBL5jpd7hQqpy9+6TRt3sDSL8foLdVGsWFG3QMTie+++m2PdFla5NlW8Lzz/vCfbqSvaMXXHdvW2O7dz7dq3zzEbRXS4XxthGMgvHuD3Amlos41/S7D+X3/lxo0f5xeQyA/lZIFlJ5Gsxx1/gv+dUz4fe/wJ31+DLAltbJ0keBYuXKD+On2LaSdTRcJ2e+rJLAtr1ClyAceIXGzffpeciur18c8862yHRBDPghck3OlnnumaNG6c4/OFGYDDJKN9OtTlKaee5o465pjCTHqLjfutt950wyQZFGRvwIT+vEPLVu58eRgjyZGTHaEdPp0kM4EOcvBAZpcO7SDevv/uWzfqjz829ifeFcVLuHMlY7SbPKGjO1Linw1/33LrrW6//fYVqbvOtzEWgltroffMs88JQQrs++OPP3ZzJPEBJmrMfpzngMrTTjvdldCick4GHnXr1nVFN4yRhOf9uF6HcpoZAoaAIWAIGAKGgCFgCBgChoAhkBcEjIDOC2pb8TPVJdXw3nt9REIdn7AUrXZs5T76+BO3q7buQjgxsceYLHNIYO+33074XPxF9Dlf0hbjZZLX8JNgBWAyG34TnrjxppwoIjkQuPHxpPqbQwyjHlnEV6lSJXfTLbd4Iin6LKR6vH3ycT9/+CHeYcEoM0T5p59/4Q7Wtvdkdvsdd7gu8vLeTl6ia9Zk1Q2FhHynd+8YdsniyOv1YfLM/Obbb/whXOQ3GOW/8KKL3FPdu2vLdWLS7GgRVk8+1c17w63RogAGecpCw/RpG70pQ5zb4jeHLc6cNdN7fQf8aK8NReA/8dRTXts1WbnpB+eLdGorz2lwC/1Dyzsited6j/Jkz27K64Pkyc4iBRbKSF7J/+133O66ilxG6zWRNW/Zwn0mKZc99tzDE9XB05vdENOnT9MhZC8memyzXUOr+4cffhDhPj5WH2QGr368S7s//bS76pprk+Zvv/33V713897SYUEGrCAx35Zucm616ZMmlMcbK6RVP2TQoCxlgyBs3ry5e/CBBzUWfOcGScP3a3nUJvrgacv1z778yr3bp6+7W96xyPVszTZVWsbINs1VnwvvFOqMRZZLL7vM9XrnXR2s1zxhEem3t9x2m7vrnnt8n6fOQ9+YJYmjV17ume25vn36uK+1qBP/HmGR4qlu3TWmdtcZB3WyPccFDvPt8eyzntiuVKmyJ4ND+yL/9ykfBW1v6CDgWTNmakE1c7cT6dGPm6rN9Hn/g5SLKrwPn1MfZ2FVwPisgTHvf3bJmBkChoAhYAgYAoaAIWAIGAKGgCGQFwQ2uo/m5Wl7ZqtDgIlofW0pv/mWW92p8obCaxNZDQ5RQxu3pg4q23GnnfzEMxBPEFh80Ml98YXn0yozhPIH0ii96uprRHRVzXxGaQf/KeJj4v/111+7ZcuXpxVnfCCeXyWSKWrkGa/k7j16OMgE5BJKiSRYrjTuu/ceN3bMRumEb4YOlQ5yW7dzu51dqZKlYiQ4BEVTbVe+R3IFbFmePXuODlX8xxOONWvWcpVFciNRAl6kB6Z8kCoY8+ef7i5pCeeFUI+WI6ff74tIQsf5wgsv8nVIePKADi7an5AhU6dM9Z7iCyWJUqFCeX8oG6RVQxGt4B/yXqZMhhs16g/3xGOP5ZTsNnO/r7bbN92+qcciaHdDsjQXaXX//fe7iWrro0aNclMm/+092iFltlf4ndu3k5flDt4TMvQPSK/p02f4Qwy3JIB66tC6OjqIr/NJJ/lDQalzDM/3I4880rcfDrGbK1JphfpHZcmHVJfXMIcV4plJewplBJuVq1a64ZJ94MDQLc3QRr/5xhtcr97v+H5K/yPvkMj0kwsku7LHHru7pRrrkG+AtMarGC9p7tdvUF9hS8d2BIAVY8Y7vXtlO7htU5ed3Rr9dIjg3ffd5/stmtfUDYsJkJt15KnK33xSGTtYWGihbg888EDfxh9QnIyJW6O9+frr/l12+RVXuPnz5nsvZDCgHaPP/IxI35k6gHHhgoWZY6SaPzrtaKEjLRMWYGgnRfSe4Nnx2jXAIbSJ7IvPP5c3fXs/voYxA+kd4jvqyKP8boFZWtgiPWSoSkkvmQXfunXr+bMU8NYO9UTd8e4d0H+Am6wxpjDst99+cztox0NZjV0sWJA27/ldd91VUiUvqKzjHQeWTpky2S9AgltTHeTILpA2bTIX2EK+0CH//rvvJPsyPFyyb0PAEDAEDAFDwBAwBAwBQ8AQMARyhYAR0LmCa+sOXEYTUYgXttSjB40cBgTuammoIsGQuZ25iO6vzEJmoG37x+9/uCcff9wtzYVWM5P0X+SlxiScuAOZBYqQvGvXrXXPPN3DLVe4vBiT/cGDBroOHTrGtlCTRunSpUQqt3fFNnioMtlHsoMyjxs7NktSeCpDuF0tD0lIuOANB0bNRVK0kAwJ1yGBxFJ4eQ9ILbwrCYsxsYd8RjOzt+IbLG/FwjZIi17SD23duo0/fCwchAXRgFferrvu7qUHqK8VOhCxtMg16hEKkjChLsj3xIkT3AvSTsWL9L9i/T76yB/MddbZZ3sSErIxk4gq4r3nW6red911N5FE831/KFGipCduIWghncAQA09wfU5k1xfymt+SbOzYMZ5Ma6ZFB/SNo20EPeiOHTv6NsxOAsoDyc6HvolHPO0ag3zm+hfyin6ky8Oxsm9JZYVwHooXsLxUDzvscJ9n+mhYCKKPo+W8Wv0aEhoiloUp2j91GO3PlJfdGvfcc7cbOXLkFlFMJE9Y/EN2o5w07mmr1E9oh+lkElKduoV4hXhvIW3gShUrubvkEc+BqdwPdZ5OfJs7DN64kMIHHHCAvMFbxA7/ZFymnBzKSAvOHL+X+/JlCDvaMu0gjN+Uu2y5sm6Yxr+ujz6aFFMO8eOAWhY4eZ+Fg2ppO+XKl/Pe9tTLMr0rVsprnfdORtkMV1JjR2iL4OvPVVC+vtWBpz26dys0GJ955mlXbcNiE4tklJf0Ke+uu+3mWmmhGa9miHDuUabqNarrfV3d9//wjuBZ3tH9+/f3sieFlmGL2BAwBAwBQ8AQMAQMAUPAEDAEtmkEjIDepqs3s3BMOJevWO769HnPndj5JE2IS/gJcZiMliyZuU03qvfMk8WLFfcT6F9G/OK9Y7/8MvcE24siNiG/sulJa6I+d+5c91s+CB62xr+urcb7i4BgshzIJn5DtAeDUIIsKK3DvMAiGL/nSi7jGW3Rx/vxpJM6S8KjsifoiSNo3/J8hQoV/WNch6wMxuQcUgMP4tdffc1jHO4l+ib5aB4ShUn32ohffnFddFja+fLuPPjgg31+IRJ8+UU6kw6kAoQLdQ3pxjdGmTiskcPb3pLMQK8U0iobEduYs4IqA0SRMrox4nz8SpanRLFDuvbs+ZK21JfUYYRnupo1a/qdALQh6p24OGSsVq2a/je4cW+NyKaN/aak97Dtq3716quvqD3PiYXNRzFSPurLkqhASZ4aOnSIPxD03PPOc0hNhEUWykKfoJy0A75pNxBloY1wjcUMwn344YfuqSef0ALOuEIvY5Ki5HiZMuHFP0OHdJ7QubOrqoWvVSLSKRdELR9fXvUHjHJCRIby0peRLJivxaoe2kHR86WXsowjOWagoAIkqF/y+FjXR0Uc7u7HU6SHuEb/Id98+76UIA+E48PYEP2ABWT9+HFjdZjhND8e+8eVPvfya/mPQTnIIS8cvPjQgw+6U0XMHyCvbvouZaS8gSDOHL8zdfG5HhY8KSNkMIsNA0SuPv5YV+/lm6zctKPPRXjjRc1huu20yMnCJNej/QnCmR012Hpppq9Ym/kuon4YjxctXuS+1GIO7x2kRBIZeUtUB4muJXv+70mT1B+6ql0UcUcddbTv52BCfvlmgRbvbbSeiTeUI7zfuIbnM3i+1rOn69u3j/+dKD27ZggYAoaAIWAIGAKGgCFgCBgChkBOCBgBnRNC28B9Jr4rlq+QBMW9mnwvd4ceepirW08HDOl6mKwz2QwfrkNq4DU87MdhfqKMXnJe7KeffnJTp071W56JHwIAQgDP3AEDBvg8MPHNi0E2IOHx5htvuE6dDvGSGMQPGcBhSUrOlwnvVYg0yhU1wpKnGdOney/ApUuXuH322dd7huMhGuLiOxhxhE8R/caD7Ed5xr3+2qvufUmOBPIy+kx4NnxzcCKkH9hjYE0+cmuQH9QLnuBLliyWLvHOqtd6nlgAA/IQPiGdULfz58+XN9sw99lnn7qP5Q0cSIdEeSimhQiIiGDEXVQe8x7gcDGHb+qcOqDcPg8i+krjnS1PQWUyh6dzvk0UEIwQPKRBHstmlPFeiPyOt1DvL7/U02+ZR5IAr2dkVQhPmwS7UEc8zzN4NZJ/7o/X9vVRo0e7hx643/8mTKp6535uDMxY3Fi/gVAjXfKmnppWNOQXKQAkM5AiwAN6J3k9QjpxL5QxtBGukQYf0oak+lOSMniGPvfsM/43YVKVsYQOZisjUn8NJK/CktNS+pvnNoVBSLIwNUPSIsced5zfxUB7oKyhXvkdyso3ZaX9oA0++s/RbsiQwe6xRx9JmV0wYmEn4MGuCNo3caVrkMg8ExaIeK60FgPj4yCNaiLT99xrL39vvdpAUY0ZkKeMN1NFHi+Slj6LC9mahsoFwUoaSK9Q9zyDUY+LRYYedHAn7wHNOBqMNHkmYJOhXSVBTziEiX5zj75HeJ5dDdnPGJELYxxkl05GRln15dU+Pg76i18YDVGSDosFSGbQF+doQXNvaVuzmEQ+ovVNWQlPvZEO9xkvkJX6Q4cLPq0Fhx91qGEq4/mZWrDrqrYxfvw4Sduc7NMLB0SGNhbtT2Fs55sdQXjUf6NFodclHzJaEj/Emag/Me5AHIfxknyTX+ouUfj4fIfy/v777+4J7VxaIFkQpFdatmzp4ySvfAgXHeMCPuSLtIbr/e3jeOJx/55Mlt/49O1vQ8AQMAQMAUPAEDAEDAFDwBAwBOIRMAI6HpFt9G8mmui93nD9ddKcnOz23X8/V69uPXn8VnQQouxVZpKMx+ByEU+QzyPk+fzCc89JomFivlCBGAkH3hERhAjE2Gsvv5zWZDpZ4kyGIY3+7+KL3UNdHtHkuoWrVrWaqyAdZMgZJtiQF3g5zpI8BocDxk/ew0QdAvaeu+5ye++zjw4jO8XrwlarVtWTIZBLpEV8GMQc5O+8ef/ooLcR3lMSIiNYfBrhOt/oUg8dPNjVE1EMQSLYPWeUigCOPp/oN7qc58vD9dJLL3N7dejgPdo4QArSGMIUI++kAQkC+f+HiIknn3rSTZaXHJaKWKD+B8pDcK3yi0GATZg4wXtU+wtp/APhTXtaKc/sVZJ8oa398888N3XylGx1kkZ02YKsX79OhM5o9422tSNRsE7lhUCjnNRVvIV6nzTpL+9Z+sEH77tL/u//5F26k9fRzhB5jcd8lHBGA5mFHDDEc/59bcd/682NpF18Gvn9mwM6aSvgTTuBsFyga2CZjkXbIdv9kcO5THq5u8mLFiKSRRYIUEgnDFKO/r9CnwVKA2LzQ+Hy6SefeM/oVG0k5IfFpsFDv/FtzFPO+gdddDyrN5WB2xOPPyZi8Xd3mnTua9ep7ceDipKbQHKDMoMNeUJuaNnSZR7TkdLMfVcSOrTTVMaztAE05NVxfFzsKhkreR8I0XSNcZY6mf+P6lNxYhCwSPlEDWL37HPOdbfdfrsnCyEiqaup06a6H77/wf30049uksYfxjfqKGr//rtebbikJDdqSte3tXaLHOgP0AxhIB8bNmrkGjZsFC75fv3999/7OiQd8ka+/p70dyxM/A8OvAz9jjww5uZWL3j27Fl+seOvGn/5clJPxDtr5qz45Pzf0fb9i3aDXHTB+e5WYYROM7r2tG/IYcYBxhvGW+qbRS8WY0jvs08/8ws01Cf5jsYZn2i4x1iKFMfXX33lHnzoYa8fnkF60tkvX76CJ84DYcyYgRwH76nJ0lru3ett7229Tp7RqdKjzD8O+1HttpR/h9H3kayarsVSypGOkV/SAMNrrrrSL2CwE6Jhg4bKq3BRu+IdQR2TX+Jl5xDtkh0i0zhwVO9/xlQsVX7TyY+FMQQMAUPAEDAEDAFDwBAwBAyB/zYCzFYzZ75bAQ5NmungoKrV3bQpk9xMTY7MEiNw6223u/POP99PwJlUMsGEnNip1Q5ZJthtd97ZHXjQQZ5w+1cewxxCBDk9fvwEHXr1ode6TZxC7q5+qm3L6DRDgDKJZbILYXBop4NzF1EaodvIC7hDxw6uFpIKSm+6SDS81f4c/WdMAzeNaDxhsc9++4mQbCWyrq4nIldIxgS6+G+RlniGfvftt+lEFQuzqSbwrVq1cm13bucaNW7kPXo5YItFgAkT5LErkvYHkUvp2qbKc7r52RTh2ks7tlnTpq5Bo8ZehqO0FiCWaefAdOnwTtDBXRxOyPb2wrSccM/pfk55wxuydds2Xgcbr2UWhfC2nCqSbJLKhtzO0iVLc4pmi70fjw+e7SwuccBqAxFwkLhzRPROmz7VjRzxq/tVC0lr1mTuSMhvoeLTzkt80TjQrv/2h2F+IYK4GD/xML755pvcG6++mqvoGeN/+mWEr+tAekPSdunysLv7zjtzjCuarxA40bVwb3N+835D65gDB9G6XiTSebr+v2Hy35MktfG9J3MLKn8Q3hzu126X9lq83N6T3nPmqH3p/cNY0V/a5CtXZnqeF1SaeY2Hxdnd99jDL7Ky+FCuXHlJhpT00iR/Ka/j9L78Q4sxSGSZGQKGgCFgCBgChoAhYAgYAobA5kGgRq3arn6jJm6RnFnGjxm1eTJRwKkWL+D4LLqtCIFfdfAUn8K0//3vSld/uwaeMCEdyHAmtoMHDyqUZPFI5pNfwzNwgOQ9+BSUBQ+6goovWTwQpHwKwjZVngsirwUVB56bufXeLKi0Qzw54Z7T/RBPsu/fRDDx2VYtHh92dOC1yqewLT7tvKQX4oAcRtsYvV484TE8otGnZldCbg3iHW9pNPkZi0kHQruoFqnSsZCvaNhE16L3N9fvTfF+C2VjcRLpFj5buuH5z4GdfMwMAUPAEDAEDAFDwBAwBAwBQ8AQ2FQIpDfr3FS5sXS2OQSOO+EEV6NmDbdOhC7GoW94WD14//3bXFmtQIaAIWAIFCQCSCXs1LpNTP6HuPFWR9M7N3If0TzVqlXLk86BOJZSvP8vGsZ+GwKGgCFgCBgChoAhYAgYAoaAIWAIGAIFiYAR0AWJpsWVBYEnunVzbPGF6OCDx928ufO8Lm+WgPaHIWAIGAKGQDYEkLcoXjzrwYboK++z3/7+0EweIEw6xvh79DHHuCpVqsSe4dk1q9d4SZJ04rAwhoAhYAgYAoaAIWAIGAKGgCFgCBgChkBeEDACOi+o2TMpEUBr9cWeL7ujjjzKoZ8bDu/jALAR0n5+7tlnUz5vNw0BQ8AQMASc+2fePNf/q6+9x3LAAwmFPaThe+lll3kSOngyh/uJvtF+vuHGm9yN+gTpDcLxe8aMGW7mjJmJHrNrhoAhYAgYAoaAIWAIGAKGgCFgCBgChkCBIGAa0AUC4383Ejzozj7nHLdXhw46ZGmlCOfSrmGjhjrsq7V0S4uJfM7ULS0lInra1Glu0KCBOuhsyn8XMCu5IWAIGAJpIrBixQqv1V2qdOmYlzKEMwt7++9/gKtRo4b7/fff3axZs/xBs4sWLvSHvXKgZKVKlVy16tVdzRo1ddhkY9e6TRtXp04dt0oe1MEqKszLPXu6Dz8ofG3skKZ9GwKGgCFgCBgChoAhYAgYAoaAIWAI/PcQMAL6v1fnBVpiSI7DDj/cnXTiiW75ylWS2nBuzdo1jm3igXwuXry4J08+EMnRt0+fAk3fIjMEDAFDYFtGYO7cOe7jfv3cIYcc4sdRdpRwmGD58uXdvvvu5zp23NvNnjPbLZi/wC1dutStYiFQBxWWL1/OQTBXrVrNZehvyOxAPuP5jL70d99+6/r0ec9xSCOLiel4ZJqTqAAAQABJREFUU2/LWFvZDAFDwBAwBAwBQ8AQMAQMAUPAEDAECgcBI6ALB9fNGitEAp9NYZAYkM5Lli13y5Yty5IkecDzmS3jH370oXvppRf9dm8jOrLAZH8YAoaAIZAUgSVLlrhHu3RxpUqWdHvvu48rUaKEH1PXrVvnvZ0ZT6uJZK5RvYaX6gjjK0Q1H8IRB1a0aFFXUvEsXLTI9e/f3/XUmPzbyJH+npHPHgb7xxAwBAwBQ8AQMAQMAUPAEDAEDAFDoBAQMAK6EEDd3FFCJODhxrbtdWvX+t8lShRSVSstDsmC1IBohvzQPw5Wmr/HjPlThw7+4R5+8AE3ceJE87Lb3I3D0jcEDIGtCoG1GsN//nm4u+uuO91111/v2u68s6terbpf3GOsh2Dmm3DxxnjMuwDimTDLly93o0ePdsOH/+Tuv/det1CSHWaGgCFgCBgChoAhYAgYAoaAIWAIGAKGQGEjUEisZGFn2+JPhcCUKZNFMoxy1eURBwFdROTDrJmFc8jUam0FnzVzlpsiXWc0oCFB+EA+s637kS4Pu2+GDvXZDZ55qfJu9wwBQ8AQMASyI4Cn8llnnOHOu+ACd/TRx7jatWt7ErqM5DWQOYJk5hPGWYjpINeB/MYSyXP8NXGC96YeNWpU9gTsiiFgCBgChoAhYAgYAoaAIWAIGAKGgCFQSAig0yABha3DmjRr4apUre6mTZnkZk6ftnVk+j+Qy7Llyrntt9/eVZAcx/SpU9306dPdKhHQZoaAIWAIGAKFh0CLli39YYQcLsj4W75Ceb/zBcJ50cJF8nBe4CaMH++1nidPnlx4GbGYDQFDwBAwBAwBQ8AQMAQMAUPAEDAECgyBGrVqu/qNmrhFCxa48WO2DQci84AusObx341omTzrgo4oKLDV28wQMAQMAUOgcBEYO2aMGzd2bKb0UZKkGI9tTE4Cjl02BAwBQ8AQMAQMAUPAEDAEDAFDwBDYJAgYAb1JYN72EzGCY9uvYyuhIWAIbFkIGLm8ZdWH5cYQMAQMAUPAEDAEDAFDwBAwBAwBQyAxAkUTX7arhoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGQP4QMAI6f/jZ04aAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgCSRAwAjoJMHbZEDAEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQyB/CBgBnT/87GlDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMgSQIGAGdBBi7bAgYAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCGQPwSMgM4ffva0IWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChkASBIyATgKMXTYEDAFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQyB8CRkDnDz972hAwBAwBQ8AQMAQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMAUMgCQJGQCcBxi4bAoaAIWAIGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCOQPASOg84efPW0IGAKGgCFgCBgChoAhYAgYAoaAIWAIGAKGgCFgCBgChoAhkAQBI6CTAGOXDQFDIHcIFC1a1DVo2NDVrVfPFStePNvDRYoUyXbNLhgCBYlA/fr1XaNGjVzxYsVi0f4X291/scyxCrcfhoAhYAgYAoaAIWAIGAKGgCFgCBgCWxwC2VmiLS6LliFDwBDYUhE49LDDXJu2bV3ZjAxXoWJFV6VKFbd+3Xq3aPFit2jhQvfqa6+6v//6y61bt879+++/btddd3WHH3mkCMLi7l/+07W5c+a6V1952S1ZsmRLLeZWn68aNWq4YsJ85swZW31ZIFdpN1jLHXZwxxx7rMtQ+ytZoqSrXae2K1qkqJu/YL5bvWq16/fRR27IkMFbfZlzWwDw2X///d0ee+7lypYr6/tkkaJF3EL1ya6PPJLb6Cy8IWAIGAKGgCFgCBgChoAhYAgYAoaAIZAvBIyAzhd89rAh8N9DAAKwevXq7oADD3QXXHiRa92mtStXrpxIQeeJZvyci8kDdf369e67779zUydP9tdBahcR0DffcosIMcjn9W69HvpLBHXfPu8ZAV0ITal169buwIMOdrVr13bF5ZU+evQoN+yHYe7PP0e7tWvXFkKKhR8l5CqE+p577eWOP+EEd/gRR7gyZTJEPBfZsNCh9le8mMsoVdLNmzf3P0lAUwt777Ov+79LL3WVtShEXdMnp0+fbgR04TdRS8EQMAQMAUPAEDAEDAFDwBAwBAwBQyAOASOg4wCxPw0BQyA1AhBZEM9XXnWVK1mypFu9erW8nRdleQiSGq9nSMGoHAC/16xZ65YtXerDQyauEzmW6c+aJQr7I58INGrU2F1x5VXuvPPOdStWrnKsEOAF27dPX3ft1Ve5OXPm5DOFzff40ccc4666+hrXpEkTt2jRIrdEHvfxVrRyJbW1NfGX/zN/s7izYsUKV0z40BdZgFipv80MAUPAEDAEDAFDwBAwBAwBQ8AQMAQMgU2NgGlAb2rEN2N6ZcqU8VvV0eo1MwTyggBtp02bNu6a667zj69cudJ7OkMsQ0yXKFHCE11884mSzzwA4fyvPKNjv/lbH7OCR+CoY452B8pLff78BZ6gReJk8aLF7vjjj3fNm7fIVjcFn4PCiXEveT6fcsqprqG0nhcuWBhrP0Xj2l/x4iXcf3qsi+tXvu/FXSucGrJYDQFDwBAwBAwBQ8AQMAQMAUPAEDAEDIGsCJgHdFY8tqm/IARLly7tCcHSIp/33ntv6aKucgMHDjS5g22qpjddYThgsOvjT7g18nqOGh6WS+XVvGz5ck8IcggchBcEtRHMUaQ23e+6deq6WrVqeQ/haKp4xSKFMmrUHyKn50dvbRW/L7viCteufXu3FM3wyLmWeNUvV/tbq7ZYTAsllHPZsmVbRZksk4aAIWAIGAKGgCFgCBgChoAhYAgYAobAtoyAEdDbcO02b97cnXv+BZ54btCggfcG/Pnnn92IESOMgN6G670wi4YXfWt5QK8SsRwMT2d0nB99pIt7p3fvcNmx6EE4I6BjkGzSH+vXr/Pe6fGJ4pU+ceKErZKcbaYxrWbNWn4sC+2KhTYO1+v+1FOue/dusTKXKlXK2l585dvfhoAhYAgYAoaAIWAIGAKGgCFgCBgChsBmQMAI6M0A+qZKsl37XdzFF18iz9Qlfru9J2xsC/amgn+bTKe8DhuMyhpAZq6Wzm63p57MQj5TeNOb3bxNYJoOnJs1e5arVHGjFjL1tVCawL+NHOlWaTfE1mZtd97ZVaxYMXaoJeTzosWL3IcffuB69OgeI58p19ZYvq2tPiy/hoAhYAgYAoaAIWAIGAKGgCFgCBgChkA6CJgYcDoobaVhihdHgqNUzFsQAtrUdrfSytwCsl2xUkW36267ufWSOAiG9/PwH390Y/4cEy7Z9xaCwAvPPee6PPSw14CuUKGiK1++vFuwcIG7+qor3cyZM7eQXOYuGy1atPTlWL9BR5z2N2P6DPfcs8/GSOncxWihDQFDwBAwBAwBQ8AQMAQMAUPAEDAEDAFDoLARMA/owkZ4M8YP4QxRE7aqb8asWNLbAAIZZco6NKCj7QkPVOQ3/vnnn22ghNtWEVZLp/ud3r3cL7/87JBOUcW55dJFHvXHH1utd3DValVdyZIlY20Qb3y0nyeMH79tVZ6VxhAwBAwBQ8AQMAQMAUPAEDAEDAFDwBDYhhAwAnobqkwriiFQmAgULVrElSheIkb+kRaSDgsWLNDhb3bYW2Fin5e4vdyGtJGH//RTXh7fIp/hcEvKFbV10ro2MwQMAUPAEDAEDAFDwBAwBAwBQ8AQMAQMgS0XAZPg2HLrJt85wwMynqxBPmH58uX5jtsi2LIRiK/3dHNbNI7ciz5Hu4lvU6QD+bxkyZJo0M3yO69l3iyZtUTzhMAa6Y1HPfCJZN0GOY5kEW7V7SJFf0xWXrueGoHCbg+FHX/q0m3eu3ktezHJhZkZAoaAIWAIGAKGgCFgCBgChsC2jYB5QG8j9ZuRkeFa7bijK1kic3v60mVLHXqpEDZRq6ADvDruvbebMWOG92blXhF5tnJg15QpU9yc2bOjwRP+3m677Vz9+g0cmsBIMJQuXdqRPmkt0gFna9eucytXrtDhh0vdryNGpK3NWrNmTVe3bj1XJqOMJ5nWr1sv/dp/3Lhx42L5qFOnjtu+aVNXoUKFzLQlLVC6VCmFm6/014ogXeXGjR3rpk2bFnsmNz/Kli3rmjVv7qpXr+5KlSwlcJw/9KxYseJugdKQoIlbt3atx2vihAlu8uTJuYk+W9gddtjB1alb15UqVVqLBc4fGIeswOIli4XjWo/d4sWL3ejRo3362SJIcgGSrq7ibdSosVv/73ofap0WH/CG5RtDlqFFy5YOTEuo3VSsUB6XZvfBBx+4RfKcrV6jhtuu3na+PiCeCdewUaMsB70RF2nsu99+bt68ea64cPKmsiD/8uOwYVnCZ97M/7+VKlVW+27uqlStKo3zYmoLRV21atUcWNGWISVX65t2MF7tByxTGe2pWbPmrmSpkpKqUEjlf9XKVW7s2DG+Had6lnu0ydq1a6ttCFs9C/4rJHcx8tdfsxGmieJqv8suvh/9u/5f3x9XLF/hpusQwdk6RDCvRh5qKU/bN9k+1ga49tfEiW7u3Llp1UvDhg3ddvXru/L0N7VLxpcKFSv4si1ftty3JTyQiW/Mn3+6ZcsKzhOeOtl+++1daS8f4tyatWu8BAxkFeXAaH8cssjhhBllMjZCpTqgzif//bcwTD2mlSlT2jVV3VN/xYsX9+MK46QS8XW/VuPKWqUzT2UcN36cW6wxLl2DkGvduo3LKJvhFwNpq8QzefLfHkPioXy77bqbKyeN7pIlS7iqVasJzznuJ2mrF7ZWd2316aYbxlPKXrp0GZ8HdjWs0/i7VAtLv/46wverdMucKBzvhxYtW2hcraGxpoQrprS4xtjNuEF9Ul/U1ehRowpEIoZ0mjZr5sfBkhrLaTe8qzhIlTRpO7xj/vlnnhszZox/dyXKe6JrYFW/QQPHO4s65sMCHe+D+RvkiJq3aKGxsZEvL2Mt5V26ZKlbuWqlb1eMS/TxRFZDYy/Pc+Am5SinPK/UeMSYwjtu1qxZbqzynJ+DNhnLeZejDU+7zNiQx2VaUCQd3ucrV6zUoaULfZ3E/79EonxTj+S9cZMmscNquYZEDjJNQbud+81UN7x36H/0t5+HD3d//P57tv9nIR3w3qFVKx83dYiBDe8b8rty5Upfl6uEzbSp0/y47QPZP4aAIWAIGAKGgCFgCBgChoAhsMUgYAT0FlMVec8IJHC79u3dPffep0lZJU2s1/qJHgROPCHUQITSHXfd7SBVNGf2xuSOyeGbb7zhXnm5Z9KMMOGDsDzu+BPcwQcf7CeZfjKoCSaTTCbhTDCXioRiEj5d5F+3bk+5Eb/84onAMPlMlsCBBx3szjjzTE+a4anN5PrHH4e5q6+80kEMQ4Rx/9jjjncNVQ5IR8hC0ob0WybSDuK0z3vvuvf79vXkHxPpdIwDGynbrrvt7k466WTXpm3bTOJZpFvIdxH/W+Q6k3Kl86GI2o8+/NCNFykFAQdJm45BKFAP9aSnfNFFF/sFgUqVK2tBoDicl2wDliKOVygtyKrXX33Vff/995lEidJOxw4/4kj3v6uuUn5X+Lphon7iCSe4uSJ5atWq5Q448CB35tlnuw4dOmQSbyIhFi9e5EaOHOkXDo444gh38imnupoKu0ZlK6WJf1URvlEylzo6SG1h9z328CTdhibl04MwPPH443VIXGKSJZ0yxIeB3CAPB3c6xJ1yyimuhQj8UiKxIEchnYMHN4QhxMnQwYPde+++68sEGRnNezTuZs1buEcefdSTgP8qHtoyCyj/u+Jy9/tvv0WDZvsNOfR//3epO/Sww3x/41naJORxZ+ENOZLKypev4O574AFXs0ZNnz/aBwtEb7/5pnvjjddTPZrjPfrpDTfd7NsAgSHdnn/uWde7V69sY0M0MshY2ugpp57q20l99T0ONIUgz+xvIt30AG1+5arVwmike+vNN9zQIUO8JAsEX34NAu6Bhx5ylbXYQB8kXQhT8Al9kvQh+Z59/oVY3ZMuizgQZo8/1lU62L0TZoV6Y6GJBbkTO3dWG97TlRVJyHjoy6inqEswW6E6/E39grbU/+uv3Jw5c/wYkDDiyEWev+2OO1wDkZX8ZrwcOnSI696tmyf1mohg32PPPd1NqqPttKhXSgQ0n+E//+IeeuhB1/e99yKx5fOn0g8GGbrddvXd6Wee4cdzMIyOp+R1lbCdOnWqe7pHdzd40CA3ReQqfSI3BrneRGRje72fTj/jDNe6TVtPeNJfMXBmXKVfMk4N/3m4e+2VV9zPP//sZotkZUEzt0b7gBxu23Zn1/mkzr5+eS8i34KtV5qkzxhB+0ETvVevt92Ar7928/Temqu6zckgbS9Rn9933319WyuquMnvw6ozsOp0yKG+vIcffrgrW66s+krmmACuDPEs9lK3PV960Wvoh/bsiW31u1NPPc2dfPLJfgHGPwNOepY8L9Ei2/CfhrtXXunpvvj885T9OFE5GEPpR+edf4Hbb//9tZhM3xapqzRC36bNo63O/xeg8c//FwzRWBolkRPFzbW9OnR0N996ayYBrTgp21NPPuHeeecdV1Zj9Y477uTOOudsd+KJnbUwU9bXxWr11ddfe9XdesstbqEWP4KFumzdpo07S++qdu3a+/GfugyYgQu/aa+8l8nniy8872ZqDKX9pvteDmnatyFgCBgChoAhYAgYAoaAIWAIFA4CRkAXDq6bNFYI6P0POMBP9CFqw8SMyWT4HTKEx9l2Ij6jBlkDqbfb7rsnJaDr1q3nTjv9dHf9jTf6iTyEwSoRBpAG8caEsEqVKt4j9c23e4ukfd8TLsN++MGTOfHhw98QFa3k5QQxRL4hFJlUQpZAet91993e4wxPMybh8Ua6eLdddtnlDjL7iccfE6n+uifN4sNG/6b8++yzr3vkscdc0+2bZnrQagKezNORdMjjOeee6y646CL36SefuCefeNx9/9130WiT/u7QcW937333aTLdznuagSWT/URGWngh33X3PZ44efD++91bb73pyf1E4cM1CJaGIjKaybsREocyQsbXFfGwXGl1ebSrgxwh/pA27QgpDcgHrIOIuTaa+HPoG/VBewqfkA5/s9BRqVKlcMl/Ey/xQDz9IzIyP556IWLawdXXXudOO+003169JIgI8FVJCN4S8o47RETQkUcd7f6Ud+71117jPcB5Lt4glFqKzAY3yoSx4FKnTt0cCehDDj3M7bnXXn5BIZQTvPEYhwjD0zHEGZ8uhNORRx2lemrmMQQzrpVRWfGMz4+RhwYN1AbkacjCTKgTFgvwco9fnAppQVDdfMut7qRTTpaHamlfdyuEGZ9ERry0E+KFhIOsevjhh/2iRaLw6V6rBjmsvhLt66EdhjjAlQWIxiJQ462yFnUg1xIZnr7HaXHgSi3QtGy5gy8b/TAZwUoZW7du7XbbbTc3WwRlNxFqr4oohfBKZTzHmAam5J28QsDhdQyeXTXmHHDAgb5vrsDzVBATZunSJfnGL1u+NrRr3hHHHHusu+uee/1CFPmIYhx9robq4FGNFRMmjHddu3b15HD0fqrf7FLY/8ADVMbH/fuARSzad7K0wGqX9rtoLN7HTf57suvevZt7/tlnky4aJUqbMWI3tcNHlOfmavcsQvDBkzuRkWbz5s3dQ2qvYRH2/nvvzVGmCo9mFi4aaowlDvoadcwi6akan3o8/YxPDvJz0cLsJHpljZdX/O9/7jAt8l1w3rnuFxHuxMM48vAjj/r+xLiciIAnrb332VuLzu1E7D7pF1nS8U4mQyw6/N+ll7oLL744k4TP4T3OrhK8vCGqWch5WnXyu7yUU5G61atXcztpNxZ9iTLR7ndVv/n8s8/8AvKlej+zwMU4zDuWMPQ9DkiNHyc7dOzoF2f23ncf9Y0VPlyq9sMC0lEaT0848UQ3QpjeccftbtDAgYmq3q4ZAoaAIWAIGAKGgCFgCBgChsAmRsA0oDcx4IWVHBM4JvdM9vgOv+PTY4IX7ofv8AxxJLIm2sJ/w003uTvuvDMmP8GzmTRd5hPRiSO/iZP4lsij9uCDO7k+fd93519wQaLoY9fYyh/KQfxrRRxAivLcvSIFIDqZ1BJ3IgvpQqI2FPF35113uetvuDFR0CzXjj76GNfrnXddvbr1PClHHqLlyRJYf4R0IBshCQ6T5+ttt9/uFwHiw8b/feY557jX5GkO6YFcBMRBTmmBBeQxROvt8qaELEFyIJVRN+uFZ6hj/61ygV1PeVPvJ8kMrqUiEoL0QIiDZxPllWshTPw3ciwFYaVFLLyrNnSO8MNbLxDlifIT0uMe5aOOGokoAvdzzzvfS4+EMOGbbfi/yFM/WhYwBydIm1QGyY5HOe0hlD+0odNOO90vViR7HrK50yGHeK/e0PZp82P+HOMG9B+Q7LG0rlMW3wZU7yFffJOOCpowDki0l15+WZ6jJymM8+0uWX8LEZAOcULy0UcvlFf/U091C7fz/I0nOv0jmnfSirdonUXDkqdEeYfweuDBB909WtRpIK9jSLB0+qEvo9oSi1w33HiTe7Jbd1/e+PzE/x3NE79XiGVuLvmYa6+/XmTrfn7MSZTP+Hjy+zdp0HcgIB986GFJl1T0fSNV2txjnKpbt567+eZb3NXXXJtWNiAtr7r6avfCiy9K2qF0jOBPVH8hwtCOFi9a7Bcvb7v9DveEME7XIJ/x6n31tddUr/U9rvT/nNKkTpDGKKNFifM0PvR+r49jvEllPq9xbRPZkiuvvEqLi/f79sR4kCxtcOVdVk+LTK+/+ZaXCekosvWp7t09cU6bJF+JjDjZVYF38LXXXed3PiUKF38NmaCujz/uLhL5zLs1jFfRHhXNL7/JJ32Dvn3cccf5vF562WXxUWf5e712SYS+F9o+aV1w4YXurLPO9nXL4lc0LXVJ+YhnNXYlPC6CHfKaNpFOHyW/1Dn5RbKjW/ceWrw+PmvE9pchYAgYAoaAIWAIGAKGgCFgCGwWBIyA3iywF3yieEVBZqGtyTcfriUyCK4QJvrN9XjDGw+PrnNE/MV7TDIBJj2uI0GBNyDkDtejxmQUL9qzzznXdda24nSNCSpeqBA1bOVmMkv85JP4wof0uB41Jqs1JGmAl3HFOO/caDgmp3fKs5rnmbwGA7sS2gqPF/ZiTWaXiCxgok5a8bjiybXnnnu5/0kqhMlyMrv8f1e6Bx54UFvsS2YjF0L9USYw99iqnPHlIq0jjzzKXX31tfLYbZUsqWzXwbK48g751F7bmEkjWl7SIQ9gG9JM1E7iy05C/rlIu4u2qaLSF8+vEd+XX33t2srLNr6e+Jt8ghdlAj/Cx+eTtoM3701aSDnp5FO8pEs0X9O0VfuLzz7N0nZpQ3tJnqRRo4bRoNl+N2jYwHsvR/EkEPnCSxLpkmRGPvGsJf/heX6PHzfGDR/+Y7LHCuU65PNll1/hdpUeMRYIIjAGU8oD8bVA/ZydCcVLZF4L7YVnPM4q78GdOnnP1+g97ufGihRhTCuRZaxKFF/IX7Td+d/KX3w74Dok37Ei09j+z9gUjHhCWyqptpSsH1JPaOYeeOCBrsczz7gaNWuEKHL85lk8kPfddz8vQbBKesBRIw/kmfiRpihIoz5J+wqNU/ST6HhKm+Ma32AQjzN9AW/YM886048hqfJFO2Kh57LLL5cXNwtsG0NnwVjpRdPcGCqzHSGnc6w8td94++3orYS/y2pRoLOkk25U/0a7n7JFDUxpS6SXql7JXzst7n3+xZfZ2k40vvjf1Gs17SJCdz/sQiIu8AzjEr/j2yP5LKc6gWh9qsfTroY0ssGaZ2mr5Dd8qJeokSZx77jTjpI2aRO9le03msuXX3GFvO0P8PGHACGPxM25EXj3875DUoT0o6M3JDKey4cffoRrv0v7EEXK7zCGoDXN4kBd7b6KLnqSPh/aO9iE9Pbeex93xhln+gWi+PDgQbzkk886SVXxro7HFhzJ73XX3yCJHS2omRkChoAhYAgYAoaAIWAIGAKGwGZFwCQ4Niv8BZM4JAp6kgvmL/AebkxMIYrYznvMMcd4L8aQEkTq22+95QnjoInJAXvzF8x3H3/ycQgW+z5VshsnS2uXNMJkMhAUN998kxs4YID3HtMc0hO0ZUQ+IeXx2BNPek3jQAQwGWQrOhPL96QFGeKKJRT3g/tMgCE9yCd/4+H299+T3GfayvvJxx/rsMFxmuxneG/gayTNgFcxZeeDcQgdmpFXX3ONu0uew/HGxLdVqx39AXLRLdoQhmzb7frII37rOeWFQ0GeYfvtm7pb5e0MsU2ZQjko5847t/PEFoeHxdthkrs49thjPNkQ1QRm0gy5/plkPAYIy2E/fO81dJu3aOkOOfRQ6Ssf5OrLA3eVdHZBmPRI97DDD3PTZ053t0gSJR3jOcqBJAXbx8GI8kNgrJVm+JzZc/yBZ3/qsMPJ0ifFkFJgazi4kyaSBujV7qID80K9QqoM1+FRP0heBakN0sCImzR+1KGHUQLB38zFP0idXHPttV5iwdeDyhEM3NBrRZf3B+ljc1gaB7l1kAbpEUce6beolytbznv68QwYQCziRf7NN9+4iZIVCMYhlkOHDPX5DtfQIcdrsKpkCJIZ+LFIEp830gIDDkGj3SQzwlWrWs2TJ+BFe4BUmR/RQU32bEFfx2sVndWoUb+MDa/IK/qdDbrRlMt/lFe8IdGrxfM51DNl4u/9RdDyO682evQod+P113rikHhocxDHmYeXlfBxkz8OfntJnrYQU8HIH4sfg6THG4zxhLHpsMOkyyvSL4wT3Kce8arvLx1gNGQHDx7k09tDC0vID+yvD5IqG+VbMscndncgE4IMT7RfhzTjvxlHOcCV8pDH8E2fXLp0mTSI57hZM2dJ2/cL9+svI+Ifz/ffpAlBS7qkOW36NPet+sJnn37qD5Fs2LixxohDvO53HZF3YE5YjN9IuhwmAhLP5rVahEhk7Xfd1ZPc4bkQBu9rtMHpe599+okfN9SSNKbs4d9VJ0gTGB18xhqM51msa6+xlnb2dI8eIaps39TN7dqhQxsI9UqukZyiXocP/8nXEWWlDjn0k7Hs+BNO9O+YICVFmrSTJsLhlttuc49LdiR+4TVb4hsugC1GH4bA5V31iHarMDZSpp1FbCNts5MWnIKcDenRhnfffQ//zfOMt5OkV99bxHu/jz70mHFIH4Tsxf/3fwDj64KwkMJoXV988SXuskt1L85CG+Ng3VPUT8O4TTDqg8Wke+660335xRf+HUfcGO9AJJpuue12j2GoE/r4jsr/VVoAPfP003zYnP4hDyzQkl6w0FcXLFzgD56cOGGi6/dhP9XNCh/kIC1g7anFv5Cux1bxTJw4wd2rMyw4lJd7XOf9haTNVVdf4zrpuY19NPMg0h0lB8Jhv2aGgCFgCBgChoAhYAgYAoaAIbB5ETACevPiXyCpM+Eer1PmZ86cmek1pzkkh8kxOTtJW+mjB/FNFVnz7ju93aS/JsUIGwXzBDNbraMGmcfEGB1VJnXER1qTJk1y11x9lT/kL5FmKvmAFMLTEFkLJuRMtJn8QuTgKfzkE09Ek0r6O5DPEEYff9zP9RTxMWLECO9tHSbTHNiGxi8ed3hnQVpyD7IHAhuyOJHtprLtrHsQjRjl4zkm/V11IB2HjsUbac353xx/eODx0pBlUh3SgqBFriSRobnaunWbGElHGNJbKQLhkosv8of+oUEa6gAMSb+3Dse6UDrTxx13vMce/EkPwuwQHcSHvvDLL72UKMmE1wLxlulF5twbb77hD7tji/PqNavdcnmzB+3rn0Usc0AX5CrEA8QZhyWig0seMMgTwr2leDj0CS9Db3AxqvOF2kpO3efV0FQ9U9u2owQvuFF+SLOHJaUwa9ZMtYdFImMyvUnxZubewYd08lvq2+pASUio0H7RJ4eEvu+eu7XAMCGWtcVLFnsPwApq9xiHlaHVyqJKMmNhAU972low0gllzhDJh9ffbB38GG+UgQMc8SQO4SnnxIkT1T//ig9e6H/Xk5ditWrVRYRm6uV6MlzjyMM6CLCXFq0SEXEQdBD3N958s9tZODNOhLKAHd76X3zxeYxIyk0hOMT0dckpeE9gNaE1ap87tWntGosczGy/mWThnDmz3QvPP59V6mRD+4uSUZB492sHAuNDyCPfkOU/atEIzXjaMn2Q9oJBmEJI9+3znu+HRx9zrBb65vu2xLOQlRCVE9WOOLwzJ+OZQL7Rl3me9vKQ2vGggQP84gN9DTmH6GFsOcWbm/vkAQz69ftIh+C95P7443eltdAT6Bw4N1Lj68s9e0pm5EavT00fp33zHHluqcNabxMxeZf0deMNzV7IYrR4o+8d0mOBjcPhhmtRCm3jUDf0XxYK3lIb69LlER8/5CLpMc5UrlzFjwEsnIJLvEE+sihYRWMThCzGsxzu+cuIn30Zv/7qKz+uhXqdM3eO+06a/b1E8t6sg+8OPvgQP36EMlIvyEWwuDVG75Z0jT7DQYEDvvzC3aE8oYkeyskCHfrJd4lAZVE35IW4Q3uGfP7oo4+8vviPw36IaUDzPuiuA31/0qG8D2thlDGHdkJ90H4ZJxMZ5WHh9yR5ADMWhT5M+T7VGMkhiN9+863qPpP4jcbBocSQ509Lh7tp02Z+QZf0Sqo9MKaepDKwKJWOsdhBXjD6IYfDvvDCC27smD/9LiMIeQ72XL16lV9wrldPnuTCYuO4vc7/f8clkg9hkTQ63hInC5HswhqoPnSn8EW+h/T4MH7suNNOXuv9zz9HE9zMEDAEDAFDwBAwBAwBQ8AQMAQ2AwJGQG8G0AsjSSZk8QdiQSTFb+OGFGAivEzbbcU1pjQm4HvJizpM9pi0ksaNN1zvveaSPYwnIB6pt996q+smr7UqIhAgFJgwsxV3jz32dE+69AhoP4EUQfPdt9+6Ht26uW/1HW+kx6S0i4iydjrEqpkmuIEgxRMN8oMJPulHrVmzpl4rlLxhEEGU9TGRaonIZ8IwAR89apQ/+AlvyuCNCUlTVlqntaUFDBkwdYMXMc9wyFybNm19HgIpA9EI0XXF5ZfJ2/EzxZuVpCVPs2fP8h/CQWwcpIMVg/cyZWnQsKHXD84NAU3+qcdp06a6V6UFzcFSELaJDDInEDrcRyfZe+4Jp2BgtkTtjMl/lFAJ9/PzXV2exydJsqVq1apZ8gGJDhn14AP3e1IiPg3w4vPWm2/6QzIv+b9LPQkT6hnsjjjyCPf8c89mIaAhivBeP+igg2JkCXjtJPICWQEIknjj8M9q1arG2hv3Ia4DQrTfTloomCyPRhYYoka7PEIELRgGY0GDPCRq5yFMYXyzUIOn4Dp5EwajnQwcMNB7BQfiKtwL39Q73qytRQzjMQtOlIf+5j07dSDcgAH980RAJxrT6OthTCAPpEW9Qk4vkKd2MqO/tZHnJtrpwduVsBw++ZmkV1gQY4yhvqNGm+ADSQoZ/c8/8+WJekaMyCOPO+zQyrWRF+oojQthrIzGEf+b/GPkaZYIyptvutENGzbMk2jxYQvjbzBjgYYyczBs1OgbkJ187r3nHn+AK7tWymRk7pqgfBw4iqdpFgKaNqxytVIbQss46g3O2EUbeEL6w+wsCeUP6dK2+LDgcLkkgh7q0sV7JzPWEBac6mkR55RTT/VkcnRMIg7014/QYX7R8Z32N/ynH90zzz7jPnz//SzjB8+sXLFSH42vwv8mEe2MFyefcqrXDuY+Rp9AC/0ZvcOo+3SMsQli9w4tSrBQGzXyx3uB+21E4DZs2DDWL0KbXqJFMBaIvxKBHW8sYkFOI2XBAY/UI8/xgVyG2A2Lh9Fn99irg39PhHcP9zjwr4cOFKTNJzMWCdgB8/qrr7mLL7nEy4tQBt6ttIET5bGeLgEdyldS3vfPPv2069nzJZHPYxL2F9oQUiSxd7jaD++WPn36Jj0QlvjHjR3r5muMZVfCHhp3GEsZwzLUdlm0gog3AjpZbdt1Q8AQMAQMAUPAEDAEDAFDoPARSL43vPDTthQKGQEm/pqdZkkFQppJWTq29z77+Ekyk07igiQYOnRI2qfKf/H5537CCGHAZBkjHrRX0zWe45knIIjksZbKpmhy//333/lJOKQFhncz2r8tWrTM9mi5cuV9Xpi8YqQFATXy11+zhY2/gIf3OyIKJsjz/PfffvcSBWyvflbeYlEihOeOEAGNNmggTigPZMAgef1BBMWTz/FpMVF/VF5vSCGEuiPPeIfX1dbzBjpwMTdGGV+U99nT8lBPRj4nio+0yXt8m0JiIuQr0XN5vQYBfeyxx2XBE1ITr+U+8kiNJ3ii6VCXHNrYR9I0veRFXlqLA8HALiOjrBYF2vjt7uH6fJGLfeTxyLN8MOoSXe9khz42b97CoT8LprQ5pDzGySs91v50nYUDvK7jDYLE6y0rrVgbFJbjxo3NsoAR/1xh/E0ZatWqnYWApQzsrOAQx5wMuYCvJV8Bcfnll1+6rl0flQfoba5//69jJFtOcaRzH13gGLuvB+i5oa5SPQ9Jeax2EXD4WjDfRjQ2fSXv2G+GDs1S9hAm+v2rPIPxiIW8i6ZJO0Mqp2XL9Lf5Q5CC1X333uM+7tdvk5LPYNbtqaeykc/RsvKbcafLww9JDmJSFh1zyo53O4SeHw8IrD7FDpAWLVrEJD64jCHx9EyPp71cU2jnmXey/4uMDnImEPNhTKFvkQ7a7fT/qEH4QuaWVX+Oxk3fevvtt9z7ffr4cTdaX9Hn+f2Xdhy837ev33kQ0uQ6fZ+dJ9VSSPAQLhj9hQWZwRrXGZuSpTl40EARzF9mkaQgDtLGC5zF21TGe5BxJjrGlC1X1rXeqXW2x+rovcP4xfgTcGQR4YXnnnM/atEjHXvjjde95zbl4UM8tN+GItBzY0gmvf3Wm1rgfdTvrEm2WFNLC1mUh3Qw0uTdycJvMkxDPlgoeOKxx9xULaoi00EbuEvSLE/p/x/428wQMAQMAUPAEDAEDAFDwBAwBDYfAukxkZsvf1tVyiU0KSsvIic6EU6nAEyqICSDd186zxR2GLy/KlasEJvwMTnGA/TNN97MVdLfffe9J3/xjGTCyaSSbcaNGjeRzMDElHGFye5EhRsoD7p0cP1eHl0dO3T0urx4UIX0Wu7Q0v32W9Yt8hy6hHdjmNQSP5P6Qw89zH0ur+ScDFkCtv4uX7bcfS/t5lkilBJZY5UVb9dAQIMlBMuzzzydKHjCa2wDH/HLL14vGOkGyoXnZ3VJJuAZiExCOgaRM2TIEEl79PLtjbKng2s6cRd0mKpqg40aNcqylR8CCrIIz7xURpkoGyTSN1o0gbSuHSFY8YI9RPX8s+IJRAzb0L/99hvfTgO5Q5tFB7qh8hFveKND7BQXwbZ63WpPjiEFM1T4tpX3KH2afDRvKVJOhFi8cShk3Xp1/XZx7lE3yC7Ee0rHP1cYfyO9Qv+OEYpKhLK3b9/effB+X0+spUr3b3l4v/bqK37xhnb6y4hfspC9qZ7dFPcgETtJUz14VZIm/QjN55zaUjR/kJUQxhyOF/Wox0uYdvn7779Fgyf8Dca0y+HDf/L9MGGgQrhIf6D8vymPPwzL6vmcLDkkI1iQg1gm34w7xAGZeJrOB7j7rrt8WXh+//0P8PrwG72fGVvWuz9G/e6+/S65p2182v3k5Yte8gknnujbYBiX6Yd4+UZln9BTRtc+6t1LPsdp4YRdBNRROmPcT5IFwVOa8wICMUq6jeQ5W0U7MNIxSFn0rSHRMZ5PZJCkY+Wti/RO1Bhzer31dkK5nmg4NPeRdOKAvY3v1LIOnedvvhkaDSoJrd1dS9VdqBOw4D30dI/usXJmeSDBH4u06+kvvYOXLV8m+Y3MAwDBGJI/XSNddl69+OILbvr06Skf4zyCZXqnkgYGjoy1HTp2cJ9rt0JONnjwIP9uXbw4U/v774gnejptIaf47b4hYAgYAoaAIWAIGAKGgCFgCOQNgawzoLzFYU8JAQgmdBH32Xdft0bkQm6sSJGifuvv119/ldKrMzdx5jcsXmUVKlSMTVKZHCO/MUSTu9zYaGkI40FZVB6IGOQFmpV4n6ZDQEMgfKoDB8NkNKe0J4yf4LEsWjTTA5rJK3XD4VnxxsSUyfD222/viQrIFchhtoCvF3GCJyuT5mTSEpDI6GSmMggMFiWY+GJ8g8H06dO8FmqqZ+Pv4c3Ldn8OW4RE8FiKkNldkia5sWef7hHTUk1GkuQmvsIIC7nRUB52gQgmDbCj3JDEeBrmRCaEss0WodHn3fd0SNXVMbIM4qa1yCu29gcCmjRWqe+i843HeqirqlWqOj5R496+++3nF1NIh7/XrFnrFznYPn/vfffFgnNIITIiUaM9I6HCIWuBHKLtQWDmRNBE4ymo3+DJAg0EfyDz6HsH60C6X0Qoo4GMTAHkWSBe49PGczMn7834ZzbV3+yCqKc6jZKXEIbvi1xHkzhd42C5l3u+5E6Q/nvAgXGDAxwrSHM4HQPjMdK+5TDVTWm0ORbc3nj99agTeY5Z4OC+XXSwIAe50f9o72DHuBMdl1tIG7pho8YxXDgEctWqtZJweDXtxQj60aRJ0qEe+as7WiQrf4d+jPZw4yZNdGDq7Nh7qV697VwrSeQE0pjCMGa827uXD8ff4Xl+JzLSIE7I20svuzxLmuwy4d2BNjie7qmMesVLl7znZErSj9/RcLQnDuXLycCHegzYh/qoUbNGtkerS8oCuQzaKIY8EB78ibS0sz0cucDi1CLp7NesWSsWV8mSJUQMo/W9PBIy8U/q5MMPP8iRXOdpxqG50uhmPMR4z7GAe9ppp7sB/ftLPmqaH/9TaaSjbZ7IcmoLiZ6xa4aAIWAIGAKGgCFgCBgChoAhUDAIGAFdMDhK+7S669y5sz+JPZleaqqkKmjL6TnnnrvFENB4mzHpi01cNYFlgg1pxnUssX/XxlIy2WOLtGb0sYvEx/McHJWTQQxALPz040+e3MspPPchjSGMixXb6D3FRLZylcrZHsermMPDDpCObzDSrCNZizflifa9CLUP5NU4TN6CC0S+Uwryg/ciBABkTE6Gri6H2DGJxoifZ2fOnJXTo9nus7X70ksvc8VEBAVje3t5Efrp2gqRKL/qsLRAnqX73KYOB2HbtFmzLMQShAvk8JrVmTIK6ZIJeKlzkNy1110XK4Zvm2qHpURMRo36heDmgMng7Qd5Qn4g3ah7jLwcdfQxvn1Tt7QxiOO/Jv6ldiE9YrWXUuov9BFkYNBSR6c86EjXVhs7/vgTspSPHRRDJQWxubaKc4gkXo600YAtOrw3S8v9NOkefy7C9EvJ6owa9YfKX0xteq1vR2BCnwvPeIC2sH+KajwIhF3I2hrVNVIGubXZs2Y7no0acZNGOkY9jx07zst5pBO+oMKE8RRCOTf9f/DggRt07NvExjzKC7FJnMEyymaIkNRYtzZzrOM64z1yE2GRJYRN9h3a0GK1Jxb/SCOMndxrpbGPQxLDomDp0qX0PpFcw7pMgpV46a+D1N9ZVEnHQppgMlNa37W0W2ed0sIYD5o13d4fcDgzyQ6XkAbpohW+dEnOkjXrlN+1WrCK9rWl2oWwEc0Qa/ZvtLLZwRHFnlDxf3ONHRos+FIPPi19s0DeXgsKfMefEcEz8UbdVdIi2jphEaobzIoVLe7wQP9ZnvyhjuKfDX+DzZvS5J+Rg/cz4YmLha7Vqo+AD/nn/yU++Kif+167qj795GNJnQyMLURy8CPlIa+8X80MAUPAEDAEDAFDwBAwBAwBQ2DLQ8AI6AKqk3/X/+u9J9k6mpcJEOSWFBYLKDf5j6Z+/Qbeu5OJHwbZyjbsYSKDw4Q9nVQIG0hbwvM3W99r1c70iE4Zh2a7TEbxiIoejpbqmeUi0FZISiF+Mk79xBsExU+aPONpV0GHkYVJdPhm+zLEYRF58nnvtPkL/OF9Y8eM1db9/m7gwP7eW5TyhWfi06hbt54nLgNmEDdMkvG4y62xsIF3aiANiLNY8WKe4E4nLsJTZq+jm84DmzGM1ySWt13AjaxQp+R/eRoed9GsE8eMGdP/n723ALDkOM+1S8vMzMyMWu1qJa3YK8myZDux/6ApcW5yDYmT3CTGxAFjHENu/hjigNmyLLRwpQXBMjMzM+N9nzrbsz1nzpk5MzuzM0d+P3t0qLu66qnq6q23vvqqTJugHSZedsnxeDk+prixDz74UIwdTr3S9keNGR1m3HlnFGGTvLDiAe960mdyhpi5xAk+f/5cWClP5gkTJsbwGrSd22fcKSHuhRIBup3i5bJRVnJ/kSaTJmwKV5W2keT/el4PagOvx3/xeHj7299eijsrGDoqHMrv/u7vhve9733xN/q4vfv3aRXDlrBCExo//9lPY5gT6oj7IV2u68lTdZ3bpnWbUmUin5QrLZZW5lqcmw5BQBsgrnghxrH0U8pQIYdX6zG0Z1Z+VMb27z8QBUFERIz8w48wHGnjGdZQIRouXTwTv+YYjkW45bUydkLe9myCh4BKnuPZSqO7Viw0lOdtYty/3MdnTmeuyfdctyr3EGkgerORrBpwvAT5TmISJ9fM94p3cb7nQPY5uZ70eOdfunrd7OPTn7lObpplv23dpnWc8I0MdR7G6o7nnns+nWS57+HJ+fylJy7orwYPHqQ+b3GF5aZch9R3F2rz5s6L8fFZKZVM9FIXhAoaO3aMQgONC5/+7GejiH/s+NE4+bdh3YY4WfwTeb+TT/oh/mwmYAImYAImYAImYAImYAJ1g0BhLlt1I6/OxQ0kQHxJBIa0cMB7BoN4PBb6x0AwnUYsgkbfhB2pyBikI2Ttk1hbJo1yTq6MkE9Yi69+5ctxM0IG2mnj2uT/vDxaEbDxxhs+fER4xyOPhH/5xtfD0hUrwwsvvaxYwvflFXXxdMXjMck/10BA3b1nd/pSBb9nIJ8W9xCTWZpekXFd8rBPYUMKFUkqSrMmf8fbrZPCGpQqq8R7xCzEv0qbyp/2WoVFQ4lXiad8kh6CBR6iiacz39MG+vbtG0ZJDEmM81nyzhJ93jeSCEbs15UrV0TvTDbgZLIBg/dQhSdo1+FaGA424iScQFI+jt2ze488G8tf5p9cvyZe2ZDys9qw66iEv+x7gTJSDrjAA8G9R7fuirc+Nfzhhz8c74Nluh/+6YtfCoM1UVWXjLjBffv3K9XuKd9RiZznNFlQWWMyLDtUAmy6dutaJtRKdtpcF36JqJb9e01+pg65dlXs0mVE4GsCJ+VgZYcaSklytAkEYa6D8Zp4sZYcVOAbNgRFDE7uISUWz2RTPUTuxLgen5Nr8j3XrIqxJwD9SzLBRxrcn500Eda8WWbVT3npXtGxV7NZ3mF5f2OlRApx3uOYCEhhz3scPxAig1UeaT6xXirxDKet0i+m04gXVSbqi38hxoTVtdZT8Rm/fPwX4ac//UnAs5lNbtNGnZCf88rXZbXLltpMePCgwWHmAzPDZxV7f+XqNWHWq7PD72jCjPBHNhMwARMwARMwARMwARMwgbpBoPS/7OtGnooyFwzI8cRq0aKZdnBvUem/JvLqYlOyumIM3BAUsgedCALX84fwXF/L9xNvuvLKy7VrWixlEPudf//38P+95zdjbEw2SGzQoGEZAS7JJ/VM3mGDAEP86G9861vh69/8VhgxYmRyWMkrQmqJiKJvOZ+l14Us0y5JJPXm4sULURQhHSyKCfquUDt+/FiZOi303Bt5XEPVQVPVRXb7Q3yuisBEOhdTwlSsBwmJuTwOETi2alM9xDqO4zMxoLt17RYR4Ol59z33SsDO3B8cg2deEhaAWOnPPvNMSb1zbUJ4EO85MTygm6U8SGlTixcvkof3/uSQWnklNvkdt03Xpp8vZ9q48pgRvK4JjUnGKDe/ZUTAhtFb9Z3aOO673/uPGIooOa62X+HOCod0W2KS6vy5s1XqX2gPhCbJNrznCxGWCWVAvPAbbZS/KvcO+bysCTj+0oZQm24VtIf0Z46mrFUxVrEgWpJm2ppLUE33p+pRy0z+xWuqrJU1JldOKvRH+oowo59voJUmdcvSucyfMybIsifZOLqensPX9xwXd9U/938hBtv0/VfIOd/6xjfC70tE3iKP/eTfI6Xr/loq6b6IlQm9e/cOn/zUp8P3vv+fYZJWMmHZbena2X5nAiZgAiZgAiZgAiZgAiZwIwgU5r5yI3JS5NdgQzoGTAhPVRFN8cZcpQ2M6oohAFAO8pUMHBFe8N69noEcIjsezcuWVrxR041iQUgM6m2bREfCKjys2Lzjxo2LoiFlxduKP3jAgD8MLgyI2XzsUQlvJ06eCJ/9zGdKiVNHjhyO5yXMOIe4pR06dqhS8RD78AhL6oREEPQLMc4hzmi2kFTIuTf6mLMSB48dU9ztlABF/tvLi7hpSritTL5Yuo83O0ZaUYBJpZ9Oa968eXFyAeEj3gdqt20kGmNMNL1t5swSb09EmB3bd4S9qbjeiNGHFNKipYRPDO/G8eMnKBb17Bja5vY7ZsQ2FX/Uf5jQIPTHpk2bkq9q7ZU4rX/+iU+EXurPHnr7Q+FOhR7p269/5I6XJ8L8RcX5xfuQewGW/GGwYVLmPe99b9ghj2pCc9S2IWQeSHvTKkN48zZXyAy4V9aobzZoTVumn7gUuaS/z36fHHfhQqYdZv9ek5+5dlXKS54UhaiUJyr1jdCblnlj33i1HXAOEmkMl5H6ju8LMeIWEz6CcBNpI2Z3WtS+os1isyeRWHFSFWNCqL1CzSRtmTRgdkwTSoVMLFTlmjV9DvyyGVKmU2cIAUMBq5YD+k4m2ohrX8i/d+CXKwxWRVdnQ9dNmzbGzXffqT02CIvVUTG6eQ7SDpjIYUVCrucye01MmzYtfOhDfxBXlhDKy2YCJmACJmACJmACJmACJlB7BCxAVxN7RJnNmzfHv2pKslaT2b9vf8Cjr9FVAQ1hafXqVeFjH/1oiahWlQwy+EUQ2iJWdcnw0FoqUXzD+g3yRF2iTSU7RfGEwS6xr4cOGRp6yauKkBpt27aJMUcTry7qHq+rBx54MIpu3/z610uKRlgFjqPcGANllkUT4qQqlu2djVjC9Qs16jS9lL7Q8270cXgUH1AbTHu8IZx3VnzWuLFlJTNEmJK0tx71gSc6m4FlG0x/+D//Hd6h2OB4LiOwMAHRs2ePcItCTqxauTLGbyZvHItH9KJFC8PqNatLkuL4latWhsmTJsfr0gaI+TyIjRUlmExRbPF0vbHUfK1iSDMZUhdsx47tasvbw7ZtW8MvFRe6ZauWUTjv0aNHGK1Jmv4KH9Kte4/QRfVBGBjynUzSwAUPxD/4wz+UqP6zUoJebZSN2Olbt2wt1ZaoNyYXqLvKGu2otWJKp43vjhw5Ig7XYhGnf0+/R7ivauzpdDqVfU+bZ0KRV8pfGWvevEWpczg9ttVUOrRn2kCSPq8NtEnqTWKjxl6Zy8VwR20V/5kJDyxJcxebkKbSYiIk6V+TMuH1W0/XrawRFqezwuok6XA+bXmfYp1XZWPhyl6/Jo6njrL5EEf/4x/7aOSY7l8re302g12+fHl8plV0LqtPqvLcIe9sFrxx4wa9ro79PxOQTPoOGTokDBs+XBsj940bB7fVBCGidAz3oXZJW2TC5b63vS1u7GoBuqJa8u8mYAImYAImYAImYAImULMEKj9Kq9n8OPWaJqCBWSHSw47t2+JALgxP4KIAAEAASURBVPEAZaDKBngLF1RuE8KaLk51p39Km4NlD1TZtKlnz57R8wov2LaKBc0mdSNGjowCBaIyA/1evXpp08KpIS1Ab9++vUQAIK+IG4jVnTp2qnTW8ZpungpLgSjDtc9UQrSM3mop0ajSmbhBJ5w4cVIbB+7OEg0Vj1XcmiimaWUMbzkmD7I98M7G2Ka5hTE8kY+lwpUgZnTv3iNMn35bWK5N9xBi4Y8hcixcKAE6tYKBzUif/OUTYaI2IuT6nD9EcaCJE4zn4MCBg0p5Du7cuaNqsa0rA6IKxxIXmr/EEH/69usXJ1AQ51tKCBqp+4A46J0VsxtPR9okZR4osX3YsGFhjQQkvqtNwyM9HduX+5BQSYnYmAicheSRMBbNmjcLFySOpe1MgZtjcs3kuunzb8R7xFn6MrzTC80DkyYdO3Usaa8l/Y6eB2k7p9UFaSakz7F9+/YL69etrVQboF2xcWS63ZAW9wmiZGKEJMr2Tua69MWbN20syXNyfHmvTLJ26NCx1DV57hEXmg0Ci9FOnDiu5/gp7ROQiZNNeWD6wvPP39DixLZWyD888uSKycLV8rbmLzH2CKCeeW3bpm3o2LGjPKRvVniku2N/yzWZrGAjy+ESqvm3DBtb2kzABEzABEzABEzABEzABGqHgAXo2uFea1fNjtuZLyMbN26MgljiIYWAxuD8ne96d/jpT36c77Sc3/ft2zd0kccvsRz3ajBfV4xNBbtpIzWWXePVjL3+2mvhoJbrxwHz1YzuUkgC/tK2bu268KnPfCZuTgcjjkcgadq0tDi6Qst+Ee4TjhyHAA2PytrMmQ9GD7BkMz2uh/iyb9/egpPinGKwQ4cOhnUSrRAyE4NdB9VVOwmflbEuXbrGkBnppeLUx355Ap48qaXoeYzJA4RivGQ5FwFjjEKz4BHPMn+8+uCJkL1z585SbQYx8sUXXgifVhvBEH3Id1fFkaZMrVu3KhFDSGPenLkK4VJ7Ihfl6SIhBzGnneJdEwKBeNCI7XgUJkZbRmhPi+2sEiBkzzve8UgUe2BFeWlp06ZPj2FFordskkhtvCpUwzmFdUkbtwJ1OWf27HiPpn/L9562MHbs2BiOIpm6iPehRNFc3vT50qmN76kT6vnBt789/Pu//VspIbe8/BAuZuDAgaWOJ+wFE0Tp8A6EGzqujR1pO7QB7lc8w4kLzkavlfEiRkxsrf45LWjfpDggq1asKFVXCMOH1VfwbErub55VDz74YPSYze63yysnEyrt23dQOtfiVnOvbli3LhD6oxiNzRyPHzseV/RQ/+qwQgutamJSYOvWLaX6rIrKx8QTk7EbNmyIm9lWdHxVf2fTUFZW0AYQj4kTslHXXJNaYULa+xXKi7+0TZw4Ka7WIJQWdUcbZJ+Hbt27hTG6b1995ZX04X5vAiZgAiZgAiZgAiZgAiZwAwl4E8IbCLsuXIpN9tKegPnytHLlinBc3lMICBiDewbnxDpOi4L5zk9//97f+q3wd5//+/CHf/jhcPOUKaGflu8n6aaPu5HvCRHw7t/4zfCJv/hL5e3z4Z//5evhn//5a+Ht73i4oGw899yvwuw5s6M4l4jLMGqmuLJ9+vQpSYN414cPH4pxShGqGBBzPB60d91zT8lxhbx55NFHo+dpspkeDI8ePRJe0YZxbzVDRGISBGEzMdgh3k+dNjX0kBdnodavfz/FMn44esUl5+C1vGD+fIVm2Jx8VeZ1rkRhJiPgzLVp94MHDwrvfPe7Y0xnTqAuiR1+8uSJMufv2bM7HJXHHedG0+vYcWOjlx6xSzHaBGk88cQvJaQdit/d8P8oD6NHjw4f+djHwt988lPhC1/8YtxY83Of+9soSFeUnwP792sjz2+HBQvmx/rh+KSdDx48uNbvdfJzSiL6xg0bI28+Y2fPnJM4+q4wRX1SoYYIR2iRdBgI6m+HJiuO1HGRkjppJC/f97znvaGJPNkLMbYVvGPGjBjmIOl3KC+hfF566aWS+4C0li5ZEieNkrAmXK9+g/rhN7XBK+ERCrURI0fEMC+EzUnuHV4Rm9evX1/KQ3mzViosmL+gVGxr+uGH1Y8z8Vmo9ZQn7dSp09R+G5dck3NPa8Jlo66RiNuFpldXjtuv8CGEhkmet4Q0gesH/+BDmlhrXHA2OZ928/l/+IfwoT/4gzB+woTQT/dCdRvt8+GH3xH+TDHoP6v+56tf+5fwNYW0+uCHPlTQpeiDvvH1fynzXEbIZhWMzQRMwARMwARMwARMwARMoPYIWICuPfY1fmUG7Zfl+Zc2YuiyDLsi27J5iwSxa15feE81a9ZUIQUmaFOyu0s8eitKhyX4M2c+EDcP+tM/+0R44smnw1//zd+E7hJga9MmTJwYPvDBD4bf+I3fiGECWij+J6LM7/zO70ZP10LyRpzsJL5mcjwiJUv707Zq5apwNCUCIF7h3fVnn/hzxTMufWz6vPR7PEkZ8CPuJKIM19qjje9+8D8/SB/6lnmP5+3yZctLtTW+wwv/vvvvL6iceDVO1UZUHfSacONEPEGfeeqpsFLxnPPZs08/FZffs3EmhgjVrm27cOddd5eIYNTB66+/HkMaZKeDULd61crYRniP9/Btt90eZj7wQEmsYPJ0XhvSvfHGG6U8TLPTqsnPjcViutrXxyVA84qXIw+GyRJm8XwtxPbs3R0OHTxUInRxDuI6ITt4rW3DUxKRn/pKjI0Ax0+cEMuZfFfR66hRo8Ktt04vJUgSuuGll14Ma9auqej0Wv2dtsYGpoTUoP+rV8Bz4B2PPBL6IzTq3CSCAm2Z+/AnP/pBqUmdWZoIe/ONN0vF1UbAZpUJzJg8KsR+7/d+P24exzUw2g/33uJFi8ucvkIe0c9oA9lE9OYAytmhQ6cYZ51VLoXYTG0qyiZ3yTU5h3KyWe6Zq/koJJ26dgyCPeFWknYPmwYNG0RBd/iI4QVn9+2Kh0+fO37c+PAJPbeefvZX4W8+9amSdAtOqIIDmaj4wAc/EJ/DeDG3krc2K0+m3XqrPJtbVXB25ucNihfNBGbS79Bu2Tuhie5TmwmYgAmYgAmYgAmYgAmYQO0RsABde+xr/MoMws6dvbYBHhckTmsXCQLZlgzW0t+zKRobFiXeUwiniKtfk4fRgAEDSg360+fxHg/TNvI6+r/yjGTDMrzX8BJtII+44cNHxL/sc27k55//7Gdhvjxg2RAMTggclJOlyQ8+9FCFGy0yoB8/fnxoIR5xabMyD0OWmW/btq1UUZ588om4mVtaBIDPYAlB7/2t39YAO79IQp5YjvzVr/5zDD+ReF4mguYuhX4oZOOzUhkqkg94jz/22M9LhASyDet2Einuuec+CUxTKywJAtpHPvKx2P6Sg6kn2vWu3aXDqiS/J69seIYHNOIbhniD0EUM3cSoxxeeey5skrd2ttGmiLV6VsIz1yTvCCyEEeE9313RBBFenGzkV1tGGBfiNO+XgEz7It+EViD8wf/+yEfCZG2eWJHdcceMGBM9ic+blHfH9h1Kr/QkWEVp1cTv1Pd///d/x7Kl0z9z+kx497t/Qx6hf5D+Ouf7BxTW4eN/+melQkBwIGV94oknYj3mPLEOfUkbpn6//o1vxNjd+bJGXzV48JDwib/8y7hiJYmzTFk5n/tinybgSC9tOxW25YhinNM/Jca5f/+P/xQmTZqcfJXzlb6O8CA3T7klbnhZ0q8qLdL4sQTvXKFcdis80gHlh7wlxrPmYx//U3lCvyP5Ku8rk3v33Htv7IeTa3Iw6bGJ5n55+BerIaDPnTOnlCDLTAKbYH7jm99SOJlx5RaNdsBGfx/44IfCKK2SIJY6zzgmMm6+eUp8/pWbQCV/3Ld3rzZy3qLVVydKnst43nfU/gef/dznKrweE17cz0012ZHUJXklNMy+vaXDdVQyaz7cBEzABEzABEzABEzABEzgOglcGyVeZ0I+ve4RQAxiA6L0wJx4iN/7j/+Iy1wT0Suz+VKHMgX44hf+KbysZdaE7UgMwQGPpFmz58Ql+5kYjcmvmVfSI1THnLnzolDNQJDzyAdi70p5hT77zNOlT6qFT8QHTYsl5JMB9xe+/OXwO7/3e7GcubKFUPLHf/K/NQC/OXr1cR5lIy4qITFOavCcttfmzQvL5alHfSTMEXHwCPzsZz8Twx0QezfbEDfvuOuu8Jq8YwnZgSWCD4zx/vvOd76dfdpb5vMxCVmPP/ZYOJQV2gABZMaMO8K3/vVfwx/98R/nLC88vyaR7R//6QtQK+HGwYjI/6ZzN8g7sCLbsUOhFRTbljpPjGXsiVGnuyVkJ/WSfM8rdfzDH/wgnESwuXo+x6WPvSgh6JVZr5TZSC2dzo14j4j32ry5pTwaEaPZVPNTn/50mH7bbXmzwQTT+z/wgTBBqyMSgZD7ATb/9Z/frzMTJCclQs2a9XLkn/SJlLFbt27hkwo9wnL/fIaY+XUJdqxCoA9LjHqdJ251KbZ9krfyXtsrzvdTTz8THn30naWeD5xDH8imkk9ohUBfhbFIJr2S39iU7zvfzt3vvKq2zOQeQmDaCG3xU93LH/noR/OKiH+v8A5f+cpXood2uh1d1gTGHgmTj/38sVJ5SdJfp1jx3M/ZXtCI4F/88lfCV/5Zk3daAZHLyM83Va94aPOsTNthrVp5/PHHS2K1p38rpvdz584JTz35VCkPdPog2vITTz8dPvxHf5S3Tt7/gQ+GH/zwRzHkRuIJTptHiCYECxuqVre9/to8bXy6Xe2wYUya52vTps3Cu7Ty5W8VLosY47mM5yUrOChPU/2bhfMw2sUqhRR7pg78myNXvv2dCZiACZiACZiACZiACfy6ELi2HvnXpcS/RuU8cuRo3ByNgWYyGGPgybLWL2mg/zkN5vjMEvzjx4+FH/3oh+ErX/pyCSGEvvmKqXjL1KnRCzctROBV9Ed/9L/iUlliTO6VQEC83g7tO8Rj27RpHeMhlySmN3gLz5o1K3xN164L9tyvng3jFJP3bW+bGT2kkjzdJA+xP1O4kPe//wMxRAMbrh04sD+GbWBTuim33BI3bENkQWTEGJQTC3ft2nVJMqVevyBxpa2E+3f/xnskaFwbtCOS3H777WHWK6/Gja7waD4n4Y4QHYRLoa6IK50WLRGI2BTrlVdmhXlz55a6zlvtA17QH/7QB8MPf/yT6FWZtGNEQLz5/0weqdQTHpmwY4MtPMaZGEGo4Lg0O4THdevXRc9GvGIrMuJET5t2a/QWTeo6OYe02FiT+ML5DCENsYZzOT6dF+qe/H3/+98vtfQ/X1o1+f0ybTb4ve98J9x//9tKiUrc86NHjwnf+e73whZtWrZ08ZKwXUv6T0jM7Srhdvz4cdFTllAniWhIPiknMeTZqC5d5posQ0Vp00Y+8id/EuYpTERL9UVJvmhTiFSPyFt+huIdE8uZsAWqsBhznbIRyiHtVVlyrZvqhb/+P/9HAlf+UC4lx9byG9ofbY62SNkR7L7wpS+Fv/7kJxWr/Gj0bG3UsFHsd5pLwKO/Tk+2JO2XsA7/89//lbM0mzZtDE899WSYceeM0Lljp3Dxav/IwVzzox/7eHifJisO7D+gZ8aeGEO6R89e8X6FMRNraY95PrOi5A8VliG597MvjIcyKyXe/sg7Qp9evUvqletd0v1FnO+777k39plMtLBipHv3HtrToH1ckZDux0mbvpz78kPvf3/s07OvV2yf8YKmTmY+OLNUHxTbgJ4lf/7nfyHR9n8FBHdC1bCBKqs0uokRzx/E3HQ74F7hvv7YRz9SIyi+993vxomvIUOG6ll5Pl6DvPLce+SRR8Pdd98Tli1bqmft2rB71+7YpgcoVBB9UZ8+fWO75niMNkuIo4OKr0+d2kzABEzABEzABEzABEzABGqPgAXo2mNf41d+/fXXwn9873vhK1/9ailRiQsjzuHJjDHgZhDeu3ef+Dn9n+/r/O4K2fFXf/3XUaRNBnEM8PCMRqRALMVTDoGAQSLCBpYIdhzL9Rgw/vCHP4ieu+lr1Nb7xYsWRU++tm3aKczA5JIwDeS3uWJC84dIMXnSpHBBg1cGs3gtU2YsEURY+N1Mxz4mD79//so1AT8edPU/eA3+6Ec/igPkSZMnl3jVcS14derUKV6LzRH5jrjDDcUSSzjyHr7Eqv62PBC/rM3i3upGe3vzzTfl6f2d8AEJV7BCFIUR9UFImBZqW127dpUQmtnwjmNo09RPSR3pWL47I0H4j7SJ3PoNGwpC96S8QO+97/7o3ZuEIUhORMx7/bXXYnzv5Ltcr+vWrdO91TveY+Q7Md4jXm/fvq1ENEt+q43XuVqx8Nd/9VfhM1rqflqTT+SPP9oc4uDIESNDP4WowbOZNokQRR+ASAjnpGzcI/u0+dlfSZhNt93aKFP2NZnQ+NOPfTT8yze+GUXopE7JO/nGG5p7kc0GMcpI+dNtie9pS2yY9nGlRfiSum60VcIgrV69SvF0p8dNBClzSwmM/HH/UEbuKe4ffsuuO457Te39c5/5TLnFfemFF8KnFOf/25q0UIIlwh8iZuxXdc92kjhNLGquU5ax7hF9T59KfX373/+93FjtZGa97rE//vCHwy9++USM9UveSZs/2mcXTVZ1lKjat0+fuC8CQjvlTOqV4zC+R7DkmvPnv1mS9/hjEf9njjbM/fd/+/8VQuZP46aElBuj3LEPVd3S7on3zW+0eeqF3xOWHM+zj+f45//ub0OyKSXfV6fRv3xVk9TNm7dQvPyZpf7twj1Kn4PH+sSJk2JfRJuljvker+lLl64JzW3atomrUP5H4XdsJmACJmACJmACJmACJmACtUvAIThql3+NXh0RadGihWHzls1xcJa+GINKxL3kj8/16l0LM5Aci9j3zW98XZ6mH49ezgjJDPgwBqqJIM1glcEhwgxp8YcxkEWgRgz//Of/LjyhJc35jHSTtPMdU9XvEWBy2Usvvhi+9rWvhiXy7GwnsRlRAkvKQJn4Hm9bBuiIMAzKkwE8A992EjYe+/nPw1e+/KUy8WHT13z1lVfCpz/9qeit117ncC3KS3oJR9KLHK96KiYcyT+Df7zSP/+3n5P4/IVaD9uQlO0m5a1y9ZZpPyXnX21PyefsVzbvow1+RqEgCJlCG6SdYdQDXo7wYRKFdojBk9/IF0IhXPFk/633vkd1rc3MxLwQu6T2j6c090F2GWnbP5fnJZML5dksLVXHq7a+jk+MtBBaNkgIJ/830rLLkVybUCN4tn7pC1+IXo8IOnBN2ifnwZ77GcESL3N400Y5hlURTGodkrfhNxX+BCHyhljp5lThJZ/71a/CB9//vrBx08boMZ/c80l/Rjm5B/njfdKWSJg6hwsxat//vt8PP/vJT8q953NlhjT5q2lLX4N6ZIM9Nuz7zKc+GYVhyhfvH9Ufx3JPcRzlTfod8kiZ6QOfVzzz//OXfyExeEW5Wefcp558Mnzgfe/TvbH7qjB4bTKN9s71kr6O99mM2+p6q3S//o0mPvN5W6czQftbuGBBvL/XajNI0qZtknZSrxzP902bNC0pJ79hlJ22ffDwIfUznwrf+tY3S3n0x4Oy/kPapS37c+lfS33Sodnnx88FJJF9XpLuTfLGz2eEiPn6v3wtrgA4e/ac2naGAcdTX/DH0s/xdDvgHmEylg1X//wTnwg8N/NZxKL/UCeJFVq25PilS5coHMuXwjPPPhM6duoY+3DQJHVJPTIpljyXqTvabiI+k98OHTqGF194MXz3298pKNxScm2/moAJmIAJmIAJmIAJmIAJ1AyBa4pIzaTvVGuZwFp5531Wwt3v/M7vhjvuvLNETEpELwZtiRCKgJdtDBxZuo5HGMtu77v//vCI4oY207HJwJXXZCBPevwxoOdvs0IUfP8//iP88pePh/nyZI0eh4xQU4PT9DXJAxu1MfjlfESTylrzFs1Di2ZNo3CCeEL+EBBzGd8zSD1x/IQ8A28ND2sZN5tvkb+kXJSNwTQsKBuDdPLG+0ULF4bnX3heQtRPwzp5hpVnCKmI0Icl0G3auEneXQ9EL0DOSa7F+2TgHlnqOnhCszx61tNPBcSzX8jTmtib5Cc5lvOyjbiZTRtLhNFAnWPx4kY8431VDKGZ5dht5VV2/nyGZ5NGDWOdnpNncSEGu5bNEYozXpbkn+XRFeVoj9ref//Xf0Yx+J3vemcMC0O4l0QkoY4oF6+Rm/JKu4brRm0Q+KLq6BnFvJ396quFZLPUMYQKIJxE167dSnn9Eb95kzYQ5Brl2dOqtz/RZn7tFZbm7FVutEuE7edVnzVpCE3pNkBeqcd8hsfpv/3ffw1bt22NoWm4J9qq/XAef/DlD4M39QlvBCHK84wE2Z/99KfhDQlViaiV71pV+R6v2DbatJPJGPJD+2vWtHmlkiJUyPPaOJJ7/5FHHw0z7pgReslDHbtwgZAtmfIlbYryUV+UFz5ztKnb44//IvzyF78o6Lr0aa3F8MplifT15Yl86qTqoKIWX1DS5R6E/Je5X9tqcuCmuJner559VhMEBxUW5mT4fQnEI0eOjGVjMoTyJv0JZaaPo14JgfFfmpj4T4WKWcrkTQFGemzgd0HexIQ4mqFnD97lGNyTNqRWpG+uqA3VVz4yz4ydO3eEn/3sp7EdzZk9O07UxBML+A/96yflfT1z5sxw1933xDjHlCO5ZqZOaf9cM1NGvGYPHNwfXlAfQfzq59Q2TslbvDyjLTSWgI8IGoVfFaNJQ7yGMxOY5Z3Lb7SnFs2bxfsnYX5E+wcU0irY1LSZnm+t9Jzj/qOf49kC83zGNdjz4Lvf/U4Mt/LwOzLhZpgw4j5N96OkAZuk3auAcaLsRU1AUC88x8szytZS+WukfHFd2iFx/AspWzrdN7X3Af924Rl77733xQ0TlZW418Llq30R6VMX5DX2RarrBvpbpzAxX1Psb+I+ryyC8Djpcvu9CZiACZiACZiACZiACbxVCViAfqvWrMrFwIzd33/y4x9H7+VFixdp6XPnKATgVVQPMUSefMRw3rVzV5itZbrZlgzwGOAyOF++fHncpZ54qHgfde/RXTF3u5Z4BhPvFnEUkXX9hvVh44aN4WnFn0TELjENGnMZYgOiEnEn2dAv5v/YsRJRJNc5ub5DAFuzek0URjNlPBk9sHMdyzWIeUk85de0+dGmTRvDIAnQffr0jp6ebdu2i2JXImZSPuIvI7YRc/jNN9+IonB5g//s67J5INdZs2a1rjU4itCdO3eJwjvHMoBHNCFW9OFDh8MGCag7tm8Pc2a/Ko/2RTE58k3d5DN+e/nll/TzFZXvbGQJW2JnJmEH8p2b73vi/uLVimc9aWGNtbkY9YZndiG2QF6K//SFL0rwUBgNTlA+EfXgWpERQuDnEkBgN3XqtDBw0EDVU9/omYdnOnWAMMmkxXG1mx2qn62KW7xm9eoo/FfkqZzv+nNVvi/VbxC9fhFqEoPjcbX1iox78LvaLJL6S4R76pf7BIHkmhhXUUqV/f2KxNLZ4ctfaRYFKjUZXetKoA64n/MZ9fGfmjTCY5wQI/0HDIghDPCCRXAjjAJCLXXIppuH1EbxsNy4cUP0koV3TdkzComyVZNaxK2/rLbTUOLhBl23Kjbr5ZfDZk0gLJi/IAwfPiz0VCzirt3oy9jk7Erc+Iw6PqHJh31798W40IRTYbPGQkUt6vZf5U3LpBrtvZ68VImVz8akNW1zNNlySXXEvYFAt3v3nrBl8+Z4WdrjwYMHwqjRo8PQIUN1H/WJoRjo5+g7aLMI1YRbYBLzKXHfpzj/lbUnn3gi3n/0W2xWyX4EXbp2iYy5FvcsEyLH1I54RmzetDmsV4z2F198IWzbuq2yl4vHv6J9BkhjsVa1DBs2NPRW2Xr06Bk9nPH6PnfurPrXBiVl5DocTzx9YqEXYifUFxEzvZvaizrXeArhO7i3CjHiMv/DP/5jnJRI+nH2GaBPKMR+8D//ExZKmD1/7nzJs4J+qiKjPbMxKhNnhKBqIRGbDVvhw/McT+JLly+p/zwenz/sa7B12/bo9c7kJ8/1imzxosWxbPQ1UX5Ww9+vkDy0qcoYz5jlqo+Vel6u0L87xo0fH3r07BnDt3A/0RexqoRQIEwqHZb3+sEDB9Xv74h9149/9OM4AVKZa/pYEzABEzABEzABEzABEzCBmiPAyCm/ilVz161Syv0HDdFS4I5h5/YtYc+unVVK49f9pFYtW4ehElsQAhA6D0iE2Clxc+vWrSUxkAtlxCBw+IgRElAHx2Wyly9djiICy64RTFlCXahVJKje6HS6d+8e48B2767Nqjq0jxuQ4UV3QCLJTm1QhpCzUwJnYteTfwS+AQMHhB66Fh6BDSWuNZI33R4JPnDEm/StYNfDKFf5ab+IEnivdpQ39GmJqiwTRxRlY7KlEnmoq+ux6shzdaRxPWW43nMJYTJw4MDQWxu8IdC20X1/TsLXeYk+u6/e6wiyyaTE9V6vKudXhXH2OdyDw4YNjxNPiIKt5WnNxArCIDGGEdYRvavLsq9fXemSTmXS5lkwceLEGGYDj3liNe+VYLhDns/zqlkoHzp0aBiiv46KAY0YfPr0KU2Eqq9TO2JiAaGxuq1Xr15h1JgxUbhEjD8lD3Ri7NNHbFcZEWKrcxKoIvYV/V5R+av7H22E0hkxalQYOGBgDDN1QZMWsGFSaZMmPxGrE6so7xX9nqRT1deOEsn7Kw599549QldNfPOsPH91koiNQ7du2aqNYTOTLFW9hs8zARMwARMwARMwARMwgbpAoJP+vdurb/9wTA6jG9YWrq3Vhbzny0N1j2XyXadavrcAXS0YnYgJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEAdJPBWFKDzBwOtgxXgLJmACZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQPAQvQxVNXzqkJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFBUBC9BFVV3OrAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUDwEL0MVTV86pCZiACZiACZiACZiACZiACZiACZiACZiACZiACRQVAQvQRVVdzqwJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFA8BC9DFU1fOqQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUFQEL0EVVXc6sCZiACZiACZiACZiACZiA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v/rSiwF/vWw65mACJmACJmACJmACJmACJmACJmACJmACpyIBC9CnYqk7zyZgAu8Ygbe1eeCf7/+drJ43auOvnXHTxXfsYo7YBEzABN4HBNh4E/dF/B1vSOJJxXX88R1veny+CZiACZiACZiACZiACZiA9skyBBMwARMwgcIRwF/pyuVLCxehYzIBEzCB9zmBvdpPoIr+O7B/nzYQPnBcucXP80H9xyaaBw7sP664fLIJmIAJmIAJmIAJmIAJmEBhCFiALgxHx2ICJmACJmACJmACJlBGAgcOHAjPP/NkqFSpUrSAXrF8WRljyD581AvPhspVqsS4Vq9alf2jP5mACZiACZiACZiACZiACbwrBCxAvyvYfVETMAETMAETMAETMIGDBw+GhfPnFQzEooULChaXIzIBEzABEzABEzABEzABEygMgfKFicaxmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEA2AQvQ2Tz8yQRMwARMwARMwARMwARMwARMwARMwARMwARMwARMoEAELEAXCKSjMQETMAETMAETMAETMAETMAETMAETMAETMAETMAETyCZgATqbhz+ZgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUiIAF6AKBdDQmYAImYAImYAImYAImYAImYAImYAImYAImYAImYALZBCxAZ/PwJxMwARMwARMwARMwARMwARMwARMwARMwARMwARMwgQIRsABdIJCOxgRMwARMwARMwARMwARMwARMwARMwARMwARMwARMIJuABehsHv5kAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZQIAIWoAsE0tGYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAlkE7AAnc3Dn0zABEzABEzABEzABEzABEzABEzABEzABEzABEzABApEwAJ0gUA6GhMwARMwARMwARMwARMwARMwARMwARMwARMwARMwgWwCFqCzefiTCZiACZiACZiACZiACZiACZiACZiACZiACZiACZhAgQhYgC4QSEdjAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiaQTcACdDYPfzIBEzABEzABEzABEzABEzABEzABEzABEzABEzABEygQAQvQBQLpaEzABEzABEzABEzABEzABEzABEzABEzABEzABEzABLIJWIDO5uFPJmACJmACJmACJmACJmACJmACJmACJmACJmACJmACBSJgAbpAIB2NCZiACZiACZiACZiACZiACZiACZiACZiACZiACZhANgEL0Nk8/MkETMAETMAETMAETMAETMAETMAETMAETMAETMAETKBABCxAFwikozEBEzABEzABEzABEzABEzABEzABEzABEzABEzABE8gmYAE6m4c/mYAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFIiABegCgXQ0JmACJmACJmACJmACJmACJmACJmACJmACJmACJmAC2QQsQGfz8CcTMAETMAETMAETMAETMAETMAETMAETMAETMAETMIECEbAAXSCQjsYETMAETMAETMAETMAETMAETMAETMAETMAETMAETCCbgAXobB7+ZAImYAImYAImYAImYAImYAImYAImYAImYAImYAImUCACFqALBNLRmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJZBOwAJ3Nw59MwARMwARMwARMwARMwARMwARMwARMwARMwARMwAQKRMACdIFAOhoTMAETMAETMAETMAETMAETMAETMAETMAETMAETMIFsAhags3n4kwmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYQIEIWIAuEEhHYwImYAImYAImYAImYAImYAImYAImYAImYAImYAImkE3AAnQ2D38yARMwARMwARMwARMwARMwARMwARMwARMwARMwARMoEAEL0AUC6WhMwARMwARMwARMwARMwARMwARMwARMwARMwARMwASyCViAzubhTyZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAgUiYAG6QCAdjQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYQDYBC9DZPPzJBEzABEzABEzABEzABEzABEzABEzABEzABEzABEygQAQsQBcIpKMxARMwARMwARMwARMwARMwARMwARMwARMwARMwARPIJmABOpuHP5mACZiACZiACZiACZiACZiACZiACZiACZiACZiACRSIgAXoAoF0NCZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAtkEKmZ/9KdjIVC9eo1QpVq1cPDgwWM53eeYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmcYALlypULu3ftCju2bzvBVz61LmcBugDl3aBx49C0ecuwf9++AsTmKEzABEzABEzABEzABEzABEzABEzABEzABEzABN5pAhUqVgxrV68Ki+bPfacvdUrHbwG6AMW/Z/eesH3btnBg//4CxOYoTMAETMAETMAETMAETMAETMAETMAETMAETMAE3mkC5StUCHt2736nL3PKx28BugBVYPXK5YE/BxMwARMwARMwARMwARMwARMwARMwARMwARMwARMwgRIC3oSwhIXfmYAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJFJCABegCwnRUJmACJmACJmACJmACJmACJmACJmACJmACJmACJmACJQQsQJew8DsTMAETMAETMAETMAETMAETMAETMAETMAETMAETMIECErAAXUCYjsoETMAETMAETMAETMAETMAETMAETMAETMAETMAETKCEgAXoEhZ+ZwImYAImYAImYAImYAImYAImYAImYAImYAImYAImUEACFqALCNNRmYAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJlBCwAF3Cwu9MwARMwARMwARMwARMwARMwARMwARMwARMwARMwAQKSMACdAFhOioTMAETMAETMAETMAETMAETMAETMAETMAETMAETMIESAhagS1j4nQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYQAEJWIAuIExHZQImYAImYAImYAImYAImYAImYAImYAImYAImYAImUELAAnQJC78zARMwARMwARMwARMwARMwARMwARMwARMwARMwARMoIAEL0AWE6ahMwARMwARMwARMwARMwARMwARMwARMwARMwARMwARKCFiALmHhdyZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAgUkYAG6gDAdlQmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYQAkBC9AlLPzOBEzABEzABEzABEzABEzABEzABEzABEzABEzABEyggAQsQBcQpqMyARMwARMwARMwARMwARMwARMwARMwARMwARMwARMoIWABuoSF35mACZiACZiACZiACZiACZiACZiACZiACZiACZiACRSQgAXoAsJ0VCZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiUELECXsPA7EzABEzABEzABEzABEzABEzABEzABEzABEzABEzCBAhKwAF1AmI7KBEzABEzABEzABEzABEzABEzABEzABEzABEzABEyghIAF6BIWfmcCJmACJmACJmACJmACJmACJmACJmACJmACJmACJlBAAhagCwjTUZmACZiACZiACZiACZiACZiACZiACZiACZiACZiACZQQsABdwsLvTMAETMAETMAETMAETMAETMAETMAETMAETMAETMAECkjAAnQBYToqEzABEzABEzABEzABEzABEzABEzABEzABEzABEzCBEgIWoEtY+J0JmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEABCViALiBMR2UCJmACJmACJmACJmACJmACJmACJmACJmACJmACJlBCwAJ0CQu/MwETMAETMAETMAETMAETMAETMAETMAETMAETMAETKCABC9AFhOmoTMAETMAETMAETMAETMAETMAETMAETMAETMAETMAESghYgC5h4XcmYAImYAImYAImYAImYAImYAImYAImYAImYAImYAIFJGABuoAwHZUJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEAJAQvQJSz8zgRMwARMwARMwARMwARMwARMwARMwARMwARMwARMoIAELEAXEKajMgETMAETMAETMAETMAETMAETMAETMAETMAETMAETKCFgAbqEhd+ZgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAkUkIAF6ALCdFQmYAImYAImYAImYAImYAImYAImYAImYAImYAImYAIlBCxAl7DwOxMwARMwARMwARMwARMwARMwARMwARMwARMwARMwgQISsABdQJiOygRMwARMwARMwARMwARMwARMwARMwARMwARMwARMoISABegSFn5nAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZgAiZQQAIWoAsI01GZgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmYgAmUELAAXcLC70zABEzABEzApRnT+gAAQABJREFUBEzABEzABEzABEzABEzABEzABEzABApIwAJ0AWE6KhMwARMwARMwARMwARMwARMwARMwARMwARMwARMwgRICFqBLWPidCZiACZiACZiACZiACZiACZiACZiACZiACZiACZhAAQlYgC4gTEdlAiZgAiZgAiZgAiZgAiZgAiZgAiZg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uYePRUoOH8eexhfPQ1NgFAEWmSQnN+lxyIn821gk9USsJWFRQAEFFFBAAQUUUEABBSZDwAD0ZKi6TQUUUGCGCRw/fjQW7XsjUm+cOzFy8o6Vj/7cK/2bAgpMJ4HfP/5Y1tHelu3s6JgGuZGnk4zHooACCiiggAIKKKCAApMhYAB6MlTdpgIKKDDDBAg0f/LJ0Aw7K09HgXIKVCqVbGBgIC0c6CBSOe8Bz1oBBRRQQAEFFFBAgSIFDEAXqe2+FFBAAQUUUECBKRYYGhpKKTim+DDcvQIKKKCAAgoooIACCpRE4LKSnKenqYACCiiggAIKKKCAAgoooIACCiiggAIKKFCwgAHogsHdnQIKKKCAAgoooIACCiiggAIKKKCAAgooUBYBA9BludKepwIKKKCAAgoooIACCiiggAIKKKCAAgooULCAAeiCwd2dAgoooIACCiiggAIKKKCAAgoooIACCihQFgED0GW50p6nAgoooIACCiiggAIKKKCAAgoooIACCihQsIAB6ILB3Z0CCiiggAIKKKCAAgoooIACCiiggAIKKFAWAQPQZbnSnqcCCiiggAIKKKCAAgoooIACCiiggAIKKFCwgAHogsHdnQIKKKCAAgoooIACCiiggAIKKKCAAgooUBYBA9BludKepwIKKKCAAgoooIACCiiggAIKKKCAAgooULCAAeiCwd2dAgoooIACCiiggAIKKKCAAgoooIACCihQFgED0GW50p6nAgoooIACCiiggAIKKKCAAgoooIACCihQsIAB6ILB3Z0CCiiggAIKKKCAAgoooIACCiiggAIKKFAWAQPQZbnSnqcCCiiggAIKKKCAAgoooIACCiiggAIKKFCwgAHogsHdnQIKKKCAAgoooIACCiiggAIKKKCAAgooUBYBA9BludKepwIKKKCAAgoooIACCiiggAIKKKCAAgooULCAAeiCwd2dAgoooIACCiiggAIKKKCAAgoooIACCihQFgED0GW50p6nAgoooIACCiiggAIKKKCAAgoooIACCihQsIAB6ILB3Z0CCiiggAIKKKCAAgoooIACCiiggAIKKFAWAQPQZbnSnqcCCiiggAIKKKCAAgoooIACCiiggAIKKFCwgAHogsHdnQIKKKCAAgoooIACCiiggAIKKKCAAgooUBYBA9BludKepwIKKKCAAgoooIACCiiggAIKKKCAAgooULCAAeiCwd2dAgoooIACCiiggAIKKKCAAgoooIACCihQFgED0GW50p6nAgoooIACCiiggAIKKKCAAgoooIACCihQsIAB6ILB3Z0CCiiggAIKKKCAAgoooIACCiiggAIKKFAWAQPQZbnSnqcCCiiggAIKKKCAAgoooIACCiiggAIKKFCwgAHogsHdnQIKKKCAAgoooIACCiiggAIKKKCAAgooUBYBA9BludKepwIKKKCAAgoooIACCiiggAIKKKCAAgooULDA/wExQPeHgfe8pQAAAABJRU5ErkJggg==" + } + }, + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "![image.png](attachment:image.png)\n", + "\n", + "Source: Twitter" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "![Framework comparison](https://www.assemblyai.com/blog/content/images/2021/12/Fraction-of-Papers-Using-PyTorch-vs.-TensorFlow.png)\n", + "\n", + "Source: Assembly AI" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "q-K33cgaoY_s", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# first imports\n", + "import torch\n", + "from torch import nn # model\n", + "from torch import optim # optimizer\n", + "from torchvision import datasets, transforms # data and data transforms\n", + "from torch.utils.data import random_split, DataLoader # utilities\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n4094EXrlsmY", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 1 Tensors" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "earp3FM4lg53", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# directly from data\n", + "data = [[1, 2], [3, 4]]\n", + "x_data = torch.tensor(data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "T8VPI6Rglwbi", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# from numpy array\n", + "np_array = np.array(data)\n", + "x_np = torch.from_numpy(np_array)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "hd-_NAsDlzxi", + "outputId": "a3929eb9-d37d-417e-c45a-8119a46565c6", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# from another tensor\n", + "x_ones = torch.ones_like(x_data) # retains the properties of x_data\n", + "print(f\"Ones Tensor: \\n {x_ones} \\n\")\n", + "\n", + "x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data\n", + "print(f\"Random Tensor: \\n {x_rand} \\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "KOmRiBhYmCef", + "outputId": "11a4a70b-f59e-4160-8dc3-7f80287e546b", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# use tuples to determine tensor dimensions\n", + "shape = (\n", + " 2,\n", + " 3,\n", + ")\n", + "rand_tensor = torch.rand(shape)\n", + "ones_tensor = torch.ones(shape)\n", + "zeros_tensor = torch.zeros(shape)\n", + "\n", + "print(f\"Random Tensor: \\n {rand_tensor} \\n\")\n", + "print(f\"Ones Tensor: \\n {ones_tensor} \\n\")\n", + "print(f\"Zeros Tensor: \\n {zeros_tensor}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZIe8tIYbmHqW", + "outputId": "82df9f81-d0dc-49f1-b928-6c0f086de49d", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# tensor attributes\n", + "tensor = torch.rand(3, 4)\n", + "\n", + "print(f\"Shape of tensor: {tensor.shape}\")\n", + "print(f\"Datatype of tensor: {tensor.dtype}\")\n", + "print(f\"Device tensor is stored on: {tensor.device}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "vkzYCe5qmMAO", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# by default, tensors are created on CPU\n", + "# We move our tensor to the GPU if available\n", + "if torch.cuda.is_available():\n", + " tensor = tensor.to(\"cuda\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "KYUOfiXAmUj3", + "outputId": "14572a5c-62a0-4d8e-d78c-5be716af2c1c", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# indexing like numpy\n", + "tensor = torch.ones(4, 4)\n", + "print(f\"First row: {tensor[0]}\")\n", + "print(f\"First column: {tensor[:, 0]}\")\n", + "print(f\"Last column: {tensor[..., -1]}\")\n", + "tensor[:, 1] = 0\n", + "print(tensor)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "N_PqtgNXmR4T", + "outputId": "694ff4c8-381e-4bc4-a5ff-a43ee0892209", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# joining tensors\n", + "t1 = torch.cat([tensor, tensor, tensor], dim=1)\n", + "print(t1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ppYSqJGnmewf", + "outputId": "7720cf9e-eafa-4d73-aabe-2c5f8a07b359", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# This computes the matrix multiplication between two tensors. y1, y2, y3 will have the same value\n", + "y1 = tensor @ tensor.T\n", + "y2 = tensor.matmul(tensor.T)\n", + "\n", + "y3 = torch.rand_like(y1)\n", + "torch.matmul(tensor, tensor.T, out=y3)\n", + "\n", + "\n", + "# This computes the element-wise product. z1, z2, z3 will have the same value\n", + "z1 = tensor * tensor\n", + "z2 = tensor.mul(tensor)\n", + "\n", + "z3 = torch.rand_like(tensor)\n", + "torch.mul(tensor, tensor, out=z3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "PWuFy1EwGs0H", + "outputId": "85d8845a-c691-47e9-8e93-26315c469bf3", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# GPU via CUDA\n", + "# torch.randn(5).cuda()\n", + "# better (more flexible):\n", + "device = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\"cpu\")\n", + "torch.randn(5).to(device)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "CX_XMFuTmlzi", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 2 Datasets and DataLoaders" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zryt62ZKmyVp", + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "- datasets: stores the samples and their corresponding labels\n", + "- DataLoader: wraps an iterable around the Dataset to enable easy access to the samples" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "lZT2YnVMu96w", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# import and split data\n", + "train_data = datasets.MNIST(\n", + " \"data\", train=True, download=True, transform=transforms.ToTensor()\n", + ")\n", + "train, val = random_split(train_data, [55000, 5000])\n", + "train_loader = DataLoader(train, batch_size=32)\n", + "val_loader = DataLoader(val, batch_size=32)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 466 + }, + "id": "6BhOxZy-nHP0", + "outputId": "1e07d5b6-0c13-4366-8da0-54f9f1a07881", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "figure = plt.figure(figsize=(8, 8))\n", + "cols, rows = 3, 3\n", + "for i in range(1, cols * rows + 1):\n", + " sample_idx = torch.randint(len(train_data), size=(1,)).item()\n", + " img, label = train_data[sample_idx]\n", + " figure.add_subplot(rows, cols, i)\n", + " plt.axis(\"off\")\n", + " plt.imshow(img.squeeze(), cmap=\"gray\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 319 + }, + "id": "EsmxozRsnXA9", + "outputId": "43701d04-f650-49ec-d29a-18a3cbbf006e", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "train_features, train_labels = next(iter(train_loader))\n", + "print(f\"Feature batch shape: {train_features.size()}\")\n", + "print(f\"Labels batch shape: {train_labels.size()}\")\n", + "img = train_features[0].squeeze()\n", + "label = train_labels[0]\n", + "plt.imshow(img, cmap=\"gray\")\n", + "plt.show()\n", + "print(f\"Label: {label}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bZqXqXe5n33K", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 3 Coding a neural network" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZQqu_MGNM9mE", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# in theory easy via stateless approach\n", + "# import torch.nn.functional as F\n", + "\n", + "# loss_func = F.cross_entropy\n", + "\n", + "# def model(xb):\n", + "# return xb @ weights + bias\n", + "\n", + "# print(loss_func(model(xb), yb), accuracy(model(xb), yb))\n", + "# gets messy quickly!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "HigdC6uGHfdQ", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# define model via explicit nn.Module class\n", + "class MyModel(nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.l1 = nn.Linear(28 * 28, 64)\n", + " self.l2 = nn.Linear(64, 64)\n", + " self.l3 = nn.Linear(64, 10)\n", + " self.do = nn.Dropout(0.1)\n", + "\n", + " def forward(self, x):\n", + " h1 = nn.functional.relu(self.l1(x))\n", + " h2 = nn.functional.relu(self.l2(h1))\n", + " do = self.do(h2 + h1) # residual connection\n", + " logits = self.l3(do)\n", + " return logits" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OEdxKC9goNxP", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "[nn.Sequential](https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html) is an ordered container of modules; good for easy and quick networks. No need to specify forward method!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "RM9PGgqQoqeo", + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# defining model via sequential\n", + "# shorthand, no need for forward method\n", + "model_seq = nn.Sequential(\n", + " nn.Linear(28 * 28, 64),\n", + " nn.ReLU(),\n", + " nn.Linear(64, 64),\n", + " nn.ReLU(),\n", + " nn.Dropout(0.1), # often helps with overfitting\n", + " nn.Linear(64, 10),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "IyB6DSiANTkf", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# move model to GPU/device memory\n", + "model = model_seq.to(device)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A9pgmNmaofHI", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Many layers inside a neural network are parameterized, i.e. have associated weights and biases that are optimized during training. Subclassing nn.Module automatically tracks all fields defined inside your model object, and makes all parameters accessible using your model’s parameters() or named_parameters() methods." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "GyC1MegLofzP", + "outputId": "ae35c0ea-3a89-4b1c-dc9f-ce26a628fade", + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(f\"Model structure: {model}\\n\\n\")\n", + "\n", + "for name, param in model.named_parameters():\n", + " print(f\"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YONSCevnqZUi", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# define loss function\n", + "loss = nn.CrossEntropyLoss() # softmax + neg. log" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "wvofYk8GqSeD", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 4 Backpropagation via Autograd" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0M40WT7jqEt4", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "![Computational graph](https://pytorch.org/tutorials/_images/comp-graph.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZyWtRqDYpSaz", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "In a forward pass, autograd does two things simultaneously:\n", + "\n", + "- run the requested operation to compute a resulting tensor\n", + "\n", + "- maintain the operation’s gradient function in the DAG.\n", + "\n", + "The backward pass kicks off when .backward() is called on the DAG root. autograd then:\n", + "\n", + "- computes the gradients from each .grad_fn,\n", + "\n", + "- accumulates them in the respective tensor’s .grad attribute\n", + "\n", + "- using the chain rule, propagates all the way to the leaf tensors." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Ra6xARRFqbbD", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 5 Optimization of model parameters (training)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DXpp_QiCqi3Z", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "We define the following hyperparameters for training:\n", + "\n", + "- Number of Epochs - the number times to iterate over the dataset\n", + "- Batch Size - the number of data samples propagated through the network before the parameters are updated (defined in train_Loader)\n", + "- Learning Rate - how much to update models parameters at each batch/epoch. Smaller values yield slow learning speed, while large values may result in unpredictable behavior during training." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JgTXf_DbqlZP", + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "lr = 1e-2\n", + "epochs = 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "62yFqEQ-p9qc", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# defining optimizer\n", + "params = model.parameters()\n", + "optimiser = optim.SGD(params, lr=1e-2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I0YUXfJnq7n9", + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Inside the training loop, optimization happens in three steps:\n", + "\n", + "- Call **optimizer.zero_grad()** to reset the gradients of model parameters. Gradients by default add up; to prevent double-counting, we explicitly zero them at each iteration.\n", + "- Backpropagate the prediction loss with a call to **loss.backward()**. PyTorch deposits the gradients of the loss w.r.t. each parameter.\n", + "- Once we have our gradients, we call **optimizer.step()** to adjust the parameters by the gradients collected in the backward pass." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5XwqYKq8ql5G", + "outputId": "2e780ec9-8f22-4c97-a575-eb9f00f5a787", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# define training and validation loop\n", + "# training loop\n", + "for epoch in range(epochs):\n", + " losses = list()\n", + " accuracies = list()\n", + " model.train() # enables dropout/batchnorm\n", + " for batch in train_loader:\n", + " x, y = batch\n", + " batch_size = x.size(0)\n", + " # x: b x 1 x 28 x 28\n", + " x = x.view(batch_size, -1).to(device)\n", + "\n", + " # 5 steps to train network\n", + " # 1 forward\n", + " l = model(x) # l: logits\n", + "\n", + " # 2 compute objective function\n", + " J = loss(l, y.to(device))\n", + "\n", + " # 3 cleaning the gradients (could also call this on optimiser)\n", + " model.zero_grad()\n", + " # optimizer.zero_grad() is equivalent\n", + " # manually: params.grad._zero()\n", + "\n", + " # 4 accumulate the partial derivatives of J wrt params\n", + " J.backward()\n", + " # manually: params.grad.add_(dJ/dparams)\n", + "\n", + " # 5 step in the opposite direction of the gradient\n", + " optimiser.step()\n", + " # could have done manual gradient update:\n", + " # with torch.no_grad():\n", + " # params = params - lr * params.grad\n", + " losses.append(J.item())\n", + " accuracies.append(y.eq(l.detach().argmax(dim=1).cpu()).float().mean())\n", + "\n", + " print(f\"epoch {epoch + 1}\", end=\", \")\n", + " print(f\"training loss: {torch.tensor(losses).mean():.2f}\", end=\", \")\n", + " print(\n", + " f\"training accuracy: {torch.tensor(accuracies).mean():.2f}\"\n", + " ) # print two decimals\n", + "\n", + " # validation loop\n", + " losses = list()\n", + " accuracies = list()\n", + " model.eval() # disables dropout/batchnorm\n", + " for batch in val_loader:\n", + " x, y = batch\n", + " batch_size = x.size(0)\n", + " # x: b x 1 x 28 x 28\n", + " x = x.view(batch_size, -1).to(device)\n", + "\n", + " # 5 steps to train network\n", + " # 1 forward\n", + " with torch.no_grad(): # more efficient, just tensor no graph connected\n", + " l = model(x) # l: logits\n", + "\n", + " # 2 compute objective function\n", + " J = loss(l, y.to(device))\n", + " losses.append(J.item())\n", + " accuracies.append(y.eq(l.detach().argmax(dim=1).cpu()).float().mean())\n", + "\n", + " print(f\"epoch {epoch + 1}\", end=\", \")\n", + " print(f\"validation loss: {torch.tensor(losses).mean():.2f}\", end=\", \")\n", + " print(\n", + " f\"validation accuracy: {torch.tensor(accuracies).mean():.2f}\"\n", + " ) # print two decimals" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BQye3VF6rlMp", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 6 Store models\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "MQbKGqSVrm6E", + "outputId": "1f3eb8f5-3ce4-46fa-999b-df745dc24319", + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# just save model weights without structure\n", + "torch.save(model.state_dict(), \"model_weights.pth\")\n", + "model.load_state_dict(torch.load(\"model_weights.pth\"))\n", + "model.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "njC3UgJer4Zw", + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# save whole model\n", + "torch.save(model, \"model.pth\")\n", + "new_model = torch.load(\"model.pth\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cKqbikpVsccx", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 7 Material sources/more resources:\n", + "- [PyTorch Tutorial Page](https://pytorch.org/tutorials/beginner/basics/)\n", + "- [YouTube Series for PyTorch Lightning](https://www.youtube.com/watch?v=OMDn66kM9Qc)\n", + "- [PyTorch common mistakes video from Alladin Persson](https://www.youtube.com/watch?v=O2wJ3tkc-TU&list=PLhhyoLH6IjfxeoooqP9rhU3HJIAVAJ3Vz&index=14)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "I6HFBPPrrF6A", + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "Extra: interactive debugging during training loop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "3DcFOjNJrJNc", + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [], + "source": [ + "# import pdb; pdb.set_trace() (put these commands after logit computation in training loop)\n", + "# interactive debugger, leave via q\n", + "# you can call the following commands interactively during the training loop\n", + "# p l.size()\n", + "# p l[0]\n", + "# p l[0].detach().argmax()\n", + "# p l[0].detach().softmax(dim=0)\n", + "# p [f\"{prob:.2f}\" for prob in l[0].detach().softmax(dim=0)\n", + "# p y[:4]\n", + "# p l.detach().argmax(dim=1)[:4]\n", + "# p y[:4].eq(l.detach().argmax(dim=1)[:4])\n", + "# p y.eq(l.detach().argmax(dim=1)).float().mean()" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "celltoolbar": "Slideshow", + "colab": { + "collapsed_sections": [], + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3.10.6 64-bit ('3.10.6')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + }, + "vscode": { + "interpreter": { + "hash": "ebbca54691d61843c0a04253fcd790a2bc545e11985b7cc4dd8a14aab0b5083b" + } + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/lunchtime10/lunchtime10.slides.html b/lunchtime10/lunchtime10.slides.html new file mode 100644 index 0000000..4712f24 --- /dev/null +++ b/lunchtime10/lunchtime10.slides.html @@ -0,0 +1,16729 @@ + + + + + + + + + +lunchtime10 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime10/model.pth b/lunchtime10/model.pth new file mode 100644 index 0000000..7a7a6d2 Binary files /dev/null and b/lunchtime10/model.pth differ diff --git a/lunchtime10/model_weights.pth b/lunchtime10/model_weights.pth new file mode 100644 index 0000000..713da7a Binary files /dev/null and b/lunchtime10/model_weights.pth differ diff --git a/lunchtime11/lunchtime11.ipynb b/lunchtime11/lunchtime11.ipynb new file mode 100644 index 0000000..f2865ac --- /dev/null +++ b/lunchtime11/lunchtime11.ipynb @@ -0,0 +1,949 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "SEOtINgnsNVw", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## 25.11.2022: spaCy\n", + "\n", + "\n", + "[spaCy](https://spacy.io/) is an open-source natural language processing library written in Python and Cython.\n", + "\n", + "spaCy focuses on production usage and is very fast and efficient. It also supports deep learning workflows through interfacing with [TensorFlow](https://www.tensorflow.org/) or [PyTorch](https://pytorch.org/), as well as the transformer model library [Hugging Face](https://github.com/huggingface).\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 0 What to do with spaCy" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "spaCy is very powerful for text annotation:\n", + "- sentencize and tokenize\n", + "- POS (part-of-speech) and lemma\n", + "- NER (named entity recognition)\n", + "- dependency parsing\n", + "- text classification\n", + "- morphological analysis\n", + "- pattern matching\n", + "- ...\n", + "\n", + "spaCy can also learn new tasks through integration with your machine learning stack. It also provides multi-task learning with pretrained transformers like [BERT](https://arxiv.org/abs/1810.04805). \n", + "(BERT is used in the google search engine.)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "import spacy\n", + "from spacy import displacy\n", + "\n", + "if \"google.colab\" in str(get_ipython()):\n", + " spacy.cli.download(\"en_core_web_md\")\n", + "nlp = spacy.load(\"en_core_web_md\")\n", + "doc = nlp(\n", + " \"The Scientific Software Center offers lunch-time Python - an informal way to learn about new Python libraries.\"\n", + ")\n", + "displacy.render(doc, style=\"dep\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "displacy.render(doc, style=\"ent\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "n4094EXrlsmY", + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 1 Install spaCy\n", + "You can install spaCy using `pip`:\n", + "\n", + "`pip install spacy`\n", + "\n", + "It is also available via `conda-forge`:\n", + "\n", + "`conda install -c conda-forge spacy`\n", + "\n", + "After installing spaCy, you also need to download the language model. For a medium-sized English model, you would do this using\n", + "\n", + "`python -m spacy download en_core_web_md`\n", + "\n", + "The available models are listed on the spaCy website: https://spacy.io/usage/models" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Install spaCy with CUDA support\n", + "\n", + "`pip install -U spacy[cuda]`\n", + "\n", + "You can also explore the [online tool](https://spacy.io/usage) for installation instructions." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "earp3FM4lg53", + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# 2 Let's try it out!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "nlp = spacy.load(\"en_core_web_md\")\n", + "nlp(\"This is lunch-time Python.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "doc = nlp(\"This is lunch-time Python.\")\n", + "print(type(doc))\n", + "[i for i in doc]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "t = doc[0]\n", + "type(t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "t.ent_id_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "displacy.render(doc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "spacy.explain(\"AUX\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [], + "source": [ + "for t in doc:\n", + " print(t.text, t.pos_, t.dep_, t.lemma_)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 3 Pipelines\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "![pipeline](https://spacy.io/pipeline-fde48da9b43661abcdf62ab70a546d71.svg)\n", + "\n", + "[source: spaCy 101]\n", + "\n", + "The capabilities of the processing pipeline dependes on the components, their models and how they were trained." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "nlp.pipe_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "nlp.tokenizer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "text = \"Python is a very popular - maybe even the most popular - programming language among scientific software developers. One of the reasons for this success story is the rich standard library and the rich ecosystem of available (scientific) libraries. To fully leverage this ecosystem, developers need to stay up to date and explore new libraries. Lunch Time Python aims at providing a communication platform between Pythonistas to learn about new libraries in an informal setting. Sessions take roughly 30 minutes, one library is presented per session and the code will be made available afterwards. Come by, enjoy your lunch with us and step up your Python game!\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(text)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "doc = nlp(text)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "for i, sent in enumerate(doc.sents):\n", + " print(i, sent)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "for i, sent in enumerate(doc.sents):\n", + " for j, token in enumerate(sent):\n", + " print(i, j, token.text, token.pos_)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Adding custom components\n", + "You can add custom pipeline components, for example rule-based or phrase matchers, and add the custom attributes to the `doc`, `token` and `span` objects." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Processing batches of texts\n", + "You can process batches of texts using the `nlp.pipe()` command.\n", + "\n", + "`docs = list(nlp.pipe(LOTS_OF_TEXTS))`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Disabling pipeline components\n", + "To achieve higher efficiency, it is possible to disable pipeline components.\n", + "\n", + "`nlp.select_pipes(disable=[\"ner\"])`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 4 Rule-based matching" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# Import the Matcher\n", + "from spacy.matcher import Matcher\n", + "\n", + "# Initialize the matcher with the shared vocab\n", + "matcher = Matcher(nlp.vocab)\n", + "\n", + "# Add the pattern to the matcher\n", + "python_pattern = [{\"TEXT\": \"Python\", \"POS\": \"PROPN\"}]\n", + "matcher.add(\"PYTHON_PATTERN\", [python_pattern])\n", + "\n", + "doc = nlp(text)\n", + "\n", + "# Call the matcher on the doc\n", + "matches = matcher(doc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# Iterate over the matches\n", + "for match_id, start, end in matches:\n", + " # Get the matched span\n", + " matched_span = doc[start:end]\n", + " print(matched_span.text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 5 Phrase matching\n", + "More efficient than the rule-based matching, can be used for finding sequences of words, and also gives you access to the tokens in context.\n", + "\n", + "- Rule-based matching: find patterns in the tokens (token-based matching)\n", + "- Phrase matching: find exact string; useful for names and if there are several options of tokenizing the string" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "doc = nlp(\n", + " \"The Scientific Software Center supports researchers in developing scientific software.\"\n", + ")\n", + "\n", + "# Import the PhraseMatcher and initialize it\n", + "from spacy.matcher import PhraseMatcher\n", + "\n", + "matcher = PhraseMatcher(nlp.vocab)\n", + "# you can also pass in attributes, for example attr=\"LOWER\" or attr=\"POS\"\n", + "\n", + "# Create pattern Doc objects and add them to the matcher\n", + "term = \"Scientific Software Center\"\n", + "pattern = nlp(term)\n", + "# or use pattern = nlp.make_doc(term) to only invoke tokenizer - more efficient!\n", + "matcher.add(\"SSC\", [pattern])\n", + "\n", + "# Call the matcher on the test document and print the result\n", + "matches = matcher(doc)\n", + "\n", + "for match_id, start, end in matches:\n", + " span = doc[start:end]\n", + " print(span.text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 6 Word vectors and semantic similarity\n", + "spaCy can compare two objects and predict similarity:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "text1 = \"I like Python.\"\n", + "text2 = \"I like snakes.\"\n", + "\n", + "\n", + "doc1 = nlp(text1)\n", + "doc2 = nlp(text2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(doc1.similarity(doc2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "token1 = doc1[2]\n", + "token2 = doc2[2]\n", + "print(token1.text, token2.text)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(token1.similarity(token2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "The similarity score is generated from word vectors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(token1.vector)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Similarity can be used to predict similar texts to users, or to flag duplicate content. \n", + "\n", + "But: Similarity always depends on the context." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "text3 = \"I hate snakes.\"\n", + "doc3 = nlp(text3)\n", + "print(doc2.similarity(doc3))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "These come out similar as both statements express a sentiment." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 7 Internal workings\n", + "spaCy stores all strings as hash values and creates a lookup table. This way, a word that occurs several times only needs to be stored once." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "nlp.vocab.strings.add(\"python\")\n", + "python_hash = nlp.vocab.strings[\"python\"]\n", + "python_string = nlp.vocab.strings[python_hash]\n", + "print(python_hash, python_string)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "- lexemes are entries in the vocabulary and contain context-independent information (the text, hash, lexical attributes).\n", + "![data structure](https://course.spacy.io/vocab_stringstore.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 8 Train your own model\n", + "![training_scheme](https://course.spacy.io/training.png)\n", + "[source: spaCy online course]\n", + "\n", + "Training data: Annotated text \n", + "Text: The input text that the model should label \n", + "Label: The label that the model should predict \n", + "Gradient: How to change the weights" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## The training data\n", + "- Examples in context\n", + "- Update existing model: a few hundred to a few thousand examples\n", + "- Train a new category: a few thousand to a million examples\n", + "- Created manually by human annotators\n", + "- Use matcher to semi-automatize\n", + "\n", + "Also need evaluation data." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Create a training corpus" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from spacy.tokens import Span\n", + "\n", + "nlp = spacy.blank(\"en\")\n", + "\n", + "# Create a Doc with entity spans\n", + "doc1 = nlp(\"iPhone X is coming\")\n", + "doc1.ents = [Span(doc1, 0, 2, label=\"GADGET\")]\n", + "# Create another doc without entity spans\n", + "doc2 = nlp(\"I need a new phone! Any tips?\")\n", + "\n", + "docs = [doc1, doc2] # and so on..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Configuring the training\n", + "The training `config.cfg` contains the settings for the training, such as configuration of the pipeline and setting of hyperparameters." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```\n", + "[nlp]\n", + "lang = \"en\"\n", + "pipeline = [\"tok2vec\", \"ner\"]\n", + "batch_size = 1000\n", + "\n", + "[nlp.tokenizer]\n", + "@tokenizers = \"spacy.Tokenizer.v1\"\n", + "\n", + "[components]\n", + "\n", + "[components.ner]\n", + "factory = \"ner\"\n", + "\n", + "[components.ner.model]\n", + "@architectures = \"spacy.TransitionBasedParser.v2\"\n", + "hidden_width = 64\n", + "...\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Use the [quickstart-widget](https://spacy.io/usage/training#quickstart) to initialize a config." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## That's it! All you need is the training and evaluation data and the config.\n", + "`python -m spacy train ./config.cfg --output ./output --paths.train train.spacy --paths.dev dev.spacy`\n", + "\n", + "After you have completed the training, the model can be loaded and used with `spacy.load()`.\n", + "\n", + "You can also package and deploy your pipeline so others can use it." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## A few notes on training\n", + "- If you update existing models, previously predicted categories can be unlearned (\"catastrophic forgetting\")!\n", + "- Labels need to be consistent and not too specific" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 9 spaCy transformers\n", + "You can load in transformer models using `spacy-transformers`:\n", + "\n", + "`pip install spacy-transformers`\n", + "\n", + "Remember that transformer models work with context, so if you have a list of terms with no context around them (say, titles of blog posts), a transformer model may not be the best choice.\n", + "\n", + "![transformer_pipeline](https://spacy.io/pipeline_transformer-3464b402cf7b19c3dd1efe1c0b4336dd.svg)\n", + "[source: spaCy documentation]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "transformer-based pipelines end in `_trf`:\n", + "\n", + "`python -m spacy download en_core_web_trf`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 10 Further information" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# spaCy demos\n", + "- You can explore spaCy using [online tools](https://explosion.ai/software)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "For example, the [rule-based matcher explorer](https://demos.explosion.ai/matcher) -" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "- or the [spaCy online course](https://course.spacy.io/en/).\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Example use cases\n", + "- [Detection of programming language in stackoverflow posts](https://github.com/koaning/spacy-youtube-material)\n", + "- take a look at [spaCy projects](https://spacy.io/usage/projects)!\n" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "celltoolbar": "Slideshow", + "colab": { + "collapsed_sections": [], + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.1" + }, + "vscode": { + "interpreter": { + "hash": "ebbca54691d61843c0a04253fcd790a2bc545e11985b7cc4dd8a14aab0b5083b" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/lunchtime11/lunchtime11.slides.html b/lunchtime11/lunchtime11.slides.html new file mode 100644 index 0000000..011de27 --- /dev/null +++ b/lunchtime11/lunchtime11.slides.html @@ -0,0 +1,17243 @@ + + + + + + + + + +lunchtime11 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime12/lunchtime12.ipynb b/lunchtime12/lunchtime12.ipynb new file mode 100644 index 0000000..c5c67e5 --- /dev/null +++ b/lunchtime12/lunchtime12.ipynb @@ -0,0 +1,855 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "notes" + } + }, + "source": [ + "# Relevant Links:\n", + "\n", + "\n", + "- Docs: https://dash.plotly.com/dash-core-components \n", + "- Style-sheets: https://dash.plotly.com/external-resources\n", + "- callbacks: https://dash.plotly.com/pattern-matching-callbacks\n", + "- dash enrich: https://www.dash-extensions.com/getting_started/enrich\n", + "- examples: https://dash.gallery/Portal/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Welcome to Dash\n", + "\n", + "### UI elements for both websites and jupyter notebooks\n", + "\n", + "Dash is a comparatively easy and stable way to build standalone or jupyter based widgets/apps.
\n", + "It is based on `flask` and `react.js` this combined with the html elements of dash enables one to write interactive and scalable webpages without knowing JavaScript or HTML.
\n", + "Since it is flask based dash servers can be deployed in the same way as a standalone web service.
\n", + "Originally Dash is designed for web applications but with the help of the `jupyter-dash` library it works very well in notebooks.\n", + "\n", + "\n", + "All components listed here can also be found under https://dash.plotly.com/dash-core-components for a more in depth documentation.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "notes" + } + }, + "source": [ + "Simple text is automatically shown side by side:
\n", + "`html.Div([\"some nested text \", \"some parallel text\"]),`
\n", + "while nested Div's are shown side by side:
\n", + "`html.Div([html.Div(\"some nested text \"), html.Div(\"some parallel text\")])`
\n", + "Unless you use the style property to change the display property to inline-block:
\n", + "`html.Div([html.Div(\"some nested text \", style={\"display\":\"inline-block\"}), html.Div(\"some parallel text\", style={\"display\":\"inline-block\"})],),`\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install dash jupyter_dash dash_extensions -qqq\n", + "import plotly.express as px\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [], + "source": [ + "from dash import Dash, dcc, html\n", + "import jupyter_dash" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The UI is defined as a hierarchy of HTML components inside the app.layout.\n", + "Many dash objects have a `children` attribute that we can put more dash objects into. \n", + "The most commonly used structuring tool is `html.Div`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "basic_layout = html.Div(\n", + " children=[\n", + " html.Div([\"some nested text \", \"some parallel text\"]),\n", + " html.Br(), # this is just a line break\n", + " html.Div([html.Div(\"some nested text \"), html.Div(\"some parallel text\")]),\n", + " html.Br(),\n", + " html.Div(\n", + " [\n", + " html.Div(\n", + " \"some nested text \",\n", + " style={\"display\": \"inline-block\"},\n", + " ),\n", + " html.Div(\n", + " \"some parallel text\",\n", + " style={\"display\": \"inline-block\"},\n", + " ),\n", + " ],\n", + " ),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# standalone dash server\n", + "app1 = Dash(\"app1\")\n", + "\n", + "app1.layout = basic_layout\n", + "# app1.run_server(debug=True, port=5050, use_reloader=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "This would run a dash server and provide an ip address to open the app in a new browser tab.\n", + "However this does not really work in jupyter notebooks as the cell never actually finishes.\n", + "\n", + "A better solution inside Notebooks is the `jupyter-dash` library. This enables us to run the entire notebook while either calling dash in a standalone mode or `inline`. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + }, + "tags": [ + "nbval-ignore-output" + ] + }, + "outputs": [], + "source": [ + "app2 = jupyter_dash.JupyterDash(\"app2\")\n", + "app2.layout = basic_layout\n", + "app2.run_server(debug=True, port=8071, mode=\"inline\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Styling and components\n", + "With the `style` argument most dash components can be changed according to the css standard.\n", + "\n", + "Most dash components are found under `dcc`, though some are in `html`.
\n", + "With just these we can generate a UI that can't really do anything yet.
\n", + "For data visualization Dash works very well with the `plotly` library.\n", + "\n", + "\n", + "Note: Dash also supports css style sheets. See: https://dash.plotly.com/external-resources\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "external_stylesheets = [\"https://codepen.io/chriddyp/pen/bWLwgP.css\"]\n", + "my_style = {\"width\": \"30%\", \"margin-top\": \"20px\", \"margin-bottom\": \"20px\"}\n", + "\n", + "app3 = jupyter_dash.JupyterDash(\"app3\", external_stylesheets=external_stylesheets)\n", + "\n", + "app3.layout = html.Div(\n", + " [\n", + " \"Choosing and displaying a function:\",\n", + " dcc.Dropdown(\n", + " options=[\"x^2\", \"2x\", \"e^x\"],\n", + " value=\"x^2\",\n", + " style=my_style,\n", + " ),\n", + " html.Div(\n", + " dcc.RangeSlider(min=0, max=20, step=1, value=[5, 15]),\n", + " style={\"width\": \"50%\"},\n", + " ),\n", + " html.Button(\n", + " \"Click_me\",\n", + " style=my_style,\n", + " ),\n", + " dcc.Graph(),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + }, + "tags": [ + "nbval-ignore-output" + ] + }, + "outputs": [], + "source": [ + "app3.run_server(debug=True, port=8072, mode=\"inline\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Callbacks\n", + "With the use of callbacks we can now add functionality to all our elements.\n", + "\n", + "In this example I want to be able to choose a function type, set the x limits for the calculation and show the graph upon clicking the button.\n", + "\n", + "The Dash callbacks allow us to access and monitor each object variable.
\n", + "For this to work we first need to assign IDs to every object we want to interact with.
\n", + "Many of the Dividers for example don't need a specific ID.
\n", + "\n", + "\n", + "Note that even though the `n_click` value of the button is not used it must still be the first function argument since its the value we want to observe." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "app4 = jupyter_dash.JupyterDash(\"app4\")\n", + "\n", + "app4.layout = html.Div(\n", + " [\n", + " \"Choosing and displaying a function:\",\n", + " dcc.Dropdown(\n", + " options=[\"x^2\", \"2x\", \"e^x\"],\n", + " value=\"x^2\",\n", + " style=my_style,\n", + " id=\"dropdown\",\n", + " ),\n", + " html.Div(\n", + " dcc.RangeSlider(\n", + " min=0,\n", + " max=20,\n", + " step=1,\n", + " value=[5, 15],\n", + " id=\"slider\",\n", + " ),\n", + " style={\"width\": \"50%\"},\n", + " ),\n", + " html.Button(\n", + " \"Click_me\",\n", + " style=my_style,\n", + " id=\"button\",\n", + " ),\n", + " dcc.Graph(id=\"graph\"),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Callbacks can have as many inputs and outputs as needed.
\n", + "Any component provided as `Input` will trigger the callback, while `State` can be used to obtain certain variables without triggering the function.
\n", + "Basically every property of the selected object can be interacted with.
\n", + "Eg.: One can give an ID to a `html.Div` and attach to or rewrite its children attribute, thus potentially rewriting the entire app within one callback.\n", + "\n", + "\n", + "Lastly `Output` is used to define which object the return value will be assigned to.\n", + "The order of function and return arguments is dependent on the order in the decorator.\n", + "`Ouput, Ìnput`and `State` must always be used in exactly this order." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from dash import Input, Output, State\n", + "\n", + "\n", + "@app4.callback(\n", + " Output(\"graph\", \"figure\"),\n", + " Input(\"button\", \"n_clicks\"),\n", + " State(\"dropdown\", \"value\"),\n", + " State(\"slider\", \"value\"),\n", + ")\n", + "def update_graph(n_clicks, dropdown_value, slider_value):\n", + " def _plot_function(x, function_name):\n", + " if function_name == \"x^2\":\n", + " return x**2\n", + " elif function_name == \"2x\":\n", + " return 2 * x\n", + " elif function_name == \"e^x\":\n", + " return np.exp(x)\n", + " else:\n", + " raise ValueError(f\"Unknown function_name: {function_name}\")\n", + "\n", + " x_range = np.linspace(slider_value[0], slider_value[1], 100)\n", + " y = _plot_function(x_range, dropdown_value)\n", + " figure = px.line(x=x_range, y=y, title=dropdown_value)\n", + "\n", + " return figure" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "notes" + } + }, + "outputs": [], + "source": [ + "# what happens if I deselect the functions?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + }, + "tags": [ + "nbval-ignore-output" + ] + }, + "outputs": [], + "source": [ + "app4.run_server(debug=True, port=8073, mode=\"inline\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Dynamically add more widgets\n", + "\n", + "So far we have only considered static IDs and that is fine for many work cases. However sometimes it might be necessary to add widgets inside of callbacks.\n", + "An example for this could be the creation of a new tab with its own button and text on the inside.\n", + "\n", + "\n", + "For these callbacks dash provides three patterns `MATCH` `ALL` and `AllSMALLER`.\n", + "Here I will only go over `MATCH`, for more information see https://dash.plotly.com/pattern-matching-callbacks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from dash.dependencies import MATCH\n", + "\n", + "app5 = jupyter_dash.JupyterDash(\"app5\", external_stylesheets=external_stylesheets)\n", + "\n", + "app5.layout = html.Div(\n", + " [\n", + " html.Button(\"Add Tab\", id=\"button_add_tab\"),\n", + " dcc.Tabs(id=\"tabs\", children=[]),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "@app5.callback(\n", + " Output(\"tabs\", \"children\"),\n", + " Input(\"button_add_tab\", \"n_clicks\"),\n", + " State(\"tabs\", \"children\"),\n", + " prevent_initial_call=True,\n", + ")\n", + "def add_tab(n_clicks, tabs_children):\n", + " new_tab = dcc.Tab(\n", + " label=f\"Tab {n_clicks}\",\n", + " children=[\n", + " html.Div(\n", + " [\n", + " html.Button(\n", + " f\"Button {n_clicks}\",\n", + " id={\"type\": \"button_tab\", \"index\": n_clicks},\n", + " ),\n", + " html.Div(\n", + " f\"Button {n_clicks} clicked 0 times. \",\n", + " id={\"type\": \"div_tab\", \"index\": n_clicks},\n", + " ),\n", + " ]\n", + " )\n", + " ],\n", + " )\n", + " tabs_children.append(new_tab)\n", + " return tabs_children" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "@app5.callback(\n", + " Output({\"type\": \"div_tab\", \"index\": MATCH}, \"children\"),\n", + " Input({\"type\": \"button_tab\", \"index\": MATCH}, \"n_clicks\"),\n", + " State({\"type\": \"button_tab\", \"index\": MATCH}, \"id\"),\n", + " prevent_initial_call=True,\n", + ")\n", + "def tabs_button_click(n_clicks, button_id):\n", + " return f\"Button {button_id['index']} clicked {n_clicks} times. \"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + }, + "tags": [ + "nbval-ignore-output" + ] + }, + "outputs": [], + "source": [ + "app5.run_server(debug=True, port=8074, mode=\"inline\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Using dash inside a class\n", + "\n", + "Unfortunately the decorator style of dashs callbacks we have used so far is very much incompatible with encapsulating the dash app inside a class. \n", + "Normally the app itself is to be used in the whole module.
\n", + "`@self.app.callback()` or smililar things don't work.\n", + "However we can simply refer any function as a callback as seen here:\n", + "\n", + "##### A piece of warning though: \n", + "The [dash website](https://dash.plotly.com/sharing-data-between-callbacks) advices against using a callback to access out of scope data or variables. As far as I can tell this is only relevant when deploying the dash server in a way that multiple user access the same instance and it should not be a problem for local or cloud hosted python environments.\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "class App6:\n", + " def __init__(self):\n", + " external_stylesheets = [\"https://codepen.io/chriddyp/pen/bWLwgP.css\"]\n", + " self.app6 = jupyter_dash.JupyterDash(\n", + " \"app6\", external_stylesheets=external_stylesheets\n", + " )\n", + " my_style = {\n", + " \"width\": \"50%\",\n", + " \"margin-top\": \"20px\",\n", + " \"margin-bottom\": \"20px\",\n", + " }\n", + " self.app6.layout = html.Div(\n", + " [\n", + " \"Choosing and displaying a function:\",\n", + " dcc.Dropdown(\n", + " options={\"x^2\": \"quadratic\", \"2x\": \"linear\", \"e^x\": \"exponential\"},\n", + " value=\"x^2\",\n", + " style=my_style,\n", + " id=\"dropdown\",\n", + " ),\n", + " html.Div(\n", + " dcc.RangeSlider(\n", + " min=0,\n", + " max=20,\n", + " step=1,\n", + " value=[5, 15],\n", + " id=\"slider\",\n", + " ),\n", + " style={\"width\": \"50%\"},\n", + " ),\n", + " html.Button(\n", + " \"Click_me\",\n", + " style=my_style,\n", + " id=\"button\",\n", + " ),\n", + " dcc.Graph(id=\"graph\"),\n", + " ]\n", + " )\n", + " self.app6.callback(\n", + " Output(\"graph\", \"figure\"),\n", + " Input(\"button\", \"n_clicks\"),\n", + " State(\"dropdown\", \"value\"),\n", + " State(\"slider\", \"value\"),\n", + " )(self.update_graph)\n", + "\n", + " def update_graph(self, n_clicks, dropdown_value, slider_value):\n", + " def _plot_function(x, function_name):\n", + " if function_name == \"x^2\":\n", + " return x**2\n", + " elif function_name == \"2x\":\n", + " return 2 * x\n", + " elif function_name == \"e^x\":\n", + " return np.exp(x)\n", + " elif function_name == None:\n", + " return None\n", + " else:\n", + " raise ValueError(\n", + " f\"Unknown function_name: {function_name}, type: {type(function_name)}\"\n", + " )\n", + "\n", + " x_range = np.linspace(slider_value[0], slider_value[1], 100)\n", + " y = _plot_function(x_range, dropdown_value)\n", + " if y is not None:\n", + " figure = px.line(x=x_range, y=y, title=dropdown_value)\n", + " else:\n", + " figure = px.line()\n", + "\n", + " return figure\n", + "\n", + " def run(self, port=8081):\n", + " self.app6.run_server(debug=True, port=port, mode=\"inline\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + }, + "tags": [ + "nbval-ignore-output" + ] + }, + "outputs": [], + "source": [ + "app_6 = App6()\n", + "app_6.run(port=8811)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Additional Dash Components\n", + "\n", + "- [Download button](https://dash.plotly.com/dash-core-components/download)\n", + "- [Upload button](https://dash.plotly.com/dash-core-components/upload)\n", + "- [Data Tables from pandas](https://dash.plotly.com/datatable)\n", + "- [Bio and molecule viewer](https://dash.plotly.com/dash-bio)\n", + "- [Many more]( https://dash.plotly.com/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "# Extended dash functionality \n", + "\n", + "\n", + "- [Dash Extensions - Enrich](https://www.dash-extensions.com/getting_started/enrich)\n", + "- [Dash json viewer](https://github.com/ghandic/dash_renderjson)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Dash extensions DashBlueprint\n", + "\n", + "Blueprints can be used to create and plan dash layouts and callbacks. Because these blueprints do not call the DashApp directly they can be created in differend scopes, files or libraries and later imported when needed. \n", + "This can help keep the actual code much cleaner." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from dash_extensions.enrich import DashBlueprint, DashProxy # , html, Output, Input\n", + "\n", + "bp = DashBlueprint()\n", + "\n", + "bp.layout = html.Div(\n", + " [\n", + " \"Choosing and displaying a function:\",\n", + " dcc.Dropdown(\n", + " options=[\"x^2\", \"2x\", \"e^x\"],\n", + " value=\"x^2\",\n", + " style=my_style,\n", + " id=\"dropdown\",\n", + " ),\n", + " html.Div(\n", + " dcc.RangeSlider(\n", + " min=0,\n", + " max=20,\n", + " step=1,\n", + " value=[5, 15],\n", + " id=\"slider\",\n", + " ),\n", + " style={\"width\": \"50%\"},\n", + " ),\n", + " html.Button(\n", + " \"Click_me\",\n", + " style=my_style,\n", + " id=\"button\",\n", + " ),\n", + " dcc.Graph(id=\"graph\"),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "@bp.callback(\n", + " Output(\"graph\", \"figure\"),\n", + " Input(\"button\", \"n_clicks\"),\n", + " State(\"dropdown\", \"value\"),\n", + " State(\"slider\", \"value\"),\n", + ")\n", + "def update_graph2(n_clicks, dropdown_value, slider_value):\n", + " def _plot_function(x, function_name):\n", + " if function_name == \"x^2\":\n", + " return x**2\n", + " elif function_name == \"2x\":\n", + " return 2 * x\n", + " elif function_name == \"e^x\":\n", + " return np.exp(x)\n", + " else:\n", + " raise ValueError(f\"Unknown function_name: {function_name}\")\n", + "\n", + " x_range = np.linspace(slider_value[0], slider_value[1], 100)\n", + " y = _plot_function(x_range, dropdown_value)\n", + " figure = px.line(x=x_range, y=y, title=dropdown_value)\n", + "\n", + " return figure" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "app7 = DashProxy(blueprint=bp)\n", + "# app7.run_server()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The problem here is that DashProxy and JupyterDash are not compatible.\n", + "If you run `DashProxy.run_server()` in a notebook the cell will never finish. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Personal grievances\n", + "\n", + "I have two problems with dash that I have not found a good solution for.\n", + "\n", + "- First is that dash code can get very convoluted and messy.
\n", + " Extracting part of the layout into individual functions can help a lot, but it still mostly looks messy.\n", + "\n", + "- Second is Dash's tendency to swallow error messages, especially inside a notebook.
\n", + "This can be somewhat circumvented by running dash in a browser as that at least provides you with some of the messages. But mostly its just annoying.
\n", + "Also printing and logging doesn't always work either\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "And to finish off small more comprehensive examples:\n", + "- https://dash.gallery/named-entity-recognition/\n", + "- https://dash.gallery/dash-opioid-epidemic/\n", + "- https://dash.gallery/Portal/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.1" + }, + "rise": { + "scroll": true + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/lunchtime12/lunchtime12.slides.html b/lunchtime12/lunchtime12.slides.html new file mode 100644 index 0000000..6659545 --- /dev/null +++ b/lunchtime12/lunchtime12.slides.html @@ -0,0 +1,16428 @@ + + + + + + + + + +lunchtime12 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime2/README.md b/lunchtime2/README.md new file mode 100644 index 0000000..34a9f70 --- /dev/null +++ b/lunchtime2/README.md @@ -0,0 +1,7 @@ +# Lunchtime #2: SymPy (Nov. 26) + +[SymPy](https://www.sympy.org/) is a Python library for symbolic mathematics. +It can parse mathematical expressions, substitute, differentiate, integrate and evaluate them, as well as solve algebraic and differential equations. +It is also itself written entirely in Python, with a focus keeping the code comprehensible and easily extensible. +There is also a related project [SymEngine](https://github.com/symengine/symengine.py), +which is written in C++ with a focus on speed, which offers a much faster implementation of a subset of SymPy's functionality. \ No newline at end of file diff --git a/lunchtime2/lunchtime2.ipynb b/lunchtime2/lunchtime2.ipynb new file mode 100644 index 0000000..24fd164 --- /dev/null +++ b/lunchtime2/lunchtime2.ipynb @@ -0,0 +1,1158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## Lunch 2: SymPy\n", + "\n", + "\n", + "\n", + "[SymPy](https://www.sympy.org/) is a Python library for symbolic mathematics.\n", + "It can parse mathematical expressions, substitute, differentiate, integrate and evaluate them, as well as solve algebraic and differential equations.\n", + "It is also itself written entirely in Python, with a focus keeping the code comprehensible and easily extensible.\n", + "There is also a related project [SymEngine](https://github.com/symengine/symengine.py),\n", + "which is written in C++ with a focus on speed, which offers a much faster implementation of a subset of SymPy's functionality.\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# SymPy Installation\n", + "\n", + "- Anaconda: pre-installed\n", + "- Conda: `conda install sympy`\n", + "- Pip: `python -m pip install sympy`\n", + "\n", + "Or try it out online:\n", + "\n", + "- [live.sympy.org](https://live.sympy.org/)\n", + " - online python shell with SymPy installed\n", + "- [sympygamma.com](https://www.sympygamma.com/input/?i=cos%28x%29)\n", + " - SymPy powered web app similar to [Wolfram|Alpha](https://www.wolframalpha.com/)\n", + "- [this notebook on binder](https://mybinder.org/v2/gh/ssciwr/lunch-time-python.git/HEAD?labpath=lunchtime2%2Flunchtime2.ipynb)\n", + " - interactive version of this notebook on binder\n" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Symbols\n", + "\n", + "- basic building block of expressions\n", + "- `sympy.symbols`\n", + " - takes a string of variable names separated by spaces\n", + " - returns a tuple of Symbol objects, one for each name\n", + " - usually a good idea to use the same name for the Python object, but you don't have to" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "import sympy as sp\n", + "\n", + "# Define a single symbol x named 'x':\n", + "\n", + "x = sp.symbols(\"x\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "x" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "type(x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# Define multiple symbols at once:\n", + "\n", + "y, z, t, nu = sp.symbols(\"y z t nu\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# Can use different name for symbol & object (not recommended!)\n", + "\n", + "confusing = sp.symbols(\"alpha\")\n", + "print(confusing)" + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Expressions\n", + "\n", + "- Symbols can be combined with the usual arithmetic operations (`+`, `-`, `*`, `/`)\n", + "- Result is an expression\n", + "- The type of an expression depends on the operation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr = x + y - 2 * z" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "type(expr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr.args" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "type(expr.args[2])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr.args[2].args" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Numbers\n", + "\n", + "- will automatically convert to SymPy Numbers when required\n", + "- but take care with math only involving Python numbers!\n", + "- sometimes an explicit conversion is helpful" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "x + 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "type((1 + x).args[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "type((123 + x).args[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# be careful with unexpected Python maths!\n", + "x + 1 / 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# explicit construction of Rational\n", + "x + sp.Rational(1, 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# explicit construction of Integer\n", + "x + sp.Integer(1) / 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# equivalent but now all operations involve a sympy expr:\n", + "(2 * x + 1) / 2" + ] + }, + { + "cell_type": "markdown", + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Functions\n", + "\n", + "- `sympy.functions` contains many built-in analytic functions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr = sp.sin(x) * sp.exp(y) + sp.gamma(t)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Substitution\n", + "\n", + "- evaluate an expression by substituting numbers for symbols\n", + "- substitute sub-expressions for sub-expressions\n", + "- `.subs` takes a list of `(old, new)` pairs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "(x + 1).subs(x, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "(x * sp.cos(y)).subs([(x, 1), (y, 0.2)])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "(x * y).subs(x, y**3)" + ] + }, + { + "cell_type": "markdown", + "id": "30", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Parsing\n", + "\n", + "- `sympify` converts a string into a SymPy expression\n", + "- existing symbols are used if the name matches\n", + "- otherwise new symbols will be created as necessary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr = sp.sympify(\"x\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "type(expr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr == x" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "expr = sp.sympify(\"cos(x) + a\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr.args[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr.args[1].args[0] == x" + ] + }, + { + "cell_type": "markdown", + "id": "38", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Evaluating\n", + "\n", + "- `evalf` for one off numerical evaluation of an expression\n", + " - can take a dict of `Symbol : number` pairs\n", + "- `lambdify` for efficient repeated evaluation of an expression\n", + " - replaces sympy functions like `sin`, `cos` with numpy equivalents" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "sp.sqrt(2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.sqrt(2).evalf()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "41", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr = sp.sqrt(1 + x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr.evalf(subs={x: 1})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "f = sp.lambdify(x, expr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "f(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "a = np.array([1, 2, 3, 5.21])\n", + "f(a)" + ] + }, + { + "cell_type": "markdown", + "id": "47", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Simplification\n", + "\n", + "- `simplify` applies various simplifications to an expression\n", + "- `expand` expands a polynomial to a sum of monomials\n", + "- `factor` looks for common terms to factorize a polynomial\n", + "- `collect` collects common powers of a term\n", + "- as well as [many more](https://docs.sympy.org/latest/tutorial/simplification.html)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "sp.cos(x) ** 2 + sp.sin(x) ** 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.simplify(sp.cos(x) ** 2 + sp.sin(x) ** 2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "50", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.gamma(x) / sp.gamma(x - 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.simplify(sp.gamma(x) / sp.gamma(x - 3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "52", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "(z + t) ** 2 * (x + 2 * y) ** 6" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(sp.expand((z + t) ** 2 * (x + 2 * y) ** 6))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "sp.factor(\n", + " t**2 * x**6\n", + " + 12 * t**2 * x**5 * y\n", + " + 60 * t**2 * x**4 * y**2\n", + " + 160 * t**2 * x**3 * y**3\n", + " + 240 * t**2 * x**2 * y**4\n", + " + 192 * t**2 * x * y**5\n", + " + 64 * t**2 * y**6\n", + " + 2 * t * x**6 * z\n", + " + 24 * t * x**5 * y * z\n", + " + 120 * t * x**4 * y**2 * z\n", + " + 320 * t * x**3 * y**3 * z\n", + " + 480 * t * x**2 * y**4 * z\n", + " + 384 * t * x * y**5 * z\n", + " + 128 * t * y**6 * z\n", + " + x**6 * z**2\n", + " + 12 * x**5 * y * z**2\n", + " + 60 * x**4 * y**2 * z**2\n", + " + 160 * x**3 * y**3 * z**2\n", + " + 240 * x**2 * y**4 * z**2\n", + " + 192 * x * y**5 * z**2\n", + " + 64 * y**6 * z**2\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "55", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Differentiation\n", + "\n", + "- `sympy.diff` differentiates expressions\n", + " - `diff(f, x)` : $df/dx$\n", + " - `diff(f, x, 3)` : $d^3f/dx^3$\n", + " - `diff(f, x, y, z)` : $d^3f/dxdydz$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.diff(expr, x)" + ] + }, + { + "cell_type": "markdown", + "id": "58", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Integration\n", + "\n", + "- `sympy.integrate` integrates expressions\n", + " - indefinite by default, without the integration constant\n", + " - definite if tuple of `(Symbol, lower_limit, upper_limit)` is provided" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "60", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.integrate(expr, x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "sp.integrate(expr, (x, 0, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sp.diff(sp.integrate(expr, x), x)" + ] + }, + { + "cell_type": "markdown", + "id": "63", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Limits\n", + "\n", + "- `sympy.limit` takes limit of expression at singular point" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "64", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sinc = sp.sin(x) / x" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sinc.subs(x, 0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "66", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sinc.limit(x, 0)" + ] + }, + { + "cell_type": "markdown", + "id": "67", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Series expansion\n", + "\n", + "- `sympy.series` expands an expression around a point" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "68", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sinc.series(x, 0, 10)" + ] + }, + { + "cell_type": "markdown", + "id": "69", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# SymEngine\n", + "\n", + "- Fast C++ implementation of (some of) SymPy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "expr = sp.cos(x + 7 * x**2) + sp.sin(x - 2 * x**3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "71", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%time _ = (sp.series(expr, n=100))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install symengine -qqq\n", + "import symengine as se\n", + "\n", + "%time _ = se.series(expr, n=100)" + ] + }, + { + "cell_type": "markdown", + "id": "73", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# More at [docs.sympy.org](https://docs.sympy.org/)\n", + "\n", + "- Algebraic equation solving\n", + "- Differential equation solving\n", + "- Matrices\n", + "- Assumptions\n", + "- Printing\n", + "- Code generation\n", + "\n", + "## [ssciwr.github.io/lunch-time-python](https://ssciwr.github.io/lunch-time-python/)" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime2/lunchtime2.slides.html b/lunchtime2/lunchtime2.slides.html new file mode 100644 index 0000000..4dedd04 --- /dev/null +++ b/lunchtime2/lunchtime2.slides.html @@ -0,0 +1,17663 @@ + + + + + + + + + +lunchtime2 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime3/README.md b/lunchtime3/README.md new file mode 100644 index 0000000..bb22d0b --- /dev/null +++ b/lunchtime3/README.md @@ -0,0 +1,4 @@ +# Lunchtime #3: Click (Jan. 22) + +[Click](https://click.palletsprojects.com/en/8.0.x/) is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. diff --git a/lunchtime3/click1.py b/lunchtime3/click1.py new file mode 100644 index 0000000..60e7ebf --- /dev/null +++ b/lunchtime3/click1.py @@ -0,0 +1,13 @@ +import click + + +@click.command() +@click.argument("inputfile", type=click.Path(exists=True)) +def stats(inputfile): + """Read data from the given INPUTFILE and calculate useful statistics""" + print(f"Calculating statistics from {inputfile}") + + +# This allows use of this Python file both for imports and for the CLI +if __name__ == "__main__": + stats() diff --git a/lunchtime3/click2.py b/lunchtime3/click2.py new file mode 100644 index 0000000..cf5d5ed --- /dev/null +++ b/lunchtime3/click2.py @@ -0,0 +1,22 @@ +import click + + +@click.command() +@click.option( + "--input", + type=click.Path(exists=True), + default="input.txt", + help="The data file to read from", +) +@click.option( + "--verbose/--no-verbose", type=bool, help="Whether to output intermediate results" +) +def stats(verbose, input): + """Read data and calculate useful statistics""" + if verbose: + print("Started the CLI script") + print(f"Calculating statistics from {input}") + + +if __name__ == "__main__": + stats() diff --git a/lunchtime3/click3.py b/lunchtime3/click3.py new file mode 100644 index 0000000..a646f80 --- /dev/null +++ b/lunchtime3/click3.py @@ -0,0 +1,35 @@ +import click + + +@click.group() +def main(): + pass + + +@click.command() +@click.option( + "--input", + type=click.Path(exists=True), + default="input.txt", + help="The data file to read from", +) +@click.option( + "--verbose/--no-verbose", type=bool, help="Whether to output intermediate results" +) +def stats(verbose, input): + """Read data and calculate useful statistics""" + if verbose: + print("Started the CLI script") + print(f"Calculating statistics from {input}") + + +@click.command() +def preprocess(): + print("Apply preprocessing") + + +main.add_command(stats) +main.add_command(preprocess) + +if __name__ == "__main__": + main() diff --git a/lunchtime3/lunchtime3.ipynb b/lunchtime3/lunchtime3.ipynb new file mode 100644 index 0000000..2bbe991 --- /dev/null +++ b/lunchtime3/lunchtime3.ipynb @@ -0,0 +1,422 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunchtime Python #3: Click" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Presenter: Dominic Kempf, Scientific Software Center" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "[Click](https://click.palletsprojects.com/en/8.0.x/) is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary." + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Command Line Interfaces: Why?" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Natural evolution of a piece of research software in Python:\n", + "* Starts on a Jupyter notebook playground\n", + "* At some point freezes into a script for long term use\n", + "* (Automated) Application to a wider range of usage scenarios" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "For the last step, good Command Line Interface (CLI) is very helpful. Important aspects:\n", + "\n", + "* Easy addition into existing code\n", + "* Few lines of code to ease maintenance and focus on the scientific part\n", + "* Good help text generation" + ] + }, + { + "cell_type": "markdown", + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## How not to do it\n", + "\n", + "We get access to command line arguments similar to C through `sys.argv`:" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "# DON'T DO THIS!\n", + "import sys\n", + "\n", + "inputfile = sys.argv[1]\n", + "print(f\"Calculating statistics from {inputfile}\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Why is this bad?\n", + "* No help text generation\n", + "* No validation of arguments\n", + "* Prone to errors in argument indexing\n", + "* Logic for non-string and optional arguments becomes quickly unwieldy" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The standard libraries `argparse` and `optparse` are better options, but there is even better." + ] + }, + { + "cell_type": "markdown", + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Click: A beautiful, opinionated approach" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "import click\n", + "\n", + "@click.command()\n", + "@click.argument(\"inputfile\", type=click.Path(exists=True))\n", + "def stats(inputfile):\n", + " \"\"\"Read data from the given INPUTFILE and calculate useful statistics\"\"\"\n", + " click.echo(f\"Calculating statistics from {inputfile}\")\n", + "\n", + "# This allows use of this Python file both for imports and for the CLI\n", + "if __name__ == \"__main__\":\n", + " stats()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Arguments vs. Options" + ] + }, + { + "cell_type": "markdown", + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Arguments are positional and only too a small extent optional or defaultable. Use them only for absolute essential, self-explanatory input. To customize your script's behavious *options* are the better choice:" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "import click\n", + "\n", + "@click.command()\n", + "@click.option(\n", + " \"--input\",\n", + " type=click.Path(exists=True),\n", + " default=\"input.txt\",\n", + " help=\"The data file to read from\",\n", + ")\n", + "@click.option(\n", + " \"--verbose/--no-verbose\", type=bool, help=\"Whether to output intermediate results\"\n", + ")\n", + "def stats(verbose, input):\n", + " \"\"\"Read data and calculate useful statistics\"\"\"\n", + " if verbose:\n", + " click.echo(\"Started the CLI script\")\n", + " click.echo(f\"Calculating statistics from {input}\")\n", + "\n", + "if __name__ == \"__main__\":\n", + " stats()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Composability of commands\n", + "\n", + "Add subcommand structure by reusing previously defined commands:" + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "@click.group()\n", + "def main():\n", + " pass\n", + "\n", + "@click.command()\n", + "def preprocess():\n", + " click.echo(\"Apply preprocessing\")\n", + "\n", + "main.add_command(stats)\n", + "main.add_command(preprocess)\n", + "\n", + "if __name__ == \"__main__\":\n", + " main()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "This mechanism is very powerful: arbitrary nesting, runtime extension e.g. through plugins etc." + ] + }, + { + "cell_type": "markdown", + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Setuptools integration\n", + "\n", + "As software becomes more mature, it is also advisable to package and distribute it as a Python package. Click easily integrates with `setuptools` as well using the entrypoints mechanism:" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "# In setup.py\n", + "setup(entry_points={\"console_scripts\": [\"myscript = mypackage.mymodule:myclifunction\"]})\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "```python\n", + "# In setup.cfg\n", + "[options.entry_points]\n", + "console_scripts =\n", + " myscript = mypackage.mymodule:myclifunction\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Further information about click" + ] + }, + { + "cell_type": "markdown", + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Today's presentation can be found on the Lunch Time Python website: [https://ssciwr.github.io/lunch-time-python/](https://ssciwr.github.io/lunch-time-python/)" + ] + }, + { + "cell_type": "markdown", + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "For further information, see also the (very good) [Click documentation](https://click.palletsprojects.com) " + ] + }, + { + "cell_type": "markdown", + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "For questions to the Scientific Software Center, please write us to [ssc@iwr.uni-heidelberg.de](mailto:ssc@iwr.uni-heidelberg.de)" + ] + }, + { + "cell_type": "markdown", + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Lunch Time Python Session #4\n", + "\n", + "Library options, please vote now:\n", + "\n", + "* [itertools](https://docs.python.org/3/library/itertools.html) is a standard library that implements a number of iterator building blocks inspired by functional programming languages.\n", + "* [pytest](https://docs.pytest.org/en/6.2.x/) The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.\n", + "* [matplotlib](https://matplotlib.org/) Matplotlib is a comprehensive library for creating static, animated, and interactive visualizations in Python" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "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.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime3/lunchtime3.slides.html b/lunchtime3/lunchtime3.slides.html new file mode 100644 index 0000000..a9c0ad6 --- /dev/null +++ b/lunchtime3/lunchtime3.slides.html @@ -0,0 +1,15693 @@ + + + + + + + + + +lunchtime3 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime3/sysargv.py b/lunchtime3/sysargv.py new file mode 100644 index 0000000..c54d697 --- /dev/null +++ b/lunchtime3/sysargv.py @@ -0,0 +1,7 @@ +# DON'T DO THIS! +import sys + +inputfile = sys.argv[1] +outputfile = sys.argv[2] + +print(f"Doing something with {inputfile} and {outputfile}") diff --git a/lunchtime4/README.md b/lunchtime4/README.md new file mode 100644 index 0000000..a8f8cba --- /dev/null +++ b/lunchtime4/README.md @@ -0,0 +1,6 @@ +# Lunchtime #4: pytest (Feb. 25) + +[pytest](https://docs.pytest.org/) is a widely used Python test framework, +which makes it easy to write small and readable tests, +and also offers more advanced features such as fixtures and mocks. +There is also a large ecosystem of plugins providing additional functionality. \ No newline at end of file diff --git a/lunchtime4/lunchtime4.ipynb b/lunchtime4/lunchtime4.ipynb new file mode 100644 index 0000000..a7ed648 --- /dev/null +++ b/lunchtime4/lunchtime4.ipynb @@ -0,0 +1,707 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## Lunch 4: pytest\n", + "\n", + "\n", + "\n", + "[pytest](https://docs.pytest.org/) is a widely used Python test framework, which makes it easy to write small and readable tests, and also offers more advanced features such as fixtures and mocks. There is also a large ecosystem of plugins providing additional functionality.\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Why write tests?\n", + "\n", + "- ensure correctness\n", + "- maintain correctness\n", + "- find bugs earlier and more easily\n", + "- allow refactoring without fear\n", + "- allow others to contribute without unknowingly breaking stuff\n", + "- can complement documentation as examples of use\n", + "- give others confidence in your code" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# pytest installation\n", + "\n", + "- Conda: `conda install pytest`\n", + "- Pip: `python -m pip install pytest`" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# First steps\n", + "\n", + "## Create a test\n", + "\n", + "1. create a file that starts with `test_`, e.g. `test_math.py`\n", + "2. add a function to it that starts with `test_` and asserts things, e.g.\n", + "```python\n", + "# in file: test_math.py\n", + "def test_add():\n", + " assert 1 + 1 == 2\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Run the tests\n", + "\n", + "3. run `pytest -v` or `python -m pytest -v`\n", + "\n", + "```bash\n", + "================ test session starts =======================\n", + "platform linux -- Python 3.10.2, pytest-7.0.0, pluggy-1.0.0\n", + "rootdir: /home/liam/test\n", + "plugins: anyio-3.5.0\n", + "collected 1 item \n", + "\n", + "test_math.py::test_add PASSED \n", + " [100%]\n", + "\n", + "====================== 1 passed in 0.00s ====================\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## What just happened?\n", + "\n", + "- pytest looks for all files that start with `test_`\n", + "- it collects all functions in these files that start with `test_`\n", + "- it runs them all, and reports PASS/FAIL for each assertion in each function\n", + "\n", + "## Some things we didn't do\n", + "\n", + "- import a test library\n", + "- inherit from some base test class\n", + "- use some special `assertEqual` function\n", + "- register our test file or test cases" + ] + }, + { + "cell_type": "markdown", + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Simple pytest test strategy\n", + "\n", + "- for each file `abc.py`, add a `test_abc.py`\n", + "- for each function `foo()` in `abc.py`, add a `test_foo()` to `test_abc.py`\n", + "- inside `test_foo()` assert things involving `foo()` that should be true \n", + "- that's it" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# ipytest" + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "## disclaimer\n", + "\n", + "- For demonstration purposes, these tests will be written inside this jupyter notebook\n", + "- We'll use a helper library `ipytest` to call pytest on them from inside the notebook\n", + "- But generally I would recommend putting functions and tests into files and running pytest directly" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install ipytest -qqq\n", + "import ipytest\n", + "import pytest\n", + "\n", + "ipytest.autoconfig()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "\n", + "def test_math():\n", + " assert 1 + 1 == 2" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Failing tests" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%ipytest -q\n", + "\n", + "\n", + "def f(x):\n", + " return 2 * x\n", + "\n", + "\n", + "def g(x):\n", + " return f(x) + 3\n", + "\n", + "\n", + "def test_math():\n", + " a = 2\n", + " b = 3\n", + " assert f(a) * g(b) == 36" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -q\n", + "\n", + "\n", + "def test_list():\n", + " a = [1, 2, 5, 8]\n", + " b = [1, 2, 5, 8]\n", + " assert a == b" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Exceptions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%ipytest -q\n", + "\n", + "\n", + "def test_exception():\n", + " my_list = [1, 2, 3]\n", + " with pytest.raises(IndexError):\n", + " my_list[5]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -q\n", + "\n", + "\n", + "def test_exception():\n", + " my_list = [1, 2, 3]\n", + " with pytest.raises(Exception) as e:\n", + " my_list[5]\n", + " assert e.type == IndexError\n", + " assert \"out of range\" in str(e.value)" + ] + }, + { + "cell_type": "markdown", + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Temporary files\n", + "\n", + "- often need to write to a temporary file in a test\n", + "- simply add `tmp_path` as an argument to your test function\n", + "- pytest will provide a unique temporary path object for each test\n", + "- this is an example of a *fixture*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%ipytest -qs\n", + "\n", + "\n", + "def test_write(tmp_path):\n", + " print(tmp_path)\n", + " assert str(tmp_path) != \"\"" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Monkey-patching\n", + "\n", + "- a fixture to temporarily modify an object, dict or environment variable\n", + "- all modifications are undone after the test is finished\n", + "- add `monkeypatch` as an argument to your test function\n", + "- provides various methods, e.g.\n", + " - `monkeypatch.setattr(obj, name, value)`\n", + " - `monkeypatch.setenv(name, value)`\n", + " - `monkeypatch.syspath_prepend(path)`\n", + " - `monkeypatch.chdir(path)`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -qs\n", + "\n", + "import os\n", + "\n", + "\n", + "def test_env(monkeypatch):\n", + " assert os.getenv(\"TEST_API_KEY\") == None\n", + " monkeypatch.setenv(\"TEST_API_KEY\", \"abc123\")\n", + " assert os.getenv(\"TEST_API_KEY\") == \"abc123\"" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Fixtures\n", + "\n", + "- a way to provide context (e.g. data or environment) to a test\n", + "- test \"requests\" a fixture by declaring it as an argument\n", + "- various built-in fixtures (`tmp_path`, `monkeypatch`, ...)\n", + "- you can create your own with the `@pytest.fixture` decorator\n", + "- for each test function argument, pytest looks for a fixture with the same name\n", + "- fixtures can themselves request other fixtures" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "# a fixture to provide some data to a test\n", + "@pytest.fixture\n", + "def colours():\n", + " return [\"red\", \"green\", \"blue\"]\n", + "\n", + "\n", + "def test_colours(colours):\n", + " assert colours[0] == \"red\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "\n", + "@pytest.fixture\n", + "def colours():\n", + " return [\"red\", \"green\", \"blue\"]\n", + "\n", + "\n", + "# a fixture that itself requests another fixture\n", + "@pytest.fixture\n", + "def sorted_colours(colours):\n", + " return sorted(colours)\n", + "\n", + "\n", + "def test_colours(sorted_colours):\n", + " assert sorted_colours[0] == \"blue\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "# a fixture that uses monkeypatch to set an environment variable\n", + "@pytest.fixture\n", + "def api_key(monkeypatch):\n", + " monkeypatch.setenv(\"TEST_API_KEY\", \"abc123\")\n", + "\n", + "\n", + "def test_missing_api_key():\n", + " assert os.getenv(\"TEST_API_KEY\") == None\n", + "\n", + "\n", + "def test_api_key(api_key):\n", + " assert os.getenv(\"TEST_API_KEY\") == \"abc123\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "# a parameterized fixture: test will be repeated for each parameter\n", + "@pytest.fixture(params=[\"red\", \"green\", \"blue\", \"yellow\"])\n", + "def colour(request):\n", + " return request.param\n", + "\n", + "\n", + "def test_colour(colour):\n", + " assert len(colour) >= 3" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Test grouping\n", + "\n", + "- put functions into a class whose name begins with `Test`\n", + "- a class can request a fixture, all member functions then have this fixture" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "\n", + "class TestMath:\n", + " def test_add(self):\n", + " assert 1 + 1 == 2\n", + "\n", + " def test_mul(self):\n", + " assert 2 * 2 == 4" + ] + }, + { + "cell_type": "markdown", + "id": "28", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Marking tests\n", + "\n", + "- mark tests with attributes using `@pytest.mark` decorator\n", + "- common use cases\n", + " - `skipif` to conditionally skip a test\n", + " - e.g. depending on python version or platform\n", + " - `xfail` to mark a test that is expected to fail\n", + " - e.g. a test that documents a known bug that is not yet fixed\n", + "- can also mark a test class to mark all tests within that class\n", + "- can also create your own custom markers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "import sys\n", + "\n", + "\n", + "@pytest.mark.xfail(reason=\"bug from issue #123\")\n", + "def test_add():\n", + " assert 1 + 1 == 3\n", + "\n", + "\n", + "@pytest.mark.skipif(not sys.platform.startswith(\"win\"), reason=\"windows only test\")\n", + "def test_mul():\n", + " assert 2 * 2 == 4" + ] + }, + { + "cell_type": "markdown", + "id": "30", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Parameterizing tests\n", + "\n", + "- can parameterize tests using the `@pytest.mark.parameterize` decorator\n", + "- takes comma-delimeted list of arguments as a string\n", + "- followed by a list of tuples of argument values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "\n", + "@pytest.mark.parametrize(\"n\", [1, 2, 3])\n", + "def test_n(n):\n", + " assert n > 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%ipytest -vv\n", + "\n", + "\n", + "@pytest.mark.parametrize(\"n,n_squared\", [(1, 1), (2, 4), (3, 9)])\n", + "def test_n(n, n_squared):\n", + " assert n * n == n_squared" + ] + }, + { + "cell_type": "markdown", + "id": "33", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Summary\n", + "\n", + "- pytest is very easy to get started with and use\n", + "- just writing test functions with assertions already provides a lot of value\n", + "- fixtures allow you to provide context to your test functions\n", + "- parameterizing fixtures and/or tests can turn a single test into many test cases\n", + "- (many) more features at [docs.pytest.org](https://docs.pytest.org/)" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime4/lunchtime4.slides.html b/lunchtime4/lunchtime4.slides.html new file mode 100644 index 0000000..56fea87 --- /dev/null +++ b/lunchtime4/lunchtime4.slides.html @@ -0,0 +1,16431 @@ + + + + + + + + + +lunchtime4 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime5/README.md b/lunchtime5/README.md new file mode 100644 index 0000000..a71eac0 --- /dev/null +++ b/lunchtime5/README.md @@ -0,0 +1,5 @@ +# Lunchtime 5: pillow (March 25th) + +[Pillow](https://pillow.readthedocs.io/en/stable/) is the friendly fork of the +Python Imaging Library (PIL). It provides provides extensive file format support, +an efficient internal representation, and fairly powerful image processing capabilities. diff --git a/lunchtime5/final.jpg b/lunchtime5/final.jpg new file mode 100644 index 0000000..683f129 Binary files /dev/null and b/lunchtime5/final.jpg differ diff --git a/lunchtime5/lunchtime5.ipynb b/lunchtime5/lunchtime5.ipynb new file mode 100644 index 0000000..8e3ffaa --- /dev/null +++ b/lunchtime5/lunchtime5.ipynb @@ -0,0 +1,584 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunchtime #5: Pillow" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "\n", + "## Why using Python for image processing?\n", + "\n", + "* Easy automation of image processing (compared to GUIs)\n", + "* High-Level interfaces usable without very deep knowledge of image formats\n", + "* Easy integration with other Python-based tools for e.g.\n", + " * Image Analysis\n", + " * Web Scraping\n", + " * ML/AI" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Pillow is *the friendly fork* of PIL, the Python Imaging Library:\n", + "\n", + "* PIL is/was the state-of-the-art library for image processing in Python\n", + "* Had several issues caused by the project maintenance:\n", + " * Compatibility issues with standard installation procedures\n", + " * Missing open community work for issues, contributions etc.\n", + " * Sustainability issues due to missing Continuous Integration\n", + "* Pillow has stepped in, PIL had its last release in 2009" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## The Basics: Loading an image\n", + "We import `Image` from the `PIL` package:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from PIL import Image" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "We can open an image from disk by using `open`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !wget https://ssciwr.github.io/lunch-time-python/lunchtime5/thingstaette.png -q\n", + "img = Image.open(\"thingstaette.png\")" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The image is represented using the `Image` class from PIL (or one of its specialized subclasses). Images can be created by loading from file, from other images or programmatically." + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "The `img` object can be queried for a number of metadata fields of the image:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.format" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.size" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.width, img.height" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.mode" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.getbands()" + ] + }, + { + "cell_type": "markdown", + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Visualizing images in Jupyter" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "To display the image directly in Jupyter notebooks, we can use the `IPython`'s rich display system. Alternatively, `img.show()` can open the image in an external viewer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "img" + ] + }, + { + "cell_type": "markdown", + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Modifying images\n", + "\n", + "Image modifications operate on one image and return a new image which is a copy of the original with the applied modifications. This is common (good) practice in object-oriented programming." + ] + }, + { + "cell_type": "markdown", + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Cropping" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "cropped = img.crop([330, 100, 650, 550])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "cropped" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Resizing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "resized = cropped.reduce(2)\n", + "# resized = cropped.resize((150, 100))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "resized" + ] + }, + { + "cell_type": "markdown", + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Transforming" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "rotated = resized.rotate(180)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "rotated" + ] + }, + { + "cell_type": "markdown", + "id": "27", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Applying filters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from PIL import ImageFilter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "blurred = rotated.filter(ImageFilter.BLUR)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "blurred" + ] + }, + { + "cell_type": "markdown", + "id": "31", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Merging\n", + "\n", + "Merging is done as an in-place operation on the `Image` object:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img.paste(rotated, (100, 100))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "img" + ] + }, + { + "cell_type": "markdown", + "id": "34", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Saving Images\n", + "\n", + "After successful transformation, we can save the result.\n", + "\n", + "* Output format deduced from given file extension\n", + "* Alternatively passed explicitly\n", + "* Format conversion implemented by `PIL`\n", + "* Some formats require certain conditions on the data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [], + "source": [ + "converted = img.convert(\"RGB\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "converted.getbands()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "converted.save(\"final.jpg\")" + ] + }, + { + "cell_type": "markdown", + "id": "38", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Further information\n", + "\n", + "Pillow has much more functionality than shown here today, check the examples and references in its documentation:\n", + "\n", + "[https://pillow.readthedocs.io](https://pillow.readthedocs.io)\n" + ] + }, + { + "cell_type": "markdown", + "id": "39", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Thanks for joining!" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime5/lunchtime5.slides.html b/lunchtime5/lunchtime5.slides.html new file mode 100644 index 0000000..8bcdcab --- /dev/null +++ b/lunchtime5/lunchtime5.slides.html @@ -0,0 +1,16194 @@ + + + + + + + + + +lunchtime5 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime5/thingstaette.png b/lunchtime5/thingstaette.png new file mode 100644 index 0000000..06eea95 Binary files /dev/null and b/lunchtime5/thingstaette.png differ diff --git a/lunchtime6/README.md b/lunchtime6/README.md new file mode 100644 index 0000000..963b167 --- /dev/null +++ b/lunchtime6/README.md @@ -0,0 +1,6 @@ +# Lunchtime #6: numba + +[numba](https://numba.pydata.org/) is a just-in-time (JIT) compiler for Python. +With a few simple annotations, array-oriented and math-heavy Python code can be +just-in-time optimized to performance similar as C, C++ and Fortran, +without having to switch languages or Python interpreters. diff --git a/lunchtime6/build/lib.linux-x86_64-cpython-310/pybind11_7993cdc.cpython-310-x86_64-linux-gnu.so b/lunchtime6/build/lib.linux-x86_64-cpython-310/pybind11_7993cdc.cpython-310-x86_64-linux-gnu.so new file mode 100755 index 0000000..0e9046c Binary files /dev/null and b/lunchtime6/build/lib.linux-x86_64-cpython-310/pybind11_7993cdc.cpython-310-x86_64-linux-gnu.so differ diff --git a/lunchtime6/lunchtime6.ipynb b/lunchtime6/lunchtime6.ipynb new file mode 100644 index 0000000..0264471 --- /dev/null +++ b/lunchtime6/lunchtime6.ipynb @@ -0,0 +1,865 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## Lunch 6: numba\n", + "\n", + "\n", + "\n", + "[numba](https://numba.pydata.org/) is a just-in-time (JIT) compiler for Python. With a few simple annotations, array-oriented and math-heavy Python code can be just-in-time optimized to performance similar as C, C++ and Fortran, without having to switch languages or Python interpreters.\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Motivation\n", + "\n", + "- Many reasons to use Python, but performance not one of them\n", + "- What to do when a Python function is too slow?\n", + "- Ideally, find a library (e.g. numpy) with an equivalent function\n", + "- Otherwise:\n", + " - use PyPy instead of CPython (if all your libraries are available)\n", + " - write a fortan function and compile with f2py or fortranmagic\n", + " - write a C function and compile with Cython\n", + " - write a C++ function and compile using pybind11 or ipybind\n", + " - magically make your slow Python function faster (numba)" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# numba installation\n", + "\n", + "- Conda: `conda install numba`\n", + "- Pip: `python -m pip install numba`" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Vector reduction example\n", + "\n", + "Toy example: implement a vector reduction operation:\n", + "\n", + "r(x,y) = $ \\sum_i \\cos(x_i) \\sin(y_i) $\n", + "\n", + "Some random vectors to benchmark our functions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "x = np.random.uniform(low=-1, high=1, size=5000000)\n", + "y = np.random.uniform(low=-1, high=1, size=5000000)" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Python" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "import math\n", + "\n", + "\n", + "def r_python(x_vec, y_vec):\n", + " s = 0\n", + " for x, y in zip(x_vec, y_vec):\n", + " s += math.cos(x) * math.sin(y)\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_python(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_python(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# numpy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "def r_numpy(x_vec, y_vec):\n", + " return np.dot(np.cos(x_vec), np.sin(y_vec))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_numpy(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_numpy(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Cython" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# pip install cython\n", + "%load_ext cython" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%cython\n", + "\n", + "import math\n", + "\n", + "def r_cython(x_vec, y_vec):\n", + " s = 0\n", + " for x,y in zip(x_vec, y_vec):\n", + " s += math.cos(x) * math.sin(y)\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_cython(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_cython(x,y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "%%cython\n", + "\n", + "import math\n", + "# use C math functions\n", + "from libc.math cimport sin, cos\n", + "\n", + "# use C types instead of Python types\n", + "def r_cython(double[:] x_vec, double[:] y_vec):\n", + " cdef double s = 0\n", + " cdef int i\n", + " for i in range(len(x_vec)):\n", + " s += cos(x_vec[i])*sin(y_vec[i])\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_cython(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_cython(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Fortran" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install fortran-magic -qqq\n", + "%load_ext fortranmagic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%fortran\n", + "\n", + "subroutine r_fortran(x_vec, y_vec, res)\n", + " real, intent(in) :: x_vec(:), y_vec(:)\n", + " real, intent(out) :: res\n", + " integer :: i, n\n", + " n = size(x_vec)\n", + " res = 0\n", + " do i=1,n\n", + " res = res + cos(x_vec(i))*sin(y_vec(i))\n", + " enddo\n", + "endsubroutine r_fortran" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_fortran(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_fortran(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# C++ / pybind11" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install git+https://github.com/aldanor/ipybind.git -qqq\n", + "%load_ext ipybind" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%%pybind11\n", + "\n", + "#include \n", + "#include \n", + "PYBIND11_PLUGIN(example) {\n", + " py::module m(\"example\");\n", + " m.def(\"r_pybind\", [](const py::array_t& x, const py::array_t& y) {\n", + " double sum{0};\n", + " auto rx{x.unchecked<1>()};\n", + " auto ry{y.unchecked<1>()};\n", + " for (py::ssize_t i = 0; i < rx.shape(0); i++){\n", + " sum += std::cos(rx[i])*std::sin(ry[i]);\n", + " }\n", + " return sum;\n", + " });\n", + " return m.ptr();\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_pybind(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_pybind(x, y)" + ] + }, + { + "cell_type": "markdown", + "id": "31", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# numba" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from numba import jit\n", + "\n", + "\n", + "@jit\n", + "def r_numba(x_vec, y_vec):\n", + " s = 0\n", + " for x, y in zip(x_vec, y_vec):\n", + " s += math.cos(x) * math.sin(y)\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_numba(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# pure python with numba JIT\n", + "%timeit r_numba(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "35", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Numba compilation\n", + "\n", + "Two compilation modes\n", + "\n", + "- `nopython` mode (default)\n", + " - Fast because it doesn't access the Python C API\n", + " - Needs to be able to infer the native (C) types of all values\n", + "- `object` mode (fallback)\n", + " - Slow because it uses Python objects and the Python C API\n", + " - Only used if `nopython` mode is not possible\n", + " - To raise an error instead of falling back to this, set `nopython=True` or use `@njit`" + ] + }, + { + "cell_type": "markdown", + "id": "36", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Numba function signatures\n", + "\n", + "You can optionally explicitly specify the function signature. Use cases:\n", + "\n", + "- you want the function to be compiled when it is defined rather than when it is first called\n", + "- you need fine-grained control over types (e.g. if you want 32-bit floats)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from numba import float32\n", + "\n", + "\n", + "@jit(float32(float32, float32))\n", + "def sum(a, b):\n", + " return a + b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "sum(1, 0.99999999)" + ] + }, + { + "cell_type": "markdown", + "id": "39", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Numba options\n", + "\n", + "- `nopython=True` disable Object mode fallback\n", + "- `nogil=True` release the Python Global Interpreter Lock (GIL)\n", + "- `cache=True` cache the compiled funtions on disk\n", + "- `parallel=True` enable automatic parallelization" + ] + }, + { + "cell_type": "markdown", + "id": "40", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Parallelization\n", + "\n", + "- set `parallel=True` option to enable\n", + "- use `prange` to explicitly parallelize a loop over a `range`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "41", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from numba import jit, prange\n", + "\n", + "\n", + "@jit(parallel=True)\n", + "def r_numba(x_vec, y_vec):\n", + " s = 0\n", + " for i in prange(len(x_vec)):\n", + " s += math.cos(x[i]) * math.sin(y[i])\n", + " return s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r_numba(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit r_numba(x,y)" + ] + }, + { + "cell_type": "markdown", + "id": "44", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# NumPy universal functions\n", + "\n", + "- a numpy `ufunc` is a function that operates on scalars\n", + "- can create one using `@numba.vectorize` and use it like built-in numpy ufuncs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from numba import vectorize, float64\n", + "\n", + "\n", + "@vectorize([float64(float64, float64)], target=\"parallel\")\n", + "def r(x, y):\n", + " return np.cos(x) * np.sin(y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r(2, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "r(x, y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "np.sum(r(x, y))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%timeit np.sum(r(x,y))" + ] + }, + { + "cell_type": "markdown", + "id": "50", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Advanced features\n", + "\n", + "- Ahead of Time (AoT) compilation\n", + " - the compiled module only depends on NumPy\n", + "- Flexible specializations\n", + " - `@generated_jit` decorator for compile-time logic, e.g. type specializations\n", + "- Stencil\n", + " - `@stencil` decorator for creating a stencil to apply to an array\n", + "- C callbacks\n", + " - `@cfunc` decorator to generate a C-callback (e.g. to pass to scipy.integrate)\n", + "- CUDA support\n", + " - compile CUDA kernels to run on a GPU\n", + "- see [numba.readthedocs.io](https://numba.readthedocs.io/) for more" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime6/lunchtime6.slides.html b/lunchtime6/lunchtime6.slides.html new file mode 100644 index 0000000..2ac998d --- /dev/null +++ b/lunchtime6/lunchtime6.slides.html @@ -0,0 +1,16767 @@ + + + + + + + + + +lunchtime6 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime7/lunchtime7.ipynb b/lunchtime7/lunchtime7.ipynb new file mode 100644 index 0000000..4cf5f66 --- /dev/null +++ b/lunchtime7/lunchtime7.ipynb @@ -0,0 +1,836 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## Lunch 7: matplotlib\n", + "\n", + "\n", + "\n", + "[matplotlib](https://matplotlib.org/) is a plotting library for Python and the NumPy library. It is easy to use and can be used to generate scatter or bar plots, density maps and even 3D plots in publication quality.\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Advantages of matplotlib:\n", + "\n", + "- matplotlib is mostly used in conjunction with [pyplot](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.html) - a matplotlib module - that provides an easy-to-use interface\n", + "- Very versatile, works with many types of data\n", + "- Directly plot NumPy functions and arrays\n", + "- Many export options\n", + "- Customizable \n", + "- Can be used with additional toolkits that extend the functionality, like [seaborn](https://seaborn.pydata.org/)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## matplotlib installation\n", + "\n", + "Available via pip: \n", + "`python -m pip install -U matplotlib` \n", + "Or install via conda: \n", + "`conda install matplotlib`" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Basic plots\n", + "Plot the sin and cos over a range of angles. For this, we also need numpy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "xvals = np.arange(0, 2 * np.pi, 0.1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "plt.plot(xvals, np.sin(xvals))\n", + "plt.plot(xvals, np.cos(xvals))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The default settions already look quite nice!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Running inside a script\n", + "Or more generally, if you want to suppress the output (return) of the `plt()` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "plt.plot(xvals, np.sin(xvals))\n", + "plt.plot(xvals, np.cos(xvals))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "`plt.show()` closes the plot; if you plot using a script and not a notebook, place one `plt.show()` command at the end of your script." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Running inside a notebook: static images\n", + "You can plot static images inside your notebook using the `%matplotlib inline` magic: You only need to run this once. It is not always necessary to put this, but it makes it clear which Matplotlib backend should be used." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "plt.plot(xvals, np.sin(xvals))\n", + "plt.plot(xvals, np.cos(xvals))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Scatter plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "xvals = np.random.randint(10, size=10)\n", + "yvals = np.random.randint(10, size=10)\n", + "plt.scatter(xvals, yvals)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Bar plot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "xvals = np.linspace(1, 10, 10)\n", + "yvals = np.random.randint(10, size=10)\n", + "plt.bar(xvals, yvals)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Customizing plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "plt.bar(xvals, yvals, label=\"Random series\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Customizing plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "plt.bar(xvals, yvals, label=\"Random series\")\n", + "plt.legend(fontsize=16, loc=\"upper right\")\n", + "plt.xlabel(\"Integer\", fontsize=18)\n", + "plt.ylabel(\"Magnitude\", fontsize=22, color=\"red\")\n", + "plt.title(\"My custom plot\", fontsize=22)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Customizing plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "xvals = np.arange(0, 2 * np.pi, 0.1)\n", + "plt.plot(xvals, np.sin(xvals), marker=\"x\", markevery=10, color=\"blue\")\n", + "plt.plot(xvals, np.cos(xvals), marker=\"<\", color=\"black\", alpha=0.5)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "You can set x- and y-limits, annotate points on the plot, change the axis position and intersection, add a grid in the background, ... \n", + "A list of available markers is found [here](https://matplotlib.org/2.0.2/api/markers_api.html) and named colors [here](https://matplotlib.org/stable/gallery/color/named_colors.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Figure class: Advanced plots with the artist layer\n", + "A `Figure` in matplotlib is the whole plot (or window in the user interface) and can contain multiple plots. By accessing the **Artist layer** (\"object-based plotting\"), you can access more customizing options than with the basic `plt.xxx` **Scripting layer** (\"procedural plotting\") (see https://matplotlib.org/1.5.1/faq/usage_faq.html#parts-of-a-figure).\n", + "\n", + "This also allows you to include multiple plots in one Figure.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(12, 10)) # width = 12 inches and height = 10 inches\n", + "# create one axes object\n", + "ax1 = fig.add_subplot(211) # (2, 1, 1) no of rows, no of columns, no of plots\n", + "ax1.plot(xvals, np.sin(xvals), marker=\"x\", color=\"blue\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "It is also possible to use `add_axes()` instead of `add_subplot()`, but not recommended as with the latter, matplotlib takes care of the exact position of the axes in the figure." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Several subplots\n", + "Using `add_subplot()`, we can add one `axes` object at a time:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(12, 10))\n", + "ax1 = fig.add_subplot(221)\n", + "ax1.plot(xvals, np.sin(xvals), marker=\"x\", color=\"blue\")\n", + "ax2 = fig.add_subplot(222)\n", + "ax2.plot(xvals, np.cos(xvals), marker=\"x\", color=\"blue\")\n", + "ax3 = fig.add_subplot(223)\n", + "ax3.plot(xvals, np.tan(xvals), marker=\"x\", color=\"blue\")\n", + "ax4 = fig.add_subplot(224)\n", + "ax4.plot(xvals, np.tanh(xvals), marker=\"x\", color=\"blue\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## A more practical way to add multiple subplots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(12, 10), nrows=2, ncols=2)\n", + "ax[0, 0].plot(xvals, np.sin(xvals), marker=\"x\", color=\"blue\")\n", + "ax[0, 1].plot(xvals, np.cos(xvals), marker=\"x\", color=\"blue\")\n", + "ax[1, 0].plot(xvals, np.tan(xvals), marker=\"x\", color=\"blue\")\n", + "ax[1, 1].plot(xvals, np.tanh(xvals), marker=\"x\", color=\"blue\")\n", + "plt.savefig(\"my_figure.pdf\", bbox_inches=\"tight\")\n", + "plt.savefig(\"my_figure.jpg\", dpi=300, bbox_inches=\"tight\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 2D plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "def myfunc(x, y):\n", + " return np.sin(np.sqrt(5) + x) * y\n", + "\n", + "\n", + "mf = 16\n", + "# the x and y values need to be spanned on a 2D mesh\n", + "num1 = np.arange(-5, 5, 0.1)\n", + "num2 = np.arange(-5, 5, 0.1)\n", + "X, Y = np.meshgrid(num1, num2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(X[0])\n", + "print(Y[0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=3)\n", + "ax[0].pcolor(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[0].set_title(\"pcolor\", fontsize=mf)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "`pcolor` is the slowest plotting method of the three, but is more flexible in terms of the data mesh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=3)\n", + "\n", + "ax[0].pcolor(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[0].set_title(\"pcolor\", fontsize=mf)\n", + "\n", + "ax[1].pcolormesh(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[1].set_title(\"pcolormesh\", fontsize=mf)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "`pcolormesh` is basically identical to `pcolor` but faster." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=3)\n", + "\n", + "ax[0].pcolor(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[0].set_title(\"pcolor\", fontsize=mf)\n", + "\n", + "ax[1].pcolormesh(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[1].set_title(\"pcolormesh\", fontsize=mf)\n", + "\n", + "ax[2].imshow(myfunc(X, Y))\n", + "ax[2].set_title(\"imshow\", fontsize=mf)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "`imshow` is the fastest of the three methods. Note that the image is flipped compared to `pcolor` and `pcolormesh` and that the axis range is specified differently." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(15, 5), nrows=1, ncols=3)\n", + "\n", + "ax[0].pcolor(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[0].set_title(\"pcolor\", fontsize=mf)\n", + "\n", + "ax[1].pcolormesh(X, Y, myfunc(X, Y), cmap=\"viridis\")\n", + "ax[1].set_title(\"pcolormesh\", fontsize=mf)\n", + "\n", + "ax[2].imshow(myfunc(X, Y), extent=[-5, 5, -5, 5], origin=\"lower\", aspect=\"auto\")\n", + "ax[2].set_title(\"imshow\", fontsize=mf)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Here, we have repositioned the origin of `imshow` to match `pcolor` and `pcolormesh`, and further adjusted the aspect ratio and tick labels." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "## Imshow with contour bar" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 5))\n", + "\n", + "c = ax.imshow(myfunc(X, Y), extent=[-5, 5, -5, 5], origin=\"lower\", aspect=\"auto\")\n", + "cbar = plt.colorbar(c)\n", + "cbar.set_ticks([-5, -2.5, 0, 2.5, 5])\n", + "cbar.set_label(\"my colors\", rotation=90, fontsize=mf)\n", + "\n", + "ax.set_title(\"imshow\", fontsize=mf)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 3D plots\n", + "For 3D plots, you will need to import the `mplot3d` [module](https://matplotlib.org/stable/tutorials/toolkits/mplot3d.html). Then, when the axes are created, passing the `projection=\"3d\"` keyword enables a 3D axes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from mpl_toolkits.mplot3d import Axes3D\n", + "from matplotlib import cm" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(12, 12))\n", + "# fig, ax = plt.subplots(figsize=(12,12),subplot_kw=dict(projection='3d'))\n", + "\n", + "ax = fig.add_subplot(projection=\"3d\")\n", + "ax.plot_surface(X, Y, myfunc(X, Y), cmap=cm.viridis)\n", + "\n", + "\n", + "ax.set_title(\"3D plot\", fontsize=mf)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "The 3D plots of matplotlib are quite powerful but has its limitations: If it comes to plotting more than one set of data (two functions in one figure), then it will likely be rendered incorrectly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig = plt.figure(figsize=(12, 12))\n", + "\n", + "ax = fig.add_subplot(projection=\"3d\")\n", + "ax.plot_surface(X, Y, X + Y)\n", + "ax.plot_surface(X, Y, X + 0.1 * Y)\n", + "\n", + "\n", + "ax.set_title(\"3D plot\", fontsize=mf)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "For more advanced 3D plots, resort to [`Mayavi`](https://docs.enthought.com/mayavi/mayavi/)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Interactive plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "%matplotlib notebook" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(nrows=2, ncols=2)\n", + "ax[0, 0].plot(xvals, np.sin(xvals), marker=\"x\", color=\"blue\")\n", + "ax[0, 1].plot(xvals, np.cos(xvals), marker=\"x\", color=\"blue\")\n", + "ax[1, 0].plot(xvals, np.tan(xvals), marker=\"x\", color=\"blue\")\n", + "ax[1, 1].plot(xvals, np.tanh(xvals), marker=\"x\", color=\"blue\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Further references\n", + "\n", + "- Anatomy of matplotlib: https://nbviewer.org/github/matplotlib/AnatomyOfMatplotlib/tree/master/\n", + "- Matplotlib tutorial by Nicolas Rougier: https://github.com/rougier/matplotlib-tutorial\n", + "- Creating animations with Matplotlib: https://matplotlib.org/stable/api/animation_api.html" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lunchtime7/lunchtime7.slides.html b/lunchtime7/lunchtime7.slides.html new file mode 100644 index 0000000..71450e3 --- /dev/null +++ b/lunchtime7/lunchtime7.slides.html @@ -0,0 +1,17752 @@ + + + + + + + + + +lunchtime7 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/lunchtime7/my_figure.jpg b/lunchtime7/my_figure.jpg new file mode 100644 index 0000000..ed7364e Binary files /dev/null and b/lunchtime7/my_figure.jpg differ diff --git a/lunchtime7/my_figure.pdf b/lunchtime7/my_figure.pdf new file mode 100644 index 0000000..7c8d8c0 Binary files /dev/null and b/lunchtime7/my_figure.pdf differ diff --git a/lunchtime8/README.md b/lunchtime8/README.md new file mode 100644 index 0000000..f2d6e85 --- /dev/null +++ b/lunchtime8/README.md @@ -0,0 +1,5 @@ +# Lunchtime 8: ipywidgets (July 29th) + +[ipywidgets](https://ipywidgets.readthedocs.io/) is a widget library that provides +interactive UI controls (*widgets*) to Jupyter notebooks. They allow the generation +of frontend controls in pure Python for both demonstrator notebooks and Python libraries. diff --git a/lunchtime8/lunchtime8.ipynb b/lunchtime8/lunchtime8.ipynb new file mode 100644 index 0000000..05bf9f8 --- /dev/null +++ b/lunchtime8/lunchtime8.ipynb @@ -0,0 +1,742 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python #8: ipywidgets" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "*Jupyter Notebooks* are a perfect fit for scientific work with Python. They combine the following elements:\n", + "\n", + "* Code\n", + "* Documentation\n", + "* Visualization\n", + "* **UI Controls**" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "This allows us to write scientifically meaningful, executable documents that contain results, their interpretation and their provenance. They are a key element for reproducible research." + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## What are widgets?" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Jupyter has a so-called *rich display system*. If Python code returns an object, Jupyter accesses special methods on the object to decide how to display it. This can involve pretty printing, HTML, images, video, sounds etc:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "from PIL import Image\n", + "from io import BytesIO\n", + "import requests" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "response = requests.get(\n", + " \"https://ssciwr.github.io/lunch-time-python/lunchtime5/thingstaette.png\"\n", + ")\n", + "img = Image.open(BytesIO(response.content))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "?img._repr_png_" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "img" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "`ipywidgets` provides a number of widgets that are Python objects that display as HTML. The interactive behaviour of this HTML snippet is implemented in JavaScript and uses callback functions in Python. This way, you write interactive notebooks with pure Python." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "import ipywidgets" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "button = ipywidgets.Button(description=\"Click Me!\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "button" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "def handler(change):\n", + " button.description = \"Thanks!\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "button.on_click(handler)" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Input widgets (I)" + ] + }, + { + "cell_type": "markdown", + "id": "16", + "metadata": {}, + "source": [ + "We can create simple input fields that allow users to put in data. We can then access that data from Python reading and writing:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [ + "widget = ipywidgets.Text()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": {}, + "outputs": [], + "source": [ + "widget" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "19", + "metadata": {}, + "outputs": [], + "source": [ + "widget.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": {}, + "outputs": [], + "source": [ + "widget.value = \"Test\"" + ] + }, + { + "cell_type": "markdown", + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Input widgets (II)" + ] + }, + { + "cell_type": "markdown", + "id": "22", + "metadata": {}, + "source": [ + "Many similar working subflavors exist (for a full list see [the docs](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html)):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.FloatText(value=42.0, step=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.IntSlider(min=-10, max=10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.Checkbox(value=True, description=\"Some Option\")" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Selection widgets" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": {}, + "outputs": [], + "source": [ + "widget = ipywidgets.Dropdown(options=[\"Model A\", \"Model B\", \"Model C\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": {}, + "outputs": [], + "source": [ + "widget" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": {}, + "outputs": [], + "source": [ + "widget.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.RadioButtons(options=[\"Model A\", \"Model B\", \"Model C\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.Select(options=[\"Linux\", \"Windows\", \"macOS\"], description=\"OS:\")" + ] + }, + { + "cell_type": "markdown", + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Container widgets" + ] + }, + { + "cell_type": "markdown", + "id": "33", + "metadata": {}, + "source": [ + "If multiple widgets should be placed together, possibly applying some styling, they can be grouped into container widgets. In contrast to other widgets, these do not have an accessible `value`, but some have `selected_index`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": {}, + "outputs": [], + "source": [ + "widgets = [ipywidgets.Text(value=f\"#{i}\") for i in range(4)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.HBox(children=widgets)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": {}, + "outputs": [], + "source": [ + "ipywidgets.VBox(children=widgets)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "37", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "ipywidgets.Accordion(children=widgets, titles=tuple(f\"Tab #{i}\" for i in range(4)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38", + "metadata": {}, + "outputs": [], + "source": [ + "tab = ipywidgets.Tab(children=widgets, titles=tuple(f\"Tab #{i}\" for i in range(4)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39", + "metadata": {}, + "outputs": [], + "source": [ + "tab" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40", + "metadata": {}, + "outputs": [], + "source": [ + "tab.selected_index" + ] + }, + { + "cell_type": "markdown", + "id": "41", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Putting things together" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": {}, + "outputs": [], + "source": [ + "import io\n", + "\n", + "\n", + "def img_to_widget(i):\n", + " membuf = io.BytesIO()\n", + " i.save(membuf, format=\"png\")\n", + " return ipywidgets.Image(value=membuf.getvalue(), format=\"png\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43", + "metadata": {}, + "outputs": [], + "source": [ + "img_widget = img_to_widget(img)\n", + "cropped_widget = img_to_widget(img)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44", + "metadata": {}, + "outputs": [], + "source": [ + "x0 = ipywidgets.IntText(value=0, layout=ipywidgets.Layout(width=\"100px\"))\n", + "y0 = ipywidgets.IntText(value=0, layout=ipywidgets.Layout(width=\"100px\"))\n", + "x1 = ipywidgets.IntText(value=img.size[0], layout=ipywidgets.Layout(width=\"100px\"))\n", + "y1 = ipywidgets.IntText(value=img.size[1], layout=ipywidgets.Layout(width=\"100px\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "controls = ipywidgets.VBox(\n", + " children=[\n", + " ipywidgets.VBox(children=[ipywidgets.Label(\"Upper left:\"), x0, y0]),\n", + " ipywidgets.VBox(children=[ipywidgets.Label(\"Lower right:\"), x1, y1]),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46", + "metadata": {}, + "outputs": [], + "source": [ + "def crop_handler(_):\n", + " cropped_widget.value = img_to_widget(\n", + " img.crop([x0.value, y0.value, x1.value, y1.value])\n", + " ).value\n", + "\n", + "\n", + "x0.observe(crop_handler, names=\"value\")\n", + "y0.observe(crop_handler, names=\"value\")\n", + "x1.observe(crop_handler, names=\"value\")\n", + "y1.observe(crop_handler, names=\"value\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47", + "metadata": {}, + "outputs": [], + "source": [ + "app = ipywidgets.AppLayout(\n", + " left_sidebar=controls,\n", + " center=img_widget,\n", + " right_sidebar=cropped_widget,\n", + " pane_widths=(1, 2, 2),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "48", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "app" + ] + }, + { + "cell_type": "markdown", + "id": "49", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## A simple alternative - interact" + ] + }, + { + "cell_type": "markdown", + "id": "50", + "metadata": {}, + "source": [ + "`ipywidgets` contains a much simpler interface that automatically creates widgets for you. You simply need to annotate (\"decorate\") a function that does something and you will get a continuously updated interactive version:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51", + "metadata": {}, + "outputs": [], + "source": [ + "@ipywidgets.interact(x=(0, 100), y=(0, 100))\n", + "def add(x, y):\n", + " return x + y" + ] + }, + { + "cell_type": "markdown", + "id": "52", + "metadata": {}, + "source": [ + "Notably, this does not change the function nature of `add`. It is merely displaying a UI as a side effect of the function definition:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53", + "metadata": {}, + "outputs": [], + "source": [ + "?add" + ] + }, + { + "cell_type": "markdown", + "id": "54", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "`ipywidgets.interact` has many more options and flavors. Here are some:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55", + "metadata": {}, + "outputs": [], + "source": [ + "@ipywidgets.interact(\n", + " operation=[(\"add\", 1.0), (\"subtract\", -1.0)],\n", + " rounding=False,\n", + " x=(0, 100, 0.1),\n", + " y=(0, 100, 0.1),\n", + ")\n", + "def op(operation, rounding, x, y):\n", + " val = x * operation + y\n", + " if rounding:\n", + " return round(val)\n", + " else:\n", + " return val" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56", + "metadata": {}, + "outputs": [], + "source": [ + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57", + "metadata": {}, + "outputs": [], + "source": [ + "@ipywidgets.interact_manual(x=(0, 100), y=(0, 100))\n", + "def slow_add(x, y):\n", + " time.sleep(1)\n", + " return x + y" + ] + }, + { + "cell_type": "markdown", + "id": "58", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## More information\n", + "\n", + "For more information, see the `ipywidgets` documentation:\n", + "\n", + "[https://ipywidgets.readthedocs.io](https://ipywidgets.readthedocs.io)" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime8/lunchtime8.slides.html b/lunchtime8/lunchtime8.slides.html new file mode 100644 index 0000000..d039d00 --- /dev/null +++ b/lunchtime8/lunchtime8.slides.html @@ -0,0 +1,16850 @@ + + + + + + + + + +lunchtime8 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ + +
+ +
+
+ +
+ +
+
+ +
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + diff --git a/lunchtime9/README.md b/lunchtime9/README.md new file mode 100644 index 0000000..329a722 --- /dev/null +++ b/lunchtime9/README.md @@ -0,0 +1,8 @@ +# Lunchtime #9: mypy + +[mypy](https://mypy.readthedocs.io/en/stable/) is a static type checker for Python. +By adding type annotations to your code mypy can find a variety of bugs. +These type annotations also act as machine-checked documentation of your code, +and your IDE can make use of them to improve its code completion. +They don't affect how your program runs, as the Python interpreter ignores +these type annotations at run-time \ No newline at end of file diff --git a/lunchtime9/duck0.png b/lunchtime9/duck0.png new file mode 100644 index 0000000..c5046cb Binary files /dev/null and b/lunchtime9/duck0.png differ diff --git a/lunchtime9/duck1.png b/lunchtime9/duck1.png new file mode 100644 index 0000000..df48903 Binary files /dev/null and b/lunchtime9/duck1.png differ diff --git a/lunchtime9/duck2.png b/lunchtime9/duck2.png new file mode 100644 index 0000000..f968dcb Binary files /dev/null and b/lunchtime9/duck2.png differ diff --git a/lunchtime9/duck3.png b/lunchtime9/duck3.png new file mode 100644 index 0000000..732214b Binary files /dev/null and b/lunchtime9/duck3.png differ diff --git a/lunchtime9/lunchtime9.ipynb b/lunchtime9/lunchtime9.ipynb new file mode 100644 index 0000000..b85ffae --- /dev/null +++ b/lunchtime9/lunchtime9.ipynb @@ -0,0 +1,1051 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Lunch Time Python\n", + "\n", + "## Lunch 9: mypy\n", + "\n", + "\n", + "[mypy](https://mypy.readthedocs.io/en/stable/) is a static type checker for Python.\n", + "By adding type annotations to your code mypy can find a variety of bugs.\n", + "These type annotations also act as machine-checked documentation of your code,\n", + "and your IDE can make use of them to improve its code completion.\n", + "They doesn't affect how your program runs, as the Python interpreter ignores\n", + "these type annotations at run-time\n", + "\n", + "*Press `Spacebar` to go to the next slide (or `?` to see all navigation shortcuts)*\n", + "\n", + "[Lunch Time Python](https://ssciwr.github.io/lunch-time-python/), [Scientific Software Center](https://ssc.iwr.uni-heidelberg.de), [Heidelberg University](https://www.uni-heidelberg.de/)" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Motivation\n", + "\n", + "- Python is a **dynamically typed** language\n", + " - It infers the type of objects automatically\n", + " - \"Duck typing\" - if something looks like a duck and quacks like a duck, it's a duck\n", + "- This makes Python very flexible and convenient compared to a **statically typed** language like C\n", + " - But this flexibility also leaves room for bugs, makes static analysis difficult\n", + " - Harder to maintain and understand large complicated projects without type safety\n", + "- Solution: add optional **type annotations** (or hints) to your code\n", + " - mypy can use these to check the code for bugs\n", + " - they are ignored by the Python interpreter at run-time" + ] + }, + { + "cell_type": "markdown", + "id": "2", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# How does this help?\n", + "\n", + "Imagine you call a function with the wrong type of object\n", + "\n", + "- This may be a runtime error, e.g. `str` + `int`\n", + " - This is a good bug: the program stops at the place where the bug is!\n", + " - Assuming your test suite executes this line, you find it by running the tests\n", + " - But even better would be to have your IDE point this out as you write the code\n", + "- This may not be an error, just do something undesirable\n", + " - Eventually this may cause a runtime error or incorrect output\n", + " - Hopefully some test fails, but could be very far away from the original bug\n", + " - This is a bad bug: can be hard to trace back to the root cause\n", + " - If your IDE points out the root cause as you type it this is a big win" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "\"DALL·E" + ] + }, + { + "cell_type": "markdown", + "id": "4", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "\"DALL·E" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "\"DALL·E" + ] + }, + { + "cell_type": "markdown", + "id": "6", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "\"DALL·E" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# mypy installation\n", + "\n", + "- Conda: `conda install mypy`\n", + "- Pip: `python -m pip install mypy`\n", + "\n", + "# mypy use\n", + "\n", + "- `mypy my_file_to_check.py`" + ] + }, + { + "cell_type": "markdown", + "id": "8", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### jupyter notebook use\n", + "\n", + "These slides also use the [nb-mypy](https://pypi.org/project/nb-mypy/) extension:\n", + "\n", + "- `python -m pip install nb-mypy`\n", + "\n", + "This automatically runs mypy on every cell before it is executed.\n", + "\n", + "This is just for convenience to show the mypy output for this talk.\n", + "\n", + "In general I would recommend running mypy separately or as a pre-commit hook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if \"google.colab\" in str(get_ipython()):\n", + " !pip install nb-mypy -qqq\n", + "%load_ext nb_mypy" + ] + }, + { + "cell_type": "markdown", + "id": "10", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Hello world" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "def greet(thing):\n", + " return f\"Hello {thing}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(\"world\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(True))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(greet))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def greet(thing: str) -> str:\n", + " return f\"Hello {thing}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(\"world\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(True))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(greet(greet))" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Basic types\n", + "\n", + "- to annotate an object, add its type after a `:`\n", + " - `my_string: str`\n", + "- to annotate the return type of a function, add the type after `->`\n", + " - `def hello() -> str:`\n", + "- intrinsic types like `None`, `int`, `float`, `str`, `bool` can be used directly\n", + "- other types like `list`, `dict`, `tuple`, `set`\n", + " - import a capitalized version from typing: `from typing import List`\n", + " - use `list` directly (only with Python >= 3.9)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def mul(a, b):\n", + " return a * b\n", + "\n", + "\n", + "print(mul(2, 2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(mul(2, [0]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(mul(2, \"really?\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "23", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def mul(a: float, b: float) -> float:\n", + " return a * b\n", + "\n", + "\n", + "print(mul(2, 2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(mul(2, [0]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(mul(2, \"really?\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# does operation & returns result\n", + "def append1(l):\n", + " return l + [1]\n", + "\n", + "\n", + "# does operation in place\n", + "def append2(l):\n", + " l.append(1)\n", + "\n", + "\n", + "l0 = [0]\n", + "print(append1(l0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(append2(l0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "28", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import List\n", + "\n", + "\n", + "def append1(l: List[int]) -> List[int]:\n", + " return l + [1]\n", + "\n", + "\n", + "def append2(l: List[int]) -> None:\n", + " l.append(1)\n", + "\n", + "\n", + "l0 = [0]\n", + "print(append1(l0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(append2(l0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def count(l: List[str]):\n", + " return len(l)\n", + "\n", + "\n", + "a = []\n", + "# a: List[str] = []\n", + "# a.append(\"ok\")\n", + "# a = [\"ok\"]\n", + "print(count(a))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import List, Tuple\n", + "\n", + "\n", + "def count(coords: List[Tuple[float, float]]) -> int:\n", + " return len(coords)\n", + "\n", + "\n", + "print(count([(0, 0), (1, 1), (2, 2)]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import Dict\n", + "\n", + "\n", + "def invert(ages: Dict[str, int]) -> Dict[int, str]:\n", + " return {key: value for value, key in ages.items()}\n", + "\n", + "\n", + "ages = {\"bob\": 2, \"joe\": 7}\n", + "names = invert(ages)\n", + "print(names)" + ] + }, + { + "cell_type": "markdown", + "id": "33", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Generic collections\n", + "\n", + "- if you can do \"for\" to iterate over the object\n", + " - `my_obj: Iterable`\n", + "- if it's like a list\n", + " - `my_obj: Sequence`\n", + "- if it's like a read-only dict\n", + " - `my_obj: Mapping`\n", + "- if it's a dict we can modify\n", + " - `my_obj: MutableMapping`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import Iterable\n", + "\n", + "\n", + "def count(items: Iterable):\n", + " i = 0\n", + " for item in items:\n", + " i += 1\n", + " return i\n", + "\n", + "\n", + "print(count([\"a\", \"b\", \"c\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import Sequence\n", + "\n", + "\n", + "def last(items: Sequence):\n", + " return items[-1]\n", + "\n", + "\n", + "print(last([1, 2, 3]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "print(count([\"a\", \"b\", \"c\"]))\n", + "from typing import Dict, Mapping\n", + "\n", + "\n", + "def invert(ages: Mapping[str, int]) -> Dict[int, str]:\n", + " # ages[\"simon\"] = 12\n", + " return {key: value for value, key in ages.items()}\n", + "\n", + "\n", + "ages = {\"bob\": 2, \"joe\": 7}\n", + "names = invert(ages)\n", + "print(names)" + ] + }, + { + "cell_type": "markdown", + "id": "37", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "\n", + "# Flexible types\n", + "\n", + "- if an object could have several types, use typing.Union\n", + " - `my_obj: Union[str, float]`\n", + "- if an object can be either a dict or None\n", + " - `my_obj: Union[Dict, None]`\n", + " - `my_obj: Optional[Dict]`\n", + "- if an object can be anything\n", + " - `my_obj: Any`\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "38", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def hi(name=None):\n", + " if name is None:\n", + " name = \"you\"\n", + " print(f\"hello {name}\")\n", + "\n", + "\n", + "hi()\n", + "hi(\"joe\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import Union\n", + "\n", + "\n", + "def hi(name: Union[str, None] = None) -> None:\n", + " if name is None:\n", + " name = \"you\"\n", + " print(f\"hello {name}\")\n", + "\n", + "\n", + "hi()\n", + "hi(\"joe\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import Optional\n", + "\n", + "\n", + "def hi(name: Optional[str] = None) -> None:\n", + " if name is None:\n", + " name = \"you\"\n", + " print(f\"hello {name}\")\n", + "\n", + "\n", + "hi()\n", + "hi(\"joe\")" + ] + }, + { + "cell_type": "markdown", + "id": "41", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "\n", + "# Generics\n", + "\n", + "- TypeVar specifies a generic type\n", + " - Possible types can optionally be constrained\n", + " - Within a scope it represents a single type\n", + " - For any c++ programmers it's a bit like a `template`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# concatenation of lists of a single type\n", + "def add(x, y):\n", + " return x + y\n", + "\n", + "\n", + "# desired use\n", + "print(add([1, 2], [3]))\n", + "print(add([\"A\"], [\"B\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# don't want to allow e.g.\n", + "print(add([1.0], [\"B\"])) # this shouldn't be allowed\n", + "print(add([[0]], [{1, 2}])) # this shouldn't be allowed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "44", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import TypeVar, List\n", + "\n", + "T = TypeVar(\"T\")\n", + "\n", + "\n", + "def add(x: List[T], y: List[T]) -> List[T]:\n", + " return x + y\n", + "\n", + "\n", + "print(add([1, 2], [3]))\n", + "print(add([\"A\"], [\"B\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "add([1.0], [\"B\"]) # this shouldn't be allowed\n", + "add([[0]], [{1, 2}]) # this shouldn't be allowed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "from typing import TypeVar\n", + "\n", + "IntOrStr = TypeVar(\"IntOrStr\", str, int)\n", + "\n", + "\n", + "def add(x: List[IntOrStr], y: List[IntOrStr]) -> List[IntOrStr]:\n", + " return x + y\n", + "\n", + "\n", + "print(add([1, 2], [3]))\n", + "print(add([\"A\"], [\"B\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "print(add([1.0, 2.0], [3.0]))" + ] + }, + { + "cell_type": "markdown", + "id": "48", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Other tricks\n", + "\n", + "- to have mypy ignore a line, append\n", + " - `# type: ignore`\n", + "- to see what type mypy infers for an object\n", + " - `reveal_type(my_obj)`\n", + "- to override the inferred type\n", + " - `cast(str, my_obj)`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "def add1(x: int) -> int:\n", + " return x + 1\n", + "\n", + "\n", + "f = 0.1\n", + "\n", + "reveal_type(f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "50", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# (mis)use of type ignore:\n", + "print(add1(f)) # type: ignore" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from typing import cast\n", + "\n", + "# (mis)use of cast:\n", + "print(add1(cast(int, f)))" + ] + }, + { + "cell_type": "markdown", + "id": "52", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# 3rd party libraries\n", + "\n", + "- some libraries include type information and will just work with mypy\n", + "- type information for many other libraries is available from [typeshed](https://github.com/python/typeshed)\n", + " - e.g. for the requests library `pip install types-requests`\n", + " - or run mypy with `--install-types` to automatically download them as needed\n", + "- a few libraries offer a separate stubs package to install instead\n", + "\n", + "If no type information is available, you can add `# type: ignore` to the end of the line where you import the package to suppress mypy error messages related to this package." + ] + }, + { + "cell_type": "markdown", + "id": "53", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# Advanced features\n", + "\n", + "- define your own [protocols](https://mypy.readthedocs.io/en/stable/protocols.html)\n", + " - an example of a built-in protocal is `Iterable[T]`\n", + "- define your own [generic classes](https://mypy.readthedocs.io/en/stable/generics.html)\n", + " - and example of a similar built-in class is `list[X]`\n", + "- use [mypyc](https://mypyc.readthedocs.io/) to compile type-annoted Python to C extensions\n", + " - similar to Cython but code remains valid python & get run-time type checks\n", + " - note: still alpha and not competitive for numeric code" + ] + }, + { + "cell_type": "markdown", + "id": "54", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# TLDR\n", + "\n", + "Add type annotations and run mypy to catch bugs earlier and more easily\n", + "\n", + "# Strategy\n", + "\n", + "- you don't need to annotate everything\n", + "- start with just a few functions in a single file\n", + "- mypy infers types where possible\n", + " - e.g. `a = [1, 2, 3]` is automatically inferred to be a `List[int]`\n", + "- a few annotations can go a long way" + ] + }, + { + "cell_type": "markdown", + "id": "55", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "# More information\n", + "\n", + "- mypy is well documented\n", + "- a good starting point: [getting started](https://mypy.readthedocs.io/en/stable/getting_started.html)\n", + "- basic summary: [cheat sheet](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html)\n", + "- full documentation: [mypy.readthedocs.io](https://mypy.readthedocs.io/)\n", + "- beyond that try github issues: [github.com/python/mypy/issues](https://github.com/python/mypy/issues)\n" + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lunchtime9/lunchtime9.slides.html b/lunchtime9/lunchtime9.slides.html new file mode 100644 index 0000000..a44a8c5 --- /dev/null +++ b/lunchtime9/lunchtime9.slides.html @@ -0,0 +1,17264 @@ + + + + + + + + + +lunchtime9 slides + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + +