Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickthoreson/ab561c624f839a94ab17ea64905c5014 to your computer and use it in GitHub Desktop.
Save patrickthoreson/ab561c624f839a94ab17ea64905c5014 to your computer and use it in GitHub Desktop.
Created on Cognitive Class Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a href=\"https://cognitiveclass.ai\"><img src = \"https://ibm.box.com/shared/static/9gegpsmnsoo25ikkbl4qzlvlyjbgxs5x.png\" width = 400> </a>\n",
"\n",
"<h1 align=center><font size = 5>Learning FourSquare API with Python</font></h1>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## Introduction\n",
"\n",
"In this lab, you will learn in details how to make calls to the Foursquare API for different purposes. You will learn how to construct a URL to send a request to the API to search for a specific type of venues, to explore a particular venue, to explore a Foursquare user, to explore a geographical location, and to get trending venues around a location. Also, you will learn how to use the visualization library, Folium, to visualize the results."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## Table of Contents\n",
"\n",
"1. <a href=\"#item1\">Foursquare API Search Function</a>\n",
"2. <a href=\"#item2\">Explore a Given Venue</a> \n",
"3. <a href=\"#item3\">Explore a User</a> \n",
"4. <a href=\"#item4\">Foursquare API Explore Function</a> \n",
"5. <a href=\"#item5\">Get Trending Venues</a> "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Import necessary Libraries"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Folium installed\n",
"Libraries imported.\n"
]
}
],
"source": [
"import requests # library to handle requests\n",
"import pandas as pd # library for data analsysis\n",
"import numpy as np # library to handle data in a vectorized manner\n",
"import random # library for random number generation\n",
"\n",
"#!conda install -c conda-forge geopy --yes \n",
"from geopy.geocoders import Nominatim # module to convert an address into latitude and longitude values\n",
"\n",
"# libraries for displaying images\n",
"from IPython.display import Image \n",
"from IPython.core.display import HTML \n",
" \n",
"# tranforming json file into a pandas dataframe library\n",
"from pandas.io.json import json_normalize\n",
"\n",
"#!conda install -c conda-forge folium=0.5.0 --yes\n",
"import folium # plotting library\n",
"\n",
"print('Folium installed')\n",
"print('Libraries imported.')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Define Foursquare Credentials and Version"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"##### Make sure that you have created a Foursquare developer account and have your credentials handy"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Your credentials:\n",
"CLIENT_ID: your-client-ID\n",
"CLIENT_SECRET:your-client-secret\n"
]
}
],
"source": [
"CLIENT_ID = 'your-client-ID' # your Foursquare ID\n",
"CLIENT_SECRET = 'your-client-secret' # your Foursquare Secret\n",
"VERSION = '20180604'\n",
"LIMIT = 30\n",
"print('Your credentials:')\n",
"print('CLIENT_ID: ' + CLIENT_ID)\n",
"print('CLIENT_SECRET:' + CLIENT_SECRET)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Let's again assume that you are staying at the Conrad hotel. So let's start by converting the Contrad Hotel's address to its latitude and longitude coordinates."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to define an instance of the geocoder, we need to define a user_agent. We will name our agent <em>foursquare_agent</em>, as shown below."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"40.7149555 -74.0153365\n"
]
}
],
"source": [
"address = '102 North End Ave, New York, NY'\n",
"\n",
"geolocator = Nominatim(user_agent=\"foursquare_agent\")\n",
"location = geolocator.geocode(address)\n",
"latitude = location.latitude\n",
"longitude = location.longitude\n",
"print(latitude, longitude)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item1\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## 1. Search for a specific venue category\n",
"> `https://api.foursquare.com/v2/venues/`**search**`?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&ll=`**LATITUDE**`,`**LONGITUDE**`&v=`**VERSION**`&query=`**QUERY**`&radius=`**RADIUS**`&limit=`**LIMIT**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Now, let's assume that it is lunch time, and you are craving Italian food. So, let's define a query to search for Italian food that is within 500 metres from the Conrad Hotel. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Italian .... OK!\n"
]
}
],
"source": [
"search_query = 'Italian'\n",
"radius = 500\n",
"print(search_query + ' .... OK!')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Define the corresponding URL"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"'https://api.foursquare.com/v2/venues/search?client_id=your-client-ID&client_secret=your-client-secret&ll=40.7149555,-74.0153365&v=20180604&query=Italian&radius=500&limit=30'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"url = 'https://api.foursquare.com/v2/venues/search?client_id={}&client_secret={}&ll={},{}&v={}&query={}&radius={}&limit={}'.format(CLIENT_ID, CLIENT_SECRET, latitude, longitude, VERSION, search_query, radius, LIMIT)\n",
"url"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Send the GET Request and examine the results"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"{'meta': {'code': 200, 'requestId': '5c74bc25f594df76b9d58ba4'},\n",
" 'response': {'venues': [{'id': '4fa862b3e4b0ebff2f749f06',\n",
" 'name': \"Harry's Italian Pizza Bar\",\n",
" 'location': {'address': '225 Murray St',\n",
" 'lat': 40.71521779064671,\n",
" 'lng': -74.01473940209351,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 40.71521779064671,\n",
" 'lng': -74.01473940209351}],\n",
" 'distance': 58,\n",
" 'postalCode': '10282',\n",
" 'cc': 'US',\n",
" 'city': 'New York',\n",
" 'state': 'NY',\n",
" 'country': 'United States',\n",
" 'formattedAddress': ['225 Murray St',\n",
" 'New York, NY 10282',\n",
" 'United States']},\n",
" 'categories': [{'id': '4bf58dd8d48988d1ca941735',\n",
" 'name': 'Pizza Place',\n",
" 'pluralName': 'Pizza Places',\n",
" 'shortName': 'Pizza',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/pizza_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'delivery': {'id': '294544',\n",
" 'url': 'https://www.seamless.com/menu/harrys-italian-pizza-bar-225-murray-st-new-york/294544?affiliate=1131&utm_source=foursquare-affiliate-network&utm_medium=affiliate&utm_campaign=1131&utm_content=294544',\n",
" 'provider': {'name': 'seamless',\n",
" 'icon': {'prefix': 'https://fastly.4sqi.net/img/general/cap/',\n",
" 'sizes': [40, 50],\n",
" 'name': '/delivery_provider_seamless_20180129.png'}}},\n",
" 'referralId': 'v-1551154213',\n",
" 'hasPerk': False},\n",
" {'id': '4f3232e219836c91c7bfde94',\n",
" 'name': 'Conca Cucina Italian Restaurant',\n",
" 'location': {'address': '63 W Broadway',\n",
" 'lat': 40.71446,\n",
" 'lng': -74.010086,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 40.71446,\n",
" 'lng': -74.010086}],\n",
" 'distance': 446,\n",
" 'postalCode': '10007',\n",
" 'cc': 'US',\n",
" 'city': 'New York',\n",
" 'state': 'NY',\n",
" 'country': 'United States',\n",
" 'formattedAddress': ['63 W Broadway',\n",
" 'New York, NY 10007',\n",
" 'United States']},\n",
" 'categories': [{'id': '4d4b7105d754a06374d81259',\n",
" 'name': 'Food',\n",
" 'pluralName': 'Food',\n",
" 'shortName': 'Food',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/default_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'referralId': 'v-1551154213',\n",
" 'hasPerk': False},\n",
" {'id': '3fd66200f964a520f4e41ee3',\n",
" 'name': 'Ecco',\n",
" 'location': {'address': '124 Chambers St',\n",
" 'crossStreet': 'btwn Church St & W Broadway',\n",
" 'lat': 40.71533713859952,\n",
" 'lng': -74.00884766217825,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 40.71533713859952,\n",
" 'lng': -74.00884766217825}],\n",
" 'distance': 549,\n",
" 'postalCode': '10007',\n",
" 'cc': 'US',\n",
" 'city': 'New York',\n",
" 'state': 'NY',\n",
" 'country': 'United States',\n",
" 'formattedAddress': ['124 Chambers St (btwn Church St & W Broadway)',\n",
" 'New York, NY 10007',\n",
" 'United States']},\n",
" 'categories': [{'id': '4bf58dd8d48988d110941735',\n",
" 'name': 'Italian Restaurant',\n",
" 'pluralName': 'Italian Restaurants',\n",
" 'shortName': 'Italian',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/italian_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'referralId': 'v-1551154213',\n",
" 'hasPerk': False}]}}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results = requests.get(url).json()\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Get relevant part of JSON and transform it into a *pandas* dataframe"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>categories</th>\n",
" <th>delivery.id</th>\n",
" <th>delivery.provider.icon.name</th>\n",
" <th>delivery.provider.icon.prefix</th>\n",
" <th>delivery.provider.icon.sizes</th>\n",
" <th>delivery.provider.name</th>\n",
" <th>delivery.url</th>\n",
" <th>hasPerk</th>\n",
" <th>id</th>\n",
" <th>location.address</th>\n",
" <th>...</th>\n",
" <th>location.crossStreet</th>\n",
" <th>location.distance</th>\n",
" <th>location.formattedAddress</th>\n",
" <th>location.labeledLatLngs</th>\n",
" <th>location.lat</th>\n",
" <th>location.lng</th>\n",
" <th>location.postalCode</th>\n",
" <th>location.state</th>\n",
" <th>name</th>\n",
" <th>referralId</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>[{'id': '4bf58dd8d48988d1ca941735', 'name': 'P...</td>\n",
" <td>294544</td>\n",
" <td>/delivery_provider_seamless_20180129.png</td>\n",
" <td>https://fastly.4sqi.net/img/general/cap/</td>\n",
" <td>[40, 50]</td>\n",
" <td>seamless</td>\n",
" <td>https://www.seamless.com/menu/harrys-italian-p...</td>\n",
" <td>False</td>\n",
" <td>4fa862b3e4b0ebff2f749f06</td>\n",
" <td>225 Murray St</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>58</td>\n",
" <td>[225 Murray St, New York, NY 10282, United Sta...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71521779064671...</td>\n",
" <td>40.715218</td>\n",
" <td>-74.014739</td>\n",
" <td>10282</td>\n",
" <td>NY</td>\n",
" <td>Harry's Italian Pizza Bar</td>\n",
" <td>v-1551154213</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>[{'id': '4d4b7105d754a06374d81259', 'name': 'F...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>False</td>\n",
" <td>4f3232e219836c91c7bfde94</td>\n",
" <td>63 W Broadway</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>446</td>\n",
" <td>[63 W Broadway, New York, NY 10007, United Sta...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71446, 'lng': ...</td>\n",
" <td>40.714460</td>\n",
" <td>-74.010086</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>Conca Cucina Italian Restaurant</td>\n",
" <td>v-1551154213</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>[{'id': '4bf58dd8d48988d110941735', 'name': 'I...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>False</td>\n",
" <td>3fd66200f964a520f4e41ee3</td>\n",
" <td>124 Chambers St</td>\n",
" <td>...</td>\n",
" <td>btwn Church St &amp; W Broadway</td>\n",
" <td>549</td>\n",
" <td>[124 Chambers St (btwn Church St &amp; W Broadway)...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71533713859952...</td>\n",
" <td>40.715337</td>\n",
" <td>-74.008848</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>Ecco</td>\n",
" <td>v-1551154213</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>3 rows × 23 columns</p>\n",
"</div>"
],
"text/plain": [
" categories delivery.id \\\n",
"0 [{'id': '4bf58dd8d48988d1ca941735', 'name': 'P... 294544 \n",
"1 [{'id': '4d4b7105d754a06374d81259', 'name': 'F... NaN \n",
"2 [{'id': '4bf58dd8d48988d110941735', 'name': 'I... NaN \n",
"\n",
" delivery.provider.icon.name \\\n",
"0 /delivery_provider_seamless_20180129.png \n",
"1 NaN \n",
"2 NaN \n",
"\n",
" delivery.provider.icon.prefix delivery.provider.icon.sizes \\\n",
"0 https://fastly.4sqi.net/img/general/cap/ [40, 50] \n",
"1 NaN NaN \n",
"2 NaN NaN \n",
"\n",
" delivery.provider.name delivery.url \\\n",
"0 seamless https://www.seamless.com/menu/harrys-italian-p... \n",
"1 NaN NaN \n",
"2 NaN NaN \n",
"\n",
" hasPerk id location.address ... \\\n",
"0 False 4fa862b3e4b0ebff2f749f06 225 Murray St ... \n",
"1 False 4f3232e219836c91c7bfde94 63 W Broadway ... \n",
"2 False 3fd66200f964a520f4e41ee3 124 Chambers St ... \n",
"\n",
" location.crossStreet location.distance \\\n",
"0 NaN 58 \n",
"1 NaN 446 \n",
"2 btwn Church St & W Broadway 549 \n",
"\n",
" location.formattedAddress \\\n",
"0 [225 Murray St, New York, NY 10282, United Sta... \n",
"1 [63 W Broadway, New York, NY 10007, United Sta... \n",
"2 [124 Chambers St (btwn Church St & W Broadway)... \n",
"\n",
" location.labeledLatLngs location.lat \\\n",
"0 [{'label': 'display', 'lat': 40.71521779064671... 40.715218 \n",
"1 [{'label': 'display', 'lat': 40.71446, 'lng': ... 40.714460 \n",
"2 [{'label': 'display', 'lat': 40.71533713859952... 40.715337 \n",
"\n",
" location.lng location.postalCode location.state \\\n",
"0 -74.014739 10282 NY \n",
"1 -74.010086 10007 NY \n",
"2 -74.008848 10007 NY \n",
"\n",
" name referralId \n",
"0 Harry's Italian Pizza Bar v-1551154213 \n",
"1 Conca Cucina Italian Restaurant v-1551154213 \n",
"2 Ecco v-1551154213 \n",
"\n",
"[3 rows x 23 columns]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# assign relevant part of JSON to venues\n",
"venues = results['response']['venues']\n",
"\n",
"# tranform venues into a dataframe\n",
"dataframe = json_normalize(venues)\n",
"dataframe.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Define information of interest and filter dataframe"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>name</th>\n",
" <th>categories</th>\n",
" <th>address</th>\n",
" <th>cc</th>\n",
" <th>city</th>\n",
" <th>country</th>\n",
" <th>crossStreet</th>\n",
" <th>distance</th>\n",
" <th>formattedAddress</th>\n",
" <th>labeledLatLngs</th>\n",
" <th>lat</th>\n",
" <th>lng</th>\n",
" <th>postalCode</th>\n",
" <th>state</th>\n",
" <th>id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Harry's Italian Pizza Bar</td>\n",
" <td>Pizza Place</td>\n",
" <td>225 Murray St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>NaN</td>\n",
" <td>58</td>\n",
" <td>[225 Murray St, New York, NY 10282, United Sta...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71521779064671...</td>\n",
" <td>40.715218</td>\n",
" <td>-74.014739</td>\n",
" <td>10282</td>\n",
" <td>NY</td>\n",
" <td>4fa862b3e4b0ebff2f749f06</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Conca Cucina Italian Restaurant</td>\n",
" <td>Food</td>\n",
" <td>63 W Broadway</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>NaN</td>\n",
" <td>446</td>\n",
" <td>[63 W Broadway, New York, NY 10007, United Sta...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71446, 'lng': ...</td>\n",
" <td>40.714460</td>\n",
" <td>-74.010086</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>4f3232e219836c91c7bfde94</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Ecco</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>124 Chambers St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>btwn Church St &amp; W Broadway</td>\n",
" <td>549</td>\n",
" <td>[124 Chambers St (btwn Church St &amp; W Broadway)...</td>\n",
" <td>[{'label': 'display', 'lat': 40.71533713859952...</td>\n",
" <td>40.715337</td>\n",
" <td>-74.008848</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>3fd66200f964a520f4e41ee3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" name categories address cc \\\n",
"0 Harry's Italian Pizza Bar Pizza Place 225 Murray St US \n",
"1 Conca Cucina Italian Restaurant Food 63 W Broadway US \n",
"2 Ecco Italian Restaurant 124 Chambers St US \n",
"\n",
" city country crossStreet distance \\\n",
"0 New York United States NaN 58 \n",
"1 New York United States NaN 446 \n",
"2 New York United States btwn Church St & W Broadway 549 \n",
"\n",
" formattedAddress \\\n",
"0 [225 Murray St, New York, NY 10282, United Sta... \n",
"1 [63 W Broadway, New York, NY 10007, United Sta... \n",
"2 [124 Chambers St (btwn Church St & W Broadway)... \n",
"\n",
" labeledLatLngs lat lng \\\n",
"0 [{'label': 'display', 'lat': 40.71521779064671... 40.715218 -74.014739 \n",
"1 [{'label': 'display', 'lat': 40.71446, 'lng': ... 40.714460 -74.010086 \n",
"2 [{'label': 'display', 'lat': 40.71533713859952... 40.715337 -74.008848 \n",
"\n",
" postalCode state id \n",
"0 10282 NY 4fa862b3e4b0ebff2f749f06 \n",
"1 10007 NY 4f3232e219836c91c7bfde94 \n",
"2 10007 NY 3fd66200f964a520f4e41ee3 "
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# keep only columns that include venue name, and anything that is associated with location\n",
"filtered_columns = ['name', 'categories'] + [col for col in dataframe.columns if col.startswith('location.')] + ['id']\n",
"dataframe_filtered = dataframe.loc[:, filtered_columns]\n",
"#print(\"dataframe_filtered step 1:\", dataframe_filtered.head())\n",
"# function that extracts the category of the venue\n",
"def get_category_type(row):\n",
" try:\n",
" categories_list = row['categories']\n",
" except:\n",
" categories_list = row['venue.categories']\n",
" \n",
" if len(categories_list) == 0:\n",
" return None\n",
" else:\n",
" return categories_list[0]['name']\n",
"\n",
"# filter the category for each row\n",
"dataframe_filtered['categories'] = dataframe_filtered.apply(get_category_type, axis=1)\n",
"\n",
"# clean column names by keeping only last term\n",
"dataframe_filtered.columns = [column.split('.')[-1] for column in dataframe_filtered.columns]\n",
"\n",
"dataframe_filtered"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Let's visualize the Italian restaurants that are nearby"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"0 Harry's Italian Pizza Bar\n",
"1 Conca Cucina Italian Restaurant\n",
"2 Ecco\n",
"Name: name, dtype: object"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dataframe_filtered.name"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfNWFjMjgxZTEwZjhlNGY5M2I0NmM5MjZhNjQ5NDBjYTUgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzVhYzI4MWUxMGY4ZTRmOTNiNDZjOTI2YTY0OTQwY2E1IiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF81YWMyODFlMTBmOGU0ZjkzYjQ2YzkyNmE2NDk0MGNhNSA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF81YWMyODFlMTBmOGU0ZjkzYjQ2YzkyNmE2NDk0MGNhNScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDAuNzE0OTU1NSwtNzQuMDE1MzM2NV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiAxMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heEJvdW5kczogYm91bmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5ZXJzOiBbXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmxkQ29weUp1bXA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHRpbGVfbGF5ZXJfNDY0NTRjMzUzNjM5NDk0NmI1Yjg4MzExZmE0YTI0Y2UgPSBMLnRpbGVMYXllcigKICAgICAgICAgICAgICAgICdodHRwczovL3tzfS50aWxlLm9wZW5zdHJlZXRtYXAub3JnL3t6fS97eH0ve3l9LnBuZycsCiAgICAgICAgICAgICAgICB7CiAgImF0dHJpYnV0aW9uIjogbnVsbCwKICAiZGV0ZWN0UmV0aW5hIjogZmFsc2UsCiAgIm1heFpvb20iOiAxOCwKICAibWluWm9vbSI6IDEsCiAgIm5vV3JhcCI6IGZhbHNlLAogICJzdWJkb21haW5zIjogImFiYyIKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWFjMjgxZTEwZjhlNGY5M2I0NmM5MjZhNjQ5NDBjYTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I5N2I5ODk0N2E3OTQzY2VhODAzZWI4NjM5ZWIwMDQyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0OTU1NSwtNzQuMDE1MzM2NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDEwLAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzVhYzI4MWUxMGY4ZTRmOTNiNDZjOTI2YTY0OTQwY2E1KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzM4MDVlYjNlM2NjMzQwYzJiMjNhNjIxYjQ1Mzg4NDIyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzA5MzJiNDk3MjQ4NTRhNzRiODI3NThlYzBjM2FmMzViID0gJCgnPGRpdiBpZD0iaHRtbF8wOTMyYjQ5NzI0ODU0YTc0YjgyNzU4ZWMwYzNhZjM1YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q29ucmFkIEhvdGVsPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zODA1ZWIzZTNjYzM0MGMyYjIzYTYyMWI0NTM4ODQyMi5zZXRDb250ZW50KGh0bWxfMDkzMmI0OTcyNDg1NGE3NGI4Mjc1OGVjMGMzYWYzNWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjk3Yjk4OTQ3YTc5NDNjZWE4MDNlYjg2MzllYjAwNDIuYmluZFBvcHVwKHBvcHVwXzM4MDVlYjNlM2NjMzQwYzJiMjNhNjIxYjQ1Mzg4NDIyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2EyZGNjODI2NjNiZTQ2YTA5MjcwMGQ4NGIzZDUwMDIwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE1MjE3NzkwNjQ2NzEsLTc0LjAxNDczOTQwMjA5MzUxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzVhYzI4MWUxMGY4ZTRmOTNiNDZjOTI2YTY0OTQwY2E1KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ3YTk4MzE5YWRlNDRhMzA4OGM4YjU5Njg0ZTZmYzAyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdlOTZhNzUyNDM0ZDRiNTM4ZTY4ODZkY2VmNzJlOWQzID0gJCgnPGRpdiBpZD0iaHRtbF83ZTk2YTc1MjQzNGQ0YjUzOGU2ODg2ZGNlZjcyZTlkMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGl6emEgUGxhY2U8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ3YTk4MzE5YWRlNDRhMzA4OGM4YjU5Njg0ZTZmYzAyLnNldENvbnRlbnQoaHRtbF83ZTk2YTc1MjQzNGQ0YjUzOGU2ODg2ZGNlZjcyZTlkMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hMmRjYzgyNjYzYmU0NmEwOTI3MDBkODRiM2Q1MDAyMC5iaW5kUG9wdXAocG9wdXBfNDdhOTgzMTlhZGU0NGEzMDg4YzhiNTk2ODRlNmZjMDIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGQyYmI0YTczYjJiNGI2Yjg3ZGE1MzQ3Njk2ZDNkYjcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTQ0NiwtNzQuMDEwMDg2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzVhYzI4MWUxMGY4ZTRmOTNiNDZjOTI2YTY0OTQwY2E1KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQxYzEyZjFmMWI5MzRjZjE4ODYyNjVmMGI3NDA4Yzk4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI0NDc1NzQ0MmI4YzRkZTRhYTk1OTYwMTBjMTNjMjU3ID0gJCgnPGRpdiBpZD0iaHRtbF8yNDQ3NTc0NDJiOGM0ZGU0YWE5NTk2MDEwYzEzYzI1NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rm9vZDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDFjMTJmMWYxYjkzNGNmMTg4NjI2NWYwYjc0MDhjOTguc2V0Q29udGVudChodG1sXzI0NDc1NzQ0MmI4YzRkZTRhYTk1OTYwMTBjMTNjMjU3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzhkMmJiNGE3M2IyYjRiNmI4N2RhNTM0NzY5NmQzZGI3LmJpbmRQb3B1cChwb3B1cF80MWMxMmYxZjFiOTM0Y2YxODg2MjY1ZjBiNzQwOGM5OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MzQ5NmI1ZDI0Mjg0ZjAxYTQ0ZDk1Y2VkMDgwOTM4YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTMzNzEzODU5OTUyLC03NC4wMDg4NDc2NjIxNzgyNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF81YWMyODFlMTBmOGU0ZjkzYjQ2YzkyNmE2NDk0MGNhNSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84OWRjMTRiZDViZTA0ODAyOWI2NjU4YmU4NmEzZTI4ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84ZWU3ZTNhOGU4YjM0MmJhYTc5NDA5NmJjODY4YjJlOSA9ICQoJzxkaXYgaWQ9Imh0bWxfOGVlN2UzYThlOGIzNDJiYWE3OTQwOTZiYzg2OGIyZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkl0YWxpYW4gUmVzdGF1cmFudDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODlkYzE0YmQ1YmUwNDgwMjliNjY1OGJlODZhM2UyOGYuc2V0Q29udGVudChodG1sXzhlZTdlM2E4ZThiMzQyYmFhNzk0MDk2YmM4NjhiMmU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzYzNDk2YjVkMjQyODRmMDFhNDRkOTVjZWQwODA5MzhjLmJpbmRQb3B1cChwb3B1cF84OWRjMTRiZDViZTA0ODAyOWI2NjU4YmU4NmEzZTI4Zik7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f9a46a93da0>"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"venues_map = folium.Map(location=[latitude, longitude], zoom_start=13) # generate map centred around the Conrad Hotel\n",
"\n",
"# add a red circle marker to represent the Conrad Hotel\n",
"folium.features.CircleMarker(\n",
" [latitude, longitude],\n",
" radius=10,\n",
" color='red',\n",
" popup='Conrad Hotel',\n",
" fill = True,\n",
" fill_color = 'red',\n",
" fill_opacity = 0.6\n",
").add_to(venues_map)\n",
"\n",
"# add the Italian restaurants as blue circle markers\n",
"for lat, lng, label in zip(dataframe_filtered.lat, dataframe_filtered.lng, dataframe_filtered.categories):\n",
" folium.features.CircleMarker(\n",
" [lat, lng],\n",
" radius=5,\n",
" color='blue',\n",
" popup=label,\n",
" fill = True,\n",
" fill_color='blue',\n",
" fill_opacity=0.6\n",
" ).add_to(venues_map)\n",
"\n",
"# display map\n",
"venues_map"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item2\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## 2. Explore a Given Venue\n",
"> `https://api.foursquare.com/v2/venues/`**VENUE_ID**`?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&v=`**VERSION**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### A. Let's explore the closest Italian restaurant -- _Harry's Italian Pizza Bar_"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"'https://api.foursquare.com/v2/venues/4fa862b3e4b0ebff2f749f06?client_id=your-client-ID&client_secret=your-client-secret&v=20180604'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"venue_id = '4fa862b3e4b0ebff2f749f06' # ID of Harry's Italian Pizza Bar\n",
"url = 'https://api.foursquare.com/v2/venues/{}?client_id={}&client_secret={}&v={}'.format(venue_id, CLIENT_ID, CLIENT_SECRET, VERSION)\n",
"url"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Send GET request for result"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dict_keys(['id', 'name', 'contact', 'location', 'canonicalUrl', 'categories', 'verified', 'stats', 'url', 'price', 'hasMenu', 'likes', 'dislike', 'ok', 'rating', 'ratingColor', 'ratingSignals', 'delivery', 'menu', 'allowMenuUrlEdit', 'beenHere', 'specials', 'photos', 'reasons', 'hereNow', 'createdAt', 'tips', 'shortUrl', 'timeZone', 'listed', 'hours', 'popular', 'pageUpdates', 'inbox', 'attributes', 'bestPhoto', 'colors'])\n"
]
},
{
"data": {
"text/plain": [
"{'id': '4fa862b3e4b0ebff2f749f06',\n",
" 'name': \"Harry's Italian Pizza Bar\",\n",
" 'contact': {'phone': '2126081007', 'formattedPhone': '(212) 608-1007'},\n",
" 'location': {'address': '225 Murray St',\n",
" 'lat': 40.71521779064671,\n",
" 'lng': -74.01473940209351,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 40.71521779064671,\n",
" 'lng': -74.01473940209351}],\n",
" 'postalCode': '10282',\n",
" 'cc': 'US',\n",
" 'city': 'New York',\n",
" 'state': 'NY',\n",
" 'country': 'United States',\n",
" 'formattedAddress': ['225 Murray St',\n",
" 'New York, NY 10282',\n",
" 'United States']},\n",
" 'canonicalUrl': 'https://foursquare.com/v/harrys-italian-pizza-bar/4fa862b3e4b0ebff2f749f06',\n",
" 'categories': [{'id': '4bf58dd8d48988d1ca941735',\n",
" 'name': 'Pizza Place',\n",
" 'pluralName': 'Pizza Places',\n",
" 'shortName': 'Pizza',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/pizza_',\n",
" 'suffix': '.png'},\n",
" 'primary': True},\n",
" {'id': '4bf58dd8d48988d110941735',\n",
" 'name': 'Italian Restaurant',\n",
" 'pluralName': 'Italian Restaurants',\n",
" 'shortName': 'Italian',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/italian_',\n",
" 'suffix': '.png'}}],\n",
" 'verified': False,\n",
" 'stats': {'tipCount': 55},\n",
" 'url': 'http://harrysitalian.com',\n",
" 'price': {'tier': 2, 'message': 'Moderate', 'currency': '$'},\n",
" 'hasMenu': True,\n",
" 'likes': {'count': 119,\n",
" 'groups': [{'type': 'others', 'count': 119, 'items': []}],\n",
" 'summary': '119 Likes'},\n",
" 'dislike': False,\n",
" 'ok': False,\n",
" 'rating': 7.1,\n",
" 'ratingColor': 'C5DE35',\n",
" 'ratingSignals': 209,\n",
" 'delivery': {'id': '294544',\n",
" 'url': 'https://www.seamless.com/menu/harrys-italian-pizza-bar-225-murray-st-new-york/294544?affiliate=1131&utm_source=foursquare-affiliate-network&utm_medium=affiliate&utm_campaign=1131&utm_content=294544',\n",
" 'provider': {'name': 'seamless',\n",
" 'icon': {'prefix': 'https://fastly.4sqi.net/img/general/cap/',\n",
" 'sizes': [40, 50],\n",
" 'name': '/delivery_provider_seamless_20180129.png'}}},\n",
" 'menu': {'type': 'Menu',\n",
" 'label': 'Menu',\n",
" 'anchor': 'View Menu',\n",
" 'url': 'https://foursquare.com/v/harrys-italian-pizza-bar/4fa862b3e4b0ebff2f749f06/menu',\n",
" 'mobileUrl': 'https://foursquare.com/v/4fa862b3e4b0ebff2f749f06/device_menu'},\n",
" 'allowMenuUrlEdit': True,\n",
" 'beenHere': {'count': 0,\n",
" 'unconfirmedCount': 0,\n",
" 'marked': False,\n",
" 'lastCheckinExpiredAt': 0},\n",
" 'specials': {'count': 0, 'items': []},\n",
" 'photos': {'count': 146,\n",
" 'groups': [{'type': 'checkin',\n",
" 'name': \"Friends' check-in photos\",\n",
" 'count': 0,\n",
" 'items': []},\n",
" {'type': 'venue',\n",
" 'name': 'Venue photos',\n",
" 'count': 146,\n",
" 'items': [{'id': '4fad980de4b091b4626c3633',\n",
" 'createdAt': 1336776717,\n",
" 'source': {'name': 'Foursquare for Android',\n",
" 'url': 'https://foursquare.com/download/#/android'},\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/ya1iQFI7pLjuIJp1PGDKlrZS3OJdHCF7tpILMmjv_2w.jpg',\n",
" 'width': 480,\n",
" 'height': 640,\n",
" 'user': {'id': '13676709',\n",
" 'firstName': 'Leony',\n",
" 'lastName': 'Naciri',\n",
" 'gender': 'none',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/T0ANFNGNMCHUDEUE.jpg'}},\n",
" 'visibility': 'public'},\n",
" {'id': '513a2e50e4b08ac082454376',\n",
" 'createdAt': 1362767440,\n",
" 'source': {'name': 'Foursquare for iOS',\n",
" 'url': 'https://foursquare.com/download/#/iphone'},\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/6195366_2CTGLooEIZ-oVxZlMGjQFunPJuwJql1jtFnIf69-8Tw.jpg',\n",
" 'width': 717,\n",
" 'height': 959,\n",
" 'user': {'id': '6195366',\n",
" 'firstName': 'Michelle',\n",
" 'lastName': 'Thornton',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/2RJUIIDMSRLF1UOE.jpg'}},\n",
" 'visibility': 'public'}]}],\n",
" 'summary': '0 photos'},\n",
" 'reasons': {'count': 1,\n",
" 'items': [{'summary': 'Lots of people like this place',\n",
" 'type': 'general',\n",
" 'reasonName': 'rawLikesReason'}]},\n",
" 'hereNow': {'count': 0, 'summary': 'Nobody here', 'groups': []},\n",
" 'createdAt': 1336435379,\n",
" 'tips': {'count': 55,\n",
" 'groups': [{'type': 'others',\n",
" 'name': 'All tips',\n",
" 'count': 55,\n",
" 'items': [{'id': '53d27909498e0523841340b6',\n",
" 'createdAt': 1406302473,\n",
" 'text': \"Harry's Italian Pizza bar is known for it's amazing pizza, but did you know that the brunches here are amazing too? Try the Nutella French toast and we know you'll be sold.\",\n",
" 'type': 'user',\n",
" 'canonicalUrl': 'https://foursquare.com/item/53d27909498e0523841340b6',\n",
" 'lang': 'en',\n",
" 'likes': {'count': 4,\n",
" 'groups': [{'type': 'others',\n",
" 'count': 4,\n",
" 'items': [{'id': '369426',\n",
" 'firstName': 'P.',\n",
" 'lastName': 'M.',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/JPQYUWJKUT0H2OO4.jpg'}},\n",
" {'id': '87587879',\n",
" 'firstName': 'Diane',\n",
" 'lastName': 'Danneels',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/87587879-ESLRSZLQ2CBE2P4W.jpg'}},\n",
" {'id': '87591341',\n",
" 'firstName': 'Tim',\n",
" 'lastName': 'Sheehan',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/-Z4YK4VKE0JSVXIY1.jpg'}},\n",
" {'id': '87473404',\n",
" 'firstName': 'TenantKing.com',\n",
" 'gender': 'none',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/87473404-HI5DTBTK0HX401CA.png'},\n",
" 'type': 'page'}]}],\n",
" 'summary': '4 likes'},\n",
" 'logView': True,\n",
" 'agreeCount': 4,\n",
" 'disagreeCount': 0,\n",
" 'todo': {'count': 0},\n",
" 'user': {'id': '87473404',\n",
" 'firstName': 'TenantKing.com',\n",
" 'gender': 'none',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/87473404-HI5DTBTK0HX401CA.png'},\n",
" 'type': 'page'}},\n",
" {'id': '53962e98498ecd43845cc813',\n",
" 'createdAt': 1402351256,\n",
" 'text': \"I'm not sure if this place is one of the famous pizzerias in NYC but I loved their pizza.\",\n",
" 'type': 'user',\n",
" 'canonicalUrl': 'https://foursquare.com/item/53962e98498ecd43845cc813',\n",
" 'photo': {'id': '53962e9c498e53dbbf59b28e',\n",
" 'createdAt': 1402351260,\n",
" 'source': {'name': 'Foursquare for iOS',\n",
" 'url': 'https://foursquare.com/download/#/iphone'},\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/7012699_DCcCtW8oRbhNv62E68gxtLnWn7IgRhapBr8vdnIQjYk.jpg',\n",
" 'width': 720,\n",
" 'height': 720,\n",
" 'visibility': 'public'},\n",
" 'photourl': 'https://fastly.4sqi.net/img/general/original/7012699_DCcCtW8oRbhNv62E68gxtLnWn7IgRhapBr8vdnIQjYk.jpg',\n",
" 'lang': 'en',\n",
" 'likes': {'count': 2,\n",
" 'groups': [{'type': 'others',\n",
" 'count': 2,\n",
" 'items': [{'id': '7012699',\n",
" 'firstName': 'Hani',\n",
" 'lastName': 'Alawadi',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/2ZMJFSP2Z4R5NBVX.jpg'}},\n",
" {'id': '61939758',\n",
" 'firstName': 'Leena',\n",
" 'lastName': 'Ragheb',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/61939758_pBzZmOnI_mALXdaYa4C4EqqytWYHr5jq5XUZi3ImFD8uORx0A5-KLcSxtzsxwgtMRPn1Ur7-v.jpg'}}]}],\n",
" 'summary': '2 likes'},\n",
" 'logView': True,\n",
" 'agreeCount': 2,\n",
" 'disagreeCount': 0,\n",
" 'todo': {'count': 0},\n",
" 'user': {'id': '7012699',\n",
" 'firstName': 'Hani',\n",
" 'lastName': 'Alawadi',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/2ZMJFSP2Z4R5NBVX.jpg'}},\n",
" 'authorInteractionType': 'liked'}]}]},\n",
" 'shortUrl': 'http://4sq.com/JNblHV',\n",
" 'timeZone': 'America/New_York',\n",
" 'listed': {'count': 50,\n",
" 'groups': [{'type': 'others',\n",
" 'name': 'Lists from other people',\n",
" 'count': 50,\n",
" 'items': [{'id': '4fa32fd0e4b04193744746b1',\n",
" 'name': 'Manhattan Haunts',\n",
" 'description': '',\n",
" 'type': 'others',\n",
" 'user': {'id': '24592223',\n",
" 'firstName': 'Becca',\n",
" 'lastName': 'McArthur',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/24592223-RAW2UYM0GIB1U40K.jpg'}},\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': False,\n",
" 'url': '/becca_mcarthur/list/manhattan-haunts',\n",
" 'canonicalUrl': 'https://foursquare.com/becca_mcarthur/list/manhattan-haunts',\n",
" 'createdAt': 1336094672,\n",
" 'updatedAt': 1380845377,\n",
" 'photo': {'id': '4e8cc9461081e3b3544e12e5',\n",
" 'createdAt': 1317849414,\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/0NLVU2HC1JF4DXIMKWUFW3QBUT31DC11EFNYYHMJG3NDWAPS.jpg',\n",
" 'width': 492,\n",
" 'height': 330,\n",
" 'user': {'id': '742542',\n",
" 'firstName': 'Time Out New York',\n",
" 'gender': 'none',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/XXHKCBSQHBORZNSR.jpg'},\n",
" 'type': 'page'},\n",
" 'visibility': 'public'},\n",
" 'followers': {'count': 22},\n",
" 'listItems': {'count': 187,\n",
" 'items': [{'id': 'v4fa862b3e4b0ebff2f749f06',\n",
" 'createdAt': 1342934485}]}},\n",
" {'id': '4fae817be4b085f6b2a74d19',\n",
" 'name': 'USA NYC MAN FiDi',\n",
" 'description': 'Where to go for decent eats in the restaurant wasteland of Downtown NYC aka FiDi, along with Tribeca & Battery Park City.',\n",
" 'type': 'others',\n",
" 'user': {'id': '12113441',\n",
" 'firstName': 'Kino',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/12113441-K5HTHFLU2MUCM0CM.jpg'}},\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': False,\n",
" 'url': '/kinosfault/list/usa-nyc-man-fidi',\n",
" 'canonicalUrl': 'https://foursquare.com/kinosfault/list/usa-nyc-man-fidi',\n",
" 'createdAt': 1336836475,\n",
" 'updatedAt': 1536019882,\n",
" 'photo': {'id': '55984992498e13ba75e353bb',\n",
" 'createdAt': 1436043666,\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/12113441_iOa6Uh-Xi8bhj2-gpzkkw8MKiAIs7RmOcz_RM7m8ink.jpg',\n",
" 'width': 540,\n",
" 'height': 960,\n",
" 'user': {'id': '12113441',\n",
" 'firstName': 'Kino',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/12113441-K5HTHFLU2MUCM0CM.jpg'}},\n",
" 'visibility': 'public'},\n",
" 'followers': {'count': 20},\n",
" 'listItems': {'count': 272,\n",
" 'items': [{'id': 'v4fa862b3e4b0ebff2f749f06',\n",
" 'createdAt': 1373909433}]}},\n",
" {'id': '4fddeff0e4b0e078037ac0d3',\n",
" 'name': 'NYC Resturants',\n",
" 'description': '',\n",
" 'type': 'others',\n",
" 'user': {'id': '21563126',\n",
" 'firstName': 'Richard',\n",
" 'lastName': 'Revilla',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/21563126_v05J1KPw_SVj6Ehq9g8B9jeAGjFUMsU5QGl-NZ8inUQ7pKQm5bKplW37EmR7jS2A7GYPBBAtl.jpg'}},\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': True,\n",
" 'url': '/rickr7/list/nyc-resturants',\n",
" 'canonicalUrl': 'https://foursquare.com/rickr7/list/nyc-resturants',\n",
" 'createdAt': 1339944944,\n",
" 'updatedAt': 1550795902,\n",
" 'photo': {'id': '5072dd13e4b09145cdf782d1',\n",
" 'createdAt': 1349704979,\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/208205_fGh2OuAZ9qJ4agbAA5wMVNOSIm9kNUlRtNwj1N-adqg.jpg',\n",
" 'width': 800,\n",
" 'height': 800,\n",
" 'user': {'id': '208205',\n",
" 'firstName': 'Thalia',\n",
" 'lastName': 'K',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/SNOOLCAW2AG04ZKD.jpg'}},\n",
" 'visibility': 'public'},\n",
" 'followers': {'count': 12},\n",
" 'listItems': {'count': 194,\n",
" 'items': [{'id': 't54ed3b13498e857fd7dbb6fc',\n",
" 'createdAt': 1514680908}]}},\n",
" {'id': '5266c68a498e7c667807fe09',\n",
" 'name': 'Foodie Love in NY - 02',\n",
" 'description': '',\n",
" 'type': 'others',\n",
" 'user': {'id': '547977',\n",
" 'firstName': 'WiLL',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/-Q5NYGDMFDMOITQRR.jpg'}},\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': False,\n",
" 'url': '/sweetiewill/list/foodie-love-in-ny--02',\n",
" 'canonicalUrl': 'https://foursquare.com/sweetiewill/list/foodie-love-in-ny--02',\n",
" 'createdAt': 1382467210,\n",
" 'updatedAt': 1391995585,\n",
" 'followers': {'count': 7},\n",
" 'listItems': {'count': 200,\n",
" 'items': [{'id': 'v4fa862b3e4b0ebff2f749f06',\n",
" 'createdAt': 1386809936}]}}]}]},\n",
" 'hours': {'status': 'Closed until 11:30 AM tomorrow',\n",
" 'richStatus': {'entities': [], 'text': 'Closed until 11:30 AM tomorrow'},\n",
" 'isOpen': False,\n",
" 'isLocalHoliday': False,\n",
" 'dayData': [],\n",
" 'timeframes': [{'days': 'Mon–Wed, Sun',\n",
" 'includesToday': True,\n",
" 'open': [{'renderedTime': '11:30 AM–11:00 PM'}],\n",
" 'segments': []},\n",
" {'days': 'Thu–Sat',\n",
" 'open': [{'renderedTime': '11:30 AM–Midnight'}],\n",
" 'segments': []}]},\n",
" 'popular': {'isOpen': False,\n",
" 'isLocalHoliday': False,\n",
" 'timeframes': [{'days': 'Today',\n",
" 'includesToday': True,\n",
" 'open': [{'renderedTime': 'Noon–2:00 PM'},\n",
" {'renderedTime': '6:00 PM–8:00 PM'}],\n",
" 'segments': []},\n",
" {'days': 'Tue–Thu',\n",
" 'open': [{'renderedTime': 'Noon–2:00 PM'},\n",
" {'renderedTime': '5:00 PM–10:00 PM'}],\n",
" 'segments': []},\n",
" {'days': 'Fri',\n",
" 'open': [{'renderedTime': 'Noon–3:00 PM'},\n",
" {'renderedTime': '5:00 PM–11:00 PM'}],\n",
" 'segments': []},\n",
" {'days': 'Sat',\n",
" 'open': [{'renderedTime': 'Noon–11:00 PM'}],\n",
" 'segments': []},\n",
" {'days': 'Sun',\n",
" 'open': [{'renderedTime': 'Noon–3:00 PM'},\n",
" {'renderedTime': '5:00 PM–8:00 PM'}],\n",
" 'segments': []}]},\n",
" 'pageUpdates': {'count': 0, 'items': []},\n",
" 'inbox': {'count': 0, 'items': []},\n",
" 'attributes': {'groups': [{'type': 'price',\n",
" 'name': 'Price',\n",
" 'summary': '$$',\n",
" 'count': 1,\n",
" 'items': [{'displayName': 'Price', 'displayValue': '$$', 'priceTier': 2}]},\n",
" {'type': 'payments',\n",
" 'name': 'Credit Cards',\n",
" 'summary': 'Credit Cards',\n",
" 'count': 7,\n",
" 'items': [{'displayName': 'Credit Cards',\n",
" 'displayValue': 'Yes (incl. American Express)'}]},\n",
" {'type': 'outdoorSeating',\n",
" 'name': 'Outdoor Seating',\n",
" 'summary': 'Outdoor Seating',\n",
" 'count': 1,\n",
" 'items': [{'displayName': 'Outdoor Seating', 'displayValue': 'Yes'}]},\n",
" {'type': 'serves',\n",
" 'name': 'Menus',\n",
" 'summary': 'Happy Hour, Brunch & more',\n",
" 'count': 8,\n",
" 'items': [{'displayName': 'Brunch', 'displayValue': 'Brunch'},\n",
" {'displayName': 'Lunch', 'displayValue': 'Lunch'},\n",
" {'displayName': 'Dinner', 'displayValue': 'Dinner'},\n",
" {'displayName': 'Happy Hour', 'displayValue': 'Happy Hour'}]},\n",
" {'type': 'drinks',\n",
" 'name': 'Drinks',\n",
" 'summary': 'Beer, Wine & Cocktails',\n",
" 'count': 5,\n",
" 'items': [{'displayName': 'Beer', 'displayValue': 'Beer'},\n",
" {'displayName': 'Wine', 'displayValue': 'Wine'},\n",
" {'displayName': 'Cocktails', 'displayValue': 'Cocktails'}]},\n",
" {'type': 'diningOptions',\n",
" 'name': 'Dining Options',\n",
" 'summary': 'Delivery',\n",
" 'count': 5,\n",
" 'items': [{'displayName': 'Delivery', 'displayValue': 'Delivery'}]}]},\n",
" 'bestPhoto': {'id': '4fad980de4b091b4626c3633',\n",
" 'createdAt': 1336776717,\n",
" 'source': {'name': 'Foursquare for Android',\n",
" 'url': 'https://foursquare.com/download/#/android'},\n",
" 'prefix': 'https://fastly.4sqi.net/img/general/',\n",
" 'suffix': '/ya1iQFI7pLjuIJp1PGDKlrZS3OJdHCF7tpILMmjv_2w.jpg',\n",
" 'width': 480,\n",
" 'height': 640,\n",
" 'visibility': 'public'},\n",
" 'colors': {'highlightColor': {'photoId': '4fad980de4b091b4626c3633',\n",
" 'value': -13619152},\n",
" 'highlightTextColor': {'photoId': '4fad980de4b091b4626c3633', 'value': -1},\n",
" 'algoVersion': 3}}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = requests.get(url).json()\n",
"print(result['response']['venue'].keys())\n",
"result['response']['venue']"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### B. Get the venue's overall rating"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7.1\n"
]
}
],
"source": [
"try:\n",
" print(result['response']['venue']['rating'])\n",
"except:\n",
" print('This venue has not been rated yet.')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"That is not a very good rating. Let's check the rating of the second closest Italian restaurant."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This venue has not been rated yet.\n"
]
}
],
"source": [
"venue_id = '4f3232e219836c91c7bfde94' # ID of Conca Cucina Italian Restaurant\n",
"url = 'https://api.foursquare.com/v2/venues/{}?client_id={}&client_secret={}&v={}'.format(venue_id, CLIENT_ID, CLIENT_SECRET, VERSION)\n",
"\n",
"result = requests.get(url).json()\n",
"try:\n",
" print(result['response']['venue']['rating'])\n",
"except:\n",
" print('This venue has not been rated yet.')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Since this restaurant has no ratings, let's check the third restaurant."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7.9\n"
]
}
],
"source": [
"venue_id = '3fd66200f964a520f4e41ee3' # ID of Ecco\n",
"url = 'https://api.foursquare.com/v2/venues/{}?client_id={}&client_secret={}&v={}'.format(venue_id, CLIENT_ID, CLIENT_SECRET, VERSION)\n",
"\n",
"result = requests.get(url).json()\n",
"try:\n",
" print(result['response']['venue']['rating'])\n",
"except:\n",
" print('This venue has not been rated yet.')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Since this restaurant has a slightly better rating, let's explore it further."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### C. Get the number of tips"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"16"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result['response']['venue']['tips']['count']"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### D. Get the venue's tips\n",
"> `https://api.foursquare.com/v2/venues/`**VENUE_ID**`/tips?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&v=`**VERSION**`&limit=`**LIMIT**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Create URL and send GET request. Make sure to set limit to get all tips"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'meta': {'code': 200, 'requestId': '5c74c2c8db04f505a38385fb'},\n",
" 'response': {'tips': {'count': 16,\n",
" 'items': [{'id': '5ab1cb46c9a517174651d3fe',\n",
" 'createdAt': 1521601350,\n",
" 'text': 'A+ Italian food! Trust me on this: my mom’s side of the family is 100% Italian. I was born and bred to know good pasta when I see it, and Ecco is one of my all-time NYC favorites',\n",
" 'type': 'user',\n",
" 'canonicalUrl': 'https://foursquare.com/item/5ab1cb46c9a517174651d3fe',\n",
" 'lang': 'en',\n",
" 'likes': {'count': 0, 'groups': []},\n",
" 'logView': True,\n",
" 'agreeCount': 2,\n",
" 'disagreeCount': 0,\n",
" 'todo': {'count': 0},\n",
" 'user': {'id': '484542633',\n",
" 'firstName': 'Nick',\n",
" 'lastName': 'El-Tawil',\n",
" 'gender': 'male',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/484542633_mK2Yum7T_7Tn9fWpndidJsmw2Hof_6T5vJBKCHPLMK5OL-U5ZiJGj51iwBstcpDLYa3Zvhvis.jpg'}},\n",
" 'authorInteractionType': 'liked'},\n",
" {'id': '5247cb68498eeac13eb4c3e1',\n",
" 'createdAt': 1380436840,\n",
" 'text': 'Service was truly excellent- attentive, quick, & friendly. Food was equally amazing- particularly calamari and pollo alla scarpiello. The sauces were incredibly flavorful. Great wine list too! A+++',\n",
" 'type': 'user',\n",
" 'canonicalUrl': 'https://foursquare.com/item/5247cb68498eeac13eb4c3e1',\n",
" 'lang': 'en',\n",
" 'likes': {'count': 0, 'groups': []},\n",
" 'logView': True,\n",
" 'agreeCount': 0,\n",
" 'disagreeCount': 0,\n",
" 'todo': {'count': 0},\n",
" 'user': {'id': '25279241',\n",
" 'firstName': 'Nicole',\n",
" 'lastName': 'F',\n",
" 'gender': 'female',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/SDJDCS2XH2USIRK0.jpg'}}}]}}}"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"## Ecco Tips\n",
"limit = 15 # set limit to be greater than or equal to the total number of tips\n",
"url = 'https://api.foursquare.com/v2/venues/{}/tips?client_id={}&client_secret={}&v={}&limit={}'.format(venue_id, CLIENT_ID, CLIENT_SECRET, VERSION, limit)\n",
"\n",
"results = requests.get(url).json()\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Get tips and list of associated features"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['id', 'createdAt', 'text', 'type', 'canonicalUrl', 'lang', 'likes', 'logView', 'agreeCount', 'disagreeCount', 'todo', 'user', 'authorInteractionType'])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tips = results['response']['tips']['items']\n",
"\n",
"tip = results['response']['tips']['items'][0]\n",
"tip.keys()"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Format column width and display all tips"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>text</th>\n",
" <th>agreeCount</th>\n",
" <th>disagreeCount</th>\n",
" <th>id</th>\n",
" <th>user.firstName</th>\n",
" <th>user.lastName</th>\n",
" <th>user.gender</th>\n",
" <th>user.id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>A+ Italian food! Trust me on this: my mom’s side of the family is 100% Italian. I was born and bred to know good pasta when I see it, and Ecco is one of my all-time NYC favorites</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>5ab1cb46c9a517174651d3fe</td>\n",
" <td>Nick</td>\n",
" <td>El-Tawil</td>\n",
" <td>male</td>\n",
" <td>484542633</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Service was truly excellent- attentive, quick, &amp; friendly. Food was equally amazing- particularly calamari and pollo alla scarpiello. The sauces were incredibly flavorful. Great wine list too! A+++</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>5247cb68498eeac13eb4c3e1</td>\n",
" <td>Nicole</td>\n",
" <td>F</td>\n",
" <td>female</td>\n",
" <td>25279241</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" text \\\n",
"0 A+ Italian food! Trust me on this: my mom’s side of the family is 100% Italian. I was born and bred to know good pasta when I see it, and Ecco is one of my all-time NYC favorites \n",
"1 Service was truly excellent- attentive, quick, & friendly. Food was equally amazing- particularly calamari and pollo alla scarpiello. The sauces were incredibly flavorful. Great wine list too! A+++ \n",
"\n",
" agreeCount disagreeCount id user.firstName \\\n",
"0 2 0 5ab1cb46c9a517174651d3fe Nick \n",
"1 0 0 5247cb68498eeac13eb4c3e1 Nicole \n",
"\n",
" user.lastName user.gender user.id \n",
"0 El-Tawil male 484542633 \n",
"1 F female 25279241 "
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.set_option('display.max_colwidth', -1)\n",
"\n",
"tips_df = json_normalize(tips) # json normalize tips\n",
"\n",
"# columns to keep\n",
"filtered_columns = ['text', 'agreeCount', 'disagreeCount', 'id', 'user.firstName', 'user.lastName', 'user.gender', 'user.id']\n",
"tips_filtered = tips_df.loc[:, filtered_columns]\n",
"\n",
"# display tips\n",
"tips_filtered"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Now remember that because we are using a personal developer account, then we can access only 2 of the restaurant's tips, instead of all 15 tips."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item3\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## 3. Search a Foursquare User\n",
"> `https://api.foursquare.com/v2/users/`**USER_ID**`?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&v=`**VERSION**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Define URL, send GET request and display features associated with user"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['id', 'firstName', 'lastName', 'gender', 'canonicalUrl', 'photo', 'friends', 'tips', 'homeCity', 'bio', 'contact', 'photos', 'type', 'mayorships', 'checkins', 'lists', 'lenses'])"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"user_id = '484542633' # user ID with most agree counts and complete profile\n",
"\n",
"url = 'https://api.foursquare.com/v2/users/{}?client_id={}&client_secret={}&v={}'.format(user_id, CLIENT_ID, CLIENT_SECRET, VERSION) # define URL\n",
"\n",
"# send GET request\n",
"results = requests.get(url).json()\n",
"user_data = results['response']['user']\n",
"\n",
"# display features associated with user\n",
"user_data.keys()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"First Name: Nick\n",
"Last Name: El-Tawil\n",
"Home City: New York, NY\n"
]
}
],
"source": [
"print('First Name: ' + user_data['firstName'])\n",
"print('Last Name: ' + user_data['lastName'])\n",
"print('Home City: ' + user_data['homeCity'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### How many tips has this user submitted?"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'count': 241}"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"user_data['tips']"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Wow! So it turns out that Nick is a very active Foursquare user, with more than 250 tips."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Get User's tips"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>text</th>\n",
" <th>agreeCount</th>\n",
" <th>disagreeCount</th>\n",
" <th>id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>The best! I’m especially fond of the salmon burger, but I’ve had half of the menu and never been disappointed. There’s a reason this place is well known even outside of the Village!</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5aec594b1f7440002c138612</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>I used to down a pint of chocolate like it was nothing back when I was bulking. Highly recommended!</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5accc9f66fa81f196724807b</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>They serve coffee!!!!!!</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5accc98c0313204c9d7ec157</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>I’m a fan. In fact, I’m such a big fan, I want Taim to hire me to be their spokesman. Kind of like the Arabic Jared Fogle - but without the kid stuff.</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5accbf033abcaf09a24612a0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>The linguine with clams is on point 👌</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5accbe3a911fc423730f3ed3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Great for a quick, cheap lunch! Shorter lines than Chipotle too👌</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5acbecb86fa81f1967e019b0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Quick, cheap lunch that tastes good! Way shorter line than Chipotle, too.</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5acbec70a0215b732e264fe8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>You’re not a real New Yorker until you’ve shame-ordered Insomnia Cookies for delivery at 3am</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5acbbd4eb1538e45373b07f5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Good for you yet still tasty! Clean green protein is my go-to after I hit the gym 💪</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>5acbbcda01235808d5d6dc75</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>Coffee game on point</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5acbbb1501235808d5d6525e</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>This is the dive bar to end all other dive bars. Go here if you like cheap drinks! 🥃</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5ab576abea1e444f2abb051e</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Burger game strong 💪</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5ab575fb6bdee65f759da8c1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Great burgers &amp; fries! Also, this place is exactly what it’s like when you go to a bar in the Southwest. Source: I’m from Arizona.</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>5ab5575d73fe2516ad8f363b</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>That guy looks familiar...</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5ab5299635f98312029a53b7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Açaí bowl + peanut butter + whey protein = 💪💪💪</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>5ab42db53c858d64af2688a4</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" text \\\n",
"0 The best! I’m especially fond of the salmon burger, but I’ve had half of the menu and never been disappointed. There’s a reason this place is well known even outside of the Village! \n",
"1 I used to down a pint of chocolate like it was nothing back when I was bulking. Highly recommended! \n",
"2 They serve coffee!!!!!! \n",
"3 I’m a fan. In fact, I’m such a big fan, I want Taim to hire me to be their spokesman. Kind of like the Arabic Jared Fogle - but without the kid stuff. \n",
"4 The linguine with clams is on point 👌 \n",
"5 Great for a quick, cheap lunch! Shorter lines than Chipotle too👌 \n",
"6 Quick, cheap lunch that tastes good! Way shorter line than Chipotle, too. \n",
"7 You’re not a real New Yorker until you’ve shame-ordered Insomnia Cookies for delivery at 3am \n",
"8 Good for you yet still tasty! Clean green protein is my go-to after I hit the gym 💪 \n",
"9 Coffee game on point \n",
"10 This is the dive bar to end all other dive bars. Go here if you like cheap drinks! 🥃 \n",
"11 Burger game strong 💪 \n",
"12 Great burgers & fries! Also, this place is exactly what it’s like when you go to a bar in the Southwest. Source: I’m from Arizona. \n",
"13 That guy looks familiar... \n",
"14 Açaí bowl + peanut butter + whey protein = 💪💪💪 \n",
"\n",
" agreeCount disagreeCount id \n",
"0 1 0 5aec594b1f7440002c138612 \n",
"1 1 0 5accc9f66fa81f196724807b \n",
"2 1 0 5accc98c0313204c9d7ec157 \n",
"3 1 0 5accbf033abcaf09a24612a0 \n",
"4 1 0 5accbe3a911fc423730f3ed3 \n",
"5 1 0 5acbecb86fa81f1967e019b0 \n",
"6 1 0 5acbec70a0215b732e264fe8 \n",
"7 1 0 5acbbd4eb1538e45373b07f5 \n",
"8 2 0 5acbbcda01235808d5d6dc75 \n",
"9 1 0 5acbbb1501235808d5d6525e \n",
"10 1 0 5ab576abea1e444f2abb051e \n",
"11 1 0 5ab575fb6bdee65f759da8c1 \n",
"12 2 0 5ab5575d73fe2516ad8f363b \n",
"13 1 0 5ab5299635f98312029a53b7 \n",
"14 1 0 5ab42db53c858d64af2688a4 "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# define tips URL\n",
"url = 'https://api.foursquare.com/v2/users/{}/tips?client_id={}&client_secret={}&v={}&limit={}'.format(user_id, CLIENT_ID, CLIENT_SECRET, VERSION, limit)\n",
"\n",
"# send GET request and get user's tips\n",
"results = requests.get(url).json()\n",
"tips = results['response']['tips']['items']\n",
"\n",
"# format column width\n",
"pd.set_option('display.max_colwidth', -1)\n",
"\n",
"tips_df = json_normalize(tips)\n",
"\n",
"# filter columns\n",
"filtered_columns = ['text', 'agreeCount', 'disagreeCount', 'id']\n",
"tips_filtered = tips_df.loc[:, filtered_columns]\n",
"\n",
"# display user's tips\n",
"tips_filtered"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Let's get the venue for the tip with the greatest number of agree counts"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cowgirl\n",
"{'address': '519 Hudson St', 'crossStreet': 'at W 10th St', 'lat': 40.73373338282062, 'lng': -74.0062998849649, 'labeledLatLngs': [{'label': 'display', 'lat': 40.73373338282062, 'lng': -74.0062998849649}], 'postalCode': '10014', 'cc': 'US', 'city': 'New York', 'state': 'NY', 'country': 'United States', 'formattedAddress': ['519 Hudson St (at W 10th St)', 'New York, NY 10014', 'United States']}\n"
]
}
],
"source": [
"tip_id = '5ab5575d73fe2516ad8f363b' # tip id\n",
"\n",
"# define URL\n",
"url = 'http://api.foursquare.com/v2/tips/{}?client_id={}&client_secret={}&v={}'.format(tip_id, CLIENT_ID, CLIENT_SECRET, VERSION)\n",
"\n",
"# send GET Request and examine results\n",
"result = requests.get(url).json()\n",
"print(result['response']['tip']['venue']['name'])\n",
"print(result['response']['tip']['venue']['location'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Get User's friends"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"Empty DataFrame\n",
"Columns: []\n",
"Index: []"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"user_friends = json_normalize(user_data['friends']['groups'][0]['items'])\n",
"user_friends"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Interesting. Despite being very active, it turns out that Nick does not have any friends on Foursquare. This might definitely change in the future."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Retrieve the User's Profile Image"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"{'id': '484542633',\n",
" 'firstName': 'Nick',\n",
" 'lastName': 'El-Tawil',\n",
" 'gender': 'male',\n",
" 'canonicalUrl': 'https://foursquare.com/nickeltawil',\n",
" 'photo': {'prefix': 'https://fastly.4sqi.net/img/user/',\n",
" 'suffix': '/484542633_mK2Yum7T_7Tn9fWpndidJsmw2Hof_6T5vJBKCHPLMK5OL-U5ZiJGj51iwBstcpDLYa3Zvhvis.jpg'},\n",
" 'friends': {'count': 0,\n",
" 'groups': [{'type': 'others',\n",
" 'name': 'Other friends',\n",
" 'count': 0,\n",
" 'items': []}]},\n",
" 'tips': {'count': 241},\n",
" 'homeCity': 'New York, NY',\n",
" 'bio': 'https://www.tawil.team/nick-el-tawil/',\n",
" 'contact': {},\n",
" 'photos': {'count': 0, 'items': []},\n",
" 'type': 'user',\n",
" 'mayorships': {'count': 0, 'items': []},\n",
" 'checkins': {'count': 1, 'items': []},\n",
" 'lists': {'count': 2,\n",
" 'groups': [{'type': 'created', 'count': 0, 'items': []},\n",
" {'type': 'followed', 'count': 0, 'items': []},\n",
" {'type': 'yours',\n",
" 'count': 2,\n",
" 'items': [{'id': '484542633/todos',\n",
" 'name': \"Nick's Saved Places\",\n",
" 'description': '',\n",
" 'type': 'todos',\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': False,\n",
" 'url': '/nickeltawil/list/todos',\n",
" 'canonicalUrl': 'https://foursquare.com/nickeltawil/list/todos',\n",
" 'listItems': {'count': 0}},\n",
" {'id': '484542633/venuelikes',\n",
" 'name': 'Nick’s Liked Places',\n",
" 'description': '',\n",
" 'type': 'likes',\n",
" 'editable': False,\n",
" 'public': True,\n",
" 'collaborative': False,\n",
" 'url': '/nickeltawil/list/venuelikes',\n",
" 'canonicalUrl': 'https://foursquare.com/nickeltawil/list/venuelikes',\n",
" 'listItems': {'count': 0}}]}]},\n",
" 'lenses': []}"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"user_data"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<img src=\"https://igx.4sqi.net/img/user/300x300/484542633_mK2Yum7T_7Tn9fWpndidJsmw2Hof_6T5vJBKCHPLMK5OL-U5ZiJGj51iwBstcpDLYa3Zvhvis.jpg\"/>"
],
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 1. grab prefix of photo\n",
"# 2. grab suffix of photo\n",
"# 3. concatenate them using the image size \n",
"Image(url='https://igx.4sqi.net/img/user/300x300/484542633_mK2Yum7T_7Tn9fWpndidJsmw2Hof_6T5vJBKCHPLMK5OL-U5ZiJGj51iwBstcpDLYa3Zvhvis.jpg')"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item4\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## 4. Explore a location\n",
"> `https://api.foursquare.com/v2/venues/`**explore**`?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&ll=`**LATITUDE**`,`**LONGITUDE**`&v=`**VERSION**`&limit=`**LIMIT**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### So, you just finished your gourmet dish at Ecco, and are just curious about the popular spots around the restaurant. In order to explore the area, let's start by getting the latitude and longitude values of Ecco Restaurant."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"button": false,
"collapsed": true,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"latitude = 40.715337\n",
"longitude = -74.008848"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Define URL"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"'https://api.foursquare.com/v2/venues/explore?client_id=your-client-ID&client_secret=your-client-secret&ll=40.7149555,-74.0153365&v=20180604&radius=500&limit=30'"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"url = 'https://api.foursquare.com/v2/venues/explore?client_id={}&client_secret={}&ll={},{}&v={}&radius={}&limit={}'.format(CLIENT_ID, CLIENT_SECRET, latitude, longitude, VERSION, radius, LIMIT)\n",
"url"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Send GET request and examine results"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"button": false,
"collapsed": true,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"import requests"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"'There are 30 around Ecco restaurant.'"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results = requests.get(url).json()\n",
"'There are {} around Ecco restaurant.'.format(len(results['response']['groups'][0]['items']))"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Get relevant part of JSON"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'reasons': {'count': 0,\n",
" 'items': [{'summary': 'This spot is popular',\n",
" 'type': 'general',\n",
" 'reasonName': 'globalInteractionReason'}]},\n",
" 'venue': {'id': '4af5d65ff964a52091fd21e3',\n",
" 'name': 'Korin',\n",
" 'location': {'address': '57 Warren St',\n",
" 'crossStreet': 'Church St',\n",
" 'lat': 40.71482437714839,\n",
" 'lng': -74.00940425461492,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 40.71482437714839,\n",
" 'lng': -74.00940425461492}],\n",
" 'distance': 73,\n",
" 'postalCode': '10007',\n",
" 'cc': 'US',\n",
" 'neighborhood': 'Tribeca',\n",
" 'city': 'New York',\n",
" 'state': 'NY',\n",
" 'country': 'United States',\n",
" 'formattedAddress': ['57 Warren St (Church St)',\n",
" 'New York, NY 10007',\n",
" 'United States']},\n",
" 'categories': [{'id': '4bf58dd8d48988d1f8941735',\n",
" 'name': 'Furniture / Home Store',\n",
" 'pluralName': 'Furniture / Home Stores',\n",
" 'shortName': 'Furniture / Home',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/shops/furniture_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'photos': {'count': 0, 'groups': []},\n",
" 'venuePage': {'id': '33104775'}},\n",
" 'referralId': 'e-0-4af5d65ff964a52091fd21e3-0'}"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"items = results['response']['groups'][0]['items']\n",
"items[0]"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Process JSON and convert it to a clean dataframe"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>name</th>\n",
" <th>categories</th>\n",
" <th>address</th>\n",
" <th>cc</th>\n",
" <th>city</th>\n",
" <th>country</th>\n",
" <th>crossStreet</th>\n",
" <th>distance</th>\n",
" <th>formattedAddress</th>\n",
" <th>labeledLatLngs</th>\n",
" <th>lat</th>\n",
" <th>lng</th>\n",
" <th>neighborhood</th>\n",
" <th>postalCode</th>\n",
" <th>state</th>\n",
" <th>id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Korin</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>57 Warren St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>Church St</td>\n",
" <td>73</td>\n",
" <td>[57 Warren St (Church St), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71482437714839, 'lng': -74.00940425461492}]</td>\n",
" <td>40.714824</td>\n",
" <td>-74.009404</td>\n",
" <td>Tribeca</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>4af5d65ff964a52091fd21e3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Chambers Street Wines</td>\n",
" <td>Wine Shop</td>\n",
" <td>148 Chambers St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>btwn West Broadway &amp; Hudson St</td>\n",
" <td>88</td>\n",
" <td>[148 Chambers St (btwn West Broadway &amp; Hudson St), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.715773063928374, 'lng': -74.00971823312332}]</td>\n",
" <td>40.715773</td>\n",
" <td>-74.009718</td>\n",
" <td>NaN</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>4adcf23cf964a520cc6221e3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Takahachi Bakery</td>\n",
" <td>Bakery</td>\n",
" <td>25 Murray St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>at Church St</td>\n",
" <td>187</td>\n",
" <td>[25 Murray St (at Church St), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.713652845301894, 'lng': -74.0088038953017}]</td>\n",
" <td>40.713653</td>\n",
" <td>-74.008804</td>\n",
" <td>NaN</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>4c154c9a77cea593c401d260</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Takahachi</td>\n",
" <td>Sushi Restaurant</td>\n",
" <td>145 Duane St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>btwn W Broadway &amp; Church St</td>\n",
" <td>146</td>\n",
" <td>[145 Duane St (btwn W Broadway &amp; Church St), New York, NY 10013, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71652647412374, 'lng': -74.00810108466207}]</td>\n",
" <td>40.716526</td>\n",
" <td>-74.008101</td>\n",
" <td>NaN</td>\n",
" <td>10013</td>\n",
" <td>NY</td>\n",
" <td>4a8f2f39f964a520471420e3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Juice Press</td>\n",
" <td>Vegetarian / Vegan Restaurant</td>\n",
" <td>83 Murray St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>btwn Greenwich St &amp; W Broadway</td>\n",
" <td>202</td>\n",
" <td>[83 Murray St (btwn Greenwich St &amp; W Broadway), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71478769908051, 'lng': -74.0111317502157}]</td>\n",
" <td>40.714788</td>\n",
" <td>-74.011132</td>\n",
" <td>NaN</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>54148bc6498ea7bb8c05b70a</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Mulberry &amp; Vine</td>\n",
" <td>Café</td>\n",
" <td>73 Warren St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>btwn W Broadway &amp; Greenwich St</td>\n",
" <td>117</td>\n",
" <td>[73 Warren St (btwn W Broadway &amp; Greenwich St), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71517693966315, 'lng': -74.01022747778285}]</td>\n",
" <td>40.715177</td>\n",
" <td>-74.010227</td>\n",
" <td>NaN</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>5171b5cc011cef9833bbb787</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Nish Nūsh</td>\n",
" <td>Falafel Restaurant</td>\n",
" <td>88 Reade St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>at Church St</td>\n",
" <td>97</td>\n",
" <td>[88 Reade St (at Church St), New York, NY 10013, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71553710116416, 'lng': -74.00772452925565}]</td>\n",
" <td>40.715537</td>\n",
" <td>-74.007725</td>\n",
" <td>NaN</td>\n",
" <td>10013</td>\n",
" <td>NY</td>\n",
" <td>50ba9119e4b071a4bae6dc10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Equinox Tribeca</td>\n",
" <td>Gym</td>\n",
" <td>54 Murray Street</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>at W Broadway</td>\n",
" <td>154</td>\n",
" <td>[54 Murray Street (at W Broadway), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71409860726041, 'lng': -74.0096857179283}]</td>\n",
" <td>40.714099</td>\n",
" <td>-74.009686</td>\n",
" <td>NaN</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>4a6e331af964a52031d41fe3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Ten Over Ten</td>\n",
" <td>Nail Salon</td>\n",
" <td>112 Reade St</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>NaN</td>\n",
" <td>68</td>\n",
" <td>[112 Reade St, New York, NY 10013, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.71594125566931, 'lng': -74.00872053564494}]</td>\n",
" <td>40.715941</td>\n",
" <td>-74.008721</td>\n",
" <td>NaN</td>\n",
" <td>10013</td>\n",
" <td>NY</td>\n",
" <td>4ce2a27cd58c60fc0fa1a76f</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>Whole Foods Market</td>\n",
" <td>Grocery Store</td>\n",
" <td>270 Greenwich Street</td>\n",
" <td>US</td>\n",
" <td>New York</td>\n",
" <td>United States</td>\n",
" <td>at Warren St</td>\n",
" <td>214</td>\n",
" <td>[270 Greenwich Street (at Warren St), New York, NY 10007, United States]</td>\n",
" <td>[{'label': 'display', 'lat': 40.715579155420606, 'lng': -74.01136823958119}]</td>\n",
" <td>40.715579</td>\n",
" <td>-74.011368</td>\n",
" <td>Tribeca</td>\n",
" <td>10007</td>\n",
" <td>NY</td>\n",
" <td>49bc3b0af964a52020541fe3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" name categories address \\\n",
"0 Korin Furniture / Home Store 57 Warren St \n",
"1 Chambers Street Wines Wine Shop 148 Chambers St \n",
"2 Takahachi Bakery Bakery 25 Murray St \n",
"3 Takahachi Sushi Restaurant 145 Duane St \n",
"4 Juice Press Vegetarian / Vegan Restaurant 83 Murray St \n",
"5 Mulberry & Vine Café 73 Warren St \n",
"6 Nish Nūsh Falafel Restaurant 88 Reade St \n",
"7 Equinox Tribeca Gym 54 Murray Street \n",
"8 Ten Over Ten Nail Salon 112 Reade St \n",
"9 Whole Foods Market Grocery Store 270 Greenwich Street \n",
"\n",
" cc city country crossStreet distance \\\n",
"0 US New York United States Church St 73 \n",
"1 US New York United States btwn West Broadway & Hudson St 88 \n",
"2 US New York United States at Church St 187 \n",
"3 US New York United States btwn W Broadway & Church St 146 \n",
"4 US New York United States btwn Greenwich St & W Broadway 202 \n",
"5 US New York United States btwn W Broadway & Greenwich St 117 \n",
"6 US New York United States at Church St 97 \n",
"7 US New York United States at W Broadway 154 \n",
"8 US New York United States NaN 68 \n",
"9 US New York United States at Warren St 214 \n",
"\n",
" formattedAddress \\\n",
"0 [57 Warren St (Church St), New York, NY 10007, United States] \n",
"1 [148 Chambers St (btwn West Broadway & Hudson St), New York, NY 10007, United States] \n",
"2 [25 Murray St (at Church St), New York, NY 10007, United States] \n",
"3 [145 Duane St (btwn W Broadway & Church St), New York, NY 10013, United States] \n",
"4 [83 Murray St (btwn Greenwich St & W Broadway), New York, NY 10007, United States] \n",
"5 [73 Warren St (btwn W Broadway & Greenwich St), New York, NY 10007, United States] \n",
"6 [88 Reade St (at Church St), New York, NY 10013, United States] \n",
"7 [54 Murray Street (at W Broadway), New York, NY 10007, United States] \n",
"8 [112 Reade St, New York, NY 10013, United States] \n",
"9 [270 Greenwich Street (at Warren St), New York, NY 10007, United States] \n",
"\n",
" labeledLatLngs \\\n",
"0 [{'label': 'display', 'lat': 40.71482437714839, 'lng': -74.00940425461492}] \n",
"1 [{'label': 'display', 'lat': 40.715773063928374, 'lng': -74.00971823312332}] \n",
"2 [{'label': 'display', 'lat': 40.713652845301894, 'lng': -74.0088038953017}] \n",
"3 [{'label': 'display', 'lat': 40.71652647412374, 'lng': -74.00810108466207}] \n",
"4 [{'label': 'display', 'lat': 40.71478769908051, 'lng': -74.0111317502157}] \n",
"5 [{'label': 'display', 'lat': 40.71517693966315, 'lng': -74.01022747778285}] \n",
"6 [{'label': 'display', 'lat': 40.71553710116416, 'lng': -74.00772452925565}] \n",
"7 [{'label': 'display', 'lat': 40.71409860726041, 'lng': -74.0096857179283}] \n",
"8 [{'label': 'display', 'lat': 40.71594125566931, 'lng': -74.00872053564494}] \n",
"9 [{'label': 'display', 'lat': 40.715579155420606, 'lng': -74.01136823958119}] \n",
"\n",
" lat lng neighborhood postalCode state \\\n",
"0 40.714824 -74.009404 Tribeca 10007 NY \n",
"1 40.715773 -74.009718 NaN 10007 NY \n",
"2 40.713653 -74.008804 NaN 10007 NY \n",
"3 40.716526 -74.008101 NaN 10013 NY \n",
"4 40.714788 -74.011132 NaN 10007 NY \n",
"5 40.715177 -74.010227 NaN 10007 NY \n",
"6 40.715537 -74.007725 NaN 10013 NY \n",
"7 40.714099 -74.009686 NaN 10007 NY \n",
"8 40.715941 -74.008721 NaN 10013 NY \n",
"9 40.715579 -74.011368 Tribeca 10007 NY \n",
"\n",
" id \n",
"0 4af5d65ff964a52091fd21e3 \n",
"1 4adcf23cf964a520cc6221e3 \n",
"2 4c154c9a77cea593c401d260 \n",
"3 4a8f2f39f964a520471420e3 \n",
"4 54148bc6498ea7bb8c05b70a \n",
"5 5171b5cc011cef9833bbb787 \n",
"6 50ba9119e4b071a4bae6dc10 \n",
"7 4a6e331af964a52031d41fe3 \n",
"8 4ce2a27cd58c60fc0fa1a76f \n",
"9 49bc3b0af964a52020541fe3 "
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dataframe = json_normalize(items) # flatten JSON\n",
"\n",
"# filter columns\n",
"filtered_columns = ['venue.name', 'venue.categories'] + [col for col in dataframe.columns if col.startswith('venue.location.')] + ['venue.id']\n",
"dataframe_filtered = dataframe.loc[:, filtered_columns]\n",
"\n",
"# filter the category for each row\n",
"dataframe_filtered['venue.categories'] = dataframe_filtered.apply(get_category_type, axis=1)\n",
"\n",
"# clean columns\n",
"dataframe_filtered.columns = [col.split('.')[-1] for col in dataframe_filtered.columns]\n",
"\n",
"dataframe_filtered.head(10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Let's visualize these items on the map around our location"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2IiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNiA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDAuNzE1MzM3LC03NC4wMDg4NDhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyX2JjZmVmZGVlNzU4OTRkNTg5MmU5MWUyMjY1YzQzMzYyID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMmFkNzEwMzY2MTA0YTQ1ODE5Y2UyNjU3NjljOWE3MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTMzNywtNzQuMDA4ODQ4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogMTAsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODljYTY0NTQxYzA4NDFiN2E2MDA4NmJhODhmZTJmNTcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDQ0NzQ3NDhkZWU0NDlhOGIwYzk0Y2I3MDQ3ZTkwYzggPSAkKCc8ZGl2IGlkPSJodG1sXzA0NDc0NzQ4ZGVlNDQ5YThiMGM5NGNiNzA0N2U5MGM4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5FY2NvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84OWNhNjQ1NDFjMDg0MWI3YTYwMDg2YmE4OGZlMmY1Ny5zZXRDb250ZW50KGh0bWxfMDQ0NzQ3NDhkZWU0NDlhOGIwYzk0Y2I3MDQ3ZTkwYzgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTJhZDcxMDM2NjEwNGE0NTgxOWNlMjY1NzY5YzlhNzMuYmluZFBvcHVwKHBvcHVwXzg5Y2E2NDU0MWMwODQxYjdhNjAwODZiYTg4ZmUyZjU3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JjZDUyZDkxNjlhMTRiNjc4ZGZhZjBiYjc0MjI4Mzg2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0ODI0Mzc3MTQ4MzksLTc0LjAwOTQwNDI1NDYxNDkyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzBkOGQxMmFhNDYzNzQ5MjRhOTRkMzRhMGI1NTJjOWNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg4OTk4OTY0OTcwYzQxMmE4MDliZGMyOTYyNzYzNDU1ID0gJCgnPGRpdiBpZD0iaHRtbF84ODk5ODk2NDk3MGM0MTJhODA5YmRjMjk2Mjc2MzQ1NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RnVybml0dXJlIC8gSG9tZSBTdG9yZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGQ4ZDEyYWE0NjM3NDkyNGE5NGQzNGEwYjU1MmM5Y2Quc2V0Q29udGVudChodG1sXzg4OTk4OTY0OTcwYzQxMmE4MDliZGMyOTYyNzYzNDU1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2JjZDUyZDkxNjlhMTRiNjc4ZGZhZjBiYjc0MjI4Mzg2LmJpbmRQb3B1cChwb3B1cF8wZDhkMTJhYTQ2Mzc0OTI0YTk0ZDM0YTBiNTUyYzljZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMDAwODUwMWY5NGY0ZjVkYWQ2ODY5YmY2NzA4YWZiOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTc3MzA2MzkyODM3NCwtNzQuMDA5NzE4MjMzMTIzMzJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGNmMTk4MTE1YTNhNDU4NGE3MGM5NTMyZDRmZjI1M2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmQwMjVjYThkZDI1NDM5MzhlYTY3Y2VlM2EwYjZiYTkgPSAkKCc8ZGl2IGlkPSJodG1sXzJkMDI1Y2E4ZGQyNTQzOTM4ZWE2N2NlZTNhMGI2YmE5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaW5lIFNob3A8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzhjZjE5ODExNWEzYTQ1ODRhNzBjOTUzMmQ0ZmYyNTNkLnNldENvbnRlbnQoaHRtbF8yZDAyNWNhOGRkMjU0MzkzOGVhNjdjZWUzYTBiNmJhOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jMDAwODUwMWY5NGY0ZjVkYWQ2ODY5YmY2NzA4YWZiOC5iaW5kUG9wdXAocG9wdXBfOGNmMTk4MTE1YTNhNDU4NGE3MGM5NTMyZDRmZjI1M2QpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTVmY2EwZTBjZDM1NDUwMjgxZjUwMzBlMGUzMjY2NWUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTM2NTI4NDUzMDE4OTQsLTc0LjAwODgwMzg5NTMwMTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTI2NDM2N2IzODg4NDlkNGE4NTQ0ZWVkOTdkZDZiYjMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDg0NDY3ZjU1N2UzNGUzMmFlM2QyYjRmZjk2YmIyY2UgPSAkKCc8ZGl2IGlkPSJodG1sXzQ4NDQ2N2Y1NTdlMzRlMzJhZTNkMmI0ZmY5NmJiMmNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CYWtlcnk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzkyNjQzNjdiMzg4ODQ5ZDRhODU0NGVlZDk3ZGQ2YmIzLnNldENvbnRlbnQoaHRtbF80ODQ0NjdmNTU3ZTM0ZTMyYWUzZDJiNGZmOTZiYjJjZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81NWZjYTBlMGNkMzU0NTAyODFmNTAzMGUwZTMyNjY1ZS5iaW5kUG9wdXAocG9wdXBfOTI2NDM2N2IzODg4NDlkNGE4NTQ0ZWVkOTdkZDZiYjMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGUzNzU4MTg4NzBiNGI3OWIxOTU4NGQ2YmUzZGRiN2QgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTY1MjY0NzQxMjM3NCwtNzQuMDA4MTAxMDg0NjYyMDddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWVkMmNmNTVmNzhjNDllYTk0N2JjZmRmODY4OTQ3OWQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjRmNGUxMjg1OGQ4NGY4ZWFlMzJhZDg5NTMxNDQ1MTAgPSAkKCc8ZGl2IGlkPSJodG1sXzI0ZjRlMTI4NThkODRmOGVhZTMyYWQ4OTUzMTQ0NTEwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdXNoaSBSZXN0YXVyYW50PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lZWQyY2Y1NWY3OGM0OWVhOTQ3YmNmZGY4Njg5NDc5ZC5zZXRDb250ZW50KGh0bWxfMjRmNGUxMjg1OGQ4NGY4ZWFlMzJhZDg5NTMxNDQ1MTApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOGUzNzU4MTg4NzBiNGI3OWIxOTU4NGQ2YmUzZGRiN2QuYmluZFBvcHVwKHBvcHVwX2VlZDJjZjU1Zjc4YzQ5ZWE5NDdiY2ZkZjg2ODk0NzlkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2VjZWNlN2Q1N2RhNDRkZjQ5Y2NmZTA1ZDE1ZTYzNjBkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0Nzg3Njk5MDgwNTEsLTc0LjAxMTEzMTc1MDIxNTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOWQ5NzZiOTdkNjMzNDhjMmJlNTg4ZGZkOTBlNjM0NTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzA4NGJhZGM0MDZjNGJmZDg5NTFjYjYwOWEyMzU1M2EgPSAkKCc8ZGl2IGlkPSJodG1sXzMwODRiYWRjNDA2YzRiZmQ4OTUxY2I2MDlhMjM1NTNhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5WZWdldGFyaWFuIC8gVmVnYW4gUmVzdGF1cmFudDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOWQ5NzZiOTdkNjMzNDhjMmJlNTg4ZGZkOTBlNjM0NTAuc2V0Q29udGVudChodG1sXzMwODRiYWRjNDA2YzRiZmQ4OTUxY2I2MDlhMjM1NTNhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2VjZWNlN2Q1N2RhNDRkZjQ5Y2NmZTA1ZDE1ZTYzNjBkLmJpbmRQb3B1cChwb3B1cF85ZDk3NmI5N2Q2MzM0OGMyYmU1ODhkZmQ5MGU2MzQ1MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MGFjNjFhMGE3ZWY0YTA5ODY1YTY4MDdiZDNlODgwMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTE3NjkzOTY2MzE1LC03NC4wMTAyMjc0Nzc3ODI4NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yN2RkYWY0YzY4ODM0ZWM2YjlmZDAxOWM2YmU3ZDlkOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85ZmE5YWQ0MThhMGU0ZmUxYTM2MTNhZmY4ZjZiMjE4OSA9ICQoJzxkaXYgaWQ9Imh0bWxfOWZhOWFkNDE4YTBlNGZlMWEzNjEzYWZmOGY2YjIxODkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhZsOpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yN2RkYWY0YzY4ODM0ZWM2YjlmZDAxOWM2YmU3ZDlkOS5zZXRDb250ZW50KGh0bWxfOWZhOWFkNDE4YTBlNGZlMWEzNjEzYWZmOGY2YjIxODkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTBhYzYxYTBhN2VmNGEwOTg2NWE2ODA3YmQzZTg4MDEuYmluZFBvcHVwKHBvcHVwXzI3ZGRhZjRjNjg4MzRlYzZiOWZkMDE5YzZiZTdkOWQ5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2FjZmM1NjhhODljMjRhMmE4NmM4OTc1NDQyYTg3Nzc2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE1NTM3MTAxMTY0MTYsLTc0LjAwNzcyNDUyOTI1NTY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNiM2E1NzJmMGRkZjQzZWZhYTEzYzQ5YWUyZTJjODY4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzEyMTA2N2MwYjA2YjRiMmNhNzA1MGFjNGJiNGVkZjBiID0gJCgnPGRpdiBpZD0iaHRtbF8xMjEwNjdjMGIwNmI0YjJjYTcwNTBhYzRiYjRlZGYwYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmFsYWZlbCBSZXN0YXVyYW50PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zYjNhNTcyZjBkZGY0M2VmYWExM2M0OWFlMmUyYzg2OC5zZXRDb250ZW50KGh0bWxfMTIxMDY3YzBiMDZiNGIyY2E3MDUwYWM0YmI0ZWRmMGIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWNmYzU2OGE4OWMyNGEyYTg2Yzg5NzU0NDJhODc3NzYuYmluZFBvcHVwKHBvcHVwXzNiM2E1NzJmMGRkZjQzZWZhYTEzYzQ5YWUyZTJjODY4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2VjN2M3NGZiODAzZDQ1NzM4MDk3MGI3ZDk1YzM0MTkwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0MDk4NjA3MjYwNDEsLTc0LjAwOTY4NTcxNzkyODNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmZhMTk1MTYwNGVlNDJlNGI4ZjYzM2M2OGY2M2RkM2YgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTlmMzY4ODE5Y2M5NDAyNTgyMGQ3MTE1MDcwMThmZTEgPSAkKCc8ZGl2IGlkPSJodG1sX2E5ZjM2ODgxOWNjOTQwMjU4MjBkNzExNTA3MDE4ZmUxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HeW08L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JmYTE5NTE2MDRlZTQyZTRiOGY2MzNjNjhmNjNkZDNmLnNldENvbnRlbnQoaHRtbF9hOWYzNjg4MTljYzk0MDI1ODIwZDcxMTUwNzAxOGZlMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lYzdjNzRmYjgwM2Q0NTczODA5NzBiN2Q5NWMzNDE5MC5iaW5kUG9wdXAocG9wdXBfYmZhMTk1MTYwNGVlNDJlNGI4ZjYzM2M2OGY2M2RkM2YpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWUxYjAyNmM0YjU2NGU4MWE0NWE3OTkxNTc2ZDIzNzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTU5NDEyNTU2NjkzMSwtNzQuMDA4NzIwNTM1NjQ0OTRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTQ3ZDA0NjBiMTY3NGY4Y2E5OWJjNGQ5ZDlkM2ZjYjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjMzMWVhZDFhMzg4NGE4M2I1OTA2MzZlNDM4NWFmYWEgPSAkKCc8ZGl2IGlkPSJodG1sX2YzMzFlYWQxYTM4ODRhODNiNTkwNjM2ZTQzODVhZmFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5OYWlsIFNhbG9uPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lNDdkMDQ2MGIxNjc0ZjhjYTk5YmM0ZDlkOWQzZmNiNS5zZXRDb250ZW50KGh0bWxfZjMzMWVhZDFhMzg4NGE4M2I1OTA2MzZlNDM4NWFmYWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMWUxYjAyNmM0YjU2NGU4MWE0NWE3OTkxNTc2ZDIzNzEuYmluZFBvcHVwKHBvcHVwX2U0N2QwNDYwYjE2NzRmOGNhOTliYzRkOWQ5ZDNmY2I1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzc5ZmJlOTgyMTgzODRhZDBiYWM2Njk1NjdlZDgzYTFlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE1NTc5MTU1NDIwNjA2LC03NC4wMTEzNjgyMzk1ODExOV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mZjExY2VkMWFiMTU0YzRlYjcxZmZmYTVjMWQxNjkxMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84OTNhZDkyYjZmZTk0OGY2YmRmODRhNTVhZTkyNjQ5NCA9ICQoJzxkaXYgaWQ9Imh0bWxfODkzYWQ5MmI2ZmU5NDhmNmJkZjg0YTU1YWU5MjY0OTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdyb2NlcnkgU3RvcmU8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZmMTFjZWQxYWIxNTRjNGViNzFmZmZhNWMxZDE2OTEyLnNldENvbnRlbnQoaHRtbF84OTNhZDkyYjZmZTk0OGY2YmRmODRhNTVhZTkyNjQ5NCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83OWZiZTk4MjE4Mzg0YWQwYmFjNjY5NTY3ZWQ4M2ExZS5iaW5kUG9wdXAocG9wdXBfZmYxMWNlZDFhYjE1NGM0ZWI3MWZmZmE1YzFkMTY5MTIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODk4NDY3YmYxOWI2NDRhZTg3ZDYwMjY4Nzg5MmM0MDEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTY3NTI4MTY4NzY2MzUsLTc0LjAwODU4Mzc2Mjk1MjIxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJmYmFhNzFlNzZmZjRmZDU5OWRlMTQ2Njg0Yzg3ZjBjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzYwZjE4ZTY1ZGNlMjQzZWNhZWVkNjA4NmVlOWEyZGViID0gJCgnPGRpdiBpZD0iaHRtbF82MGYxOGU2NWRjZTI0M2VjYWVlZDYwODZlZTlhMmRlYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QXNpYW4gUmVzdGF1cmFudDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmZiYWE3MWU3NmZmNGZkNTk5ZGUxNDY2ODRjODdmMGMuc2V0Q29udGVudChodG1sXzYwZjE4ZTY1ZGNlMjQzZWNhZWVkNjA4NmVlOWEyZGViKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzg5ODQ2N2JmMTliNjQ0YWU4N2Q2MDI2ODc4OTJjNDAxLmJpbmRQb3B1cChwb3B1cF8yZmJhYTcxZTc2ZmY0ZmQ1OTlkZTE0NjY4NGM4N2YwYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZTU3NTRmNmJiZTY0ZjI3YjUwMjhjZDljNzA0NzI1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNzAxMDExNDA5OTA2LC03NC4wMDgwNDI0NDU2MjIyNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYjRlY2RlNzA0MzA0ZDE4OTA2NTY2YWZkYzgyY2VkZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZDkxNzM3MmI0MWI0YTczYTJkMTQ5YWNmYzdhNjMyOSA9ICQoJzxkaXYgaWQ9Imh0bWxfM2Q5MTczNzJiNDFiNGE3M2EyZDE0OWFjZmM3YTYzMjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZyZW5jaCBSZXN0YXVyYW50PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kYjRlY2RlNzA0MzA0ZDE4OTA2NTY2YWZkYzgyY2VkZi5zZXRDb250ZW50KGh0bWxfM2Q5MTczNzJiNDFiNGE3M2EyZDE0OWFjZmM3YTYzMjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfN2U1NzU0ZjZiYmU2NGYyN2I1MDI4Y2Q5YzcwNDcyNTYuYmluZFBvcHVwKHBvcHVwX2RiNGVjZGU3MDQzMDRkMTg5MDY1NjZhZmRjODJjZWRmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA0NDMyNGUyNGU5MzRkYjQ5MjBkZWE2MjRiYzIzNGQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE2NzkzMDQ4NTU4MDgsLTc0LjAwODIxOTk4ODc4NDU3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA5MDU4MTMyNmNmNDRlYjBhMWI3ZGVkYTUyMzQzMjAxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcyZWEyZTU4YTE4YjRhOGI4ZTJhZWZkMzM5MjJiMjM1ID0gJCgnPGRpdiBpZD0iaHRtbF83MmVhMmU1OGExOGI0YThiOGUyYWVmZDMzOTIyYjIzNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QW1lcmljYW4gUmVzdGF1cmFudDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDkwNTgxMzI2Y2Y0NGViMGExYjdkZWRhNTIzNDMyMDEuc2V0Q29udGVudChodG1sXzcyZWEyZTU4YTE4YjRhOGI4ZTJhZWZkMzM5MjJiMjM1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzA0NDMyNGUyNGU5MzRkYjQ5MjBkZWE2MjRiYzIzNGQ1LmJpbmRQb3B1cChwb3B1cF8wOTA1ODEzMjZjZjQ0ZWIwYTFiN2RlZGE1MjM0MzIwMSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hYmU3MWI1YWViYWU0ZTZjOWY5MWE5NjEzOWY1YmI4ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTI4NDIzMTMyODI3LC03NC4wMDg3ODA5Mzk1MjAxOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jMTdiNWY2MjI4NWM0MzJjOWU4NGI3ZmM4ZWE3NDY4NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yYzJkMzhhMTkzODQ0Zjk2OGRmYTI2YmMxMDRiNjMxMCA9ICQoJzxkaXYgaWQ9Imh0bWxfMmMyZDM4YTE5Mzg0NGY5NjhkZmEyNmJjMTA0YjYzMTAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFudGlxdWUgU2hvcDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzE3YjVmNjIyODVjNDMyYzllODRiN2ZjOGVhNzQ2ODcuc2V0Q29udGVudChodG1sXzJjMmQzOGExOTM4NDRmOTY4ZGZhMjZiYzEwNGI2MzEwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FiZTcxYjVhZWJhZTRlNmM5ZjkxYTk2MTM5ZjViYjhlLmJpbmRQb3B1cChwb3B1cF9jMTdiNWY2MjI4NWM0MzJjOWU4NGI3ZmM4ZWE3NDY4Nyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82NjlhNmUyMDQ0OTk0NWRlYjg2Yjc0NGI4YWExNTE1ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNjc0MDg0MTYzMzY5LC03NC4wMDg2NjY0NDM4ODkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E2YTVlMzNjODQ2NDQ5ZGY4ZDhlNTEwMDAwYTJmOWE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzYwMTAwZmYwODViZjRlODg5Zjc2YWE0YjBjMzRmNWJiID0gJCgnPGRpdiBpZD0iaHRtbF82MDEwMGZmMDg1YmY0ZTg4OWY3NmFhNGIwYzM0ZjViYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q29ja3RhaWwgQmFyPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNmE1ZTMzYzg0NjQ0OWRmOGQ4ZTUxMDAwMGEyZjlhNC5zZXRDb250ZW50KGh0bWxfNjAxMDBmZjA4NWJmNGU4ODlmNzZhYTRiMGMzNGY1YmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjY5YTZlMjA0NDk5NDVkZWI4NmI3NDRiOGFhMTUxNWUuYmluZFBvcHVwKHBvcHVwX2E2YTVlMzNjODQ2NDQ5ZGY4ZDhlNTEwMDAwYTJmOWE0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U4ZGViMWQ1NDIyMTQ2MmU4NzQyMDRlN2EyNmMyOGRhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0MzUsLTc0LjAwOThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzI1NjcxYTY1MzVlNDRjODhmNzhlMGI3YzMzZDk2YzMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjEwOWUwNWYxM2I0NGY4YjkzZGY3MzdlMDhjMjY3NjYgPSAkKCc8ZGl2IGlkPSJodG1sXzYxMDllMDVmMTNiNDRmOGI5M2RmNzM3ZTA4YzI2NzY2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdHJpcCBDbHViPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jMjU2NzFhNjUzNWU0NGM4OGY3OGUwYjdjMzNkOTZjMy5zZXRDb250ZW50KGh0bWxfNjEwOWUwNWYxM2I0NGY4YjkzZGY3MzdlMDhjMjY3NjYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZThkZWIxZDU0MjIxNDYyZTg3NDIwNGU3YTI2YzI4ZGEuYmluZFBvcHVwKHBvcHVwX2MyNTY3MWE2NTM1ZTQ0Yzg4Zjc4ZTBiN2MzM2Q5NmMzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzUyYjRmM2VmMWI5NjRlYzI4NzQ2ZDFkMDg1Y2FiMWRmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE1NDg2NTg1MjQ5NzM1LC03NC4wMDkxMzMxMzUxMDgzNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kN2E4ZmFiN2RmMTU0OWZkOWNjODRiYzk1YTQ2MWNmOCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mZmM2ZDg0YmEzMWQ0NzY2OTc4ZDY2NzRkYzUyMWY4OSA9ICQoJzxkaXYgaWQ9Imh0bWxfZmZjNmQ4NGJhMzFkNDc2Njk3OGQ2Njc0ZGM1MjFmODkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFtZXJpY2FuIFJlc3RhdXJhbnQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Q3YThmYWI3ZGYxNTQ5ZmQ5Y2M4NGJjOTVhNDYxY2Y4LnNldENvbnRlbnQoaHRtbF9mZmM2ZDg0YmEzMWQ0NzY2OTc4ZDY2NzRkYzUyMWY4OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81MmI0ZjNlZjFiOTY0ZWMyODc0NmQxZDA4NWNhYjFkZi5iaW5kUG9wdXAocG9wdXBfZDdhOGZhYjdkZjE1NDlmZDljYzg0YmM5NWE0NjFjZjgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDBkNDJkZjYxMDFlNDQ1ZDlkZThlMTYzZDFmM2ZiN2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTYzNzk4NDMxNzA3MSwtNzQuMDA5NjI5MzM0NTM0MjhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWI2OWQxNTc4N2UyNDk1M2E3OWZiNzMzNGY0ZjM3Y2MgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmFlNDJkNDkxM2RiNGYyOTk0MzFhNzlmNjViZjMxOTYgPSAkKCc8ZGl2IGlkPSJodG1sX2ZhZTQyZDQ5MTNkYjRmMjk5NDMxYTc5ZjY1YmYzMTk2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5OZXcgQW1lcmljYW4gUmVzdGF1cmFudDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYWI2OWQxNTc4N2UyNDk1M2E3OWZiNzMzNGY0ZjM3Y2Muc2V0Q29udGVudChodG1sX2ZhZTQyZDQ5MTNkYjRmMjk5NDMxYTc5ZjY1YmYzMTk2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQwZDQyZGY2MTAxZTQ0NWQ5ZGU4ZTE2M2QxZjNmYjdhLmJpbmRQb3B1cChwb3B1cF9hYjY5ZDE1Nzg3ZTI0OTUzYTc5ZmI3MzM0ZjRmMzdjYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85OGNjNTAzNTRlOWY0Mjk3YmE5ZmNjZjdiYmUwYmQ2MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNDM0MjI5MDE1ODA4NiwtNzQuMDA4MDkzNTY4NDAwMDRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTUyNzEyYjIyZGJlNDNkNjg4NWMxODg0NWZhMzQ1NmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGU3MTJmYzQyMGU3NDNiYTk1YTBjNDRhNWFmZWZlZDYgPSAkKCc8ZGl2IGlkPSJodG1sXzRlNzEyZmM0MjBlNzQzYmE5NWEwYzQ0YTVhZmVmZWQ2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Zb2dhIFN0dWRpbzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTUyNzEyYjIyZGJlNDNkNjg4NWMxODg0NWZhMzQ1NmUuc2V0Q29udGVudChodG1sXzRlNzEyZmM0MjBlNzQzYmE5NWEwYzQ0YTVhZmVmZWQ2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzk4Y2M1MDM1NGU5ZjQyOTdiYTlmY2NmN2JiZTBiZDYzLmJpbmRQb3B1cChwb3B1cF8xNTI3MTJiMjJkYmU0M2Q2ODg1YzE4ODQ1ZmEzNDU2ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iZjgzNmZkZDBkY2M0OGI5OTVjYjkyOTMwNWFlOGU3YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTU5ODQ4NjY4NzY3NSwtNzQuMDA3ODgyMjc1MTEyODhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjY1MDZmNDRhNDM5NDAwM2FiM2VmY2FiZjhmYTQxYmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWY4Y2Y5MjYxOTM5NGJjMzg4YTI4ZGQ2MjcwNGQwMDUgPSAkKCc8ZGl2IGlkPSJodG1sXzFmOGNmOTI2MTkzOTRiYzM4OGEyOGRkNjI3MDRkMDA1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TcGE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I2NTA2ZjQ0YTQzOTQwMDNhYjNlZmNhYmY4ZmE0MWJlLnNldENvbnRlbnQoaHRtbF8xZjhjZjkyNjE5Mzk0YmMzODhhMjhkZDYyNzA0ZDAwNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iZjgzNmZkZDBkY2M0OGI5OTVjYjkyOTMwNWFlOGU3YS5iaW5kUG9wdXAocG9wdXBfYjY1MDZmNDRhNDM5NDAwM2FiM2VmY2FiZjhmYTQxYmUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTk1NTFlMDQ5OWJiNGU1MmEyYjJmZGY3N2YwNjNhNDEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTQ5MDk1MDE1Mzk4MiwtNzQuMDA5NDgwMjcwMTE5MDNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDY2YTdiMWU5MjE3NDMxNWJkMTgzMDVkZTUzZDIwNjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTJiN2QxMDI1YzM1NDJiODhjNTJmOGU5NGZkY2U4YTkgPSAkKCc8ZGl2IGlkPSJodG1sX2UyYjdkMTAyNWMzNTQyYjg4YzUyZjhlOTRmZGNlOGE5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Cb29rc3RvcmU8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzA2NmE3YjFlOTIxNzQzMTViZDE4MzA1ZGU1M2QyMDY1LnNldENvbnRlbnQoaHRtbF9lMmI3ZDEwMjVjMzU0MmI4OGM1MmY4ZTk0ZmRjZThhOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81OTU1MWUwNDk5YmI0ZTUyYTJiMmZkZjc3ZjA2M2E0MS5iaW5kUG9wdXAocG9wdXBfMDY2YTdiMWU5MjE3NDMxNWJkMTgzMDVkZTUzZDIwNjUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTk0NjgyMTllMWI5NGVlMGE5YjZkNzkxZWU0M2E0NDEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTQ5NjMxOTc5MTgxMSwtNzQuMDA5ODM4NzM4MzUxMjhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmRkN2M1ODRjZmY4NGQwZjk1OWU3OWY5MTQ3NjhhNGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNmVkZWM4ZGJjMzc3NGQyMThjZTA4MzUxNDM4N2ZiNTEgPSAkKCc8ZGl2IGlkPSJodG1sXzZlZGVjOGRiYzM3NzRkMjE4Y2UwODM1MTQzODdmYjUxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaWRzIFN0b3JlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iZGQ3YzU4NGNmZjg0ZDBmOTU5ZTc5ZjkxNDc2OGE0Zi5zZXRDb250ZW50KGh0bWxfNmVkZWM4ZGJjMzc3NGQyMThjZTA4MzUxNDM4N2ZiNTEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTk0NjgyMTllMWI5NGVlMGE5YjZkNzkxZWU0M2E0NDEuYmluZFBvcHVwKHBvcHVwX2JkZDdjNTg0Y2ZmODRkMGY5NTllNzlmOTE0NzY4YTRmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI2N2U1NjU1ZjdlMzQzNTliZWFkNmRlNDQ2ZjkwMThiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE1NTgsLTc0LjAwOTg1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzYxMGM3ZDgxZmM4NTQwNzU5ZjI5MmNkZWI2YTU0ZjcwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY1MjUzMjkwYmY2NzQ5NDRhOTBhNjUwYjU0MjI1Njc3ID0gJCgnPGRpdiBpZD0iaHRtbF82NTI1MzI5MGJmNjc0OTQ0YTkwYTY1MGI1NDIyNTY3NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmFnZWwgU2hvcDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjEwYzdkODFmYzg1NDA3NTlmMjkyY2RlYjZhNTRmNzAuc2V0Q29udGVudChodG1sXzY1MjUzMjkwYmY2NzQ5NDRhOTBhNjUwYjU0MjI1Njc3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzI2N2U1NjU1ZjdlMzQzNTliZWFkNmRlNDQ2ZjkwMThiLmJpbmRQb3B1cChwb3B1cF82MTBjN2Q4MWZjODU0MDc1OWYyOTJjZGViNmE1NGY3MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iOTg3Y2ZhY2Y0NzA0NGRlYjI3NTkwZDBkOGVmM2E4NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTg4NTEyNjA4NjAxNSwtNzQuMDA4NzEzNjE5MDI0MThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTZmNmZjOGI5ZGZkNDk4MGE0NWJjMDNlMzU2OWU0OGEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGM5OWVjZDJlZjZmNGFhM2FkNzAwNzM0MGM3NjM1ZmYgPSAkKCc8ZGl2IGlkPSJodG1sXzRjOTllY2QyZWY2ZjRhYTNhZDcwMDczNDBjNzYzNWZmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db2NrdGFpbCBCYXI8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E2ZjZmYzhiOWRmZDQ5ODBhNDViYzAzZTM1NjllNDhhLnNldENvbnRlbnQoaHRtbF80Yzk5ZWNkMmVmNmY0YWEzYWQ3MDA3MzQwYzc2MzVmZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iOTg3Y2ZhY2Y0NzA0NGRlYjI3NTkwZDBkOGVmM2E4Ni5iaW5kUG9wdXAocG9wdXBfYTZmNmZjOGI5ZGZkNDk4MGE0NWJjMDNlMzU2OWU0OGEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNGJkMjI2OGU4MGYwNGVlZTkzNDc3YTJmOTY4YmQyYWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTU2Mjg2MjAwMjU2LC03NC4wMDc5OTIyNTgzODUzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU5Yjk0ZmE5NDk2MjQzYjVhNTZlZTAwNjk5ZGY0Y2FmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VmYzc0Yzk4MGQ0MjQ5YWY4NTk2YjUzNTRmMWEwNjIzID0gJCgnPGRpdiBpZD0iaHRtbF9lZmM3NGM5ODBkNDI0OWFmODU5NmI1MzU0ZjFhMDYyMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3ltIC8gRml0bmVzcyBDZW50ZXI8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU5Yjk0ZmE5NDk2MjQzYjVhNTZlZTAwNjk5ZGY0Y2FmLnNldENvbnRlbnQoaHRtbF9lZmM3NGM5ODBkNDI0OWFmODU5NmI1MzU0ZjFhMDYyMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80YmQyMjY4ZTgwZjA0ZWVlOTM0NzdhMmY5NjhiZDJhYi5iaW5kUG9wdXAocG9wdXBfNTliOTRmYTk0OTYyNDNiNWE1NmVlMDA2OTlkZjRjYWYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGJmNDZiNTJlMTk0NDczNzhjYzM5ZmFlZTJkZjk0ZjAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTY2ODQzOTIyNzgyMiwtNzQuMDA4MzQzNDI4NjkyMzhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmYyY2FkZDRlMDliNDcwYjkwYWViNTYyN2E5NmI5MmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWIxZDUyYjk2ZmU3NGNkYWIwZWZhMGMwOWZlMzljOWQgPSAkKCc8ZGl2IGlkPSJodG1sX2ViMWQ1MmI5NmZlNzRjZGFiMGVmYTBjMDlmZTM5YzlkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdXNoaSBSZXN0YXVyYW50PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iZjJjYWRkNGUwOWI0NzBiOTBhZWI1NjI3YTk2YjkyZS5zZXRDb250ZW50KGh0bWxfZWIxZDUyYjk2ZmU3NGNkYWIwZWZhMGMwOWZlMzljOWQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZGJmNDZiNTJlMTk0NDczNzhjYzM5ZmFlZTJkZjk0ZjAuYmluZFBvcHVwKHBvcHVwX2JmMmNhZGQ0ZTA5YjQ3MGI5MGFlYjU2MjdhOTZiOTJlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIzZGUyOWE4NzNiMTQ4YzJiYjZiMDc5OWNmMDUxZTMzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0NzU0MTUxNDYxMjM2LC03NC4wMDc1ODA2MDAyMDM5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjYsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzJmYTA0NmM2NzAyMzRhMzI4YmIxYWU5ZWRiNDg1NmI2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc4YzE1ZWEyYjA2MjQ4ZDA4YWI5ZTc0NWFmZWUwYjUzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcxN2IxZWNhOGJkNzQ3YzI4MGQwNTgxNGUyZWUwZjNmID0gJCgnPGRpdiBpZD0iaHRtbF83MTdiMWVjYThiZDc0N2MyODBkMDU4MTRlMmVlMGYzZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RnJlbmNoIFJlc3RhdXJhbnQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc4YzE1ZWEyYjA2MjQ4ZDA4YWI5ZTc0NWFmZWUwYjUzLnNldENvbnRlbnQoaHRtbF83MTdiMWVjYThiZDc0N2MyODBkMDU4MTRlMmVlMGYzZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yM2RlMjlhODczYjE0OGMyYmI2YjA3OTljZjA1MWUzMy5iaW5kUG9wdXAocG9wdXBfNzhjMTVlYTJiMDYyNDhkMDhhYjllNzQ1YWZlZTBiNTMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjE1NzgxMmYzMTQwNGNmNjkyNmU1YzBhZGI5ODIyNDAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0MC43MTUwNDUxMjU1ODk5NiwtNzQuMDExNTA4NzEwMjgyMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC42LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yZmEwNDZjNjcwMjM0YTMyOGJiMWFlOWVkYjQ4NTZiNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80NjY1OWQ5OTAwNWM0Zjg1YjcwZjY0YmZjMDk4ODgzYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80N2QxNjk5NTAxOWQ0MjJhOGIxMWRhYWE3Y2MwZmQ2NSA9ICQoJzxkaXYgaWQ9Imh0bWxfNDdkMTY5OTUwMTlkNDIyYThiMTFkYWFhN2NjMGZkNjUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNvZmZlZSBTaG9wPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NjY1OWQ5OTAwNWM0Zjg1YjcwZjY0YmZjMDk4ODgzYy5zZXRDb250ZW50KGh0bWxfNDdkMTY5OTUwMTlkNDIyYThiMTFkYWFhN2NjMGZkNjUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjE1NzgxMmYzMTQwNGNmNjkyNmU1YzBhZGI5ODIyNDAuYmluZFBvcHVwKHBvcHVwXzQ2NjU5ZDk5MDA1YzRmODViNzBmNjRiZmMwOTg4ODNjKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2FjNmMwNzVhYTkxMjQ3NWVhMWNhYmExZmVlOWM2OGZhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDAuNzE0NzIxMTY3OTY4MzksLTc0LjAwOTgzMTgxOTY2NjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDY4M2ViOTEzZGJhNDZhMGI0MWJmYTBhNzM1ZGE1NDQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODA0NzVmZjRkYTQ0NDgyM2IzMzBlNGJiOWQzZGUxZjQgPSAkKCc8ZGl2IGlkPSJodG1sXzgwNDc1ZmY0ZGE0NDQ4MjNiMzMwZTRiYjlkM2RlMWY0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaW5lIEJhcjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDY4M2ViOTEzZGJhNDZhMGI0MWJmYTBhNzM1ZGE1NDQuc2V0Q29udGVudChodG1sXzgwNDc1ZmY0ZGE0NDQ4MjNiMzMwZTRiYjlkM2RlMWY0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FjNmMwNzVhYTkxMjQ3NWVhMWNhYmExZmVlOWM2OGZhLmJpbmRQb3B1cChwb3B1cF80NjgzZWI5MTNkYmE0NmEwYjQxYmZhMGE3MzVkYTU0NCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82ODc1ZjI1NDgyYmE0YWFjYTBmMjRkM2EyMjBmMGRjNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQwLjcxNTE0MzksLTc0LjAwOTE4MjZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMmZhMDQ2YzY3MDIzNGEzMjhiYjFhZTllZGI0ODU2YjYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjkwYmFjZWRiMTA1NDU0OTk5YjIyZjcyOWNjMWFkZWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTUyYTkzMGY4MzQ2NGM2NzgzOTg0MDEwN2YzMTU1YTggPSAkKCc8ZGl2IGlkPSJodG1sXzE1MmE5MzBmODM0NjRjNjc4Mzk4NDAxMDdmMzE1NWE4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ib3RlbDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjkwYmFjZWRiMTA1NDU0OTk5YjIyZjcyOWNjMWFkZWMuc2V0Q29udGVudChodG1sXzE1MmE5MzBmODM0NjRjNjc4Mzk4NDAxMDdmMzE1NWE4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzY4NzVmMjU0ODJiYTRhYWNhMGYyNGQzYTIyMGYwZGM2LmJpbmRQb3B1cChwb3B1cF82OTBiYWNlZGIxMDU0NTQ5OTliMjJmNzI5Y2MxYWRlYyk7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f9a3dca35c0>"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"venues_map = folium.Map(location=[latitude, longitude], zoom_start=15) # generate map centred around Ecco\n",
"\n",
"\n",
"# add Ecco as a red circle mark\n",
"folium.features.CircleMarker(\n",
" [latitude, longitude],\n",
" radius=10,\n",
" popup='Ecco',\n",
" fill=True,\n",
" color='red',\n",
" fill_color='red',\n",
" fill_opacity=0.6\n",
" ).add_to(venues_map)\n",
"\n",
"\n",
"# add popular spots to the map as blue circle markers\n",
"for lat, lng, label in zip(dataframe_filtered.lat, dataframe_filtered.lng, dataframe_filtered.categories):\n",
" folium.features.CircleMarker(\n",
" [lat, lng],\n",
" radius=5,\n",
" popup=label,\n",
" fill=True,\n",
" color='blue',\n",
" fill_color='blue',\n",
" fill_opacity=0.6\n",
" ).add_to(venues_map)\n",
"\n",
"# display map\n",
"venues_map"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item5\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"## 5. Explore Trending Venues\n",
"> `https://api.foursquare.com/v2/venues/`**trending**`?client_id=`**CLIENT_ID**`&client_secret=`**CLIENT_SECRET**`&ll=`**LATITUDE**`,`**LONGITUDE**`&v=`**VERSION**"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"#### Now, instead of simply exploring the area around Ecco, you are interested in knowing the venues that are trending at the time you are done with your lunch, meaning the places with the highest foot traffic. So let's do that and get the trending venues around Ecco."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'meta': {'code': 200, 'requestId': '5c74c5a29fb6b740ef4925e4'},\n",
" 'response': {'venues': []}}"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# define URL\n",
"url = 'https://api.foursquare.com/v2/venues/trending?client_id={}&client_secret={}&ll={},{}&v={}'.format(CLIENT_ID, CLIENT_SECRET, latitude, longitude, VERSION)\n",
"\n",
"# send GET request and get trending venues\n",
"results = requests.get(url).json()\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Check if any venues are trending at this time"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"button": false,
"collapsed": true,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"if len(results['response']['venues']) == 0:\n",
" trending_venues_df = 'No trending venues are available at the moment!'\n",
" \n",
"else:\n",
" trending_venues = results['response']['venues']\n",
" trending_venues_df = json_normalize(trending_venues)\n",
"\n",
" # filter columns\n",
" columns_filtered = ['name', 'categories'] + ['location.distance', 'location.city', 'location.postalCode', 'location.state', 'location.country', 'location.lat', 'location.lng']\n",
" trending_venues_df = trending_venues_df.loc[:, columns_filtered]\n",
"\n",
" # filter the category for each row\n",
" trending_venues_df['categories'] = trending_venues_df.apply(get_category_type, axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [
{
"data": {
"text/plain": [
"'No trending venues are available at the moment!'"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# display trending venues\n",
"trending_venues_df"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"Now, depending on when you run the above code, you might get different venues since the venues with the highest foot traffic are fetched live. "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Visualize trending venues"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"outputs": [],
"source": [
"if len(results['response']['venues']) == 0:\n",
" venues_map = 'Cannot generate visual as no trending venues are available at the moment!'\n",
"\n",
"else:\n",
" venues_map = folium.Map(location=[latitude, longitude], zoom_start=15) # generate map centred around Ecco\n",
"\n",
"\n",
" # add Ecco as a red circle mark\n",
" folium.features.CircleMarker(\n",
" [latitude, longitude],\n",
" radius=10,\n",
" popup='Ecco',\n",
" fill=True,\n",
" color='red',\n",
" fill_color='red',\n",
" fill_opacity=0.6\n",
" ).add_to(venues_map)\n",
"\n",
"\n",
" # add the trending venues as blue circle markers\n",
" for lat, lng, label in zip(trending_venues_df['location.lat'], trending_venues_df['location.lng'], trending_venues_df['name']):\n",
" folium.features.CircleMarker(\n",
" [lat, lng],\n",
" radius=5,\n",
" poup=label,\n",
" fill=True,\n",
" color='blue',\n",
" fill_color='blue',\n",
" fill_opacity=0.6\n",
" ).add_to(venues_map)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"button": false,
"collapsed": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
},
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"'Cannot generate visual as no trending venues are available at the moment!'"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# display map\n",
"venues_map"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<a id=\"item6\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"### Thank you for completing this lab!\n",
"\n",
"This notebook was created by [Alex Aklson](https://www.linkedin.com/in/aklson/). I hope you found this lab interesting and educational. Feel free to contact me if you have any questions!"
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"This notebook is part of a course on **Coursera** called *Applied Data Science Capstone*. If you accessed this notebook outside the course, you can take this course online by clicking [here](http://cocl.us/DP0701EN_Coursera_Week2_LAB1)."
]
},
{
"cell_type": "markdown",
"metadata": {
"button": false,
"deletable": true,
"new_sheet": false,
"run_control": {
"read_only": false
}
},
"source": [
"<hr>\n",
"Copyright &copy; 2018 [Cognitive Class](https://cognitiveclass.ai/?utm_source=bducopyrightlink&utm_medium=dswb&utm_campaign=bdu). This notebook and its source code are released under the terms of the [MIT License](https://bigdatauniversity.com/mit-license/)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
},
"widgets": {
"state": {},
"version": "1.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment