From bb8a3db2770f43932c239ded6c2e500305ff99c3 Mon Sep 17 00:00:00 2001 From: Jess Sullivan Date: Tue, 16 Aug 2022 15:50:49 -0400 Subject: [PATCH] updates script user info --- csv/void | 0 financial_vis.ipynb | 389 ----------------- financial_vis.ipynb.archive | 850 ++++++++++++++++++++++++++++++++++++ financial_vis_v2.ipynb | 413 ++++++++++++++++++ 4 files changed, 1263 insertions(+), 389 deletions(-) delete mode 100644 csv/void delete mode 100644 financial_vis.ipynb create mode 100644 financial_vis.ipynb.archive create mode 100644 financial_vis_v2.ipynb diff --git a/csv/void b/csv/void deleted file mode 100644 index e69de29..0000000 diff --git a/financial_vis.ipynb b/financial_vis.ipynb deleted file mode 100644 index 3ed0428..0000000 --- a/financial_vis.ipynb +++ /dev/null @@ -1,389 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4f2b6377-5107-40af-b742-78f4c7060d45", - "metadata": { - "tags": [] - }, - "source": [ - "# **PayPal 🡲 Membershipworks Migration & Reporting**\n", - "## *For the [Ithaca Generator](https://ithacagenerator.org/)*\n", - "\n", - "- - - \n", - "\n", - "#### *A work in progress by [Jess](https://www.transscendsurvival.org/)*\n", - "\n", - "\n", - "#### The objectives of this notebook and its scripts are:\n", - "##### - Merge PayPal & Membershipworks members in a sorta intelligent way to create kinda accurate financial reports\n", - "##### - Convert a PayPal transaction export into an upsert-able csv to import into membershipworks\n", - "##### - Keep tabs on PayPal memberships as they become deprecated \n", - "\n", - "\n", - "\n", - "- - - \n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "b847619f-f175-4e16-9cbf-84e7ee663cdb", - "metadata": {}, - "source": [ - "
\n", - "\n", - "\\pagebreak" - ] - }, - { - "cell_type": "markdown", - "id": "cdd9925f-3f2b-43c7-91e3-d9a7eaa85ede", - "metadata": {}, - "source": [ - "\n", - "## **January 2022 Financial Stuff:**\n", - "\n", - "\n", - "![](table_fig.png)\n", - " \n", - "\n", - "\n", - "![](gross_income.png)" - ] - }, - { - "cell_type": "markdown", - "id": "bf30aed5-13e8-478b-97ed-19860a958995", - "metadata": {}, - "source": [ - "
\n", - "\n", - "\\pagebreak" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6d8315c8-686f-4e5d-ab4f-257b6c422e7c", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "from matplotlib import pyplot as plt\n", - "import matplotlib.patches as mpatches\n", - "from pandas.plotting import table\n", - "import datetime\n", - "import json\n", - "import csv\n", - "import random\n", - "import math\n", - "import random\n", - "import shutil\n", - "import os\n", - "\n", - "# Plot configurations\n", - "# Set matplotlib font size\n", - "SMALL_SIZE = 16\n", - "MEDIUM_SIZE = 18\n", - "BIGGER_SIZE = 24\n", - "EXTRACHUNGUS_SIZE = 28\n", - "EXTRAJANKY_SIZE = 44\n", - "\n", - "plt.rc('font', size=EXTRACHUNGUS_SIZE) # controls default text sizes\n", - "plt.rc('axes', titlesize=EXTRACHUNGUS_SIZE) # fontsize of the axes title\n", - "plt.rc('axes', labelsize=BIGGER_SIZE) # fontsize of the x and y labels\n", - "plt.rc('xtick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", - "plt.rc('ytick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", - "plt.rc('legend', fontsize=EXTRACHUNGUS_SIZE) # legend fontsize\n", - "plt.rc('figure', titlesize=EXTRAJANKY_SIZE) # fontsize of the figure title\n", - "\n", - "# `Halt()` to quietly exit mid cell:\n", - "class HaltNoTrace(Exception):\n", - " def _render_traceback_(self):\n", - " pass\n", - "\n", - "def Halt():\n", - " raise HaltNoTrace\n", - "\n", - "# filter out ragged array warning cause i r b lazy:\n", - "np.warnings.filterwarnings('ignore', category=np.VisibleDeprecationWarning) \n", - "\n", - "## file paths:\n", - "# paypal csv obtained from `https://www.paypal.com/reports/statements/custom`\n", - "paypal_csv_fp = \"./csv/paypal_export.CSV\"\n", - "paypal_df = pd.read_csv(paypal_csv_fp)\n", - "print('loaded %d paypal records' % paypal_df.shape[0])\n", - "\n", - "# memebershipworks csv with existing account IDs exported from `https://membershipworks.com/admin/#folder/Members`\n", - "mw_ids_csv_fp = \"./csv/mw_export.CSV\"\n", - "mw_ids_df = pd.read_csv(mw_ids_csv_fp, encoding='cp437')\n", - "print('loaded %d existing membershipworks records' % mw_ids_df.shape[0])\n", - "\n", - "## files to export\n", - "\n", - "# all members:\n", - "membershipworks_import_fp = './csv/membershipworks_import.csv'\n", - "\n", - "# members as of last month:\n", - "membershipworks_pastmonth_import_fp = './csv/membershipworks_import_pastmonth.csv'\n", - "\n", - "# establish what one month ago was:\n", - "thisMonth = datetime.datetime.today().replace(day=1)\n", - "lastMonth = thisMonth - datetime.timedelta(days=31)\n", - "priorMonth = lastMonth.replace(day=1) - datetime.timedelta(days=31)\n", - "\n", - "# convert the date column values into python datetime objects:\n", - "paypal_df['Date'] = pd.to_datetime(paypal_df['Date'])\n", - "print('converted `Date` column to datetime objects')\n", - "\n", - "# transactions below this value are discarded:\n", - "min_net = 10\n", - "standard_price = 35\n", - " \n", - "# keep only rows from within a range:\n", - "dates_df = paypal_df[paypal_df['Date'] <= thisMonth]\n", - "dates_df = dates_df[dates_df['Date'] >= lastMonth]\n", - "\n", - "print('kept %d records processed between %s and %s; discarded %d records' %\n", - " (dates_df.shape[0],\n", - " thisMonth.__format__('%d/%m/%y').__str__(),\n", - " lastMonth.__format__('%d/%m/%y').__str__(),\n", - " paypal_df.shape[0] - dates_df.shape[0]))\n", - "\n", - "\n", - "members = []\n", - "membership_levels = ['Extra Membership', \n", - " 'Offline Extra Membership',\n", - " 'Standard Membership', \n", - " 'Offline Standard Membership',\n", - " 'Offline VIP Membership']\n", - "\n", - "\n", - "memershipworks_df=pd.DataFrame(columns=['Name',\n", - " 'Email',\n", - " 'Membership Level',\n", - " 'Join Date',\n", - " 'Renewal Date',\n", - " 'Account ID'])\n", - "\n", - "# is there a level value?\n", - "is_lvl = lambda _L: isinstance(_Series[_L].item(), str)\n", - "\n", - "# is there a mw id value?\n", - "has_id = has_level = lambda _S: _S.shape[0] \n", - "\n", - "# some members might make multiple transactions per month; only count transactions > $10.\n", - "for _, row in dates_df.iterrows():\n", - " \n", - " # make sure this is a valid row\n", - " if type(row['From Email Address']) == str:\n", - "\n", - " # make sure this is a membership payment, not a lil donation stub or refund or sumth:\n", - " if eval(row['Net']) > 10 and eval(row['Net']) < 140 and row['Description'] == 'Subscription Payment': \n", - " if row['From Email Address'] not in members:\n", - " members.append(row['From Email Address'])\n", - " else:\n", - " print(\"%s already in member list! continuing...\" % (row['Name'])) \n", - " continue \n", - " else:\n", - " print(\"discarded %s's %s record for %s, continuing...\" % (row['Name'], row['Description'], row['Gross']))\n", - " continue\n", - " \n", - " ## get Account ID if there is one:\n", - " # The pandas series of membershipworks stuff of this Account ID:\n", - " _Series = mw_ids_df[mw_ids_df['Email'] == row['From Email Address']]['Account ID'] \n", - " membership_id = '' if not has_id(_Series) else _Series.item()\n", - "\n", - " ## get membership level if there is one:\n", - " # The pandas series of membershipworks stuff of this email address:\n", - " _Series = mw_ids_df[mw_ids_df['Email'] == row['From Email Address']]\n", - " new_lvl = 'Offline Standard Membership' if eval(row['Gross']) < standard_price else 'Offline Extra Membership'\n", - " membership_level = new_lvl if not has_level(_Series) else [l for l in membership_levels if is_lvl(l)][0]\n", - " \n", - " # get a past join date; not sure how best to actually track this but its whatever:\n", - " join_date = lastMonth.__format__('%m/%d/%Y').__str__()\n", - "\n", - " # append:\n", - " memershipworks_df.loc[row['From Email Address']] = row['Name'], row[\n", - " 'From Email Address'], membership_level, join_date, join_date, membership_id\n", - "\n", - " \n", - "mw_member_names = set(mw_ids_df['Account Name']) - set(memershipworks_df['Name'])\n", - "\n", - "for mw_member in mw_member_names:\n", - " \n", - " # get exported MW member info:\n", - " _Series = mw_ids_df[mw_ids_df['Account Name']==mw_member]\n", - " \n", - " mw_email = _Series['Email'].item()\n", - " \n", - " # get membership id if we can:\n", - " mw_membership_id = _Series['Account ID']\n", - "\n", - " # get membership level if we can:\n", - " mw_membership_level = [l for l in membership_levels if is_lvl(l)][0]\n", - " \n", - " if 'Offline Standard' in mw_membership_level or 'Offline Extra' in mw_membership_level:\n", - " print('please REVIEW %s from MW member directory in PayPal' % mw_member)\n", - " \n", - " mw_join_date = pd.to_datetime(_Series['Join Date']).item().__format__('%m/%d/%Y').__str__()\n", - " memershipworks_df.loc[mw_email] = mw_member, mw_email, mw_membership_level, mw_join_date, mw_join_date, mw_membership_id\n", - "\n", - " \n", - "memershipworks_df.to_csv(membershipworks_import_fp)\n", - "\n", - "export_str = 'exported: %d Members! \\n - %d Standard Members \\n - %d Offline Standard Members \\n - %d Extra Members \\n - %d Offline Extra Members \\n ...to a membershipworks-readable format at %s' % (memershipworks_df.shape[0], memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0],\n", - " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0],\n", - " memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0], \n", - " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0],\n", - " membershipworks_import_fp)\n", - "print(export_str)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91cc475e-a932-4263-abf4-b29ae0bdca06", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot some stuff:\n", - "def bar_view():\n", - " offline_extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", - " offline_extra_gross = 75 * offline_extra_ct\n", - "\n", - " offline_std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", - " offline_std_gross = 35 * offline_std_ct\n", - "\n", - " extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", - " extra_gross = 75 * extra_ct\n", - "\n", - " std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", - " std_gross = 35 * std_ct\n", - "\n", - " counts = [offline_extra_ct, offline_std_ct, extra_ct, std_ct]\n", - " gross = [offline_extra_gross, offline_std_gross, extra_gross, std_gross]\n", - " labels = ['Off. Extra', 'Off. Standard', 'Extra', 'Standard']\n", - "\n", - " counts = np.array(counts)\n", - " gross = np.array(gross)\n", - " labels = np.array(labels)\n", - "\n", - " # sorts our numpy arrays:\n", - " map_sort = lambda *sortables: map(np.array, zip(*sorted(zip(*sortables))))\n", - "\n", - " # this is the order we'll sort by:\n", - " sortable_arrays = gross, counts, labels\n", - "\n", - " # apply sort:\n", - " gross, counts, labels = map_sort(*sortable_arrays)\n", - "\n", - " # reverse so the most prevalent countries are listed first:\n", - " counts = counts[::-1]\n", - " gross = gross[::-1]\n", - " labels = labels[::-1]\n", - "\n", - " # initialize plot:\n", - " width = 0.8\n", - " fig3 = plt.figure(figsize=(12, 12))\n", - " ax3 = fig3.add_subplot()\n", - "\n", - " labels_loc = np.arange(len(labels))\n", - "\n", - " # draw bars:\n", - " rects3 = ax3.bar(labels_loc + width/2, gross, width, label='', color=['blue', 'green', 'green', 'blue'])\n", - "\n", - " plt.xticks(rotation = 75)\n", - " ax3.set_xlabel('Membership Type')\n", - " ax3.set_ylabel('Gross Incoome')\n", - " ax3.set_title('Monthly Gross Income: %d (%d per annum)' % (sum(gross), sum(gross*12)))\n", - "\n", - " ax3.set_xticks(labels_loc)\n", - " ax3.set_xticklabels(labels)\n", - "\n", - " for xy in zip(labels_loc, gross):\n", - " if xy[1]: # if 0, don't plot\n", - " ax3.text(xy[0] + width/2, xy[1], '%s$' % xy[1].__str__(),\n", - " ha='center', va='bottom')\n", - "\n", - " fig3.tight_layout()\n", - " plt.tight_layout()\n", - " plt.savefig('gross_income.png')\n", - " \n", - "bar_view()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e2a8202a-35a3-4c79-9b4e-54dd5a894410", - "metadata": {}, - "outputs": [], - "source": [ - "def table_view(): \n", - " ## build a table of sums ##\n", - " total_members = memershipworks_df.shape[0]\n", - " offline_extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", - " extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", - " offline_std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", - " std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", - " spons_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline VIP Membership'].shape[0]\n", - "\n", - " count_df = pd.DataFrame()\n", - "\n", - " # convert sums with __str__ to avoid recasting\n", - " # as a float when the table gets drawn\n", - " count_df.loc['Count:', 'Total Members'] = total_members.__str__()\n", - " count_df.loc['Count:', 'Offline Extra'] = offline_extra_members.__str__()\n", - " count_df.loc['Count:', 'Extra'] = extra_members.__str__()\n", - " count_df.loc['Count:', 'Offline Standard'] = offline_std_members.__str__()\n", - " count_df.loc['Count:', 'Standard'] = std_members.__str__()\n", - " count_df.loc['Count:', 'Sponsored'] = spons_members.__str__()\n", - "\n", - " # draw long low table only:\n", - " fig = plt.figure(figsize=(18,2))\n", - " ax = fig.add_subplot(111, frame_on=False)\n", - " ax.xaxis.set_visible(False)\n", - " ax.yaxis.set_visible(False)\n", - "\n", - "\n", - " # draw table:\n", - " table_fig = table(ax, count_df, rowLoc='right',\n", - " colLoc='center', loc='bottom',\n", - " bbox=[.1, -0.3, 1, 1.2])\n", - "\n", - " table_fig.auto_set_font_size(False)\n", - " table_fig.set_fontsize(18)\n", - "\n", - " fig.savefig('table_fig.png')\n", - "\n", - "table_view()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.10" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/financial_vis.ipynb.archive b/financial_vis.ipynb.archive new file mode 100644 index 0000000..7ab454b --- /dev/null +++ b/financial_vis.ipynb.archive @@ -0,0 +1,850 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4f2b6377-5107-40af-b742-78f4c7060d45", + "metadata": { + "tags": [] + }, + "source": [ + "# **PayPal 🡲 Membershipworks Migration & Reporting**\n", + "## *For the [Ithaca Generator](https://ithacagenerator.org/)*\n", + "\n", + "- - - \n", + "\n", + "#### *A work in progress by [Jess](https://www.transscendsurvival.org/)*\n", + "\n", + "\n", + "#### The objectives of this notebook and its scripts are:\n", + "##### - Merge PayPal & Membershipworks members in a sorta intelligent way to create kinda accurate financial reports\n", + "##### - Convert a PayPal transaction export into an upsert-able csv to import into membershipworks\n", + "##### - Keep tabs on PayPal memberships as they become deprecated \n", + "\n", + "\n", + "\n", + "- - - \n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "b847619f-f175-4e16-9cbf-84e7ee663cdb", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\\pagebreak" + ] + }, + { + "cell_type": "markdown", + "id": "cdd9925f-3f2b-43c7-91e3-d9a7eaa85ede", + "metadata": {}, + "source": [ + "\n", + "## **January 2022 Financial Stuff:**\n", + "\n", + "\n", + "![](table_fig.png)\n", + " \n", + "\n", + "\n", + "![](gross_income.png)" + ] + }, + { + "cell_type": "markdown", + "id": "bf30aed5-13e8-478b-97ed-19860a958995", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\\pagebreak" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6d8315c8-686f-4e5d-ab4f-257b6c422e7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loaded 297 paypal records\n", + "loaded 88 existing membershipworks records\n", + "converted `Date` column to datetime objects\n", + "kept 99 records processed between 01/02/22 and 01/01/22; discarded 198 records\n", + "discarded nan's General Withdrawal record for -5,000.00, continuing...\n", + "Wendy Marvel already in member list! continuing...\n", + "Wendy Marvel already in member list! continuing...\n", + "Wendy Marvel already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Matthew Stillerman already in member list! continuing...\n", + "Regina DeMauro already in member list! continuing...\n", + "DigitalOcean already in member list! continuing...\n", + "discarded Lightweight Labware, LLC's Invoice Received record for 436.37, continuing...\n", + "FastSpring already in member list! continuing...\n", + "PayPal already in member list! continuing...\n", + "FastSpring already in member list! continuing...\n", + "FastSpring already in member list! continuing...\n", + "Laurence Clarkberg already in member list! continuing...\n", + "please REVIEW Ryan Carey from MW member directory in PayPal\n", + "please REVIEW Jonathan Wells from MW member directory in PayPal\n", + "please REVIEW Noah Avi Dessauer from MW member directory in PayPal\n", + "please REVIEW Denise OÆLeary from MW member directory in PayPal\n", + "exported: 92 Members! \n", + " - 7 Standard Members \n", + " - 58 Offline Standard Members \n", + " - 5 Extra Members \n", + " - 20 Offline Extra Members \n", + " ...to a membershipworks-readable format at ./csv/membershipworks_import.csv\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "import matplotlib.patches as mpatches\n", + "from pandas.plotting import table\n", + "import datetime\n", + "import json\n", + "import csv\n", + "import random\n", + "import math\n", + "import random\n", + "import shutil\n", + "import os\n", + "\n", + "# Plot configurations\n", + "# Set matplotlib font size\n", + "SMALL_SIZE = 16\n", + "MEDIUM_SIZE = 18\n", + "BIGGER_SIZE = 24\n", + "EXTRACHUNGUS_SIZE = 28\n", + "EXTRAJANKY_SIZE = 44\n", + "\n", + "plt.rc('font', size=EXTRACHUNGUS_SIZE) # controls default text sizes\n", + "plt.rc('axes', titlesize=EXTRACHUNGUS_SIZE) # fontsize of the axes title\n", + "plt.rc('axes', labelsize=BIGGER_SIZE) # fontsize of the x and y labels\n", + "plt.rc('xtick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", + "plt.rc('ytick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", + "plt.rc('legend', fontsize=EXTRACHUNGUS_SIZE) # legend fontsize\n", + "plt.rc('figure', titlesize=EXTRAJANKY_SIZE) # fontsize of the figure title\n", + "\n", + "# `Halt()` to quietly exit mid cell:\n", + "class HaltNoTrace(Exception):\n", + " def _render_traceback_(self):\n", + " pass\n", + "\n", + "def Halt():\n", + " raise HaltNoTrace\n", + "\n", + "# filter out ragged array warning cause i r b lazy:\n", + "np.warnings.filterwarnings('ignore', category=np.VisibleDeprecationWarning) \n", + "\n", + "## file paths:\n", + "# paypal csv obtained from `https://www.paypal.com/reports/statements/custom`\n", + "paypal_csv_fp = \"./csv/paypal_export.CSV\"\n", + "paypal_df = pd.read_csv(paypal_csv_fp)\n", + "print('loaded %d paypal records' % paypal_df.shape[0])\n", + "\n", + "# memebershipworks csv with existing account IDs exported from `https://membershipworks.com/admin/#folder/Members`\n", + "mw_ids_csv_fp = \"./csv/mw_export.CSV\"\n", + "mw_ids_df = pd.read_csv(mw_ids_csv_fp, encoding='cp437')\n", + "print('loaded %d existing membershipworks records' % mw_ids_df.shape[0])\n", + "\n", + "## files to export\n", + "\n", + "# all members:\n", + "membershipworks_import_fp = './csv/membershipworks_import.csv'\n", + "\n", + "# members as of last month:\n", + "membershipworks_pastmonth_import_fp = './csv/membershipworks_import_pastmonth.csv'\n", + "\n", + "# establish what one month ago was:\n", + "thisMonth = datetime.datetime.today().replace(day=1)\n", + "lastMonth = thisMonth - datetime.timedelta(days=31)\n", + "priorMonth = lastMonth.replace(day=1) - datetime.timedelta(days=31)\n", + "\n", + "# convert the date column values into python datetime objects:\n", + "paypal_df['Date'] = pd.to_datetime(paypal_df['Date'])\n", + "print('converted `Date` column to datetime objects')\n", + "\n", + "# transactions below this value are discarded:\n", + "min_net = 10\n", + "standard_price = 35\n", + " \n", + "# keep only rows from within a range:\n", + "dates_df = paypal_df[paypal_df['Date'] <= thisMonth]\n", + "dates_df = dates_df[dates_df['Date'] >= lastMonth]\n", + "\n", + "print('kept %d records processed between %s and %s; discarded %d records' %\n", + " (dates_df.shape[0],\n", + " thisMonth.__format__('%d/%m/%y').__str__(),\n", + " lastMonth.__format__('%d/%m/%y').__str__(),\n", + " paypal_df.shape[0] - dates_df.shape[0]))\n", + "\n", + "\n", + "members = []\n", + "membership_levels = ['Extra Membership', \n", + " 'Offline Extra Membership',\n", + " 'Standard Membership', \n", + " 'Offline Standard Membership',\n", + " 'Offline VIP Membership']\n", + "\n", + "\n", + "memershipworks_df=pd.DataFrame(columns=['Name',\n", + " 'Email',\n", + " 'Membership Level',\n", + " 'Join Date',\n", + " 'Renewal Date',\n", + " 'Account ID'])\n", + "\n", + "# is there a level value?\n", + "is_lvl = lambda _L: isinstance(_Series[_L].item(), str)\n", + "\n", + "# is there a mw id value?\n", + "has_id = has_level = lambda _S: _S.shape[0] \n", + "\n", + "# some members might make multiple transactions per month; only count transactions > $10.\n", + "for _, row in dates_df.iterrows():\n", + " \n", + " # make sure this is a valid row\n", + " if type(row['From Email Address']) == str:\n", + " \n", + " # make sure this is a membership payment, not a lil donation stub or refund or sumth:\n", + " try:\n", + " if eval(row['Net']) > 10 and eval(row['Net']) < 140 and row['Type'] == 'Subscription Payment': \n", + " if row['From Email Address'] not in members:\n", + " members.append(row['From Email Address'])\n", + " else:\n", + " print(\"%s already in member list! continuing...\" % (row['Name'])) \n", + " continue \n", + "\n", + " ## get Account ID if there is one:\n", + " # The pandas series of membershipworks stuff of this Account ID:\n", + " _Series = mw_ids_df[mw_ids_df['Email'] == row['From Email Address']]['Account ID'] \n", + " membership_id = '' if not has_id(_Series) else _Series.item()\n", + "\n", + " ## get membership level if there is one:\n", + " # The pandas series of membershipworks stuff of this email address:\n", + " _Series = mw_ids_df[mw_ids_df['Email'] == row['From Email Address']]\n", + " new_lvl = 'Offline Standard Membership' if eval(row['Gross']) < standard_price else 'Offline Extra Membership'\n", + " membership_level = new_lvl if not has_level(_Series) else [l for l in membership_levels if is_lvl(l)][0]\n", + "\n", + " # get a past join date; not sure how best to actually track this but its whatever:\n", + " join_date = lastMonth.__format__('%m/%d/%Y').__str__()\n", + "\n", + " # append:\n", + " memershipworks_df.loc[row['From Email Address']] = row['Name'], row[\n", + " 'From Email Address'], membership_level, join_date, join_date, membership_id\n", + " \n", + " except:\n", + " print(\"discarded %s's %s record for %s, continuing...\" % (row['Name'], row['Type'], row['Gross']))\n", + " \n", + " \n", + "mw_member_names = set(mw_ids_df['Account Name']) - set(memershipworks_df['Name'])\n", + "\n", + "for mw_member in mw_member_names:\n", + " \n", + " # get exported MW member info:\n", + " _Series = mw_ids_df[mw_ids_df['Account Name']==mw_member]\n", + " \n", + " mw_email = _Series['Email'].item()\n", + " \n", + " # get membership id if we can:\n", + " mw_membership_id = _Series['Account ID']\n", + "\n", + " # get membership level if we can:\n", + " mw_membership_level = [l for l in membership_levels if is_lvl(l)][0]\n", + " \n", + " if 'Offline Standard' in mw_membership_level or 'Offline Extra' in mw_membership_level:\n", + " print('please REVIEW %s from MW member directory in PayPal' % mw_member)\n", + " \n", + " mw_join_date = pd.to_datetime(_Series['Join Date']).item().__format__('%m/%d/%Y').__str__()\n", + " memershipworks_df.loc[mw_email] = mw_member, mw_email, mw_membership_level, mw_join_date, mw_join_date, mw_membership_id\n", + "\n", + " \n", + "memershipworks_df.to_csv(membershipworks_import_fp)\n", + "\n", + "export_str = 'exported: %d Members! \\n - %d Standard Members \\n - %d Offline Standard Members \\n - %d Extra Members \\n - %d Offline Extra Members \\n ...to a membershipworks-readable format at %s' % (memershipworks_df.shape[0], memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0],\n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0],\n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0], \n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0],\n", + " membershipworks_import_fp)\n", + "print(export_str)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "66705453-2b93-4baa-8040-37f6d89e5bfc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Position/relationAdmin noteAccount NameFirst NameLast NameContact PersonAddress (Full)Address (Street)Address (City)Address (State/Province)...Offline VIP MembershipStandard MembershipofflineJoin DateRenewal DateBilling MethodAuto Billing IDIP AddressAccount IDParent Account ID
0NaNNaNRyan CareyRyanCareyNaNNaNNaNNaNNaN...NaNNaNNaNNov 30, 2021Feb 22, 2022Manual BillingNaN74.69.164.14761c3ad5eb323af62587e0a0cNaN
1NaNNaNJonathan WellsJonathanWellsNaNNaNNaNNaNNaN...NaNNaNNaNNov 30, 2021Feb 22, 2022Manual BillingNaNNaN61c3ad5eb323af62587e0a0dNaN
2NaNNaNNoah Avi DessauerNoah AviDessauerNaNNaNNaNNaNNaN...NaNNaNNaNNov 30, 2021Feb 22, 2022Manual BillingNaN68.175.144.261c3ad5eb323af62587e0a0eNaN
3NaNNaNAndrew RestrepoAndrewRestrepoNaNNaNNaNNaNNaN...NaNNaNNaNNov 30, 2021Feb 22, 2022Manual BillingNaNNaN61c3ad5eb323af62587e0a0fNaN
4NaNNaNBrenda BluestoneBrendaBluestoneNaNNaNNaNNaNNaN...NaNNaNNaNNov 30, 2021Feb 22, 2022Manual BillingNaNNaN61c3ad5eb323af62587e0a11NaN
..................................................................
83NaNNaNMisbah MusthafaMisbahMusthafaNaNNaNNaNNaNNaN...NaNStandard MembershipofflineFeb 2, 2022Mar 9, 2022Standard Membershipcus_L4zkaTUaUqAaTe67.249.140.061faee33056d745cbc75ab83NaN
84NaNNaNJohnFuchsNaNFuchsNaNNaNNaNNaN...Offline VIP MembershipNaNNaNFeb 3, 2022NaNNaNNaNNaN61fc325b30cc9c697e66d0d1NaN
85NaNNaNUther ElderUtherElderNaNNaNNaNNaNNaN...NaNStandard MembershipNaNFeb 11, 2022Mar 18, 2022Standard Membershipcus_L8P19Tdezwa0F067.241.67.946206ec3eb024cb19027c5955NaN
86NaNNaNJacob TyrellJacobTyrellNaNNaNNaNNaNNaN...NaNStandard MembershipNaNFeb 17, 2022Feb 24, 2022Standard Membershipcus_LAXlczFxi7y4as172.58.239.94620e752f7217ac16ad0d8e46NaN
87NaNNaNMaryam AdibMaryamAdibNaNNaNNaNNaNNaN...NaNNaNNaNFeb 18, 2022Feb 25, 2022Extra Membershipcus_LAzrOp3CQASPvX67.241.70.20762100d89628b0138d5258043NaN
\n", + "

