浏览代码

pep8 of notebook

Will K 6 年之前
父节点
当前提交
15ebdadc49
共有 1 个文件被更改,包括 235 次插入216 次删除
  1. 235 216
      slack_interaction/Interacting with Slack.ipynb

+ 235 - 216
slack_interaction/Interacting with Slack.ipynb

@@ -18,21 +18,11 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 1,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "cloudfoundry-client 0.0.25 has requirement protobuf==2.6.1, but you'll have protobuf 3.6.1 which is incompatible.\n",
-      "You are using pip version 10.0.1, however version 18.1 is available.\n",
-      "You should consider upgrading via the 'python -m pip install --upgrade pip' command.\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
-    "!pip install -q -U Slacker"
+    "!pip install - q - U Slacker"
    ]
   },
   {
@@ -41,25 +31,30 @@
    "metadata": {},
    "outputs": [],
    "source": [
+    "# ALl outputs \n",
+    "from IPython.core.interactiveshell import InteractiveShell\n",
+    "InteractiveShell.ast_node_interactivity = 'all'\n",
+    "\n",
+    "# Slacker\n",
+    "from slacker import Slacker\n",
+    "\n",
+    "# Data manipulation\n",
     "import numpy as np\n",
     "import pandas as pd\n",
     "\n",
     "%load_ext autoreload\n",
     "%autoreload 2\n",
     "\n",
-    "# Slacker \n",
-    "from slacker import Slacker\n",
+    "\n",
     "\n",
     "# Visualization\n",
-    "import matplotlib.pyplot as plt\n",
     "import seaborn as sns\n",
+    "import matplotlib.pyplot as plt\n",
     "%matplotlib inline\n",
     "plt.style.use('fivethirtyeight')\n",
     "\n",
     "# Displaying images\n",
-    "from IPython.display import Image\n",
-    "from IPython.core.interactiveshell import InteractiveShell\n",
-    "InteractiveShell.ast_node_interactivity = 'all'"
+    "from IPython.display import Image"
    ]
   },
   {
@@ -122,7 +117,8 @@
     "# Connect to Slack\n",
     "slack = Slacker(slack_api_token)\n",
     "if slack.api.test().successful:\n",
-    "    print(f\"Successfully connected to {slack.team.info().body['team']['name']}.\")\n",
+    "    print(\n",
+    "        f\"Successfully connected to {slack.team.info().body['team']['name']}.\")\n",
     "else:\n",
     "    print('Try Again!')"
    ]
@@ -195,7 +191,7 @@
    "source": [
     "from IPython.display import Image\n",
     "\n",
-    "Image(url = 'https://avatars.slack-edge.com/2018-11-30/492734348690_802c4805ab4a0d29383b_230.png')"
+    "Image(url='https://avatars.slack-edge.com/2018-11-30/492734348690_802c4805ab4a0d29383b_230.png')"
    ]
   },
   {
@@ -266,10 +262,10 @@
     }
    ],
    "source": [
-    "import warnings\n",
-    "warnings.filterwarnings('ignore', category = FutureWarning)\n",
     "from utils import get_data_and_model, get_options\n",
-    "                    \n",
+    "import warnings\n",
+    "warnings.filterwarnings('ignore', category=FutureWarning)\n",
+    "\n",
     "command_dict = get_options(slack)\n",
     "command_dict['functions']['users']\n",
     "command_dict['functions']['channels']"
@@ -319,7 +315,8 @@
     "\n",
     "# Iterate through channels\n",
     "for channel in channels['channels']:\n",
-    "    print(f'Channel {channel[\"name\"]} Purpose: {channel[\"purpose\"][\"value\"]}\\n')"
+    "    print(\n",
+    "        f'Channel {channel[\"name\"]} Purpose: {channel[\"purpose\"][\"value\"]}\\n')"
    ]
   },
   {
@@ -372,7 +369,7 @@
     }
    ],
    "source": [
-    "slack.channels.history(channel = 'CCCT28F08').body"
+    "slack.channels.history(channel='CCCT28F08').body"
    ]
   },
   {
@@ -433,7 +430,8 @@
     "\n",
     "for user in users['members']:\n",
     "    # Print some information\n",
-    "    print(f'\\nUser: {user[\"name\"]}, Real Name: {user[\"real_name\"]}, Time Zone: {user[\"tz_label\"]}.')\n",
+    "    print(\n",
+    "        f'\\nUser: {user[\"name\"]}, Real Name: {user[\"real_name\"]}, Time Zone: {user[\"tz_label\"]}.')\n",
     "    print(f'Current Status: {user[\"profile\"][\"status_text\"]}')\n",
     "    # Get image data and show\n",
     "    Image(user['profile']['image_192'])"
@@ -469,12 +467,12 @@
     "\n",
     "for channel in channels['channels']:\n",
     "    channel_dict[channel['name']] = channel['id']\n",
-    "    \n",
+    "\n",
     "user_dict = {}\n",
     "\n",
     "for user in users['members']:\n",
     "    user_dict[user['name']] = user['id']\n",
-    "    \n",
+    "\n",
     "user_dict"
    ]
   },
@@ -503,15 +501,16 @@
    ],
    "source": [
     "# Set the purpose of the channel\n",
-    "r = slack.channels.set_purpose(channel_dict['python_content2'], \n",
-    "                           purpose = 'Learning how to use Python for Slack interaction')\n",
+    "r = slack.channels.set_purpose(channel_dict['python_content2'],\n",
+    "                               purpose='Learning how to use Python for Slack interaction')\n",
     "\n",
     "channels = slack.channels.list().body\n",
     "\n",
     "# Iterate through channels\n",
     "for channel in channels['channels']:\n",
     "    if channel['name'] == 'python_content2':\n",
-    "        print(f'Channel {channel[\"name\"]} Purpose: {channel[\"purpose\"][\"value\"]}\\n')"
+    "        print(\n",
+    "            f'Channel {channel[\"name\"]} Purpose: {channel[\"purpose\"][\"value\"]}\\n')"
    ]
   },
   {
@@ -589,10 +588,10 @@
    "outputs": [],
    "source": [
     "for new_value, name in zip(['Data Scientist and Writer', 'Willk', 'data-sciencing', ':male-technologist:'],\n",
-    "                          ['title', 'display_name', 'status_text', 'status_emoji']):\n",
-    "    \n",
-    "    r = slack.users.profile.set(user = user_dict['wjk68'],\n",
-    "                               name = name, value = new_value)\n",
+    "                           ['title', 'display_name', 'status_text', 'status_emoji']):\n",
+    "\n",
+    "    r = slack.users.profile.set(user=user_dict['wjk68'],\n",
+    "                                name=name, value=new_value)\n",
     "    if not r:\n",
     "        print(r.error)"
    ]
@@ -679,9 +678,11 @@
    "source": [
     "import emoji\n",
     "\n",
+    "\n",
     "def print_emoji(emoji_name):\n",
     "    print(emoji.emojize(emoji_name, use_aliases=True))\n",
-    "    \n",
+    "\n",
+    "\n",
     "print_emoji(':runner:')"
    ]
   },
@@ -729,7 +730,7 @@
     }
    ],
    "source": [
-    "Image(url = 'https://a.slack-edge.com/c00d19/img/emoji_2017_12_06/sheet_google_64_indexed_256.png')"
+    "Image(url='https://a.slack-edge.com/c00d19/img/emoji_2017_12_06/sheet_google_64_indexed_256.png')"
    ]
   },
   {
@@ -766,7 +767,7 @@
     }
    ],
    "source": [
-    "matches = slack.search.messages(query = 'Python').body['messages']['matches']\n",
+    "matches = slack.search.messages(query='Python').body['messages']['matches']\n",
     "for match in matches:\n",
     "    print(f\"Time: {convert_ts(match['ts'])}, Text: {match['text']}\")"
    ]
@@ -809,7 +810,7 @@
     }
    ],
    "source": [
-    "matches = slack.search.files(query = 'plot').body['files']['matches']\n",
+    "matches = slack.search.files(query='plot').body['files']['matches']\n",
     "for match in matches:\n",
     "    print(f\"Time: {convert_ts(match['timestamp'])}, Title: {match['title']}\")"
    ]