88 rows × 44 columns

\n", + "
" + ], + "text/plain": [ + " Position/relation Admin note Account Name First Name Last Name \\\n", + "0 NaN NaN Ryan Carey Ryan Carey \n", + "1 NaN NaN Jonathan Wells Jonathan Wells \n", + "2 NaN NaN Noah Avi Dessauer Noah Avi Dessauer \n", + "3 NaN NaN Andrew Restrepo Andrew Restrepo \n", + "4 NaN NaN Brenda Bluestone Brenda Bluestone \n", + ".. ... ... ... ... ... \n", + "83 NaN NaN Misbah Musthafa Misbah Musthafa \n", + "84 NaN NaN John Fuchs NaN \n", + "85 NaN NaN Uther Elder Uther Elder \n", + "86 NaN NaN Jacob Tyrell Jacob Tyrell \n", + "87 NaN NaN Maryam Adib Maryam Adib \n", + "\n", + " Contact Person Address (Full) Address (Street) Address (City) \\\n", + "0 NaN NaN NaN NaN \n", + "1 NaN NaN NaN NaN \n", + "2 NaN NaN NaN NaN \n", + "3 NaN NaN NaN NaN \n", + "4 NaN NaN NaN NaN \n", + ".. ... ... ... ... \n", + "83 NaN NaN NaN NaN \n", + "84 Fuchs NaN NaN NaN \n", + "85 NaN NaN NaN NaN \n", + "86 NaN NaN NaN NaN \n", + "87 NaN NaN NaN NaN \n", + "\n", + " Address (State/Province) ... Offline VIP Membership \\\n", + "0 NaN ... NaN \n", + "1 NaN ... NaN \n", + "2 NaN ... NaN \n", + "3 NaN ... NaN \n", + "4 NaN ... NaN \n", + ".. ... ... ... \n", + "83 NaN ... NaN \n", + "84 NaN ... Offline VIP Membership \n", + "85 NaN ... NaN \n", + "86 NaN ... NaN \n", + "87 NaN ... NaN \n", + "\n", + " Standard Membership offline Join Date Renewal Date \\\n", + "0 NaN NaN Nov 30, 2021 Feb 22, 2022 \n", + "1 NaN NaN Nov 30, 2021 Feb 22, 2022 \n", + "2 NaN NaN Nov 30, 2021 Feb 22, 2022 \n", + "3 NaN NaN Nov 30, 2021 Feb 22, 2022 \n", + "4 NaN NaN Nov 30, 2021 Feb 22, 2022 \n", + ".. ... ... ... ... \n", + "83 Standard Membership offline Feb 2, 2022 Mar 9, 2022 \n", + "84 NaN NaN Feb 3, 2022 NaN \n", + "85 Standard Membership NaN Feb 11, 2022 Mar 18, 2022 \n", + "86 Standard Membership NaN Feb 17, 2022 Feb 24, 2022 \n", + "87 NaN NaN Feb 18, 2022 Feb 25, 2022 \n", + "\n", + " Billing Method Auto Billing ID IP Address \\\n", + "0 Manual Billing NaN 74.69.164.147 \n", + "1 Manual Billing NaN NaN \n", + "2 Manual Billing NaN 68.175.144.2 \n", + "3 Manual Billing NaN NaN \n", + "4 Manual Billing NaN NaN \n", + ".. ... ... ... \n", + "83 Standard Membership cus_L4zkaTUaUqAaTe 67.249.140.0 \n", + "84 NaN NaN NaN \n", + "85 Standard Membership cus_L8P19Tdezwa0F0 67.241.67.94 \n", + "86 Standard Membership cus_LAXlczFxi7y4as 172.58.239.94 \n", + "87 Extra Membership cus_LAzrOp3CQASPvX 67.241.70.207 \n", + "\n", + " Account ID Parent Account ID \n", + "0 61c3ad5eb323af62587e0a0c NaN \n", + "1 61c3ad5eb323af62587e0a0d NaN \n", + "2 61c3ad5eb323af62587e0a0e NaN \n", + "3 61c3ad5eb323af62587e0a0f NaN \n", + "4 61c3ad5eb323af62587e0a11 NaN \n", + ".. ... ... \n", + "83 61faee33056d745cbc75ab83 NaN \n", + "84 61fc325b30cc9c697e66d0d1 NaN \n", + "85 6206ec3eb024cb19027c5955 NaN \n", + "86 620e752f7217ac16ad0d8e46 NaN \n", + "87 62100d89628b0138d5258043 NaN \n", + "\n", + "[88 rows x 44 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# did we lose anyone in paypal?\n", + "mw_ids_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91cc475e-a932-4263-abf4-b29ae0bdca06", + "metadata": {}, + "outputs": [], + "source": [ + "# Plot some stuff:\n", + "def bar_view():\n", + " offline_extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", + " offline_extra_gross = 75 * offline_extra_ct\n", + "\n", + " offline_std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", + " offline_std_gross = 35 * offline_std_ct\n", + "\n", + " extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", + " extra_gross = 75 * extra_ct\n", + "\n", + " std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", + " std_gross = 35 * std_ct\n", + "\n", + " counts = [offline_extra_ct, offline_std_ct, extra_ct, std_ct]\n", + " gross = [offline_extra_gross, offline_std_gross, extra_gross, std_gross]\n", + " labels = ['Off. Extra', 'Off. Standard', 'Extra', 'Standard']\n", + "\n", + " counts = np.array(counts)\n", + " gross = np.array(gross)\n", + " labels = np.array(labels)\n", + "\n", + " # sorts our numpy arrays:\n", + " map_sort = lambda *sortables: map(np.array, zip(*sorted(zip(*sortables))))\n", + "\n", + " # this is the order we'll sort by:\n", + " sortable_arrays = gross, counts, labels\n", + "\n", + " # apply sort:\n", + " gross, counts, labels = map_sort(*sortable_arrays)\n", + "\n", + " # reverse so the most prevalent countries are listed first:\n", + " counts = counts[::-1]\n", + " gross = gross[::-1]\n", + " labels = labels[::-1]\n", + "\n", + " # initialize plot:\n", + " width = 0.8\n", + " fig3 = plt.figure(figsize=(12, 12))\n", + " ax3 = fig3.add_subplot()\n", + "\n", + " labels_loc = np.arange(len(labels))\n", + "\n", + " # draw bars:\n", + " rects3 = ax3.bar(labels_loc + width/2, gross, width, label='', color=['blue', 'green', 'green', 'blue'])\n", + "\n", + " plt.xticks(rotation = 75)\n", + " ax3.set_xlabel('Membership Type')\n", + " ax3.set_ylabel('Gross Incoome')\n", + " ax3.set_title('Monthly Gross Income: %d (%d per annum)' % (sum(gross), sum(gross*12)))\n", + "\n", + " ax3.set_xticks(labels_loc)\n", + " ax3.set_xticklabels(labels)\n", + "\n", + " for xy in zip(labels_loc, gross):\n", + " if xy[1]: # if 0, don't plot\n", + " ax3.text(xy[0] + width/2, xy[1], '%s$' % xy[1].__str__(),\n", + " ha='center', va='bottom')\n", + "\n", + " fig3.tight_layout()\n", + " plt.tight_layout()\n", + " plt.savefig('gross_income.png')\n", + " \n", + "bar_view()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e2a8202a-35a3-4c79-9b4e-54dd5a894410", + "metadata": {}, + "outputs": [], + "source": [ + "def table_view(): \n", + " ## build a table of sums ##\n", + " total_members = memershipworks_df.shape[0]\n", + " offline_extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", + " extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", + " offline_std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", + " std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", + " spons_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline VIP Membership'].shape[0]\n", + "\n", + " count_df = pd.DataFrame()\n", + "\n", + " # convert sums with __str__ to avoid recasting\n", + " # as a float when the table gets drawn\n", + " count_df.loc['Count:', 'Total Members'] = total_members.__str__()\n", + " count_df.loc['Count:', 'Offline Extra'] = offline_extra_members.__str__()\n", + " count_df.loc['Count:', 'Extra'] = extra_members.__str__()\n", + " count_df.loc['Count:', 'Offline Standard'] = offline_std_members.__str__()\n", + " count_df.loc['Count:', 'Standard'] = std_members.__str__()\n", + " count_df.loc['Count:', 'Sponsored'] = spons_members.__str__()\n", + "\n", + " # draw long low table only:\n", + " fig = plt.figure(figsize=(18,2))\n", + " ax = fig.add_subplot(111, frame_on=False)\n", + " ax.xaxis.set_visible(False)\n", + " ax.yaxis.set_visible(False)\n", + "\n", + "\n", + " # draw table:\n", + " table_fig = table(ax, count_df, rowLoc='right',\n", + " colLoc='center', loc='bottom',\n", + " bbox=[.1, -0.3, 1, 1.2])\n", + "\n", + " table_fig.auto_set_font_size(False)\n", + " table_fig.set_fontsize(18)\n", + "\n", + " fig.savefig('table_fig.png')\n", + "\n", + "table_view()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9389731b-8695-4510-8cf9-af81b3238a84", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/financial_vis_v2.ipynb b/financial_vis_v2.ipynb new file mode 100644 index 0000000..3885b3a --- /dev/null +++ b/financial_vis_v2.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4f2b6377-5107-40af-b742-78f4c7060d45", + "metadata": { + "tags": [] + }, + "source": [ + "# **PayPal 🡲 Membershipworks Migration & Reporting**\n", + "## *For the [Ithaca Generator](https://ithacagenerator.org/)*\n", + "\n", + "- - - \n", + "\n", + "#### *A work in progress by [Jess](https://www.transscendsurvival.org/)*\n", + "\n", + "\n", + "#### The objectives of this notebook and its scripts are:\n", + "##### - Merge PayPal & Membershipworks members in a sorta intelligent way to create kinda accurate financial reports\n", + "##### - Convert a PayPal transaction export into an upsert-able csv to import into membershipworks\n", + "##### - Keep tabs on PayPal memberships as they become deprecated \n", + "\n", + "\n", + "\n", + "- - - \n", + "\n", + "## How to use this notebook:\n", + "\n", + "1. export the last three months of paypal transactions as `./csv/paypal_export.CSV` from `https://www.paypal.com/reports/statements/custom`\n", + "2. export all current MW member transaction data as `./csv/mw_export.CSV` from `https://membershipworks.com/admin/#folder/Members`\n", + "3. Uncomment \"review user\" print lines; this script will identify membership discrepancies and alert you to paypal users that have canceled their membership, thus no longer need to be represented in MW as offline users. Use this information to delete, update, modify users in MW after comparing data in paypal and MW for flagged users." + ] + }, + { + "cell_type": "markdown", + "id": "b847619f-f175-4e16-9cbf-84e7ee663cdb", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\\pagebreak" + ] + }, + { + "cell_type": "markdown", + "id": "cdd9925f-3f2b-43c7-91e3-d9a7eaa85ede", + "metadata": {}, + "source": [ + "\n", + "## **August 2022 Financial Stuff:**\n", + "\n", + "![](table_fig.png)\n", + "\n", + "![](gross_income.png)\n" + ] + }, + { + "cell_type": "markdown", + "id": "bf30aed5-13e8-478b-97ed-19860a958995", + "metadata": {}, + "source": [ + "
\n", + "\n", + "\\pagebreak" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6d8315c8-686f-4e5d-ab4f-257b6c422e7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loaded 208 paypal records\n", + "loaded 106 existing membershipworks records\n", + "converted `Date` column to datetime objects\n", + "kept 60 records processed between 01/07/22 and 01/08/22; discarded 148 records\n", + "exported: 93 Members! \n", + " - 22 Standard Members \n", + " - 33 Offline Standard Members \n", + " - 5 Extra Members \n", + " - 12 Offline Extra Members \n", + " ...to a membershipworks-readable format at ./csv/membershipworks_import.csv\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "import matplotlib.patches as mpatches\n", + "from pandas.plotting import table\n", + "import datetime\n", + "import json\n", + "import csv\n", + "import random\n", + "import math\n", + "import random\n", + "import shutil\n", + "import os\n", + "\n", + "# Plot configurations\n", + "# Set matplotlib font size\n", + "SMALL_SIZE = 16\n", + "MEDIUM_SIZE = 18\n", + "BIGGER_SIZE = 24\n", + "EXTRACHUNGUS_SIZE = 28\n", + "EXTRAJANKY_SIZE = 44\n", + "\n", + "plt.rc('font', size=EXTRACHUNGUS_SIZE) # controls default text sizes\n", + "plt.rc('axes', titlesize=EXTRACHUNGUS_SIZE) # fontsize of the axes title\n", + "plt.rc('axes', labelsize=BIGGER_SIZE) # fontsize of the x and y labels\n", + "plt.rc('xtick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", + "plt.rc('ytick', labelsize=BIGGER_SIZE) # fontsize of the tick labels\n", + "plt.rc('legend', fontsize=EXTRACHUNGUS_SIZE) # legend fontsize\n", + "plt.rc('figure', titlesize=EXTRAJANKY_SIZE) # fontsize of the figure title\n", + "\n", + "# `Halt()` to quietly exit mid cell:\n", + "class HaltNoTrace(Exception):\n", + " def _render_traceback_(self):\n", + " pass\n", + "\n", + "def Halt():\n", + " raise HaltNoTrace\n", + " \n", + "# filter out ragged array warning cause i r b lazy:\n", + "np.warnings.filterwarnings('ignore', category=np.VisibleDeprecationWarning) \n", + "\n", + "## file paths:\n", + "# paypal csv obtained from `https://www.paypal.com/reports/statements/custom`\n", + "paypal_csv_fp = \"./csv/paypal_export.CSV\"\n", + "paypal_df = pd.read_csv(paypal_csv_fp)\n", + "print('loaded %d paypal records' % paypal_df.shape[0])\n", + "\n", + "# memebershipworks csv with existing account IDs exported from `https://membershipworks.com/admin/#folder/Members`\n", + "mw_ids_csv_fp = \"./csv/mw_export.CSV\"\n", + "mw_ids_df = pd.read_csv(mw_ids_csv_fp, encoding='cp437')\n", + "print('loaded %d existing membershipworks records' % mw_ids_df.shape[0])\n", + "\n", + "## files to export\n", + "\n", + "# all members:\n", + "membershipworks_import_fp = './csv/membershipworks_import.csv'\n", + "\n", + "# members as of last month:\n", + "membershipworks_pastmonth_import_fp = './csv/membershipworks_import_pastmonth.csv'\n", + "\n", + "# establish what one month ago was:\n", + "thisMonth = datetime.datetime.today().replace(day=1)\n", + "lastMonth = thisMonth - datetime.timedelta(days=31)\n", + "priorMonth = lastMonth.replace(day=1) - datetime.timedelta(days=31)\n", + "\n", + "# convert the date column values into python datetime objects:\n", + "paypal_df['Date'] = pd.to_datetime(paypal_df['Date'])\n", + "print('converted `Date` column to datetime objects')\n", + "\n", + "# transactions below this value are discarded:\n", + "min_net = 10\n", + "standard_price = 35\n", + " \n", + "# keep only rows from within a range:\n", + "dates_df = paypal_df[paypal_df['Date'] <= thisMonth]\n", + "dates_df = dates_df[dates_df['Date'] >= lastMonth]\n", + "\n", + "print('kept %d records processed between %s and %s; discarded %d records' %\n", + " (dates_df.shape[0],\n", + " lastMonth.__format__('%d/%m/%y').__str__(),\n", + " thisMonth.__format__('%d/%m/%y').__str__(),\n", + " paypal_df.shape[0] - dates_df.shape[0]))\n", + "\n", + "\n", + "members = []\n", + "membership_levels = ['Extra Membership', \n", + " 'Offline Extra Membership',\n", + " 'Standard Membership', \n", + " 'Offline Standard Membership',\n", + " 'Offline Basic Membership',\n", + " 'Offline VIP Membership']\n", + "\n", + "\n", + "memershipworks_df=pd.DataFrame(columns=['Name',\n", + " 'Email',\n", + " 'Membership Level',\n", + " 'Join Date',\n", + " 'Renewal Date',\n", + " 'Account ID'])\n", + "\n", + "# is there a level value?\n", + "is_lvl = lambda _L: isinstance(_Series[_L].item(), str)\n", + "\n", + "# is there a mw id value?\n", + "has_id = has_level = lambda _S: _S.shape[0] \n", + " \n", + "mw_member_names = set(mw_ids_df['Account Name'])\n", + "pp_names = paypal_df['Name'].values\n", + "\n", + "for mw_member in mw_member_names:\n", + " \n", + " # get exported MW member info:\n", + " _Series = mw_ids_df[mw_ids_df['Account Name']==mw_member]\n", + " \n", + " try:\n", + " mw_email = _Series['Email'].item()\n", + "\n", + " # get membership id if we can:\n", + " mw_membership_id = _Series['Account ID']\n", + "\n", + " # get membership level if we can:\n", + " mw_membership_level = [l for l in membership_levels if is_lvl(l)][0]\n", + "\n", + " if mw_member not in pp_names and 'Offline' in mw_membership_level:\n", + " # uncomment the following print lines to see paypal and MW discrepancies to investigate\n", + " _ = True # print(mw_member + ' ' + mw_membership_level)\n", + "\n", + " if 'Offline Standard' in mw_membership_level or 'Offline Extra' in mw_membership_level:\n", + " _ = True # print('please REVIEW %s from MW member directory in PayPal' % mw_member)\n", + " \n", + "\n", + " mw_join_date = pd.to_datetime(_Series['Join Date']).item().__format__('%m/%d/%Y').__str__()\n", + " memershipworks_df.loc[mw_email] = mw_member, mw_email, mw_membership_level, mw_join_date, mw_join_date, mw_membership_id\n", + " \n", + " except:\n", + " # print(mw_email)\n", + " continue\n", + " \n", + "memershipworks_df.to_csv(membershipworks_import_fp)\n", + "\n", + "export_str = 'exported: %d Members! \\n - %d Standard Members \\n - %d Offline Standard Members \\n - %d Extra Members \\n - %d Offline Extra Members \\n ...to a membershipworks-readable format at %s' % (memershipworks_df.shape[0], memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0],\n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0],\n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0], \n", + " memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0],\n", + " membershipworks_import_fp)\n", + "\n", + "print(export_str)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "91cc475e-a932-4263-abf4-b29ae0bdca06", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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9tln2+6LiNlarsaNG8eVV17J2LFjDWIkSdJCoTsP7O9SEbEIcCl5uuOXqT64vjQN89Q6RU0pu96/St5G8/evlSCldF5KaUhKaciKK84xo5wWIieccEJbALP33ntzzz33cO655wIwdepUnn/+eS6//HIOPvhg+vTpsyCrKkmSNN8sTC0xvyV3JfsA+GxKacICro9U14wZM7jyyisBGDp0KNdddx0RwVNP5Un3Fl10UdZee23WXnttPv3pTzNx4sQFWV1JkqT5ZqFoiYmI08ndyGYCh6aU7qqRdHKxXaxOcYuXXZ9UJW+j+SfVSaNu4Pvf/z4DBw6kX79+LLvssmy66aYce+yxPProo02Vc+SRR7LaaqvRt29fll9+ebbaaitOOOEEXnzxxbr53njjDSZPzm+rfffdt8MxQksuuWRT9ZIkSWpVPT6IiYjvA98DEvDFlNKVdZKXxqvUW8a2fN/YKnkbzT+2Thp1A3fffTcvvfQSH3zwAe+++y6PPvoo55xzDptuuinHHXcc06dPb6ickSNHMmbMGKZPn87bb7/NqFGjOOOMM1h//fX56U9rLxm02GLtsfD48ePn+vFIkiT1FD26O1lEfAP4SXHzuJTShR1kKc08tlFE9KoxQ1lpVrEEPFl2/1PFfQFsQpXpkyOiF7BBxbHUzQwYMIADDjiAHXbYgbXXXps+ffowZswYbrnlFi644AKmTJnC2WefzYQJExg+fHjNcgYNGsQBBxzAdtttx5prrkmvXr146aWXuO6667jsssuYPn06J554Iu+//37VBS+XWWYZBg8ezGOPPcbvfvc79txzTz7ykY/MuwcuSZLUImLOCbq6p4gYCJT632yUUnqqg/RfBn5f3PxuSunnDRxjY9qnR942pTTHWjERcS555rB7U0rbVey7H9gK+L+U0per5N0OKC3GuWEji10OGTIkjRo1qqNkPVKp+9ROO+3EyJEjm85fPsXyEUccUTfgKJk8eTJ9+/atOUj+6aefZrfdduPVV18FYMSIEey1115zpJswYQJLLbVUzS5g99xzD3vssQfvvfcevXr14uGHH+ZDH/rQHOlGjBjBvvvuy6xZOZ7efvvtWWKJJbjtttt44YUX5moKaUmSpO4uIh5IKQ2pvL9HdieLiCOAc4qbpzYSwACklJ4AHilufqdKuasCnyluXlqliMuK7aERUW0K5dI8wg80EsBo/ltiiSXqzvK1wQYbcMkll7TdPvvss6umW3rppeuOYdluu+3a8s6aNYvf/e53VdPtvffeXHXVVay22mpA7uJ22223AbD22mszYMAAjj76aB5/vOrSRJIkST1Stw5iImKF0gUoXx59mfJ9RTetUp4DgT+Ru3WdkVL6UZOHPbHYHhgRv4iIJYtyNwauB5YEXgDOr5L3XOClIs2IIg8RsWRE/AI4oOIYakE77bQTG220EQB33nlnWytJsw499NC2wfj1Wpr2228/XnjhBa6++mqOOuoo1llnnbZ948aN4/zzz2ezzTarO75GkiSpJ+nWQQzwRtnlwbL776nYV74i5BlA7+L64RHxep3L9pUHTCndCPyguPkd4J2ImEDuZrYF8Cawb0rp/Sp5pwL7Am8VaR8v8r5blJWA76WUbu3Ec6FuZJNNNgFg2rRpvPXWW50qY5FFFmGDDfIQqVL3tFr69u3L/vvvz/nnn89JJ50EwO233843vvENFl98cWbOnMmJJ57IX/7yl07VRZIkqZV09yCmM8of08odXPpWKyCl9BPgY8ANwDtAP3Lry9nA4JTSY7UOnlJ6BBhcpH2hyPtWUdbHUko/m4vHpm6io+mO50c5u+yyC2eeeSYPPfQQSy+9NAC//vWvu6RekiRJ3Vm3np0spdT0P7yU0sAuOvY/gH90Mu/rwHHFRT1QaQxKv379WH755TtVxowZM3j66Tw0atVV683KXd/666/PQQcdxJ/+9Kem17CRJElqRT2xJUaap/7973/zxBN5huwddtiBXr069zG6/PLLee+994A8zmZulCYj6N27dwcpJUmSWp9BjFR45513uOOOO+qmefrppzn00EPbbn/1q1+dI83o0aN58MEH57i/3D333MPXvvY1IHcp+8pXvjJHmvHjx/OnP/2JmTNn1i1r7NixXHPNNQBsuummddNKkiT1BN26O5kWHg8//DAPP/xw1X2vv/76HGu87LHHHgwYMGC2+/7zn//w3HPPtd1+8803264/99xzc5Rx0EEH0b9//7bbEyZMYJdddmHw4MHst99+bLnllqy66qr06dOH1157bbbFLgE+/elPs//++89R39GjRzN06FC22WYb9tlnHzbffHNWXnllIqJtsctLL72UGTNmAHDCCSewxRZbzFHOlClTOOqoozjttNP4/Oc/z2677dY2oQDA888/z80338zpp5/OuHHjgOpBlSRJUk/TMotdLqwWlsUuTz75ZE455ZSG099xxx3svPPOs903bNgwLrrooobLePHFFxk4cGDb7fLFMeuJCI499lh++ctf0rfvnHNDjBw5kqFDh3ZYTp8+ffjRj37EiSeeWHWA/+uvv86GG27IhAkT5jh+tc/tt771LX75y192eFxJkqRWUWuxS1tipMKqq67K3/72N+69917++9//8uqrr/Lmm28ydepUllpqKdZdd1122GEHvvCFL7StE1PNlltuySWXXMK9997LAw88wJgxY3jzzTeZPn06yyyzDBtssAFDhw7lqKOOYo011qhZzoABAxg7dizXX389t9xyCw888ACjR49m4sSJpJTo168fK6+8Mttttx3HHHNMQ4GTJElST2BLTDe3sLTEqHHDhw/nyCOPrNoaI0mS1JPUaolxYL8kSZKklmIQI0mSJKmlGMRIkiRJaikGMVKLGTZsmONhJEnSQs3ZyVRXlZl/JQCMoyRJ0oJiS4wkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSp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j9vKOOWUU6oe55133knLLrtsAtJqq62WXn/99TnSHHXUUW3lXHTRRTUf17Rp09Kpp56a1lprrbb05Zdll1027b333ukPf/hDzTIkSeoMYFRKc/5HtjtZN2d3MnVXfnXMbubMmaywwgq8++67rLnmmrzwwgv07t27atqtt96a//73v6y88sqMGTOGXr3aG8WvuuoqDjroIAB+/OMfc9JJJ82Rf9asWWy44YY8++yzLLvssowfP55FFllktjS/+tWv+Pa3vw3AxRdfzOc+97k5ypk0aRKrr746EyZMYPDgwTz66KNzpJkyZQq77ror9957b9t9EUG1347VVlutrZVGkqSuYHcySZqHnn32Wd59910Adt9995oBDMCee+4JwLhx4/j3v/89276rr7667frnP//5qvl79erV1q3snXfeYeTIkXOkKZWz5JJLcvDBB1ctp3///m37HnvsMZ577rk50vziF79oC2A+8pGP8I9//IMbb7wRgKeffpqXX36Za665hmHDhrH44ovXfMySJHUlgxhJ6gJvvfVW2/WVV165btry/Xfeeeds+/7zn/8AsN5667HqqqvWLGPo0KFz5CmZPn06999/PwDbbrst/fr161Q5AH/5y18A2HDDDfnHP/7BrrvuyqKLLgpA3759WWONNdhvv/248MILeeCBB2oeR5KkrmQQI0ldoH///m3XJ0yYUDdtqcUG4PHHH2+7PmnSJF555RUANt5447plbLjhhm3XK2dCe+aZZ5gxY8ZclwPw4osvArDHHnu0BS+1LLnkknX3S5LUVQxiJKkLrLvuuvTp0weAf/3rX3XTlre+vPzyy23XX3vttbaxJquvvnrdMpZbbrm27lulwKekfFxKR+WsscYabdcrywFYbLHFABg/fnzdciRJmp8MYiSpCyyxxBLstttuADz66KNccsklVdP985//5JZbbmm7PXHixKrXy1t2aimlqZxmuZlyyvdXm655xx13BOCKK67gmmuu6bBOkiTNDwYxktRFTj755LZZwo488khOPvlkRo8ezYwZMxgzZgxnnXUWn/zkJ9tabACmTp1a9Xrfvn07PF5prEt5vmbLKR8vU1kOwCmnnMKiiy7KjBkzOOCAA9h88835zW9+A8Do0aOrzlImSdK8ZhAjSV1k66235k9/+hN9+/ZlxowZnHLKKQwaNIg+ffqw2mqr8c1vfpNp06ZxzjnntOUpH0dS6roF1FwIs9z7778/R75myymVUa0cgC222ILbbruNDTbYAIBHHnmEv//970CeFGC55Zbj0EMP5Z577umwvpIkdRWDGEnqQocffjj3338/Bx988GwBSq9evdhtt92466672GeffdruX3bZZduul6ev1rWrUilNZZexZsop31+r69kOO+zAE088wc0338yxxx7L4MGD2/a9++67XHbZZWy//fZ89atftWVGkjRfLNJxEklSMzbbbDOuuOIKZs6cydixY5k2bRqrrrpq20D88qmMN9lkk7brq622WttCkh0tGvn2228zZcoUYPbB+TD7YP6OyikfzF9ZTrlevXrx8Y9/nI9//OOMHDmSoUOH8te//pXHHnuM3/3ud7zzzjv8/ve/Z4011uC73/1u3WNKkjS3bImRpHmkd+/erL766qy77rqzLQQ5atSotuvbbLNN2/X+/fu3BRLVpjsu99RTT7Vdr5xGef31128bmzM35XRk66235tRTT+Wpp55irbXWAuA3v/mNrTGSpHnOIEaS5rO//e1vACy++OKzdS2D3HUL4Nlnn2XMmDE1yxg5cuQceUr69OnD1ltvDcC9995bd1xMvXIatdJKK3HUUUcB8Prrr/Pmm292qhxJkhplECNJ89FNN93E3XffDcDnPvc5ll566dn2H3DAAW3XL7jggqplzJo1i4suugjIY2p23nnnOdKUypk4cSJXXHFF1XImTZrUtm/w4MGsu+66zT2YMuUzrvXu3bvT5UiS1AiDGEnqQq+99lrNfQ899BCHHXYYACuuuCKnn376HGn23Xdf1ltvPQB+/vOf8/TTT8+R5qc//SnPPPMMAMcff3xb17FyX/jCF9omDfje975XdbHKb37zm0yYMAGA73znO1XrfMYZZ8w2g1k1kydPbguqVl99dZZbbrm66SVJmlth3+XubciQIam8//z8FrHADq1uzq+O6pZddll22GEH9t57bwYPHsxiiy3Ga6+9xogRI7jwwguZPn06iy++OCNGjGDo0KFVy7j11lvZc889mTlzJiussALf//732W677Zg0aRKXXHIJw4cPB2CjjTbi/vvvrzmr2J/+9Ke2bl4DBw7kxBNPZPPNN+eNN97g3HPP5brrrgNgp5124p///Ce9es15XisiGDBgAEcccQSf+MQn2GyzzXj44YcZOnQo//nPf3j++ec57bTT2oKq008/ne9973tz+zRKkgRARDyQUhoyx/0GMd2bQYy6K786quvfvz+TJ0+uuX/QoEFcdNFF7LjjjnXLGT58OF/+8peZNm1a1f0bbbQRN9xwA4MGDapbzmmnncYPf/hDZs2aVXX/9ttvz/XXX1+z9WTAgAGMGzdutvtKM6hV+tSnPsWll15qdzJJUpcxiGlRBjHqrvzqqO6vf/0rt956K/fffz9jx47lvffeY8UVV2TjjTfmwAMP5Igjjqi6qGQ1Tz31FGeffTa33norr732Gostthjrr78+hxxyCF/+8pcbLuf+++/nnHPO4V//+hevv/46Sy65JJtssgmf+9znOPLII+sGHdOnT+eWW27hpptu4r///S/PP/88EyZMYObMmfTp04cVVliBrbbaimHDhrH//vs3VB9JkhplENOiDGLUXfnVsfAqrRPz4osvMnDgwAVdHUlSD1YriHFgvyRJkqSWYhAjSZIkqaUYxEiSJElqKXMuLiBJUh0777xz1dnJJEmaXwxiJLW0OMXZJ1Rd+pGBliT1VHYnkyRJktRSDGIkSZIktRSDGEmSJEktxSBGkiRJUksxiJEkSZLUUgxiJEmSJLUUgxhJkiRJLcUgRpIkSVJLMYiRJEmS1FIMYiRJkiS1FIMYSZIkSS3FIEaSJElSSzGIkSRJktRSDGIkSZIktRSDGEmSJEktxSBGkiRJUksxiJEkSZLUUgxiJEmSJLUUgxhJkiRJLcUgRpIkSVJLMYiRJEmS1FIMYiRJkiS1FIMYSZIkSS3FIEaSJElSSzGIkSRJktRSDGIkSZIktRSDGEmSJEktxSBGkiRJUksxiJEkSZLUUgxiJEmSJLUUgxhJkiRJLcUgRpIkSVJLMYiRJEmS1FIMYiRJkiS1FIMYSZLUY5x88skMHDhwQVdD0jxmECNJ0kJg5513JiKaugwfPny2MprNHxGMHj26br3+9re/seeee7LqqqvSr18/1lhjDQ4++GBuu+22efdkSGp5BjGSJKmqDTfccK7yL7300gwYMKDqvvfff5/99tuPQw45hJtuuomxY8fywQcf8Oqrr3LllVey++6785WvfIWU0lzVQVLPtMiCroAkSZr3LrzwQiZPnlw3zbhx49htt90AWH/99dl2221n2//oo492eJwbbriB7373uwB86lOfYtFFF62a7qijjuLaa68FYIcdduAb3/gGa665Jk899RS/+MUvePTRR/nDH/7ACiuswKmnntrhcVNKjB07lrfeeovp06fz6quvsvLKK9OnT58O80pqPQYxkiQtBAYNGtRhmltvvbXt+hFHHDHH/sGDB3dYxoknnli3DIA777yTSy65BIBPfOITXHfddSyySP5LMmTIEPbbbz922GEHHnnkEX72s59xxBFHsM4661Qta8yYMfzoRz/iqquu4p133mm7f4011iAiWH311dl555057LDD+NjHPtZh/SW1hh7bnSwiekXEkRHxj4h4IyKmR8S7EXFfRHw/Ipask7dvRJwQEQ9HxKQi3z0RcXRERAPH3i0iro+I8RExLSKej4jfRMTKXfsoJUnqOhdddBEAvXr14rDDDms6/xtvvMFNN90EwHrrrcf2229fNd0ZZ5wBQO/evfnDH/7QFsCU9O/fn9/+9rcATJ8+nV//+tdVy3nmmWfYfPPN+eMf/9gWwJT/TKeUeOWVV7j44ovbHpuknqFHBjERsThwG3ABsCuwAjAZWArYGvgJ8GhErF0l71LA3cDPgc2AABYDtgXOBa6LiJotWBHx/eLYewPLA+8DawNfL47Z8WksSZLms0ceeYT//e9/AOyyyy6sscYaTZdx2WWXMWPGDKB2K8ykSZPaBu3vuuuurLXWWlXT7bjjjqy33noA/P3vf686Nuboo4/mjTfeAGDYsGE8/PDDnHTSSay11lpMmjSJp556igsuuIBPfOIT9OrVI//ySAutnvqJ/gGwC5CA7wHLpJSWARYFPgO8C6wF/LFK3vOBLYG3gX2A/sDiwDBgGjk4OaXaQSNiT3KABPCr4rhLA4OBh4EVgWsjot/cPTxJkrpWeUtFrQCk0TIiomZLzn//+1/ef/99AHbaaae65e28884AvPrqq7z00kuz7Rs7diz/+te/gBzAXHjhhWy22WZtwcoSSyzBBhtswJFHHsmNN97IOeec06nHJKl76qlBzGeL7YUppZ+llCYApJQ+SCn9BfhGsX9oRCxbyhQRHwYOKW4emVIakbKZKaWLgO8W+74REStVOe7pxfaalNK3U0oTi+M+Tg6IJpFbZY7uoscpSdJcmzFjBpdeeikASy65JAcccEDTZTz66KM89NBDAAwdOpQ111yzaronnnii7frGG29ct8zy2dHK8wGzTd283377dVi/JZes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CSmlVGP/b4El6+SfCCzXmYpJkiRJUjUdBTHTgcVq7Uwpnd5B/v5AzbE0kiRJktSsjrqTvQEsGhErN1twRAwAFi3KkCRJkqQu0VEQ82Cx/Xgnyv5ERRmSJEnSQm348OFERMcJVVdHQczN5IUr/19E9G200IjoB5xAntnsps5XT5IkSQuDKVOmcOWVV3LCCSewyy67sN5667HsssvSp08fVlhhBT7ykY9w8skn89prr9UsY+DAgUREU5eRI0fOUU4p0GjkcvLJJ8+7J0U1dTQm5mLyIpcbApdHxGEppSn1MkTE4sAl5FnJxhbXJUmSpJqeeOIJDj744Kr73nrrLe6++27uvvtufvnLX3LOOedwxBFHzPUxe/XqxXrrrTfX5Wj+qxvEpJTej4ijgWuA/YDHIuLXwI0ppefK00bEusBewHHAWsBM4OiU0vvzoN6SJEnqYVZZZRWGDh3KlltuyVprrcUqq6xC7969ee2117jhhhu47LLLmDx5MkceeSQrrrgie+6552z5b731Vj744IO6x3jooYc4/PDDAdhtt91YbbXV6qa/5ZZbWHXVVWvuX2mllRp8dDB+/Hhef/11AF566SUGDBhAv379Gs6vdh21xJBSuj4ijgHOAQYCZwFnRcQ04N0i2TLkQfyQu599AHwlpXRDF9dXkiRJPdCHP/xhxowZU3P/AQccwDHHHMMOO+zA9OnTOemkk+YIYtZff/0Oj3Peeee1XW+kNWf99ddn4MCBHaarZcKECZx66qlceumljBs3ru3+Upkrr7wyO+64IwcffDCHHHJIp4+zsOloTAwAKaU/AdvTPkYmyFMvr1JcFiu7/yZgu5TSBfOiwpIkSep5evfu3WGarbfeml122QXILSqTJk1q6hjTp0/n8ssvB2CppZZi//33b76iTRg/fjxbbbUVZ555ZlsAUzmof9y4cVx55ZWcffbZ87QuPU2HLTElKaUHgT0jYnVgJ2Aj2heyfBt4EvhXSunVLq+lJEmSBCy5ZPs66++//z79+/dvOO+NN97Im2++CcAhhxzCYovVXA6xS5xwwgk8++yzAOy99958//vf59FHH+Xoo49m6tSpjBkzhvvvv5+rr76aN95wVZJmNBzElBRByqXzoC6SJElSTW+88Qa33347ACussALLL798U/kvuuiitutdMTFAPTNmzODKK68EYOjQoVx33XVEBE899RQAiy66KGuvvTZrr702n/70p5k4ceI8rU9P01B3sp4gIvpHxCsRkYrLsDpp+0bECRHxcERMioh3I+KeiDg6GpjYOyJ2i4jrI2J8REyLiOcj4jedWTRUkiRpYTZt2jReeOEFzjvvPLbbbjveeecdAI4//vimynnrrbe44YY8XHudddZhhx12aCjfkUceyWqrrUbfvn1Zfvnl2WqrrTjhhBN48cUX6+Z74403mDx5MgD77rtvh2vDlLcwqWNNt8S0sJ8Aq3eUKCKWAv4JbFncNYU85mfb4rJPROyfUppRI//3i2MBzAImAWsDXwc+ExG7pJQem5sHIkmS1JONGDGCffbZp+b+YcOG8Z3vfKepMi+//PK2mctKs5M1onwdmbfffpu3336bUaNGcdZZZ3Hqqafyve99r2q+8q5q48ePb6qu6thC0RITEVsAxwL3NZD8fHIA8zawD9AfWBwYBkwD9gZOqXGcPWkPYH4FLJNSWhoYDDwMrAhcWywGKkmSpCasu+663H777Vx44YX07dvwOuwA/PnPfwbywPpGgphBgwbxrW99iyuvvJL777+fUaNGcdVVV3HEEUfQp08fZsyYwYknnlhzsctlllmGwYMHA/C73/2Ou+66q6n6qr5IKS3oOsxTEdGLHLx8GNgKeLDYdWRKaXhF2g+X7d83pXRdxf7jgF8DU4GBKaXxFfsfBjYDrkkpHVCxb3Xy5Af9ga+nlH7bSP2HDBmSRo0a1UjSeaLjznNaWHWXr444xTepqks/6h5vUt+jqqW7vEe7o4kTJ/LSSy8BefD+Sy+9xHXXXccll1zCyiuvzGmnncawYcMaLu/JJ59k4403BmDnnXfmjjvuqJt+woQJLLXUUjW7gN1zzz3ssccevPfee/Tq1YuHH36YD33oQ3OkGzFiBPvuuy+zZs0CYPvtt2eJJZbgtttu44UXXmDQoEENP4aFVUQ8kFIaUnn/wtAS8zVgCPCHlNJDHaT9bLF9ujKAKZwHTCB3L6sMUjYhBzAAZ1RmLCZEuLy4eWhjVZckSVr4LLnkkgwePJjBgwez5ZZbcsABBzB8+HBuueUW3nrrLY488khOPfXUhstrdkD/0ksvXXcMy3bbbdc2JfKsWbP43e9+VzXd3nvvzVVXXdW2oObdd9/NbbfdBsDaa6/NgAEDOProo3n88ccbfizKenQQExGrAT8GxgEnNZBlaLG9tdrOlNJU4N/FzV1q5J1A7W5rtxTbrSOi8fkAJUmSxK677spxxx0HwCmnnNI201c9s2bN4pJLLgFgiSWW4KCDDuqSuhx66KFtg/HLx81U2m+//XjhhRe4+uqrOeqoo1hnnXXa9o0bN47zzz+fzTbbjJ/+9KddUq+FRY8OYoDfAksC304pTaiXsJh1bMPiZr1w+Iliu3HF/aXbT6aUZnWQt/xYkiRJatC+++4L5ODk6quv7jD97bffzmuvvQbAgQce2NS6MvUsssgibLDBBgC8+mr9ZRL79u3L/vvvz/nnn89JJ53UVq9vfOMbLL744sycOZMTTzyRv/zlL11St4VBjw1iImIfYH9gZErpkgayLAUsUVwfUyddad8qFfevUrG/Xt5q+SVJktSBFVdcse16adxMPfNybZgGVt6oaZddduHMM8/koYceYumllwbg17/+dRfVrOfrkUFMRCwB/A6YDny1wWxLlF2fWifdlGJbGcaX8jeSt1r+NsV6NKMiYpSrt0qSJLUrtaoAHbaqTJw4kWuuuQaANddck6FDh9ZN34wZM2bw9NNPA7Dqqqt2upz111+/rYvbo48+2iV1Wxj0yCAGOBVYEzgrpfRER4m7m5TSeSmlISmlIeVnGyRJkhZ2f/vb39quV5sRrDLtlCn5HPJhhx02Vy0nlS6//HLee+89AHbaaae5KqtPnz4A9O7de67rtbDocUFMRGwOHAe8Qg5mGjW57PpiNVPlNWMgL2JZLX8jeavllyRJWmhdfPHFTJpU/+/RFVdcwbnnngvkGcQ++clP1k1fWhsGGu9KNnr0aB588MG6ae655x6+9rWvAblL2Ve+8pU50owfP54//elPzJw5s25ZY8eObWst2nTTTRuqo2CRBV2BeeA3QG/g++Tx+rXaGfsV+2allKYA75EDkSWAem2CpX1jK+4fU7G/Xt5q+SVJkhZav/rVrzj22GPZf//9+ehHP8p6663HUkstxeTJk3nqqae48soruemmm4AcOPzmN79hueWWq1ne6NGjufPOO4G8Pst6663XUD1Gjx7N0KFD2Wabbdhnn33YfPPNWXnllYmItvVqLr30UmbMmAHACSecwBZbbDFHOVOmTOGoo47itNNO4/Of/zy77bYbm2yySdv+559/nptvvpnTTz+dcePGAfDVrzY6CkI9MYhZq9j+uW4q+L/i8hJ54coUEU+S15TZpE6+0ixkld3USrc3ioheNWYoK+VN5IUvJUmSVHjvvfe46KKLZhuMX2m55Zbjt7/9LZ/97GdrpoHcClNa1L0zA/rvu+8+7ruv1qoZuQvYj370I0488cSq+xdddFGWXnppXnzxRX7wgx/wgx/8AGifDGDdddedLf23vvUtPvOZzzRdz4VVTwxi5sYd5CDmY9V2RsSiwI7Fzdur5AVYGtiK6mvF7F5s70spTa6yX5IkaaF09dVXM2LECO666y6eeeYZxo0bx5tvvknfvn1ZYYUV2HTTTdljjz347Gc/yzLLLNNheaWuZIsuuiiHHHJIw/XYcsstueSSS7j33nt54IEHGDNmDG+++SbTp09nmWWWYYMNNmDo0KEcddRRrLHGGjXLGTBgAGPHjuX666/nlltu4YEHHmD06NFMnDiRlBL9+vVj5ZVXZrvttuOYY47p0kkHFgZRilAXFhFResBHppSGV+z7MFDqBLlPSmlExf6vAWeTZyAbmFIaX7H/YWAz4KqU0kEV+1YFniKvW/O1lFL1pV0rDBkyJI0aNaqRpPNEF45/Uw/TXb464hTfpKou/ah7vEl9j6qW7vIe1fw1fPhwjjzySBa2/+CdFREPpJSGVN7f4wb2z42U0kPAFcXN4RGxJ0BE9I6Iw4GfF/vOqgxgCqX2xAMj4hcRsWSRf2PgenIA8wJw/rx6DJIkSVJPZxAzpy8CDwDLAzdExGTygP+LyDOPjQB+VC1jSulG4AfFze8A70TEBOBxYAvgTWDflNL78/QRSJIkST2YQUyFlNJ7wPbAd4FHyIPw3wfuBY4BPplSmlEn/0/IY2puAN4B+pFbX84GBqeUHpunD0CSJEnq4Ra6MTGtxjEx6q66y1eH4w1US3cZb+B7VLV0l/eo1J05JkaSJElSj+AUy5IkSQsxe12onu7S86KSLTGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaX0yCAmItaMiOMj4vqIeDki3o+IiRHxSET8LCJW6SB/34g4ISIejohJEfFuRNwTEUdHRDRw/N2KY4+PiGkR8XxE/CYiVu66RylJkiQtnBZZ0BXoahGxBjAaKA823gOWADYtLkdHxIEppTuq5F8K+CewZXHXFGAxYNvisk9E7J9SmlHj+N8HflLcnAVMAtYGvg58JiJ2SSk9NlcPUpIkSVqI9cSWmN7F9gbgYGC5lNLSwOLAnsCLwLLA3yNiQJX855MDmLeBfYD+Rd5hwDRgb+CUageOiD1pD2B+BSxTHHsw8DCwInBtRPSbq0coSZIkLcR6YhDzDvDhlNLeKaUrU0rvAKSUPkgp3UQOZKYBSwHHlGeMiA8DhxQ3j0wpjUjZzJTSRcB3i33fiIiVqhz79GJ7TUrp2ymlicWxHycHRKVWmaO77NFKkiRJC5keF8SklCaklB6ps/8p4N7i5pYVuz9bbJ9OKV1XJft5wARy97IDyndExCbAZsXNM6oc91Xg8uLmofUegyRJkqTaelwQ06C3im3vivuHFttbq2VKKU0F/l3c3KVG3gnAfTWOe0ux3Toi+jdWVUmSJEnlFrogJiIWAT5S3Hys7P4ANixuPl6niCeK7cYV95duP5lSmtVB3vJjSZIkSWrCQhfEAF8FBpBnDruo7P6lyDOYAYypk7+0r3Ka5lUq9tfLWy1/m2Iq51ERMeqNN96oU5wkSZK08FmogpiI2BT4aXHzdymlJ8p2L1F2fWqdYqYU28ruYKX8jeStlr9NSum8lNKQlNKQFVdcsU5xkiRJ0sJnoQliigUu/04elP8A8P8WaIUkSZIkdcpCEcRExHLkwfqDgGeBvVJK0yqSTS67vlid4hYvtpNq5G8kb7X8kiRJkhrQ44OYiFiaPCvYYOBlYLeU0rgqSd+jPRBZtU6RpX1jK+4fU7G/Xt5q+SVJkiQ1oEcHMRGxBHAjMAR4nRzAvFwtbUopAU8WNzepU2xpFrInKu4v3d4oImo9r6W85ceSJEmS1IQeG8RExGLA9cD25HVhdkspPdtBtjuK7cdqlLkosGNx8/YaeZcGtqpR/u7F9r6U0uQaaSRJkiTV0SODmIjoC1xNXoDyXWD3lFK9tV9KLi+2G0bE3lX2f5EcpEwFrinfUcx09khx8ztV6rQq8Jni5qUN1EWSJElSFT0uiImI3sBlwB7AROATKaUHG8mbUnoIuKK4OTwi9iyVGRGHAz8v9p2VUhpfpYgTi+2BEfGLiFiyyL8xuVVoSeAF4PzmH5kkSZIkgEUWdAXmgY8ABxbX+wB/j4haaV9JKVV2/foisA6wJXBDREwBegP9iv0jgB9VKyyldGNE/AD4Mbk15psRMZm8kCbAm8C+KaX3m35UkiRJkoAe2BLD7I9pUWDlOpc5VpJMKb1HHkfzXXL3sAS8D9wLHAN8MqU0o9bBU0o/IY+puQF4hxz8vACcDQxOKT02dw9PkiRJWrj1uJaYlNJIoGbTS4NlfEDuOvbzjtLWyP8P4B9zUwdJkiRJ1fXElhhJkiRJPZhBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQYwkSZKklmIQI0mSJKmlGMRIkiRJaikGMZIkSZJaikGMJEmSpJZiECNJkiSppRjESJIkSWopBjGSJEmSWopBjCRJkqSWYhAjSZIkqaUYxEiSJElqKQYxkiRJklqKQcw8EhEDIuI3EfF8REyLiHERcX1E7Lqg6yZJkiS1MoOYeSAiNgUeA74OrA28D6wA7A3cFhHfXYDVkyRJklqaQUwXi4jFgOuA5YGHgMEppaWBZYFfAQGcHhG7L7haSpIkSa3LIKbrHQOsBUwC9kkpPQ6QUnovpfRt4O/kQOanC6yGkiRJUgsziOl6hxbby1JKr1XZf0ax3SIiNphPdZIkSZJ6DIOYLhQRSwJbFjdvqZHsXmBCcd1B/pIkSVKTDGK61kbkrmIAj1dLkFKaBTxd3Nx4flRKkiRJ6kkWWdAV6GFWKbs+pk660r5Vqu2MiKOBo4ubkyLi6Wrp5pMVgDcX4PHVTUV0nGY+8T2qquLkbvMm9T2qqnyPqhV0g9/7tardaRDTtZYouz61TropxbZ/tZ0ppfOA87qqUnMjIkallIYs6HpItfgeVXfne1Tdne9RtSK7k0mSJElqKQYxXWty2fXF6qRbvNhOmod1kSRJknokg5iuVT4OZtU66Ur7xs7DunSVbtGtTarD96i6O9+j6u58j6rlREppQdehxyimWJ5AnqHswJTS1VXS9ALeBpYGvppS+v38raUkSZLU2myJ6UIppYnAqOLmx2ok24YcwADcPs8rJUmSJPUwBjFd77Jie2hEVJtC+dvF9oGU0oKcOlmSJElqSQYxXe9c4CVgSWBERGwMuatZRPwCOKBId+ICqp8kSZLU0hwTMw9ExGbkrmLLF3e9R14TpheQgBNTSj9bQNWTJEmSWppBzDwSEQOA7wF7A6uRA5n7gbNSSj1iLExEfBMYD9ydUnphQddHkiRJCweDGHVKRCxGXhcnAa8Cj5ODtHuBh1JK4xZg9aQ2ERHJLzpJknoUgxh1SkSsDvwcWB3YBFiu2PUB8CLwKDmouQd4JKXkwp5aYCKiT0pp+oKuhxZuRQv9uymlaQu6LpLU6gxi1GkRsRywArA2sDGwJbBecb0fMLW4vAw8RG6l+S/wREpp5oKosxYexZpMmwK7kYPsxcgLzD5Cnh3wzQVYPS1kImIt8oKCdwKPAS+Q34/vppRmLMi6SVIrMohRl4iIRcldy/YBvgLsXOx6D1gC6F3cHgM8Sw5q7ib/mXxxvlZWPVap61hE9AGOA04GFie/NwOYBEwn/3n8H7m18D5ya+GUBVJpLRQi4hjgD8XNScBz5ID6YeBJ8qyW44AJdn9Ud2X3XHUnBjGaK+VfaBHxUeBS8lnvn5O7lfUinwHfANgW2IzcSvM+MIMc3ByXUvrj/K+9epqI6JVSmhUR3yZPY74ocAn57PfRwA7kP4pLkd+XU4C3gVfIwfXfUko3LIi6q2eLiMHAfsBg4MPAWkDfYvdb5HGFD5FbaZ4mvyffTClNnu+V1UKp7CRQf2ARcvfwJYFpwMSU0qxaeeZzVSXAIEZzqexLbxAwkvzH8JMppXsr0i1FDmQOBb5GPit+N7A9sHtK6R/zteLq0SLiOXI3x8+nlIYX9z0ObER+DwJ8mRzUQP6RXhQ4JaV0yvytrRY2xULIQ8jBzLbAVrRPyZ/IrTJP0h7UPAe8BryVUvpgvldYC42IOBLYA/gE8C7wVHEpD67HO85V3YFBjOZKRCySUpoREV8DfkOeQvpbxXiEqDb2JSI+A1wI/Izcledmz+RobpW1wmxDnlDiwZTSkGLfcsCbwEsppUHFfWsCJwGHAacBqwJnp5SeWiAPQD1a8Z1I+dnsiAjgV8Dx5MBlKrASOaBevEg2ldxKWApqXgT+kVJ6Z37VXT1f0SX8aODXxV0Ti+2SZcleIU/a8yg5qHkGeB14rVorjTSvLbKgK6CWV/ri2q3Y/rPY9qocrBoRvYug5hbgAXILzMnFD7k0t0rvo52K7TVl+0r33Q1t78WXI+IM4ABgR2Afz3JrXin9ySsLttcn/2EcCvwW+HNK6YFi+vrBwHbAQeTWwk2Ly6eK4tYADGI018p+l3cgjyF8G/hd8du8D3AtuRVwNPAR8ntvT/LYwpfJgczB5K650nzVa0FXQK2t+DEO8jgXyGcRAWZVBicppZlFy83b5DOLW0TEdrbCqIuUAur1i+2dZft2Lrb/LrZRdIV8FrgS+BD5x1ma10q/u4eRu+2cmVI6rghgFkkpTU0p/TeldHZK6aPkIPtV4A3gZmBUSum1BVN19WCfBpYBfgn8tLiv9F36h5TSjsCuwI3ksTLjgAHAYCdF0YJiEKO5VgQhNxc3v1qsyTGrPDiJAlDqXrYpeVDrW/O3tuqpirFZi5DfV7PIM5CVrFts/1dsZ9LeEr0E+cd44HyophZyZS3UBxXbi6DtjPiM4nqviOhd3Pd34I/kiVB+TR5HKHWJsi7fexbbi1NK7xfX9yu29xRp7wC+Qe5WNhb4PDkYlxYIgxh1ldvJfbq3AG6MiF2LwfxA/oNZEhHbAZsDb6SUnlkw1VUPlchjBqaTJ5IgIhYnD1Btu69QarnZptj6XtR8ERErA4OACcCLZV16gNzCnVKaWXbf78ljZD5Nfo9Lc63UWyIiBpJ7UTxRauUrTghtQ55J9N7ivt5F6/WvyTONjk0p3TlnydL8YRCjuVb08X4UOIvcL3ZX4BfA/4uIT0bE1hGxZURsVEwA8Lci618XUJXVQxV/+q4hD9QfW9w3hTwQtQ+wT0QsVsTTMyPiKHIrzQsppVcWVL210FmcPNNTX2Cvjhb/LRZmTeQZzfrWSys1odTlewPy/8GHyvZtQW6tfjSlNLX4nS+9T28kvw8PQlqAHNivuVYasJpSOjsiXiOvz/Hh4jKLfGb8A/L0trPIX5aXks8uSl0qpfRwMZ1y+Ww515IXYd0PeDIiHiT/gO9J7qZz6fyupxZOxVisFyNiFHks1vER8XxxIoiIKC0MXPpeTRGxJXm8wlMppf/f3n3H2VVX+/9/vdOAQELoHUIXA5EuggioSBcFFewgelHUC/bCtX2VK9YfFuReVERExCsoRUGUEkBCC71D6EgLhHRCQrJ+f6zPzuycnJm0mTMzZ97Px+M89pxdTj5nZuecvfbns9bn5d5ot7WfWkWxeWQVvOeqwhPA5mVb1UMtScNK8ZNNyro1W9das0W5J8aWSfVFK+lgSY9IOrokpZ4PvBf4AtkFLfLDcEOyFONzwBeBT7mUrXWH2pCINSQdL2mLiJjbMDznPuCzwE3AemQwcyh5I+cndMykbtajarmCvyWHk70J+I6kfcr2eeVRDb/dGjixHPPP1rfYBoD7gafJ3MChZd0TwAxga0nrl3Oyqt74zrK8vaWtNGvgeWJsmVRjuCX9Avg4nUwSKGllskdmbbIi2cOuZGLdqXYufgz4X+ByYL9mVe/K3DBvICuRjQAmAJcsbjiPWU+QdBDwazqqOj4FXE2WAp8MvJk8X7cF7gXeFxF3Nnkps+VSJqxeOyJuLM9XJW/6bAn8kuytnkEG3V8le2FeV/UgmvUGBzG2XCRdSZav3Tginip3xUX28s1vNgFWGU7hE8+6RW3ejVOBTwDviYjzasMiqv0WnHc+B63VaufpGGAt4PaImCLpjcDHyIBlg04Ovwf4eERc16LmWpurnY9rAlMa53Ur+xwF/IAcyliV9d6YLJLyh4g4qjWtNWvOOTG2zCStQM5dMK0sq6ESQS0focxUHdVFoy8erTvVApWVynJCtalhv6j/3BjkmPWwKon62+TEgh8GLo2If0m6kawEtQOZZL05sBk5KfA44IqIeLjlLbaB4BfABpI+D9zQ8Dl5pqTZZJA9hswffAK4APh6L7TVbCHuibHlIukj5BwGh0bExY0Bi1mrSHoHcA5wYESMayxba9bbSi7hNDLgHhkRM+rBdClrOzwippXnK0bE7N5rsbUzSSPIvKzpwEbVeVe21XuuhwOvJXtkbomIl3qhuWaLcGK/LbVaUv/hZLfyROAoSSOiYZJLs55UguZqngPIMdvHw0KTuNUnWzXrTZuTd7OvaQxgICfCjIhp1bkaEbN93lp3q51T25Xl1eW8qyrjNfZcz4qICRFxuQMY60s8nMyWWu3isEr0G0rOtbGepNPIqmTPRMSMxmOdi2DdrPoy/gUwkqywc6ikX5NJ/vdExMzGc87nofWSF8kqjdV5O4iFS4EDiw59bE3TbKConVMzye/wqozyILLc8iL8mWl9kYeT2TKRtC5wHlmudjVgxfJ4AbgDuBW4k6xI9hTwYkS80juttXZWemPuJHMIBtExGeB9ZD7BbWQJ0UeBZz3EzHpTmWD1a+Swx3tqvS7+MraWk3QdsCqwfbPkfrO+zEGMLRdJm5EJqbuRSalb0VEudC7wGDlb+u1khZ2JLslo3akEMTuT516VGL0ZWUVnODCLDKQfAO4uj/uBpyJiUm+02QaO6g62pNWBq8iyte8nb/Z8MiJure07hFIYxUGN9YTa+bgGcCR5vn0X+DFwWkQ836sNNFsKDmJsmTTrWpY0lEz+25Wc22B7cgz4iNpuZ0TER1vVTht4ypfz1sBY8hwcQ56Ha5E9NVPIYWc3RcQxvdNKGyhqF43vAv6vtmk+2Ut4HnBBRDzQeBwwmOykce+hdYvavFpfIoOXylTgdOBPwB0RMbdXGmi2FBzE2HIpd8EHk3cO5zVsG0leSO4G7ATsD3w7In7c8oZa26ldHB5HDmO8OCJebrLfhsA2ZECzPTl5285l/0Nb12IbyCStDRxI3uB5C9lbWPc88E/gr8CV7iW0niTp7cCJ5ESqK9U2zSd7C68CriHnM3qu9S00WzwHMdZtSkAzlOyefrVxDg5JGwBTmyX8my2NWgCzGpksfX1E7FFtIxOnFyn1XXoLqyGQ90TELS1uullVsnYrMqDZB9gTWKdht3vIIik/joj7WttCG0gk7QEcQN5o3LFh81RgPHA5OW/RTS77bX2FgxhbKg2144eSd7iHA/dFxNSGfYfQ0UvjrmnrNpKGRMSrkg4jh+P8MSLe22xumK6CGrO+oOTLjCEnwXwzGdwML5s/FBFn91bbrP2U7+5VgBmN382SVgH2Ag4G9gNGNxy+R0Rc34p2mi2OgxhbJpI+BhxLJvFvAMwBHgYuBS4GxjdWOvHkg7a8yh3s2bXJAX9Dznx+VESc1dk51pBcfQBwq+9uW6vVJwMuwXX1fH5tHwHrk0Uq3gL8V0TM7JUGW1up3fw5GjiEHN59W5kfRuQNx2YjKN4CvJ3sNVzHVcysr3AQY0tF0jDgU8APy6oJ5PCxnVh48tQArgMuAf4aEXe3sp3WfsoF4H+Rd6qvIQPm84F1gQ0j4unGyQNrx1Zf3h8AzgK+FhEntbD5NsA19GI3K4wyiI4LSX8xW7cq59eg8jk4gRw29paIuKrxfKwFNfN8Llpf5iDGlkitosmbyZ6Wl8hA5nRySNnN5JwwfyOTV7dqeIn5wFqe7deWlaS1gF+RdxDrpgFfJc/B+yNiepNjq/P3LOADwOER8ZeebrNZpRQ6OYxMol4ZmE72Xt8bEU832b8aiusvaes25UbkDPI7fHSzYihNjhlO9hgudl+zVhrS2w2wfqOaYfoI8kv42xFxCoCkvcu28yLiRElnA18o+z5a9l/RAYwtj4iYVHpSDgD2AD5IXgyOBH5edntU0jV0zMfxSETMKQHMMDLAhkxSNWsJSXsBvwS2KKuCLPU9GXha0j3khK13AA9ExGQPvbXuUIaD7Q5MiohxZA/MEHLI98slP2Y+XQfMJwBzJJ3qQMb6EvfE2FKRNJGs7rRZRDxW1v2THDO7X0T8s6wbRiZcrw4cDcyt9jfrDpLOB94JnAasSQY3qzTsdhtwNfAEOZ77EOAfEbF/C5tqA1Ct9+9twA+A7cgSyuPJUt+HAq+QF5ArkmXCnwWeBO4DbomIc3uh6dZGJL2DvMmzJlldbARZVvkHEfGlJvtXw8JVzt91gGcAImJQ4/5mvck9MbZYtaToDciE04m1AEZkJZ35ZDlQSl7CHEnnAOcAu0fEb3un9dZuyjAbgMeBv0fEJ2vbXkcGMweRvTU7lEflQeCnLWqqDWzVHcJjyADmp8BJpUfx9LLtVLKU8seBXcgJWbciewwvBRzE2PJ6ngycdyLnxxpa1h8jaSey9288GTQ/1iSncLey/HMrGmu2NNwTY4tVC2LeRA7DuTgiDi/bXkfe7b47IsbWE6vL5G5PAX8EPtws4dpseUhaJyKeqxL3G7YNIwOZtwJbAw+QvYN3eqiOtYKkFch5NoYBa5DzZM2v9WhvEhFPShoFfAn4DFmsIoB/+uaPLa8y1cF65Pn3BjJwnl4e65fd5pM9gPeQw3BvIL/XXwL+RPYafjAift/SxpsthntibLFq42RnA/OAaZKGlvryo8kPwInV7rUyt5uR59gqDmCsO9SG6OwHPF/Kgy4IYKoKPOT47jlkbsxV9WN7rfE2YNRu5uxCBjCXVjmBktYjPxsfjognASJiiqQfkz2IY8rymV5pvLWV8tn4JPCkpC3L6glkwLwn2Uv4Ojp6AA8khzlOJr/vNwQeI4dCmvUpDmJsaTwMjCPzDlYA5pIfbs8Cu0kaGxF3kh98AIeXpWdFt+72P8CLkvaqz6FRLhzrc27Uy9bOcyBjLTa2LMfX1r2xLG+GjuC6DDM7A/g+WTXq3y1sp7W5Mgz3QuA9ZMGTOyU9QE6qui6wKRlAb1+Wm5OFU+4GvhURz/dGu8264iDGllhEvCjpcGBURMwoq+8ku6W3Bj4n6TRgEjmXzAfKPpe0vLHWlkogMoTsbXkd8FNJn46IWZ3sP78+B4IDGGuFWs/zqLKsT6xaBTY3VStqvYkzye/lncl5tsy6Rfnsm0cOqa2Gib9C9rq8BNxXivSsRk5iPZS8ATQjIh7snVabdc2VJmyJlQ+9WdWcBrWLw4+SyYMfJO843gUcT47BPTUibu2tNlv7KRd7nwQGk5XvjpE0uFZVB+ioslObYPCjkka0ur02oD1K9gyu3bB+Pvn5WF1cVjcU9yzLJ1vSOmt7pfgOkraSdFP1GdisnHJEzI2I5yPi7oi4LSJujYgHq9cw62scxNgiJO0raQtJI2qVoBb50CvJ/oqI64B3kKVuJ5LlQm8ETgQ+27qW20BQzrm/Av9RVv2EnLxyfv3LtjzfV9KXJT0HnNhsIkyzHnQT+bk4ubbuOvK7d19J6wNExGxJrydLhsPCw8/Mlkd1nfcmsofvK5JW7uqAWuAzGJoHPGZ9gauT2UIk7UpWJrmfrE5yPVmC8VHyi/jlxX2glZnVB0XEcz3cXBugSi/LEOC/ymMmmQx9Azmh4MHknDA7k/lbABdGxDsXfTWz5dOQe7XI56Ok4dWQxxK4/JXMPZhIKTxBVtHbFLgsIg5oRbtt4JD0PuBsckjZJyPi9GY5gvUKo+V5VcTHrM9xEGMLkfROcm6XFWqr55ClF28mLxLvIoc7TC1jajt7LfkOjvWkkh9zMbAfeY7eT5YDrYbnTCTztn4N3BgRk5u9jll3aujBXiQPS9JewP8j5+4YXtt0GfDNiLixxxtpA46kY8meQYADI+LvZf1C39WlPP2WwBeB8yPiopY31mwJOIixRUgaSk4QuA/wZvJu9mq1XV4CbiWHSkwgLxyfA6b7jo21iqSRwL7kHexja5umkIH2/5ITuD3Q+tbZQCFpf+AT5Hwa10XEow3bRQ7piYY73FuSn69blu3PAr91D7b1lDKM7CTg0+T3+Hsi4sra9u2A3YEPkz3aawL7R8Q/eqG5ZovlIMYW0tiVXNatSM46fSI5o/TghsOeJHtpbiaDm4nAC2RVE59gttxqE66uB2xMFpGo5jgAmEGW/gb4n4g4rvHYljbYBgxJvwfeW56+Svb8XQNcCdwQES807D+Y/O6t5jZaKSJebmGTbQArw73PIIffXgn8N1lF7xNk4LIJOeQsgN9ExLHNX8ms9zmIsaZqkwoOBfYCvklO0HY9WTJ5ODmR2xvIevJ19wKPAJ+LiIda1mhre5IuJHNdKjeRRST+F9gN+BmwEnBURJzV+hbaQFMmXt0L2LE81qxtnkIGNeOAK4CbI2J2k9cYSpnLqKfbawNT/WZOyX39FbAt8DL5mQk5dPxyMrj5IzDZAbb1ZQ5irKlaELMXcD5ZS/7IiLi2yb57kCVvDy2rqg/E9SPi2ZY02NpWrRdmW/KC8GGywtMfyeE708p+Q8mJAj9Bzl300Yi4sJeabQNIySEYSc5uPgbYlQxodmPhnuunybzCq4BrIuKuFjfVBrAScO8GHAVsQEfu4FTgK8AdEXF977TObOl5sktbnPcDqwMfjohrayVsqzk45kXEdZKeIuc92BY4oWxzAGPLrMolqN2dHkT2CP4kIqbW9gFyjgNJnwVGkwH1lyQ94gtF62kRMYccQvsCcLukG8gJf3cruzxAFksZDRxWHvMkPUz2bl9GDj17rLUtt3ZVDQ2XtC55vn2UrH63KnlT8mngUvI7fgQwMyKu9/Bb60/cE2NdkvQoOUZ2w4h4utkHXO1O+Q7kkImTIuJH/jC0ntSkFGjVezgKOBd4G3AtcFBEzOilZtoAIWlIRLwqaSzwYzJp/yfA78jZz+eTOYW7kgUpdgSGkaWZIQujrNryhltbqp2P9ZytJ4GrydEV15J5L98l59x6CPjPiLisN9prtiwcxFinyh2cm8iE6b26uqMtaVhEzJH0IJlkvV9ETGpRU63NSFod+Dw5t0vTcrOdBNTV3cdtyOTV1wNfiYjv9XijbUCrnXvnAEeSxVDOajIPx8rAWHIi4MPJnK5XgUkRcViLm21tTtKVZOL+ycDtEfFgw/aVgT+Qc2uNBz4QEY81K/Jj1tc4iLFOSRpBXggeTg7h+Uxt/oMF5UJrPTHDyFLLs4DRLrdsS6t2Ln0Q+C3ws4g4flm+UCUdBPwZ2NvjvK0VJA0n8wtmVb0q1ZDHTibBvADYGvgQ8EhEvNi61lq7KeffCOD58jk6GHh9RIyv7TOo9t1dBd6jgAvJio9/A97r3mvrDwb1dgOsbyoXk9PpmE36Y5I+UXJg5tU+BIfUvpzfTo63fcABjC2j6jPp4LL8V1mqzIqOpC0kHVrKLXcqIv4G/IcDGOtp1blJzqk1GLijrB8cRSf7n0YGMZs5gLFu8H6y6tjOsCBndTzkOVfOxwU3g6qfI2IK8AVyioSDgDMkrYBZH+cgxpqqfen+Gvg5WVL5VEk3S/qcpF3KELJXJW1ZEqpPLsf8uTfabP1fbejNm8kcgiqImU9H7sDngL8Ar12C1/ttd7fRrFHtwnA1sjLeSEmjS45WVwV0HinLg7vYx2xJnUAGIYIFcxIBeY52VcI7Im6i4zt8u4h4pQfbadYtXJ3MuhQRr0j6EdlF/W5gp/KYBcyS9G/yPBpTDjkDOK832mrtQdJryEp3N0fEM7AgqK4HOAD3lf3r8x9UyazvIZOm/+heQWuhy8gKZWOB9wDfjzKpZaVcWFY3iXYvy6kta6G1pZLbsg3wb+AWyJtCtSFj3wZmkkPDm879EhHnSfoGWSrcrM9zEGOLFRGPA0dLOpMs1bgLWSp0XTomdnsQuBj4lsfS2rKojdU+oKy6sqwfTE4EGJK2BrYEJjarlle7YPw+sDFZmGKhRFaznhIRsyWdCpwEnFwrMHF3RLxU9pkHOSwS+Eg59MreaK+1lb3L8vp68FICmBHAiQARcXJnL1CG6H6XvAFk1uc5iLEulaTUYcDciLha0p1kALMRHefPIODaiHiuOsallW05VENrrqitG0T2xOxdnv+zLAeTlZ3qRQE2JCdye7qxEo9ZC/ySLJ/8PjJhfzvgekn3kz0us8ncwa+Tn6N34SDGlt9BZXl5WaoqO09WaQT4R9lQrV+gDHv8JTAZOLoF7TVbbg5irEslGHml9vwl4CXgtmb7O4CxZVXuGIqskDOdLD1bDYmoxna/tSwvrg6rvUQV6OxFBjdXYdZipSDKByRdDxxHBjQ7AnPJ4TyjarvfD3yyJFabLY/9yvLqspxPR95z9bn597JcMElwrQd8V+BAchhvp7kzZn2JgxhbSO1u9grkXcIDyAvK24HHqyERtf0HUyu37ADGlkUt+N2d/FwaXy4GgQWBzBBgj7Lq2mp9k5ervrD/2oNNNmuqdpf7NPKCcj8yj2tL8sLyYfIcPxc4LyIe9s0fWx6S1gc2BR6MiAeg0zzCS8uy/rlZBTT7lOXferCpZt3KQYwtUEsA3BD4Djlh2yA6zpNJkq4j73CPJ0spO//FuoPIXpW3l+erSjoUmEjOn/Ey8DoyD+uWiJjZOCSi9vObytJDdKylymfoPFhQsezu8viRpFXJPK2XIuKp2jEOYGx5vaUsr4CcfJqMY+aWAGcnYHJDgFOpKutVN38uaUF7zbqFgxhboFYm9AfAO8lcmOvJ4WM7kheQ7ygPgIclXU1eLN5OBjXuhrZlUX2pVl/Gu5FllAFul/Q3YJPy/BJYuBemCmgkbUvHHclJPd9ssw7lJtBwciLpmQ3bppL5L43HOICx5VXd/LkfICLm1LbtSd4kqgKcIfWKeWXkxWrkcLKXI2JCa5pstvwcxBiw0DCyDYAjyCFkHyET9p8s+2wK7AscQnY9b14eVYWdt9GRVGi2xGoXcp8hy9PuUh7bANuXB2Swc6Ck6WQZ0TsiYnItoKmGRFRjv81aQtLBZHL1SsAISc+Tk17eBNzTOO9GNeFlffJBs2VUVXT8vKQDyZzVG8nhY9VQsnPLUrUy34NKQPMG8rz156b1Kw5irFIlRe9Znl8UEedAxzCziHgUOL08kLQj+eF5IPkheEfLW21tJSKulTQe+B2wFrAFGcDsRt4pXI+OuYoAnpf0L2AcOZZ7/7L+YsxaRNLnyRK2q5ZV88jiEgAvAg9KuoXs2b45IiY6eLHuUG48PgmsSI6W2IjMw5oBPEVtzhdJKzQE09U5uG9ZOo/Q+hW5J9tgoZ6YLwDfAz4YEb+XNKzqmi6Vo6pE/sbyjMMaurDNuoWkoeRkq+uRPTM7kiVDd2DhSk+QFaAGASv7fLSeVMsh3IksNDGELGF7JzAFWIc8X8eQF5JVAvVT5LCyB4BvRsS0Fjfd2kyZB2YzsjLjXuTNn/XIoHpo2e1FMti5A7iB7Km5r0xoPYH8XN0yIh5ucfPNlpmDGFuIpF3ID7cjIuJPzerJ1/YdRF4wLhLUmPWUUjlvFHnHcQw57Oz1wGvJIRH3R8Rre62BNiBUuQVlhvNvAL8CToiIWeWGz8rAGmQy/9ZkYYrtga3IXsaIiMFNX9xsGZVzb3Xys/GtdExOvR6wCvmdPRd4gZwI+GFySPizEbF+LzTZbJk5iLEFSlCyDtml/HxEHLCYQ8x6VTlnVyIvFjchK5PdFxF/7tWGWdur9V5fQg5j3DUiJkgaGhFzG/cFRpKfr5uQwyHnRMSPW95wG1BKafp1yZ6W/YFtycB6TWA4mRsj4NyIeF9vtdNsWTiIsfodxY+SF4GvAMcA3wX+F3jK47etPyhf2PN9vlorlATps4B3AatGxOyG7U3LJ5chkoMb9zfraZJWJAPpN5A9NZuS+Ybvi4g/9WbbzJaWgxir31G8hcwzqEwFLgIuI8dwPw1Ma7zLaGY20NRyYo4A/gDsHhE3LOYYzwljfYqkkcBrgLvKfFxm/YaDGFtA0j5kOcZ9yPyCUbXNzwG3kvkyE8ixtM8DM50PY2YDSW1eoteRxU5+CjxDFkSZXYY5isx7ca+gmVkPcBBjTUlaF9iDDGj2JJMEB9V2eZgMaO4GftY4sZuZWbuq9V7PJKuSTS3LnwA/iYgpDftXQc1898SYmXUPBzG2QBnfTbOeFUlbkvkybybH0o6utkXEoMb9zczamaRRwJVkaduRtU2vkJP+XkXOX3S7e2PMzLqfgxhrqiRIDybvHDZW2hlM5s4cSJ5D3+qFJpqZ9ZrSu7IusD5ZOnkXYGdgOxaeSPoRYDwZ8FzreTjMzLqHgxhbIpKGkcMh5kXEq73dHjOzvqKh1Pdm5E2e3cigZtOG3S+IiMNa20Izs/bjIMaABT0vO5FVSsYAc4B7gOsj4rGGfQdRZgGOiFda21Izs76t9FavAqxNTnS5c3kcCJwaEZ/uxeaZmbUFBzEDWC05dUXg68DnKMFJMZ8c330PcC05xnt8RExueWPNzPqp0pM9gswlfDIinu/dFpmZ9X8OYgxJ/w18iayw82fgauBb5BfudPLLt/ICWWr5FuAMj++2ZSVpM+CliHiptk6QdWl7rWFmi1G7AVSVWl6F7HmZ4gkszcxaw0HMAFX7Et4AuB94FTg6Ii4ow8VmAvOAQ8jhZR8ih0MEmRsD8O6IOL/1rbf+TtJ6wL3AORHxyd5uj9mSqn12vgl4P1mG/kXgKeBxcg6t+4BHgWedQ2hm1jOGLH4Xa1ODyCBlP2Bl4OyIuKBs2xlYAbgiIq6SdCM5pOz7wEbAycDrgcta3WhrG28FVqVWmlbSmuS5d2O9d6ZRbab0nwMPAdcDE1zG1lqhBDCHAWcDK5bVa5OfiQCzgCfJIP1+SfeRQY2HkZmZdSMHMbZXWf6ltu6AshwHEBGzgKskfYmc/2DtiHhvy1po7Wifsvxzbd0HyAD5WOC3nR1YApi1gONqq/1ZZj2qFjxvB/yA7JH+DXAiOXfW+cA0cgLgHciEfsghuP8G/i3p6IiY1PLGm5m1IU9SOEDVJrTcrCzH1zZXgc3VkJXLSq7CePKu956SVm5JQ61dbVCW9d6T9wDDgMegY/LVTqwF/IMcsjPOvTDWAtX35TvJsslnAJ+NiGfpGGJ7HrAv8HFgQlk3nzxf93QAY2bWfXz3cgArw3dE3iWcWtatQMcF5oMAEfFqSWCdLWk4mfC/LuCkfltqJTgZT17sHS9pCjn0ZlfyrvX1ZdeuApOHyB6bTch8BLOeVt34ObQsz4yIqeXnd5flPyPiZeB3kq4A/k4Omfwh4ADGzKwbuSdmYJsNvERW1XltWbc2eSE5GdgcQNLQUoFnJJnk/6qrktmyKr2A5wI3A3uTpbvvJj+PngHWlrRyVxXKImJuRDweEddExD0taLYNcCUXZiTZC/N8RNxc21z1Xl8HIGnFiHga+CkwCngoIv7YyvaambU7BzEDWETMAH5Eju9+sax7kkxKXZ2sTEZEzC3Dx44le+9u6pUGWzt5GDiezCl4gRxu8wqwHfAEcIOkn0k6XNLoUjFvAaVBVUlms55UO8+2BoaTQXe1bTTZM/1URDwFUCuzfDHZE3NEmSvGzMy6iYeT2dVkZacZtXV/AvYHvizpzeTQn9HA24E5gO8o2jKTNLwUi7ihPJD0ALAl2TuzE9njNwb4JDAXuFHSVeSkq3eU3ALXh7eWqPUKDiOD7aerRH/gNWXbvZA91+WQV4HVyrb1I2JOK9tsZtbuHMQMMLU5DkYAQ0op2xkNu/2FvJA8jsxT2LW27essXMnMbIlJeiNwjaSTIuJrZd3qZAAzNSJeX+5670FWyTsIGAu8sTwAJku6BrgNOC0iXmj1+7AB6wFyXq0h5DDcacDzZL7LBpLWL8PIKvuX5f0tbaWZ2QDgyS4HGElDSqL+F4HDgBMi4oZO9h1NlsJ9DTmu+/fAtZ5N3ZaVpJOArwBfiYjvlXWbkpOpPh4RZzY5ZlUyd+Yg8qJww9rm0RHxRA832wzIMsvAbsA6EfGXsm4l4EZgW7Ji2W/ICnt7AN8mA/QDIsLzapmZdSMHMQNMba6Dh8kE1W0j4t6qh6bsI/LccNla61aSxpMXgbtExC1l3S+BPYHDI+Ke6vwjc/bmN56HkjYmg5ldIuJjLX0DZk1IOooMYCB7a4bSUb7+MuCdtTwZMzPrBg5iBiBJawPPAo9ExBZLeMzIiJjWsy2zdlbuWN9JlkXeoJozQ9JzZGL/1hHxUD2grh07mPy8erXV7baBrXbjZ2dgFjCxWX6LpLeTOVxjgJWBlcjJXE+MiEdb2WYzs4HAOTFtrJb/MpocEvZURNwNvKnsck3Zb8gSXByeXIZSfKbMg2C2tIaSifubAz+VdApZKGItsrjEQ9WOJWiZXwUztclZq57CwQ5orBVqPYHXAo+QOYKLBDERcZGkO4BtyF7EB8hSzNObBeZmZrZ8HMS0sdqX5kHAzwAkXUeWTwa4tezX9GKwdgfyNeQM1A86gLFlFRHTJF0EHAkcARxMzlMEML0ME3sxImbSMbFglYdQXiIBDmCsx5U5suZK2glYAZgWETM7C0oi4nHg8SbrHcCYmXUzBzEDw93kLOhvIJNNIcvTnizpYPIO49XAPaVaWWUQOWt6dcyVrWmutaNy4XeupCeBY4BdyLvWQRaQuBmYKGkCWXr55oiY2CQnZqFeGrPuJmmliHg5IuaWVW8ry0vLcghZ+rvxuOrGzxBgC7InZnLPt9jMbOBxTswAI+lo4NfkcIjGydeeAf5FzqB+Aznp4PrAr8ghFG+LiMtb11prV5LWBDYm5yCCnOl8C2Cj8jyAfwP3kMHN9cBtEfFsi5tqA5CkjwCHkuffxcDPgR2AsWVIbjWscRDZ0TK/rKuCmLcCFwKnRMSJvfEezMzanXtiBoByV3BQSUadVFZ/D/gm8H6y0tO+wHrAu8sDcvy3yCpmt5A9NmbLLSJekLQWGUhPAN5FzgezFfA6YHtydvT9ymMO8Kik28lJBU+JiOmtb7m1O0nDgdcCh5THZ+mY5PKgMsfWPaXQSWOu1jBgNrAXmdjvYihmZj3EPTEDjKQtgLcCV0fEfQ3btiKHTRxETiy4MjCFnFTwpIjwcDLrNpLGkhOqXh4R55V1AkYC6wKjyYvJ7ckAZ3NygkEiYtCir2i2/CQNJQPpt5A3cN5CnnuV6cBE4Hayh/Am4N56bmFJ8N8O2CYiHmhNy83MBhYHMW2uJEWvDMxolkNQemmaJveXi8zVgDsbcmXMlkutct5QMr9lXif7DSHPwfXIeTd2BV6NiK+3rrU2EEkaHhGzJF0AvB34KzAT2JksE16NZJgE3E8WSrkbWAf4DhnYbNvqdpuZDRQOYtpYGRbxXjKh/5yIuLIENdFJQFNdWLocqPWokpy/GjnvxobksJynF1f9rsw1M6hUMDPrcZJOBz4KvJ4MVsaQ+VtjyV7C15K5g3XPASdHxE9a11Izs4HFQUwbqgUj+5NJ+esD74mI8zqZSHAomUi9Zlm+EBHzyvpXHdBYd5E0ikyY3pMc1jicHJozjbyjfReZ7H97RMzoKug26wklV2t6RMxezH4jyV6XDYEtybm4NibnPfopcHGzSTHNzKx7OIhpY5L+SCbpfxk4tT6/QW25F/AxMhfmUTJp+rKIOLe8hntlbLnUKjbtDnydjnK1zSrkTSHvdl8InO5hjNYKtc/D9YGfAIcDn46IU2tzxYj8zpzf5Pgh5LDdaf68NDNrDQcxbUrSpmR50MnAmIiY2mSfQ4Df0DH5Zd044H0uaWvdQdIYsnT3msCLZAnvu8mgeV1gNzLXYKPaYY8Bx0bEP1vaWBtwakHM8cC3yXPzuIi4vRaEL7ihI2kjMuF/JnBdRDzd+Fq98T7MzAYSl1huM9UXLllhbEXg/IiYKmlwPXla0mjgVDKAmQ78HXiYnIBwD3K4zyeBr7X2HVi7kbQJ8GMygLka+EpE3NBkP5H5Wx8CDiYDmlMkfSQibmxhk22AKQHMiuS5twpZjfH2sm1+bZ/BwMnAEcCosi+SrgG+ExGXO4AxM2sNlyltX/uV5aWNG8oX8THkWO5HgC9ExBHAicCRwO+BwcCRZV+zpVbyWQAOJOch+hvZs3KDpGG1/YaU4DsiYjzwaeBb5Hwb2wBfKheYZt2uBM+QvYE7AP+KiL812W8wcBLwOfKzcxXgeXJY5J7AdyW5GpmZWYs4iGkztfHaW5blXWX9vNqX9Z7AO8vPPwd+W34eHBEvAmeQQ34E7NjjjbZ2d2RZnhIRD5bhNgsSniPi1dqM54qIuRHxSzKfaybwDjIIMusJ1fdg9Zn4f7AgaKnbF/hi+XkC2WvzRfIzdD6wE/CFHm2pmZkt4CCmDZXk1BlkPswmZV19nPb7yEo6k4AzI+IVyIvJ8sV9B/AkOTeHe2JsmZQ8guHkELEpZJ4VXQ23qeUcDI2IvwN/KJv2LevV2bFmy6i68fOmsryqLBecp6Vi2THl6V/JfJmzI+KsiPg8cHzZ9gZJq/R0g83MzEFMu3qWzG9ZnVIJqnZx+Ebgw8DLwG8iYkr9wjAi5kXELGAr8vzwbNO21Grn1HZk7t29pTdwiYLiiJhbfrwKmAusL2mU8w2su5Vcl9XIz8uZ5BCxeq82wCHA3uXnn0bEBKXqfB4PPEXe9BnTkoabmQ1wTuxvQ+UO+C3kcJz/lPQqWQ1qCzIhdShwBR13uQVErQrPWHL+jrtc4taW0zpkr+CU0ivT5WSWTVxHnq8bkReYZj1hBPAEmay/C3CJpBUi4hVJawIfANYgK5FdDgtuDFXDdO8ie3TWJXvAzcysh7knpn2dAVxEfil/k5z08hfAXuSX7SkRcQcscscRsrIZwGWtaKi1n1qPya1k4LI3sEatwlOXakUBNi7LSbXeGbNuU27ePAE8QwYzhwGUAGYQmdO1Nxnk/KY6pjq+nOujyHN1WkQ81Mr2m5kNVA5i2lREvAB8A/gz+XfeGJhKDjN7d0T8o8kx8yWtA7y/rPpLi5pr7esFcnjjcOAzkEMWl+C4ajja/mU5vvubZrbQTZyLgWnAhyVdIemLwDnk5yjkZ+nF1WGwUPL/7mU5oedbbGZm4OFkba30tLxL0ggyuXolcjjEC832L8MiPg28liyHe1Or2mrtKSJmSzoV+B+yZPf9wB+ruYvKbvNrOVsqx82TtAYdlc3+2uq224BzNvBW4IPAPuVRuRX4YURMgo6exlpAfkRZXtCSlpqZGXKebPuqhjw0GS7W2f7vB34HPA58JiIu6LnW2UBRKjv9iaz+9BzwI+B/I2J6F8esCpxFJlRfEhEHt6KtZpL2J8+7MeR8MJcAP4iIJzvZ/w3kfFyzgZ0i4t+taquZ2UDmnpg2Vg9eqqT9zvYt1XleV56eDVzYw82zAaCU9p4k6RgyT2tP4PvAVyVdRF78/YvMR9gQWBMYCxwH7EwmTP+oN9puA1NE/F3SOGBIRMyQNLj0DC7yGVrK2X+F7OX+lQMYM7PWcU+MLUTSEPLLe3Zvt8Xai6QdgBOA/YC1GzY/Q/YAjiGTqwEeInsEL2lVG82WhqTvAl8ih95+NCLu7uUmmZkNGA5ibIHqjmNvt8PaV8mDOZSsgDeWnFB1NfJONmQZZZHDGn8SEff3RjvNFkfSSDLX8GDg/IgY17stMjMbWBzEmFnLlQvArYCtgbWAOWQFs8lkae9JETGn91potmR888fMrHc4iDGzPqnk0/gDyszMzBbheWLMrE+oyitXHMCYmZlZZ9wTY2ZmZmZm/Yp7YszMzMzMrF9xEGNmZmZmZv2KgxgzMzMzM+tXHMT0c5I2k7Rawzo1JkmbmZmZmbULBzH9mKT1gFuA79TXR9E7rTIzMzMz61kOYvq3twKrAiOrFZLWlLR/Y+9MI0mDyvLnko6XtGu1zszMzMysLxvS2w2w5bJPWf65tu4DwMnAscBvOzswIuZLWgs4rrba54OZmZmZ9Xm+aO3fNijL+bV17wGGAY8BSBocEfM6OX4t4B/AlsDjETG/k/3MzMzMzPoMBzH9lKTBwHhgX+B4SVOAe4FdgReA68uuXQUmD5E9NpsAL/ZYY83MzMzMupGc/91/SdoaOAvYpayaRPau3AUcBLwUETN7qXlmZmZmZj3CQUw/JmkIsDPwMeAQYE3gFWCFsss9wLjyuAV4oj5krJRhFqWgWcsabmZmZma2HBzE9FOShkfErIZ1D5D5LTcDO7Fw9bm5wI3AVcC1wB0RMalFzTUzMzMz6zYOYvohSW8ErgFOioivlXWrk7kwUyNitdLLsgdwADm0bGzDy0wur3EbcFpEvNCq9puZmZmZLQ8n9vdPB5TljNq6VYFvAY9Djg8D/lUeJ0paFdibDGj2BzYE3lEenZZiNjMzMzPraxzE9E/V/DCX19Z9FdgTOBwWyncZBMyPiKnAheWBpI3JYGaXiHiiRe02MzMzM1tuHk7Wz0haCbiTLIu8QZXXIuk5sjLZ1hHxkCQ1JuuXssyKiFdb3W4zMzMzs+4yaPG7WB8zlEzcHwL8VNLrJe1ABjATIuKhakdJg0uPDAARMa8KYJTcE2dmZmZm/Y6DmH4mIqYBF5WnR5BDyi4sz6dL2ljSypHmVb0xkgaVh8rrhHtkzMzMzKw/8nCyfqYaJiZpD+AYcqLLbcj8F5ETXk4EJgA3ADdHxMQmrzOYzJXxCWBmZmZm/YqDmH5M0prAxsD4suo6YAtgo/I8gH+Tk17eDFwP3BYRz7a4qWZmZmZm3cZBTD8naRsySJkA7EfOB7MV8Dpge2BrYI2y+xzgUeB24F7glIiY3toWm5mZmZktHwcx/ZykscBxwOURcV5ZJ2AksC4wGngtGdCMBTYHVgGICOdEmZmZmVm/4yCmH6vlxwwl81vmdbLfEGA1YD1gM2BX4NWI+HrrWmtmZmZm1j0cxPRjJTl/NWAWsCEwD3g6Il5ezHErAYMiYmbPt9LMzMzMrHs5iOmHJI0CDgX2BN4KDCcrkk0jq5PdRSb73x4RMyQNolRV7p0Wm5mZmZl1Hwcx/YSkQRExX9LuwNeBt5VNc4BhDbtPAe4n5485PSJeallDzczMzMx6mIOYfkTSGOAqYE3gRXIemLvJSmPrArsBO9NRYhngMeDYiPhnSxtrZmZmZtZDHMT0E5I2AU4H9gWuBr4SETc02U/AG4APAQcD6wAPAh+JiBtb12IzMzMzs57hErt9XMlnATiQDGD+Rvas3CBpWG2/IWXIWUTEeODTwLeA2cA2wJckrdji5puZmZmZdTv3xPRxtVyYq8lE/n0j4oqqvHInxyzYJml/4E/AysChEXFxyxpvZmZmZtYD3BPTx5UAZjg5RGwKMK6s7zT6rAUwQyPi78AfyqZ9y3r1YJPNzMzMzHqUg5g+rBZsbAcMAe6NiHllfpjFioi55cergLnA+pJGudSymZmZmfVnDmL6h3WAGcCU0iszfymPvw4YSlYt8wSXZmZmZtavOYjpw2o9JrcCLwN7A2tERCxJb0ytKMDGZTmp1jtjZmZmZtYvOYjpH14AngWGA58BiIh5S3BcNRxt/7Ic3/1NMzMzMzNrLQcx/UBEzAZOLU+PlPQfklYFkDS4PBYk66so+TNrAEeWTX9tbcvNzMzMzLqfg5j+4y/ANcC65PwvH5M0IiLmlceCZP0yV0yUQOcMYDPgkoi4s1dabmZmZmbWjTxPTD9QzfsiaXMyKNmzbJoCXARcCvwLeAbYEFgTGAscB+wM3AWcEBFXtbjpZmZmZmbdzkFMPyNpB+AEYD9g7YbNzwCPA2OAEWXdQ8BnIuKSVrXRzMzMzKwnOYjph0plskOBg8gel/WA1YCVyi4zyaT+3wE/iYj7e6OdZmZmZmY9wUFMPyZpJLAVsDWwFjCHrGA2GbiMLKk8p/daaGZmZmbW/RzEtLkqn6a322FmZmZm1l1cnazN1Estw0ITZpqZmZmZtQX3xJiZmZmZWb/inhgzMzMzM+tXHMSYmZmZmVm/4iDGzMzMzMz6FQcxZmZmZmbWrziIMTMzMzOzfsVBjJmZtYSk0ZJCUtuUxZQ0rryno5bh2G+WY8/s/paZmbU3BzFmZr1M0pnVxb2kuZLWXsz+h9b2X6YLaBtYJO3dcM4szeObvd1+M7NGQ3q7AWZmtpAhwPuAU7rY58OtaYr1sBeAB4BnWvBvzQGe62TbOmU5DXi5yfYZPdIiM7Pl4CDGzKzveALYGPgQnQQxklYHDiIvLOcAq7eqcda9IuLnwM9b9G+NB9Zttq02vO/4iDizFe0xM1teHk5mZtZ3XA88DOwgaUwn+xwJDAPOp/ldczMzs7bnIMbMrG/5XVl+qJPt1fqzluTFJB0i6UJJz0qaI+l5SRdL2q+T/Y8qeRDjyvP3ShovaZqkSZL+Immb2v7rSfqZpMckzZY0UdKXJQ1egrbtIemv5XVnSbpd0qckdfndJGlbSWdIerT8m1MkXSfp45KGNtl/oYICknaTdJ6kZyTNk3RKbd9NJZ0m6UFJL5d2PV4S+L8iac0u2rVSSdZ/oBz7vKRzJW3Zyf6dJvbX8lFGl/d7bvkbzpZ0v6SvSVqhq9/T8pD0ofLvPyup01EbkvYp+82StGpt/WNl/d6SNpb0K0lPlvY/KumH9f07ee21JH1X0l2SZkiaKeluSSeVHkkzG8giwg8//PDDj158AGcCAZwLbFZ+fgoY1LDfVmXbE+RNqKfK86OavOZQ4OyyvXpMbXj+vSbHHVW2jQO+V36eS+ZLVMe9UNqyJfBkWTcNeLW2z6lNXnt0bfvh5XUDeKn2cwB/AYZ08rv6FDCvtu/0hn/3KmB4F//uEbV/awo5JO+Ust+ODe9zTmlb/Xe2f8Nrjyvr/xO4tfw8G5hVO+ZFYPMm7+WbZfuZTbZVx76PHDpY/f1eqW27HlilG86/6vWOqq1bqfx+Ajiki2N/V/Y5u2H9Y2X9R4Hna3+rl2v/3kPAep287hvL763a95WGY58Atu7t/7t++OFH7z3cE2Nm1odExCPAdcAGwFsaNle9ML+PiPmLeanvA+8HJgLvIS92VwVGAseRF5RflPTeTo7fHvgMcAKwakSMBMaSiehrACeTQdKTwPZl+0jgv8rxn5C0bRft+zVwObBZRKwGjAK+CMwH3lF+XoikdwA/A2aW7WtFxAhgOLA/eVG8N/D/dfHv/gq4ENg0IkaVY08p234IjABuBHaMiGGlbSsDu5T9pnbyut8CVivtWBlYBXgTGWiuDny3izZ15RfAvcDY8vcbARxNXtDvBvx4GV+3SxHxMnBOeXp0s30kjQQOK0/P6OSlfkj+zvYsf6uVyb/vC8AWwG+bvO4mwMXk7+00MlheqRy7HfAPYCPgz0vS42dmbaq3oyg//PDDj4H+oNYTU57/R3l+Vm0f0XF3e5uyrmlPDHnRN5+8A75RJ//mkeXYuxvWH0XH3e5vNDluz9r2ycCoJvtcUbZ/vWH96NqxdwMrNDn2m3T0OgyvrR9ce//7dfKeNicDnLnU7vA3/Lv/oqGHq7Zf1Xvy+qX4240rx8wCtmiy/XA6emeGdfJez2xyXNXe54DVm2yv/k7zgI2X8/xbpCemrN+Bjh6ptZocV52njwBq2Fb9rV7u5PeyT+3ffWPDtqoH8budtHcYcEfZ51098X/SDz/86PsP98SYmfU9/0de9B4maeWybi9gE2BCRNy3mOM/RAY9f4yIJzvZ5zxyiM4YSes12T6H5nf5ryttAzgtIqY02eeKsuyqJ+ZHEfFKk/U/Lq8/Enhbbf3e5Pu/OyIua/aCEfEwcANZeXPvLv7dznqxppVls9/H4pwXERObrL+IvNhegex5WFr/ExGTm6w/izLkkI7ekG4VEbeRQ+SGAh9oskvVQ3NmREQnL/N/zX4vEXEVML48fVe1XtJw4N1kEN60lyki5pDnL8C+i3kbZtamHMSYmfUxJTC4mBw+c3hZvTQJ/buX5YdLYvYiD/ICuEqC36jJazwWEdObtG0+ORQIsjelmWo+ktW6aOO4ZisjYhpwW3m6Y21T9Z627Ow9lfdV7dfsPUHmkXTmkrI8S9LJpQDAIoUCOnFzs5URMZfsEYOufx+dGdfJ684Hri1Pd2y2Tzf5VVkuNKSsFHfYjQw2zuzi+HFdbLu6LOvt34nsaRFwVxd/58+X/Tv7O5tZm3MQY2bWN1XBygclrUTerZ4L/GEJjq16EkaQExl29qi+A4Y3eY2uJmCct5h9qu1dBQD/XoJta9XWVe9pBbp+TyuW/Zq9J4BJXfy7XyB7B0YAXyIDnmmSrpT0ifJ36MwiAV9N1XO1pAFR3dL+nrrbOeRQue0k7VRb/5GyvDwinuji+GX9O4uu/84jy36d/Z3NrM05iDEz65v+Tl5wv5msyDUCuDQiXujyqFR9tn8mIrQEj3E98xa6VfWeLlzC9/TNZi8SEfOarS/bXiSrYu0L/JTsERpG5m/8Arhb0obd+ab6uoiYCvypPD0aoJRc/mBZ11lC/7Kq/s5Tl/DvvHc3//tm1k84iDEz64Mi4lWy12UQcFJZ/bvOj1hINZxr4+5uVzdafwm21XtNWvKeIl0eEcdHxI7AmsCxZBGDzei68llPWNrfU0+ohpS9r8xNcyDZGzIZuGAxxy7r33nk4uaRMbOBzUGMmVnfVQ0pG0rOV3LxEh5X5X3s3+0t6j57NVspaQQdORK31jZV72mspA16smF1EfFSRJwOfLWsatruHtTZ70lkCWdY+PfU7SLiX8D9ZE7PO+jIjzmnk+IMdV39vqpt9fZPIOf9EX37/DWzXuYgxsysj4qIW8gyvD8CTliCC8bKWZRSzJKO7WpHScuSbN4dPidpWJP1J5B5LdPI+UAqV5Bz0gwGftDVCy/Le5I0qKuZ6clSwZA5Oa30CUmjmqz/ALAhmVj/5xa0o+qN+SxwUPn510tw3BGSNmtcKelNwB7laTVcjVJM4vzy9P+VoLYpSUMkrbIEbTCzNuQgxsysD4uIb0XE5yNiSaqSVcfcS8ewp19I+m49l0PSCElvk3Q2tQvIFtsY+Iuk0aVNwyV9jgzaAL4XEbOqnUuVr0+Rwdl7JV0gaftqu6ShknaW9H3g0WVoz0hgoqQTJW1XTaJYgpu30DGkr2l55x60IvD3auLQ8j4/DPxP2f7rxSTWd5ezyLLbu5I9g7dFxO1LcNwc4FJJu8OC3+chdJRI/mdEXNdwzJfJoWpbAeMl7V9ViVPaUtJnyd6hnZfzfZlZP9XVXSczM+u/vkjOcv4J8qLwy5KmkUHASHK4DnRdArcnHQOcCzwqaQo5w331nXQh8P3GAyLiIknHkBfwhwKHSnqZ7CVZleylWR6bAN8pj7mSpje87iNkT0QrHQf8kiw3PJX8m1Y9WDe0qj0RMUnSRXTM6bKkCf2fB/4buE7SDPJ3WVV5mwh8uMm/9Zik/cl8m22BS8m/xzSywEW9B6+z+WnMrM25J8bMrA1FxLyIOI6stnU28Dg5FGpF4AlyEsZPUZtosMXtO5+s+vU3siTzq+Qs7J8GDiuFDZod9xtga+AU4J5y7EjgRTIg+0bZvrSmAQeX172JTDYfAcwk54A5Edg+Ip5ahtdeHuOB15MToL5CXrQ/AHwd2DsiZrSwLdWwtVeA3y/hMRPJ3pIzgKlkEPMYOURy54hoWqY7Im4GXkOWuh4PzABGkeWeJ5DV4/aKiKubHW9m7U+dT7JrZmZmvUFS9eW8aUQ81pttqUj6JfBR4I8RceRi9n2M7Nnap5+U8DazfsY9MWZmZtalUu64ClxO7822mJmBgxgzMzPrQqki92Myb+nOiLiyl5tkZubEfjMzM1uUpHcBPyQn/FyZzMf5XK82ysyscE+MmZmZNbMKmdcyBLiNLLhwee82ycwsObHfzMzMzMz6FffEmJmZmZlZv+IgxszMzMzM+hUHMWZmZmZm1q84iDEzMzMzs37FQYyZmZmZmfUr/z+BZOfuPGEu4QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot some stuff:\n", + "\n", + "def bar_view():\n", + " \n", + " offline_extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", + " offline_extra_gross = 75 * offline_extra_ct\n", + "\n", + " offline_std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", + " offline_std_gross = 35 * offline_std_ct\n", + "\n", + " extra_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", + " extra_gross = 75 * extra_ct\n", + "\n", + " std_ct = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", + " std_gross = 35 * std_ct\n", + "\n", + " counts = [offline_extra_ct, offline_std_ct, extra_ct, std_ct]\n", + " gross = [offline_extra_gross, offline_std_gross, extra_gross, std_gross]\n", + " labels = ['Off. Extra', 'Off. Standard', 'Extra', 'Standard']\n", + "\n", + " counts = np.array(counts)\n", + " gross = np.array(gross)\n", + " labels = np.array(labels)\n", + "\n", + " # sorts our numpy arrays:\n", + " map_sort = lambda *sortables: map(np.array, zip(*sorted(zip(*sortables))))\n", + "\n", + " # this is the order we'll sort by:\n", + " sortable_arrays = gross, counts, labels\n", + "\n", + " # apply sort:\n", + " gross, counts, labels = map_sort(*sortable_arrays)\n", + "\n", + " # reverse so the most prevalent countries are listed first:\n", + " counts = counts[::-1]\n", + " gross = gross[::-1]\n", + " labels = labels[::-1]\n", + "\n", + " # initialize plot:\n", + " width = 0.8\n", + " fig3 = plt.figure(figsize=(12, 12))\n", + " ax3 = fig3.add_subplot()\n", + "\n", + " labels_loc = np.arange(len(labels))\n", + "\n", + " # draw bars:\n", + " rects3 = ax3.bar(labels_loc + width/2, gross, width, label='', color=['blue', 'green', 'green', 'blue'])\n", + "\n", + " plt.xticks(rotation = 75)\n", + " ax3.set_xlabel('Membership Type')\n", + " ax3.set_ylabel('Gross Incoome')\n", + " ax3.set_title('Monthly Gross Income: %d (%d per annum)' % (sum(gross), sum(gross*12)))\n", + "\n", + " ax3.set_xticks(labels_loc)\n", + " ax3.set_xticklabels(labels)\n", + "\n", + " for xy in zip(labels_loc, gross):\n", + " if xy[1]: # if 0, don't plot\n", + " ax3.text(xy[0] + width/2, xy[1], '%s$' % xy[1].__str__(),\n", + " ha='center', va='bottom')\n", + "\n", + " fig3.tight_layout()\n", + " plt.tight_layout()\n", + " plt.savefig('gross_income.png')\n", + " \n", + "bar_view()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "e2a8202a-35a3-4c79-9b4e-54dd5a894410", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABF8AAACbCAYAAAC07DTVAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAA4IklEQVR4nO3dd1gUx/8H8Pci5ehIEVQEEbCLLXYRNGKMWEBNbAh2I/YaS4wQW0zyjcaoUaJRg1+jsdcYMWKJPYqxRZAfYMWCikhRKfP7w9x9Oe9AOFgBfb+e555HZ4fdudvZmd3Pzu5IQggQEREREREREZE89Eq6AEREREREREREbzMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhnpl3QBqHCMjY3vPnv2zL6ky0Flj0KhyHn27BkDrqQT1h/SFesOFQXrD+mKdYeKgvWHdKVQKO5lZGQ4aFsmCSHedHmoCCRJEtxnpAtJksC6Q7pi/SFdse5QUbD+kK5Yd6goWH9IV//WHUnbMkbziIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyYjBFyIiIiIiIiIiGTH4QkREREREREQkIwZfiIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyYjBFyIiIiIiIiIiGTH4QkREREREREQkIwZfiIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyYjBFyIiIiIiIiIiGTH4QrKTJAkDBgwo6WIUu4SEBEiShJCQkJIuylstKSkJgYGBqFSpEiRJgre3NwAgJycHISEhqFatGvT19SFJUskWlIhKBbYZmkqqvwoJCYEkSUhISHij26WXSuL8a82a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C3Os5/V9lG3Yq1P6Hj58WLRo0UIYGRmJChUqiODgYHHx4kWNqaaFKHhf/rqps7Ozs8WcOXOEk5OTMDQ0FHXq1BHr1q177TFQECXd9vz+++8iODhYeHh4CBsbG1GuXDlhbW0tvL29xapVq9Sm1Y2JiRE+Pj7C3Nxc1aYoFeZ4z6vNz+sc5cKFC8LHx0eYmJiI8uXLi759+4p79+5prTvFUfeUli9fLqpXry4MDQ2Fq6urWLhwofjpp5841XQx09Z36enpCTs7O+Hv7y9Onz6tlr+g+7ig55N5HcePHz8WkydPFq6urqpz7tatW2tMkV5WvYn6U5j2RXk8RkREiKZNmwqFQiEqVKggRo0apXF+KoQQcXFxIiAgQNjZ2QkDAwPh4uIipk2bpjY9vBD5n6u8WmfCwsJE+/bthb29vTAwMBAODg7iww8/VJveWenQoUOiffv2wtzcXBgZGYkGDRqoTXGt9LpznoJeOwlRuLZQTshnqmnp5XIqKyRJEtxnpAtJksC6Q7pi/SFdse5QUbD+kK5Yd6goSlv9kSQJQUFBWLNmTUkXhV7j37qj9eVvfOcLEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDLibEdEREREREREpVRpev8M6Y4jX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREclIv6QL8CpjY+O7z549sy/pcpRWCoUCkiSVdDGoDGLdoaJg/SFdse5QUbD+kK5Yd6goWH9IVwqFIievZZIQ4k2W5bUkSRKlrUyliSRJ4O9DumDdoaJg/SFdse5QUbD+kK5Yd6goWH9IV//WHa2ROz52REREREREREQkIwZfiIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyYjBFyIiIiIiIiIiGTH4QkREREREREQkIwZfiIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyYjBFyIiIiIiIiIiGTH4QkREREREREQkIwZfiIiIiIiIiIhkxOALEREREREREZGMGHwhIiIiIiIiIpIRgy9ERERERERERDJi8IWIiIiIiIiISEYMvhARERERERERyajMBV/S09OxaNEieHp6wtraGgYGBrC3t0enTp2wZs0aZGVllXQR1SQnJyMkJASHDh0q6aJQCbh37x4++eQTVKlSBYaGhnBycsLYsWORnJyslu8///kPvL29UbFiRRgZGaFixYpo27Yttm3bVjIFpxI3f/58fPTRR6hWrRokSULVqlW15nv27Bl+/PFHdOvWDVWrVoWxsTGqVauGPn364J9//nmzhaYyS5IkrR8zM7OSLhq9YdHR0ejXrx9q1aoFS0tLmJiYoGbNmpgwYQISExPV8rLvotxiYmLw+eefo3nz5rCzs4O5uTkaNGiAuXPnIi0tTZVPCIF169ahd+/ecHNzg4mJCZycnNC1a1ecOnWqBL8BlaSCnvdo8+mnn7LPogILCQnJ87xHkiQYGBjItm1JCCHbynUhSZLIq0yxsbHw9fVFTEwM2rdvjw4dOsDW1hb379/HgQMHcODAAUyePBlfffXVGy513hISEuDi4oJZs2YhJCSkyOuTJAmlbZ+Rdvfv30fTpk1x584dDB8+HHXr1sWlS5ewYsUK1KlTB8eOHYOJiQkAoFevXjA2Nkbt2rVha2uLR48eYdOmTTh9+jS++OILzJw5s8jlYd0pWyRJgrW1NRo1aoSzZ8/CwsICCQkJGvmuXr2KWrVqoXXr1ujQoQMqVaqEuLg4/PDDD0hLS8O+ffvQtm3bYikP68/bS5IkeHp6YtiwYWrpBgYG6NWrV5HXzbpTdvzxxx+YO3cumjdvDkdHR+jr6+PixYtYvXo1LCwscP78eVSoUAEA+y5SN3XqVCxduhRdu3ZF8+bNYWBggMjISPz666/w8PDAyZMnYWxsjGfPnsHY2BgNGjSAr68vXFxckJiYiOXLl+POnTv4+eefERAQUOTysO6ULQU973nV+fPn0aRJEygU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NWumNuMNvf1GjBiBxMREtGvXDs7Oznj27BnOnj2LDRs2wNzcXPUyVPZd9KqlS5di1qxZcHJyQvv27bF+/Xq15fb29vDx8cHTp0/Rtm1bJCQkYPTo0YiOjkZ0dLRaXh8fH466e8cU9LynRYsWWv9+yZIluH79epEmU6F3y507d7Bv3z40bdr0zT3yKIQoVZ+XRcpbWlqa+Pbbb0WrVq2ElZWV0NfXFxUqVBCdOnUSP//8s8jKylLLv3XrVtGiRQthYmIiTExMRIsWLcS2bdu0rvurr74STk5OwtDQUNSsWVOsWrVKrF69WgAQkZGRqnyzZs0SAER8fLzGOpydnYWXl5da2qlTp0TLli2FiYmJACCcnZ1Vy4KCgjTWn5/X/T5Uejx//lz07t1bVK1aVRgZGYny5cuLDh06iH379qnle/DggRg5cqTw8PAQ5cuXF/r6+sLGxka0b99erFu3TuTk5BRLeVh3yhYvLy8BQOsndxsTGRmZZz7lR1tbVVisP2+v7du3iw4dOohKlSoJIyMjYWJiIurXry/mzp0rMjIyirx+1p2yZePGjcLX11c4OjoKIyMjoVAoRI0aNcSoUaPE9evXVfnYd9GrlOe0r+u74uPjX9tvFfS8OD+sO2VLQc978vt7U1PTYisP68/bb+7cuQKACAsLK9b1/lt3tMY6JFHKXg4rSZIobWUqTSRJ4gt9SSesO1QUrD+kK9YdKgrWH9IV6w4VBesP6erfuqP1ZVdl5p0vRERERERERERlEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQyYvCFiIiIiIiIiEhGDL4QEREREREREcmIwRciIiIiIiIiIhkx+EJEREREREREJCMGX4iIiIiIiIiIZMTgCxERERERERGRjBh8ISIiIiIiIiKSEYMvREREREREREQy0i/pArxKoVDckyTJvqTLUVopFIocSZIYNKNCY92homD9IV2x7lBRsP6Qrlh3qChYf0hXCoXiXl7LJCHEmywLEREREREREdE7hdE8IiIiIiIiIiIZMfhCRERERERERCQjBl+IiIiIiIiIiGTE4AsRERERERERkYwYfCEiIiIiIiIiktH/A8DN1iANUkJYAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "def table_view(): \n", + " \n", + " ## build a table of sums ##\n", + " total_members = memershipworks_df.shape[0]\n", + " offline_extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Extra Membership'].shape[0]\n", + " extra_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Extra Membership'].shape[0]\n", + " offline_basic_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Basic Membership'].shape[0]\n", + " offline_std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline Standard Membership'].shape[0]\n", + " std_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Standard Membership'].shape[0]\n", + " spons_members = memershipworks_df[memershipworks_df['Membership Level'] == 'Offline VIP Membership'].shape[0]\n", + "\n", + " count_df = pd.DataFrame()\n", + "\n", + " # convert sums with __str__ to avoid recasting\n", + " # as a float when the table gets drawn\n", + " count_df.loc['Count:', 'Total Members'] = total_members.__str__()\n", + " count_df.loc['Count:', 'Off. Extra'] = offline_extra_members.__str__()\n", + " count_df.loc['Count:', 'Extra'] = extra_members.__str__()\n", + " count_df.loc['Count:', 'Off. Standard'] = offline_std_members.__str__()\n", + " count_df.loc['Count:', 'Standard'] = std_members.__str__()\n", + " count_df.loc['Count:', 'Basic'] = offline_basic_members.__str__()\n", + " count_df.loc['Count:', 'Sponsored'] = spons_members.__str__()\n", + "\n", + " # draw long low table only:\n", + " fig = plt.figure(figsize=(18,2))\n", + " ax = fig.add_subplot(111, frame_on=False)\n", + " ax.xaxis.set_visible(False)\n", + " ax.yaxis.set_visible(False)\n", + "\n", + "\n", + " # draw table:\n", + " table_fig = table(ax, count_df, rowLoc='right',\n", + " colLoc='center', loc='bottom',\n", + " bbox=[.1, -0.3, 1, 1.2])\n", + "\n", + " table_fig.auto_set_font_size(False)\n", + " table_fig.set_fontsize(18)\n", + "\n", + " fig.savefig('table_fig.png')\n", + "\n", + "table_view()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}