@@ -873,7 +874,7 @@
     }
    ],
    "source": [
-    "slack.dnd.set_snooze(num_minutes = 120).body"
+    "slack.dnd.set_snooze(num_minutes=120).body"
    ]
   },
   {
@@ -1005,10 +1006,10 @@
     }
    ],
    "source": [
-    "r = slack.chat.post_message(channel = 'python_content', \n",
-    "                            text = 'Have a great day!',\n",
-    "                            username = 'Python Test',\n",
-    "                            icon_url = 'http://devarea.com/wp-content/uploads/2017/11/python-300x300.png')\n",
+    "r = slack.chat.post_message(channel='python_content',\n",
+    "                            text='Have a great day!',\n",
+    "                            username='Python Test',\n",
+    "                            icon_url='http://devarea.com/wp-content/uploads/2017/11/python-300x300.png')\n",
     "r.successful"
    ]
   },
@@ -1043,7 +1044,8 @@
     }
    ],
    "source": [
-    "slack.channels.history(channel = channel_dict['python_content']).body['messages'][0]['text']"
+    "slack.channels.history(\n",
+    "    channel=channel_dict['python_content']).body['messages'][0]['text']"
    ]
   },
   {
@@ -1072,11 +1074,11 @@
     }
    ],
    "source": [
-    "r = slack.chat.post_message(channel = 'python_content', \n",
-    "                            text = \"Here's an uplifting story: https://www.forbes.com/sites/stevedenning/2017/11/30/why-the-world-is-getting-better-why-hardly-anyone-knows-it/#181c93b27826\",\n",
-    "                            unfurl_links = True,\n",
-    "                            username = 'Uplift',\n",
-    "                            icon_emoji = ':point_up::skin-tone-5:')\n",
+    "r = slack.chat.post_message(channel='python_content',\n",
+    "                            text=\"Here's an uplifting story: https://www.forbes.com/sites/stevedenning/2017/11/30/why-the-world-is-getting-better-why-hardly-anyone-knows-it/#181c93b27826\",\n",
+    "                            unfurl_links=True,\n",
+    "                            username='Uplift',\n",
+    "                            icon_emoji=':point_up::skin-tone-5:')\n",
     "r.successful"
    ]
   },
@@ -1113,11 +1115,11 @@
     }
    ],
    "source": [
-    "r = slack.chat.post_message(channel = 'python_content', \n",
-    "                            text = '<@UCEKVNHPH> Have you read any good books lately?',\n",
-    "                            link_names = True,\n",
-    "                            username = 'Query',\n",
-    "                            icon_emoji = ':green_book:')\n",
+    "r = slack.chat.post_message(channel='python_content',\n",
+    "                            text='<@UCEKVNHPH> Have you read any good books lately?',\n",
+    "                            link_names=True,\n",
+    "                            username='Query',\n",
+    "                            icon_emoji=':green_book:')\n",
     "r.successful"
    ]
   },
@@ -1152,9 +1154,9 @@
     }
    ],
    "source": [
-    "r = slack.chat.post_message(channel = 'python_content', \n",
-    "                            text = 'Anyone up for a trip to the store?',\n",
-    "                            as_user = 'willk')\n",
+    "r = slack.chat.post_message(channel='python_content',\n",
+    "                            text='Anyone up for a trip to the store?',\n",
+    "                            as_user='willk')\n",
     "r.successful"
    ]
   },
@@ -1182,7 +1184,8 @@
     }
    ],
    "source": [
-    "slack.channels.history(channel = channel_dict['python_content']).body['messages'][0]['text']"
+    "slack.channels.history(\n",
+    "    channel=channel_dict['python_content']).body['messages'][0]['text']"
    ]
   },
   {
@@ -1209,10 +1212,10 @@
     }
    ],
    "source": [
-    "r = slack.chat.post_message(channel = 'python_content',\n",
-    "                            text = '<!everyone> *This is not a test!*',\n",
-    "                            username = 'Alert',\n",
-    "                            icon_emoji = ':female-firefighter:')\n",
+    "r = slack.chat.post_message(channel='python_content',\n",
+    "                            text='<!everyone> *This is not a test!*',\n",
+    "                            username='Alert',\n",
+    "                            icon_emoji=':female-firefighter:')\n",
     "r.successful"
    ]
   },
@@ -1238,33 +1241,33 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "r = slack.chat.post_message(channel = 'random',\n",
-    "                            username = 'Fancy Message',\n",
-    "                            icon_emoji = ':earth_africa:',\n",
-    "                            attachments =  [\n",
-    "        {\n",
-    "            \"fallback\": \"Required plain-text summary of the attachment.\",\n",
-    "            \"color\": \"#2eb886\",\n",
-    "            \"pretext\": \"Optional text that appears above the attachment block\",\n",
-    "            \"author_name\": \"Fancy Message\",\n",
-    "            \"title\": \"Slack API Documentation\",\n",
-    "            \"title_link\": \"https://api.slack.com/\",\n",
-    "            \"text\": \"Optional text that appears within the attachment\",\n",
-    "            \"fields\": [\n",
-    "                {\n",
-    "                    \"title\": \"Priority\",\n",
-    "                    \"value\": \"High\",\n",
-    "                    \"short\": False\n",
-    "                }\n",
-    "            ],\n",
-    "            \"image_url\": \"http://my-website.com/path/to/image.jpg\",\n",
-    "            \"thumb_url\": \"http://example.com/path/to/thumb.png\",\n",
-    "            \"footer\": \"Slack API\",\n",
-    "            \"footer_icon\": \"https://platform.slack-edge.com/img/default_application_icon.png\",\n",
-    "            \"ts\": 123456789\n",
-    "        }\n",
-    "    ]\n",
-    "                           )"
+    "r = slack.chat.post_message(channel='random',\n",
+    "                            username='Fancy Message',\n",
+    "                            icon_emoji=':earth_africa:',\n",
+    "                            attachments=[\n",
+    "                                {\n",
+    "                                    \"fallback\": \"Required plain-text summary of the attachment.\",\n",
+    "                                    \"color\": \"#2eb886\",\n",
+    "                                    \"pretext\": \"Optional text that appears above the attachment block\",\n",
+    "                                    \"author_name\": \"Fancy Message\",\n",
+    "                                    \"title\": \"Slack API Documentation\",\n",
+    "                                    \"title_link\": \"https://api.slack.com/\",\n",
+    "                                    \"text\": \"Optional text that appears within the attachment\",\n",
+    "                                    \"fields\": [\n",
+    "                                        {\n",
+    "                                            \"title\": \"Priority\",\n",
+    "                                            \"value\": \"High\",\n",
+    "                                            \"short\": False\n",
+    "                                        }\n",
+    "                                    ],\n",
+    "                                    \"image_url\": \"http://my-website.com/path/to/image.jpg\",\n",
+    "                                    \"thumb_url\": \"http://example.com/path/to/thumb.png\",\n",
+    "                                    \"footer\": \"Slack API\",\n",
+    "                                    \"footer_icon\": \"https://platform.slack-edge.com/img/default_application_icon.png\",\n",
+    "                                    \"ts\": 123456789\n",
+    "                                }\n",
+    "                            ]\n",
+    "                            )"
    ]
   },
   {
@@ -1287,58 +1290,58 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "r = slack.chat.post_message(channel = 'random', text = 'Play a game!',\n",
-    "                        username = 'Game Overseer', \n",
-    "                        icon_emoji = ':black_joker:',\n",
-    "                   attachments = [\n",
-    "        {\n",
-    "            \"text\": \"Choose a game to play\",\n",
-    "            \"fallback\": \"You are unable to choose a game\",\n",
-    "            \"callback_id\": \"wopr_game\",\n",
-    "            \"color\": \"#3AA3E3\",\n",
-    "            \"attachment_type\": \"default\",\n",
-    "            \"actions\": [\n",
-    "                {\n",
-    "                    \"name\": \"game\",\n",
-    "                    \"text\": \"Chess\",\n",
-    "                    \"type\": \"button\",\n",
-    "                    \"value\": \"chess\",\n",
-    "                    \"confirm\": {\n",
-    "                        \"title\": \"Chess is a great game for the mind\",\n",
-    "                        \"text\": \"Are you up to the challenge?\",\n",
-    "                        \"ok_text\": \"Yes\",\n",
-    "                        \"dismiss_text\": \"No\"\n",
-    "                    }\n",
-    "                },\n",
-    "                {\n",
-    "                    \"name\": \"game\",\n",
-    "                    \"text\": \"Falken's Maze\",\n",
-    "                    \"type\": \"button\",\n",
-    "                    \"value\": \"maze\",\n",
-    "                    \"confirm\": {\n",
-    "                        \"title\": \"Mazes aren't that interesting!\",\n",
-    "                        \"text\": \"How about the other options?\",\n",
-    "                        \"ok_text\": \"Yes\",\n",
-    "                        \"dismiss_text\": \"No\"\n",
-    "                    }\n",
-    "                },\n",
-    "                {\n",
-    "                    \"name\": \"game\",\n",
-    "                    \"text\": \"Thermonuclear War\",\n",
-    "                    \"style\": \"danger\",\n",
-    "                    \"type\": \"button\",\n",
-    "                    \"value\": \"war\",\n",
-    "                    \"confirm\": {\n",
-    "                        \"title\": \"Are you sure?\",\n",
-    "                        \"text\": \"Wouldn't you prefer a good game of chess?\",\n",
-    "                        \"ok_text\": \"Yes\",\n",
-    "                        \"dismiss_text\": \"No\"\n",
-    "                    }\n",
-    "                }\n",
-    "            ]\n",
-    "        }\n",
-    "    ]\n",
-    "                  )"
+    "r = slack.chat.post_message(channel='random', text='Play a game!',\n",
+    "                            username='Game Overseer',\n",
+    "                            icon_emoji=':black_joker:',\n",
+    "                            attachments=[\n",
+    "                                {\n",
+    "                                    \"text\": \"Choose a game to play\",\n",
+    "                                    \"fallback\": \"You are unable to choose a game\",\n",
+    "                                    \"callback_id\": \"wopr_game\",\n",
+    "                                    \"color\": \"#3AA3E3\",\n",
+    "                                    \"attachment_type\": \"default\",\n",
+    "                                    \"actions\": [\n",
+    "                                        {\n",
+    "                                            \"name\": \"game\",\n",
+    "                                            \"text\": \"Chess\",\n",
+    "                                            \"type\": \"button\",\n",
+    "                                            \"value\": \"chess\",\n",
+    "                                            \"confirm\": {\n",
+    "                                                \"title\": \"Chess is a great game for the mind\",\n",
+    "                                                \"text\": \"Are you up to the challenge?\",\n",
+    "                                                \"ok_text\": \"Yes\",\n",
+    "                                                \"dismiss_text\": \"No\"\n",
+    "                                            }\n",
+    "                                        },\n",
+    "                                        {\n",
+    "                                            \"name\": \"game\",\n",
+    "                                            \"text\": \"Falken's Maze\",\n",
+    "                                            \"type\": \"button\",\n",
+    "                                            \"value\": \"maze\",\n",
+    "                                            \"confirm\": {\n",
+    "                                                \"title\": \"Mazes aren't that interesting!\",\n",
+    "                                                \"text\": \"How about the other options?\",\n",
+    "                                                \"ok_text\": \"Yes\",\n",
+    "                                                \"dismiss_text\": \"No\"\n",
+    "                                            }\n",
+    "                                        },\n",
+    "                                        {\n",
+    "                                            \"name\": \"game\",\n",
+    "                                            \"text\": \"Thermonuclear War\",\n",
+    "                                            \"style\": \"danger\",\n",
+    "                                            \"type\": \"button\",\n",
+    "                                            \"value\": \"war\",\n",
+    "                                            \"confirm\": {\n",
+    "                                                \"title\": \"Are you sure?\",\n",
+    "                                                \"text\": \"Wouldn't you prefer a good game of chess?\",\n",
+    "                                                \"ok_text\": \"Yes\",\n",
+    "                                                \"dismiss_text\": \"No\"\n",
+    "                                            }\n",
+    "                                        }\n",
+    "                                    ]\n",
+    "                                }\n",
+    "                            ]\n",
+    "                            )"
    ]
   },
   {
@@ -1374,9 +1377,9 @@
     }
    ],
    "source": [
-    "r = slack.files.upload(file_ = 'images/volcano_crater.jpg',\n",
-    "                   channels= ['random'], title = 'Volcano Crater',\n",
-    "                   initial_comment = 'This would make a great display background')\n",
+    "r = slack.files.upload(file_='images/volcano_crater.jpg',\n",
+    "                       channels=['random'], title='Volcano Crater',\n",
+    "                       initial_comment='This would make a great display background')\n",
     "r.successful"
    ]
   },
@@ -1457,22 +1460,23 @@
     }
    ],
    "source": [
+    "import seaborn as sns\n",
     "import warnings\n",
-    "warnings.filterwarnings('ignore', category = FutureWarning)\n",
+    "warnings.filterwarnings('ignore', category=FutureWarning)\n",
     "\n",
     "# library & dataset\n",
-    "import seaborn as sns\n",
     "df = sns.load_dataset('iris')\n",
-    " \n",
+    "\n",
     "# Basic 2D density plot\n",
     "sns.set_style(\"white\")\n",
-    " \n",
+    "\n",
     "# Some features are characteristic of 2D: color palette and wether or not color the lowest range\n",
-    "sns.kdeplot(df.sepal_width, df.sepal_length, cmap=\"Blues\", shade=True, shade_lowest=True, );\n",
-    "plt.title('Good Ole Iris Data Set');\n",
+    "sns.kdeplot(df.sepal_width, df.sepal_length,\n",
+    "            cmap=\"Blues\", shade=True, shade_lowest=True, )\n",
+    "plt.title('Good Ole Iris Data Set')\n",
     "\n",
     "# Save last figure\n",
-    "plt.savefig('iris_plot.png', dpi = 500);"
+    "plt.savefig('iris_plot.png', dpi=500)"
    ]
   },
   {
@@ -1481,10 +1485,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "r = slack.files.upload(file_='iris_plot.png', \n",
-    "                       channels = ['slack_interaction','python_content3'],\n",
-    "                  title = 'Iris Seaborn Plot', \n",
-    "                    initial_comment = \"I've seen this data set way too many times. Seaborn makes some nice plots though.\")"
+    "r = slack.files.upload(file_='iris_plot.png',\n",
+    "                       channels=['slack_interaction', 'python_content3'],\n",
+    "                       title='Iris Seaborn Plot',\n",
+    "                       initial_comment=\"I've seen this data set way too many times. Seaborn makes some nice plots though.\")"
    ]
   },
   {
@@ -1533,7 +1537,7 @@
     "sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,\n",
     "            square=True, linewidths=.5, cbar_kws={\"shrink\": .5})\n",
     "\n",
-    "plt.savefig('heatmap_ex.png');"
+    "plt.savefig('heatmap_ex.png')"
    ]
   },
   {
@@ -1542,10 +1546,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "r = slack.files.upload(file_='heatmap_ex.png', \n",
-    "                       channels = ['slack_interaction','python_content3'],\n",
-    "                  title = 'Correlation Heatmap', \n",
-    "                    initial_comment = \"The correlations are meaningless becuase they are random. Nice plot though.\")"
+    "r = slack.files.upload(file_='heatmap_ex.png',\n",
+    "                       channels=['slack_interaction', 'python_content3'],\n",
+    "                       title='Correlation Heatmap',\n",
+    "                       initial_comment=\"The correlations are meaningless becuase they are random. Nice plot though.\")"
    ]
   },
   {
@@ -1592,9 +1596,10 @@
     "\n",
     "if reporting_channel not in channel_list:\n",
     "    slack.channels.create('training_report')\n",
-    "    \n",
+    "\n",
     "cid = slack.channels.get_channel_id('training_report')\n",
-    "r = slack.channels.set_purpose(cid, 'Report progress while training machine learning models')\n",
+    "r = slack.channels.set_purpose(\n",
+    "    cid, 'Report progress while training machine learning models')\n",
     "r = slack.channels.set_topic(cid, 'Progress Monitoring')\n",
     "r = slack.channels.info(cid).body\n",
     "r['channel']['latest']"
@@ -1673,17 +1678,17 @@
     "from keras.callbacks import Callback\n",
     "from datetime import datetime\n",
     "\n",
+    "\n",
     "def report_stats(text, channel):\n",
     "    \"\"\"Report training stats\"\"\"\n",
-    "    r = slack.chat.post_message(channel = channel, text = text, \n",
-    "                                username = 'Training Report',\n",
-    "                                icon_emoji = ':clipboard:')\n",
-    "    \n",
+    "    r = slack.chat.post_message(channel=channel, text=text,\n",
+    "                                username='Training Report',\n",
+    "                                icon_emoji=':clipboard:')\n",
+    "\n",
     "    if r.successful:\n",
     "        return True\n",
     "    else:\n",
-    "        return r.error\n",
-    "    "
+    "        return r.error"
    ]
   },
   {
@@ -1694,23 +1699,24 @@
    "source": [
     "from timeit import default_timer as timer\n",
     "\n",
+    "\n",
     "class SlackUpdate(Callback):\n",
     "    \"\"\"Custom Keras callback that posts to Slack while training a neural network\"\"\"\n",
-    "    \n",
+    "\n",
     "    def __init__(self, channel):\n",
     "        self.channel = channel\n",
-    "    \n",
+    "\n",
     "    def on_train_begin(self, logs={}):\n",
-    "        report_stats(text = f'Training started at {datetime.now()}',\n",
-    "                     channel = reporting_channel)\n",
-    "        \n",
+    "        report_stats(text=f'Training started at {datetime.now()}',\n",
+    "                     channel=reporting_channel)\n",
+    "\n",
     "        self.start_time = timer()\n",
     "        self.train_acc = []\n",
     "        self.valid_acc = []\n",
     "        self.train_loss = []\n",
     "        self.valid_loss = []\n",
     "        self.n_epochs = 0\n",
-    "    \n",
+    "\n",
     "    def on_epoch_end(self, batch, logs={}):\n",
     "\n",
     "        self.train_acc.append(logs.get('acc'))\n",
@@ -1718,24 +1724,23 @@
     "        self.train_loss.append(logs.get('loss'))\n",
     "        self.valid_loss.append(logs.get('val_loss'))\n",
     "        self.n_epochs += 1\n",
-    "        \n",
+    "\n",
     "        message = f'Epoch: {self.n_epochs} Training Loss: {self.train_loss[-1]:.4f} Validation Loss: {self.valid_loss[-1]:.4f}'\n",
-    "        \n",
-    "        report_stats(message, channel = self.channel)\n",
-    "        \n",
+    "\n",
+    "        report_stats(message, channel=self.channel)\n",
+    "\n",
     "    def on_train_end(self, logs={}):\n",
-    "        \n",
+    "\n",
     "        best_epoch = np.argmin(self.valid_loss)\n",
     "        valid_loss = self.valid_loss[best_epoch]\n",
     "        train_loss = self.train_loss[best_epoch]\n",
     "        train_acc = self.train_acc[best_epoch]\n",
     "        valid_acc = self.valid_acc[best_epoch]\n",
-    "        \n",
-    "        \n",
+    "\n",
     "        message = f'Trained for {self.n_epochs} epochs. Best epoch was {best_epoch + 1}.'\n",
-    "        report_stats(message, channel = self.channel)\n",
+    "        report_stats(message, channel=self.channel)\n",
     "        message = f'Best validation loss = {valid_loss:.4f} Training Loss = {train_loss:.2f} Validation accuracy = {100*valid_acc:.2f}%'\n",
-    "        report_stats(message, channel= self.channel)        "
+    "        report_stats(message, channel=self.channel)"
    ]
   },
   {
@@ -1787,13 +1792,13 @@
     }
    ],
    "source": [
-    "updater = SlackUpdate(channel = reporting_channel)\n",
-    "\n",
     "import tensorflow as tf\n",
+    "updater = SlackUpdate(channel=reporting_channel)\n",
+    "\n",
     "\n",
     "# Fit the model for 10 epochs\n",
-    "history = model.fit(x_train, y_train, epochs = 12, batch_size = 512,\n",
-    "                    callbacks = [updater], validation_split = 0.4)"
+    "history = model.fit(x_train, y_train, epochs=12, batch_size=512,\n",
+    "                    callbacks=[updater], validation_split=0.4)"
    ]
   },
   {
@@ -1846,7 +1851,7 @@
     "from utils import plot_history\n",
     "\n",
     "plot_history(history.history)\n",
-    "plt.savefig('training_curves.png');"
+    "plt.savefig('training_curves.png')"
    ]
   },
   {
@@ -1879,8 +1884,8 @@
     "\n",
     "# Upload file\n",
     "comment = f\"Best loss of {min_loss:.4f} at epoch {best_epoch}.\"\n",
-    "r = slack.files.upload(file_ = 'training_curves.png', title = \"Training Curves\", channels = [reporting_channel],\n",
-    "                   initial_comment = comment)\n",
+    "r = slack.files.upload(file_='training_curves.png', title=\"Training Curves\", channels=[reporting_channel],\n",
+    "                       initial_comment=comment)\n",
     "r = slack.channels.info(cid).body\n",
     "r['channel']['latest']['text']"
    ]
@@ -1908,13 +1913,14 @@
    "outputs": [],
    "source": [
     "from matplotlib import MatplotlibDeprecationWarning\n",
-    "warnings.filterwarnings('ignore', category = MatplotlibDeprecationWarning)\n",
+    "warnings.filterwarnings('ignore', category=MatplotlibDeprecationWarning)\n",
+    "\n",
     "\n",
-    "def plot_image(image, ax = None):\n",
+    "def plot_image(image, ax=None):\n",
     "    if ax is not None:\n",
-    "        ax.imshow(image.reshape((28, 28)), cmap = 'Greys')\n",
+    "        ax.imshow(image.reshape((28, 28)), cmap='Greys')\n",
     "    else:\n",
-    "        plt.imshow(image.reshape((28, 28)), cmap = 'Greys')"
+    "        plt.imshow(image.reshape((28, 28)), cmap='Greys')"
    ]
   },
   {
@@ -1963,29 +1969,30 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "def plot_predictions(n = 4):\n",
+    "def plot_predictions(n=4):\n",
     "    \"\"\"Plot test image and predictions\"\"\"\n",
-    "    \n",
+    "\n",
     "    # Get random images to plot\n",
     "    to_plot = np.random.choice(list(range(x_test.shape[0])),\n",
-    "                               size = n, replace = False)\n",
+    "                               size=n, replace=False)\n",
     "    correct = []\n",
     "    # Make predictions and plot each image\n",
     "    for i in to_plot:\n",
     "        image = x_test[i]\n",
     "        probs = model.predict_proba(image.reshape((1, 28, 28, 1)))[0]\n",
     "        pred = pd.DataFrame({'prob': probs})\n",
-    "        fig, axs = plt.subplots(1, 2, figsize = (16, 6))\n",
+    "        fig, axs = plt.subplots(1, 2, figsize=(16, 6))\n",
     "        plot_image(image, axs[0])\n",
-    "        \n",
-    "        pred['prob'].plot.bar(ax = axs[1])\n",
-    "        axs[1].set_xlabel('Class'); axs[1].set_ylabel('Probability')\n",
-    "        axs[1].set_title('Predictions');\n",
+    "\n",
+    "        pred['prob'].plot.bar(ax=axs[1])\n",
+    "        axs[1].set_xlabel('Class')\n",
+    "        axs[1].set_ylabel('Probability')\n",
+    "        axs[1].set_title('Predictions')\n",
     "        plt.savefig(f'images/test-{i}-predictions.png')\n",
     "        plt.show()\n",
-    "        \n",
+    "\n",
     "        correct.append(np.argmax(probs) == np.argmax(y_test[i]))\n",
-    "        \n",
+    "\n",
     "    return to_plot, correct"
    ]
   },
@@ -2045,20 +2052,20 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "def post_predictions(channel, n = 4):\n",
+    "def post_predictions(channel, n=4):\n",
     "    \"\"\"Post Keras preditions to Slack\"\"\"\n",
-    "    \n",
+    "\n",
     "    # Make predictions\n",
-    "    plot_indexes, correct = plot_predictions(n = n)\n",
-    "    \n",
-    "     #Iterate through images and correct indicators\n",
+    "    plot_indexes, correct = plot_predictions(n=n)\n",
+    "\n",
+    "    # Iterate through images and correct indicators\n",
     "    for i, r in zip(plot_indexes, correct):\n",
     "        filename = f'images/test-{i}-predictions.png'\n",
     "        # Upload the files\n",
-    "        r = slack.files.upload(file_ = filename, \n",
-    "                               title = \"Predictions\", \n",
-    "                               channels = [channel],\n",
-    "                               initial_comment = 'Correct' if r else 'Incorrect')"
+    "        r = slack.files.upload(file_=filename,\n",
+    "                               title=\"Predictions\",\n",
+    "                               channels=[channel],\n",
+    "                               initial_comment='Correct' if r else 'Incorrect')"
    ]
   },
   {
@@ -2119,7 +2126,7 @@
     "\n",
     "![](images/prediction_plots.PNG)\n",
     "\n",
-    "Looks like this model does pretty well. If you set up a model to train overnight, it would be nice to see these results in the morning! "
+    "Looks like this model does pretty well. If you set up a model to train overnight, it would be nice to see these results in the morning."
    ]
   },
   {
@@ -2158,6 +2165,18 @@
    "language": "python",
    "name": "python3"
   },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.5"
+  },
   "toc": {
    "base_numbering": 1,
    "nav_menu": {},